AA branch: io.RenderDrawListsFn signature changed to take ImDrawData, neater and future proof breaking of the render API (#133 #254)

This commit is contained in:
ocornut 2015-07-05 22:03:46 -06:00
parent 2633325b9f
commit f3303fa84f
6 changed files with 42 additions and 43 deletions

View File

@ -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) // 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: // 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) // - 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 // Copy and convert all vertices into a single contiguous buffer
D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource; D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource;
@ -50,9 +50,9 @@ static void ImGui_ImplDX11_RenderDrawLists(ImDrawList** const cmd_lists, int cmd
return; return;
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData; ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_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(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)); memcpy(idx_dst, &cmd_list->idx_buffer[0], cmd_list->idx_buffer.size() * sizeof(ImDrawIdx));
vtx_dst += cmd_list->vtx_buffer.size(); 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 // Render command lists
int vtx_offset = 0; int vtx_offset = 0;
int idx_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++) for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i];

View File

@ -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) // 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: // 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) // - 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 // Copy and convert all vertices into a single contiguous buffer
CUSTOMVERTEX* vtx_dst; CUSTOMVERTEX* vtx_dst;
ImDrawIdx* idx_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; 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; 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]; const ImDrawVert* vtx_src = &cmd_list->vtx_buffer[0];
for (size_t i = 0; i < cmd_list->vtx_buffer.size(); i++) 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 // Render command lists
int vtx_offset = 0; int vtx_offset = 0;
int idx_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++) for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i];

View File

@ -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) // 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: // 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) // - 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 // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
GLint last_program, last_texture; GLint last_program, last_texture;
glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); 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]); glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
// Grow our buffer according to what we need // 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); 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) if (g_VboSize < needed_vtx_size)
{ {
g_VboSize = needed_vtx_size + 5000 * sizeof(ImDrawVert); // Grow buffer 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); unsigned char* vtx_data = (unsigned char*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
if (!vtx_data) if (!vtx_data)
return; 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)); memcpy(vtx_data, &cmd_list->vtx_buffer[0], cmd_list->vtx_buffer.size() * sizeof(ImDrawVert));
vtx_data += 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); glBindVertexArray(g_VaoHandle);
int vtx_offset = 0; 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 ImDrawIdx* idx_buffer = (const unsigned short*)&cmd_list->idx_buffer.front();
const ImDrawCmd* pcmd_end = cmd_list->commands.end(); const ImDrawCmd* pcmd_end = cmd_list->commands.end();

View File

@ -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) // 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: // 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) // - 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! // 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. // 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. // 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 // Render command lists
#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) #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 unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->vtx_buffer.front();
const ImDrawIdx* idx_buffer = (const unsigned short*)&cmd_list->idx_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))); glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos)));

View File

@ -141,6 +141,7 @@
Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix. 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. 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 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/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 - 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 // Render
if (!g.RenderDrawLists[0].empty()) 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);
}
} }
} }

14
imgui.h
View File

@ -31,6 +31,7 @@
// Forward declarations // Forward declarations
struct ImDrawCmd; struct ImDrawCmd;
struct ImDrawList; struct ImDrawList;
struct ImDrawData;
struct ImFont; struct ImFont;
struct ImFontAtlas; struct ImFontAtlas;
struct ImGuiIO; struct ImGuiIO;
@ -670,7 +671,7 @@ struct ImGuiIO
// REQUIRED: rendering function. // REQUIRED: rendering function.
// See example code if you are unsure of how to implement this. // 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 // 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) // (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 // 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. // Draw callbacks for advanced uses.
@ -1087,6 +1088,15 @@ struct ImDrawList
IMGUI_API void UpdateTextureID(); 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. // 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. // 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. // We also add custom graphic data into the texture that serves for ImGui.