#include #include #include #include #include #include #include #include "gui.h" #include "state.h" #include "notify.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)); auto inotify = NotifyService(); // set up a GUI state auto gui = Gui(&state); if (argc == 2) { auto proj = Project::fromFile(std::string(argv[1])); inotify.watch(*proj); 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; unsigned long frame_n = 0; 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); if ((frame_n % 10) == 0) { inotify._poll(); } std::cout << std::flush; std::cerr << std::flush; frame_n++; } ImGui_ImplGlfwGL3_Shutdown(); glfwDestroyWindow(window); glfwTerminate(); return 0; }