diff --git a/resources/shaders/options_120.fs b/resources/shaders/options_120_flat.fs similarity index 81% rename from resources/shaders/options_120.fs rename to resources/shaders/options_120_flat.fs index 90d417b6e..656eccd1d 100644 --- a/resources/shaders/options_120.fs +++ b/resources/shaders/options_120_flat.fs @@ -5,7 +5,7 @@ uniform vec3 uniform_color; uniform float percent_outline_radius; uniform float percent_center_radius; -vec4 hard_color(float sq_radius) +vec4 hardcoded_color(float sq_radius) { if ((sq_radius < 0.005625) || (sq_radius > 0.180625)) return vec4(0.5 * uniform_color, 1.0); @@ -13,7 +13,7 @@ vec4 hard_color(float sq_radius) return vec4(uniform_color, 1.0); } -vec4 custom_color(float sq_radius) +vec4 customizable_color(float sq_radius) { float in_radius = 0.5 * percent_center_radius; float out_radius = 0.5 * (1.0 - percent_outline_radius); @@ -30,5 +30,6 @@ void main() if (sq_radius > 0.25) discard; - gl_FragColor = custom_color(sq_radius); + gl_FragColor = customizable_color(sq_radius); +// gl_FragColor = hardcoded_color(sq_radius); } diff --git a/resources/shaders/options_120.vs b/resources/shaders/options_120_flat.vs similarity index 100% rename from resources/shaders/options_120.vs rename to resources/shaders/options_120_flat.vs diff --git a/resources/shaders/options_120_solid.fs b/resources/shaders/options_120_solid.fs new file mode 100644 index 000000000..68d0bd4ee --- /dev/null +++ b/resources/shaders/options_120_solid.fs @@ -0,0 +1,88 @@ +// version 120 is needed for gl_PointCoord +#version 120 + +#define INTENSITY_CORRECTION 0.6 + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +// normalized values for (1./1.43, 0.2/1.43, 1./1.43) +const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) + +#define INTENSITY_AMBIENT 0.3 + +uniform vec3 uniform_color; +uniform float percent_outline_radius; +uniform float percent_center_radius; + +// x = width, y = height +uniform ivec2 viewport_sizes; +uniform vec2 z_range; +uniform mat4 inv_proj_matrix; + +varying vec3 eye_center; + +float radius = 0.5; +// x = tainted, y = specular; +vec2 intensity; + +vec3 eye_position_from_fragment() +{ + // Convert screen coordinates to normalized device coordinates (NDC) + vec4 ndc = vec4( + (gl_FragCoord.x / viewport_sizes.x - 0.5) * 2.0, + (gl_FragCoord.y / viewport_sizes.y - 0.5) * 2.0, + (gl_FragCoord.z - 0.5) * 2.0, + 1.0); + + // Convert NDC throuch inverse clip coordinates to view coordinates + vec4 clip = inv_proj_matrix * ndc; + return (clip / clip.w).xyz; +} + +vec3 eye_position_on_sphere(vec3 eye_fragment_position) +{ + vec3 eye_dir = normalize(eye_fragment_position); + float a = dot(eye_dir, eye_dir); + float b = 2.0 * dot(-eye_center, eye_dir); + float c = dot(eye_center, eye_center) - radius * radius; + float discriminant = b * b - 4 * a * c; + float t = -(b + sqrt(discriminant)) / (2.0 * a); + return t * eye_dir; +} + +vec4 on_sphere_color(vec3 eye_on_sphere_position) +{ + vec3 eye_normal = normalize(eye_on_sphere_position - eye_center); + + // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. + // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. + float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_on_sphere_position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + + return vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, 1.0); +} + +void main() +{ + vec2 pos = gl_PointCoord - vec2(0.5, 0.5); + float sq_radius = dot(pos, pos); + if (sq_radius > 0.25) + discard; + + vec3 eye_on_sphere_position = eye_position_on_sphere(eye_position_from_fragment()); + +// gl_FragDepth = eye_on_sphere_position.z; +// gl_FragDepth = (eye_on_sphere_position.z - z_range.x) / (z_range.y - z_range.x); + gl_FragColor = on_sphere_color(eye_on_sphere_position); +} diff --git a/resources/shaders/options_120_solid.vs b/resources/shaders/options_120_solid.vs new file mode 100644 index 000000000..0ad75003c --- /dev/null +++ b/resources/shaders/options_120_solid.vs @@ -0,0 +1,14 @@ +#version 120 + +uniform float zoom; +// x = min, y = max +uniform vec2 point_sizes; + +varying vec3 eye_center; + +void main() +{ + gl_PointSize = clamp(zoom, point_sizes.x, point_sizes.y); + eye_center = (gl_ModelViewMatrix * gl_Vertex).xyz; + gl_Position = ftransform(); +} diff --git a/resources/shaders/shells.fs b/resources/shaders/shells.fs deleted file mode 100644 index 0c3388df7..000000000 --- a/resources/shaders/shells.fs +++ /dev/null @@ -1,13 +0,0 @@ -#version 110 - -const vec3 ZERO = vec3(0.0, 0.0, 0.0); - -uniform vec4 uniform_color; - -// x = tainted, y = specular; -varying vec2 intensity; - -void main() -{ - gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + uniform_color.rgb * intensity.x, uniform_color.a); -} diff --git a/resources/shaders/shells.vs b/resources/shaders/shells.vs deleted file mode 100644 index bb9c144e6..000000000 --- a/resources/shaders/shells.vs +++ /dev/null @@ -1,42 +0,0 @@ -#version 110 - -#define INTENSITY_CORRECTION 0.6 - -// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) -const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); -#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) -#define LIGHT_TOP_SHININESS 20.0 - -// normalized values for (1./1.43, 0.2/1.43, 1./1.43) -const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); -#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) - -#define INTENSITY_AMBIENT 0.3 - -// x = tainted, y = specular; -varying vec2 intensity; - -void main() -{ - // First transform the normal into camera space and normalize the result. - vec3 normal = normalize(gl_NormalMatrix * gl_Normal); - - // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. - // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. - float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0); - - intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; - intensity.y = 0.0; - - if (NdotL > 0.0) - { - vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz; - intensity.y += LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS); - } - - // Perform the same lighting calculation for the 2nd light source (no specular applied). - intensity.x += max(dot(normal, LIGHT_FRONT_DIR), 0.0) * LIGHT_FRONT_DIFFUSE; - - gl_Position = ftransform(); -} diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 5631dadf3..984373ea4 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -15,7 +15,7 @@ #define ENABLE_RENDER_STATISTICS 0 // Shows an imgui dialog with camera related data #define ENABLE_CAMERA_STATISTICS 0 -// Render the picking pass instead of the main scene (use [T] key to toggle between regular rendering and picking pass only rendering) +// Render the picking pass instead of the main scene (use [T] key to toggle between regular rendering and picking pass only rendering) #define ENABLE_RENDER_PICKING_PASS 0 // Enable extracting thumbnails from selected gcode and save them as png files #define ENABLE_THUMBNAIL_GENERATOR_DEBUG 0 diff --git a/src/slic3r/GUI/Camera.hpp b/src/slic3r/GUI/Camera.hpp index ece999c07..6e4256235 100644 --- a/src/slic3r/GUI/Camera.hpp +++ b/src/slic3r/GUI/Camera.hpp @@ -84,6 +84,7 @@ public: double get_near_z() const { return m_frustrum_zs.first; } double get_far_z() const { return m_frustrum_zs.second; } + const std::pair<double, double>& get_z_range() const { return m_frustrum_zs; } double get_fov() const; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 6d4197694..978b4b95a 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -415,12 +415,12 @@ void GCodeViewer::init_shaders() { switch (buffer_type(i)) { - case GCodeProcessor::EMoveType::Tool_change: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; } - case GCodeProcessor::EMoveType::Color_change: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; } - case GCodeProcessor::EMoveType::Pause_Print: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; } - case GCodeProcessor::EMoveType::Custom_GCode: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; } - case GCodeProcessor::EMoveType::Retract: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; } - case GCodeProcessor::EMoveType::Unretract: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110"; break; } + case GCodeProcessor::EMoveType::Tool_change: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120_solid" : "options_110"; break; } + case GCodeProcessor::EMoveType::Color_change: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120_solid" : "options_110"; break; } + case GCodeProcessor::EMoveType::Pause_Print: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120_solid" : "options_110"; break; } + case GCodeProcessor::EMoveType::Custom_GCode: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120_solid" : "options_110"; break; } + case GCodeProcessor::EMoveType::Retract: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120_solid" : "options_110"; break; } + case GCodeProcessor::EMoveType::Unretract: { m_buffers[i].shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120_solid" : "options_110"; break; } case GCodeProcessor::EMoveType::Extrude: { m_buffers[i].shader = "extrusions"; break; } case GCodeProcessor::EMoveType::Travel: { m_buffers[i].shader = "travels"; break; } default: { break; } @@ -754,21 +754,26 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool void GCodeViewer::render_toolpaths() const { #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR - bool is_glsl_120 = m_shaders_editor.glsl_version == 1 && wxGetApp().is_glsl_version_greater_or_equal_to(1, 20); + bool is_glsl_120 = m_shaders_editor.shader_version >= 1 && wxGetApp().is_glsl_version_greater_or_equal_to(1, 20); std::array<float, 2> point_sizes; if (m_shaders_editor.size_dependent_on_zoom) - { point_sizes = { std::min(static_cast<float>(m_shaders_editor.sizes[0]), m_detected_point_sizes[1]), std::min(static_cast<float>(m_shaders_editor.sizes[1]), m_detected_point_sizes[1]) }; - } else point_sizes = { static_cast<float>(m_shaders_editor.fixed_size), static_cast<float>(m_shaders_editor.fixed_size) }; #else bool is_glsl_120 = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20); std::array<float, 2> point_sizes = { std::min(8.0f, m_detected_point_sizes[1]), std::min(48.0f, m_detected_point_sizes[1]) }; #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR - double zoom = wxGetApp().plater()->get_camera().get_zoom(); + const Camera& camera = wxGetApp().plater()->get_camera(); + double zoom = camera.get_zoom(); + const std::array<int, 4>& viewport = camera.get_viewport(); + std::array<int, 2> viewport_sizes = { viewport[2], viewport[3] }; + const std::pair<double, double>& camera_z_range = camera.get_z_range(); + std::array<float, 2> z_range = { static_cast<float>(camera_z_range.first), static_cast<float>(camera_z_range.second) }; - auto render_options = [this, is_glsl_120, zoom, point_sizes](const IBuffer& buffer, EOptionsColors colors_id, GLShaderProgram& shader) { + Transform3d inv_proj = camera.get_projection_matrix().inverse(); + + auto render_options = [this, is_glsl_120, zoom, viewport, inv_proj, viewport_sizes, z_range, point_sizes](const IBuffer& buffer, EOptionsColors colors_id, GLShaderProgram& shader) { shader.set_uniform("uniform_color", Options_Colors[static_cast<unsigned int>(colors_id)]); #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR shader.set_uniform("zoom", m_shaders_editor.size_dependent_on_zoom ? zoom : 1.0f); @@ -779,6 +784,9 @@ void GCodeViewer::render_toolpaths() const shader.set_uniform("percent_outline_radius", 0.15f); shader.set_uniform("percent_center_radius", 0.15f); #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR + shader.set_uniform("viewport_sizes", viewport_sizes); + shader.set_uniform("inv_proj_matrix", inv_proj); + shader.set_uniform("z_range", z_range); shader.set_uniform("point_sizes", point_sizes); glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); if (is_glsl_120) @@ -896,7 +904,7 @@ void GCodeViewer::render_shells() const if (!m_shells.visible || m_shells.volumes.empty()) return; - GLShaderProgram* shader = wxGetApp().get_shader("shells"); + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); if (shader == nullptr) return; @@ -954,25 +962,25 @@ void GCodeViewer::render_legend() const { #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR draw_list->AddCircle({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 0.5f * icon_size, ICON_BORDER_COLOR, 16); - draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, - ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); - float radius = ((0.5f * icon_size) - 2.0f) * (1.0f - 0.01f * static_cast<float>(m_shaders_editor.percent_outline)); - draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, radius, - ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); - if (m_shaders_editor.percent_center > 0) - { - radius = ((0.5f * icon_size) - 2.0f) * 0.01f * static_cast<float>(m_shaders_editor.percent_center); - draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, radius, + if (m_shaders_editor.shader_version == 1) { + draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); + float radius = ((0.5f * icon_size) - 2.0f) * (1.0f - 0.01f * static_cast<float>(m_shaders_editor.percent_outline)); + draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, radius, + ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); + if (m_shaders_editor.percent_center > 0) { + radius = ((0.5f * icon_size) - 2.0f) * 0.01f * static_cast<float>(m_shaders_editor.percent_center); + draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, radius, + ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); + } + } else { + draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, + ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); } #else draw_list->AddCircle({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 0.5f * icon_size, ICON_BORDER_COLOR, 16); draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 2.0f, - ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); - draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, (0.5f * icon_size) - 3.0f, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); - draw_list->AddCircleFilled({ 0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size) }, 1.5f, - ImGui::GetColorU32({ 0.5f * color[0], 0.5f * color[1], 0.5f * color[2], 1.0f }), 16); #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR break; } @@ -1195,7 +1203,11 @@ void GCodeViewer::render_legend() const auto add_option = [this, add_item](GCodeProcessor::EMoveType move_type, EOptionsColors color, const std::string& text) { const IBuffer& buffer = m_buffers[buffer_id(move_type)]; if (buffer.visible && buffer.indices_count > 0) - add_item(EItemType::Circle, Options_Colors[static_cast<unsigned int>(color)], text); +#if ENABLE_GCODE_VIEWER_SHADERS_EDITOR + add_item((m_shaders_editor.shader_version == 0) ? EItemType::Rect : EItemType::Circle, Options_Colors[static_cast<unsigned int>(color)], text); +#else + add_item((buffer.shader == "options_110") ? EItemType::Rect : EItemType::Circle, Options_Colors[static_cast<unsigned int>(color)], text); +#endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR }; // options @@ -1337,12 +1349,15 @@ void GCodeViewer::render_shaders_editor() const imgui.set_next_window_pos(static_cast<float>(cnv_size.get_width()), 0.5f * static_cast<float>(cnv_size.get_height()), ImGuiCond_Once, 1.0f, 0.5f); imgui.begin(std::string("Shaders editor (DEV only)"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize); - ImGui::RadioButton("glsl version 1.10 (low end PCs)", &m_shaders_editor.glsl_version, 0); - ImGui::RadioButton("glsl version 1.20 (default)", &m_shaders_editor.glsl_version, 1); - switch (m_shaders_editor.glsl_version) + ImGui::RadioButton("glsl version 1.10 (low end PCs)", &m_shaders_editor.shader_version, 0); + ImGui::RadioButton("glsl version 1.20 flat (billboards)", &m_shaders_editor.shader_version, 1); + ImGui::RadioButton("glsl version 1.20 solid (spheres default)", &m_shaders_editor.shader_version, 2); + + switch (m_shaders_editor.shader_version) { case 0: { set_shader("options_110"); break; } - case 1: { set_shader("options_120"); break; } + case 1: { set_shader("options_120_flat"); break; } + case 2: { set_shader("options_120_solid"); break; } } if (ImGui::CollapsingHeader("Options", ImGuiTreeNodeFlags_DefaultOpen)) @@ -1364,7 +1379,7 @@ void GCodeViewer::render_shaders_editor() const else ImGui::SliderInt("fixed size", &m_shaders_editor.fixed_size, 1, 100); - if (m_shaders_editor.glsl_version == 1) + if (m_shaders_editor.shader_version == 1) { ImGui::SliderInt("percent outline", &m_shaders_editor.percent_outline, 0, 50); ImGui::SliderInt("percent center", &m_shaders_editor.percent_center, 0, 50); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 1d940b66a..a2f9c14af 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -205,12 +205,12 @@ class GCodeViewer #if ENABLE_GCODE_VIEWER_SHADERS_EDITOR struct ShadersEditor { - int glsl_version{ 1 }; + int shader_version{ 2 }; bool size_dependent_on_zoom{ true }; int fixed_size{ 16 }; - std::array<int, 2> sizes{ 8, 64 }; - int percent_outline{ 15 }; - int percent_center{ 15 }; + std::array<int, 2> sizes{ 3, 21 }; + int percent_outline{ 0 }; + int percent_center{ 33 }; }; #endif // ENABLE_GCODE_VIEWER_SHADERS_EDITOR diff --git a/src/slic3r/GUI/GLShader.cpp b/src/slic3r/GUI/GLShader.cpp index a6d641f89..3c2612b45 100644 --- a/src/slic3r/GUI/GLShader.cpp +++ b/src/slic3r/GUI/GLShader.cpp @@ -215,6 +215,26 @@ bool GLShaderProgram::set_uniform(const char* name, double value) const return set_uniform(name, static_cast<float>(value)); } +bool GLShaderProgram::set_uniform(const char* name, const std::array<int, 2>& value) const +{ + int id = get_uniform_location(name); + if (id >= 0) { + glsafe(::glUniform2iv(id, 1, static_cast<const GLint*>(value.data()))); + return true; + } + return false; +} + +bool GLShaderProgram::set_uniform(const char* name, const std::array<int, 3>& value) const +{ + int id = get_uniform_location(name); + if (id >= 0) { + glsafe(::glUniform3iv(id, 1, static_cast<const GLint*>(value.data()))); + return true; + } + return false; +} + bool GLShaderProgram::set_uniform(const char* name, const std::array<int, 4>& value) const { int id = get_uniform_location(name); diff --git a/src/slic3r/GUI/GLShader.hpp b/src/slic3r/GUI/GLShader.hpp index 521f6796f..a1160f8e9 100644 --- a/src/slic3r/GUI/GLShader.hpp +++ b/src/slic3r/GUI/GLShader.hpp @@ -43,6 +43,8 @@ public: bool set_uniform(const char* name, bool value) const; bool set_uniform(const char* name, float value) const; bool set_uniform(const char* name, double value) const; + bool set_uniform(const char* name, const std::array<int, 2>& value) const; + bool set_uniform(const char* name, const std::array<int, 3>& value) const; bool set_uniform(const char* name, const std::array<int, 4>& value) const; bool set_uniform(const char* name, const std::array<float, 2>& value) const; bool set_uniform(const char* name, const std::array<float, 3>& value) const; diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index dd77351bd..4bebf7b98 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -1,6 +1,7 @@ #include "libslic3r/libslic3r.h" #include "GLShadersManager.hpp" #include "3DScene.hpp" +#include "GUI_App.hpp" #include <cassert> #include <algorithm> @@ -28,19 +29,21 @@ std::pair<bool, std::string> GLShadersManager::init() bool valid = true; - // used to render bed axes and model, selection hints, gcode sequential view marker model + // used to render bed axes and model, selection hints, gcode sequential view marker model, preview shells valid &= append_shader("gouraud_light", { "gouraud_light.vs", "gouraud_light.fs" }); // used to render printbed valid &= append_shader("printbed", { "printbed.vs", "printbed.fs" }); // used to render options in gcode preview valid &= append_shader("options_110", { "options_110.vs", "options_110.fs" }); - valid &= append_shader("options_120", { "options_120.vs", "options_120.fs" }); + if (GUI::wxGetApp().is_glsl_version_greater_or_equal_to(1, 20)) + { + valid &= append_shader("options_120_flat", { "options_120_flat.vs", "options_120_flat.fs" }); + valid &= append_shader("options_120_solid", { "options_120_solid.vs", "options_120_solid.fs" }); + } // used to render extrusion paths in gcode preview valid &= append_shader("extrusions", { "extrusions.vs", "extrusions.fs" }); // used to render travel paths in gcode preview valid &= append_shader("travels", { "travels.vs", "travels.fs" }); - // used to render shells in gcode preview - valid &= append_shader("shells", { "shells.vs", "shells.fs" }); // used to render objects in 3d editor valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }); // used to render variable layers heights in 3d editor