diff --git a/resources/shaders/flat_attr.vs b/resources/shaders/flat_attr.vs new file mode 100644 index 000000000..1b0088675 --- /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/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 8e7fba126..ac4dace80 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -70,6 +70,8 @@ #define ENABLE_GLBEGIN_GLEND_REMOVAL (1 && ENABLE_2_5_0_ALPHA1) // Enable replace GLIndexedVertexArray with GLModel #define ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL (1 && ENABLE_GLBEGIN_GLEND_REMOVAL) +// Enable using vertex attributes and matrices in shaders +#define ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES (1 && ENABLE_GLBEGIN_GLEND_REMOVAL) // Enable show non-manifold edges #define ENABLE_SHOW_NON_MANIFOLD_EDGES (1 && ENABLE_2_5_0_ALPHA1) // Enable rework of Reload from disk command diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 244a802db..b0b6fcd42 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -11,6 +11,10 @@ #include "GUI_App.hpp" #include "GLCanvas3D.hpp" +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES +#include "Plater.hpp" +#include "Camera.hpp" +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES #include @@ -384,7 +388,7 @@ void Bed3D::init_gridlines() init_data.reserve_vertices(2 * gridlines.size()); init_data.reserve_indices(2 * gridlines.size()); - for (const Line& l : gridlines) { + for (const Slic3r::Line& l : gridlines) { init_data.add_vertex(Vec3f(unscale(l.a.x()), unscale(l.a.y()), GROUND_Z)); init_data.add_vertex(Vec3f(unscale(l.b.x()), unscale(l.b.y()), GROUND_Z)); const unsigned int vertices_counter = (unsigned int)init_data.vertices_count(); @@ -694,10 +698,19 @@ void Bed3D::render_default(bool bottom, bool picking) init_gridlines(); init_triangles(); +#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(); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + const Transform3d matrix = wxGetApp().plater()->get_camera().get_projection_view_matrix(); + shader->set_uniform("projection_view_model_matrix", matrix); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + 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 a61eb44ec..6a0158e6d 100644 --- a/src/slic3r/GUI/Camera.hpp +++ b/src/slic3r/GUI/Camera.hpp @@ -78,6 +78,9 @@ 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; } +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + Transform3d get_projection_view_matrix() const { return m_projection_matrix * m_view_matrix; } +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES Vec3d get_dir_right() const { return m_view_matrix.matrix().block(0, 0, 3, 3).row(0); } Vec3d get_dir_up() const { return m_view_matrix.matrix().block(0, 0, 3, 3).row(1); } diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index f0eac9a24..6eeeda7d9 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -982,17 +982,64 @@ void GLModel::render(const std::pair& range) glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id)); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + bool use_attributes = boost::algorithm::iends_with(shader->get_name(), "_attr"); + + int position_id = -1; + int normal_id = -1; + int tex_coord_id = -1; +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + 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 ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + 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 { +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + 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 ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + } +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES } if (normal) { - glsafe(::glNormalPointer(GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::normal_offset_bytes(data.format))); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + 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 { +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + glsafe(::glNormalPointer(GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::normal_offset_bytes(data.format))); + glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + } +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES } 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 ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + 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 { +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + 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 ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + } +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES } shader->set_uniform("uniform_color", data.color); @@ -1001,12 +1048,26 @@ 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 ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + 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 { +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + if (tex_coord) + glsafe(::glDisableClientState(GL_TEXTURE_COORD_ARRAY)); + if (normal) + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); + if (position) + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + } +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); } diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index 33ac9b6bc..70b1b6c31 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -36,6 +36,9 @@ std::pair GLShadersManager::init() #if ENABLE_GLBEGIN_GLEND_REMOVAL // basic shader, used to render all what was previously rendered using the immediate mode valid &= append_shader("flat", { "flat.vs", "flat.fs" }); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + valid &= append_shader("flat_attr", { "flat_attr.vs", "flat.fs" }); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES // 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