| 442 | } |
| 443 | |
| 444 | void imgui_instance::end_frame() |
| 445 | { |
| 446 | ImGui::SetCurrentContext(data.context); |
| 447 | ImGui::Render(); |
| 448 | ImDrawData * drawData = ImGui::GetDrawData(); |
| 449 | |
| 450 | // Backup GL state |
| 451 | GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); |
| 452 | GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); |
| 453 | GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); |
| 454 | GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); |
| 455 | GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); |
| 456 | GLint last_blend_src; glGetIntegerv(GL_BLEND_SRC, &last_blend_src); |
| 457 | GLint last_blend_dst; glGetIntegerv(GL_BLEND_DST, &last_blend_dst); |
| 458 | GLint last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb); |
| 459 | GLint last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha); |
| 460 | GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); |
| 461 | GLboolean last_enable_blend = glIsEnabled(GL_BLEND); |
| 462 | GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); |
| 463 | GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); |
| 464 | GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); |
| 465 | |
| 466 | // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled |
| 467 | glEnable(GL_BLEND); |
| 468 | glBlendEquation(GL_FUNC_ADD); |
| 469 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
| 470 | glDisable(GL_CULL_FACE); |
| 471 | glDisable(GL_DEPTH_TEST); |
| 472 | glEnable(GL_SCISSOR_TEST); |
| 473 | glActiveTexture(GL_TEXTURE0); |
| 474 | |
| 475 | // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) |
| 476 | ImGuiIO & io = ImGui::GetIO(); |
| 477 | int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); |
| 478 | int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); |
| 479 | if (fb_width == 0 || fb_height == 0) return; |
| 480 | drawData->ScaleClipRects(io.DisplayFramebufferScale); |
| 481 | |
| 482 | // Setup viewport, orthographic projection matrix |
| 483 | glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); |
| 484 | const float ortho_projection[4][4] = { |
| 485 | { 2.0f / io.DisplaySize.x, 0.0f, 0.0f, 0.0f }, |
| 486 | { 0.0f, 2.0f / -io.DisplaySize.y, 0.0f, 0.0f }, |
| 487 | { 0.0f, 0.0f, -1.0f, 0.0f }, |
| 488 | {-1.0f, 1.0f, 0.0f, 1.0f }, |
| 489 | }; |
| 490 | |
| 491 | glUseProgram(data.ShaderHandle); |
| 492 | glUniform1i(data.AttribLocationTex, 0); |
| 493 | glUniformMatrix4fv(data.AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); |
| 494 | glBindVertexArray(data.VaoHandle); |
| 495 | |
| 496 | for (int n = 0; n < drawData->CmdListsCount; n++) |
| 497 | { |
| 498 | const ImDrawList* cmd_list = drawData->CmdLists[n]; |
| 499 | const ImDrawIdx* idx_buffer_offset = 0; |
| 500 | |
| 501 | glBindBuffer(GL_ARRAY_BUFFER, data.VboHandle); |