From 7be3edc3bc428798a10fb3e60fe9fdf7359aea47 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 8 Apr 2022 08:18:48 +0200 Subject: [PATCH] Tech ENABLE_OPENGL_ES - Added shader wireframe --- resources/shaders/ES/wireframe.fs | 19 ++++ resources/shaders/ES/wireframe.vs | 20 ++++ src/slic3r/GUI/GLModel.cpp | 124 +++++++++++++++++----- src/slic3r/GUI/GLModel.hpp | 32 +++--- src/slic3r/GUI/GLShadersManager.cpp | 2 + src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp | 29 ++++- 6 files changed, 183 insertions(+), 43 deletions(-) create mode 100644 resources/shaders/ES/wireframe.fs create mode 100644 resources/shaders/ES/wireframe.vs diff --git a/resources/shaders/ES/wireframe.fs b/resources/shaders/ES/wireframe.fs new file mode 100644 index 0000000000..036ee88792 --- /dev/null +++ b/resources/shaders/ES/wireframe.fs @@ -0,0 +1,19 @@ +#version 100 +#extension GL_OES_standard_derivatives : enable + +// see for reference: https://stackoverflow.com/questions/7361582/opengl-debugging-single-pass-wireframe-rendering + +precision highp float; + +uniform vec4 uniform_color; + +varying vec3 barycentric; + +void main() +{ + float min_dist = min(min(barycentric.x, barycentric.y), barycentric.z); + if (min_dist > 0.5 * fwidth(min_dist)) + discard; + + gl_FragColor = uniform_color; +} \ No newline at end of file diff --git a/resources/shaders/ES/wireframe.vs b/resources/shaders/ES/wireframe.vs new file mode 100644 index 0000000000..00a5214f58 --- /dev/null +++ b/resources/shaders/ES/wireframe.vs @@ -0,0 +1,20 @@ +#version 100 + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +uniform float offset; + +attribute vec3 v_position; +attribute vec3 v_normal; +attribute vec3 v_extra; + +varying vec3 barycentric; + +void main() +{ + barycentric = v_extra; + // Add small epsilon to z to solve z-fighting + vec4 clip_position = projection_matrix * view_model_matrix * vec4(v_position, 1.0); + clip_position.z -= offset * abs(clip_position.w); + gl_Position = clip_position; +} \ No newline at end of file diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index a2c9b54d7d..fdc3e8a0ae 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -112,6 +112,20 @@ void GLModel::Geometry::add_vertex(const Vec3f& position, const Vec3f& normal) vertices.emplace_back(normal.z()); } +void GLModel::Geometry::add_vertex(const Vec3f& position, const Vec3f& normal, const Vec3f& extra) +{ + assert(format.vertex_layout == EVertexLayout::P3N3E3); + vertices.emplace_back(position.x()); + vertices.emplace_back(position.y()); + vertices.emplace_back(position.z()); + vertices.emplace_back(normal.x()); + vertices.emplace_back(normal.y()); + vertices.emplace_back(normal.z()); + vertices.emplace_back(extra.x()); + vertices.emplace_back(extra.y()); + vertices.emplace_back(extra.z()); +} + void GLModel::Geometry::add_vertex(const Vec4f& position) { assert(format.vertex_layout == EVertexLayout::P4); @@ -253,13 +267,14 @@ size_t GLModel::Geometry::vertex_stride_floats(const Format& format) { switch (format.vertex_layout) { - case EVertexLayout::P2: { return 2; } - case EVertexLayout::P2T2: { return 4; } - case EVertexLayout::P3: { return 3; } - case EVertexLayout::P3T2: { return 5; } - case EVertexLayout::P3N3: { return 6; } - case EVertexLayout::P4: { return 4; } - default: { assert(false); return 0; } + case EVertexLayout::P2: { return 2; } + case EVertexLayout::P2T2: { return 4; } + case EVertexLayout::P3: { return 3; } + case EVertexLayout::P3T2: { return 5; } + case EVertexLayout::P3N3: { return 6; } + case EVertexLayout::P3N3E3: { return 9; } + case EVertexLayout::P4: { return 4; } + default: { assert(false); return 0; } }; } @@ -268,12 +283,13 @@ size_t GLModel::Geometry::position_stride_floats(const Format& format) switch (format.vertex_layout) { case EVertexLayout::P2: - case EVertexLayout::P2T2: { return 2; } + case EVertexLayout::P2T2: { return 2; } case EVertexLayout::P3: case EVertexLayout::P3T2: - case EVertexLayout::P3N3: { return 3; } - case EVertexLayout::P4: { return 4; } - default: { assert(false); return 0; } + case EVertexLayout::P3N3: + case EVertexLayout::P3N3E3: { return 3; } + case EVertexLayout::P4: { return 4; } + default: { assert(false); return 0; } }; } @@ -286,8 +302,9 @@ size_t GLModel::Geometry::position_offset_floats(const Format& format) case EVertexLayout::P3: case EVertexLayout::P3T2: case EVertexLayout::P3N3: - case EVertexLayout::P4: { return 0; } - default: { assert(false); return 0; } + case EVertexLayout::P3N3E3: + case EVertexLayout::P4: { return 0; } + default: { assert(false); return 0; } }; } @@ -295,8 +312,9 @@ size_t GLModel::Geometry::normal_stride_floats(const Format& format) { switch (format.vertex_layout) { - case EVertexLayout::P3N3: { return 3; } - default: { assert(false); return 0; } + case EVertexLayout::P3N3: + case EVertexLayout::P3N3E3: { return 3; } + default: { assert(false); return 0; } }; } @@ -304,8 +322,9 @@ size_t GLModel::Geometry::normal_offset_floats(const Format& format) { switch (format.vertex_layout) { - case EVertexLayout::P3N3: { return 3; } - default: { assert(false); return 0; } + case EVertexLayout::P3N3: + case EVertexLayout::P3N3E3: { return 3; } + default: { assert(false); return 0; } }; } @@ -329,6 +348,24 @@ size_t GLModel::Geometry::tex_coord_offset_floats(const Format& format) }; } +size_t GLModel::Geometry::extra_stride_floats(const Format& format) +{ + switch (format.vertex_layout) + { + case EVertexLayout::P3N3E3: { return 3; } + default: { assert(false); return 0; } + }; +} + +size_t GLModel::Geometry::extra_offset_floats(const Format& format) +{ + switch (format.vertex_layout) + { + case EVertexLayout::P3N3E3: { return 6; } + default: { assert(false); return 0; } + }; +} + size_t GLModel::Geometry::index_stride_bytes(const Geometry& data) { switch (data.index_type) @@ -349,8 +386,9 @@ bool GLModel::Geometry::has_position(const Format& format) case EVertexLayout::P3: case EVertexLayout::P3T2: case EVertexLayout::P3N3: - case EVertexLayout::P4: { return true; } - default: { assert(false); return false; } + case EVertexLayout::P3N3E3: + case EVertexLayout::P4: { return true; } + default: { assert(false); return false; } }; } @@ -362,9 +400,10 @@ bool GLModel::Geometry::has_normal(const Format& format) case EVertexLayout::P2T2: case EVertexLayout::P3: case EVertexLayout::P3T2: - case EVertexLayout::P4: { return false; } - case EVertexLayout::P3N3: { return true; } - default: { assert(false); return false; } + case EVertexLayout::P4: { return false; } + case EVertexLayout::P3N3: + case EVertexLayout::P3N3E3: { return true; } + default: { assert(false); return false; } }; } @@ -373,12 +412,28 @@ bool GLModel::Geometry::has_tex_coord(const Format& format) switch (format.vertex_layout) { case EVertexLayout::P2T2: - case EVertexLayout::P3T2: { return true; } + case EVertexLayout::P3T2: { return true; } case EVertexLayout::P2: case EVertexLayout::P3: case EVertexLayout::P3N3: - case EVertexLayout::P4: { return false; } - default: { assert(false); return false; } + case EVertexLayout::P3N3E3: + case EVertexLayout::P4: { return false; } + default: { assert(false); return false; } + }; +} + +bool GLModel::Geometry::has_extra(const Format& format) +{ + switch (format.vertex_layout) + { + case EVertexLayout::P3N3E3: { return true; } + case EVertexLayout::P2: + case EVertexLayout::P2T2: + case EVertexLayout::P3: + case EVertexLayout::P3T2: + case EVertexLayout::P3N3: + case EVertexLayout::P4: { return false; } + default: { assert(false); return false; } }; } #else @@ -868,9 +923,10 @@ void GLModel::render(const std::pair& range) const GLenum index_type = get_index_type(data); const size_t vertex_stride_bytes = Geometry::vertex_stride_bytes(data.format); - const bool position = Geometry::has_position(data.format); - const bool normal = Geometry::has_normal(data.format); + const bool position = Geometry::has_position(data.format); + const bool normal = Geometry::has_normal(data.format); const bool tex_coord = Geometry::has_tex_coord(data.format); + const bool extra = Geometry::has_extra(data.format); #if ENABLE_GL_CORE_PROFILE glsafe(::glBindVertexArray(m_render_data.vao_id)); @@ -878,9 +934,10 @@ void GLModel::render(const std::pair& range) #endif // ENABLE_GL_CORE_PROFILE glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id)); - int position_id = -1; - int normal_id = -1; + int position_id = -1; + int normal_id = -1; int tex_coord_id = -1; + int extra_id = -1; if (position) { position_id = shader->get_attrib_location("v_position"); @@ -903,6 +960,13 @@ void GLModel::render(const std::pair& range) glsafe(::glEnableVertexAttribArray(tex_coord_id)); } } + if (extra) { + extra_id = shader->get_attrib_location("v_extra"); + if (extra_id != -1) { + glsafe(::glVertexAttribPointer(extra_id, Geometry::extra_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (const void*)Geometry::extra_offset_bytes(data.format))); + glsafe(::glEnableVertexAttribArray(extra_id)); + } + } shader->set_uniform("uniform_color", data.color); @@ -914,6 +978,8 @@ void GLModel::render(const std::pair& range) glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); #endif // !ENABLE_GL_CORE_PROFILE + if (extra_id != -1) + glsafe(::glDisableVertexAttribArray(extra_id)); if (tex_coord_id != -1) glsafe(::glDisableVertexAttribArray(tex_coord_id)); if (normal_id != -1) diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index 64f0c67625..e88af0c0ec 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -58,12 +58,13 @@ namespace GUI { enum class EVertexLayout : unsigned char { - P2, // position 2 floats - P2T2, // position 2 floats + texture coords 2 floats - P3, // position 3 floats - P3T2, // position 3 floats + texture coords 2 floats - P3N3, // position 3 floats + normal 3 floats - P4, // position 4 floats + P2, // position 2 floats + P2T2, // position 2 floats + texture coords 2 floats + P3, // position 3 floats + P3T2, // position 3 floats + texture coords 2 floats + P3N3, // position 3 floats + normal 3 floats + P3N3E3, // position 3 floats + normal 3 floats + extra 3 floats + P4, // position 4 floats }; enum class EIndexType : unsigned char @@ -88,12 +89,13 @@ namespace GUI { void reserve_vertices(size_t vertices_count) { vertices.reserve(vertices_count * vertex_stride_floats(format)); } void reserve_indices(size_t indices_count) { indices.reserve(indices_count); } - void add_vertex(const Vec2f& position); // EVertexLayout::P2 - void add_vertex(const Vec2f& position, const Vec2f& tex_coord); // EVertexLayout::P2T2 - void add_vertex(const Vec3f& position); // EVertexLayout::P3 - void add_vertex(const Vec3f& position, const Vec2f& tex_coord); // EVertexLayout::P3T2 - void add_vertex(const Vec3f& position, const Vec3f& normal); // EVertexLayout::P3N3 - void add_vertex(const Vec4f& position); // EVertexLayout::P4 + void add_vertex(const Vec2f& position); // EVertexLayout::P2 + void add_vertex(const Vec2f& position, const Vec2f& tex_coord); // EVertexLayout::P2T2 + void add_vertex(const Vec3f& position); // EVertexLayout::P3 + void add_vertex(const Vec3f& position, const Vec2f& tex_coord); // EVertexLayout::P3T2 + void add_vertex(const Vec3f& position, const Vec3f& normal); // EVertexLayout::P3N3 + void add_vertex(const Vec3f& position, const Vec3f& normal, const Vec3f& extra); // EVertexLayout::P3N3E3 + void add_vertex(const Vec4f& position); // EVertexLayout::P4 void set_vertex(size_t id, const Vec3f& position, const Vec3f& normal); // EVertexLayout::P3N3 @@ -139,11 +141,17 @@ namespace GUI { static size_t tex_coord_offset_floats(const Format& format); static size_t tex_coord_offset_bytes(const Format& format) { return tex_coord_offset_floats(format) * sizeof(float); } + static size_t extra_stride_floats(const Format& format); + static size_t extra_stride_bytes(const Format& format) { return extra_stride_floats(format) * sizeof(float); } + static size_t extra_offset_floats(const Format& format); + static size_t extra_offset_bytes(const Format& format) { return extra_offset_floats(format) * sizeof(float); } + static size_t index_stride_bytes(const Geometry& data); static bool has_position(const Format& format); static bool has_normal(const Format& format); static bool has_tex_coord(const Format& format); + static bool has_extra(const Format& format); #else struct Entity { diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index 02a175fa6e..da8bf254ff 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -36,6 +36,8 @@ std::pair GLShadersManager::init() #if ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_OPENGL_ES const std::string prefix = "ES/"; + // used to render wireframed triangles + valid &= append_shader("wireframe", { prefix + "wireframe.vs", prefix + "wireframe.fs" }); #else const std::string prefix = GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 1) ? "140/" : "110/"; #endif // ENABLE_OPENGL_ES diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp index c34678c5d2..372b1a8ae3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp @@ -354,9 +354,7 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi ImGui::Text(_u8L("%d triangles").c_str(), m_configuration.wanted_count); m_imgui->disabled_end(); // use_count -#if !ENABLE_OPENGL_ES ImGui::Checkbox(_u8L("Show wireframe").c_str(), &m_show_wireframe); -#endif // !ENABLE_OPENGL_ES m_imgui->disabled_begin(is_cancelling); if (m_imgui->button(_L("Close"))) { @@ -700,7 +698,30 @@ void GLGizmoSimplify::update_model(const State::Data &data) auto color = glmodel.get_color(); // when not reset it keeps old shape glmodel.reset(); +#if ENABLE_OPENGL_ES + GLModel::Geometry init_data; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3E3 }; + init_data.reserve_vertices(3 * its.indices.size()); + init_data.reserve_indices(3 * its.indices.size()); + + // vertices + indices + std::array barycentric_coords = { Vec3f::UnitX(), Vec3f::UnitY(), Vec3f::UnitZ() }; + unsigned int vertices_counter = 0; + for (uint32_t i = 0; i < its.indices.size(); ++i) { + const stl_triangle_vertex_indices face = its.indices[i]; + const stl_vertex vertex[3] = { its.vertices[face[0]], its.vertices[face[1]], its.vertices[face[2]] }; + const stl_vertex n = face_normal_normalized(vertex); + for (size_t j = 0; j < 3; ++j) { + init_data.add_vertex(vertex[j], n, barycentric_coords[j]); + } + vertices_counter += 3; + init_data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1); + } + + glmodel.init_from(std::move(init_data)); +#else glmodel.init_from(its); +#endif // ENABLE_OPENGL_ES #if ENABLE_LEGACY_OPENGL_REMOVAL glmodel.set_color(color); #else @@ -763,7 +784,11 @@ void GLGizmoSimplify::on_render() gouraud_shader->stop_using(); if (m_show_wireframe) { +#if ENABLE_OPENGL_ES + auto* contour_shader = wxGetApp().get_shader("wireframe"); +#else auto *contour_shader = wxGetApp().get_shader("mm_contour"); +#endif // ENABLE_OPENGL_ES contour_shader->start_using(); contour_shader->set_uniform("offset", OpenGLManager::get_gl_info().is_mesa() ? 0.0005 : 0.00001); #if ENABLE_LEGACY_OPENGL_REMOVAL