diff --git a/CMakeLists.txt b/CMakeLists.txt index aec8468..d396161 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,11 +52,13 @@ target_include_directories( PUBLIC $ PUBLIC $ PUBLIC $ + PUBLIC $ ) target_link_libraries(vissim ${PROJECT_NAME} glfw) target_sources(vissim PRIVATE src/utils.cc + src/srender.c 3rdparty/glfw/deps/glad_gl.c 3rdparty/imgui/imgui.cpp 3rdparty/imgui/imgui_draw.cpp diff --git a/src/srender.c b/src/srender.c new file mode 100644 index 0000000..87eabc7 --- /dev/null +++ b/src/srender.c @@ -0,0 +1,153 @@ +// clang-format off +#include +// clang-format on + +#include "srender.h" + +#include "utils.h" +#include + +typedef struct srndr { +} srndr; + +typedef struct srview { + GLuint width; + GLuint height; + + GLuint mFrameBufferId; + GLuint mColorTexture; + GLuint mDepthTexture; +} srveiw; + +typedef struct srcmdbuf { +} srcmdbuf; + +srndr* srndr_create() { + srndr* result = calloc(1, sizeof(srndr)); + + return result; +} + +void srndr_destroy(srndr* sr) { free(sr); } + +void srview_get_output_texture(srview* sv, GLuint* texture) { + *texture = sv->mColorTexture; +} + +void srview_update_framebuffer(srview* sv) { + glGenFramebuffers(1, &sv->mFrameBufferId); + glBindFramebuffer(GL_FRAMEBUFFER, sv->mFrameBufferId); + + // Color Texture + glGenTextures(1, &sv->mColorTexture); + glBindTexture(GL_TEXTURE_2D, sv->mColorTexture); + + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RGB, + sv->width, + sv->height, + 0, + GL_RGB, + GL_UNSIGNED_BYTE, + 0); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glFramebufferTexture2D( + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + sv->mColorTexture, + 0); + + // Depth Texture + glGenTextures(1, &sv->mDepthTexture); + glBindTexture(GL_TEXTURE_2D, sv->mDepthTexture); + + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_DEPTH_COMPONENT, + sv->width, + sv->height, + 0, + GL_DEPTH_COMPONENT, + GL_FLOAT, + 0); + + // Set parameters so that we can set a shadow2DSampler + glTexParameteri( + GL_TEXTURE_2D, + GL_TEXTURE_COMPARE_MODE, + GL_COMPARE_REF_TO_TEXTURE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + float border_color[] = {1.0f, 1.0f, 1.0f, 1.0f}; + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color); + + glFramebufferTexture2D( + GL_FRAMEBUFFER, + GL_DEPTH_ATTACHMENT, + GL_TEXTURE_2D, + sv->mDepthTexture, + 0); +} + +void srview_cleanup_framebuffer(srview* sv) { + if (glIsFramebuffer(sv->mFrameBufferId)) { + glDeleteFramebuffers(1, &sv->mFrameBufferId); + } + + if (sv->mColorTexture != -1) { + glDeleteTextures(1, &sv->mColorTexture); + sv->mColorTexture = -1; + } + + if (sv->mDepthTexture != -1) { + glDeleteTextures(1, &sv->mDepthTexture); + sv->mDepthTexture = -1; + } +} + +void srview_set_size(srview* sv, int width, int height) { + if (sv->width == width && sv->height == height) { + return; + } + + gLog("Setting size to %d, %d", width, height); + + sv->width = width; + sv->height = height; + + srview_cleanup_framebuffer(sv); + srview_update_framebuffer(sv); + + gLog("Color texture = %d", sv->mColorTexture); +} + +srview* srview_create() { + srview* result = calloc(1, sizeof(srview)); + + return result; +} + +void srview_destroy(srview* sv) { + srview_cleanup_framebuffer(sv); + + free(sv); +} + +void srndr_render(srndr* srndr, srview* sview, srcmdbuf* scmdbuf) { + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, sview->mFrameBufferId); + + glViewport(0, 0, sview->width, sview->height); + glClearColor(1.f, 0.f, 1.f, 1.f); + glClear(GL_COLOR_BUFFER_BIT); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); +} diff --git a/src/srender.h b/src/srender.h new file mode 100644 index 0000000..5252d25 --- /dev/null +++ b/src/srender.h @@ -0,0 +1,54 @@ +#ifndef SRENDER_H +#define SRENDER_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct srndr srndr; +typedef struct srview srview; +typedef struct srcmdbuf srcmdbuf; + +typedef enum { + SRndrCmdTypeGrid = 0, + SRndrCmdTypeBox, + SRndrCmdTypeLight, + SRndrCmdTypeSphere +} SRndrCmdType; + +typedef struct srcmd { + float mat[16]; + float color[4]; + SRndrCmdType cmd_type; +} srcmd; + +// +// Renderer +// +srndr* srndr_create(); +void srndr_destroy(srndr* sr); + +// +// View +// +srview* srview_create(); +void srview_destroy(srview* sv); + +void srview_set_proj(srview* sv, float* proj); +void srview_set_view(srview* sv, float* view); +void srview_set_size(srview* sv, int width, int height); +void srview_get_output_texture(srview* sv, GLuint* texture); + +// +// Command Buffer and Commands +// +srcmdbuf* srcmdbuf_create(unsigned int size_max); +srcmd* srcmd_create(srcmdbuf* cmdbuf); + +void srndr_render(srndr* srndr, srview* sview, srcmdbuf* scmdbuf); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utils.h b/src/utils.h index c9b9b42..a438fc9 100644 --- a/src/utils.h +++ b/src/utils.h @@ -15,13 +15,6 @@ extern "C" { #endif -struct Timer { - float mCurrentTime = 0.0f; - float mFrameTime = 0.0f; - float mDeltaTime = 0.0f; - bool mPaused = false; -}; - typedef struct { int32_t mousedX; int32_t mousedY; diff --git a/src/vissim.cc b/src/vissim.cc index 83ae8f0..85a817b 100644 --- a/src/vissim.cc +++ b/src/vissim.cc @@ -18,12 +18,25 @@ #include "backends/imgui_impl_opengl3.h" #include "imgui.h" #include "utils.h" +#include "srender.h" + +struct Timer { + float mCurrentTime = 0.0f; + float mFrameTime = 0.0f; + float mDeltaTime = 0.0f; + bool mPaused = false; +}; Timer* gTimer = nullptr; GLFWwindow* gWindow = nullptr; GuiInputState* gGuiInputState = nullptr; double gTimeAtStart = 0; +// Rendering +srndr* gRndr = nullptr; +srview* gView = nullptr; +srcmdbuf* gRndrCmds = nullptr; + double mouse_scroll_x = 0.; double mouse_scroll_y = 0.; @@ -139,6 +152,25 @@ void ShowDockspace(bool open) { ImGui::End(); } +void DoRender() { + // Render Output + ImGui::Begin("Render Output"); + const ImVec2 content_avail = ImGui::GetContentRegionAvail(); + GLuint view_texture; + + srview_set_size(gView, content_avail.x, content_avail.y); + srndr_render(gRndr, gView, gRndrCmds); + srview_get_output_texture(gView, &view_texture); + + ImGui::Image( + (void*)view_texture, + content_avail, + ImVec2(0.0f, 1.0f), + ImVec2(1.0f, 0.0f)); + + ImGui::End(); +} + int main(void) { gTimeAtStart = gGetCurrentTime(); std::cout << "Time at start: " << gTimeAtStart << std::endl; @@ -217,6 +249,9 @@ int main(void) { bool show_demo_window = true; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + gRndr = srndr_create(); + gView = srview_create(); + while (!glfwWindowShouldClose(gWindow)) { frame_counter++; @@ -257,11 +292,7 @@ int main(void) { ShowDockspace(true); - ImGui::Begin("yoyoyo"); - ImGui::End(); - - ImGui::Begin("yoyoyo3333"); - ImGui::End(); + DoRender(); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); @@ -295,6 +326,9 @@ int main(void) { gLog("Exiting application"); + srview_destroy(gView); + srndr_destroy(gRndr); + ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext();