#include #include #include #include "imgui/imgui.h" #include "imgui/imgui_impl_glfw.h" #include "imgui/imgui_impl_opengl3.h" #include "MyGLWindow.h" bool lbutton_down; bool rbutton_down; bool mbutton_down; double m_lastMouseX; double m_lastMouseY; double cx, cy; int g_width; int g_height; bool reset = false; void window_size_callback(GLFWwindow* window, int width, int height) { g_width = width; g_height = height; } static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GLFW_TRUE); if (key == GLFW_KEY_R && action == GLFW_PRESS) reset = true; } static void cursor_pos_callback(GLFWwindow* window, double xpos, double ypos) { cx = xpos; cy = ypos; } void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) { if (action == GLFW_PRESS) { double xpos, ypos; glfwGetCursorPos(window, &xpos, &ypos); m_lastMouseX = xpos; m_lastMouseY = ypos; } if (button == GLFW_MOUSE_BUTTON_LEFT) { if (GLFW_PRESS == action) lbutton_down = true; else if (GLFW_RELEASE == action) lbutton_down = false; } else if (button == GLFW_MOUSE_BUTTON_RIGHT) { if (GLFW_PRESS == action) rbutton_down = true; else if (GLFW_RELEASE == action) rbutton_down = false; } else if (button == GLFW_MOUSE_BUTTON_MIDDLE) { if (GLFW_PRESS == action) mbutton_down = true; else if (GLFW_RELEASE == action) mbutton_down = false; } } void mouseDragging(double width, double height, MyGlWindow &win) { ImGuiIO& io = ImGui::GetIO(); if (!io.WantCaptureMouse) { if (lbutton_down) { float fractionChangeX = static_cast(cx - m_lastMouseX) / static_cast(width); float fractionChangeY = static_cast(m_lastMouseY - cy) / static_cast(height); win.viewer.rotate(fractionChangeX, fractionChangeY); } else if (mbutton_down) { float fractionChangeX = static_cast(cx - m_lastMouseX) / static_cast(width); float fractionChangeY = static_cast(m_lastMouseY - cy) / static_cast(height); win.viewer.zoom(fractionChangeY); } else if (rbutton_down) { float fractionChangeX = static_cast(cx - m_lastMouseX) / static_cast(width); float fractionChangeY = static_cast(m_lastMouseY - cy) / static_cast(height); win.viewer.translate(-fractionChangeX, -fractionChangeY, 1); } m_lastMouseX = cx; m_lastMouseY = cy; } } bool initGLFW() { if (!glfwInit()) { // Windows error box return false; } glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); return true; } void initImgui(GLFWwindow **window) { IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; const char* glsl_version = "#version 430"; ImGui_ImplGlfw_InitForOpenGL(*window, true); ImGui_ImplOpenGL3_Init(glsl_version); ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); //ImGui::StyleColorsLight(); } bool createWindow(GLFWwindow **window) { int width = 1080; int height = 1080; g_width = 1080; g_height = 1080; /* Create a windowed mode window and its OpenGL context */ (*window) = glfwCreateWindow(width, height, "OpenGL FrameWork", NULL, NULL); if (!(*window)) { // Windows error box glfwTerminate(); return false; } initImgui(window); glfwMakeContextCurrent((*window)); /* Make the window's context current */ glewExperimental = GL_TRUE; GLenum err = glewInit(); if (err != GLEW_OK) { // Windows error box //Problem: glewInit failed, something is seriously wrong. return false; } glfwSetKeyCallback((*window), key_callback); return true; } void FPSDisplay(int width) { static int frameCount = 0; static int fps = 60; static double previousTime = glfwGetTime(); double currentTime = glfwGetTime(); frameCount++; // If a second has passed. if (currentTime - previousTime >= 1.0) { fps = frameCount; frameCount = 0; previousTime = currentTime; } if (ImGui::Begin("FPSCounterOutline1", false, ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoFocusOnAppearing)) ImGui::TextColored(ImVec4(0, 0, 0, 1), std::to_string(fps).c_str()); ImGui::End(); if (ImGui::Begin("FPSCounterOutline2", false, ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoFocusOnAppearing)) ImGui::TextColored(ImVec4(0, 0, 0, 1), std::to_string(fps).c_str()); ImGui::End(); if (ImGui::Begin("FPSCounterOutline3", false, ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoFocusOnAppearing)) ImGui::TextColored(ImVec4(0, 0, 0, 1), std::to_string(fps).c_str()); ImGui::End(); if (ImGui::Begin("FPSCounterOutline4", false, ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoFocusOnAppearing)) ImGui::TextColored(ImVec4(0, 0, 0, 1), std::to_string(fps).c_str()); ImGui::End(); if (ImGui::Begin("FPSCounter", false, ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoFocusOnAppearing)) ImGui::TextColored(ImVec4(1, 1, 1, 1), std::to_string(fps).c_str()); ImGui::End(); ImGui::SetWindowPos("FPSCounterOutline1", ImVec2(width - 49.f, 20.f), ImGuiCond_Once); ImGui::SetWindowPos("FPSCounterOutline2", ImVec2(width - 51.f, 20.f), ImGuiCond_Once); ImGui::SetWindowPos("FPSCounterOutline3", ImVec2(width - 50.f, 19.f), ImGuiCond_Once); ImGui::SetWindowPos("FPSCounterOutline4", ImVec2(width - 50.f, 21.f), ImGuiCond_Once); ImGui::SetWindowPos("FPSCounter", ImVec2(width - 50.f, 20.f), ImGuiCond_Once); } int loop(GLFWwindow *window) { std::printf("OpenGL %s, GLSL %s\n", glGetString(GL_VERSION), glGetString(GL_SHADING_LANGUAGE_VERSION)); int width; int heigth; glfwGetWindowSize(window, &width, &heigth); MyGlWindow glWin(width, heigth); glWin.scnctx.fboDisplayName = "position_buffer"; bool is_selected = false; glWin.scnctx.renderMode = DEFERRED_LIGHT; glWin.scnctx.firstRedraw = true; std::vector lights_strs; char const **strings = nullptr; int current_light = 0; bool orbiting_lights = true; float light_speed = 50.0f; double prev_time = glfwGetTime(); double sinceLastFrame; while (!glfwWindowShouldClose(window)) { sinceLastFrame = glfwGetTime() - prev_time; prev_time = glfwGetTime(); ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); if (ImGui::Begin("Scene settings")) { if (ImGui::BeginCombo("Debug Buffer", glWin.scnctx.fboDisplayName.c_str())) { if (ImGui::Selectable("Position buffer", &is_selected, 0, ImVec2(120, 10))) glWin.scnctx.fboDisplayName = "position_buffer"; if (ImGui::Selectable("Normal buffer", &is_selected, 0, ImVec2(120, 10))) glWin.scnctx.fboDisplayName = "normal_buffer"; if (ImGui::Selectable("Color buffer", &is_selected, 0, ImVec2(120, 10))) glWin.scnctx.fboDisplayName = "color_buffer"; ImGui::EndCombo(); } if (ImGui::BeginCombo("Render Mode", (glWin.scnctx.renderMode == DEFERRED_LIGHT) ? "Deferred Lights" : ( (glWin.scnctx.renderMode == FORWARD_LIGHT) ? "Forward 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; } if (ImGui::Selectable("Draw with Forward Lights", &is_selected, 0, ImVec2(120, 10))) { glWin.scnctx.renderMode = FORWARD_LIGHT; glWin.scnctx.firstRedraw = true; } ImGui::EndCombo(); } if (ImGui::BeginCombo("Scene Choice", (glWin.scene == MOUNTAIN) ? "Mountain" : (glWin.scene == CUBES) ? "Cubes" : "Teapots")) { if (ImGui::Selectable("Mountain", &is_selected, 0, ImVec2(100, 10))) glWin.loadScene(SceneChoice::MOUNTAIN); if (ImGui::Selectable("Cubes", &is_selected, 0, ImVec2(100, 10))) glWin.loadScene(SceneChoice::CUBES); if (ImGui::Selectable("Teapots", &is_selected, 0, ImVec2(100, 10))) glWin.loadScene(SceneChoice::TEAPOTS); ImGui::EndCombo(); } ImGui::SetWindowPos(ImVec2(20, 20)); } ImGui::End(); if (reset) { glWin.loadScene(SceneChoice::MOUNTAIN); reset = false; } if (ImGui::Begin("Light management")) { lights_strs.clear(); for (auto light : glWin.scnctx.lights) lights_strs.push_back(light.toString()); std::free(strings); strings = (char const **)std::malloc(sizeof(char *) * (lights_strs.size() + 1)); std::memset((void *)strings, 0, sizeof(char *) * (lights_strs.size() + 1)); for (int i = 0; i < lights_strs.size(); i++) strings[i] = lights_strs[i].c_str(); ImGui::ListBox("Lights", ¤t_light, strings, lights_strs.size()); if (glWin.scnctx.lights.size() > 0) { if (ImGui::SliderFloat("Selected light X", &glWin.scnctx.lights[current_light].location.x, -10, 10) && glWin.scnctx.renderMode == DEFERRED_LIGHT) glWin.multipassManager.recomputeDeferredLights(glWin.scnctx); if (ImGui::SliderFloat("Selected light Y", &glWin.scnctx.lights[current_light].location.y, -10, 10) && glWin.scnctx.renderMode == DEFERRED_LIGHT) glWin.multipassManager.recomputeDeferredLights(glWin.scnctx); if (ImGui::SliderFloat("Selected light Z", &glWin.scnctx.lights[current_light].location.z, -10, 10) && glWin.scnctx.renderMode == DEFERRED_LIGHT) glWin.multipassManager.recomputeDeferredLights(glWin.scnctx); if (ImGui::SliderFloat("Selected light R", &glWin.scnctx.lights[current_light].intensity.x, 0, 1) && glWin.scnctx.renderMode == DEFERRED_LIGHT) glWin.multipassManager.recomputeDeferredLights(glWin.scnctx); if (ImGui::SliderFloat("Selected light G", &glWin.scnctx.lights[current_light].intensity.y, 0, 1) && glWin.scnctx.renderMode == DEFERRED_LIGHT) glWin.multipassManager.recomputeDeferredLights(glWin.scnctx); if (ImGui::SliderFloat("Selected light B", &glWin.scnctx.lights[current_light].intensity.z, 0, 1) && glWin.scnctx.renderMode == DEFERRED_LIGHT) glWin.multipassManager.recomputeDeferredLights(glWin.scnctx); } ImGui::Checkbox("Orbit Lights", &orbiting_lights); ImGui::SliderFloat("Orbit degrees / second", &light_speed, 0, 360); } ImGui::End(); FPSDisplay(width); glfwSwapBuffers(window); glWin.draw(); if (orbiting_lights) glWin.orbitLights(sinceLastFrame, light_speed); ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); glfwPollEvents(); mouseDragging(g_width, g_height, glWin); glWin.resize(g_width, g_height); } ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); glfwDestroyWindow(window); glfwTerminate(); return 0; } int main() { GLFWwindow *win; if (!initGLFW() || !createWindow(&win)) return 1; glfwSetWindowSizeCallback(win, window_size_callback); glfwSetMouseButtonCallback(win, mouse_button_callback); glfwSetCursorPosCallback(win, cursor_pos_callback); glfwSetKeyCallback(win, key_callback); glfwSetWindowTitle(win, "Variables d'environnement pour le DLL :,("); return loop(win); }