Wireframe: Refactor to use GL_LINES instead of triangles with alpha blend
authorClément Foucault <foucault.clem@gmail.com>
Tue, 12 Feb 2019 22:22:36 +0000 (23:22 +0100)
committerClément Foucault <foucault.clem@gmail.com>
Mon, 18 Feb 2019 13:17:57 +0000 (14:17 +0100)
This gets rid of the progressive fading of the edges as it does not work
with depth perception (sorting problem with alpha blending).

source/blender/draw/intern/draw_cache_impl_mesh.c
source/blender/draw/modes/overlay_mode.c
source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl
source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl

index 0228f108c1dbf5929b201afef0f1da3f1f03bc09..6fe0344bf7663cae8874129ad2d96560e7618812 100644 (file)
@@ -1176,7 +1176,7 @@ static int mesh_render_data_loose_verts_len_get_maybe_mapped(const MeshRenderDat
        return ((rdata->mapped.use == false) ? rdata->loose_vert_len : rdata->mapped.loose_vert_len);
 }
 
-static int UNUSED_FUNCTION(mesh_render_data_edges_len_get)(const MeshRenderData *rdata)
+static int mesh_render_data_edges_len_get(const MeshRenderData *rdata)
 {
        BLI_assert(rdata->types & MR_DATATYPE_EDGE);
        return rdata->edge_len;
@@ -1750,6 +1750,7 @@ typedef struct MeshBatchCache {
                GPUVertBuf *loop_pos_nor;
                GPUVertBuf *loop_uv_tan;
                GPUVertBuf *loop_vcol;
+               GPUVertBuf *loop_edge_fac;
        } ordered;
 
        /* Tesselated: (all verts specified for each triangles).
@@ -1795,13 +1796,14 @@ typedef struct MeshBatchCache {
                /* Indices to vloops. */
                GPUIndexBuf *loops_tris;
                GPUIndexBuf *loops_lines;
+               GPUIndexBuf *loops_line_strips;
                /* Edit mode. */
                GPUIndexBuf *edit_loops_points; /* verts */
                GPUIndexBuf *edit_loops_lines; /* edges */
                GPUIndexBuf *edit_loops_tris; /* faces */
                /* Edit UVs */
                GPUIndexBuf *edituv_loops_points; /* verts */
-               GPUIndexBuf *edituv_loops_lines; /* edges */
+               GPUIndexBuf *edituv_loops_line_strips; /* edges */
                GPUIndexBuf *edituv_loops_tri_fans; /* faces */
        } ibo;
 
@@ -1832,6 +1834,7 @@ typedef struct MeshBatchCache {
                GPUBatch *all_edges;
                GPUBatch *loose_edges;
                GPUBatch *edge_detection;
+               GPUBatch *wire_edges; /* Individual edges with face normals. */
                GPUBatch *wire_loops; /* Loops around faces. */
                GPUBatch *wire_loops_uvs; /* Same as wire_loops but only has uvs. */
                GPUBatch *wire_triangles; /* Triangles for object mode wireframe. */
@@ -1998,7 +2001,7 @@ static void mesh_batch_cache_discard_uvedit(MeshBatchCache *cache)
        GPU_VERTBUF_DISCARD_SAFE(cache->edit.facedots_uv);
        GPU_VERTBUF_DISCARD_SAFE(cache->edit.facedots_uv_data);
        GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_tri_fans);
-       GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_lines);
+       GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_line_strips);
        GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_points);
        GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_strech_area);
        GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_strech_angle);
@@ -2847,6 +2850,115 @@ static void mesh_create_weights(MeshRenderData *rdata, GPUVertBuf *vbo, DRW_Mesh
        GPU_vertbuf_attr_fill(vbo, attr_id.weight, vert_weight);
 }
 
+static float mesh_loop_edge_factor_get(
+        const float f_no[3], const float v_co[3], const float v_no[3], const float v_next_co[3])
+{
+       float enor[3], evec[3];
+       sub_v3_v3v3(evec, v_next_co, v_co);
+       cross_v3_v3v3(enor, v_no, evec);
+       normalize_v3(enor);
+       float d = fabsf(dot_v3v3(enor, f_no));
+       /* Rescale to the slider range. */
+       d *= (1.0f / 0.065f);
+       CLAMP(d, 0.0f, 1.0f);
+       return d;
+}
+
+static void mesh_create_loop_edge_fac(MeshRenderData *rdata, GPUVertBuf *vbo)
+{
+       static GPUVertFormat format = { 0 };
+       static struct { uint wd; } attr_id;
+       if (format.attr_len == 0) {
+               attr_id.wd = GPU_vertformat_attr_add(&format, "wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
+       }
+       const int poly_len = mesh_render_data_polys_len_get(rdata);
+       const int loop_len = mesh_render_data_loops_len_get(rdata);
+       const int edge_len = mesh_render_data_edges_len_get(rdata);
+
+       GPU_vertbuf_init_with_format(vbo, &format);
+       GPU_vertbuf_data_alloc(vbo, loop_len);
+
+       GPUVertBufRaw wd_step;
+       GPU_vertbuf_attr_get_raw_data(vbo, attr_id.wd, &wd_step);
+
+       if (rdata->mapped.use == false) {
+               if (rdata->edit_bmesh) {
+                       BMesh *bm = rdata->edit_bmesh->bm;
+                       BMIter iter_efa, iter_loop;
+                       BMFace *efa;
+                       BMLoop *loop;
+                       uint f;
+
+                       BM_ITER_MESH_INDEX (efa, &iter_efa, bm, BM_FACES_OF_MESH, f) {
+                               BM_ITER_ELEM (loop, &iter_loop, efa, BM_LOOPS_OF_FACE) {
+                                       float ratio = mesh_loop_edge_factor_get(efa->no, loop->v->co, loop->v->no, loop->next->v->co);
+                                       *((uchar *)GPU_vertbuf_raw_step(&wd_step)) = ratio * 255;
+                               }
+                       }
+                       BLI_assert(GPU_vertbuf_raw_used(&wd_step) == loop_len);
+               }
+               else {
+                       const MVert *mvert = rdata->mvert;
+                       const MPoly *mpoly = rdata->mpoly;
+                       const MLoop *mloop = rdata->mloop;
+                       MEdge *medge = (MEdge *)rdata->medge;
+                       bool use_edge_render = false;
+
+                       /* TODO(fclem) We don't need them to be packed. But we need rdata->poly_normals */
+                       mesh_render_data_ensure_poly_normals_pack(rdata);
+
+                       /* Reset flag */
+                       for (int edge = 0; edge < edge_len; ++edge) {
+                               /* NOTE: not thread safe. */
+                               medge[edge].flag &= ~ME_EDGE_TMP_TAG;
+
+                               /* HACK(fclem) Feels like a hack. Detecting the need for edge render. */
+                               if ((medge[edge].flag & ME_EDGERENDER) == 0) {
+                                       use_edge_render = true;
+                               }
+                       }
+
+                       for (int a = 0; a < poly_len; a++, mpoly++) {
+                               const float *fnor = rdata->poly_normals[a];
+                               for (int b = 0; b < mpoly->totloop; b++) {
+                                       const MLoop *ml1 = &mloop[mpoly->loopstart + b];
+                                       const MLoop *ml2 = &mloop[mpoly->loopstart + (b + 1) % mpoly->totloop];
+
+                                       /* Will only work for edges that have an odd number of faces connected. */
+                                       MEdge *ed = (MEdge *)rdata->medge + ml1->e;
+                                       ed->flag ^= ME_EDGE_TMP_TAG;
+
+                                       if (use_edge_render) {
+                                               *((uchar *)GPU_vertbuf_raw_step(&wd_step)) = (ed->flag & ME_EDGERENDER) ? 255 : 0;
+                                       }
+                                       else {
+                                               float vnor_f[3];
+                                               normal_short_to_float_v3(vnor_f, mvert[ml1->v].no);
+                                               float ratio = mesh_loop_edge_factor_get(fnor,
+                                                                                       mvert[ml1->v].co,
+                                                                                       vnor_f,
+                                                                                       mvert[ml2->v].co);
+                                               *((uchar *)GPU_vertbuf_raw_step(&wd_step)) = ratio * 253 + 1;
+                                       }
+                               }
+                       }
+                       /* Gather non-manifold edges. */
+                       for (int l = 0; l < loop_len; l++, mloop++) {
+                               MEdge *ed = (MEdge *)rdata->medge + mloop->e;
+                               if (ed->flag & ME_EDGE_TMP_TAG) {
+                                       uchar data = 255;
+                                       GPU_vertbuf_attr_set(vbo, attr_id.wd, l, &data);
+                               }
+                       }
+
+                       BLI_assert(loop_len == GPU_vertbuf_raw_used(&wd_step));
+               }
+       }
+       else {
+               BLI_assert(0);
+       }
+}
+
 static void mesh_create_loop_pos_and_nor(MeshRenderData *rdata, GPUVertBuf *vbo)
 {
        /* TODO deduplicate format creation*/
@@ -3603,6 +3715,72 @@ static void mesh_create_surf_tris(MeshRenderData *rdata, GPUIndexBuf *ibo, const
 
 static void mesh_create_loops_lines(
         MeshRenderData *rdata, GPUIndexBuf *ibo, const bool use_hide)
+{
+       const int edge_len = mesh_render_data_edges_len_get(rdata);
+       const int loop_len = mesh_render_data_loops_len_get(rdata);
+       const int poly_len = mesh_render_data_polys_len_get(rdata);
+
+       GPUIndexBufBuilder elb;
+       GPU_indexbuf_init(&elb, GPU_PRIM_LINES, edge_len, loop_len);
+
+       if (rdata->mapped.use == false) {
+               if (rdata->edit_bmesh) {
+                       BMesh *bm = rdata->edit_bmesh->bm;
+                       BMIter iter;
+                       BMEdge *bm_edge;
+
+                       BM_ITER_MESH (bm_edge, &iter, bm, BM_EDGES_OF_MESH) {
+                               /* use_hide always for edit-mode */
+                               if (!BM_elem_flag_test(bm_edge, BM_ELEM_HIDDEN) &&
+                                       bm_edge->l != NULL)
+                               {
+                                       BMLoop *bm_loop1 = BM_vert_find_first_loop(bm_edge->v1);
+                                       BMLoop *bm_loop2 = BM_vert_find_first_loop(bm_edge->v2);
+                                       int v1 = BM_elem_index_get(bm_loop1);
+                                       int v2 = BM_elem_index_get(bm_loop2);
+                                       if (v1 > v2) {
+                                               SWAP(int, v1, v2);
+                                       }
+                                       GPU_indexbuf_add_line_verts(&elb, v1, v2);
+                               }
+                       }
+               }
+               else {
+                       MLoop *mloop = (MLoop *)rdata->mloop;
+                       MEdge *medge = (MEdge *)rdata->medge;
+
+                       /* Reset flag */
+                       for (int edge = 0; edge < edge_len; ++edge) {
+                               /* NOTE: not thread safe. */
+                               medge[edge].flag &= ~ME_EDGE_TMP_TAG;
+                       }
+
+                       for (int poly = 0; poly < poly_len; poly++) {
+                               const MPoly *mp = &rdata->mpoly[poly];
+                               if (!(use_hide && (mp->flag & ME_HIDE))) {
+                                       for (int j = 0; j < mp->totloop; j++) {
+                                               MEdge *ed = (MEdge *)rdata->medge + mloop[mp->loopstart + j].e;
+                                               if ((ed->flag & ME_EDGE_TMP_TAG) == 0) {
+                                                       ed->flag |= ME_EDGE_TMP_TAG;
+                                                       int v1 = mp->loopstart + j;
+                                                       int v2 = mp->loopstart + (j + 1) % mp->totloop;
+                                                       GPU_indexbuf_add_line_verts(&elb, v1, v2);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       else {
+               /* Implement ... eventually if needed. */
+               BLI_assert(0);
+       }
+
+       GPU_indexbuf_build_in_place(&elb, ibo);
+}
+
+static void mesh_create_loops_line_strips(
+        MeshRenderData *rdata, GPUIndexBuf *ibo, const bool use_hide)
 {
        const int loop_len = mesh_render_data_loops_len_get(rdata);
        const int poly_len = mesh_render_data_polys_len_get(rdata);
@@ -4125,7 +4303,7 @@ GPUBatch *DRW_mesh_batch_cache_get_edge_detection(Mesh *me, bool *r_is_manifold)
 GPUBatch *DRW_mesh_batch_cache_get_wireframes_face(Mesh *me)
 {
        MeshBatchCache *cache = mesh_batch_cache_get(me);
-       return DRW_batch_request(&cache->batch.wire_triangles);
+       return DRW_batch_request(&cache->batch.wire_edges);
 }
 
 GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(
@@ -4705,7 +4883,7 @@ void DRW_mesh_batch_cache_create_requested(
                        GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_uv);
                        GPU_VERTBUF_DISCARD_SAFE(cache->edit.facedots_uv);
                        GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_tri_fans);
-                       GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_lines);
+                       GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_line_strips);
                        GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_points);
                        /* We only clear the batches as they may already have been referenced. */
                        GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_faces_strech_area);
@@ -4750,11 +4928,16 @@ void DRW_mesh_batch_cache_create_requested(
                DRW_vbo_request(cache->batch.surface_weights, &cache->ordered.weights);
        }
        if (DRW_batch_requested(cache->batch.wire_loops, GPU_PRIM_LINE_STRIP)) {
-               DRW_ibo_request(cache->batch.wire_loops, &cache->ibo.loops_lines);
+               DRW_ibo_request(cache->batch.wire_loops, &cache->ibo.loops_line_strips);
                DRW_vbo_request(cache->batch.wire_loops, &cache->ordered.loop_pos_nor);
        }
+       if (DRW_batch_requested(cache->batch.wire_edges, GPU_PRIM_LINES)) {
+               DRW_ibo_request(cache->batch.wire_edges, &cache->ibo.loops_lines);
+               DRW_vbo_request(cache->batch.wire_edges, &cache->ordered.loop_pos_nor);
+               DRW_vbo_request(cache->batch.wire_edges, &cache->ordered.loop_edge_fac);
+       }
        if (DRW_batch_requested(cache->batch.wire_loops_uvs, GPU_PRIM_LINE_STRIP)) {
-               DRW_ibo_request(cache->batch.wire_loops_uvs, &cache->ibo.loops_lines);
+               DRW_ibo_request(cache->batch.wire_loops_uvs, &cache->ibo.loops_line_strips);
                /* For paint overlay. Active layer should have been queried. */
                if (cache->cd_lused[CD_MLOOPUV] != 0) {
                        DRW_vbo_request(cache->batch.wire_loops_uvs, &cache->ordered.loop_uv_tan);
@@ -4809,7 +4992,7 @@ void DRW_mesh_batch_cache_create_requested(
                DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &cache->edit.loop_stretch_angle);
        }
        if (DRW_batch_requested(cache->batch.edituv_edges, GPU_PRIM_LINES)) {
-               DRW_ibo_request(cache->batch.edituv_edges, &cache->ibo.edituv_loops_lines);
+               DRW_ibo_request(cache->batch.edituv_edges, &cache->ibo.edituv_loops_line_strips);
                DRW_vbo_request(cache->batch.edituv_edges, &cache->edit.loop_uv);
                DRW_vbo_request(cache->batch.edituv_edges, &cache->edit.loop_uv_data);
        }
@@ -4877,11 +5060,13 @@ void DRW_mesh_batch_cache_create_requested(
        DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_pos_nor, MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP);
        DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_uv_tan, MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_SHADING);
        DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_vcol, MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_SHADING);
+       DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_edge_fac, MR_DATATYPE_POLY | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP);
        DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->tess.pos_nor, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI | MR_DATATYPE_POLY);
        DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->tess.wireframe_data, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI);
        DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.surf_tris, MR_DATATYPE_VERT | MR_DATATYPE_LOOP |  MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI);
        DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.loops_tris, MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI);
-       DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.loops_lines, MR_DATATYPE_LOOP | MR_DATATYPE_POLY);
+       DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.loops_lines, MR_DATATYPE_LOOP | MR_DATATYPE_EDGE | MR_DATATYPE_POLY);
+       DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.loops_line_strips, MR_DATATYPE_LOOP | MR_DATATYPE_POLY);
        DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.edges_lines, MR_DATATYPE_VERT | MR_DATATYPE_EDGE);
        DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.edges_adj_lines, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI);
        DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.loose_edges_lines, MR_DATATYPE_VERT | MR_DATATYPE_EDGE);
@@ -4906,7 +5091,7 @@ void DRW_mesh_batch_cache_create_requested(
        DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.facedots_uv, combined_edit_flag | MR_DATATYPE_LOOPUV);
        DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.facedots_uv_data, combined_edit_flag);
        DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edituv_loops_points, combined_edit_flag);
-       DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edituv_loops_lines, combined_edit_flag);
+       DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edituv_loops_line_strips, combined_edit_flag);
        DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edituv_loops_tri_fans, combined_edit_flag);
        /* TODO: Some of the flags here may not be needed. */
        DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edit_loops_points, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI);
@@ -4936,6 +5121,9 @@ void DRW_mesh_batch_cache_create_requested(
        if (DRW_vbo_requested(cache->ordered.loop_pos_nor)) {
                mesh_create_loop_pos_and_nor(rdata, cache->ordered.loop_pos_nor);
        }
+       if (DRW_vbo_requested(cache->ordered.loop_edge_fac)) {
+               mesh_create_loop_edge_fac(rdata, cache->ordered.loop_edge_fac);
+       }
        if (DRW_vbo_requested(cache->ordered.loop_uv_tan)) {
                mesh_create_loop_uv_and_tan(rdata, cache->ordered.loop_uv_tan);
        }
@@ -4963,6 +5151,9 @@ void DRW_mesh_batch_cache_create_requested(
        if (DRW_ibo_requested(cache->ibo.loops_lines)) {
                mesh_create_loops_lines(rdata, cache->ibo.loops_lines, use_hide);
        }
+       if (DRW_ibo_requested(cache->ibo.loops_line_strips)) {
+               mesh_create_loops_line_strips(rdata, cache->ibo.loops_line_strips, use_hide);
+       }
        if (DRW_ibo_requested(cache->ibo.loops_tris)) {
                mesh_create_loops_tris(rdata, &cache->ibo.loops_tris, 1, use_hide);
        }
@@ -5042,14 +5233,14 @@ void DRW_mesh_batch_cache_create_requested(
            DRW_vbo_requested(cache->edit.facedots_uv) ||
            DRW_vbo_requested(cache->edit.facedots_uv_data) ||
            DRW_ibo_requested(cache->ibo.edituv_loops_points) ||
-           DRW_ibo_requested(cache->ibo.edituv_loops_lines) ||
+           DRW_ibo_requested(cache->ibo.edituv_loops_line_strips) ||
            DRW_ibo_requested(cache->ibo.edituv_loops_tri_fans))
        {
                mesh_create_uvedit_buffers(rdata,
                                           cache->edit.loop_stretch_area, cache->edit.loop_stretch_angle,
                                           cache->edit.facedots_uv, cache->edit.facedots_uv_data,
                                           cache->ibo.edituv_loops_points,
-                                          cache->ibo.edituv_loops_lines,
+                                          cache->ibo.edituv_loops_line_strips,
                                           cache->ibo.edituv_loops_tri_fans);
        }
 
index 550dfe0be7acfccf7bc75732c46571499eb20d02..9ff8e2b30f111b3dd898776f38a6eaff3e43e1c6 100644 (file)
@@ -55,7 +55,7 @@ typedef struct OVERLAY_PrivateData {
        DRWShadingGroup *flat_wires_shgrp;
        DRWShadingGroup *sculpt_wires_shgrp;
        View3DOverlay overlay;
-       float wire_step_param[2];
+       float wire_step_param;
        bool ghost_stencil_test;
        bool show_overlays;
 } OVERLAY_PrivateData; /* Transient data */
@@ -127,9 +127,8 @@ static void overlay_engine_init(void *vedata)
                });
                sh_data->face_wireframe_sculpt = GPU_shader_create_from_arrays({
                        .vert = (const char *[]){sh_cfg_data->lib, datatoc_overlay_face_wireframe_vert_glsl, NULL},
-                       .geom = (const char *[]){sh_cfg_data->lib, datatoc_overlay_face_wireframe_geom_glsl, NULL},
                        .frag = (const char *[]){datatoc_overlay_face_wireframe_frag_glsl, NULL},
-                       .defs = (const char *[]){sh_cfg_data->def, "#define USE_SCULPT\n", NULL},
+                       .defs = (const char *[]){sh_cfg_data->def, NULL},
                });
        }
 }
@@ -179,7 +178,7 @@ static void overlay_cache_init(void *vedata)
 
        {
                /* Wireframe */
-               DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND | DRW_STATE_FIRST_VERTEX_CONVENTION;
+               DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_FIRST_VERTEX_CONVENTION | DRW_STATE_OFFSET_NEGATIVE;
                float wire_size = max_ff(0.0f, U.pixelsize - 1.0f) * 0.5f;
 
                const bool use_select = (DRW_state_is_select() || DRW_state_is_depth());
@@ -200,7 +199,7 @@ static void overlay_cache_init(void *vedata)
                }
 
                g_data->face_wires_shgrp = DRW_shgroup_create(face_wires_sh, psl->face_wireframe_pass);
-               DRW_shgroup_uniform_vec2(g_data->face_wires_shgrp, "wireStepParam", g_data->wire_step_param, 1);
+               DRW_shgroup_uniform_float(g_data->face_wires_shgrp, "wireStepParam", &g_data->wire_step_param, 1);
                if (rv3d->rflag & RV3D_CLIPPING) {
                        DRW_shgroup_world_clip_planes_from_rv3d(g_data->face_wires_shgrp, rv3d);
                }
@@ -210,14 +209,7 @@ static void overlay_cache_init(void *vedata)
                        DRW_shgroup_uniform_float_copy(g_data->face_wires_shgrp, "wireSize", wire_size);
                }
 
-               /* Control aspect of the falloff. */
-               const float sharpness = 4.0f;
-               /* Scale and bias: Adjust with wiredata encoding. (see mesh_batch_cache_create_edges_wireframe_data) */
-               const float decompress = (0xFF / (float)(0xFF - 0x20));
-               g_data->wire_step_param[0] = -sharpness * decompress;
-               g_data->wire_step_param[1] = decompress + sharpness * stl->g_data->overlay.wireframe_threshold;
-
-
+               g_data->wire_step_param = stl->g_data->overlay.wireframe_threshold - 254.0f / 255.0f;
        }
 }
 
@@ -227,7 +219,6 @@ static void overlay_cache_populate(void *vedata, Object *ob)
        OVERLAY_StorageList *stl = data->stl;
        OVERLAY_PrivateData *pd = stl->g_data;
        const DRWContextState *draw_ctx = DRW_context_state_get();
-       RegionView3D *rv3d = draw_ctx->rv3d;
        View3D *v3d = draw_ctx->v3d;
 
        if ((!pd->show_overlays) ||
@@ -266,14 +257,14 @@ static void overlay_cache_populate(void *vedata, Object *ob)
                {
                        const bool is_active = (ob == draw_ctx->obact);
                        const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
-                       const bool all_wires = (pd->overlay.wireframe_threshold == 1.0f) ||
-                                              (ob->dtx & OB_DRAW_ALL_EDGES);
+                       const bool all_wires = (ob->dtx & OB_DRAW_ALL_EDGES);
                        const bool is_wire = (ob->dt < OB_SOLID);
                        const int stencil_mask = (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF;
                        DRWShadingGroup *shgrp = NULL;
 
                        const float *rim_col = NULL;
                        const float *wire_col = NULL;
+
                        if (UNLIKELY(ob->base_flag & BASE_FROM_SET)) {
                                rim_col = G_draw.block.colorDupli;
                                wire_col = G_draw.block.colorDupli;
@@ -312,47 +303,29 @@ static void overlay_cache_populate(void *vedata, Object *ob)
                        }
                        BLI_assert(rim_col && wire_col);
 
-                       /* This fixes only the biggest case which is a plane in ortho view. */
-                       int flat_axis = 0;
-                       bool is_flat_object_viewed_from_side = (
-                               (rv3d->persp == RV3D_ORTHO) &&
-                               DRW_object_is_flat(ob, &flat_axis) &&
-                               DRW_object_axis_orthogonal_to_view(ob, flat_axis));
-
-                       if (is_flat_object_viewed_from_side && !is_sculpt_mode) {
-                               /* Avoid losing flat objects when in ortho views (see T56549) */
-                               struct GPUBatch *geom = DRW_cache_object_all_edges_get(ob);
-                               if (geom) {
-                                       shgrp = pd->flat_wires_shgrp;
-                                       shgrp = DRW_shgroup_create_sub(shgrp);
+                       struct GPUBatch *geom;
+                       geom = DRW_cache_object_face_wireframe_get(ob);
+
+                       if (geom || is_sculpt_mode) {
+                               shgrp = (is_sculpt_mode) ? pd->sculpt_wires_shgrp : pd->face_wires_shgrp;
+                               shgrp = DRW_shgroup_create_sub(shgrp);
+
+                               static float all_wires_param = 10.0f;
+                               DRW_shgroup_uniform_vec2(
+                                       shgrp, "wireStepParam", (all_wires) ?
+                                       &all_wires_param : &pd->wire_step_param, 1);
+
+                               if (!(DRW_state_is_select() || DRW_state_is_depth())) {
                                        DRW_shgroup_stencil_mask(shgrp, stencil_mask);
-                                       DRW_shgroup_call_object_add(shgrp, geom, ob);
-                                       DRW_shgroup_uniform_vec4(shgrp, "color", rim_col, 1);
+                                       DRW_shgroup_uniform_vec3(shgrp, "wireColor", wire_col, 1);
+                                       DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1);
                                }
-                       }
-                       else {
-                               struct GPUBatch *geom = DRW_cache_object_face_wireframe_get(ob);
-                               if (geom || is_sculpt_mode) {
-                                       shgrp = (is_sculpt_mode) ? pd->sculpt_wires_shgrp : pd->face_wires_shgrp;
-                                       shgrp = DRW_shgroup_create_sub(shgrp);
-
-                                       static float all_wires_params[2] = {0.0f, 10.0f}; /* Parameters for all wires */
-                                       DRW_shgroup_uniform_vec2(
-                                               shgrp, "wireStepParam", (all_wires) ?
-                                               all_wires_params : pd->wire_step_param, 1);
-
-                                       if (!(DRW_state_is_select() || DRW_state_is_depth())) {
-                                               DRW_shgroup_stencil_mask(shgrp, stencil_mask);
-                                               DRW_shgroup_uniform_vec3(shgrp, "wireColor", wire_col, 1);
-                                               DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1);
-                                       }
 
-                                       if (is_sculpt_mode) {
-                                               DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat);
-                                       }
-                                       else {
-                                               DRW_shgroup_call_add(shgrp, geom, ob->obmat);
-                                       }
+                               if (is_sculpt_mode) {
+                                       DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat);
+                               }
+                               else {
+                                       DRW_shgroup_call_add(shgrp, geom, ob->obmat);
                                }
                        }
                        if (is_wire && shgrp != NULL) {
@@ -392,12 +365,18 @@ static void overlay_draw_scene(void *vedata)
        OVERLAY_Data *data = vedata;
        OVERLAY_PassList *psl = data->psl;
        DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+       DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
 
        if (DRW_state_is_fbo()) {
                GPU_framebuffer_bind(dfbl->default_fb);
        }
        DRW_draw_pass(psl->face_orientation_pass);
+
+       MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl);
+
        DRW_draw_pass(psl->face_wireframe_pass);
+
+       MULTISAMPLE_SYNC_DISABLE(dfbl, dtxl);
 }
 
 static void overlay_engine_free(void)
index cefd4eab2e3f7e9caefec7d84b4b3580b312ea33..1a984b2fbc617781e9d29de64093db82c75592f1 100644 (file)
@@ -1,41 +1,23 @@
+
 uniform vec3 wireColor;
 uniform vec3 rimColor;
 
+flat in float edgeSharpness;
 in float facing;
-in vec3 barycentric;
-flat in vec3 edgeSharpness;
 
 out vec4 fragColor;
 
-float max_v3(vec3 v) { return max(v.x, max(v.y, v.z)); }
-
-/* In pixels */
-uniform float wireSize = 0.0; /* Expands the core of the wire (part that is 100% wire color) */
-const float wire_smooth = 1.2; /* Smoothing distance after the 100% core. */
-
-/* Alpha constants could be exposed in the future. */
-const float front_alpha = 0.35;
-const float rim_alpha = 0.75;
-
 void main()
 {
-       vec3 dx = dFdx(barycentric);
-       vec3 dy = dFdy(barycentric);
-       vec3 d = vec3(
-               length(vec2(dx.x, dy.x)),
-               length(vec2(dx.y, dy.y)),
-               length(vec2(dx.z, dy.z))
-       );
-       vec3 dist_to_edge = barycentric / d;
-
-       vec3 fac = abs(dist_to_edge);
-
-       fac = smoothstep(wireSize + wire_smooth, wireSize, fac);
+       if (edgeSharpness < 0.0) {
+               discard;
+       }
 
-       float facing_clamped = clamp((gl_FrontFacing) ? facing : -facing, 0.0, 1.0);
+       float facing_clamped = clamp(abs(facing), 0.0, 1.0);
 
-       vec3 final_front_col = mix(rimColor, wireColor, 0.05);
-       fragColor = mix(vec4(rimColor, rim_alpha), vec4(final_front_col, front_alpha), facing_clamped);
+       vec3 final_front_col = mix(rimColor, wireColor, 0.4);
+       vec3 final_rim_col = mix(rimColor, wireColor, 0.1);
 
-       fragColor.a *= max_v3(fac * edgeSharpness);
+       fragColor.rgb = mix(final_rim_col, final_front_col, facing_clamped);
+       fragColor.a = 1.0f;
 }
index 1ae204de60d2b0363fdb6b24881e0406626abe36..4e7560141f6e01a9dba72246577a9580b21bcd7a 100644 (file)
@@ -3,22 +3,11 @@ uniform mat4 ModelViewProjectionMatrix;
 uniform mat4 ModelMatrix;
 uniform mat3 NormalMatrix;
 
-uniform vec2 wireStepParam;
-
-vec3 get_edge_sharpness(vec3 wd)
-{
-       bvec3 do_edge = greaterThan(wd, vec3(0.0));
-       bvec3 force_edge = equal(wd, vec3(1.0));
-       wd = clamp(wireStepParam.x * wd + wireStepParam.y, 0.0, 1.0);
-       return clamp(wd * vec3(do_edge) + vec3(force_edge), 0.0, 1.0);
-}
+uniform float wireStepParam;
 
 float get_edge_sharpness(float wd)
 {
-       bool do_edge = (wd > 0.0);
-       bool force_edge = (wd == 1.0);
-       wd = (wireStepParam.x * wd + wireStepParam.y);
-       return clamp(wd * float(do_edge) + float(force_edge), 0.0, 1.0);
+       return (wd == 1.0) ? 1.0 : ((wd == 0.0) ? -1.0 : (wd + wireStepParam));
 }
 
 /* Geometry shader version */
@@ -51,35 +40,19 @@ void main()
 
 #else /* SELECT_EDGES */
 
-/* Consecutive pos of the nth vertex
- * Only valid for first vertex in the triangle.
- * Assuming GL_FRIST_VERTEX_CONVENTION. */
-in vec3 pos0;
-in vec3 pos1;
-in vec3 pos2;
-in float wd0; /* wiredata */
-in float wd1;
-in float wd2;
+in vec3 pos;
 in vec3 nor;
+in float wd;
 
 out float facing;
-out vec3 barycentric;
-flat out vec3 edgeSharpness;
+flat out float edgeSharpness;
 
 void main()
 {
-       int v_n = gl_VertexID % 3;
-
-       barycentric = vec3(equal(ivec3(2, 0, 1), ivec3(v_n)));
-
-       vec3 wb = vec3(wd0, wd1, wd2);
-       edgeSharpness = get_edge_sharpness(wb);
-
-       /* Don't generate any fragment if there is no edge to draw. */
-       vec3 pos = (!any(greaterThan(edgeSharpness, vec3(0.04))) && (v_n == 0)) ? pos1 : pos0;
-
        gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
 
+       edgeSharpness = get_edge_sharpness(wd);
+
        facing = normalize(NormalMatrix * nor).z;
 
 #ifdef USE_WORLD_CLIP_PLANES