From c03e998ef363212f6f28e64522ae808eec14b7e7 Mon Sep 17 00:00:00 2001 From: Hugo Willaume Date: Wed, 12 Jun 2019 17:19:09 +0900 Subject: [PATCH] change of workstation --- BaseGLProject/DSLightPass.frag | 37 ++++++++++-- BaseGLProject/DSLightPass.vert | 22 +++---- BaseGLProject/Models/Mesh.cpp | 17 ++++-- BaseGLProject/Multipass.cpp | 82 +++++++++++++++++++++++-- BaseGLProject/Multipass.h | 13 +++- BaseGLProject/MyGLWindow.cpp | 106 ++++++++++++++++++++++----------- BaseGLProject/MyGLWindow.h | 8 +-- BaseGLProject/SceneContext.h | 14 ++++- BaseGLProject/Source.cpp | 49 ++++++++++----- 9 files changed, 258 insertions(+), 90 deletions(-) diff --git a/BaseGLProject/DSLightPass.frag b/BaseGLProject/DSLightPass.frag index bdd4f1a..d058b88 100644 --- a/BaseGLProject/DSLightPass.frag +++ b/BaseGLProject/DSLightPass.frag @@ -1,10 +1,39 @@ #version 440 -//Copy of simple.frag +out vec4 FragColor; -in vec3 f_color; -out vec4 FragColors; +in vec2 uv; + +uniform sampler2D pos_tex; +uniform sampler2D normal_tex; +uniform sampler2D color_tex; + +struct Light { + vec3 Position; + vec3 Color; +}; + +uniform int NLights; +uniform Light lights[64]; + +uniform vec3 view_pos; void main() { - FragColors = vec4(f_color, 1.f); + vec3 FragPos = texture(pos_tex, uv).rgb; + vec3 Normal = texture(normal_tex, uv).rgb; + vec3 Albedo = texture(color_tex, uv).rgb; + float Specular = 0.5f; + + // then calculate lighting as usual + vec3 lighting = Albedo * 0.1; // hard-coded ambient component + vec3 viewDir = normalize(view_pos - FragPos); + for (int i = 0; i < NLights; ++i) + { + // diffuse + vec3 lightDir = normalize(lights[i].Position - FragPos); + vec3 diffuse = max(dot(Normal, lightDir), 0.0) * Albedo * lights[i].Color; + lighting += diffuse; + } + + FragColor = vec4(lighting, 1.0); } diff --git a/BaseGLProject/DSLightPass.vert b/BaseGLProject/DSLightPass.vert index 3fc7cf5..5b0c83c 100644 --- a/BaseGLProject/DSLightPass.vert +++ b/BaseGLProject/DSLightPass.vert @@ -1,18 +1,12 @@ -#version 440 -// Copy of simple.vert +#version 430 -layout(location=0) in vec3 coord3d; -layout(location=1) in vec3 v_normal; -layout(location=2) in vec3 v_color; -layout(location=3) in vec2 v_texmap; +layout(location = 0) in vec2 vPosition; +layout(location = 1) in vec2 vUV; +out vec2 uv; -out vec3 f_color; - -uniform mat4 mvp; - -void main(void) +void main() { - f_color = v_color; - gl_Position = mvp * vec4(coord3d, 1.0f); -} \ No newline at end of file + gl_Position = vec4(vPosition,0.0,1.0); + uv = vUV; +} \ No newline at end of file diff --git a/BaseGLProject/Models/Mesh.cpp b/BaseGLProject/Models/Mesh.cpp index 410194a..885570e 100644 --- a/BaseGLProject/Models/Mesh.cpp +++ b/BaseGLProject/Models/Mesh.cpp @@ -314,9 +314,13 @@ Mesh::Mesh(const char *filename, std::string vert_shd, std::string frag_shd) // Check for errors if (!scene || scene->mFlags == AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) // if is Not Zero { - std::cout << "ERROR::ASSIMP:: " << importer.GetErrorString() << std::endl; - return; - } + std::cout << "ERROR::ASSIMP:: " << importer.GetErrorString() << std::endl; + throw new std::exception(("Error loading mesh at the following location : " + fullname).c_str()); + } + + for (unsigned int i = 0; i < scene->mNumMeshes; ++i) { + meshEntries.push_back(new Mesh::MeshEntry(scene->mMeshes[i], scene, this)); + } } Mesh::Mesh(Dataset &set, std::string vert_shd, std::string frag_shd) : shader(vert_shd, frag_shd) @@ -357,11 +361,12 @@ void Mesh::draw(SceneContext &ctx) { shader.addUniform("mvp", ctx.mvpMatrix); shader.addUniform("NormalMatrix", ctx.normalMatrix); shader.addUniform("ModelMatrix", ctx.modelMatrix); - - + glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, textures["0"].tex_ref); + glBindTexture(GL_TEXTURE_2D, textures["0"].tex_ref); + meshEntries.at(i)->render(ctx, shader); + glBindTexture(GL_TEXTURE_2D, 0); diff --git a/BaseGLProject/Multipass.cpp b/BaseGLProject/Multipass.cpp index e829420..6953b0f 100644 --- a/BaseGLProject/Multipass.cpp +++ b/BaseGLProject/Multipass.cpp @@ -50,6 +50,7 @@ void Multipass::addTexture(const std::string & tex_name, GLuint filter, GLuint t glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + if (depth) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); @@ -65,7 +66,74 @@ void Multipass::enableFrameBufferTexture(const std::string tex_name) glBindFramebuffer(GL_FRAMEBUFFER, _fboId); } -void Multipass::drawResultToScreen(SceneContext & scnctx) +void Multipass::gBufferSetup(SceneContext &scnctx) +{ + delete(shader); + shader = new Shader("textureViewer.vert", "textureViewer.frag"); + scnctx.firstRedraw = false; +} + +void Multipass::deferredLightSetup(SceneContext &scnctx) +{ + shader = new Shader("DSLightPass.vert", "DSLightPass.frag"); + + shader->addUniform("pos_tex", 0); + shader->addUniform("normal_tex", 1); + shader->addUniform("color_tex", 2); + + int i = 0; + for (auto light : scnctx.lights) + { + shader->addUniform("lights[" + std::to_string(i) + "].Position", glm::vec3(light.second.location)); + shader->addUniform("lights[" + std::to_string(i) + "].Color", light.second.intensity); + i++; + } + + shader->addUniform("NLights", (int)scnctx.lights.size()); + scnctx.firstRedraw = false; +} + +void Multipass::drawDeferredLightToScreen(SceneContext &scnctx) +{ + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, scnctx.width, scnctx.height); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, _pass_textures["position_buffer"]); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, _pass_textures["normal_buffer"]); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, _pass_textures["color_buffer"]); + + shader->enable(); + + shader->addUniform("view_pos", scnctx.camPos); + + glBindVertexArray(_quad_vao); + glBindBuffer(GL_ARRAY_BUFFER, _quad_vbo); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + static GLuint clearColor[4] = { 0, 0, 0, 0 }; + glClearTexImage(_pass_textures["position_buffer"], 0, GL_BGRA, GL_UNSIGNED_BYTE, &clearColor); + glClearTexImage(_pass_textures["normal_buffer"], 0, GL_BGRA, GL_UNSIGNED_BYTE, &clearColor); + glClearTexImage(_pass_textures["color_buffer"], 0, GL_BGRA, GL_UNSIGNED_BYTE, &clearColor); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, 0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, 0); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, 0); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + + shader->disable(); +} + +void Multipass::drawGBufferToScreen(SceneContext & scnctx) { glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(0, 0, scnctx.width, scnctx.height); @@ -75,19 +143,21 @@ void Multipass::drawResultToScreen(SceneContext & scnctx) glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, _pass_textures[_current_tex]); + shader->addUniform("tex", 0); glBindVertexArray(_quad_vao); glBindBuffer(GL_ARRAY_BUFFER, _quad_vbo); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); static GLuint clearColor[4] = { 0, 0, 0, 0 }; - glClearTexImage(_pass_textures[_current_tex], 0, GL_BGRA, GL_UNSIGNED_BYTE, &clearColor); + glClearTexImage(_pass_textures["position_buffer"], 0, GL_BGRA, GL_UNSIGNED_BYTE, &clearColor); + glClearTexImage(_pass_textures["normal_buffer"], 0, GL_BGRA, GL_UNSIGNED_BYTE, &clearColor); + glClearTexImage(_pass_textures["color_buffer"], 0, GL_BGRA, GL_UNSIGNED_BYTE, &clearColor); - - glBindTexture(GL_TEXTURE_2D, 0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_2D, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); shader->disable(); diff --git a/BaseGLProject/Multipass.h b/BaseGLProject/Multipass.h index d64b945..5ff8a13 100644 --- a/BaseGLProject/Multipass.h +++ b/BaseGLProject/Multipass.h @@ -18,8 +18,17 @@ public: void addTexture(const std::string &tex_name, GLuint filter, GLuint type, GLuint type_2, GLuint type_3, bool depth, SceneContext &scnctx, GLuint height = 0, GLuint width = 0); - void enableFrameBufferTexture(const std::string tex_name); - void drawResultToScreen(SceneContext &scnctx); + void enableFrameBufferTexture(const std::string tex_name); + + + void gBufferSetup(SceneContext & scnctx); + void drawGBufferToScreen(SceneContext &scnctx); + + void deferredLightSetup(SceneContext &scnctx); + void drawDeferredLightToScreen(SceneContext &scnctx); + + + GLuint getCurrentTexture(); Shader *shader; diff --git a/BaseGLProject/MyGLWindow.cpp b/BaseGLProject/MyGLWindow.cpp index e7f76d4..bec6f37 100644 --- a/BaseGLProject/MyGLWindow.cpp +++ b/BaseGLProject/MyGLWindow.cpp @@ -52,6 +52,14 @@ MyGlWindow::~MyGlWindow() shaders.clear(); } +void MyGlWindow::draw() +{ + if (_scnctx.renderMode == GBUF_DEBUG) + drawDebugGBuffer(); + else if (_scnctx.renderMode == DEFERRED_LIGHT) + drawDeferredLight(); +} + void MyGlWindow::setBgColor(float bgColor[3]) { _scnctx.bg = glm::vec4(bgColor[0], bgColor[1], bgColor[2], 1); @@ -83,19 +91,18 @@ void MyGlWindow::textureSetup() _scnctx.textures["CubeNmap"].isNmap = true; } -void MyGlWindow::lightSetup() -{ - _scnctx.lights.emplace("Spotlight1", Light(glm::vec3(0.8f), glm::vec4(10, 10, 10, 1))); -} void MyGlWindow::multipassSetup() -{ +{ _multipassManager.addTexture("position_buffer", GL_NEAREST, GL_RGB16F, GL_RGB, GL_FLOAT, false, _scnctx); _multipassManager.addTexture("normal_buffer", GL_NEAREST, GL_RGB16F, GL_RGB, GL_UNSIGNED_BYTE, false, _scnctx); - _multipassManager.addTexture("color_buffer", GL_NEAREST, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, false, _scnctx); + _multipassManager.addTexture("color_buffer", GL_NEAREST, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, false, _scnctx); + //_multipassManager.addTexture("depth_tex", GL_LINEAR, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_FLOAT, true, _scnctx); + _multipassManager.bindToFrameBuffer(GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, "position_buffer"); _multipassManager.bindToFrameBuffer(GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, "normal_buffer"); _multipassManager.bindToFrameBuffer(GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, "color_buffer"); + //_multipassManager.bindToFrameBuffer(GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, "depth_tex"); _multipassManager.setDrawBuffers(); } @@ -109,44 +116,34 @@ void MyGlWindow::setup() _scnctx.bg = glm::vec4(0.7, 0.7, 0.9, 1); textureSetup(); - lightSetup(); multipassSetup(); Dataset moddata; - //Scene for GBuffer Testing - /*Mesh *nanosuit_A = new Mesh("nanosuit/nanosuit.obj", shaders["DSGeometryPass"]); - Mesh *nanosuit_B = new Mesh("nanosuit/nanosuit.obj", shaders["DSGeometryPass"]); - Mesh *nanosuit_C = new Mesh("nanosuit/nanosuit.obj", shaders["DSGeometryPass"]); - - nanosuit_A->addStartScaling(glm::vec4(0.2, 0.2, 0.2, 1)); - nanosuit_B->addStartScaling(glm::vec4(0.2, 0.2, 0.2, 1)); - nanosuit_C->addStartScaling(glm::vec4(0.2, 0.2, 0.2, 1)); - - nanosuit_A->addStartTranslation(glm::vec4(-10, 0, 0, 1)); - nanosuit_C->addStartTranslation(glm::vec4(10, 0, 0, 1)); + //Scene for GBuffer Testing + Mesh *mountain = new Mesh("mountain/mount.blend1.obj", "DSGeometryPass.vert", "DSGeometryPass.frag"); + + meshes.emplace("Nanosuit_A", mountain); + + _scnctx.lights.emplace("RandLight", + Light(glm::vec3(1, 1, 1), glm::vec4(0, 2, 0, 1))); - meshes.emplace("Nanosuit_A", nanosuit_A); - meshes.emplace("Nanosuit_B", nanosuit_B); - meshes.emplace("Nanosuit_C", nanosuit_C); -*/ //Scene for light testing moddata.simpleCube(); //Hardcoded seed for easy scene replication - std::srand(18); + /*std::srand(18); int zob = std::rand(); - for (int i = 0; i < 100; i++) + for (int i = 0; i < 64; i++) { std::string cube_name = "Cube" + std::to_string(i); meshes.emplace(cube_name, new Mesh(moddata, "DSGeometryPass.vert", "DSGeometryPass.frag")); meshes[cube_name]->textures["0"] = _scnctx.textures["BrickTex"]; - float pos_x = std::rand() % 100 - 50; float pos_z = std::rand() % 100 - 50; @@ -160,14 +157,51 @@ void MyGlWindow::setup() float light_r = (40 + std::rand() % 60) / 100.f; float light_g = (40 + std::rand() % 60) / 100.f; float light_b = (40 + std::rand() % 60) / 100.f; - + _scnctx.lights.emplace("RandLight" + i, Light(glm::vec3(light_r, light_g, light_b), glm::vec4(pos_x, 2, pos_z, 1))); - } + }*/ } -void MyGlWindow::draw() +void MyGlWindow::drawDeferredLight() +{ + if (_scnctx.firstRedraw) + _multipassManager.deferredLightSetup(_scnctx); + + _scnctx.height = m_height; + _scnctx.width = m_width; + + glm::vec3 eye(viewer.getViewPoint().x, viewer.getViewPoint().y, viewer.getViewPoint().z); + glm::vec3 look(viewer.getViewCenter().x, viewer.getViewCenter().y, viewer.getViewCenter().z); + glm::vec3 up(viewer.getUpVector().x, viewer.getUpVector().y, viewer.getUpVector().z); + glm::mat4 view = lookAt(eye, look, up); //Calculate view matrix from parameters of m_viewer + glm::mat4 projection = perspective(45.0f, (float)_scnctx.width / (float)_scnctx.height, 0.1f, 1000.0f); + + + _scnctx.camPos = eye; + _scnctx.viewMatrix = view; + _scnctx.projectionMatrix = projection; + + glClearColor(_scnctx.bg.r, _scnctx.bg.g, _scnctx.bg.b, _scnctx.bg.a); + glViewport(0, 0, _scnctx.width, _scnctx.height); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + _multipassManager.enableFrameBufferTexture(_scnctx.fboDisplayName); + + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + for (auto it = meshes.begin(); it != meshes.end(); it++) + (*it).second->draw(_scnctx); + + glDisable(GL_CULL_FACE); + _multipassManager.drawDeferredLightToScreen(_scnctx); +} + +void MyGlWindow::drawDebugGBuffer() { + if (_scnctx.firstRedraw) + _multipassManager.gBufferSetup(_scnctx); + _scnctx.height = m_height; _scnctx.width = m_width; @@ -177,23 +211,23 @@ void MyGlWindow::draw() glm::mat4 view = lookAt(eye, look, up); //Calculate view matrix from parameters of m_viewer glm::mat4 projection = perspective(45.0f, (float)_scnctx.width / (float)_scnctx.height, 0.1f, 1000.0f); + _scnctx.camPos = eye; _scnctx.viewMatrix = view; _scnctx.projectionMatrix = projection; glClearColor(_scnctx.bg.r, _scnctx.bg.g, _scnctx.bg.b, _scnctx.bg.a); glViewport(0, 0, _scnctx.width, _scnctx.height); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - _multipassManager.enableFrameBufferTexture(_scnctx.fbo_display_name); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + _multipassManager.enableFrameBufferTexture(_scnctx.fboDisplayName); glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); + glCullFace(GL_BACK); for (auto it = meshes.begin(); it != meshes.end(); it++) - (*it).second->draw(_scnctx); - + (*it).second->draw(_scnctx); + glDisable(GL_CULL_FACE); - _multipassManager.drawResultToScreen(_scnctx); - + _multipassManager.drawGBufferToScreen(_scnctx); } diff --git a/BaseGLProject/MyGLWindow.h b/BaseGLProject/MyGLWindow.h index 110e0f0..e8d981f 100644 --- a/BaseGLProject/MyGLWindow.h +++ b/BaseGLProject/MyGLWindow.h @@ -22,7 +22,7 @@ class MyGlWindow { public: MyGlWindow(int w, int h); ~MyGlWindow(); - + void draw(); void setBgColor(float bgColor[3]); @@ -43,10 +43,10 @@ private: GLuint _vaoHandle; GLuint _iboHandle; - + + void drawDebugGBuffer(); + void drawDeferredLight(); void textureSetup(); - void shaderSetup(); - void lightSetup(); void multipassSetup(); void setup(); }; \ No newline at end of file diff --git a/BaseGLProject/SceneContext.h b/BaseGLProject/SceneContext.h index 775d24b..c637e45 100644 --- a/BaseGLProject/SceneContext.h +++ b/BaseGLProject/SceneContext.h @@ -6,6 +6,12 @@ #include "Texture.h" #include "Light.h" +enum RenderMode +{ + GBUF_DEBUG, + DEFERRED_LIGHT +}; + struct SceneContext { std::map lights; @@ -19,7 +25,7 @@ struct SceneContext glm::mat4x4 modelMatrix; glm::mat3x3 normalMatrix; - GLuint skybox_tex; + GLuint skyboxTex; std::map textures; @@ -27,7 +33,11 @@ struct SceneContext GLuint width; glm::vec4 bg; - std::string fbo_display_name; + std::string fboDisplayName; + glm::vec3 camPos; + + RenderMode renderMode; + bool firstRedraw; void adjustSpots() { diff --git a/BaseGLProject/Source.cpp b/BaseGLProject/Source.cpp index 72a030f..24d9a22 100644 --- a/BaseGLProject/Source.cpp +++ b/BaseGLProject/Source.cpp @@ -169,8 +169,11 @@ int loop(GLFWwindow *window) int fps = 60; double previousTime = glfwGetTime(); - glWin._scnctx.fbo_display_name = "position_buffer"; - bool is_selected = false; + glWin._scnctx.fboDisplayName = "position_buffer"; + bool is_selected = false; + + glWin._scnctx.renderMode = GBUF_DEBUG; + glWin._scnctx.firstRedraw = true; while (!glfwWindowShouldClose(window)) { @@ -180,14 +183,31 @@ int loop(GLFWwindow *window) if (ImGui::Begin("Scene settings")) { - if (ImGui::BeginCombo("Debug Buffer", "Choose here")) + if (ImGui::BeginCombo("Debug Buffer", glWin._scnctx.fboDisplayName.c_str())) { if (ImGui::Selectable("Position buffer", &is_selected, 0, ImVec2(120, 10))) - glWin._scnctx.fbo_display_name = "position_buffer"; + glWin._scnctx.fboDisplayName = "position_buffer"; if (ImGui::Selectable("Normal buffer", &is_selected, 0, ImVec2(120, 10))) - glWin._scnctx.fbo_display_name = "normal_buffer"; + glWin._scnctx.fboDisplayName = "normal_buffer"; if (ImGui::Selectable("Color buffer", &is_selected, 0, ImVec2(120, 10))) - glWin._scnctx.fbo_display_name = "color_buffer"; + glWin._scnctx.fboDisplayName = "color_buffer"; + + ImGui::EndCombo(); + } + + if (ImGui::BeginCombo("Render Mode", + (glWin._scnctx.renderMode == DEFERRED_LIGHT)? "Deferred Lights" : "Debug GBuffers")) + { + if (ImGui::Selectable("Draw Debug GBuffers", &is_selected, 0, ImVec2(120, 10))) + { + glWin._scnctx.renderMode = GBUF_DEBUG; + glWin._scnctx.firstRedraw = true; + } + if (ImGui::Selectable("Draw with Deferred Lights", &is_selected, 0, ImVec2(120, 10))) + { + glWin._scnctx.renderMode = DEFERRED_LIGHT; + glWin._scnctx.firstRedraw = true; + } ImGui::EndCombo(); } @@ -196,6 +216,8 @@ int loop(GLFWwindow *window) } ImGui::End(); + + double currentTime = glfwGetTime(); frameCount++; // If a second has passed. @@ -208,16 +230,14 @@ int loop(GLFWwindow *window) if (ImGui::Begin("FPSCounter", false, - ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoFocusOnAppearing)) - { - ImGui::TextColored(ImVec4(1, 1, 0, 1), std::to_string(fps).c_str()); - - } + ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoFocusOnAppearing)) + ImGui::TextColored(ImVec4(1, 1, 0, 1), std::to_string(fps).c_str()); ImGui::End(); + ImGui::SetWindowPos("FPSCounter", ImVec2(width - 50, 20), ImGuiCond_Once); - glfwSwapBuffers(window); - glWin.draw(); + glfwSwapBuffers(window); + glWin.draw(); ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); @@ -237,9 +257,6 @@ int loop(GLFWwindow *window) return 0; } - -// upload to padlet.com/mksung89/cameraControl2 - int main() { GLFWwindow *win;