Fix T61801: Wireframes on curves not working
authorClément Foucault <foucault.clem@gmail.com>
Mon, 25 Feb 2019 18:37:08 +0000 (19:37 +0100)
committerClément Foucault <foucault.clem@gmail.com>
Mon, 25 Feb 2019 18:37:16 +0000 (19:37 +0100)
source/blender/draw/intern/draw_cache_impl.h
source/blender/draw/intern/draw_cache_impl_curve.c
source/blender/draw/intern/draw_cache_impl_displist.c
source/blender/draw/intern/draw_cache_impl_metaball.c

index f56caa1..2ec4ab5 100644 (file)
@@ -81,12 +81,12 @@ struct GPUBatch **DRW_metaball_batch_cache_get_surface_shaded(
 struct GPUBatch *DRW_metaball_batch_cache_get_wireframes_face(struct Object *ob);
 
 /* DispList */
-void DRW_displist_vertbuf_create_pos_and_nor(struct ListBase *lb, struct GPUVertBuf *vbo);
-void DRW_displist_vertbuf_create_pos_and_nor_and_uv_tess(
+void DRW_displist_vertbuf_create_pos_and_nor_and_wiredata(struct ListBase *lb, struct GPUVertBuf *vbo);
+void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv(
         struct ListBase *lb, struct GPUVertBuf *vbo_pos_nor, struct GPUVertBuf *vbo_uv);
-void DRW_displist_vertbuf_create_wireframe_data_tess(struct ListBase *lb, struct GPUVertBuf *vbo);
-void DRW_displist_indexbuf_create_triangles_in_order(struct ListBase *lb, struct GPUIndexBuf *vbo);
-void DRW_displist_indexbuf_create_triangles_tess_split_by_material(
+void DRW_displist_indexbuf_create_lines_in_order(struct ListBase *lb, struct GPUIndexBuf *ibo);
+void DRW_displist_indexbuf_create_triangles_in_order(struct ListBase *lb, struct GPUIndexBuf *ibo);
+void DRW_displist_indexbuf_create_triangles_loop_split_by_material(
         struct ListBase *lb, struct GPUIndexBuf **ibo_mat, uint mat_len);
 
 /* Lattice */
index aef24dd..d40e33a 100644 (file)
@@ -347,14 +347,10 @@ typedef struct CurveBatchCache {
        struct {
                GPUVertBuf *pos_nor;
                GPUVertBuf *curves_pos;
-       } ordered;
-
-       struct {
-               GPUVertBuf *pos_nor;
-               GPUVertBuf *uv;
 
-               GPUVertBuf *wireframe_data;
-       } tess;
+               GPUVertBuf *loop_pos_nor;
+               GPUVertBuf *loop_uv;
+       } ordered;
 
        struct {
                /* Curve points. Aligned with ordered.pos_nor */
@@ -367,6 +363,7 @@ typedef struct CurveBatchCache {
 
        struct {
                GPUIndexBuf *surfaces_tris;
+               GPUIndexBuf *surfaces_lines;
                GPUIndexBuf *curves_lines;
                /* Edit mode */
                GPUIndexBuf *edit_verts_points; /* Only control points. Not handles. */
@@ -375,14 +372,13 @@ typedef struct CurveBatchCache {
 
        struct {
                GPUBatch *surfaces;
+               GPUBatch *surfaces_edges;
                GPUBatch *curves;
                /* control handles and vertices */
                GPUBatch *edit_edges;
                GPUBatch *edit_verts;
                GPUBatch *edit_handles_verts;
                GPUBatch *edit_normals;
-               /* Triangles for object mode wireframe. */
-               GPUBatch *wire_triangles;
        } batch;
 
        GPUIndexBuf **surf_per_mat_tris;
@@ -506,10 +502,6 @@ static void curve_batch_cache_clear(Curve *cu)
                GPUVertBuf **vbo = (GPUVertBuf **)&cache->ordered;
                GPU_VERTBUF_DISCARD_SAFE(vbo[i]);
        }
-       for (int i = 0; i < sizeof(cache->tess) / sizeof(void *); ++i) {
-               GPUVertBuf **vbo = (GPUVertBuf **)&cache->tess;
-               GPU_VERTBUF_DISCARD_SAFE(vbo[i]);
-       }
        for (int i = 0; i < sizeof(cache->edit) / sizeof(void *); ++i) {
                GPUVertBuf **vbo = (GPUVertBuf **)&cache->edit;
                GPU_VERTBUF_DISCARD_SAFE(vbo[i]);
@@ -884,7 +876,7 @@ GPUBatch **DRW_curve_batch_cache_get_surface_shaded(
 GPUBatch *DRW_curve_batch_cache_get_wireframes_face(Curve *cu)
 {
        CurveBatchCache *cache = curve_batch_cache_get(cu);
-       return DRW_batch_request(&cache->batch.wire_triangles);
+       return DRW_batch_request(&cache->batch.surfaces_edges);
 }
 
 /** \} */
@@ -920,14 +912,14 @@ void DRW_curve_batch_cache_create_requested(Object *ob)
                DRW_ibo_request(cache->batch.surfaces, &cache->ibo.surfaces_tris);
                DRW_vbo_request(cache->batch.surfaces, &cache->ordered.pos_nor);
        }
+       if (DRW_batch_requested(cache->batch.surfaces_edges, GPU_PRIM_LINES)) {
+               DRW_ibo_request(cache->batch.surfaces_edges, &cache->ibo.surfaces_lines);
+               DRW_vbo_request(cache->batch.surfaces_edges, &cache->ordered.pos_nor);
+       }
        if (DRW_batch_requested(cache->batch.curves, GPU_PRIM_LINE_STRIP)) {
                DRW_ibo_request(cache->batch.curves, &cache->ibo.curves_lines);
                DRW_vbo_request(cache->batch.curves, &cache->ordered.curves_pos);
        }
-       if (DRW_batch_requested(cache->batch.wire_triangles, GPU_PRIM_TRIS)) {
-               DRW_vbo_request(cache->batch.wire_triangles, &cache->tess.pos_nor);
-               DRW_vbo_request(cache->batch.wire_triangles, &cache->tess.wireframe_data);
-       }
 
        /* Edit mode */
        if (DRW_batch_requested(cache->batch.edit_edges, GPU_PRIM_LINES)) {
@@ -953,9 +945,9 @@ void DRW_curve_batch_cache_create_requested(Object *ob)
                                DRW_ibo_request(cache->surf_per_mat[i], &cache->surf_per_mat_tris[i]);
                        }
                        if (cache->cd_used & CD_MLOOPUV) {
-                               DRW_vbo_request(cache->surf_per_mat[i], &cache->tess.uv);
+                               DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_uv);
                        }
-                       DRW_vbo_request(cache->surf_per_mat[i], &cache->tess.pos_nor);
+                       DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_pos_nor);
                }
        }
 
@@ -963,10 +955,10 @@ void DRW_curve_batch_cache_create_requested(Object *ob)
        int mr_flag = 0;
        DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.pos_nor, CU_DATATYPE_SURFACE);
        DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.curves_pos, CU_DATATYPE_WIRE);
-       DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->tess.pos_nor, CU_DATATYPE_SURFACE);
-       DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->tess.uv, CU_DATATYPE_SURFACE);
-       DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->tess.wireframe_data, CU_DATATYPE_SURFACE);
+       DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_pos_nor, CU_DATATYPE_SURFACE);
+       DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_uv, CU_DATATYPE_SURFACE);
        DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.surfaces_tris, CU_DATATYPE_SURFACE);
+       DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.surfaces_lines, CU_DATATYPE_SURFACE);
        DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.curves_lines, CU_DATATYPE_WIRE);
 
        DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->edit.pos, CU_DATATYPE_OVERLAY);
@@ -987,23 +979,20 @@ void DRW_curve_batch_cache_create_requested(Object *ob)
 
        /* Generate VBOs */
        if (DRW_vbo_requested(cache->ordered.pos_nor)) {
-               DRW_displist_vertbuf_create_pos_and_nor(lb, cache->ordered.pos_nor);
+               DRW_displist_vertbuf_create_pos_and_nor_and_wiredata(lb, cache->ordered.pos_nor);
        }
        if (DRW_vbo_requested(cache->ordered.curves_pos)) {
                curve_create_curves_pos(rdata, cache->ordered.curves_pos);
        }
 
-       if (DRW_vbo_requested(cache->tess.pos_nor) ||
-           DRW_vbo_requested(cache->tess.uv))
+       if (DRW_vbo_requested(cache->ordered.loop_pos_nor) ||
+           DRW_vbo_requested(cache->ordered.loop_uv))
        {
-               DRW_displist_vertbuf_create_pos_and_nor_and_uv_tess(lb, cache->tess.pos_nor, cache->tess.uv);
-       }
-       if (DRW_vbo_requested(cache->tess.wireframe_data)) {
-               DRW_displist_vertbuf_create_wireframe_data_tess(lb, cache->tess.wireframe_data);
+               DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv(lb, cache->ordered.loop_pos_nor, cache->ordered.loop_uv);
        }
 
        if (DRW_ibo_requested(cache->surf_per_mat_tris[0])) {
-               DRW_displist_indexbuf_create_triangles_tess_split_by_material(lb, cache->surf_per_mat_tris, cache->mat_len);
+               DRW_displist_indexbuf_create_triangles_loop_split_by_material(lb, cache->surf_per_mat_tris, cache->mat_len);
        }
 
        if (DRW_ibo_requested(cache->ibo.curves_lines)) {
@@ -1012,6 +1001,9 @@ void DRW_curve_batch_cache_create_requested(Object *ob)
        if (DRW_ibo_requested(cache->ibo.surfaces_tris)) {
                DRW_displist_indexbuf_create_triangles_in_order(lb, cache->ibo.surfaces_tris);
        }
+       if (DRW_ibo_requested(cache->ibo.surfaces_lines)) {
+               DRW_displist_indexbuf_create_lines_in_order(lb, cache->ibo.surfaces_lines);
+       }
 
        if (DRW_vbo_requested(cache->edit.pos) ||
            DRW_vbo_requested(cache->edit.data) ||
index a63c4bf..b93c635 100644 (file)
@@ -165,14 +165,15 @@ static int displist_indexbufbuilder_tess_set(
        return v_idx;
 }
 
-void DRW_displist_vertbuf_create_pos_and_nor(ListBase *lb, GPUVertBuf *vbo)
+void DRW_displist_vertbuf_create_pos_and_nor_and_wiredata(ListBase *lb, GPUVertBuf *vbo)
 {
        static GPUVertFormat format = { 0 };
-       static struct { uint pos, nor; } attr_id;
+       static struct { uint pos, nor, wd; } attr_id;
        if (format.attr_len == 0) {
                /* initialize vertex format */
                attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
                attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+               attr_id.wd  = GPU_vertformat_attr_add(&format, "wd",  GPU_COMP_U8,  1, GPU_FETCH_INT_TO_FLOAT_UNIT);
        }
 
        GPU_vertbuf_init_with_format(vbo, &format);
@@ -188,6 +189,8 @@ void DRW_displist_vertbuf_create_pos_and_nor(ListBase *lb, GPUVertBuf *vbo)
                        const float *fp_no = dl->nors;
                        const int vbo_end = vbo_len_used + dl_vert_len(dl);
                        while (vbo_len_used < vbo_end) {
+                               uchar sharpness = 0xFF;
+                               GPU_vertbuf_attr_set(vbo, attr_id.wd, vbo_len_used, &sharpness);
                                GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, fp_co);
                                if (fp_no) {
                                        static short short_no[4];
@@ -224,7 +227,7 @@ void DRW_displist_indexbuf_create_triangles_in_order(ListBase *lb, GPUIndexBuf *
        GPU_indexbuf_build_in_place(&elb, ibo);
 }
 
-void DRW_displist_indexbuf_create_triangles_tess_split_by_material(
+void DRW_displist_indexbuf_create_triangles_loop_split_by_material(
         ListBase *lb,
         GPUIndexBuf **ibo_mats, uint mat_len)
 {
@@ -252,65 +255,39 @@ void DRW_displist_indexbuf_create_triangles_tess_split_by_material(
        }
 }
 
-typedef struct DRWDisplistWireThunk {
-       uint wd_id, ofs;
-       const DispList *dl;
-       GPUVertBuf *vbo;
-} DRWDisplistWireThunk;
-
 static void set_overlay_wires_tri_indices(void *thunk, uint v1, uint v2, uint v3)
 {
-       DRWDisplistWireThunk *dwt = (DRWDisplistWireThunk *)thunk;
-       uint indices[3] = {v1, v2, v3};
-
-       for (int i = 0; i < 3; ++i) {
-               /* TODO: Compute sharpness. For now, only tag real egdes. */
-               uchar sharpness = 0xFF;
-               GPU_vertbuf_attr_set(dwt->vbo, dwt->wd_id, indices[i], &sharpness);
-       }
+       GPUIndexBufBuilder *eld = (GPUIndexBufBuilder *)thunk;
+       GPU_indexbuf_add_line_verts(eld, v1, v2);
+       GPU_indexbuf_add_line_verts(eld, v2, v3);
+       GPU_indexbuf_add_line_verts(eld, v3, v1);
 }
 
 static void set_overlay_wires_quad_tri_indices(void *thunk, uint v1, uint v2, uint v3)
 {
-       DRWDisplistWireThunk *dwt = (DRWDisplistWireThunk *)thunk;
-       uint indices[3] = {v1, v2, v3};
-
-       for (int i = 0; i < 3; ++i) {
-               /* TODO: Compute sharpness. For now, only tag real egdes. */
-               uchar sharpness = (i == 0) ? 0x00 : 0xFF;
-               GPU_vertbuf_attr_set(dwt->vbo, dwt->wd_id, indices[i], &sharpness);
-       }
+       GPUIndexBufBuilder *eld = (GPUIndexBufBuilder *)thunk;
+       GPU_indexbuf_add_line_verts(eld, v1, v3);
+       GPU_indexbuf_add_line_verts(eld, v3, v2);
 }
 
-/* TODO reuse the position and normals from other tesselation vertbuf. */
-void DRW_displist_vertbuf_create_wireframe_data_tess(ListBase *lb, GPUVertBuf *vbo)
+void DRW_displist_indexbuf_create_lines_in_order(ListBase *lb, GPUIndexBuf *ibo)
 {
-       static DRWDisplistWireThunk thunk;
-       static GPUVertFormat format = {0};
-       if (format.attr_len == 0) {
-               thunk.wd_id  = GPU_vertformat_attr_add(&format, "wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
-               GPU_vertformat_triple_load(&format);
-       }
-
-       GPU_vertbuf_init_with_format(vbo, &format);
-       thunk.vbo = vbo;
+       const int tri_len = curve_render_surface_tri_len_get(lb);
+       const int vert_len = curve_render_surface_vert_len_get(lb);
 
-       int vert_len = curve_render_surface_tri_len_get(lb) * 3;
-       GPU_vertbuf_data_alloc(thunk.vbo, vert_len);
+       GPUIndexBufBuilder elb;
+       GPU_indexbuf_init(&elb, GPU_PRIM_LINES, tri_len * 3, vert_len);
 
-       thunk.ofs = 0;
+       int ofs = 0;
        for (const DispList *dl = lb->first; dl; dl = dl->next) {
-               thunk.dl = dl;
-               /* TODO consider non-manifold edges correctly. */
-               thunk.ofs = displist_indexbufbuilder_tess_set(
-                       set_overlay_wires_tri_indices,
-                       set_overlay_wires_quad_tri_indices,
-                       &thunk, dl, thunk.ofs);
+               displist_indexbufbuilder_set(
+                       (SetTriIndicesFn *)set_overlay_wires_tri_indices,
+                       (SetTriIndicesFn *)set_overlay_wires_quad_tri_indices,
+                       &elb, dl, ofs);
+               ofs += dl_vert_len(dl);
        }
 
-       if (thunk.ofs < vert_len) {
-               GPU_vertbuf_data_resize(thunk.vbo, thunk.ofs);
-       }
+       GPU_indexbuf_build_in_place(&elb, ibo);
 }
 
 static void surf_uv_quad(const DispList *dl, const uint quad[4], float r_uv[4][2])
@@ -364,7 +341,7 @@ static void displist_vertbuf_attr_set_tri_pos_nor_uv(
        }
 }
 
-void DRW_displist_vertbuf_create_pos_and_nor_and_uv_tess(
+void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv(
         ListBase *lb,
         GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_uv)
 {
index c3bc3bd..0d2c06e 100644 (file)
@@ -139,7 +139,7 @@ static GPUVertBuf *mball_batch_cache_get_pos_and_normals(Object *ob, MetaBallBat
        if (cache->pos_nor_in_order == NULL) {
                ListBase *lb = &ob->runtime.curve_cache->disp;
                cache->pos_nor_in_order = MEM_callocN(sizeof(GPUVertBuf), __func__);
-               DRW_displist_vertbuf_create_pos_and_nor(lb, cache->pos_nor_in_order);
+               DRW_displist_vertbuf_create_pos_and_nor_and_wiredata(lb, cache->pos_nor_in_order);
        }
        return cache->pos_nor_in_order;
 }
@@ -203,13 +203,15 @@ GPUBatch *DRW_metaball_batch_cache_get_wireframes_face(Object *ob)
                ListBase *lb = &ob->runtime.curve_cache->disp;
 
                GPUVertBuf *vbo_pos_nor = MEM_callocN(sizeof(GPUVertBuf), __func__);
-               GPUVertBuf *vbo_wireframe_data = MEM_callocN(sizeof(GPUVertBuf), __func__);
+               DRW_displist_vertbuf_create_pos_and_nor_and_wiredata(lb, vbo_pos_nor);
 
-               DRW_displist_vertbuf_create_pos_and_nor_and_uv_tess(lb, vbo_pos_nor, NULL);
-               DRW_displist_vertbuf_create_wireframe_data_tess(lb, vbo_wireframe_data);
+               GPUIndexBuf *ibo = MEM_callocN(sizeof(GPUIndexBuf), __func__);
+               DRW_displist_indexbuf_create_lines_in_order(lb, ibo);
 
-               cache->face_wire.batch = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo_pos_nor, NULL, GPU_BATCH_OWNS_VBO);
-               GPU_batch_vertbuf_add_ex(cache->face_wire.batch, vbo_wireframe_data, true);
+               cache->face_wire.batch = GPU_batch_create_ex(GPU_PRIM_LINES,
+                                                            vbo_pos_nor,
+                                                            ibo,
+                                                            GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX);
        }
 
        return cache->face_wire.batch;