From f3303fa84f7920b28ef5c983ee2a20745653fc98 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 5 Jul 2015 22:03:46 -0600 Subject: [PATCH] AA branch: io.RenderDrawListsFn signature changed to take ImDrawData, neater and future proof breaking of the render API (#133 #254) --- .../directx11_example/imgui_impl_dx11.cpp | 10 ++++---- examples/directx9_example/imgui_impl_dx9.cpp | 24 ++++++------------- .../opengl3_example/imgui_impl_glfw_gl3.cpp | 18 +++++--------- examples/opengl_example/imgui_impl_glfw.cpp | 9 +++---- imgui.cpp | 10 +++++++- imgui.h | 14 +++++++++-- 6 files changed, 42 insertions(+), 43 deletions(-) diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 82657f7f..9d7dc189 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -40,7 +40,7 @@ struct VERTEX_CONSTANT_BUFFER // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) // If text or lines are blurry when integrating ImGui in your engine: // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) -static void ImGui_ImplDX11_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) +static void ImGui_ImplDX11_RenderDrawLists(ImDrawData* draw_data) { // Copy and convert all vertices into a single contiguous buffer D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource; @@ -50,9 +50,9 @@ static void ImGui_ImplDX11_RenderDrawLists(ImDrawList** const cmd_lists, int cmd return; ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData; ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData; - for (int n = 0; n < cmd_lists_count; n++) + for (int n = 0; n < draw_data->cmd_lists_count; n++) { - const ImDrawList* cmd_list = cmd_lists[n]; + const ImDrawList* cmd_list = draw_data->cmd_lists[n]; memcpy(vtx_dst, &cmd_list->vtx_buffer[0], cmd_list->vtx_buffer.size() * sizeof(ImDrawVert)); memcpy(idx_dst, &cmd_list->idx_buffer[0], cmd_list->idx_buffer.size() * sizeof(ImDrawIdx)); vtx_dst += cmd_list->vtx_buffer.size(); @@ -116,9 +116,9 @@ static void ImGui_ImplDX11_RenderDrawLists(ImDrawList** const cmd_lists, int cmd // Render command lists int vtx_offset = 0; int idx_offset = 0; - for (int n = 0; n < cmd_lists_count; n++) + for (int n = 0; n < draw_data->cmd_lists_count; n++) { - const ImDrawList* cmd_list = cmd_lists[n]; + const ImDrawList* cmd_list = draw_data->cmd_lists[n]; for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++) { const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i]; diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 82e29047..56e155a1 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -30,28 +30,18 @@ struct CUSTOMVERTEX // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) // If text or lines are blurry when integrating ImGui in your engine: // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) -static void ImGui_ImplDX9_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) +static void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data) { - size_t total_vtx_count = 0; - size_t total_idx_count = 0; - for (int n = 0; n < cmd_lists_count; n++) - { - total_vtx_count += cmd_lists[n]->vtx_buffer.size(); - total_idx_count += cmd_lists[n]->idx_buffer.size(); - } - if (total_vtx_count == 0) - return; - // Copy and convert all vertices into a single contiguous buffer CUSTOMVERTEX* vtx_dst; ImDrawIdx* idx_dst; - if (g_pVB->Lock(0, (UINT)(total_vtx_count * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0) + if (g_pVB->Lock(0, (UINT)(draw_data->total_vtx_count * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0) return; - if (g_pIB->Lock(0, (UINT)(total_idx_count * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0) + if (g_pIB->Lock(0, (UINT)(draw_data->total_idx_count * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0) return; - for (int n = 0; n < cmd_lists_count; n++) + for (int n = 0; n < draw_data->cmd_lists_count; n++) { - const ImDrawList* cmd_list = cmd_lists[n]; + const ImDrawList* cmd_list = draw_data->cmd_lists[n]; const ImDrawVert* vtx_src = &cmd_list->vtx_buffer[0]; for (size_t i = 0; i < cmd_list->vtx_buffer.size(); i++) { @@ -104,9 +94,9 @@ static void ImGui_ImplDX9_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_ // Render command lists int vtx_offset = 0; int idx_offset = 0; - for (int n = 0; n < cmd_lists_count; n++) + for (int n = 0; n < draw_data->cmd_lists_count; n++) { - const ImDrawList* cmd_list = cmd_lists[n]; + const ImDrawList* cmd_list = draw_data->cmd_lists[n]; for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++) { const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i]; diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 5483d513..631de266 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -29,11 +29,8 @@ static unsigned int g_VboHandle = 0, g_VaoHandle = 0; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) // If text or lines are blurry when integrating ImGui in your engine: // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) -static void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) +static void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) { - if (cmd_lists_count == 0) - return; - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled GLint last_program, last_texture; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); @@ -61,11 +58,8 @@ static void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawList** const cmd_lists, int glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); // Grow our buffer according to what we need - size_t total_vtx_count = 0; - for (int n = 0; n < cmd_lists_count; n++) - total_vtx_count += cmd_lists[n]->vtx_buffer.size(); glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); - size_t needed_vtx_size = total_vtx_count * sizeof(ImDrawVert); + size_t needed_vtx_size = draw_data->total_vtx_count * sizeof(ImDrawVert); if (g_VboSize < needed_vtx_size) { g_VboSize = needed_vtx_size + 5000 * sizeof(ImDrawVert); // Grow buffer @@ -76,9 +70,9 @@ static void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawList** const cmd_lists, int unsigned char* vtx_data = (unsigned char*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); if (!vtx_data) return; - for (int n = 0; n < cmd_lists_count; n++) + for (int n = 0; n < draw_data->cmd_lists_count; n++) { - const ImDrawList* cmd_list = cmd_lists[n]; + const ImDrawList* cmd_list = draw_data->cmd_lists[n]; memcpy(vtx_data, &cmd_list->vtx_buffer[0], cmd_list->vtx_buffer.size() * sizeof(ImDrawVert)); vtx_data += cmd_list->vtx_buffer.size() * sizeof(ImDrawVert); } @@ -87,9 +81,9 @@ static void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawList** const cmd_lists, int glBindVertexArray(g_VaoHandle); int vtx_offset = 0; - for (int n = 0; n < cmd_lists_count; n++) + for (int n = 0; n < draw_data->cmd_lists_count; n++) { - const ImDrawList* cmd_list = cmd_lists[n]; + const ImDrawList* cmd_list = draw_data->cmd_lists[n]; const ImDrawIdx* idx_buffer = (const unsigned short*)&cmd_list->idx_buffer.front(); const ImDrawCmd* pcmd_end = cmd_list->commands.end(); diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp index 0b57536e..ee4d7a7d 100644 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ b/examples/opengl_example/imgui_impl_glfw.cpp @@ -23,11 +23,8 @@ static GLuint g_FontTexture = 0; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) // If text or lines are blurry when integrating ImGui in your engine: // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) -static void ImGui_ImplGlfw_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) +static void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) { - if (cmd_lists_count == 0) - return; - // We are using the OpenGL fixed pipeline to make the example code simpler to read! // A probable faster way to render would be to collate all vertices from all cmd_lists into a single vertex buffer. // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. @@ -56,9 +53,9 @@ static void ImGui_ImplGlfw_RenderDrawLists(ImDrawList** const cmd_lists, int cmd // Render command lists #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < cmd_lists_count; n++) + for (int n = 0; n < draw_data->cmd_lists_count; n++) { - const ImDrawList* cmd_list = cmd_lists[n]; + const ImDrawList* cmd_list = draw_data->cmd_lists[n]; const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->vtx_buffer.front(); const ImDrawIdx* idx_buffer = (const unsigned short*)&cmd_list->idx_buffer.front(); glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); diff --git a/imgui.cpp b/imgui.cpp index 87e9ebc8..d13c8ff7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -141,6 +141,7 @@ Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix. Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. + - 2015/07/05 (1.42) - io.RenderDrawListsFn signature changed from RenderDrawListsFn(ImDrawList** const cmd_lists, int cmd_lists_count) to RenderDrawListsFn(ImDrawData*). ImDrawData structure contains 'cmd_lists', 'cmd_lists_count' and more. - 2015/07/02 (1.42) - renamed SetScrollPosHere() to SetScrollFromCursorPos(). Kept inline redirection function (will obsolete). - 2015/07/02 (1.42) - renamed GetScrollPosY() to GetScrollY(). Necessary to reduce confusion along with other scrolling functions, because positions (e.g. cursor position) are not equivalent to scrolling amount. - 2015/06/14 (1.41) - changed ImageButton() default bg_col parameter from (0,0,0,1) (black) to (0,0,0,0) (transparent) - makes a difference when texture have transparence @@ -2509,7 +2510,14 @@ void ImGui::Render() // Render if (!g.RenderDrawLists[0].empty()) - g.IO.RenderDrawListsFn(&g.RenderDrawLists[0][0], (int)g.RenderDrawLists[0].size()); + { + ImDrawData data; + data.cmd_lists = &g.RenderDrawLists[0][0]; + data.cmd_lists_count = (int)g.RenderDrawLists[0].size(); + data.total_vtx_count = g.IO.MetricsRenderVertices; + data.total_idx_count = g.IO.MetricsRenderIndices; + g.IO.RenderDrawListsFn(&data); + } } } diff --git a/imgui.h b/imgui.h index 5d9d2b33..19f3f499 100644 --- a/imgui.h +++ b/imgui.h @@ -31,6 +31,7 @@ // Forward declarations struct ImDrawCmd; struct ImDrawList; +struct ImDrawData; struct ImFont; struct ImFontAtlas; struct ImGuiIO; @@ -670,7 +671,7 @@ struct ImGuiIO // REQUIRED: rendering function. // See example code if you are unsure of how to implement this. - void (*RenderDrawListsFn)(ImDrawList** const draw_lists, int count); + void (*RenderDrawListsFn)(ImDrawData* data); // Optional: access OS clipboard // (default to use native Win32 clipboard on Windows, otherwise uses a private clipboard. Override to access OS clipboard on other architectures) @@ -981,7 +982,7 @@ struct ImGuiListClipper //----------------------------------------------------------------------------- // Draw List -// Hold a series of drawing commands. The user provides a renderer for ImDrawList. +// Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList. //----------------------------------------------------------------------------- // Draw callbacks for advanced uses. @@ -1087,6 +1088,15 @@ struct ImDrawList IMGUI_API void UpdateTextureID(); }; +// All draw data to render an ImGui frame +struct ImDrawData +{ + ImDrawList** cmd_lists; + int cmd_lists_count; + int total_vtx_count; // For convenience, sum of all cmd_lists vtx_buffer.size() + int total_idx_count; // For convenience, sum of all cmd_lists idx_buffer.size() +}; + // Load and rasterize multiple TTF fonts into a same texture. // Sharing a texture for multiple fonts allows us to reduce the number of draw calls during rendering. // We also add custom graphic data into the texture that serves for ImGui.