SLA gizmo clipping plane logic moved to fragment shader

This means the clipping now works again with both legacy and modern OpenGL
This commit is contained in:
Lukas Matena 2019-03-25 12:01:02 +01:00
parent 273fcf68a1
commit 9b7857aaab
7 changed files with 41 additions and 38 deletions

View File

@ -8,16 +8,22 @@ varying vec2 intensity;
varying vec3 delta_box_min;
varying vec3 delta_box_max;
varying float world_z;
varying vec3 world_pos;
uniform vec4 uniform_color;
// x = min z, y = max z;
uniform vec2 z_range;
// clipping plane (general orientation):
uniform vec4 clipping_plane;
void main()
{
if ((world_z < z_range.x) || (z_range.y < world_z))
if ((world_pos.z < z_range.x) || (z_range.y < world_pos.z))
discard;
if (world_pos.x*clipping_plane.x + world_pos.y*clipping_plane.y + world_pos.z*clipping_plane.z + clipping_plane.w < 0.f )
discard;
// if the fragment is outside the print volume -> use darker color

View File

@ -34,7 +34,7 @@ varying vec2 intensity;
varying vec3 delta_box_min;
varying vec3 delta_box_max;
varying float world_z;
varying vec3 world_pos;
void main()
{
@ -69,5 +69,5 @@ void main()
}
gl_Position = ftransform();
world_z = vec3(print_box.volume_world_matrix * gl_Vertex).z;
world_pos = vec3(print_box.volume_world_matrix * gl_Vertex);
}

View File

@ -785,6 +785,7 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool
glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, &current_program_id));
GLint color_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "uniform_color") : -1;
GLint z_range_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "z_range") : -1;
GLint clipping_plane_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "clipping_plane") : -1;
GLint print_box_min_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.min") : -1;
GLint print_box_max_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.max") : -1;
GLint print_box_detection_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.volume_detection") : -1;
@ -799,6 +800,9 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool
if (z_range_id != -1)
glsafe(::glUniform2fv(z_range_id, 1, (const GLfloat*)z_range));
if (clipping_plane_id != -1)
glsafe(::glUniform4fv(clipping_plane_id, 1, (const GLfloat*)clipping_plane));
GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, filter_func);
for (GLVolumeWithZ& volume : to_render) {
volume.first->set_render_color();

View File

@ -427,6 +427,9 @@ private:
// z range for clipping in shaders
float z_range[2];
// plane coeffs for clipping in shaders
float clipping_plane[4];
public:
GLVolumePtrs volumes;
@ -485,6 +488,7 @@ public:
}
void set_z_range(float min_z, float max_z) { z_range[0] = min_z; z_range[1] = max_z; }
void set_clipping_plane(const double* coeffs) { clipping_plane[0] = coeffs[0]; clipping_plane[1] = coeffs[1]; clipping_plane[2] = coeffs[2]; clipping_plane[3] = coeffs[3]; }
// returns true if all the volumes are completely contained in the print volume
// returns the containment state in the given out_state, if non-null

View File

@ -1321,14 +1321,14 @@ bool GLCanvas3D::Gizmos::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
GLCanvas3D::ClippingPlane GLCanvas3D::Gizmos::get_sla_clipping_plane() const
{
if (!m_enabled)
return ClippingPlane();
if (!m_enabled || m_current != SlaSupports)
return ClippingPlane::ClipsNothing();
GizmosMap::const_iterator it = m_gizmos.find(SlaSupports);
if (it != m_gizmos.end())
return reinterpret_cast<GLGizmoSlaSupports*>(it->second)->get_sla_clipping_plane();
return ClippingPlane();
return ClippingPlane::ClipsNothing();
}
@ -4602,7 +4602,12 @@ void GLCanvas3D::_picking_pass() const
::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_camera_clipping_plane = m_gizmos.get_sla_clipping_plane();
::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)m_camera_clipping_plane.get_data());
::glEnable(GL_CLIP_PLANE0);
_render_volumes(true);
::glDisable(GL_CLIP_PLANE0);
m_gizmos.render_current_gizmo_for_picking_pass(m_selection);
if (m_multisample_allowed)
@ -4700,25 +4705,6 @@ void GLCanvas3D::set_ortho_projection(float w, float h, float near, float far) c
}
void GLCanvas3D::set_sla_clipping(bool enable) const
{
if (m_gizmos.get_current_type() != Gizmos::SlaSupports)
return;
if (enable) {
ClippingPlane gizmo_clipping_plane;
try {
gizmo_clipping_plane = m_gizmos.get_sla_clipping_plane();
}
catch (...) { return; }
::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)gizmo_clipping_plane.get_data());
::glEnable(GL_CLIP_PLANE0);
}
else
::glDisable(GL_CLIP_PLANE0);
}
void GLCanvas3D::_render_objects() const
{
@ -4728,7 +4714,7 @@ void GLCanvas3D::_render_objects() const
::glEnable(GL_LIGHTING);
::glEnable(GL_DEPTH_TEST);
set_sla_clipping(true);
m_camera_clipping_plane = m_gizmos.get_sla_clipping_plane();
if (m_use_VBOs)
{
@ -4750,6 +4736,8 @@ void GLCanvas3D::_render_objects() const
else
m_volumes.set_z_range(-FLT_MAX, FLT_MAX);
m_volumes.set_clipping_plane(m_camera_clipping_plane.get_data());
m_shader.start_using();
if (m_picking_enabled && m_layers_editing.is_enabled() && m_layers_editing.last_object_id != -1) {
int object_id = m_layers_editing.last_object_id;
@ -4770,6 +4758,9 @@ void GLCanvas3D::_render_objects() const
}
else
{
::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)m_camera_clipping_plane.get_data());
::glEnable(GL_CLIP_PLANE0);
if (m_use_clipping_planes)
{
::glClipPlane(GL_CLIP_PLANE1, (GLdouble*)m_clipping_planes[0].get_data());
@ -4778,12 +4769,15 @@ void GLCanvas3D::_render_objects() const
::glEnable(GL_CLIP_PLANE2);
}
// do not cull backfaces to show broken geometry, if any
m_volumes.render_legacy(GLVolumeCollection::Opaque, m_picking_enabled, [this](const GLVolume& volume) {
return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0);
});
m_volumes.render_legacy(GLVolumeCollection::Transparent, false);
::glDisable(GL_CLIP_PLANE0);
if (m_use_clipping_planes)
{
::glDisable(GL_CLIP_PLANE1);
@ -4791,8 +4785,7 @@ void GLCanvas3D::_render_objects() const
}
}
set_sla_clipping(false);
m_camera_clipping_plane = ClippingPlane::ClipsNothing();
::glDisable(GL_LIGHTING);
}
@ -4835,8 +4828,6 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const
if (!fake_colors)
::glEnable(GL_LIGHTING);
set_sla_clipping(true);
// do not cull backfaces to show broken geometry, if any
::glDisable(GL_CULL_FACE);
@ -4875,8 +4866,6 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const
::glEnable(GL_CULL_FACE);
set_sla_clipping(false);
if (!fake_colors)
::glDisable(GL_LIGHTING);
}

View File

@ -354,6 +354,8 @@ public:
m_data[3] = offset;
}
static ClippingPlane ClipsNothing() { return ClippingPlane(Vec3d(0., 0., 1.), DBL_MAX); }
const double* get_data() const { return m_data; }
};
@ -561,6 +563,7 @@ private:
mutable Gizmos m_gizmos;
mutable GLToolbar m_toolbar;
ClippingPlane m_clipping_planes[2];
mutable ClippingPlane m_camera_clipping_plane;
bool m_use_clipping_planes;
mutable SlaCap m_sla_caps[2];
std::string m_sidebar_field;
@ -778,9 +781,6 @@ private:
// Sets current projection matrix to ortho, accounting for current camera zoom.
void set_ortho_projection(float w, float h, float near, float far) const;
// Set/unset near clipping plane according to SLA gizmo requirements.
void set_sla_clipping(bool enable) const;
void _start_timer();
void _stop_timer();

View File

@ -615,7 +615,7 @@ void GLGizmoSlaSupports::update_cache_entry_normal(unsigned int i) const
GLCanvas3D::ClippingPlane GLGizmoSlaSupports::get_sla_clipping_plane() const
{
if (!m_model_object)
throw std::invalid_argument("GLGizmoSlaSupports::get_sla_clipping_plane() has no model object pointer.");
return GLCanvas3D::ClippingPlane::ClipsNothing();
Eigen::Matrix<GLdouble, 4, 4, Eigen::DontAlign> modelview_matrix;
::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data());