Wireframe: Fix edges or non manifold meshes not showing.

This will show the associated edges to the vertices but that's the only
workaround I can think of right now.
This commit is contained in:
Clément Foucault
2018-06-07 18:01:29 +02:00
parent f9ca750bdf
commit 00233f5f78
3 changed files with 55 additions and 43 deletions

View File

@@ -3391,22 +3391,21 @@ static EdgeHash *create_looptri_edge_adjacency_hash(MeshRenderData *rdata)
return eh;
}
static Gwn_VertBuf *mesh_batch_cache_create_edges_overlay_adj_texture_buf(MeshRenderData *rdata, bool do_adjacency)
static Gwn_VertBuf *mesh_batch_cache_create_edges_overlay_texture_buf(MeshRenderData *rdata)
{
const int tri_len = mesh_render_data_looptri_len_get(rdata);
Gwn_VertFormat format = {0};
uint index_id = GWN_vertformat_attr_add(&format, "index", GWN_COMP_I32, 1, GWN_FETCH_INT);
uint index_id = GWN_vertformat_attr_add(&format, "index", GWN_COMP_U32, 1, GWN_FETCH_INT);
Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
int vbo_len_capacity = tri_len * ((do_adjacency) ? 6 : 3);
int vbo_len_capacity = tri_len * 3;
GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
int vidx = 0;
EdgeHash *eh = NULL;
if (do_adjacency) {
eh = create_looptri_edge_adjacency_hash(rdata);
}
eh = create_looptri_edge_adjacency_hash(rdata);
for (int i = 0; i < tri_len; i++) {
bool edge_is_real[3] = {false, false, false};
@@ -3427,33 +3426,23 @@ static Gwn_VertBuf *mesh_batch_cache_create_edges_overlay_adj_texture_buf(MeshRe
}
for (int e = 0; e < 3; ++e) {
/* Save if there is an edge or not inside the sign bit. */
int v0 = mloop[mlt->tri[e]].v;
int value = (int)v0 + 1; /* Int 0 cannot be signed */
value = (edge_is_real[e]) ? -value : value;
GWN_vertbuf_attr_set(vbo, index_id, vidx++, &value);
if (do_adjacency) {
int v1 = mloop[mlt->tri[(e + 1) % 3]].v;
int v2 = mloop[mlt->tri[(e + 2) % 3]].v;
EdgeAdjacentVerts *eav = BLI_edgehash_lookup(eh, v0, v1);
int adj_v;
if (eav->vert_index[0] != v2) {
adj_v = eav->vert_index[0];
}
else if (eav->vert_index[1] != -1) {
adj_v = eav->vert_index[1];
}
else {
adj_v = v2; /* Non-manifold edge */
}
GWN_vertbuf_attr_set(vbo, index_id, vidx++, &adj_v);
int v1 = mloop[mlt->tri[(e + 1) % 3]].v;
EdgeAdjacentVerts *eav = BLI_edgehash_lookup(eh, v0, v1);
uint value = (uint)v0;
/* Real edge */
if (edge_is_real[e]) {
value |= (1 << 30);
}
/* Non-manifold edge */
if (eav->vert_index[1] == -1) {
value |= (1 << 31);
}
GWN_vertbuf_attr_set(vbo, index_id, vidx++, &value);
}
}
if (do_adjacency) {
BLI_edgehash_free(eh, MEM_freeN);
}
BLI_edgehash_free(eh, MEM_freeN);
int vbo_len_used = vidx;
@@ -3474,7 +3463,7 @@ static GPUTexture *mesh_batch_cache_get_edges_overlay_texture_buf(MeshRenderData
return cache->edges_face_overlay_tx;
}
Gwn_VertBuf *vbo = cache->edges_face_overlay = mesh_batch_cache_create_edges_overlay_adj_texture_buf(rdata, false);
Gwn_VertBuf *vbo = cache->edges_face_overlay = mesh_batch_cache_create_edges_overlay_texture_buf(rdata);
/* Upload data early because we need to create the texture for it. */
GWN_vertbuf_use(vbo);

View File

@@ -18,6 +18,7 @@ out float facing;
#ifdef LIGHT_EDGES
in vec3 obPos[];
in vec3 vNor[];
in float forceEdge[];
out float edgeSharpness;
#endif
@@ -52,6 +53,7 @@ void main(void)
vec3 fnor = normalize(cross(obPos[1] - obPos[0], obPos[2] - obPos[0]));
edgeSharpness = get_edge_sharpness(fnor, vNor[0]);
edgeSharpness = (forceEdge[0] == 1.0 || forceEdge[2] == 1.0) ? 1.0 : edgeSharpness;
#endif
gl_Position = gl_in[0].gl_Position;
facing = facings.x;
@@ -59,6 +61,7 @@ void main(void)
#ifdef LIGHT_EDGES
edgeSharpness = get_edge_sharpness(fnor, vNor[1]);
edgeSharpness = (forceEdge[1] == 1.0 || forceEdge[0] == 1.0) ? 1.0 : edgeSharpness;
#endif
gl_Position = gl_in[1].gl_Position;
facing = facings.y;
@@ -66,6 +69,7 @@ void main(void)
#ifdef LIGHT_EDGES
edgeSharpness = get_edge_sharpness(fnor, vNor[2]);
edgeSharpness = (forceEdge[2] == 1.0 || forceEdge[1] == 1.0) ? 1.0 : edgeSharpness;
#endif
gl_Position = gl_in[2].gl_Position;
facing = facings.z;

View File

@@ -9,7 +9,7 @@ uniform vec2 viewportSize;
uniform float nearDist;
uniform samplerBuffer vertData;
uniform isamplerBuffer faceIds;
uniform usamplerBuffer faceIds;
#ifdef USE_GEOM_SHADER
out vec2 ssPos;
@@ -25,6 +25,7 @@ out float facing;
#ifdef USE_GEOM_SHADER
out vec3 obPos;
out vec3 vNor;
out float forceEdge;
#else
out float edgeSharpness;
#endif
@@ -52,9 +53,9 @@ float short_to_unit_float(uint s)
return float(value) / float(0x7FFF);
}
vec3 get_vertex_nor(int v_id)
vec3 get_vertex_nor(uint id)
{
v_id *= 5; /* See vertex format for explanation. */
int v_id = int(id) * 5; /* See vertex format for explanation. */
/* Fetch compressed normal as float and unpack them. */
vec2 data;
data.x = texelFetch(vertData, v_id + 3).r;
@@ -69,9 +70,9 @@ vec3 get_vertex_nor(int v_id)
return nor;
}
vec3 get_vertex_pos(int v_id)
vec3 get_vertex_pos(uint id)
{
v_id *= 5; /* See vertex format for explanation. */
int v_id = int(id) * 5; /* See vertex format for explanation. */
vec3 pos;
pos.x = texelFetch(vertData, v_id).r;
pos.y = texelFetch(vertData, v_id + 1).r;
@@ -90,10 +91,11 @@ float get_edge_sharpness(vec3 fnor, vec3 vnor)
void main()
{
#ifdef USE_GEOM_SHADER
int v_id = texelFetch(faceIds, gl_VertexID).r;
uint v_id = texelFetch(faceIds, gl_VertexID).r;
bool do_edge = v_id < 0;
v_id = abs(v_id) - 1;
bool do_edge = (v_id & (1u << 30u)) != 0u;
bool force_edge = (v_id & (1u << 31u)) != 0u;
v_id = (v_id << 2u) >> 2u;
vec3 pos = get_vertex_pos(v_id);
vec3 nor = get_vertex_nor(v_id);
@@ -106,6 +108,7 @@ void main()
# ifdef LIGHT_EDGES
obPos = pos;
vNor = nor;
forceEdge = float(force_edge); /* meh, could try to also encode it in facingOut */
# endif
#else
@@ -113,13 +116,19 @@ void main()
int v_n = gl_VertexID % 3;
/* Getting the same positions for each of the 3 verts. */
ivec3 v_id;
uvec3 v_id;
v_id.x = texelFetch(faceIds, v_0).r;
v_id.y = texelFetch(faceIds, v_0 + 1).r;
v_id.z = texelFetch(faceIds, v_0 + 2).r;
bvec3 do_edge = lessThan(v_id, ivec3(0));
v_id = abs(v_id) - 1;
bvec3 do_edge, force_edge;
do_edge.x = (v_id.x & (1u << 30u)) != 0u;
do_edge.y = (v_id.y & (1u << 30u)) != 0u;
do_edge.z = (v_id.z & (1u << 30u)) != 0u;
force_edge.x = (v_id.x & (1u << 31u)) != 0u;
force_edge.y = (v_id.y & (1u << 31u)) != 0u;
force_edge.z = (v_id.z & (1u << 31u)) != 0u;
v_id = (v_id << 2u) >> 2u;
vec3 pos[3];
pos[0] = get_vertex_pos(v_id.x);
@@ -144,12 +153,22 @@ void main()
gl_Position = p_pos[v_n];
vec3 nor = get_vertex_nor(v_id[v_n]);
vec3 vnor = normalize(NormalMatrix * nor);
facing = vnor.z;
facing = normalize(NormalMatrix * nor).z;
# ifdef LIGHT_EDGES
vec3 fnor = normalize(cross(pos[1] - pos[0], pos[2] - pos[0]));
edgeSharpness = get_edge_sharpness(fnor, nor);
/* Fix disapearing edges. */
if (v_n == 0) {
force_edge.xy = force_edge.xz;
}
else if (v_n == 2) {
force_edge.xy = force_edge.yz;
}
if (any(force_edge.xy)) {
edgeSharpness = 1.0;
}
# endif
#endif