From d749d49903fb0eb56b08961d989ed90a9d97c28b Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 23 Feb 2018 12:37:49 +0100 Subject: [PATCH] Examples: OpenGL3: Create the VAO in the render function so the setup can more easily be used with multiple shared GL context. (#1217) --- .../opengl3_example/imgui_impl_glfw_gl3.cpp | 32 ++++++++-------- .../imgui_impl_sdl_gl3.cpp | 38 ++++++++++--------- 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 72cc4bf6..85c76684 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -13,6 +13,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-23: OpenGL: Create the VAO in the render function so the setup can more easily be used with multiple shared GL context. // 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). // 2018-02-20: Inputs: Renamed GLFW callbacks exposed in .h to not include GL3 in their name. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplGlfwGL3_RenderDrawData() in the .h file so you can call it yourself. @@ -54,7 +55,7 @@ static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; -static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0; +static unsigned int g_VboHandle = 0, g_ElementsHandle = 0; // OpenGL3 Render function. // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) @@ -113,9 +114,22 @@ void ImGui_ImplGlfwGL3_RenderDrawData(ImDrawData* draw_data) glUseProgram(g_ShaderHandle); glUniform1i(g_AttribLocationTex, 0); glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); - glBindVertexArray(g_VaoHandle); glBindSampler(0, 0); // Rely on combined texture/sampler state. + // Recreate the VAO every time + // (This is to easily allow multiple GL contexts. VAO are not shared among GL contexts, and we don't track creation/deletion of windows so we don't have an obvious key to use to cache them.) + GLuint vao_handle = 0; + glGenVertexArrays(1, &vao_handle); + glBindVertexArray(vao_handle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)); + + // Draw for (int n = 0; n < draw_data->CmdListsCount; n++) { const ImDrawList* cmd_list = draw_data->CmdLists[n]; @@ -289,17 +303,6 @@ bool ImGui_ImplGlfwGL3_CreateDeviceObjects() glGenBuffers(1, &g_VboHandle); glGenBuffers(1, &g_ElementsHandle); - glGenVertexArrays(1, &g_VaoHandle); - glBindVertexArray(g_VaoHandle); - glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); - glEnableVertexAttribArray(g_AttribLocationPosition); - glEnableVertexAttribArray(g_AttribLocationUV); - glEnableVertexAttribArray(g_AttribLocationColor); - - glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)); - glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)); - glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)); - ImGui_ImplGlfwGL3_CreateFontsTexture(); // Restore modified GL state @@ -312,10 +315,9 @@ bool ImGui_ImplGlfwGL3_CreateDeviceObjects() void ImGui_ImplGlfwGL3_InvalidateDeviceObjects() { - if (g_VaoHandle) glDeleteVertexArrays(1, &g_VaoHandle); if (g_VboHandle) glDeleteBuffers(1, &g_VboHandle); if (g_ElementsHandle) glDeleteBuffers(1, &g_ElementsHandle); - g_VaoHandle = g_VboHandle = g_ElementsHandle = 0; + g_VboHandle = g_ElementsHandle = 0; if (g_ShaderHandle && g_VertHandle) glDetachShader(g_ShaderHandle, g_VertHandle); if (g_VertHandle) glDeleteShader(g_VertHandle); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 4b870ade..2434ceac 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -12,6 +12,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-23: OpenGL: Create the VAO in the render function so the setup can more easily be used with multiple shared GL context. // 2018-02-16: Inputs: Added support for mouse cursors, honoring ImGui::GetMouseCursor() value. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplSdlGL3_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. @@ -38,15 +39,17 @@ #include #include // This example is using gl3w to access OpenGL functions (because it is small). You may use glew/glad/glLoadGen/etc. whatever already works for you. -// Data +// SDL data static Uint64 g_Time = 0; static bool g_MousePressed[3] = { false, false, false }; +static SDL_Cursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 }; + +// OpenGL data static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; -static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0; -static SDL_Cursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 }; +static unsigned int g_VboHandle = 0,g_ElementsHandle = 0; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) // Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. @@ -105,9 +108,22 @@ void ImGui_ImplSdlGL3_RenderDrawData(ImDrawData* draw_data) glUseProgram(g_ShaderHandle); glUniform1i(g_AttribLocationTex, 0); glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); - glBindVertexArray(g_VaoHandle); glBindSampler(0, 0); // Rely on combined texture/sampler state. + // Recreate the VAO every time + // (This is to easily allow multiple GL contexts. VAO are not shared among GL contexts, and we don't track creation/deletion of windows so we don't have an obvious key to use to cache them.) + GLuint vao_handle = 0; + glGenVertexArrays(1, &vao_handle); + glBindVertexArray(vao_handle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)); + + // Draw for (int n = 0; n < draw_data->CmdListsCount; n++) { const ImDrawList* cmd_list = draw_data->CmdLists[n]; @@ -289,17 +305,6 @@ bool ImGui_ImplSdlGL3_CreateDeviceObjects() glGenBuffers(1, &g_VboHandle); glGenBuffers(1, &g_ElementsHandle); - glGenVertexArrays(1, &g_VaoHandle); - glBindVertexArray(g_VaoHandle); - glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); - glEnableVertexAttribArray(g_AttribLocationPosition); - glEnableVertexAttribArray(g_AttribLocationUV); - glEnableVertexAttribArray(g_AttribLocationColor); - - glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)); - glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)); - glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)); - ImGui_ImplSdlGL3_CreateFontsTexture(); // Restore modified GL state @@ -312,10 +317,9 @@ bool ImGui_ImplSdlGL3_CreateDeviceObjects() void ImGui_ImplSdlGL3_InvalidateDeviceObjects() { - if (g_VaoHandle) glDeleteVertexArrays(1, &g_VaoHandle); if (g_VboHandle) glDeleteBuffers(1, &g_VboHandle); if (g_ElementsHandle) glDeleteBuffers(1, &g_ElementsHandle); - g_VaoHandle = g_VboHandle = g_ElementsHandle = 0; + g_VboHandle = g_ElementsHandle = 0; if (g_ShaderHandle && g_VertHandle) glDetachShader(g_ShaderHandle, g_VertHandle); if (g_VertHandle) glDeleteShader(g_VertHandle);