diff --git a/resources/shaders/flat_attr.vs b/resources/shaders/flat_attr.vs new file mode 100644 index 0000000000..1b00886757 --- /dev/null +++ b/resources/shaders/flat_attr.vs @@ -0,0 +1,10 @@ +#version 110 + +attribute vec3 v_position; + +uniform mat4 projection_view_model_matrix; + +void main() +{ + gl_Position = projection_view_model_matrix * vec4(v_position, 1.0); +} diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 26b6c89908..55a25c5141 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -12,6 +12,8 @@ #include "GUI_App.hpp" #include "GUI_Colors.hpp" #include "GLCanvas3D.hpp" +#include "Plater.hpp" +#include "Camera.hpp" #include @@ -702,10 +704,13 @@ void Bed3D::render_default(bool bottom) update_bed_triangles(); - GLShaderProgram *shader = wxGetApp().get_shader("flat"); + GLShaderProgram* shader = wxGetApp().get_shader("flat_attr"); if (shader != nullptr) { shader->start_using(); + const Transform3d matrix = wxGetApp().plater()->get_camera().get_projection_view_matrix(); + shader->set_uniform("projection_view_model_matrix", matrix); + glsafe(::glEnable(GL_DEPTH_TEST)); glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); diff --git a/src/slic3r/GUI/Camera.hpp b/src/slic3r/GUI/Camera.hpp index 401365ad4e..4abaedecac 100644 --- a/src/slic3r/GUI/Camera.hpp +++ b/src/slic3r/GUI/Camera.hpp @@ -92,6 +92,7 @@ public: const std::array& get_viewport() const { return m_viewport; } const Transform3d& get_view_matrix() const { return m_view_matrix; } const Transform3d& get_projection_matrix() const { return m_projection_matrix; } + Transform3d get_projection_view_matrix() const { return m_projection_matrix * m_view_matrix; } //BBS const Eigen::Quaterniond& get_view_rotation() const {return m_view_rotation; } diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index e73d7bc4e0..1d2337bc60 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -664,17 +664,50 @@ void GLModel::render(const std::pair& range) glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id)); + bool use_attributes = boost::algorithm::iends_with(shader->get_name(), "_attr"); + + int position_id = -1; + int normal_id = -1; + int tex_coord_id = -1; + if (position) { - glsafe(::glVertexPointer(Geometry::position_stride_floats(data.format), GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::position_offset_bytes(data.format))); - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + if (use_attributes) { + position_id = shader->get_attrib_location("v_position"); + if (position_id != -1) { + glsafe(::glVertexAttribPointer(position_id, Geometry::position_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (GLvoid*)Geometry::position_offset_bytes(data.format))); + glsafe(::glEnableVertexAttribArray(position_id)); + } + } + else { + glsafe(::glVertexPointer(Geometry::position_stride_floats(data.format), GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::position_offset_bytes(data.format))); + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + } } if (normal) { - glsafe(::glNormalPointer(GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::normal_offset_bytes(data.format))); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); + if (use_attributes) { + normal_id = shader->get_attrib_location("v_normal"); + if (normal_id != -1) { + glsafe(::glVertexAttribPointer(normal_id, Geometry::normal_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (GLvoid*)Geometry::normal_offset_bytes(data.format))); + glsafe(::glEnableVertexAttribArray(normal_id)); + } + } + else { + glsafe(::glNormalPointer(GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::normal_offset_bytes(data.format))); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); + } } if (tex_coord) { - glsafe(::glTexCoordPointer(Geometry::tex_coord_stride_floats(data.format), GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::tex_coord_offset_bytes(data.format))); - glsafe(::glEnableClientState(GL_TEXTURE_COORD_ARRAY)); + if (use_attributes) { + tex_coord_id = shader->get_attrib_location("v_tex_coord"); + if (tex_coord_id != -1) { + glsafe(::glVertexAttribPointer(tex_coord_id, Geometry::tex_coord_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (GLvoid*)Geometry::tex_coord_offset_bytes(data.format))); + glsafe(::glEnableVertexAttribArray(tex_coord_id)); + } + } + else { + glsafe(::glTexCoordPointer(Geometry::tex_coord_stride_floats(data.format), GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::tex_coord_offset_bytes(data.format))); + glsafe(::glEnableClientState(GL_TEXTURE_COORD_ARRAY)); + } } shader->set_uniform("uniform_color", data.color); @@ -683,12 +716,22 @@ void GLModel::render(const std::pair& range) glsafe(::glDrawElements(mode, range.second - range.first, index_type, (const void*)(range.first * Geometry::index_stride_bytes(data.format)))); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - if (tex_coord) - glsafe(::glDisableClientState(GL_TEXTURE_COORD_ARRAY)); - if (normal) - glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); - if (position) - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + if (use_attributes) { + if (tex_coord_id != -1) + glsafe(::glDisableVertexAttribArray(tex_coord_id)); + if (normal_id != -1) + glsafe(::glDisableVertexAttribArray(normal_id)); + if (position_id != -1) + glsafe(::glDisableVertexAttribArray(position_id)); + } + else { + if (tex_coord) + glsafe(::glDisableClientState(GL_TEXTURE_COORD_ARRAY)); + if (normal) + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); + if (position) + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + } glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); } diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index e544296714..c00599805c 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -35,6 +35,7 @@ std::pair GLShadersManager::init() // basic shader, used to render all what was previously rendered using the immediate mode valid &= append_shader("flat", { "flat.vs", "flat.fs" }); + valid &= append_shader("flat_attr", { "flat_attr.vs", "flat.fs" }); // basic shader for textures, used to render textures valid &= append_shader("flat_texture", { "flat_texture.vs", "flat_texture.fs" }); // used to render 3D scene background diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index ee7f3bc47e..d56b369f38 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -2496,13 +2496,16 @@ bool PartPlate::intersects(const BoundingBoxf3& bb) const void PartPlate::render(bool bottom, bool only_body, bool force_background_color, HeightLimitMode mode, int hover_id, bool render_cali) { - GLShaderProgram *shader = wxGetApp().get_shader("flat"); + GLShaderProgram *shader = wxGetApp().get_shader("flat_attr"); if (shader != nullptr) { shader->start_using(); glsafe(::glEnable(GL_DEPTH_TEST)); glsafe(::glEnable(GL_BLEND)); glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + const Transform3d matrix = wxGetApp().plater()->get_camera().get_projection_view_matrix(); + shader->set_uniform("projection_view_model_matrix", matrix); + if (!bottom) { // draw background render_background(force_background_color);