Delayed rendering of transparent volumes

This commit is contained in:
enricoturri1966 2021-07-14 13:20:57 +02:00
parent 18c8003a0f
commit ef8ddacdfc
6 changed files with 82 additions and 41 deletions

View file

@ -68,6 +68,8 @@
#define DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA (1 && ENABLE_ALLOW_NEGATIVE_Z)
// Enable visualization of objects clearance for sequential prints
#define ENABLE_SEQUENTIAL_LIMITS (1 && ENABLE_2_4_0_ALPHA0)
// Enable delayed rendering of transparent volumes
#define ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING (1 && ENABLE_2_4_0_ALPHA0)
#endif // _prusaslicer_technologies_h_

View file

@ -752,17 +752,15 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo
{
GLVolume* volume = volumes[i];
bool is_transparent = (volume->render_color[3] < 1.0f);
if ((((type == GLVolumeCollection::Opaque) && !is_transparent) ||
((type == GLVolumeCollection::Transparent) && is_transparent) ||
(type == GLVolumeCollection::All)) &&
if ((((type == GLVolumeCollection::ERenderType::Opaque) && !is_transparent) ||
((type == GLVolumeCollection::ERenderType::Transparent) && is_transparent) ||
(type == GLVolumeCollection::ERenderType::All)) &&
(! filter_func || filter_func(*volume)))
list.emplace_back(std::make_pair(volume, std::make_pair(i, 0.0)));
}
if ((type == GLVolumeCollection::Transparent) && (list.size() > 1))
{
for (GLVolumeWithIdAndZ& volume : list)
{
if (type == GLVolumeCollection::ERenderType::Transparent && list.size() > 1) {
for (GLVolumeWithIdAndZ& volume : list) {
volume.second.second = volume.first->bounding_box().transformed(view_matrix * volume.first->world_matrix()).max(2);
}
@ -770,8 +768,7 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo
[](const GLVolumeWithIdAndZ& v1, const GLVolumeWithIdAndZ& v2) -> bool { return v1.second.second < v2.second.second; }
);
}
else if ((type == GLVolumeCollection::Opaque) && (list.size() > 1))
{
else if (type == GLVolumeCollection::ERenderType::Opaque && list.size() > 1) {
std::sort(list.begin(), list.end(),
[](const GLVolumeWithIdAndZ& v1, const GLVolumeWithIdAndZ& v2) -> bool { return v1.first->selected && !v2.first->selected; }
);

View file

@ -480,7 +480,7 @@ typedef std::vector<GLVolumeWithIdAndZ> GLVolumeWithIdAndZList;
class GLVolumeCollection
{
public:
enum ERenderType : unsigned char
enum class ERenderType : unsigned char
{
Opaque,
Transparent,

View file

@ -2593,7 +2593,7 @@ void GCodeViewer::render_shells() const
// glsafe(::glDepthMask(GL_FALSE));
shader->start_using();
m_shells.volumes.render(GLVolumeCollection::Transparent, true, wxGetApp().plater()->get_camera().get_view_matrix());
m_shells.volumes.render(GLVolumeCollection::ERenderType::Transparent, true, wxGetApp().plater()->get_camera().get_view_matrix());
shader->stop_using();
// glsafe(::glDepthMask(GL_TRUE));

View file

@ -1475,12 +1475,20 @@ void GLCanvas3D::render()
glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
_render_background();
#if ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING
_render_objects(GLVolumeCollection::ERenderType::Opaque);
#else
_render_objects();
#endif // ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING
if (!m_main_toolbar.is_enabled())
_render_gcode();
_render_sla_slices();
_render_selection();
_render_bed(!camera.is_looking_downward(), true);
#if ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING
_render_objects(GLVolumeCollection::ERenderType::Transparent);
#endif // ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING
#if ENABLE_SEQUENTIAL_LIMITS
_render_sequential_clearance();
#endif // ENABLE_SEQUENTIAL_LIMITS
@ -5036,7 +5044,11 @@ void GLCanvas3D::_render_bed(bool bottom, bool show_axes)
wxGetApp().plater()->get_bed().render(*this, bottom, scale_factor, show_axes, show_texture);
}
#if ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING
void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
#else
void GLCanvas3D::_render_objects()
#endif // ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING
{
if (m_volumes.empty())
return;
@ -5067,37 +5079,63 @@ void GLCanvas3D::_render_objects()
if (shader != nullptr) {
shader->start_using();
if (m_picking_enabled && !m_gizmos.is_dragging() && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) {
int object_id = m_layers_editing.last_object_id;
m_volumes.render(GLVolumeCollection::Opaque, false, wxGetApp().plater()->get_camera().get_view_matrix(), [object_id](const GLVolume& volume) {
// Which volume to paint without the layer height profile shader?
return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id);
});
// Let LayersEditing handle rendering of the active object using the layer height profile shader.
m_layers_editing.render_volumes(*this, m_volumes);
} else {
// do not cull backfaces to show broken geometry, if any
m_volumes.render(GLVolumeCollection::Opaque, m_picking_enabled, wxGetApp().plater()->get_camera().get_view_matrix(), [this](const GLVolume& volume) {
return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0);
});
}
// In case a painting gizmo is open, it should render the painted triangles
// before transparent objects are rendered. Otherwise they would not be
// visible when inside modifier meshes etc.
#if ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING
switch (type)
{
const GLGizmosManager& gm = get_gizmos_manager();
GLGizmosManager::EType type = gm.get_current_type();
if (type == GLGizmosManager::FdmSupports
|| type == GLGizmosManager::Seam
|| type == GLGizmosManager::MmuSegmentation) {
shader->stop_using();
gm.render_painter_gizmo();
shader->start_using();
default:
case GLVolumeCollection::ERenderType::Opaque:
{
#endif // ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING
if (m_picking_enabled && !m_gizmos.is_dragging() && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) {
int object_id = m_layers_editing.last_object_id;
#if ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING
m_volumes.render(type, false, wxGetApp().plater()->get_camera().get_view_matrix(), [object_id](const GLVolume& volume) {
#else
m_volumes.render(GLVolumeCollection::ERenderType::Opaque, false, wxGetApp().plater()->get_camera().get_view_matrix(), [object_id](const GLVolume& volume) {
#endif // ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING
// Which volume to paint without the layer height profile shader?
return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id);
});
// Let LayersEditing handle rendering of the active object using the layer height profile shader.
m_layers_editing.render_volumes(*this, m_volumes);
}
else {
// do not cull backfaces to show broken geometry, if any
#if ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING
m_volumes.render(type, m_picking_enabled, wxGetApp().plater()->get_camera().get_view_matrix(), [this](const GLVolume& volume) {
#else
m_volumes.render(GLVolumeCollection::ERenderType::Opaque, m_picking_enabled, wxGetApp().plater()->get_camera().get_view_matrix(), [this](const GLVolume& volume) {
#endif // ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING
return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0);
});
}
}
m_volumes.render(GLVolumeCollection::Transparent, false, wxGetApp().plater()->get_camera().get_view_matrix());
// In case a painting gizmo is open, it should render the painted triangles
// before transparent objects are rendered. Otherwise they would not be
// visible when inside modifier meshes etc.
{
const GLGizmosManager& gm = get_gizmos_manager();
GLGizmosManager::EType type = gm.get_current_type();
if (type == GLGizmosManager::FdmSupports
|| type == GLGizmosManager::Seam
|| type == GLGizmosManager::MmuSegmentation) {
shader->stop_using();
gm.render_painter_gizmo();
shader->start_using();
}
}
#if ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING
break;
}
case GLVolumeCollection::ERenderType::Transparent:
{
m_volumes.render(type, false, wxGetApp().plater()->get_camera().get_view_matrix());
break;
}
}
#else
m_volumes.render(GLVolumeCollection::ERenderType::Transparent, false, wxGetApp().plater()->get_camera().get_view_matrix());
#endif // ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING
shader->stop_using();
}
@ -5258,8 +5296,8 @@ void GLCanvas3D::_render_volumes_for_picking() const
const Transform3d& view_matrix = wxGetApp().plater()->get_camera().get_view_matrix();
for (size_t type = 0; type < 2; ++ type) {
GLVolumeWithIdAndZList to_render = volumes_to_render(m_volumes.volumes, (type == 0) ? GLVolumeCollection::Opaque : GLVolumeCollection::Transparent, view_matrix);
for (const GLVolumeWithIdAndZ& volume : to_render)
GLVolumeWithIdAndZList to_render = volumes_to_render(m_volumes.volumes, (type == 0) ? GLVolumeCollection::ERenderType::Opaque : GLVolumeCollection::ERenderType::Transparent, view_matrix);
for (const GLVolumeWithIdAndZ& volume : to_render)
if (!volume.first->disabled && ((volume.first->composite_id.volume_id >= 0) || m_render_sla_auxiliaries)) {
// Object picking mode. Render the object with a color encoding the object index.
unsigned int id = volume.second.first;

View file

@ -822,7 +822,11 @@ private:
void _rectangular_selection_picking_pass();
void _render_background() const;
void _render_bed(bool bottom, bool show_axes);
#if ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING
void _render_objects(GLVolumeCollection::ERenderType type);
#else
void _render_objects();
#endif // ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING
void _render_gcode() const;
void _render_selection() const;
#if ENABLE_SEQUENTIAL_LIMITS