2019-06-18 11:47:39 +09:00

389 lines
11 KiB
C++

#include <cstdio>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#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<float>(cx - m_lastMouseX) / static_cast<float>(width);
float fractionChangeY = static_cast<float>(m_lastMouseY - cy) / static_cast<float>(height);
win.viewer.rotate(fractionChangeX, fractionChangeY);
}
else if (mbutton_down) {
float fractionChangeX = static_cast<float>(cx - m_lastMouseX) / static_cast<float>(width);
float fractionChangeY = static_cast<float>(m_lastMouseY - cy) / static_cast<float>(height);
win.viewer.zoom(fractionChangeY);
}
else if (rbutton_down) {
float fractionChangeX = static_cast<float>(cx - m_lastMouseX) / static_cast<float>(width);
float fractionChangeY = static_cast<float>(m_lastMouseY - cy) / static_cast<float>(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<std::string> 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", &current_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);
}