| @ -0,0 +1,147 @@ | |||
| #include <memory> | |||
| #include <iostream> | |||
| #include <cstdlib> | |||
| #include <imgui.h> | |||
| #include <imgui_impl_glfw_gl3.h> | |||
| #include <GL/gl3w.h> | |||
| #include <GLFW/glfw3.h> | |||
| #include "gui.h" | |||
| #include "state.h" | |||
| #define CLEAR_COLOR 0.0, 0.0, 0.0, 1.0 | |||
| static void glfw_error_callback(int error, const char* description) { | |||
| std::cerr << "GLFW error " << error << " " << description << '\n'; | |||
| } | |||
| // static void glfw_key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) { | |||
| // if (key == GLFW_KEY_R && mods == GLFW_MOD_CONTROL && action == GLFW_PRESS) { | |||
| // printf("...\n"); | |||
| // } | |||
| // } | |||
| int main(int argc, char* argv[]) { | |||
| glfwSetErrorCallback(glfw_error_callback); | |||
| if (!glfwInit()){ | |||
| // glfw init failed; crash out | |||
| std::clog << "GLFW: init failed; exiting.\n"; | |||
| std::exit(-1); | |||
| } | |||
| // request at least OpenGL v3.3 | |||
| glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); | |||
| glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); | |||
| glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); | |||
| glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); | |||
| glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, 1); | |||
| auto window = glfwCreateWindow(1024, 768, "Zinnia", NULL, NULL); | |||
| if (!window) { | |||
| // window creation failed | |||
| glfwTerminate(); | |||
| std::clog << "GLFW: failed to create window; exiting.\n"; | |||
| return EXIT_FAILURE; | |||
| } | |||
| glfwMakeContextCurrent(window); | |||
| glfwSwapInterval(1); | |||
| if (gl3wInit()) { | |||
| std::clog << "Failed to initialize OpenGL\n"; | |||
| return EXIT_FAILURE; | |||
| } | |||
| std::cout << "[GL] OpenGL v" << glGetString(GL_VERSION) | |||
| << ", GLSL v" << glGetString(GL_SHADING_LANGUAGE_VERSION) << '\n'; | |||
| ImGui_ImplGlfwGL3_Init(window, true); | |||
| // demo state | |||
| auto config = Config::from_file("../config.toml"); | |||
| auto state = DemoState(std::make_shared<Config>(config)); | |||
| // set up a GUI state | |||
| auto gui = Gui(&state); | |||
| if (argc == 2) { | |||
| auto proj = Project::fromFile(std::string(argv[1])); | |||
| state.current_project = std::move(proj); | |||
| } | |||
| const GLfloat v_quad[][2] = { | |||
| {1, 1}, {1, -1}, {-1, -1}, {-1, 1}, | |||
| }; | |||
| const GLuint i_quad[] = { | |||
| 0, 1, 3, | |||
| 1, 2, 3, | |||
| }; | |||
| GLuint vao, vbo, ebo; | |||
| glGenVertexArrays(1, &vao); | |||
| glGenBuffers(1, &ebo); | |||
| glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); | |||
| glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(i_quad), i_quad, GL_STATIC_DRAW); | |||
| glBindVertexArray(vao); | |||
| glGenBuffers(1, &vbo); | |||
| glBindBuffer(GL_ARRAY_BUFFER, vbo); | |||
| glBufferData(GL_ARRAY_BUFFER, sizeof(v_quad), v_quad, GL_STATIC_DRAW); | |||
| glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); | |||
| glEnableVertexAttribArray(0); | |||
| glBindVertexArray(0); | |||
| double t, t_prev, dt; | |||
| glfwSetTime(0); t_prev = glfwGetTime(); | |||
| while(!glfwWindowShouldClose(window) && state.running) { | |||
| t = glfwGetTime(); | |||
| dt = t - t_prev; t_prev = t; | |||
| glfwPollEvents(); | |||
| ImGui_ImplGlfwGL3_NewFrame(); | |||
| glfwGetFramebufferSize(window, &state.width, &state.height); | |||
| state.ratio = (float)state.width / (float)state.height; | |||
| glViewport(0, 0, (float)state.width, (float)state.height); | |||
| glClearColor(CLEAR_COLOR); | |||
| glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); | |||
| if (state.current_project != nullptr) { | |||
| if (state.current_project->scene_loaded) { | |||
| auto prog = *state.current_project->current_scene->shader_p; | |||
| auto u_resolution = glGetUniformLocation(prog, "u_Resolution"); | |||
| auto u_mouse = glGetUniformLocation(prog, "u_Mouse"); | |||
| auto u_time = glGetUniformLocation(prog, "u_Time"); | |||
| double m_x, m_y; | |||
| glfwGetCursorPos(window, &m_x, &m_y); | |||
| glUseProgram(prog); | |||
| glUniform2f(u_resolution, (float)state.width, (float)state.height); | |||
| glUniform4f(u_mouse, m_x, m_y, 0., 0.); | |||
| glUniform1f(u_time, t); | |||
| glBindVertexArray(vao); | |||
| glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); | |||
| glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); | |||
| glBindVertexArray(0); | |||
| } | |||
| } | |||
| gui.render(); | |||
| ImGui::Render(); | |||
| glfwSwapBuffers(window); | |||
| std::cout << std::flush; | |||
| std::cerr << std::flush; | |||
| } | |||
| ImGui_ImplGlfwGL3_Shutdown(); | |||
| glfwDestroyWindow(window); | |||
| glfwTerminate(); | |||
| return 0; | |||
| } | |||