diff --git a/resources/shaders/flat_texture_attr.vs b/resources/shaders/flat_texture_attr.vs new file mode 100644 index 000000000..bdd675052 --- /dev/null +++ b/resources/shaders/flat_texture_attr.vs @@ -0,0 +1,24 @@ +#version 110 + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +attribute vec3 v_position; +attribute vec2 v_tex_coord; + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +varying vec2 tex_coord; + +void main() +{ +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + tex_coord = v_tex_coord; + gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0); +// gl_Position = vec4(v_position, 1.0); + + +// gl_Position = ftransform(); +// tex_coord = gl_MultiTexCoord0.xy; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +} diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index dc0d9cfab..fb9a9cecf 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -41,7 +41,11 @@ std::pair GLShadersManager::init() valid &= append_shader("flat", { "flat.vs", "flat.fs" }); #endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES // basic shader for textures, used to render textures +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + valid &= append_shader("flat_texture_attr", { "flat_texture_attr.vs", "flat_texture.fs" }); +#else valid &= append_shader("flat_texture", { "flat_texture.vs", "flat_texture.fs" }); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES // used to render 3D scene background #if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES valid &= append_shader("background_attr", { "background_attr.vs", "background.fs" }); diff --git a/src/slic3r/GUI/GLTexture.cpp b/src/slic3r/GUI/GLTexture.cpp index 340bb78c3..8cfc8fd05 100644 --- a/src/slic3r/GUI/GLTexture.cpp +++ b/src/slic3r/GUI/GLTexture.cpp @@ -358,9 +358,17 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right, GLModel model; model.init_from(std::move(init_data)); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("flat_texture_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("flat_texture"); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + shader->set_uniform("view_model_matrix", Transform3d::Identity()); + shader->set_uniform("projection_matrix", Transform3d::Identity()); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES model.render(); shader->stop_using(); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index fba02963f..499a2fe49 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -665,6 +665,60 @@ void GLGizmosManager::update_after_undo_redo(const UndoRedo::Snapshot& snapshot) dynamic_cast(m_gizmos[SlaSupports].get())->reslice_SLA_supports(true); } +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES +void GLGizmosManager::render_background(float left, float top, float right, float bottom, float border_w, float border_h) const +{ + const unsigned int tex_id = m_background_texture.texture.get_id(); + const float tex_width = float(m_background_texture.texture.get_width()); + const float tex_height = float(m_background_texture.texture.get_height()); + if (tex_id != 0 && tex_width > 0 && tex_height > 0) { + const float inv_tex_width = (tex_width != 0.0f) ? 1.0f / tex_width : 0.0f; + const float inv_tex_height = (tex_height != 0.0f) ? 1.0f / tex_height : 0.0f; + + const float internal_left = left + border_w; + const float internal_right = right - border_w; + const float internal_top = top - border_h; + const float internal_bottom = bottom + border_h; + + // float left_uv = 0.0f; + const float right_uv = 1.0f; + const float top_uv = 1.0f; + const float bottom_uv = 0.0f; + + const float internal_left_uv = float(m_background_texture.metadata.left) * inv_tex_width; + const float internal_right_uv = 1.0f - float(m_background_texture.metadata.right) * inv_tex_width; + const float internal_top_uv = 1.0f - float(m_background_texture.metadata.top) * inv_tex_height; + const float internal_bottom_uv = float(m_background_texture.metadata.bottom) * inv_tex_height; + + // top-left corner + GLTexture::render_sub_texture(tex_id, left, internal_left, internal_top, top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } }); + + // top edge + GLTexture::render_sub_texture(tex_id, internal_left, internal_right, internal_top, top, { { internal_left_uv, internal_top_uv }, { internal_right_uv, internal_top_uv }, { internal_right_uv, top_uv }, { internal_left_uv, top_uv } }); + + // top-right corner + GLTexture::render_sub_texture(tex_id, internal_right, right, internal_top, top, { { internal_right_uv, internal_top_uv }, { right_uv, internal_top_uv }, { right_uv, top_uv }, { internal_right_uv, top_uv } }); + + // center-left edge + GLTexture::render_sub_texture(tex_id, left, internal_left, internal_bottom, internal_top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } }); + + // center + GLTexture::render_sub_texture(tex_id, internal_left, internal_right, internal_bottom, internal_top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } }); + + // center-right edge + GLTexture::render_sub_texture(tex_id, internal_right, right, internal_bottom, internal_top, { { internal_right_uv, internal_bottom_uv }, { right_uv, internal_bottom_uv }, { right_uv, internal_top_uv }, { internal_right_uv, internal_top_uv } }); + + // bottom-left corner + GLTexture::render_sub_texture(tex_id, left, internal_left, bottom, internal_bottom, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } }); + + // bottom edge + GLTexture::render_sub_texture(tex_id, internal_left, internal_right, bottom, internal_bottom, { { internal_left_uv, bottom_uv }, { internal_right_uv, bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_left_uv, internal_bottom_uv } }); + + // bottom-right corner + GLTexture::render_sub_texture(tex_id, internal_right, right, bottom, internal_bottom, { { internal_right_uv, bottom_uv }, { right_uv, bottom_uv }, { right_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv } }); + } +} +#else void GLGizmosManager::render_background(float left, float top, float right, float bottom, float border) const { const unsigned int tex_id = m_background_texture.texture.get_id(); @@ -717,6 +771,7 @@ void GLGizmosManager::render_background(float left, float top, float right, floa GLTexture::render_sub_texture(tex_id, internal_right, right, bottom, internal_bottom, { { internal_right_uv, bottom_uv }, { right_uv, bottom_uv }, { right_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv } }); } } +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES void GLGizmosManager::render_arrow(const GLCanvas3D& parent, EType highlighted_type) const { @@ -757,20 +812,95 @@ void GLGizmosManager::render_arrow(const GLCanvas3D& parent, EType highlighted_t } } +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES void GLGizmosManager::do_render_overlay() const { std::vector selectable_idxs = get_selectable_idxs(); if (selectable_idxs.empty()) return; - float cnv_w = (float)m_parent.get_canvas_size().get_width(); - float cnv_h = (float)m_parent.get_canvas_size().get_height(); - float zoom = (float)wxGetApp().plater()->get_camera().get_zoom(); - float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); + const Size cnv_size = m_parent.get_canvas_size(); + const float cnv_w = (float)cnv_size.get_width(); + const float cnv_h = (float)cnv_size.get_height(); - float height = get_scaled_total_height(); - float width = get_scaled_total_width(); - float zoomed_border = m_layout.scaled_border() * inv_zoom; + if (cnv_w == 0 || cnv_h == 0) + return; + + const float inv_cnv_w = 1.0f / cnv_w; + const float inv_cnv_h = 1.0f / cnv_h; + + const float height = 2.0f * get_scaled_total_height() * inv_cnv_h; + const float width = 2.0f * get_scaled_total_width() * inv_cnv_w; + const float border_h = 2.0f * m_layout.scaled_border() * inv_cnv_h; + const float border_w = 2.0f * m_layout.scaled_border() * inv_cnv_w; + + float top_x = -1.0f; + float top_y = 0.5f * height; + + render_background(top_x, top_y, top_x + width, top_y - height, border_w, border_h); + + top_x += border_w; + top_y -= border_h; + + const float icons_size_x = 2.0f * m_layout.scaled_icons_size() * inv_cnv_w; + const float icons_size_y = 2.0f * m_layout.scaled_icons_size() * inv_cnv_h; + const float stride_y = 2.0f * m_layout.scaled_stride_y() * inv_cnv_h; + + const unsigned int icons_texture_id = m_icons_texture.get_id(); + const int tex_width = m_icons_texture.get_width(); + const int tex_height = m_icons_texture.get_height(); + + if (icons_texture_id == 0 || tex_width <= 1 || tex_height <= 1) + return; + + const float du = (float)(tex_width - 1) / (6.0f * (float)tex_width); // 6 is the number of possible states if the icons + const float dv = (float)(tex_height - 1) / (float)(m_gizmos.size() * tex_height); + + // tiles in the texture are spaced by 1 pixel + const float u_offset = 1.0f / (float)tex_width; + const float v_offset = 1.0f / (float)tex_height; + + float current_y = FLT_MAX; + for (size_t idx : selectable_idxs) { + GLGizmoBase* gizmo = m_gizmos[idx].get(); + const unsigned int sprite_id = gizmo->get_sprite_id(); + // higlighted state needs to be decided first so its highlighting in every other state + const int icon_idx = (m_highlight.first == idx ? (m_highlight.second ? 4 : 5) : (m_current == idx) ? 2 : ((m_hover == idx) ? 1 : (gizmo->is_activable() ? 0 : 3))); + + const float u_left = u_offset + icon_idx * du; + const float u_right = u_left + du - u_offset; + const float v_top = v_offset + sprite_id * dv; + const float v_bottom = v_top + dv - v_offset; + + GLTexture::render_sub_texture(icons_texture_id, top_x, top_x + icons_size_x, top_y - icons_size_y, top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } }); + if (idx == m_current || current_y == FLT_MAX) { + // The FLT_MAX trick is here so that even non-selectable but activable + // gizmos are passed some meaningful value. + current_y = 0.5f * cnv_h - top_y; + } + top_y -= stride_y; + } + + if (m_current != Undefined) { + const float toolbar_top = cnv_h - wxGetApp().plater()->get_view_toolbar().get_height(); + m_gizmos[m_current]->render_input_window(width, current_y, toolbar_top); + } +} +#else +void GLGizmosManager::do_render_overlay() const +{ + std::vector selectable_idxs = get_selectable_idxs(); + if (selectable_idxs.empty()) + return; + + const float cnv_w = (float)m_parent.get_canvas_size().get_width(); + const float cnv_h = (float)m_parent.get_canvas_size().get_height(); + const float zoom = (float)wxGetApp().plater()->get_camera().get_zoom(); + const float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); + + const float height = get_scaled_total_height(); + const float width = get_scaled_total_width(); + const float zoomed_border = m_layout.scaled_border() * inv_zoom; float zoomed_top_x = (-0.5f * cnv_w) * inv_zoom; float zoomed_top_y = (0.5f * height) * inv_zoom; @@ -785,36 +915,35 @@ void GLGizmosManager::do_render_overlay() const zoomed_top_x += zoomed_border; zoomed_top_y -= zoomed_border; - float icons_size = m_layout.scaled_icons_size(); - float zoomed_icons_size = icons_size * inv_zoom; - float zoomed_stride_y = m_layout.scaled_stride_y() * inv_zoom; + const float icons_size = m_layout.scaled_icons_size(); + const float zoomed_icons_size = icons_size * inv_zoom; + const float zoomed_stride_y = m_layout.scaled_stride_y() * inv_zoom; - unsigned int icons_texture_id = m_icons_texture.get_id(); - int tex_width = m_icons_texture.get_width(); - int tex_height = m_icons_texture.get_height(); + const unsigned int icons_texture_id = m_icons_texture.get_id(); + const int tex_width = m_icons_texture.get_width(); + const int tex_height = m_icons_texture.get_height(); - if ((icons_texture_id == 0) || (tex_width <= 1) || (tex_height <= 1)) + if (icons_texture_id == 0 || tex_width <= 1 || tex_height <= 1) return; - float du = (float)(tex_width - 1) / (6.0f * (float)tex_width); // 6 is the number of possible states if the icons - float dv = (float)(tex_height - 1) / (float)(m_gizmos.size() * tex_height); + const float du = (float)(tex_width - 1) / (6.0f * (float)tex_width); // 6 is the number of possible states if the icons + const float dv = (float)(tex_height - 1) / (float)(m_gizmos.size() * tex_height); // tiles in the texture are spaced by 1 pixel - float u_offset = 1.0f / (float)tex_width; - float v_offset = 1.0f / (float)tex_height; + const float u_offset = 1.0f / (float)tex_width; + const float v_offset = 1.0f / (float)tex_height; - float current_y = FLT_MAX; - for (size_t idx : selectable_idxs) - { + float current_y = FLT_MAX; + for (size_t idx : selectable_idxs) { GLGizmoBase* gizmo = m_gizmos[idx].get(); - unsigned int sprite_id = gizmo->get_sprite_id(); + const unsigned int sprite_id = gizmo->get_sprite_id(); // higlighted state needs to be decided first so its highlighting in every other state - int icon_idx = (m_highlight.first == idx ? (m_highlight.second ? 4 : 5) : (m_current == idx) ? 2 : ((m_hover == idx) ? 1 : (gizmo->is_activable()? 0 : 3))); + const int icon_idx = (m_highlight.first == idx ? (m_highlight.second ? 4 : 5) : (m_current == idx) ? 2 : ((m_hover == idx) ? 1 : (gizmo->is_activable()? 0 : 3))); - float v_top = v_offset + sprite_id * dv; - float u_left = u_offset + icon_idx * du; - float v_bottom = v_top + dv - v_offset; - float u_right = u_left + du - u_offset; + const float u_left = u_offset + icon_idx * du; + const float u_right = u_left + du - u_offset; + const float v_top = v_offset + sprite_id * dv; + const float v_bottom = v_top + dv - v_offset; GLTexture::render_sub_texture(icons_texture_id, zoomed_top_x, zoomed_top_x + zoomed_icons_size, zoomed_top_y - zoomed_icons_size, zoomed_top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } }); if (idx == m_current || current_y == FLT_MAX) { @@ -826,10 +955,11 @@ void GLGizmosManager::do_render_overlay() const } if (m_current != Undefined) { - float toolbar_top = cnv_h - wxGetApp().plater()->get_view_toolbar().get_height(); + const float toolbar_top = cnv_h - wxGetApp().plater()->get_view_toolbar().get_height(); m_gizmos[m_current]->render_input_window(width, current_y, toolbar_top); } } +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES float GLGizmosManager::get_scaled_total_height() const { diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index b8dfdec78..3bdcd0f65 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -234,8 +234,12 @@ private: bool alt_down = false, bool control_down = false); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + void render_background(float left, float top, float right, float bottom, float border_w, float border_h) const; +#else void render_background(float left, float top, float right, float bottom, float border) const; - +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + void do_render_overlay() const; float get_scaled_total_height() const;