diff --git a/src/frontend-common/imgui_impl_opengl3.cpp b/src/frontend-common/imgui_impl_opengl3.cpp index 165e7ca9c..403f77331 100644 --- a/src/frontend-common/imgui_impl_opengl3.cpp +++ b/src/frontend-common/imgui_impl_opengl3.cpp @@ -88,7 +88,7 @@ static GLuint g_FontTexture = 0; static GLuint g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; // Uniforms location static int g_AttribLocationVtxPos = 0, g_AttribLocationVtxUV = 0, g_AttribLocationVtxColor = 0; // Vertex attributes location -static unsigned int g_VboHandle = 0, g_ElementsHandle = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0; static bool g_IsGLES = false; // Forward Declarations @@ -148,7 +148,7 @@ void ImGui_ImplOpenGL3_NewFrame() ImGui_ImplOpenGL3_CreateDeviceObjects(); } -static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object) +static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height) { // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill glEnable(GL_BLEND); @@ -183,20 +183,9 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise. #endif - (void)vertex_array_object; -#ifndef IMGUI_IMPL_OPENGL_ES2 - glBindVertexArray(vertex_array_object); -#endif - - // Bind vertex/index buffers and setup attributes for ImDrawVert + glBindVertexArray(g_VaoHandle); glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle); - glEnableVertexAttribArray(g_AttribLocationVtxPos); - glEnableVertexAttribArray(g_AttribLocationVtxUV); - glEnableVertexAttribArray(g_AttribLocationVtxColor); - glVertexAttribPointer(g_AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)); - glVertexAttribPointer(g_AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)); - glVertexAttribPointer(g_AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)); } // OpenGL3 Render function. @@ -210,54 +199,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) if (fb_width <= 0 || fb_height <= 0) return; - // Backup GL state - GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture); - glActiveTexture(GL_TEXTURE0); - GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); -#ifdef GL_SAMPLER_BINDING - GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler); -#endif - GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); -#ifndef IMGUI_IMPL_OPENGL_ES2 - GLint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array_object); -#endif -#ifdef GL_POLYGON_MODE - GLint last_polygon_mode[2]; - if (!g_IsGLES) - glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); -#endif - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); - GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb); - GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb); - GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha); - GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha); - GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb); - GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha); - GLboolean last_enable_blend = glIsEnabled(GL_BLEND); - GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); - GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); - GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); - bool clip_origin_lower_left = true; -#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__) - GLenum last_clip_origin = 0; - if (!g_IsGLES) - { - glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&last_clip_origin); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT) - if (last_clip_origin == GL_UPPER_LEFT) - clip_origin_lower_left = false; - } -#endif - - // Setup desired GL state - // Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts) - // The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound. - GLuint vertex_array_object = 0; -#ifndef IMGUI_IMPL_OPENGL_ES2 - glGenVertexArrays(1, &vertex_array_object); -#endif - ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object); + ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height); // Will project scissor/clipping rectangles into framebuffer space ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports @@ -279,7 +221,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) // User callback, registered via ImDrawList::AddCallback() // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) - ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object); + ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height); else pcmd->UserCallback(cmd_list, pcmd); } @@ -295,10 +237,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) { // Apply scissor/clipping rectangle - if (clip_origin_lower_left) - glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); - else - glScissor((int)clip_rect.x, (int)clip_rect.y, (int)clip_rect.z, (int)clip_rect.w); // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT) + glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); // Bind texture, Draw glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); @@ -311,33 +250,6 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) } } } - - // Destroy the temporary VAO -#ifndef IMGUI_IMPL_OPENGL_ES2 - glDeleteVertexArrays(1, &vertex_array_object); -#endif - - // Restore modified GL state - glUseProgram(last_program); - glBindTexture(GL_TEXTURE_2D, last_texture); - glActiveTexture(last_active_texture); -#ifndef IMGUI_IMPL_OPENGL_ES2 - glBindSampler(0, last_sampler); - glBindVertexArray(last_vertex_array_object); -#endif - glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); - glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); - glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha); - if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); - if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); - if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); - if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); -#ifdef GL_POLYGON_MODE - if (!g_IsGLES) - glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); -#endif - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); - glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); } bool ImGui_ImplOpenGL3_CreateFontsTexture() @@ -584,6 +496,22 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects() glGenBuffers(1, &g_VboHandle); glGenBuffers(1, &g_ElementsHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glBufferData(GL_ARRAY_BUFFER, sizeof(ImDrawVert), nullptr, GL_STREAM_DRAW); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + + glEnableVertexAttribArray(g_AttribLocationVtxPos); + glEnableVertexAttribArray(g_AttribLocationVtxUV); + glEnableVertexAttribArray(g_AttribLocationVtxColor); + glVertexAttribPointer(g_AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), + (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), + (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), + (GLvoid*)IM_OFFSETOF(ImDrawVert, col)); + ImGui_ImplOpenGL3_CreateFontsTexture(); // Restore modified GL state @@ -598,6 +526,7 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects() void ImGui_ImplOpenGL3_DestroyDeviceObjects() { + if (g_VaoHandle) { glDeleteVertexArrays(1, &g_VaoHandle); g_VaoHandle = 0; } if (g_VboHandle) { glDeleteBuffers(1, &g_VboHandle); g_VboHandle = 0; } if (g_ElementsHandle) { glDeleteBuffers(1, &g_ElementsHandle); g_ElementsHandle = 0; } if (g_ShaderHandle && g_VertHandle) { glDetachShader(g_ShaderHandle, g_VertHandle); }