diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 15813f65dd..30a27be521 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -1,5 +1,6 @@ #include "ImGuiWrapper.hpp" +#include #include #include @@ -21,6 +22,7 @@ namespace GUI { ImGuiWrapper::ImGuiWrapper() : m_glsl_version_string("") + , m_glsl_version(0) , m_shader_handle(0) , m_vert_handle(0) , m_frag_handle(0) @@ -45,15 +47,24 @@ ImGuiWrapper::~ImGuiWrapper() bool ImGuiWrapper::init() { // Store GLSL version string so we can refer to it later in case we recreate shaders. Note: GLSL version is NOT the same as GL version. Leave this to NULL if unsure. - std::string glsl_version; + // std::string glsl_version; -#ifdef USE_GL_ES3 - glsl_version = "#version 300 es"; -#else - glsl_version = "#version 130"; -#endif +// #ifdef USE_GL_ES3 +// glsl_version = "#version 300 es"; +// #else +// glsl_version = "#version 130"; +// #endif - m_glsl_version_string = glsl_version + "\n"; +// m_glsl_version_string = glsl_version + "\n"; + + // const GLubyte *glsl_version_string = glGetString(GL_SHADING_LANGUAGE_VERSION); + // if (glsl_version_string != nullptr) { + // unsigned v_maj = 0; + // unsigned v_min = 0; + // if (std::sscanf(reinterpret_cast(glsl_version_string), "%u.%u", &v_maj, &v_min) == 2) { + // m_glsl_version = 100 * v_maj + v_min % 100; + // } + // } ImGui::CreateContext(); @@ -73,6 +84,20 @@ bool ImGuiWrapper::init() return true; } +void ImGuiWrapper::read_glsl_version() +{ + const GLubyte *glsl_version_string = glGetString(GL_SHADING_LANGUAGE_VERSION); + wxCHECK_RET(glsl_version_string != nullptr, "Could not get GLSL version string, glGetString(GL_SHADING_LANGUAGE_VERSION) failed"); + + unsigned v_maj = 0; + unsigned v_min = 0; + int res = std::sscanf(reinterpret_cast(glsl_version_string), "%u.%u", &v_maj, &v_min); + wxCHECK_RET(res == 2, wxString::Format("Could not parse GLSL version: %s", glsl_version_string)); + + m_glsl_version = 100 * v_maj + v_min % 100; + m_glsl_version_string = (boost::format("#version %1%") % m_glsl_version).str(); +} + void ImGuiWrapper::set_display_size(float w, float h) { ImGuiIO& io = ImGui::GetIO(); @@ -198,175 +223,176 @@ bool ImGuiWrapper::want_any_input() const void ImGuiWrapper::create_device_objects() { - // Backup GL state - GLint last_texture, last_array_buffer, last_vertex_array; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); + // // Backup GL state + // GLint last_texture, last_array_buffer, last_vertex_array; + // glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + // glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); + // glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); - // Parse GLSL version string - int glsl_version = 130; - ::sscanf(m_glsl_version_string.c_str(), "#version %d", &glsl_version); + // // Parse GLSL version string + // // int glsl_version = 130; + // // ::sscanf(m_glsl_version_string.c_str(), "#version %d", &glsl_version); + // read_glsl_version(); - const GLchar* vertex_shader_glsl_120 = - "uniform mat4 ProjMtx;\n" - "attribute vec2 Position;\n" - "attribute vec2 UV;\n" - "attribute vec4 Color;\n" - "varying vec2 Frag_UV;\n" - "varying vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " Frag_UV = UV;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" - "}\n"; + // const GLchar* vertex_shader_glsl_120 = + // "uniform mat4 ProjMtx;\n" + // "attribute vec2 Position;\n" + // "attribute vec2 UV;\n" + // "attribute vec4 Color;\n" + // "varying vec2 Frag_UV;\n" + // "varying vec4 Frag_Color;\n" + // "void main()\n" + // "{\n" + // " Frag_UV = UV;\n" + // " Frag_Color = Color;\n" + // " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + // "}\n"; - const GLchar* vertex_shader_glsl_130 = - "uniform mat4 ProjMtx;\n" - "in vec2 Position;\n" - "in vec2 UV;\n" - "in vec4 Color;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " Frag_UV = UV;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" - "}\n"; + // const GLchar* vertex_shader_glsl_130 = + // "uniform mat4 ProjMtx;\n" + // "in vec2 Position;\n" + // "in vec2 UV;\n" + // "in vec4 Color;\n" + // "out vec2 Frag_UV;\n" + // "out vec4 Frag_Color;\n" + // "void main()\n" + // "{\n" + // " Frag_UV = UV;\n" + // " Frag_Color = Color;\n" + // " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + // "}\n"; - const GLchar* vertex_shader_glsl_300_es = - "precision mediump float;\n" - "layout (location = 0) in vec2 Position;\n" - "layout (location = 1) in vec2 UV;\n" - "layout (location = 2) in vec4 Color;\n" - "uniform mat4 ProjMtx;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " Frag_UV = UV;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" - "}\n"; + // const GLchar* vertex_shader_glsl_300_es = + // "precision mediump float;\n" + // "layout (location = 0) in vec2 Position;\n" + // "layout (location = 1) in vec2 UV;\n" + // "layout (location = 2) in vec4 Color;\n" + // "uniform mat4 ProjMtx;\n" + // "out vec2 Frag_UV;\n" + // "out vec4 Frag_Color;\n" + // "void main()\n" + // "{\n" + // " Frag_UV = UV;\n" + // " Frag_Color = Color;\n" + // " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + // "}\n"; - const GLchar* vertex_shader_glsl_410_core = - "layout (location = 0) in vec2 Position;\n" - "layout (location = 1) in vec2 UV;\n" - "layout (location = 2) in vec4 Color;\n" - "uniform mat4 ProjMtx;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " Frag_UV = UV;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" - "}\n"; + // const GLchar* vertex_shader_glsl_410_core = + // "layout (location = 0) in vec2 Position;\n" + // "layout (location = 1) in vec2 UV;\n" + // "layout (location = 2) in vec4 Color;\n" + // "uniform mat4 ProjMtx;\n" + // "out vec2 Frag_UV;\n" + // "out vec4 Frag_Color;\n" + // "void main()\n" + // "{\n" + // " Frag_UV = UV;\n" + // " Frag_Color = Color;\n" + // " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + // "}\n"; - const GLchar* fragment_shader_glsl_120 = - "#ifdef GL_ES\n" - " precision mediump float;\n" - "#endif\n" - "uniform sampler2D Texture;\n" - "varying vec2 Frag_UV;\n" - "varying vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n" - "}\n"; + // const GLchar* fragment_shader_glsl_120 = + // "#ifdef GL_ES\n" + // " precision mediump float;\n" + // "#endif\n" + // "uniform sampler2D Texture;\n" + // "varying vec2 Frag_UV;\n" + // "varying vec4 Frag_Color;\n" + // "void main()\n" + // "{\n" + // " gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n" + // "}\n"; - const GLchar* fragment_shader_glsl_130 = - "uniform sampler2D Texture;\n" - "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "out vec4 Out_Color;\n" - "void main()\n" - "{\n" - " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" - "}\n"; + // const GLchar* fragment_shader_glsl_130 = + // "uniform sampler2D Texture;\n" + // "in vec2 Frag_UV;\n" + // "in vec4 Frag_Color;\n" + // "out vec4 Out_Color;\n" + // "void main()\n" + // "{\n" + // " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" + // "}\n"; - const GLchar* fragment_shader_glsl_300_es = - "precision mediump float;\n" - "uniform sampler2D Texture;\n" - "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "layout (location = 0) out vec4 Out_Color;\n" - "void main()\n" - "{\n" - " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" - "}\n"; + // const GLchar* fragment_shader_glsl_300_es = + // "precision mediump float;\n" + // "uniform sampler2D Texture;\n" + // "in vec2 Frag_UV;\n" + // "in vec4 Frag_Color;\n" + // "layout (location = 0) out vec4 Out_Color;\n" + // "void main()\n" + // "{\n" + // " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" + // "}\n"; - const GLchar* fragment_shader_glsl_410_core = - "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "uniform sampler2D Texture;\n" - "layout (location = 0) out vec4 Out_Color;\n" - "void main()\n" - "{\n" - " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" - "}\n"; + // const GLchar* fragment_shader_glsl_410_core = + // "in vec2 Frag_UV;\n" + // "in vec4 Frag_Color;\n" + // "uniform sampler2D Texture;\n" + // "layout (location = 0) out vec4 Out_Color;\n" + // "void main()\n" + // "{\n" + // " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" + // "}\n"; - // Select shaders matching our GLSL versions - const GLchar* vertex_shader = nullptr; - const GLchar* fragment_shader = nullptr; - if (glsl_version < 130) - { - vertex_shader = vertex_shader_glsl_120; - fragment_shader = fragment_shader_glsl_120; - } - else if (glsl_version == 410) - { - vertex_shader = vertex_shader_glsl_410_core; - fragment_shader = fragment_shader_glsl_410_core; - } - else if (glsl_version == 300) - { - vertex_shader = vertex_shader_glsl_300_es; - fragment_shader = fragment_shader_glsl_300_es; - } - else - { - vertex_shader = vertex_shader_glsl_130; - fragment_shader = fragment_shader_glsl_130; - } + // // Select shaders matching our GLSL versions + // const GLchar* vertex_shader = nullptr; + // const GLchar* fragment_shader = nullptr; + // if (m_glsl_version < 130) + // { + // vertex_shader = vertex_shader_glsl_120; + // fragment_shader = fragment_shader_glsl_120; + // } + // else if (m_glsl_version == 410) + // { + // vertex_shader = vertex_shader_glsl_410_core; + // fragment_shader = fragment_shader_glsl_410_core; + // } + // else if (m_glsl_version == 300) + // { + // vertex_shader = vertex_shader_glsl_300_es; + // fragment_shader = fragment_shader_glsl_300_es; + // } + // else + // { + // vertex_shader = vertex_shader_glsl_130; + // fragment_shader = fragment_shader_glsl_130; + // } - // Create shaders - const GLchar* vertex_shader_with_version[2] = { m_glsl_version_string.c_str(), vertex_shader }; - m_vert_handle = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(m_vert_handle, 2, vertex_shader_with_version, nullptr); - glCompileShader(m_vert_handle); - wxASSERT(check_shader(m_vert_handle, "vertex shader")); + // // Create shaders + // const GLchar* vertex_shader_with_version[2] = { m_glsl_version_string.c_str(), vertex_shader }; + // m_vert_handle = glCreateShader(GL_VERTEX_SHADER); + // glShaderSource(m_vert_handle, 2, vertex_shader_with_version, nullptr); + // glCompileShader(m_vert_handle); + // wxASSERT(check_shader(m_vert_handle, "vertex shader")); - const GLchar* fragment_shader_with_version[2] = { m_glsl_version_string.c_str(), fragment_shader }; - m_frag_handle = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(m_frag_handle, 2, fragment_shader_with_version, nullptr); - glCompileShader(m_frag_handle); - wxASSERT(check_shader(m_frag_handle, "fragment shader")); + // const GLchar* fragment_shader_with_version[2] = { m_glsl_version_string.c_str(), fragment_shader }; + // m_frag_handle = glCreateShader(GL_FRAGMENT_SHADER); + // glShaderSource(m_frag_handle, 2, fragment_shader_with_version, nullptr); + // glCompileShader(m_frag_handle); + // wxASSERT(check_shader(m_frag_handle, "fragment shader")); - m_shader_handle = glCreateProgram(); - glAttachShader(m_shader_handle, m_vert_handle); - glAttachShader(m_shader_handle, m_frag_handle); - glLinkProgram(m_shader_handle); - wxASSERT(check_program(m_shader_handle, "shader program")); + // m_shader_handle = glCreateProgram(); + // glAttachShader(m_shader_handle, m_vert_handle); + // glAttachShader(m_shader_handle, m_frag_handle); + // glLinkProgram(m_shader_handle); + // wxASSERT(check_program(m_shader_handle, "shader program")); - m_attrib_location_tex = glGetUniformLocation(m_shader_handle, "Texture"); - m_attrib_location_proj_mtx = glGetUniformLocation(m_shader_handle, "ProjMtx"); - m_attrib_location_position = glGetAttribLocation(m_shader_handle, "Position"); - m_attrib_location_uv = glGetAttribLocation(m_shader_handle, "UV"); - m_attrib_location_color = glGetAttribLocation(m_shader_handle, "Color"); + // m_attrib_location_tex = glGetUniformLocation(m_shader_handle, "Texture"); + // m_attrib_location_proj_mtx = glGetUniformLocation(m_shader_handle, "ProjMtx"); + // m_attrib_location_position = glGetAttribLocation(m_shader_handle, "Position"); + // m_attrib_location_uv = glGetAttribLocation(m_shader_handle, "UV"); + // m_attrib_location_color = glGetAttribLocation(m_shader_handle, "Color"); - // Create buffers - glGenBuffers(1, &m_vbo_handle); - glGenBuffers(1, &m_elements_handle); + // // Create buffers + // glGenBuffers(1, &m_vbo_handle); + // glGenBuffers(1, &m_elements_handle); create_fonts_texture(); - // Restore modified GL state - glBindTexture(GL_TEXTURE_2D, last_texture); - glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); - glBindVertexArray(last_vertex_array); + // // Restore modified GL state + // glBindTexture(GL_TEXTURE_2D, last_texture); + // glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + // glBindVertexArray(last_vertex_array); } void ImGuiWrapper::create_fonts_texture() @@ -434,96 +460,56 @@ bool ImGuiWrapper::check_shader(unsigned int handle, const char *desc) void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) { - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) ImGuiIO& io = ImGui::GetIO(); int fb_width = (int)(draw_data->DisplaySize.x * io.DisplayFramebufferScale.x); int fb_height = (int)(draw_data->DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width <= 0 || fb_height <= 0) + if (fb_width == 0 || fb_height == 0) return; draw_data->ScaleClipRects(io.DisplayFramebufferScale); - // Backup GL state - GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture); - glActiveTexture(GL_TEXTURE0); - GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill. GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); -#ifdef GL_SAMPLER_BINDING - GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler); -#endif - GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); - GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); -#ifdef GL_POLYGON_MODE GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); -#endif GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); - GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb); - GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb); - GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha); - GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha); - GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb); - GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha); - GLboolean last_enable_blend = glIsEnabled(GL_BLEND); - GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); - GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); - GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); - - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill + GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glDisable(GL_COLOR_MATERIAL); glEnable(GL_SCISSOR_TEST); -#ifdef GL_POLYGON_MODE + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -#endif + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound // Setup viewport, orthographic projection matrix - // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayMin is typically (0,0) for single viewport apps. + // Our visible imgui space lies from draw_data->DisplayPps (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayMin is typically (0,0) for single viewport apps. glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - float L = draw_data->DisplayPos.x; - float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; - float T = draw_data->DisplayPos.y; - float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; - const float ortho_projection[4][4] = - { - { 2.0f / (R - L), 0.0f, 0.0f, 0.0f }, - { 0.0f, 2.0f / (T - B), 0.0f, 0.0f }, - { 0.0f, 0.0f, -1.0f, 0.0f }, - { (R + L) / (L - R), (T + B) / (B - T), 0.0f, 1.0f }, - }; - glUseProgram(m_shader_handle); - glUniform1i(m_attrib_location_tex, 0); - glUniformMatrix4fv(m_attrib_location_proj_mtx, 1, GL_FALSE, &ortho_projection[0][0]); -#ifdef GL_SAMPLER_BINDING - glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise. -#endif - // 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, m_vbo_handle); - glEnableVertexAttribArray(m_attrib_location_position); - glEnableVertexAttribArray(m_attrib_location_uv); - glEnableVertexAttribArray(m_attrib_location_color); - glVertexAttribPointer(m_attrib_location_position, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)); - glVertexAttribPointer(m_attrib_location_uv, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)); - glVertexAttribPointer(m_attrib_location_color, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(draw_data->DisplayPos.x, draw_data->DisplayPos.x + draw_data->DisplaySize.x, draw_data->DisplayPos.y + draw_data->DisplaySize.y, draw_data->DisplayPos.y, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); - // Draw + // Render command lists ImVec2 pos = draw_data->DisplayPos; for (int n = 0; n < draw_data->CmdListsCount; n++) { const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const ImDrawIdx* idx_buffer_offset = 0; - - glBindBuffer(GL_ARRAY_BUFFER, m_vbo_handle); - glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elements_handle); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW); + const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; + const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, col))); for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { @@ -543,36 +529,169 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) // Bind texture, Draw glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); } } - idx_buffer_offset += pcmd->ElemCount; + idx_buffer += pcmd->ElemCount; } } - glDeleteVertexArrays(1, &vao_handle); - // Restore modified GL state - glUseProgram(last_program); - glBindTexture(GL_TEXTURE_2D, last_texture); -#ifdef GL_SAMPLER_BINDING - glBindSampler(0, last_sampler); -#endif - glActiveTexture(last_active_texture); - glBindVertexArray(last_vertex_array); - glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); - glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); - glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha); - if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); - if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); - if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); - if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); -#ifdef GL_POLYGON_MODE - glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); -#endif + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]); glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); } +// void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) +// { +// // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) +// ImGuiIO& io = ImGui::GetIO(); +// int fb_width = (int)(draw_data->DisplaySize.x * io.DisplayFramebufferScale.x); +// int fb_height = (int)(draw_data->DisplaySize.y * io.DisplayFramebufferScale.y); +// if (fb_width <= 0 || fb_height <= 0) +// return; +// draw_data->ScaleClipRects(io.DisplayFramebufferScale); + +// // Backup GL state +// GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture); +// glActiveTexture(GL_TEXTURE0); +// GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); +// GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); +// #ifdef GL_SAMPLER_BINDING +// GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler); +// #endif +// GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); +// GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); +// #ifdef GL_POLYGON_MODE +// GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); +// #endif +// GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); +// GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); +// GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb); +// GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb); +// GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha); +// GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha); +// GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb); +// GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha); +// GLboolean last_enable_blend = glIsEnabled(GL_BLEND); +// GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); +// GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); +// GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); + +// // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill +// glEnable(GL_BLEND); +// glBlendEquation(GL_FUNC_ADD); +// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +// glDisable(GL_CULL_FACE); +// glDisable(GL_DEPTH_TEST); +// glEnable(GL_SCISSOR_TEST); +// #ifdef GL_POLYGON_MODE +// glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +// #endif + +// // Setup viewport, orthographic projection matrix +// // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayMin is typically (0,0) for single viewport apps. +// glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); +// float L = draw_data->DisplayPos.x; +// float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; +// float T = draw_data->DisplayPos.y; +// float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; +// const float ortho_projection[4][4] = +// { +// { 2.0f / (R - L), 0.0f, 0.0f, 0.0f }, +// { 0.0f, 2.0f / (T - B), 0.0f, 0.0f }, +// { 0.0f, 0.0f, -1.0f, 0.0f }, +// { (R + L) / (L - R), (T + B) / (B - T), 0.0f, 1.0f }, +// }; +// glUseProgram(m_shader_handle); +// glUniform1i(m_attrib_location_tex, 0); +// glUniformMatrix4fv(m_attrib_location_proj_mtx, 1, GL_FALSE, &ortho_projection[0][0]); +// #ifdef GL_SAMPLER_BINDING +// glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise. +// #endif +// // 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, m_vbo_handle); +// glEnableVertexAttribArray(m_attrib_location_position); +// glEnableVertexAttribArray(m_attrib_location_uv); +// glEnableVertexAttribArray(m_attrib_location_color); +// glVertexAttribPointer(m_attrib_location_position, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)); +// glVertexAttribPointer(m_attrib_location_uv, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)); +// glVertexAttribPointer(m_attrib_location_color, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)); + +// // Draw +// ImVec2 pos = draw_data->DisplayPos; +// for (int n = 0; n < draw_data->CmdListsCount; n++) +// { +// const ImDrawList* cmd_list = draw_data->CmdLists[n]; +// const ImDrawIdx* idx_buffer_offset = 0; + +// glBindBuffer(GL_ARRAY_BUFFER, m_vbo_handle); +// glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW); + +// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elements_handle); +// glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW); + +// for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) +// { +// const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; +// if (pcmd->UserCallback) +// { +// // User callback (registered via ImDrawList::AddCallback) +// pcmd->UserCallback(cmd_list, pcmd); +// } +// else +// { +// ImVec4 clip_rect = ImVec4(pcmd->ClipRect.x - pos.x, pcmd->ClipRect.y - pos.y, pcmd->ClipRect.z - pos.x, pcmd->ClipRect.w - pos.y); +// if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) +// { +// // Apply scissor/clipping rectangle +// glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); + +// // Bind texture, Draw +// glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); +// glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); +// } +// } +// idx_buffer_offset += pcmd->ElemCount; +// } +// } +// glDeleteVertexArrays(1, &vao_handle); + +// // Restore modified GL state +// glUseProgram(last_program); +// glBindTexture(GL_TEXTURE_2D, last_texture); +// #ifdef GL_SAMPLER_BINDING +// glBindSampler(0, last_sampler); +// #endif +// glActiveTexture(last_active_texture); +// glBindVertexArray(last_vertex_array); +// glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); +// glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); +// glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha); +// if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); +// if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); +// if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); +// if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); +// #ifdef GL_POLYGON_MODE +// glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); +// #endif +// glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +// glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); +// } + void ImGuiWrapper::destroy_device_objects() { if (m_vbo_handle != 0) @@ -614,8 +733,7 @@ void ImGuiWrapper::destroy_device_objects() void ImGuiWrapper::destroy_fonts_texture() { - if (m_font_texture) - { + if (m_font_texture) { ImGuiIO& io = ImGui::GetIO(); io.Fonts->TexID = 0; glDeleteTextures(1, &m_font_texture); diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 4e20af9fd8..5c1bffc88d 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -18,11 +18,12 @@ namespace GUI { class ImGuiWrapper { std::string m_glsl_version_string; - unsigned int m_shader_handle; - unsigned int m_vert_handle; - unsigned int m_frag_handle; - unsigned int m_vbo_handle; - unsigned int m_elements_handle; + unsigned m_glsl_version; + unsigned m_shader_handle; + unsigned m_vert_handle; + unsigned m_frag_handle; + unsigned m_vbo_handle; + unsigned m_elements_handle; int m_attrib_location_tex; int m_attrib_location_proj_mtx; int m_attrib_location_position; @@ -32,7 +33,7 @@ class ImGuiWrapper typedef std::map FontsMap; FontsMap m_fonts; - unsigned int m_font_texture; + unsigned m_font_texture; unsigned m_mouse_buttons; @@ -41,6 +42,7 @@ public: ~ImGuiWrapper(); bool init(); + void read_glsl_version(); void set_display_size(float w, float h); bool update_mouse_data(wxMouseEvent &evt);