diff --git a/resources/shaders/110/flat_clip.fs b/resources/shaders/110/flat_clip.fs new file mode 100644 index 000000000..ececb8eb1 --- /dev/null +++ b/resources/shaders/110/flat_clip.fs @@ -0,0 +1,15 @@ +#version 110 + +const vec3 ZERO = vec3(0.0, 0.0, 0.0); + +uniform vec4 uniform_color; + +varying vec3 clipping_planes_dots; + +void main() +{ + if (any(lessThan(clipping_planes_dots, ZERO))) + discard; + + gl_FragColor = uniform_color; +} diff --git a/resources/shaders/110/flat_clip.vs b/resources/shaders/110/flat_clip.vs new file mode 100644 index 000000000..cdf7d4b3b --- /dev/null +++ b/resources/shaders/110/flat_clip.vs @@ -0,0 +1,23 @@ +#version 110 + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +uniform mat4 volume_world_matrix; + +// Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane. +uniform vec2 z_range; +// Clipping plane - general orientation. Used by the SLA gizmo. +uniform vec4 clipping_plane; + +attribute vec3 v_position; + +varying vec3 clipping_planes_dots; + +void main() +{ + // Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded. + vec4 world_pos = volume_world_matrix * vec4(v_position, 1.0); + clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z); + + gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0); +} diff --git a/resources/shaders/140/flat_clip.fs b/resources/shaders/140/flat_clip.fs new file mode 100644 index 000000000..b77e0bfaa --- /dev/null +++ b/resources/shaders/140/flat_clip.fs @@ -0,0 +1,17 @@ +#version 140 + +const vec3 ZERO = vec3(0.0, 0.0, 0.0); + +uniform vec4 uniform_color; + +in vec3 clipping_planes_dots; + +out vec4 out_color; + +void main() +{ + if (any(lessThan(clipping_planes_dots, ZERO))) + discard; + + out_color = uniform_color; +} diff --git a/resources/shaders/140/flat_clip.vs b/resources/shaders/140/flat_clip.vs new file mode 100644 index 000000000..40cddf1e5 --- /dev/null +++ b/resources/shaders/140/flat_clip.vs @@ -0,0 +1,23 @@ +#version 140 + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +uniform mat4 volume_world_matrix; + +// Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane. +uniform vec2 z_range; +// Clipping plane - general orientation. Used by the SLA gizmo. +uniform vec4 clipping_plane; + +in vec3 v_position; + +out vec3 clipping_planes_dots; + +void main() +{ + // Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded. + vec4 world_pos = volume_world_matrix * vec4(v_position, 1.0); + clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z); + + gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0); +} diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index c9fb05439..f25b89da8 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1130,8 +1130,8 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); #endif // !ENABLE_GL_SHADERS_ATTRIBUTES - shader->set_uniform("z_range", m_z_range, 2); - shader->set_uniform("clipping_plane", m_clipping_plane, 4); + shader->set_uniform("z_range", m_z_range); + shader->set_uniform("clipping_plane", m_clipping_plane); shader->set_uniform("print_volume.type", static_cast(m_print_volume.type)); shader->set_uniform("print_volume.xy_data", m_print_volume.data); shader->set_uniform("print_volume.z_data", m_print_volume.zs); diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 950d447f0..a85b8092a 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -591,10 +591,10 @@ private: PrintVolume m_print_volume; // z range for clipping in shaders - float m_z_range[2]; + std::array m_z_range; // plane coeffs for clipping in shaders - float m_clipping_plane[4]; + std::array m_clipping_plane; struct Slope { @@ -712,7 +712,10 @@ public: void set_print_volume(const PrintVolume& print_volume) { m_print_volume = print_volume; } void set_z_range(float min_z, float max_z) { m_z_range[0] = min_z; m_z_range[1] = max_z; } - void set_clipping_plane(const double* coeffs) { m_clipping_plane[0] = coeffs[0]; m_clipping_plane[1] = coeffs[1]; m_clipping_plane[2] = coeffs[2]; m_clipping_plane[3] = coeffs[3]; } + void set_clipping_plane(const std::array& coeffs) { m_clipping_plane = coeffs; } + + const std::array& get_z_range() const { return m_z_range; } + const std::array& get_clipping_plane() const { return m_clipping_plane; } bool is_slope_active() const { return m_slope.active; } void set_slope_active(bool active) { m_slope.active = active; } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 8413141bd..3cb1fbb07 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5340,14 +5340,18 @@ void GLCanvas3D::_picking_pass() glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); +#if !ENABLE_GL_SHADERS_ATTRIBUTES m_camera_clipping_plane = m_gizmos.get_clipping_plane(); if (m_camera_clipping_plane.is_active()) { ::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)m_camera_clipping_plane.get_data()); ::glEnable(GL_CLIP_PLANE0); } +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES _render_volumes_for_picking(); +#if !ENABLE_GL_SHADERS_ATTRIBUTES if (m_camera_clipping_plane.is_active()) ::glDisable(GL_CLIP_PLANE0); +#endif // !ENABLE_GL_SHADERS_ATTRIBUTES #if ENABLE_GL_SHADERS_ATTRIBUTES const Camera& camera = wxGetApp().plater()->get_camera(); @@ -5874,7 +5878,11 @@ void GLCanvas3D::_render_overlays() void GLCanvas3D::_render_volumes_for_picking() const { #if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_clip"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GL_SHADERS_ATTRIBUTES if (shader == nullptr) return; #endif // ENABLE_LEGACY_OPENGL_REMOVAL @@ -5906,6 +5914,9 @@ void GLCanvas3D::_render_volumes_for_picking() const const Camera& camera = wxGetApp().plater()->get_camera(); shader->set_uniform("view_model_matrix", camera.get_view_matrix() * volume.first->world_matrix()); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + shader->set_uniform("volume_world_matrix", volume.first->world_matrix()); + shader->set_uniform("z_range", m_volumes.get_z_range()); + shader->set_uniform("clipping_plane", m_volumes.get_clipping_plane()); #endif // ENABLE_GL_SHADERS_ATTRIBUTES volume.first->render(); #if ENABLE_LEGACY_OPENGL_REMOVAL diff --git a/src/slic3r/GUI/GLShader.cpp b/src/slic3r/GUI/GLShader.cpp index c82658e5c..9e3001d77 100644 --- a/src/slic3r/GUI/GLShader.cpp +++ b/src/slic3r/GUI/GLShader.cpp @@ -264,6 +264,12 @@ void GLShaderProgram::set_uniform(int id, const std::array& value) con glsafe(::glUniform4fv(id, 1, static_cast(value.data()))); } +void GLShaderProgram::set_uniform(int id, const std::array& value) const +{ + const std::array f_value = { float(value[0]), float(value[1]), float(value[2]), float(value[3]) }; + set_uniform(id, f_value); +} + void GLShaderProgram::set_uniform(int id, const float* value, size_t size) const { if (id >= 0) { diff --git a/src/slic3r/GUI/GLShader.hpp b/src/slic3r/GUI/GLShader.hpp index 3b669fc77..72edb8b66 100644 --- a/src/slic3r/GUI/GLShader.hpp +++ b/src/slic3r/GUI/GLShader.hpp @@ -57,6 +57,7 @@ public: void set_uniform(const char* name, const std::array& value) const { set_uniform(get_uniform_location(name), value); } void set_uniform(const char* name, const std::array& value) const { set_uniform(get_uniform_location(name), value); } void set_uniform(const char* name, const std::array& value) const { set_uniform(get_uniform_location(name), value); } + void set_uniform(const char* name, const std::array& value) const { set_uniform(get_uniform_location(name), value); } void set_uniform(const char* name, const float* value, size_t size) const { set_uniform(get_uniform_location(name), value, size); } void set_uniform(const char* name, const Transform3f& value) const { set_uniform(get_uniform_location(name), value); } void set_uniform(const char* name, const Transform3d& value) const { set_uniform(get_uniform_location(name), value); } @@ -83,6 +84,7 @@ public: void set_uniform(int id, const std::array& value) const; void set_uniform(int id, const std::array& value) const; void set_uniform(int id, const std::array& value) const; + void set_uniform(int id, const std::array& value) const; void set_uniform(int id, const float* value, size_t size) const; void set_uniform(int id, const Transform3f& value) const; void set_uniform(int id, const Transform3d& value) const; diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index ab8dfb3e7..9edd39d7f 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -40,6 +40,8 @@ std::pair GLShadersManager::init() valid &= append_shader("imgui", { prefix + "imgui.vs", prefix + "imgui.fs" }); // basic shader, used to render all what was previously rendered using the immediate mode valid &= append_shader("flat", { prefix + "flat.vs", prefix + "flat.fs" }); + // basic shader with plane clipping, used to render volumes in picking pass + valid &= append_shader("flat_clip", { prefix + "flat_clip.vs", prefix + "flat_clip.fs" }); // basic shader for textures, used to render textures valid &= append_shader("flat_texture", { prefix + "flat_texture.vs", prefix + "flat_texture.fs" }); // used to render 3D scene background diff --git a/src/slic3r/GUI/MeshUtils.hpp b/src/slic3r/GUI/MeshUtils.hpp index 3298d3876..3b8d247c1 100644 --- a/src/slic3r/GUI/MeshUtils.hpp +++ b/src/slic3r/GUI/MeshUtils.hpp @@ -25,16 +25,14 @@ struct Camera; // lm_FIXME: Following class might possibly be replaced by Eigen::Hyperplane class ClippingPlane { - double m_data[4]; + std::array m_data; public: - ClippingPlane() - { + ClippingPlane() { *this = ClipsNothing(); } - ClippingPlane(const Vec3d& direction, double offset) - { + ClippingPlane(const Vec3d& direction, double offset) { set_normal(direction); set_offset(offset); } @@ -50,8 +48,7 @@ public: } bool is_point_clipped(const Vec3d& point) const { return distance(point) < 0.; } - void set_normal(const Vec3d& normal) - { + void set_normal(const Vec3d& normal) { const Vec3d norm_dir = normal.normalized(); m_data[0] = norm_dir.x(); m_data[1] = norm_dir.y(); @@ -62,12 +59,11 @@ public: Vec3d get_normal() const { return Vec3d(m_data[0], m_data[1], m_data[2]); } bool is_active() const { return m_data[3] != DBL_MAX; } static ClippingPlane ClipsNothing() { return ClippingPlane(Vec3d(0., 0., 1.), DBL_MAX); } - const double* get_data() const { return m_data; } + const std::array& get_data() const { return m_data; } // Serialization through cereal library template - void serialize( Archive & ar ) - { + void serialize( Archive & ar ) { ar( m_data[0], m_data[1], m_data[2], m_data[3] ); } };