Tidying up example applications

This commit is contained in:
ocornut 2014-08-11 17:46:54 +01:00
parent 4020ef7b58
commit 98a000055e
2 changed files with 36 additions and 51 deletions

View File

@ -83,45 +83,37 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat); g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat);
// Render command lists // Render command lists
int vtx_consumed = 0; // offset in vertex buffer. each command consume ImDrawCmd::vtx_count of those int vtx_offset = 0;
for (int n = 0; n < cmd_lists_count; n++) for (int n = 0; n < cmd_lists_count; n++)
{ {
const ImDrawList* cmd_list = cmd_lists[n];
// Setup stack of clipping rectangles // Setup stack of clipping rectangles
bool clip_rect_dirty = true; int clip_rect_buf_offset = 0;
int clip_rect_buf_consumed = 0;
ImVector<ImVec4> clip_rect_stack; ImVector<ImVec4> clip_rect_stack;
clip_rect_stack.push_back(ImVec4(-9999,-9999,+9999,+9999)); clip_rect_stack.push_back(ImVec4(-9999,-9999,+9999,+9999));
// Render command list // Render command list
const ImDrawCmd* pcmd = &cmd_list->commands.front(); const ImDrawList* cmd_list = cmd_lists[n];
const ImDrawCmd* pcmd_end = &cmd_list->commands.back(); const ImDrawCmd* pcmd_end = cmd_list->commands.end();
while (pcmd <= pcmd_end) for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
{ {
const ImDrawCmd& cmd = *pcmd++; switch (pcmd->cmd_type)
switch (cmd.cmd_type)
{ {
case ImDrawCmdType_DrawTriangleList: case ImDrawCmdType_DrawTriangleList:
if (clip_rect_dirty)
{ {
const ImVec4& clip_rect = clip_rect_stack.back(); const ImVec4& clip_rect = clip_rect_stack.back();
const RECT r = { (LONG)clip_rect.x, (LONG)clip_rect.y, (LONG)clip_rect.z, (LONG)clip_rect.w }; const RECT r = { (LONG)clip_rect.x, (LONG)clip_rect.y, (LONG)clip_rect.z, (LONG)clip_rect.w };
g_pd3dDevice->SetScissorRect(&r); g_pd3dDevice->SetScissorRect(&r);
clip_rect_dirty = false; g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, vtx_offset, pcmd->vtx_count/3);
vtx_offset += pcmd->vtx_count;
} }
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, vtx_consumed, cmd.vtx_count/3);
vtx_consumed += cmd.vtx_count;
break; break;
case ImDrawCmdType_PushClipRect: case ImDrawCmdType_PushClipRect:
clip_rect_stack.push_back(cmd_list->clip_rect_buffer[clip_rect_buf_consumed++]); clip_rect_stack.push_back(cmd_list->clip_rect_buffer[clip_rect_buf_offset++]);
clip_rect_dirty = true;
break; break;
case ImDrawCmdType_PopClipRect: case ImDrawCmdType_PopClipRect:
clip_rect_stack.pop_back(); clip_rect_stack.pop_back();
clip_rect_dirty = true;
break; break;
} }
} }

View File

@ -15,8 +15,6 @@ static GLuint vertexShader;
static GLuint fragmentShader; static GLuint fragmentShader;
static GLuint shaderProgram; static GLuint shaderProgram;
static GLuint fontTex; static GLuint fontTex;
static GLint uniMVP;
static GLint uniClipRect;
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structuer) // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structuer)
static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
@ -34,13 +32,11 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
unsigned char* buffer_data = (unsigned char*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); unsigned char* buffer_data = (unsigned char*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
if (!buffer_data) if (!buffer_data)
return; return;
int vtx_consumed = 0;
for (int n = 0; n < cmd_lists_count; n++) for (int n = 0; n < cmd_lists_count; n++)
{ {
const ImDrawList* cmd_list = cmd_lists[n]; const ImDrawList* cmd_list = cmd_lists[n];
memcpy(buffer_data, &cmd_list->vtx_buffer[0], cmd_list->vtx_buffer.size() * sizeof(ImDrawVert)); memcpy(buffer_data, &cmd_list->vtx_buffer[0], cmd_list->vtx_buffer.size() * sizeof(ImDrawVert));
buffer_data += cmd_list->vtx_buffer.size() * sizeof(ImDrawVert); buffer_data += cmd_list->vtx_buffer.size() * sizeof(ImDrawVert);
vtx_consumed += cmd_list->vtx_buffer.size();
} }
glUnmapBuffer(GL_ARRAY_BUFFER); glUnmapBuffer(GL_ARRAY_BUFFER);
@ -53,63 +49,59 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
// Bind texture and enable our shader // Bind texture and enable our shader
glBindTexture(GL_TEXTURE_2D, fontTex); glBindTexture(GL_TEXTURE_2D, fontTex);
glUseProgram(shaderProgram); glUseProgram(shaderProgram);
const GLint uniMVP = glGetUniformLocation(shaderProgram, "MVP");
const GLint uniClipRect = glGetUniformLocation(shaderProgram, "ClipRect");
// Setup orthographic projection matrix // Setup orthographic projection matrix
const float L = 0.0f; const float width = ImGui::GetIO().DisplaySize.x;
const float R = ImGui::GetIO().DisplaySize.x; const float height = ImGui::GetIO().DisplaySize.y;
const float B = ImGui::GetIO().DisplaySize.y;
const float T = 0.0f;
const float mvp[4][4] = const float mvp[4][4] =
{ {
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, { 2.0f/width, 0.0f, 0.0f, 0.0f },
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f }, { 0.0f, 2.0f/-height, 0.0f, 0.0f },
{ 0.0f, 0.0f, -1.0f, 0.0f }, { 0.0f, 0.0f, -1.0f, 0.0f },
{ -(R+L)/(R-L), -(T+B)/(T-B), 0.0f, 1.0f }, { -1.0f, 1.0f, 0.0f, 1.0f },
}; };
glUniformMatrix4fv(uniMVP, 1, GL_FALSE, &mvp[0][0]); glUniformMatrix4fv(uniMVP, 1, GL_FALSE, &mvp[0][0]);
// Render command lists // Render command lists
vtx_consumed = 0; // offset in vertex buffer. each command consume ImDrawCmd::vtx_count of those int vtx_offset = 0;
for (int n = 0; n < cmd_lists_count; n++) for (int n = 0; n < cmd_lists_count; n++)
{ {
const ImDrawList* cmd_list = cmd_lists[n];
// Setup stack of clipping rectangles // Setup stack of clipping rectangles
bool clip_rect_dirty = true; int clip_rect_buf_offset = 0;
int clip_rect_buf_consumed = 0;
ImVector<ImVec4> clip_rect_stack; ImVector<ImVec4> clip_rect_stack;
clip_rect_stack.push_back(ImVec4(-9999,-9999,+9999,+9999)); clip_rect_stack.push_back(ImVec4(-9999,-9999,+9999,+9999));
// Render command list // Render command list
const ImDrawCmd* pcmd = &cmd_list->commands.front(); const ImDrawList* cmd_list = cmd_lists[n];
const ImDrawCmd* pcmd_end = &cmd_list->commands.back(); const ImDrawCmd* pcmd_end = cmd_list->commands.end();
while (pcmd <= pcmd_end) for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
{ {
const ImDrawCmd& cmd = *pcmd++; switch (pcmd->cmd_type)
switch (cmd.cmd_type)
{ {
case ImDrawCmdType_DrawTriangleList: case ImDrawCmdType_DrawTriangleList:
if (clip_rect_dirty)
{
glUniform4fv(uniClipRect, 1, (float*)&clip_rect_stack.back()); glUniform4fv(uniClipRect, 1, (float*)&clip_rect_stack.back());
clip_rect_dirty = false; glDrawArrays(GL_TRIANGLES, vtx_offset, pcmd->vtx_count);
} vtx_offset += pcmd->vtx_count;
glDrawArrays(GL_TRIANGLES, vtx_consumed, cmd.vtx_count);
vtx_consumed += cmd.vtx_count;
break; break;
case ImDrawCmdType_PushClipRect: case ImDrawCmdType_PushClipRect:
clip_rect_stack.push_back(cmd_list->clip_rect_buffer[clip_rect_buf_consumed++]); clip_rect_stack.push_back(cmd_list->clip_rect_buffer[clip_rect_buf_offset++]);
clip_rect_dirty = true;
break; break;
case ImDrawCmdType_PopClipRect: case ImDrawCmdType_PopClipRect:
clip_rect_stack.pop_back(); clip_rect_stack.pop_back();
clip_rect_dirty = true;
break; break;
} }
} }
} }
// Cleanup GL state
glBindTexture(GL_TEXTURE_2D, 0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUseProgram(0);
} }
static const char* ImImpl_GetClipboardTextFn() static const char* ImImpl_GetClipboardTextFn()
@ -122,6 +114,7 @@ static void ImImpl_SetClipboardTextFn(const char* text, const char* text_end)
if (!text_end) if (!text_end)
text_end = text + strlen(text); text_end = text + strlen(text);
// Add a zero-terminator because glfw function doesn't take a size
char* buf = (char*)malloc(text_end - text + 1); char* buf = (char*)malloc(text_end - text + 1);
memcpy(buf, text, text_end-text); memcpy(buf, text, text_end-text);
buf[text_end-text] = '\0'; buf[text_end-text] = '\0';
@ -283,9 +276,6 @@ void InitImGui()
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &status); glGetProgramiv(shaderProgram, GL_LINK_STATUS, &status);
IM_ASSERT(status == GL_TRUE); IM_ASSERT(status == GL_TRUE);
uniMVP = glGetUniformLocation(shaderProgram, "MVP");
uniClipRect = glGetUniformLocation(shaderProgram, "ClipRect");
// Create Vertex Buffer Objects & Vertex Array Objects // Create Vertex Buffer Objects & Vertex Array Objects
glGenBuffers(1, &vbo); glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo);
@ -305,6 +295,9 @@ void InitImGui()
glEnableVertexAttribArray(colAttrib); glEnableVertexAttribArray(colAttrib);
err = glGetError(); IM_ASSERT(err == GL_NO_ERROR); err = glGetError(); IM_ASSERT(err == GL_NO_ERROR);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Load font texture // Load font texture
glGenTextures(1, &fontTex); glGenTextures(1, &fontTex);
glBindTexture(GL_TEXTURE_2D, fontTex); glBindTexture(GL_TEXTURE_2D, fontTex);