Tech ENABLE_OPENGL_ES - Added shader wireframe

This commit is contained in:
enricoturri1966 2022-04-08 08:18:48 +02:00
parent 8513e78759
commit 7be3edc3bc
6 changed files with 183 additions and 43 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<size_t, size_t>& 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<size_t, size_t>& 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<size_t, size_t>& 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<size_t, size_t>& 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)

View File

@ -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
{

View File

@ -36,6 +36,8 @@ std::pair<bool, std::string> 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

View File

@ -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<Vec3f, 3> 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