#include "main.h" #include "io.h" // ImGui includes #include "imgui/imgui.h" #include "imgui/imgui_impl_glfw.h" #include "imgui/imgui_impl_opengl3.h" const char FRAGMENT_SHADER_SOURCE[] = "./source/shader/fragment.glsl"; const char VERTEX_SHADER_SOURCE[] = "./source/shader/vertex.glsl"; const char PROGRAM_NAME[] = "OpenGL Template"; const unsigned int SCR_WIDTH = 1920; const unsigned int SCR_HEIGHT = 1080; const char *glsl_version; GLFWwindow *window; unsigned int VBO, VAO; unsigned int shader; __attribute__((constructor)) static void init_glfw(void) { if (!glfwInit()) { fprintf(stderr, "GLFW initialization failed\n"); abort(); // program cannot continue } #ifdef __APPLE__ glsl_version = "#version 330"; glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac #else glsl_version = "#version 130"; #endif glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, PROGRAM_NAME, NULL, NULL); if (window == NULL) { glfwTerminate(); fprintf(stderr, "Failed to create GLFW window\n"); abort(); // program cannot continue } glfwMakeContextCurrent(window); glfwSwapInterval(1); // Enable vsync if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cout << "Failed to initialize GLAD" << std::endl; glfwTerminate(); } glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glGenVertexArrays(1, &VAO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0); char *vertex_shader_source = read_file(VERTEX_SHADER_SOURCE); char *fragment_shader_source = read_file(FRAGMENT_SHADER_SOURCE); unsigned int vertex_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL); glCompileShader(vertex_shader); unsigned int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL); glCompileShader(fragment_shader); shader = glCreateProgram(); glAttachShader(shader, vertex_shader); glAttachShader(shader, fragment_shader); glLinkProgram(shader); glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); free(vertex_shader_source); free(fragment_shader_source); } __attribute__((destructor)) static void shutdown_glfw(void) { glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glfwDestroyWindow(window); glfwTerminate(); } static inline void init_imgui() { IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGui::StyleColorsDark(); ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplOpenGL3_Init(glsl_version); } int main() { #ifndef NDEBUG init_imgui(); #endif while (!glfwWindowShouldClose(window)) { // Poll events glfwPollEvents(); #ifndef NDEBUG if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { glfwSetWindowShouldClose(window, true); } // Start ImGui frame ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); // Create ImGui window ImGui::Begin("Debug"); ImGui::Text("FPS: %.1f", static_cast(ImGui::GetIO().Framerate)); ImGui::End(); #endif // Render glClearColor(0.03f, 0.03f, 0.03f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); #ifndef NDEBUG // Render ImGui ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); #endif // Swap buffers glfwSwapBuffers(window); } return 0; }