#include #include #include #include #include #include #include "gldebug.hpp" void show_overlay(float* clear_color) { static std::string gl_vendor = (const char *) glGetString(GL_VENDOR); static std::string gl_renderer = (const char *) glGetString(GL_RENDERER); static std::string gl_version = (const char *) glGetString(GL_VERSION); static std::string glsl_version = (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION); ImGuiWindowFlags window_flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoMove; ImGuiStyle &style = ImGui::GetStyle(); const auto PAD = style.DisplaySafeAreaPadding; auto window_pos = PAD; ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always); ImGui::SetNextWindowBgAlpha(0.35f * style.Alpha); ImGui::SetNextWindowCollapsed(true, ImGuiCond_Appearing); ImGui::Begin("Graphics Information", nullptr, window_flags); ImGui::Text("GL Vendor | %s", gl_vendor.c_str()); ImGui::Text("GL Renderer | %s", gl_renderer.c_str()); ImGui::Text("GL Version | %s", gl_version.c_str()); ImGui::Text("GLSL Version | %s", glsl_version.c_str()); auto v2 = ImGui::GetWindowSize(); window_pos.y += v2.y + PAD.y; ImGui::End(); ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always); ImGui::SetNextWindowBgAlpha(0.35f * style.Alpha); ImGui::Begin("Controls", nullptr, window_flags); ImGuiIO &io = ImGui::GetIO(); ImGui::Text("FPS | %.2f", io.Framerate); ImGui::Separator(); ImGui::ColorEdit3("Background", state.bg, ImGuiColorEditFlags_Float); ImGui::SliderFloat("Alpha", &state.fg[3], 0.0f, 1.0f, "%.2f"); ImGui::End(); } void set_style() { ImGui::StyleColorsDark(); ImGuiStyle &style = ImGui::GetStyle(); style.WindowRounding = 4; style.FrameRounding = 2; style.DisplaySafeAreaPadding.x = 10; style.DisplaySafeAreaPadding.y = 10; } int run(GLFWwindow *window, ImGuiContext *context) { State state; float points[]{ +0.5f, +0.5f, 0.0f, 1.0f, +0.5f, -0.5f, 0.0f, 1.0f, -0.5f, +0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.0f, 1.0f, }; unsigned int inds[]{ 0, 1, 2, 1, 2, 3, }; GLuint vao; glCreateVertexArrays(1, &vao); GLuint vbo; glCreateBuffers(1, &vbo); glNamedBufferData(vbo, sizeof(points), (void *) points, GL_STATIC_DRAW); glEnableVertexArrayAttrib(vao, 0); glVertexArrayVertexBuffer(vao, 0, vbo, 0, sizeof(float) * 4); glVertexArrayAttribFormat(vao, 0, 4, GL_FLOAT, GL_FALSE, 0); GLuint ibo; glCreateBuffers(1, &ibo); glGetError(); glNamedBufferData(ibo, sizeof(inds), (void *) inds, GL_STATIC_DRAW); glVertexArrayElementBuffer(vao, ibo); const char *vs_src = "#version 440\n" "layout(location=0) in vec4 pos;" "void main() {" " gl_Position = pos;" "}"; GLuint vs = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vs, 1, &vs_src, nullptr); glCompileShader(vs); const char *fs_src = "#version 440\n" "layout(location=0) uniform vec4 ucol;" "layout(location=0) out vec4 col;" "void main() {" " col = ucol;" "}"; GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fs, 1, &fs_src, nullptr); glCompileShader(fs); GLuint pgm = glCreateProgram(); glAttachShader(pgm, vs); glAttachShader(pgm, fs); glLinkProgram(pgm); while (!glfwWindowShouldClose(window)) { glfwPollEvents(); ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); show_overlay(state); ImGui::Render(); int display_w, display_h; glfwGetFramebufferSize(window, &display_w, &display_h); glViewport(0, 0, display_w, display_h); glClearColor(state.bg[0], state.bg[1], state.bg[2], state.bg[3]); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(pgm); glBindVertexArray(vao); glUniform4fv(0, 1, state.fg); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); glBindVertexArray(0); glUseProgram(0); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); glfwSwapBuffers(window); } glDeleteBuffers(1, &vbo); glDeleteBuffers(1, &ibo); glDeleteVertexArrays(1, &vao); return EXIT_SUCCESS; } int main() { if (!glfwInit()) { std::cerr << "GLFW:Failed initialization" << std::endl; return EXIT_FAILURE; } glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); auto *window = glfwCreateWindow(1280, 720, "Cosets Visualization", nullptr, nullptr); if (!window) { std::cerr << "GLFW:Failed to create window" << std::endl; return EXIT_FAILURE; } glfwMakeContextCurrent(window); glfwSwapInterval(1); gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); #ifndef NDEBUG glEnable(GL_DEBUG_OUTPUT); glDebugMessageCallback(log_gl_debug_callback, nullptr); glDebugMessageControl( GL_DONT_CARE, GL_DEBUG_TYPE_OTHER, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE ); #endif IMGUI_CHECKVERSION(); auto *context = ImGui::CreateContext(); ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplOpenGL3_Init("#version 130"); set_style(); int exit_code = EXIT_SUCCESS; try { exit_code = run(window, context); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; exit_code = EXIT_FAILURE; } ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); glfwDestroyWindow(window); glfwTerminate(); return exit_code; }