From 8c8f0b32a74a5fc491d7f16bd89e3e21523b1643 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 28 Feb 2022 14:33:49 +0100 Subject: [PATCH] Tech ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES - Use vertex attributes and matrices in shaders. Shader: flat - Picking for base gizmo grabbers and gizmo rotate grabber extensions --- src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 46 ++++++++--- src/slic3r/GUI/Gizmos/GLGizmoBase.hpp | 3 + src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 102 ++++++++++++++++++++---- src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp | 4 + 4 files changed, 131 insertions(+), 24 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index 82702f212..a45ea7a4a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -4,8 +4,10 @@ #include #include "slic3r/GUI/GUI_App.hpp" - #include "slic3r/GUI/GUI_ObjectManipulation.hpp" +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES +#include "slic3r/GUI/Plater.hpp" +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES // TODO: Display tooltips quicker on Linux @@ -33,11 +35,19 @@ float GLGizmoBase::Grabber::get_dragging_half_size(float size) const void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, bool picking) { +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_current_shader(); + if (shader == nullptr) + return; + + bool use_attributes = boost::algorithm::iends_with(shader->get_name(), "_attr"); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + if (!m_cube.is_initialized()) { // This cannot be done in constructor, OpenGL is not yet // initialized at that point (on Linux at least). indexed_triangle_set its = its_make_cube(1., 1., 1.); - its_translate(its, Vec3f(-0.5, -0.5, -0.5)); + its_translate(its, -0.5f * Vec3f::Ones()); #if ENABLE_GLBEGIN_GLEND_REMOVAL m_cube.init_from(its); #else @@ -53,14 +63,28 @@ void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, boo m_cube.set_color(-1, render_color); #endif // ENABLE_GLBEGIN_GLEND_REMOVAL - glsafe(::glPushMatrix()); - glsafe(::glTranslated(center.x(), center.y(), center.z())); - glsafe(::glRotated(Geometry::rad2deg(angles.z()), 0.0, 0.0, 1.0)); - glsafe(::glRotated(Geometry::rad2deg(angles.y()), 0.0, 1.0, 0.0)); - glsafe(::glRotated(Geometry::rad2deg(angles.x()), 1.0, 0.0, 0.0)); - glsafe(::glScaled(fullsize, fullsize, fullsize)); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + if (use_attributes) { + const Transform3d trafo = wxGetApp().plater()->get_camera().get_projection_view_matrix() * matrix * + Geometry::assemble_transform(center, angles, fullsize * Vec3d::Ones()); + shader->set_uniform("projection_view_model_matrix", trafo); + } + else { +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + glsafe(::glPushMatrix()); + glsafe(::glTranslated(center.x(), center.y(), center.z())); + glsafe(::glRotated(Geometry::rad2deg(angles.z()), 0.0, 0.0, 1.0)); + glsafe(::glRotated(Geometry::rad2deg(angles.y()), 0.0, 1.0, 0.0)); + glsafe(::glRotated(Geometry::rad2deg(angles.x()), 1.0, 0.0, 0.0)); + glsafe(::glScaled(fullsize, fullsize, fullsize)); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + } +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES m_cube.render(); - glsafe(::glPopMatrix()); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + if (!use_attributes) +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + glsafe(::glPopMatrix()); } GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) @@ -129,7 +153,11 @@ void GLGizmoBase::render_grabbers(float size) const void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const { #if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat"); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); #endif // ENABLE_GLBEGIN_GLEND_REMOVAL diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index 6f62382e1..c4adccf44 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -49,6 +49,9 @@ protected: bool dragging{ false }; Vec3d center{ Vec3d::Zero() }; Vec3d angles{ Vec3d::Zero() }; +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + Transform3d matrix{ Transform3d::Identity() }; +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES ColorRGBA color{ ColorRGBA::WHITE() }; Grabber() = default; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index a09ac8057..cf69864db 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -219,15 +219,20 @@ void GLGizmoRotate::on_render_for_picking() glsafe(::glDisable(GL_DEPTH_TEST)); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + m_grabbers.front().matrix = local_transform(selection); +#else glsafe(::glPushMatrix()); - transform_to_local(selection); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES const BoundingBoxf3& box = selection.get_bounding_box(); render_grabbers_for_picking(box); render_grabber_extension(box, true); +#if !ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES } void GLGizmoRotate3D::on_render_input_window(float x, float y, float bottom_limit) @@ -550,10 +555,18 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick const double size = m_dragging ? double(m_grabbers.front().get_dragging_half_size(mean_size)) : double(m_grabbers.front().get_half_size(mean_size)); #if ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat_attr" : "gouraud_light"); +#else GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat" : "gouraud_light"); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES if (shader == nullptr) return; +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + bool use_attributes = boost::algorithm::iends_with(shader->get_name(), "_attr"); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + m_cone.set_color((!picking && m_hover_id != -1) ? complementary(m_grabbers.front().color) : m_grabbers.front().color); shader->start_using(); @@ -572,22 +585,49 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick const Vec3d& center = m_grabbers.front().center; - glsafe(::glPushMatrix()); - glsafe(::glTranslated(center.x(), center.y(), center.z())); - glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0)); - glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); - glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); - glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + if (use_attributes) { + const Transform3d trafo = wxGetApp().plater()->get_camera().get_projection_view_matrix() * m_grabbers.front().matrix * + Geometry::assemble_transform(center, Vec3d(0.5 * PI, 0.0, m_angle)) * + Geometry::assemble_transform(Vec3d(0.0, 0.0, 2.0 * size), Vec3d::Zero(), Vec3d(0.75 * size, 0.75 * size, 3.0 * size)); + shader->set_uniform("projection_view_model_matrix", trafo); + } + else { +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + glsafe(::glPushMatrix()); + glsafe(::glTranslated(center.x(), center.y(), center.z())); + glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0)); + glsafe(::glRotated(90.0, 1.0, 0.0, 0.0)); + glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); + glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + } +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES m_cone.render(); - glsafe(::glPopMatrix()); - glsafe(::glPushMatrix()); - glsafe(::glTranslated(center.x(), center.y(), center.z())); - glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0)); - glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); - glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); - glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + if (use_attributes) { + const Transform3d trafo = wxGetApp().plater()->get_camera().get_projection_view_matrix() * m_grabbers.front().matrix * + Geometry::assemble_transform(center, Vec3d(-0.5 * PI, 0.0, m_angle)) * + Geometry::assemble_transform(Vec3d(0.0, 0.0, 2.0 * size), Vec3d::Zero(), Vec3d(0.75 * size, 0.75 * size, 3.0 * size)); + shader->set_uniform("projection_view_model_matrix", trafo); + } + else { +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + glsafe(::glPopMatrix()); + glsafe(::glPushMatrix()); + glsafe(::glTranslated(center.x(), center.y(), center.z())); + glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0)); + glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0)); + glsafe(::glTranslated(0.0, 0.0, 2.0 * size)); + glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size)); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + } +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES m_cone.render(); - glsafe(::glPopMatrix()); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + if (!use_attributes) +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + glsafe(::glPopMatrix()); #if !ENABLE_GLBEGIN_GLEND_REMOVAL if (! picking) @@ -595,6 +635,38 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick shader->stop_using(); } +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES +Transform3d GLGizmoRotate::local_transform(const Selection& selection) const +{ + Transform3d ret; + + switch (m_axis) + { + case X: + { + ret = Geometry::assemble_transform(Vec3d::Zero(), Vec3d(0.0, 0.5 * PI, 0.0)) * Geometry::assemble_transform(Vec3d::Zero(), Vec3d(0.0, 0.0, -0.5 * PI)); + break; + } + case Y: + { + ret = Geometry::assemble_transform(Vec3d::Zero(), Vec3d(0.0, 0.0, -0.5 * PI)) * Geometry::assemble_transform(Vec3d::Zero(), Vec3d(0.0, -0.5 * PI, 0.0)); + break; + } + default: + case Z: + { + ret = Transform3d::Identity(); + break; + } + } + + if (selection.is_single_volume() || selection.is_single_modifier() || selection.requires_local_axes()) + ret = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix(true, false, true, true) * ret; + + return Geometry::assemble_transform(m_center) * ret; +} +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + void GLGizmoRotate::transform_to_local(const Selection& selection) const { glsafe(::glTranslated(m_center.x(), m_center.y(), m_center.z())); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp index d0474df0e..59a06524a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp @@ -106,6 +106,10 @@ private: void render_grabber(const BoundingBoxf3& box); void render_grabber_extension(const BoundingBoxf3& box, bool picking); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + Transform3d local_transform(const Selection& selection) const; +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + void transform_to_local(const Selection& selection) const; // returns the intersection of the mouse ray with the plane perpendicular to the gizmo axis, in local coordinate Vec3d mouse_position_in_local_plane(const Linef3& mouse_ray, const Selection& selection) const;