From 389dc3605333d76d374a462b61d8e1c48bdad089 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 24 Mar 2022 14:45:59 +0100 Subject: [PATCH] Tech ENABLE_GL_CORE_PROFILE - Use OpenGL core profile context - 1st installment Fixed conflicts during rebase with master --- resources/shaders/140/background.fs | 4 +- resources/shaders/140/flat.fs | 4 +- resources/shaders/140/flat_texture.fs | 4 +- resources/shaders/140/gouraud.fs | 6 +- resources/shaders/140/gouraud_light.fs | 4 +- .../shaders/140/gouraud_light_instanced.fs | 4 +- resources/shaders/140/imgui.fs | 4 +- resources/shaders/140/lines_width.fs | 27 +++++ resources/shaders/140/lines_width.gs | 57 +++++++++++ resources/shaders/140/lines_width.vs | 13 +++ resources/shaders/140/mm_contour.fs | 4 +- resources/shaders/140/mm_gouraud.fs | 4 +- resources/shaders/140/printbed.fs | 5 +- resources/shaders/140/toolpaths_cog.fs | 4 +- .../shaders/140/variable_layer_height.fs | 4 +- src/libslic3r/Technologies.hpp | 2 + src/slic3r/GUI/3DBed.cpp | 2 + src/slic3r/GUI/3DScene.cpp | 11 +++ src/slic3r/GUI/GCodeViewer.cpp | 99 ++++++++++++++++++- src/slic3r/GUI/GCodeViewer.hpp | 22 ++++- src/slic3r/GUI/GLCanvas3D.cpp | 15 ++- src/slic3r/GUI/GLModel.cpp | 57 ++++++++++- src/slic3r/GUI/GLModel.hpp | 3 + src/slic3r/GUI/GLSelectionRectangle.cpp | 6 ++ src/slic3r/GUI/GLShader.cpp | 13 +++ src/slic3r/GUI/GLShader.hpp | 8 ++ src/slic3r/GUI/GLShadersManager.cpp | 4 + src/slic3r/GUI/GLTexture.cpp | 6 +- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 4 + src/slic3r/GUI/Gizmos/GLGizmoMove.cpp | 2 + src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp | 6 ++ src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 2 + src/slic3r/GUI/Gizmos/GLGizmoScale.cpp | 2 + src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp | 11 +++ src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp | 9 ++ src/slic3r/GUI/ImGuiWrapper.cpp | 82 ++++++++++++--- src/slic3r/GUI/OpenGLManager.cpp | 57 +++++++++-- src/slic3r/GUI/OpenGLManager.hpp | 7 ++ src/slic3r/GUI/Selection.cpp | 10 +- 39 files changed, 542 insertions(+), 46 deletions(-) create mode 100644 resources/shaders/140/lines_width.fs create mode 100644 resources/shaders/140/lines_width.gs create mode 100644 resources/shaders/140/lines_width.vs diff --git a/resources/shaders/140/background.fs b/resources/shaders/140/background.fs index c21f3a70c..4e595312e 100644 --- a/resources/shaders/140/background.fs +++ b/resources/shaders/140/background.fs @@ -5,7 +5,9 @@ uniform vec4 bottom_color; in vec2 tex_coord; +out vec4 out_color; + void main() { - gl_FragColor = mix(bottom_color, top_color, tex_coord.y); + out_color = mix(bottom_color, top_color, tex_coord.y); } diff --git a/resources/shaders/140/flat.fs b/resources/shaders/140/flat.fs index e74124dca..28642d53f 100644 --- a/resources/shaders/140/flat.fs +++ b/resources/shaders/140/flat.fs @@ -2,7 +2,9 @@ uniform vec4 uniform_color; +out vec4 out_color; + void main() { - gl_FragColor = uniform_color; + out_color = uniform_color; } diff --git a/resources/shaders/140/flat_texture.fs b/resources/shaders/140/flat_texture.fs index dec946721..bb6682367 100644 --- a/resources/shaders/140/flat_texture.fs +++ b/resources/shaders/140/flat_texture.fs @@ -4,7 +4,9 @@ uniform sampler2D uniform_texture; in vec2 tex_coord; +out vec4 out_color; + void main() { - gl_FragColor = texture(uniform_texture, tex_coord); + out_color = texture(uniform_texture, tex_coord); } diff --git a/resources/shaders/140/gouraud.fs b/resources/shaders/140/gouraud.fs index 273779ca8..d87e33632 100644 --- a/resources/shaders/140/gouraud.fs +++ b/resources/shaders/140/gouraud.fs @@ -42,6 +42,8 @@ in vec4 world_pos; in float world_normal_z; in vec3 eye_normal; +out vec4 out_color; + void main() { if (any(lessThan(clipping_planes_dots, ZERO))) @@ -72,8 +74,8 @@ void main() #ifdef ENABLE_ENVIRONMENT_MAP if (use_environment_tex) - gl_FragColor = vec4(0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, alpha); + out_color = vec4(0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, alpha); else #endif - gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha); + out_color = vec4(vec3(intensity.y) + color * intensity.x, alpha); } diff --git a/resources/shaders/140/gouraud_light.fs b/resources/shaders/140/gouraud_light.fs index de616e066..0f918f4f6 100644 --- a/resources/shaders/140/gouraud_light.fs +++ b/resources/shaders/140/gouraud_light.fs @@ -6,7 +6,9 @@ uniform float emission_factor; // x = tainted, y = specular; in vec2 intensity; +out vec4 out_color; + void main() { - gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a); + out_color = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a); } diff --git a/resources/shaders/140/gouraud_light_instanced.fs b/resources/shaders/140/gouraud_light_instanced.fs index de616e066..0f918f4f6 100644 --- a/resources/shaders/140/gouraud_light_instanced.fs +++ b/resources/shaders/140/gouraud_light_instanced.fs @@ -6,7 +6,9 @@ uniform float emission_factor; // x = tainted, y = specular; in vec2 intensity; +out vec4 out_color; + void main() { - gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a); + out_color = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a); } diff --git a/resources/shaders/140/imgui.fs b/resources/shaders/140/imgui.fs index 4b2571749..1666c814e 100644 --- a/resources/shaders/140/imgui.fs +++ b/resources/shaders/140/imgui.fs @@ -5,7 +5,9 @@ uniform sampler2D Texture; in vec2 Frag_UV; in vec4 Frag_Color; +out vec4 out_color; + void main() { - gl_FragColor = Frag_Color * texture(Texture, Frag_UV.st); + out_color = Frag_Color * texture(Texture, Frag_UV.st); } \ No newline at end of file diff --git a/resources/shaders/140/lines_width.fs b/resources/shaders/140/lines_width.fs new file mode 100644 index 000000000..aeb5fe47b --- /dev/null +++ b/resources/shaders/140/lines_width.fs @@ -0,0 +1,27 @@ +#version 150 + +// see as reference: https://github.com/mhalber/Lines/blob/master/geometry_shader_lines.h + +const vec2 aa_radius = vec2(1.5); + +uniform vec4 uniform_color; + +in float line_width; +in float line_length; +in vec2 uv; + +out vec4 out_color; + +void main() +{ + // We render a quad that is fattened by r, giving total width of the line to be w+r. We want smoothing to happen + // around w, so that the edge is properly smoothed out. As such, in the smoothstep function we have: + // Far edge : 1.0 = (w+r) / (w+r) + // Close edge : 1.0 - (2r / (w+r)) = (w+r)/(w+r) - 2r/(w+r)) = (w-r) / (w+r) + // This way the smoothing is centered around 'w'. + + out_color = uniform_color; + float au = 1.0 - smoothstep( 1.0 - ((2.0 * aa_radius[0]) / line_width), 1.0, abs(uv.x / line_width) ); + float av = 1.0 - smoothstep( 1.0 - ((2.0 * aa_radius[1]) / line_length), 1.0, abs(uv.y / line_length) ); + out_color.a *= min(av, au); +} diff --git a/resources/shaders/140/lines_width.gs b/resources/shaders/140/lines_width.gs new file mode 100644 index 000000000..0b7a76140 --- /dev/null +++ b/resources/shaders/140/lines_width.gs @@ -0,0 +1,57 @@ +#version 150 + +// see as reference: https://github.com/mhalber/Lines/blob/master/geometry_shader_lines.h + +layout(lines) in; +layout(triangle_strip, max_vertices = 4) out; + +const vec2 aa_radius = vec2(1.5); + +uniform vec2 viewport_size; +uniform float width; + +out float line_width; +out float line_length; +out vec2 uv; + +void main() +{ + float u_width = viewport_size[0]; + float u_height = viewport_size[1]; + float u_aspect_ratio = u_height / u_width; + + vec2 ndc_a = gl_in[0].gl_Position.xy / gl_in[0].gl_Position.w; + vec2 ndc_b = gl_in[1].gl_Position.xy / gl_in[1].gl_Position.w; + + vec2 line_vector = ndc_b - ndc_a; + vec2 viewport_line_vector = line_vector * viewport_size; + vec2 dir = normalize(viewport_line_vector); + vec2 normal_dir = vec2(-dir.y, dir.x); + + line_width = max(1.0, width) + aa_radius[0]; + line_length = length(viewport_line_vector) + 2.0 * aa_radius[1]; + + vec2 normal = vec2(line_width / u_width, line_width / u_height) * normal_dir; + vec2 extension = vec2(aa_radius[1] / u_width, aa_radius[1] / u_height) * dir; + + float half_line_width = line_width * 0.5; + float half_line_length = line_length * 0.5; + + uv = vec2(-half_line_width, half_line_length); + gl_Position = vec4((ndc_a + normal - extension) * gl_in[0].gl_Position.w, gl_in[0].gl_Position.zw); + EmitVertex(); + + uv = vec2(-half_line_width, -half_line_length); + gl_Position = vec4((ndc_a - normal - extension) * gl_in[0].gl_Position.w, gl_in[0].gl_Position.zw); + EmitVertex(); + + uv = vec2(half_line_width, half_line_length); + gl_Position = vec4((ndc_b + normal + extension) * gl_in[1].gl_Position.w, gl_in[1].gl_Position.zw); + EmitVertex(); + + uv = vec2(half_line_width, -half_line_length); + gl_Position = vec4((ndc_b - normal + extension) * gl_in[1].gl_Position.w, gl_in[1].gl_Position.zw); + EmitVertex(); + + EndPrimitive(); +} diff --git a/resources/shaders/140/lines_width.vs b/resources/shaders/140/lines_width.vs new file mode 100644 index 000000000..b65bcbc7d --- /dev/null +++ b/resources/shaders/140/lines_width.vs @@ -0,0 +1,13 @@ +#version 150 + +// see as reference: https://github.com/mhalber/Lines/blob/master/geometry_shader_lines.h + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; + +in vec3 v_position; + +void main() +{ + gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0); +} \ No newline at end of file diff --git a/resources/shaders/140/mm_contour.fs b/resources/shaders/140/mm_contour.fs index e74124dca..28642d53f 100644 --- a/resources/shaders/140/mm_contour.fs +++ b/resources/shaders/140/mm_contour.fs @@ -2,7 +2,9 @@ uniform vec4 uniform_color; +out vec4 out_color; + void main() { - gl_FragColor = uniform_color; + out_color = uniform_color; } diff --git a/resources/shaders/140/mm_gouraud.fs b/resources/shaders/140/mm_gouraud.fs index e59d844f2..cd5ffb895 100644 --- a/resources/shaders/140/mm_gouraud.fs +++ b/resources/shaders/140/mm_gouraud.fs @@ -27,6 +27,8 @@ uniform mat3 normal_matrix; in vec3 clipping_planes_dots; in vec4 model_pos; +out vec4 out_color; + void main() { if (any(lessThan(clipping_planes_dots, ZERO))) @@ -59,5 +61,5 @@ void main() NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; - gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha); + out_color = vec4(vec3(intensity.y) + color * intensity.x, alpha); } diff --git a/resources/shaders/140/printbed.fs b/resources/shaders/140/printbed.fs index 5f1bce657..b10aa3f98 100644 --- a/resources/shaders/140/printbed.fs +++ b/resources/shaders/140/printbed.fs @@ -8,7 +8,8 @@ uniform bool transparent_background; uniform bool svg_source; in vec2 tex_coord; -out vec4 frag_color; + +out vec4 out_color; vec4 svg_color() { @@ -33,5 +34,5 @@ void main() { vec4 color = svg_source ? svg_color() : non_svg_color(); color.a = transparent_background ? color.a * 0.5 : color.a; - frag_color = color; + out_color = color; } \ No newline at end of file diff --git a/resources/shaders/140/toolpaths_cog.fs b/resources/shaders/140/toolpaths_cog.fs index 1c745dda9..010abe971 100644 --- a/resources/shaders/140/toolpaths_cog.fs +++ b/resources/shaders/140/toolpaths_cog.fs @@ -11,9 +11,11 @@ uniform vec3 world_center; in vec2 intensity; in vec3 world_position; +out vec4 out_color; + void main() { vec3 delta = world_position - world_center; vec4 color = delta.x * delta.y * delta.z > 0.0 ? BLACK : WHITE; - gl_FragColor = vec4(vec3(intensity.y) + color.rgb * (intensity.x + emission_factor), 1.0); + out_color = vec4(vec3(intensity.y) + color.rgb * (intensity.x + emission_factor), 1.0); } diff --git a/resources/shaders/140/variable_layer_height.fs b/resources/shaders/140/variable_layer_height.fs index cf1fc309c..658f81228 100644 --- a/resources/shaders/140/variable_layer_height.fs +++ b/resources/shaders/140/variable_layer_height.fs @@ -15,6 +15,8 @@ in vec2 intensity; in float object_z; +out vec4 out_color; + void main() { float object_z_row = z_to_texture_row * object_z; @@ -37,5 +39,5 @@ void main() color = mix(texture(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row + 0.5 )), -10000.), texture(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row * 2. + 1.)), 10000.), lod); // Mix the final color. - gl_FragColor = vec4(vec3(intensity.y), 1.0) + intensity.x * mix(color, vec4(1.0, 1.0, 0.0, 1.0), z_blend); + out_color = vec4(vec3(intensity.y), 1.0) + intensity.x * mix(color, vec4(1.0, 1.0, 0.0, 1.0), z_blend); } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index a89a7c8b0..e4c05aaa2 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -59,6 +59,8 @@ #define ENABLE_GL_SHADERS_ATTRIBUTES (1 && ENABLE_LEGACY_OPENGL_REMOVAL) // Enable rendering imgui using shaders #define ENABLE_GL_IMGUI_SHADERS (1 && ENABLE_GL_SHADERS_ATTRIBUTES) +// Enable OpenGL core profile context +#define ENABLE_GL_CORE_PROFILE (1 && ENABLE_GL_SHADERS_ATTRIBUTES) // Shows an imgui dialog with GLModel statistics data #define ENABLE_GLMODEL_STATISTICS (0 && ENABLE_LEGACY_OPENGL_REMOVAL) // Enable show non-manifold edges diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 1ce1af741..c95e1c06a 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -875,7 +875,9 @@ void Bed3D::render_default(bool bottom, bool picking, bool show_texture) if (!picking && show_texture) { // draw grid +#if !ENABLE_GL_CORE_PROFILE glsafe(::glLineWidth(1.5f * m_scale_factor)); +#endif // !ENABLE_GL_CORE_PROFILE m_gridlines.set_color(has_model && !bottom ? DEFAULT_SOLID_GRID_COLOR : DEFAULT_TRANSPARENT_GRID_COLOR); m_gridlines.render(); } diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index f25b89da8..1b2e800f4 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -389,7 +389,9 @@ void GLVolume::NonManifoldEdges::render() { update(); +#if !ENABLE_GL_CORE_PROFILE glsafe(::glLineWidth(2.0f)); +#endif // !ENABLE_GL_CORE_PROFILE #if ENABLE_GL_SHADERS_ATTRIBUTES GLShaderProgram* shader = GUI::wxGetApp().get_current_shader(); if (shader == nullptr) @@ -398,6 +400,11 @@ void GLVolume::NonManifoldEdges::render() const GUI::Camera& camera = GUI::wxGetApp().plater()->get_camera(); shader->set_uniform("view_model_matrix", camera.get_view_matrix() * m_parent.world_matrix()); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#if ENABLE_GL_CORE_PROFILE + const std::array& viewport = camera.get_viewport(); + shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); + shader->set_uniform("width", 1.5f); +#endif // ENABLE_GL_CORE_PROFILE #else glsafe(::glPushMatrix()); glsafe(::glMultMatrixd(m_parent.world_matrix().data())); @@ -1086,7 +1093,11 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab #if ENABLE_LEGACY_OPENGL_REMOVAL GLShaderProgram* sink_shader = GUI::wxGetApp().get_shader("flat"); +#if ENABLE_GL_CORE_PROFILE + GLShaderProgram* edges_shader = GUI::wxGetApp().get_shader("lines_width"); +#else GLShaderProgram* edges_shader = GUI::wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_CORE_PROFILE #endif // ENABLE_LEGACY_OPENGL_REMOVAL if (type == ERenderType::Transparent) { diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 2134a795f..a3889969e 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -69,6 +69,14 @@ void GCodeViewer::VBuffer::reset() glsafe(::glDeleteBuffers(static_cast(vbos.size()), static_cast(vbos.data()))); vbos.clear(); } + +#if ENABLE_GL_CORE_PROFILE + if (!vaos.empty()) { + glsafe(::glDeleteVertexArrays(static_cast(vaos.size()), static_cast(vaos.data()))); + vaos.clear(); + } +#endif // ENABLE_GL_CORE_PROFILE + sizes.clear(); count = 0; } @@ -302,6 +310,9 @@ void GCodeViewer::SequentialRangeCap::reset() { buffer = nullptr; ibo = 0; +#if ENABLE_GL_CORE_PROFILE + vao = 0; +#endif // ENABLE_GL_CORE_PROFILE vbo = 0; color = { 0.0f, 0.0f, 0.0f, 1.0f }; } @@ -724,7 +735,11 @@ void GCodeViewer::init() buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Line; #if ENABLE_GL_SHADERS_ATTRIBUTES buffer.vertices.format = VBuffer::EFormat::Position; +#if ENABLE_GL_CORE_PROFILE + buffer.shader = "lines_width"; +#else buffer.shader = "flat"; +#endif // ENABLE_GL_CORE_PROFILE #else buffer.vertices.format = VBuffer::EFormat::PositionNormal3; buffer.shader = "toolpaths_lines"; @@ -2044,13 +2059,24 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) ++m_statistics.vbuffers_count; #endif // ENABLE_GCODE_VIEWER_STATISTICS - GLuint id = 0; - glsafe(::glGenBuffers(1, &id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, id)); +#if ENABLE_GL_CORE_PROFILE + GLuint vao_id = 0; + glsafe(::glGenVertexArrays(1, &vao_id)); + glsafe(::glBindVertexArray(vao_id)); +#endif // ENABLE_GL_CORE_PROFILE + + GLuint vbo_id = 0; + glsafe(::glGenBuffers(1, &vbo_id)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, vbo_id)); glsafe(::glBufferData(GL_ARRAY_BUFFER, size_bytes, v_buffer.data(), GL_STATIC_DRAW)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - t_buffer.vertices.vbos.push_back(static_cast(id)); +#if ENABLE_GL_CORE_PROFILE + glsafe(::glBindVertexArray(0)); + + t_buffer.vertices.vaos.push_back(static_cast(vao_id)); +#endif // ENABLE_GL_CORE_PROFILE + t_buffer.vertices.vbos.push_back(static_cast(vbo_id)); t_buffer.vertices.sizes.push_back(size_bytes); } } @@ -2078,9 +2104,16 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) using CurrVertexBuffer = std::pair; std::vector curr_vertex_buffers(m_buffers.size(), { 0, 0 }); +#if ENABLE_GL_CORE_PROFILE + // variable used to keep track of the vertex buffers ids + using VIndexList = std::vector; + std::vector vao_indices(m_buffers.size()); + std::vector vbo_indices(m_buffers.size()); +#else // variable used to keep track of the vertex buffers ids using VboIndexList = std::vector; std::vector vbo_indices(m_buffers.size()); +#endif // ENABLE_GL_CORE_PROFILE size_t seams_count = 0; @@ -2112,13 +2145,25 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) TBuffer& t_buffer = m_buffers[id]; MultiIndexBuffer& i_multibuffer = indices[id]; CurrVertexBuffer& curr_vertex_buffer = curr_vertex_buffers[id]; +#if ENABLE_GL_CORE_PROFILE + VIndexList& vao_index_list = vao_indices[id]; + VIndexList& vbo_index_list = vbo_indices[id]; +#else VboIndexList& vbo_index_list = vbo_indices[id]; +#endif // ENABLE_GL_CORE_PROFILE // ensure there is at least one index buffer if (i_multibuffer.empty()) { i_multibuffer.push_back(IndexBuffer()); +#if ENABLE_GL_CORE_PROFILE + if (!t_buffer.vertices.vaos.empty()) { + vao_index_list.push_back(t_buffer.vertices.vaos[curr_vertex_buffer.first]); + vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]); + } +#else if (!t_buffer.vertices.vbos.empty()) vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]); +#endif // ENABLE_GL_CORE_PROFILE } // if adding the indices for the current segment exceeds the threshold size of the current index buffer @@ -2126,6 +2171,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) size_t indiced_size_to_add = (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) ? t_buffer.model.data.indices_size_bytes() : t_buffer.max_indices_per_segment_size_bytes(); if (i_multibuffer.back().size() * sizeof(IBufferType) >= IBUFFER_THRESHOLD_BYTES - indiced_size_to_add) { i_multibuffer.push_back(IndexBuffer()); +#if ENABLE_GL_CORE_PROFILE + vao_index_list.push_back(t_buffer.vertices.vaos[curr_vertex_buffer.first]); +#endif // ENABLE_GL_CORE_PROFILE vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]); if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::BatchedModel) { Path& last_path = t_buffer.paths.back(); @@ -2141,6 +2189,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) ++curr_vertex_buffer.first; curr_vertex_buffer.second = 0; +#if ENABLE_GL_CORE_PROFILE + vao_index_list.push_back(t_buffer.vertices.vaos[curr_vertex_buffer.first]); +#endif // ENABLE_GL_CORE_PROFILE vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]); if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::BatchedModel) { @@ -2198,6 +2249,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) t_buffer.indices.push_back(IBuffer()); IBuffer& ibuf = t_buffer.indices.back(); ibuf.count = size_elements; +#if ENABLE_GL_CORE_PROFILE + ibuf.vao = vao_indices[i][t_buffer.indices.size() - 1]; +#endif // ENABLE_GL_CORE_PROFILE ibuf.vbo = vbo_indices[i][t_buffer.indices.size() - 1]; #if ENABLE_GCODE_VIEWER_STATISTICS @@ -2827,6 +2881,9 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool SequentialRangeCap& cap = (*sequential_range_caps)[0]; const IBuffer& i_buffer = buffer.indices[ibuffer_id]; cap.buffer = &buffer; +#if ENABLE_GL_CORE_PROFILE + cap.vao = i_buffer.vao; +#endif // ENABLE_GL_CORE_PROFILE cap.vbo = i_buffer.vbo; // calculate offset into the index buffer @@ -2872,6 +2929,9 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool SequentialRangeCap& cap = (*sequential_range_caps)[1]; const IBuffer& i_buffer = buffer.indices[ibuffer_id]; cap.buffer = &buffer; +#if ENABLE_GL_CORE_PROFILE + cap.vao = i_buffer.vao; +#endif // ENABLE_GL_CORE_PROFILE cap.vbo = i_buffer.vbo; // calculate offset into the index buffer @@ -2958,6 +3018,14 @@ void GCodeViewer::render_toolpaths() assert(! path.sizes.empty()); assert(! path.offsets.empty()); shader.set_uniform(uniform_color, path.color); +#if ENABLE_GL_CORE_PROFILE + const Camera& camera = wxGetApp().plater()->get_camera(); + const std::array& viewport = camera.get_viewport(); + const double zoom = camera.get_zoom(); + shader.set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); + shader.set_uniform("width", (zoom < 5.0) ? 1.0 : (1.0 + 5.0 * (zoom - 5.0) / (100.0 - 5.0))); +#endif // ENABLE_GL_CORE_PROFILE + glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); #if ENABLE_GCODE_VIEWER_STATISTICS ++m_statistics.gl_multi_lines_calls_count; @@ -3037,6 +3105,9 @@ void GCodeViewer::render_toolpaths() for (size_t j = 0; j < buffer.indices.size(); ++j) { const IBuffer& i_buffer = buffer.indices[j]; buffer_range.last = buffer_range.first + i_buffer.count / indices_per_instance; +#if ENABLE_GL_CORE_PROFILE + glsafe(::glBindVertexArray(i_buffer.vao)); +#endif // ENABLE_GL_CORE_PROFILE glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo)); #if ENABLE_GL_SHADERS_ATTRIBUTES if (position_id != -1) { @@ -3093,14 +3164,19 @@ void GCodeViewer::render_toolpaths() glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); #endif // ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); +#if ENABLE_GL_CORE_PROFILE + glsafe(::glBindVertexArray(0)); +#endif // ENABLE_GL_CORE_PROFILE buffer_range.first = buffer_range.last; } }; +#if !ENABLE_GL_CORE_PROFILE auto line_width = [](double zoom) { return (zoom < 5.0) ? 1.0 : (1.0 + 5.0 * (zoom - 5.0) / (100.0 - 5.0)); }; +#endif // !ENABLE_GL_CORE_PROFILE const unsigned char begin_id = buffer_id(EMoveType::Retract); const unsigned char end_id = buffer_id(EMoveType::Count); @@ -3158,6 +3234,9 @@ void GCodeViewer::render_toolpaths() // Not found. This shall not happen. continue; +#if ENABLE_GL_CORE_PROFILE + glsafe(::glBindVertexArray(i_buffer.vao)); +#endif // ENABLE_GL_CORE_PROFILE glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo)); #if ENABLE_GL_SHADERS_ATTRIBUTES if (position_id != -1) { @@ -3187,7 +3266,9 @@ void GCodeViewer::render_toolpaths() switch (buffer.render_primitive_type) { case TBuffer::ERenderPrimitiveType::Line: { +#if !ENABLE_GL_CORE_PROFILE glsafe(::glLineWidth(static_cast(line_width(zoom)))); +#endif // !ENABLE_GL_CORE_PROFILE render_as_lines(it_path, buffer.render_paths.end(), *shader, uniform_color); break; } @@ -3212,6 +3293,9 @@ void GCodeViewer::render_toolpaths() glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); #endif // ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); +#if ENABLE_GL_CORE_PROFILE + glsafe(::glBindVertexArray(0)); +#endif // ENABLE_GL_CORE_PROFILE } } @@ -3241,6 +3325,9 @@ void GCodeViewer::render_toolpaths() const int normal_id = shader->get_attrib_location("v_normal"); #endif // ENABLE_GL_SHADERS_ATTRIBUTES +#if ENABLE_GL_CORE_PROFILE + glsafe(::glBindVertexArray(cap.vao)); +#endif // ENABLE_GL_CORE_PROFILE glsafe(::glBindBuffer(GL_ARRAY_BUFFER, cap.vbo)); #if ENABLE_GL_SHADERS_ATTRIBUTES if (position_id != -1) { @@ -3287,6 +3374,9 @@ void GCodeViewer::render_toolpaths() #endif // ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); +#if ENABLE_GL_CORE_PROFILE + glsafe(::glBindVertexArray(0)); +#endif // ENABLE_GL_CORE_PROFILE shader->stop_using(); }; @@ -4668,4 +4758,3 @@ ColorRGBA GCodeViewer::option_color(EMoveType move_type) const } // namespace GUI } // namespace Slic3r - diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 51adcab5a..e3325f055 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -62,6 +62,10 @@ class GCodeViewer }; EFormat format{ EFormat::Position }; +#if ENABLE_GL_CORE_PROFILE + // vaos id + std::vector vaos; +#endif // ENABLE_GL_CORE_PROFILE // vbos id std::vector vbos; // sizes of the buffers, in bytes, used in export to obj @@ -162,6 +166,10 @@ class GCodeViewer // ibo buffer containing indices data (for lines/triangles) used to render a specific toolpath type struct IBuffer { +#if ENABLE_GL_CORE_PROFILE + // id of the associated vertex array buffer + unsigned int vao{ 0 }; +#endif // ENABLE_GL_CORE_PROFILE // id of the associated vertex buffer unsigned int vbo{ 0 }; // ibo id @@ -356,7 +364,11 @@ class GCodeViewer { case ERenderPrimitiveType::Line: case ERenderPrimitiveType::Triangle: { +#if ENABLE_GL_CORE_PROFILE + return !vertices.vaos.empty() && vertices.vaos.front() != 0 && !indices.empty() && indices.front().ibo != 0; +#else return !vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0; +#endif // ENABLE_GL_CORE_PROFILE } case ERenderPrimitiveType::InstancedModel: { return model.model.is_initialized() && !model.instances.buffer.empty(); } case ERenderPrimitiveType::BatchedModel: { @@ -365,7 +377,11 @@ class GCodeViewer #else return model.data.vertices_count() > 0 && model.data.indices_count() && #endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_CORE_PROFILE + !vertices.vaos.empty() && vertices.vaos.front() != 0 && !indices.empty() && indices.front().ibo != 0; +#else !vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0; +#endif // ENABLE_GL_CORE_PROFILE } default: { return false; } } @@ -558,8 +574,11 @@ class GCodeViewer struct SequentialRangeCap { TBuffer* buffer{ nullptr }; - unsigned int ibo{ 0 }; +#if ENABLE_GL_CORE_PROFILE + unsigned int vao{ 0 }; +#endif // ENABLE_GL_CORE_PROFILE unsigned int vbo{ 0 }; + unsigned int ibo{ 0 }; ColorRGBA color; ~SequentialRangeCap(); @@ -906,4 +925,3 @@ private: } // namespace Slic3r #endif // slic3r_GCodeViewer_hpp_ - diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index adab374f5..eeed9099c 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -625,7 +625,7 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G glvolume->render(); } // Revert back to the previous shader. - glBindTexture(GL_TEXTURE_2D, 0); + glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); } void GLCanvas3D::LayersEditing::adjust_layer_height_profile() @@ -6080,7 +6080,9 @@ void GLCanvas3D::_render_camera_target() static const float half_length = 5.0f; glsafe(::glDisable(GL_DEPTH_TEST)); +#if !ENABLE_GL_CORE_PROFILE glsafe(::glLineWidth(2.0f)); +#endif // !ENABLE_GL_CORE_PROFILE #if ENABLE_LEGACY_OPENGL_REMOVAL const Vec3f& target = wxGetApp().plater()->get_camera().get_target().cast(); @@ -6117,13 +6119,22 @@ void GLCanvas3D::_render_camera_target() } } +#if ENABLE_GL_CORE_PROFILE + GLShaderProgram* shader = wxGetApp().get_shader("lines_width"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_CORE_PROFILE if (shader != nullptr) { shader->start_using(); #if ENABLE_GL_SHADERS_ATTRIBUTES const Camera& camera = wxGetApp().plater()->get_camera(); - shader->set_uniform("view_model_matrix", camera.get_view_matrix() * Geometry::assemble_transform(m_camera_target.target)); + shader->set_uniform("view_model_matrix", camera.get_view_matrix()); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#if ENABLE_GL_CORE_PROFILE + const std::array& viewport = camera.get_viewport(); + shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); + shader->set_uniform("width", 1.5f); +#endif // ENABLE_GL_CORE_PROFILE #endif // ENABLE_GL_SHADERS_ATTRIBUTES for (int i = 0; i < 3; ++i) { m_camera_target.axis[i].render(); diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index e6bdae415..db75bf4d3 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -723,6 +723,12 @@ void GLModel::reset() s_statistics.gpu_memory.vertices.current -= vertices_size_bytes(); #endif // ENABLE_GLMODEL_STATISTICS } +#if ENABLE_GL_CORE_PROFILE + if (m_render_data.vao_id > 0) { + glsafe(::glDeleteVertexArrays(1, &m_render_data.vao_id)); + m_render_data.vao_id = 0; + } +#endif // ENABLE_GL_CORE_PROFILE m_render_data.vertices_count = 0; m_render_data.indices_count = 0; @@ -832,7 +838,11 @@ void GLModel::render(const std::pair& range) return; // sends data to gpu if not done yet +#if ENABLE_GL_CORE_PROFILE + if (m_render_data.vao_id == 0) { +#else if (m_render_data.vbo_id == 0 || m_render_data.ibo_id == 0) { +#endif // ENABLE_GL_CORE_PROFILE if (m_render_data.geometry.vertices_count() > 0 && m_render_data.geometry.indices_count() > 0 && !send_to_gpu()) return; } @@ -847,6 +857,10 @@ void GLModel::render(const std::pair& range) const bool normal = Geometry::has_normal(data.format); const bool tex_coord = Geometry::has_tex_coord(data.format); +#if ENABLE_GL_CORE_PROFILE + glsafe(::glBindVertexArray(m_render_data.vao_id)); + // the following binding is needed to set the vertex attributes +#endif // ENABLE_GL_CORE_PROFILE glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id)); #if ENABLE_GL_SHADERS_ATTRIBUTES @@ -894,9 +908,13 @@ void GLModel::render(const std::pair& range) shader->set_uniform("uniform_color", data.color); +#if !ENABLE_GL_CORE_PROFILE glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_render_data.ibo_id)); +#endif // !ENABLE_GL_CORE_PROFILE glsafe(::glDrawElements(mode, range.second - range.first, index_type, (const void*)(range.first * Geometry::index_stride_bytes(data)))); +#if !ENABLE_GL_CORE_PROFILE glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); +#endif // !ENABLE_GL_CORE_PROFILE #if ENABLE_GL_SHADERS_ATTRIBUTES if (tex_coord_id != -1) @@ -915,6 +933,9 @@ void GLModel::render(const std::pair& range) #endif // ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); +#if ENABLE_GL_CORE_PROFILE + glsafe(::glBindVertexArray(0)); +#endif // ENABLE_GL_CORE_PROFILE #if ENABLE_GLMODEL_STATISTICS ++s_statistics.render_calls; @@ -948,7 +969,11 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance if (offset_id == -1 || scales_id == -1) return; +#if ENABLE_GL_CORE_PROFILE + if (m_render_data.vao_id == 0) { +#else if (m_render_data.vbo_id == 0 || m_render_data.ibo_id == 0) { +#endif // ENABLE_GL_CORE_PROFILE if (!send_to_gpu()) return; } @@ -966,6 +991,10 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance assert(offset_id != -1 && scales_id != -1); #endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_CORE_PROFILE + glsafe(::glBindVertexArray(m_render_data.vao_id)); +#endif // ENABLE_GL_CORE_PROFILE + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, instances_vbo)); #if ENABLE_LEGACY_OPENGL_REMOVAL const size_t instance_stride = 5 * sizeof(float); @@ -999,6 +1028,9 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance const bool position = Geometry::has_position(data.format); const bool normal = Geometry::has_normal(data.format); +#if ENABLE_GL_CORE_PROFILE + // the following binding is needed to set the vertex attributes +#endif // ENABLE_GL_CORE_PROFILE glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id)); if (position) { @@ -1013,9 +1045,13 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance shader->set_uniform("uniform_color", data.color); +#if !ENABLE_GL_CORE_PROFILE glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_render_data.ibo_id)); +#endif // !ENABLE_GL_CORE_PROFILE glsafe(::glDrawElementsInstanced(mode, indices_count(), index_type, (const void*)0, instances_count)); +#if !ENABLE_GL_CORE_PROFILE glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); +#endif // !ENABLE_GL_CORE_PROFILE if (normal) glsafe(::glDisableVertexAttribArray(normal_id)); @@ -1071,6 +1107,9 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance #endif // ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); +#if ENABLE_GL_CORE_PROFILE + glsafe(::glBindVertexArray(0)); +#endif // ENABLE_GL_CORE_PROFILE #if ENABLE_GLMODEL_STATISTICS ++s_statistics.render_instanced_calls; @@ -1091,6 +1130,11 @@ bool GLModel::send_to_gpu() return false; } +#if ENABLE_GL_CORE_PROFILE + glsafe(::glGenVertexArrays(1, &m_render_data.vao_id)); + glsafe(::glBindVertexArray(m_render_data.vao_id)); +#endif // ENABLE_GL_CORE_PROFILE + // vertices glsafe(::glGenBuffers(1, &m_render_data.vbo_id)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id)); @@ -1104,9 +1148,9 @@ bool GLModel::send_to_gpu() data.vertices = std::vector(); // indices + const size_t indices_count = data.indices.size(); glsafe(::glGenBuffers(1, &m_render_data.ibo_id)); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_render_data.ibo_id)); - const size_t indices_count = data.indices.size(); if (m_render_data.vertices_count <= 256) { // convert indices to unsigned char to save gpu memory std::vector reduced_indices(indices_count); @@ -1115,7 +1159,6 @@ bool GLModel::send_to_gpu() } data.index_type = Geometry::EIndexType::UBYTE; glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_count * sizeof(unsigned char), reduced_indices.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); } else if (m_render_data.vertices_count <= 65536) { // convert indices to unsigned short to save gpu memory @@ -1125,13 +1168,15 @@ bool GLModel::send_to_gpu() } data.index_type = Geometry::EIndexType::USHORT; glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_count * sizeof(unsigned short), reduced_indices.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); } else { data.index_type = Geometry::EIndexType::UINT; glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.indices_size_bytes(), data.indices.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); } + +#if !ENABLE_GL_CORE_PROFILE + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); +#endif // !ENABLE_GL_CORE_PROFILE m_render_data.indices_count = indices_count; #if ENABLE_GLMODEL_STATISTICS s_statistics.gpu_memory.indices.current += data.indices_size_bytes(); @@ -1139,6 +1184,10 @@ bool GLModel::send_to_gpu() #endif // ENABLE_GLMODEL_STATISTICS data.indices = std::vector(); +#if ENABLE_GL_CORE_PROFILE + glsafe(::glBindVertexArray(0)); +#endif // ENABLE_GL_CORE_PROFILE + return true; } diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index 3176780bf..ea885ffe9 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -167,6 +167,9 @@ namespace GUI { struct RenderData { Geometry geometry; +#if ENABLE_GL_CORE_PROFILE + unsigned int vao_id{ 0 }; +#endif // ENABLE_GL_CORE_PROFILE unsigned int vbo_id{ 0 }; unsigned int ibo_id{ 0 }; size_t vertices_count{ 0 }; diff --git a/src/slic3r/GUI/GLSelectionRectangle.cpp b/src/slic3r/GUI/GLSelectionRectangle.cpp index a8be0f84e..bff1a5a52 100644 --- a/src/slic3r/GUI/GLSelectionRectangle.cpp +++ b/src/slic3r/GUI/GLSelectionRectangle.cpp @@ -105,7 +105,9 @@ namespace GUI { const float bottom = (float)std::min(start.y(), end.y()) * inv_zoom; #endif // ENABLE_GL_SHADERS_ATTRIBUTES +#if !ENABLE_GL_CORE_PROFILE glsafe(::glLineWidth(1.5f)); +#endif // !ENABLE_GL_CORE_PROFILE #if !ENABLE_LEGACY_OPENGL_REMOVAL float color[3]; color[0] = (m_state == EState::Select) ? 0.3f : 1.0f; @@ -126,9 +128,11 @@ namespace GUI { glsafe(::glScaled(gui_scale, gui_scale, 1.0)); #endif // !ENABLE_GL_SHADERS_ATTRIBUTES +#if !ENABLE_GL_CORE_PROFILE glsafe(::glPushAttrib(GL_ENABLE_BIT)); glsafe(::glLineStipple(4, 0xAAAA)); glsafe(::glEnable(GL_LINE_STIPPLE)); +#endif // !ENABLE_GL_CORE_PROFILE #if ENABLE_LEGACY_OPENGL_REMOVAL GLShaderProgram* shader = wxGetApp().get_shader("flat"); @@ -178,7 +182,9 @@ namespace GUI { glsafe(::glEnd()); #endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if !ENABLE_GL_CORE_PROFILE glsafe(::glPopAttrib()); +#endif // !ENABLE_GL_CORE_PROFILE #if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); diff --git a/src/slic3r/GUI/GLShader.cpp b/src/slic3r/GUI/GLShader.cpp index 9e3001d77..719b1bbae 100644 --- a/src/slic3r/GUI/GLShader.cpp +++ b/src/slic3r/GUI/GLShader.cpp @@ -321,6 +321,19 @@ void GLShaderProgram::set_uniform(int id, const Matrix4d& value) const } #endif // ENABLE_GL_IMGUI_SHADERS +#if ENABLE_GL_CORE_PROFILE +void GLShaderProgram::set_uniform(int id, const Vec2f& value) const +{ + if (id >= 0) + glsafe(::glUniform2fv(id, 1, static_cast(value.data()))); +} + +void GLShaderProgram::set_uniform(int id, const Vec2d& value) const +{ + set_uniform(id, static_cast(value.cast())); +} +#endif // ENABLE_GL_CORE_PROFILE + void GLShaderProgram::set_uniform(int id, const Vec3f& value) const { if (id >= 0) diff --git a/src/slic3r/GUI/GLShader.hpp b/src/slic3r/GUI/GLShader.hpp index 72edb8b66..80d2242c2 100644 --- a/src/slic3r/GUI/GLShader.hpp +++ b/src/slic3r/GUI/GLShader.hpp @@ -69,6 +69,10 @@ public: void set_uniform(const char* name, const Matrix4f& value) const { set_uniform(get_uniform_location(name), value); } void set_uniform(const char* name, const Matrix4d& value) const { set_uniform(get_uniform_location(name), value); } #endif // ENABLE_GL_IMGUI_SHADERS +#if ENABLE_GL_CORE_PROFILE + void set_uniform(const char* name, const Vec2f& value) const { set_uniform(get_uniform_location(name), value); } + void set_uniform(const char* name, const Vec2d& value) const { set_uniform(get_uniform_location(name), value); } +#endif // ENABLE_GL_CORE_PROFILE void set_uniform(const char* name, const Vec3f& value) const { set_uniform(get_uniform_location(name), value); } void set_uniform(const char* name, const Vec3d& value) const { set_uniform(get_uniform_location(name), value); } void set_uniform(const char* name, const ColorRGB& value) const { set_uniform(get_uniform_location(name), value); } @@ -96,6 +100,10 @@ public: void set_uniform(int id, const Matrix4f& value) const; void set_uniform(int id, const Matrix4d& value) const; #endif // ENABLE_GL_IMGUI_SHADERS +#if ENABLE_GL_CORE_PROFILE + void set_uniform(int id, const Vec2f& value) const; + void set_uniform(int id, const Vec2d& value) const; +#endif // ENABLE_GL_CORE_PROFILE void set_uniform(int id, const Vec3f& value) const; void set_uniform(int id, const Vec3d& value) const; void set_uniform(int id, const ColorRGB& value) const; diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index 9edd39d7f..2771563ae 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -46,6 +46,10 @@ std::pair GLShadersManager::init() valid &= append_shader("flat_texture", { prefix + "flat_texture.vs", prefix + "flat_texture.fs" }); // used to render 3D scene background valid &= append_shader("background", { prefix + "background.vs", prefix + "background.fs" }); +#if ENABLE_GL_CORE_PROFILE + // used to render thick lines + valid &= append_shader("lines_width", { prefix + "lines_width.vs", prefix + "lines_width.fs", prefix + "lines_width.gs" }); +#endif // ENABLE_GL_CORE_PROFILE #else // basic shader, used to render all what was previously rendered using the immediate mode valid &= append_shader("flat", { "flat.vs", "flat.fs" }); diff --git a/src/slic3r/GUI/GLTexture.cpp b/src/slic3r/GUI/GLTexture.cpp index 137a0a109..f8cb32ee5 100644 --- a/src/slic3r/GUI/GLTexture.cpp +++ b/src/slic3r/GUI/GLTexture.cpp @@ -334,8 +334,10 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right, glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); +#if !ENABLE_GL_CORE_PROFILE glsafe(::glEnable(GL_TEXTURE_2D)); glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)); +#endif // !ENABLE_GL_CORE_PROFILE glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)tex_id)); @@ -351,7 +353,7 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right, init_data.add_vertex(Vec2f(right, top), Vec2f(uvs.right_top.u, uvs.right_top.v)); init_data.add_vertex(Vec2f(left, top), Vec2f(uvs.left_top.u, uvs.left_top.v)); - // indices + // indices init_data.add_triangle(0, 1, 2); init_data.add_triangle(2, 3, 0); @@ -379,7 +381,9 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right, glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); +#if !ENABLE_GL_CORE_PROFILE glsafe(::glDisable(GL_TEXTURE_2D)); +#endif // !ENABLE_GL_CORE_PROFILE glsafe(::glDisable(GL_BLEND)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 9a87d5a45..9e60d079b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -167,7 +167,9 @@ void GLGizmoCut::on_render() glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); +#if !ENABLE_GL_CORE_PROFILE glsafe(::glLineWidth(m_hover_id != -1 ? 2.0f : 1.5f)); +#endif // !ENABLE_GL_CORE_PROFILE #if ENABLE_LEGACY_OPENGL_REMOVAL if (!m_grabber_connection.is_initialized() || is_changed) { m_grabber_connection.reset(); @@ -226,7 +228,9 @@ void GLGizmoCut::on_render() glsafe(::glPushMatrix()); glsafe(::glTranslated(m_cut_contours.shift.x(), m_cut_contours.shift.y(), m_cut_contours.shift.z())); #endif // ENABLE_GL_SHADERS_ATTRIBUTES +#if !ENABLE_GL_CORE_PROFILE glsafe(::glLineWidth(2.0f)); +#endif // !ENABLE_GL_CORE_PROFILE m_cut_contours.contours.render(); #if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 9dfb8bc9e..87e58e700 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -132,7 +132,9 @@ void GLGizmoMove3D::on_render() m_grabbers[2].center = { center.x(), center.y(), box.max.z() + Offset }; m_grabbers[2].color = AXES_COLOR[2]; +#if !ENABLE_GL_CORE_PROFILE glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); +#endif // !ENABLE_GL_CORE_PROFILE #if ENABLE_LEGACY_OPENGL_REMOVAL auto render_grabber_connection = [this, ¢er](unsigned int id) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index 0cba59c6d..4b2929280 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -192,7 +192,9 @@ void GLGizmoPainterBase::render_cursor_circle() center = center * inv_zoom; #endif // ENABLE_GL_SHADERS_ATTRIBUTES +#if !ENABLE_GL_CORE_PROFILE glsafe(::glLineWidth(1.5f)); +#endif // !ENABLE_GL_CORE_PROFILE #if !ENABLE_LEGACY_OPENGL_REMOVAL static const std::array color = { 0.f, 1.f, 0.3f }; glsafe(::glColor3fv(color.data())); @@ -209,9 +211,11 @@ void GLGizmoPainterBase::render_cursor_circle() glsafe(::glScaled(gui_scale, gui_scale, 1.0)); #endif // !ENABLE_GL_SHADERS_ATTRIBUTES +#if !ENABLE_GL_CORE_PROFILE glsafe(::glPushAttrib(GL_ENABLE_BIT)); glsafe(::glLineStipple(4, 0xAAAA)); glsafe(::glEnable(GL_LINE_STIPPLE)); +#endif // !ENABLE_GL_CORE_PROFILE #if ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_GL_SHADERS_ATTRIBUTES @@ -264,7 +268,9 @@ void GLGizmoPainterBase::render_cursor_circle() glsafe(::glEnd()); #endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if !ENABLE_GL_CORE_PROFILE glsafe(::glPopAttrib()); +#endif // !ENABLE_GL_CORE_PROFILE #if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); #endif // !ENABLE_GL_SHADERS_ATTRIBUTES diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index b4b9e0777..0470649d9 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -175,7 +175,9 @@ void GLGizmoRotate::on_render() transform_to_local(selection); #endif // ENABLE_GL_SHADERS_ATTRIBUTES +#if !ENABLE_GL_CORE_PROFILE glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); +#endif // !ENABLE_GL_CORE_PROFILE #if ENABLE_LEGACY_OPENGL_REMOVAL GLShaderProgram* shader = wxGetApp().get_shader("flat"); if (shader != nullptr) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp index 26c9251b4..2c77066a9 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp @@ -256,7 +256,9 @@ void GLGizmoScale3D::on_render() m_grabbers[i].angles = angles; } +#if !ENABLE_GL_CORE_PROFILE glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); +#endif // !ENABLE_GL_CORE_PROFILE const BoundingBoxf3& selection_box = selection.get_bounding_box(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp index 43169df10..e05a1f708 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp @@ -743,7 +743,11 @@ void GLGizmoSimplify::on_render() glsafe(::glMultMatrixd(trafo_matrix.data())); #endif // !ENABLE_GL_SHADERS_ATTRIBUTES auto* gouraud_shader = wxGetApp().get_shader("gouraud_light"); +#if ENABLE_GL_CORE_PROFILE + bool depth_test_enabled = ::glIsEnabled(GL_DEPTH_TEST); +#else glsafe(::glPushAttrib(GL_DEPTH_TEST)); +#endif // ENABLE_GL_CORE_PROFILE glsafe(::glEnable(GL_DEPTH_TEST)); gouraud_shader->start_using(); #if ENABLE_GL_SHADERS_ATTRIBUTES @@ -766,7 +770,9 @@ void GLGizmoSimplify::on_render() const ColorRGBA color = glmodel.get_color(); glmodel.set_color(ColorRGBA::WHITE()); #endif // ENABLE_GL_SHADERS_ATTRIBUTES +#if !ENABLE_GL_CORE_PROFILE glsafe(::glLineWidth(1.0f)); +#endif // !ENABLE_GL_CORE_PROFILE glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)); glmodel.render(); glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); @@ -775,7 +781,12 @@ void GLGizmoSimplify::on_render() #endif // ENABLE_GL_SHADERS_ATTRIBUTES contour_shader->stop_using(); } +#if ENABLE_GL_CORE_PROFILE + if (depth_test_enabled) + glsafe(::glEnable(GL_DEPTH_TEST)); +#else glsafe(::glPopAttrib()); +#endif // ENABLE_GL_CORE_PROFILE #if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); #endif // !ENABLE_GL_SHADERS_ATTRIBUTES diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp index f1156f937..add0f320a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp @@ -224,14 +224,23 @@ void InstancesHider::render_cut() const glsafe(::glColor4fv(color.data())); } #endif // !ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_CORE_PROFILE + bool depth_test_enabled = ::glIsEnabled(GL_DEPTH_TEST); +#else glsafe(::glPushAttrib(GL_DEPTH_TEST)); +#endif // ENABLE_GL_CORE_PROFILE glsafe(::glDisable(GL_DEPTH_TEST)); #if ENABLE_LEGACY_OPENGL_REMOVAL clipper->render_cut(mv->is_model_part() ? ColorRGBA(0.8f, 0.3f, 0.0f, 1.0f) : color_from_model_volume(*mv)); #else clipper->render_cut(); #endif // ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_CORE_PROFILE + if (depth_test_enabled) + glsafe(::glEnable(GL_DEPTH_TEST)); +#else glsafe(::glPopAttrib()); +#endif // ENABLE_GL_CORE_PROFILE #if !ENABLE_GL_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); #endif // !ENABLE_GL_SHADERS_ATTRIBUTES diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 5ab4685bf..15ce01c40 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -1482,6 +1482,37 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) draw_data->ScaleClipRects(io.DisplayFramebufferScale); #endif // ENABLE_GL_IMGUI_SHADERS +#if ENABLE_GL_CORE_PROFILE + // Backup GL state + GLenum last_active_texture; glsafe(::glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture)); + GLuint last_program; glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&last_program)); + GLuint last_texture; glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)&last_texture)); + GLuint last_array_buffer; glsafe(::glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer)); + GLuint last_vertex_array_object; glsafe(::glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&last_vertex_array_object)); + GLint last_viewport[4]; glsafe(::glGetIntegerv(GL_VIEWPORT, last_viewport)); + GLint last_scissor_box[4]; glsafe(::glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box)); + GLenum last_blend_src_rgb; glsafe(::glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb)); + GLenum last_blend_dst_rgb; glsafe(::glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb)); + GLenum last_blend_src_alpha; glsafe(::glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha)); + GLenum last_blend_dst_alpha; glsafe(::glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha)); + GLenum last_blend_equation_rgb; glsafe(::glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb)); + GLenum last_blend_equation_alpha; glsafe(::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_stencil_test = ::glIsEnabled(GL_STENCIL_TEST); + GLboolean last_enable_scissor_test = ::glIsEnabled(GL_SCISSOR_TEST); + + // set new GL state + glsafe(::glActiveTexture(GL_TEXTURE0)); + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendEquation(GL_FUNC_ADD)); + glsafe(::glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); + glsafe(::glDisable(GL_CULL_FACE)); + glsafe(::glDisable(GL_DEPTH_TEST)); + glsafe(::glDisable(GL_STENCIL_TEST)); + glsafe(::glEnable(GL_SCISSOR_TEST)); +#else // 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; glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture)); @@ -1494,6 +1525,7 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); glsafe(::glDisable(GL_CULL_FACE)); glsafe(::glDisable(GL_DEPTH_TEST)); + glsafe(::glDisable(GL_STENCIL_TEST)); glsafe(::glEnable(GL_SCISSOR_TEST)); #if !ENABLE_GL_IMGUI_SHADERS glsafe(::glDisable(GL_LIGHTING)); @@ -1505,6 +1537,7 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) glsafe(::glEnable(GL_TEXTURE_2D)); glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)); +#endif // ENABLE_GL_CORE_PROFILE #if ENABLE_GL_IMGUI_SHADERS // Setup viewport, orthographic projection matrix @@ -1550,16 +1583,17 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) const GLsizeiptr vtx_buffer_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert); const GLsizeiptr idx_buffer_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx); +#if ENABLE_GL_CORE_PROFILE + GLuint vao_id = 0; + glsafe(::glGenVertexArrays(1, &vao_id)); + glsafe(::glBindVertexArray(vao_id)); +#endif // ENABLE_GL_CORE_PROFILE + GLuint vbo_id; glsafe(::glGenBuffers(1, &vbo_id)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, vbo_id)); glsafe(::glBufferData(GL_ARRAY_BUFFER, vtx_buffer_size, vtx_buffer, GL_STATIC_DRAW)); - GLuint ibo_id; - glsafe(::glGenBuffers(1, &ibo_id)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id)); - glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, idx_buffer, GL_STATIC_DRAW)); - const int position_id = shader->get_attrib_location("Position"); if (position_id != -1) { glsafe(::glVertexAttribPointer(position_id, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (const void*)IM_OFFSETOF(ImDrawVert, pos))); @@ -1575,6 +1609,11 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) glsafe(::glVertexAttribPointer(color_id, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (const void*)IM_OFFSETOF(ImDrawVert, col))); glsafe(::glEnableVertexAttribArray(color_id)); } + + GLuint ibo_id; + glsafe(::glGenBuffers(1, &ibo_id)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id)); + glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, idx_buffer, GL_STATIC_DRAW)); #else glsafe(::glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos)))); glsafe(::glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv)))); @@ -1618,21 +1657,41 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) } #if ENABLE_GL_IMGUI_SHADERS - if (position_id != -1) - glsafe(::glDisableVertexAttribArray(position_id)); - if (uv_id != -1) - glsafe(::glDisableVertexAttribArray(uv_id)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + if (color_id != -1) glsafe(::glDisableVertexAttribArray(color_id)); + if (uv_id != -1) + glsafe(::glDisableVertexAttribArray(uv_id)); + if (position_id != -1) + glsafe(::glDisableVertexAttribArray(position_id)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); glsafe(::glDeleteBuffers(1, &ibo_id)); glsafe(::glDeleteBuffers(1, &vbo_id)); +#if ENABLE_GL_CORE_PROFILE + glsafe(::glDeleteVertexArrays(1, &vao_id)); +#endif // ENABLE_GL_CORE_PROFILE #endif // ENABLE_GL_IMGUI_SHADERS } +#if ENABLE_GL_CORE_PROFILE + // Restore modified GL state + glsafe(::glBindTexture(GL_TEXTURE_2D, last_texture)); + glsafe(::glActiveTexture(last_active_texture)); + glsafe(::glBindVertexArray(last_vertex_array_object)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer)); + glsafe(::glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha)); + glsafe(::glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha)); + if (last_enable_blend) glsafe(::glEnable(GL_BLEND)); else glsafe(::glDisable(GL_BLEND)); + if (last_enable_cull_face) glsafe(::glEnable(GL_CULL_FACE)); else glsafe(::glDisable(GL_CULL_FACE)); + if (last_enable_depth_test) glsafe(::glEnable(GL_DEPTH_TEST)); else glsafe(::glDisable(GL_DEPTH_TEST)); + if (last_enable_stencil_test) glsafe(::glEnable(GL_STENCIL_TEST)); else glsafe(::glDisable(GL_STENCIL_TEST)); + if (last_enable_scissor_test) glsafe(::glEnable(GL_SCISSOR_TEST)); else glsafe(::glDisable(GL_SCISSOR_TEST)); + glsafe(::glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3])); + glsafe(::glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3])); +#else // Restore modified state glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, last_texture_env_mode)); glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture)); @@ -1647,9 +1706,10 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) #endif // !ENABLE_GL_IMGUI_SHADERS glsafe(::glPopAttrib()); glsafe(::glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); - glsafe(::glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]))); + glsafe(::glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]))); glsafe(::glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3])); glsafe(::glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3])); +#endif // ENABLE_GL_CORE_PROFILE #if ENABLE_GL_IMGUI_SHADERS shader->stop_using(); diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp index 3bf0b1b27..12daa2946 100644 --- a/src/slic3r/GUI/OpenGLManager.cpp +++ b/src/slic3r/GUI/OpenGLManager.cpp @@ -95,10 +95,10 @@ float OpenGLManager::GLInfo::get_max_anisotropy() const void OpenGLManager::GLInfo::detect() const { - *const_cast(&m_version) = gl_get_string_safe(GL_VERSION, "N/A"); + *const_cast(&m_version) = gl_get_string_safe(GL_VERSION, "N/A"); *const_cast(&m_glsl_version) = gl_get_string_safe(GL_SHADING_LANGUAGE_VERSION, "N/A"); - *const_cast(&m_vendor) = gl_get_string_safe(GL_VENDOR, "N/A"); - *const_cast(&m_renderer) = gl_get_string_safe(GL_RENDERER, "N/A"); + *const_cast(&m_vendor) = gl_get_string_safe(GL_VENDOR, "N/A"); + *const_cast(&m_renderer) = gl_get_string_safe(GL_RENDERER, "N/A"); int* max_tex_size = const_cast(&m_max_tex_size); glsafe(::glGetIntegerv(GL_MAX_TEXTURE_SIZE, max_tex_size)); @@ -180,6 +180,9 @@ std::string OpenGLManager::GLInfo::to_string(bool for_github) const out << h2_start << "OpenGL installation" << h2_end << line_end; out << b_start << "GL version: " << b_end << m_version << line_end; +#if ENABLE_GL_CORE_PROFILE + out << b_start << "Profile: " << b_end << (GLEW_ARB_compatibility ? "Compatibility" : "Core") << line_end; +#endif // ENABLE_GL_CORE_PROFILE out << b_start << "Vendor: " << b_end << m_vendor << line_end; out << b_start << "Renderer: " << b_end << m_renderer << line_end; out << b_start << "GLSL version: " << b_end << m_glsl_version << line_end; @@ -238,16 +241,34 @@ OpenGLManager::~OpenGLManager() bool OpenGLManager::init_gl() { if (!m_gl_initialized) { +#if ENABLE_GL_CORE_PROFILE + glewExperimental = true; +#endif // ENABLE_GL_CORE_PROFILE GLenum err = glewInit(); if (err != GLEW_OK) { BOOST_LOG_TRIVIAL(error) << "Unable to init glew library: " << glewGetErrorString(err); return false; } + +#if ENABLE_GL_CORE_PROFILE + do { + // glewInit() generates an OpenGL GL_INVALID_ENUM error + err = ::glGetError(); + } while (err != GL_NO_ERROR); +#endif // ENABLE_GL_CORE_PROFILE + m_gl_initialized = true; +#if ENABLE_GL_CORE_PROFILE + if (GLEW_ARB_texture_compression) + s_compressed_textures_supported = true; + else + s_compressed_textures_supported = false; +#else if (GLEW_EXT_texture_compression_s3tc) s_compressed_textures_supported = true; else s_compressed_textures_supported = false; +#endif // ENABLE_GL_CORE_PROFILE if (GLEW_ARB_framebuffer_object) s_framebuffers_type = EFramebufferType::Arb; @@ -288,7 +309,13 @@ bool OpenGLManager::init_gl() wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas) { if (m_context == nullptr) { +#if ENABLE_GL_CORE_PROFILE + wxGLContextAttrs attrs; + attrs.CoreProfile().ForwardCompatible().OGLVersion(3, 3).EndList(); + m_context = new wxGLContext(&canvas, nullptr, &attrs); +#else m_context = new wxGLContext(&canvas); +#endif // ENABLE_GL_CORE_PROFILE #ifdef __APPLE__ // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets @@ -302,8 +329,12 @@ wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas) wxGLCanvas* OpenGLManager::create_wxglcanvas(wxWindow& parent) { - int attribList[] = { - WX_GL_RGBA, +#if ENABLE_GL_CORE_PROFILE + wxGLAttributes attribList; + attribList.PlatformDefaults().RGBA().DoubleBuffer().MinRGBA(8, 8, 8, 8).Depth(24).SampleBuffers(1).Samplers(4).EndList(); +#else + int attribList[] = { + WX_GL_RGBA, WX_GL_DOUBLEBUFFER, // RGB channels each should be allocated with 8 bit depth. One should almost certainly get these bit depths by default. WX_GL_MIN_RED, 8, @@ -317,6 +348,7 @@ wxGLCanvas* OpenGLManager::create_wxglcanvas(wxWindow& parent) WX_GL_SAMPLES, 4, 0 }; +#endif // ENABLE_GL_CORE_PROFILE if (s_multisample == EMultisampleState::Unknown) { detect_multisample(attribList); @@ -324,13 +356,26 @@ wxGLCanvas* OpenGLManager::create_wxglcanvas(wxWindow& parent) // std::cout << "Multisample " << (can_multisample() ? "enabled" : "disabled") << std::endl; } - if (! can_multisample()) + if (!can_multisample()) +#if ENABLE_GL_CORE_PROFILE + { + attribList.Reset(); + attribList.PlatformDefaults().RGBA().DoubleBuffer().MinRGBA(8, 8, 8, 8).Depth(24).EndList(); + } + + return new wxGLCanvas(&parent, attribList, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS); +#else attribList[12] = 0; return new wxGLCanvas(&parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS); +#endif // ENABLE_GL_CORE_PROFILE } +#if ENABLE_GL_CORE_PROFILE +void OpenGLManager::detect_multisample(const wxGLAttributes& attribList) +#else void OpenGLManager::detect_multisample(int* attribList) +#endif // ENABLE_GL_CORE_PROFILE { int wxVersion = wxMAJOR_VERSION * 10000 + wxMINOR_VERSION * 100 + wxRELEASE_NUMBER; bool enable_multisample = wxVersion >= 30003; diff --git a/src/slic3r/GUI/OpenGLManager.hpp b/src/slic3r/GUI/OpenGLManager.hpp index 0b505c645..dbed8aa9a 100644 --- a/src/slic3r/GUI/OpenGLManager.hpp +++ b/src/slic3r/GUI/OpenGLManager.hpp @@ -6,6 +6,9 @@ class wxWindow; class wxGLCanvas; class wxGLContext; +#if ENABLE_GL_CORE_PROFILE +class wxGLAttributes; +#endif // ENABLE_GL_CORE_PROFILE namespace Slic3r { namespace GUI { @@ -104,7 +107,11 @@ public: static const GLInfo& get_gl_info() { return s_gl_info; } private: +#if ENABLE_GL_CORE_PROFILE + static void detect_multisample(const wxGLAttributes& attribList); +#else static void detect_multisample(int* attribList); +#endif // ENABLE_GL_CORE_PROFILE }; } // namespace GUI diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index e7c4e1763..99b246e3d 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -2013,9 +2013,12 @@ void Selection::render_bounding_box(const BoundingBoxf3 & box, float* color) con glsafe(::glEnable(GL_DEPTH_TEST)); +#if ENABLE_GL_CORE_PROFILE + GLShaderProgram* shader = wxGetApp().get_shader("lines_width"); +#else glsafe(::glLineWidth(2.0f * m_scale_factor)); - GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // !ENABLE_GL_CORE_PROFILE if (shader == nullptr) return; @@ -2024,6 +2027,11 @@ void Selection::render_bounding_box(const BoundingBoxf3 & box, float* color) con const Camera& camera = wxGetApp().plater()->get_camera(); shader->set_uniform("view_model_matrix", camera.get_view_matrix()); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); +#if ENABLE_GL_CORE_PROFILE + const std::array& viewport = camera.get_viewport(); + shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); + shader->set_uniform("width", 1.5f); +#endif // ENABLE_GL_CORE_PROFILE #endif // ENABLE_GL_SHADERS_ATTRIBUTES m_box.set_color(to_rgba(color)); m_box.render();