diff options
author | Germano <germano.costa@ig.com.br> | 2017-12-14 17:21:38 +0300 |
---|---|---|
committer | Germano <germano.costa@ig.com.br> | 2017-12-14 17:21:38 +0300 |
commit | 5b5de35604569bfe5007a7ed427c702775c7871c (patch) | |
tree | 10bf8f2d8728239b84a97dd343aed96590d9feab | |
parent | bb9d068ccc2b86d4f3fc06fceca90f26e34cdf7e (diff) |
Support for Batchs split by material for objects of type Curve, Surface, and Text
**ToDo:**
- add vertbuff for UV (what can be adapted from `dl_surf_to_renderdata`)
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 37 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.h | 6 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl.h | 11 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_curve.c | 68 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_displist.c | 116 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_metaball.c | 10 |
6 files changed, 212 insertions, 36 deletions
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 8010a232f89..e02f6bd6306 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -520,6 +520,12 @@ Gwn_Batch **DRW_cache_object_surface_material_get( switch (ob->type) { case OB_MESH: return DRW_cache_mesh_surface_shaded_get(ob, gpumat_array, gpumat_array_len); + case OB_CURVE: + return DRW_cache_curve_surface_shaded_get(ob, gpumat_array, gpumat_array_len); + case OB_SURF: + return DRW_cache_surf_surface_shaded_get(ob, gpumat_array, gpumat_array_len); + case OB_FONT: + return DRW_cache_text_surface_shaded_get(ob, gpumat_array, gpumat_array_len); default: return NULL; } @@ -2334,6 +2340,16 @@ Gwn_Batch *DRW_cache_curve_surface_get(Object *ob) return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->curve_cache); } +/* Return list of batches */ +Gwn_Batch **DRW_cache_curve_surface_shaded_get( + Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len) +{ + BLI_assert(ob->type == OB_CURVE); + + struct Curve *cu = ob->data; + return DRW_curve_batch_cache_get_surface_shaded(cu, ob->curve_cache, gpumat_array, gpumat_array_len); +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -2372,6 +2388,17 @@ Gwn_Batch *DRW_cache_text_surface_get(Object *ob) return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->curve_cache); } +Gwn_Batch **DRW_cache_text_surface_shaded_get( + Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len) +{ + BLI_assert(ob->type == OB_FONT); + struct Curve *cu = ob->data; + if (cu->editfont && (cu->flag & CU_FAST)) { + return NULL; + } + return DRW_curve_batch_cache_get_surface_shaded(cu, ob->curve_cache, gpumat_array, gpumat_array_len); +} + Gwn_Batch *DRW_cache_text_cursor_overlay_get(Object *ob) { BLI_assert(ob->type == OB_FONT); @@ -2401,6 +2428,16 @@ Gwn_Batch *DRW_cache_surf_surface_get(Object *ob) return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->curve_cache); } +/* Return list of batches */ +Gwn_Batch **DRW_cache_surf_surface_shaded_get( + Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len) +{ + BLI_assert(ob->type == OB_SURF); + + struct Curve *cu = ob->data; + return DRW_curve_batch_cache_get_surface_shaded(cu, ob->curve_cache, gpumat_array, gpumat_array_len); +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 35ac8f4a35d..3564178dba9 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -130,6 +130,8 @@ void DRW_cache_mesh_sculpt_coords_ensure(struct Object *ob); /* Curve */ struct Gwn_Batch *DRW_cache_curve_surface_get(struct Object *ob); +struct Gwn_Batch **DRW_cache_curve_surface_shaded_get( + struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len); struct Gwn_Batch *DRW_cache_curve_surface_verts_get(struct Object *ob); struct Gwn_Batch *DRW_cache_curve_edge_wire_get(struct Object *ob); /* edit-mode */ @@ -140,12 +142,16 @@ struct Gwn_Batch *DRW_cache_curve_vert_overlay_get(struct Object *ob); /* Font */ struct Gwn_Batch *DRW_cache_text_edge_wire_get(struct Object *ob); struct Gwn_Batch *DRW_cache_text_surface_get(struct Object *ob); +struct Gwn_Batch **DRW_cache_text_surface_shaded_get( + struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len); /* edit-mode */ struct Gwn_Batch *DRW_cache_text_cursor_overlay_get(struct Object *ob); struct Gwn_Batch *DRW_cache_text_select_overlay_get(struct Object *ob); /* Surface */ struct Gwn_Batch *DRW_cache_surf_surface_get(struct Object *ob); +struct Gwn_Batch **DRW_cache_surf_surface_shaded_get( + struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len); /* Lattice */ struct Gwn_Batch *DRW_cache_lattice_verts_get(struct Object *ob); diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index c998282ae1f..5188ac0bd1a 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -29,14 +29,16 @@ struct CurveCache; struct GPUMaterial; struct Gwn_Batch; +struct Gwn_IndexBuf; +struct Gwn_VertBuf; struct ListBase; -struct MetaBall; struct ModifierData; struct ParticleSystem; struct Curve; struct Lattice; struct Mesh; +struct MetaBall; /* Expose via BKE callbacks */ void DRW_mball_batch_cache_dirty(struct MetaBall *mb, int mode); @@ -62,6 +64,9 @@ struct Gwn_Batch *DRW_curve_batch_cache_get_overlay_edges(struct Curve *cu); struct Gwn_Batch *DRW_curve_batch_cache_get_overlay_verts(struct Curve *cu); struct Gwn_Batch *DRW_curve_batch_cache_get_triangles_with_normals(struct Curve *cu, struct CurveCache *ob_curve_cache); +struct Gwn_Batch **DRW_curve_batch_cache_get_surface_shaded( + struct Curve *cu, struct CurveCache *ob_curve_cache, + struct GPUMaterial **gpumat_array, uint gpumat_array_len); /* Metaball */ struct Gwn_Batch *DRW_metaball_batch_cache_get_triangles_with_normals(struct Object *ob); @@ -71,7 +76,9 @@ struct Gwn_Batch *DRW_curve_batch_cache_get_overlay_cursor(struct Curve *cu); struct Gwn_Batch *DRW_curve_batch_cache_get_overlay_select(struct Curve *cu); /* DispList */ -struct Gwn_Batch *BLI_displist_batch_calc_surface(struct ListBase *lb); +struct Gwn_VertBuf *DRW_displist_vertbuf_calc_pos_with_normals(struct ListBase *lb); +struct Gwn_IndexBuf *DRW_displist_indexbuf_calc_triangles_in_order(struct ListBase *lb); +struct Gwn_IndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_material(struct ListBase *lb, uint gpumat_array_len); /* Lattice */ struct Gwn_Batch *DRW_lattice_batch_cache_get_all_edges(struct Lattice *lt, bool use_weight, const int actdef); diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.c index e6e52fe4579..8e38e22a210 100644 --- a/source/blender/draw/intern/draw_cache_impl_curve.c +++ b/source/blender/draw/intern/draw_cache_impl_curve.c @@ -310,7 +310,11 @@ typedef struct CurveBatchCache { } overlay; struct { + Gwn_VertBuf *verts; + Gwn_IndexBuf *triangles_in_order; + Gwn_Batch **shaded_triangles; Gwn_Batch *batch; + int mat_len; } surface; /* 3d text */ @@ -444,6 +448,14 @@ static void curve_batch_cache_clear(Curve *cu) GWN_BATCH_DISCARD_SAFE(cache->overlay.verts); GWN_BATCH_DISCARD_SAFE(cache->overlay.edges); + GWN_VERTBUF_DISCARD_SAFE(cache->surface.verts); + GWN_INDEXBUF_DISCARD_SAFE(cache->surface.triangles_in_order); + if (cache->surface.shaded_triangles) { + for (int i = 0; i < cache->surface.mat_len; ++i) { + GWN_BATCH_DISCARD_SAFE(cache->surface.shaded_triangles[i]); + } + } + MEM_SAFE_FREE(cache->surface.shaded_triangles); GWN_BATCH_DISCARD_SAFE(cache->surface.batch); /* don't own vbo & elems */ @@ -796,8 +808,20 @@ static Gwn_Batch *curve_batch_cache_get_pos_and_normals(CurveRenderData *rdata, { BLI_assert(rdata->types & CU_DATATYPE_SURFACE); if (cache->surface.batch == NULL) { - cache->surface.batch = BLI_displist_batch_calc_surface(&rdata->ob_curve_cache->disp); + ListBase *lb = &rdata->ob_curve_cache->disp; + + if (cache->surface.verts == NULL) { + cache->surface.verts = DRW_displist_vertbuf_calc_pos_with_normals(lb); + } + if (cache->surface.verts) { + if (cache->surface.triangles_in_order == NULL) { + cache->surface.triangles_in_order = DRW_displist_indexbuf_calc_triangles_in_order(lb); + } + cache->surface.batch = GWN_batch_create_ex( + GWN_PRIM_TRIS, cache->surface.verts, cache->surface.triangles_in_order, 0); + } } + return cache->surface.batch; } @@ -997,6 +1021,48 @@ Gwn_Batch *DRW_curve_batch_cache_get_triangles_with_normals( return cache->surface.batch; } +Gwn_Batch **DRW_curve_batch_cache_get_surface_shaded( + struct Curve *cu, struct CurveCache *ob_curve_cache, + struct GPUMaterial **UNUSED(gpumat_array), uint gpumat_array_len) +{ + CurveBatchCache *cache = curve_batch_cache_get(cu); + + if (cache->surface.mat_len != gpumat_array_len) { + /* TODO: deduplicate code */ + GWN_INDEXBUF_DISCARD_SAFE(cache->surface.triangles_in_order); + if (cache->surface.shaded_triangles) { + for (int i = 0; i < cache->surface.mat_len; ++i) { + GWN_BATCH_DISCARD_SAFE(cache->surface.shaded_triangles[i]); + } + } + MEM_SAFE_FREE(cache->surface.shaded_triangles); + } + + if (cache->surface.shaded_triangles == NULL) { + CurveRenderData *rdata = curve_render_data_create(cu, ob_curve_cache, CU_DATATYPE_SURFACE); + ListBase *lb = &rdata->ob_curve_cache->disp; + + cache->surface.mat_len = gpumat_array_len; + Gwn_IndexBuf **el = DRW_displist_indexbuf_calc_triangles_in_order_split_by_material(lb, gpumat_array_len); + cache->surface.shaded_triangles = MEM_mallocN(sizeof(*cache->surface.shaded_triangles) * gpumat_array_len, __func__); + + if (cache->surface.verts == NULL) { + cache->surface.verts = DRW_displist_vertbuf_calc_pos_with_normals(lb); + } + + for (int i = 0; i < gpumat_array_len; ++i) { + cache->surface.shaded_triangles[i] = GWN_batch_create( + GWN_PRIM_TRIS, cache->surface.verts, el[i]); + /* TODO: Add vertbuff for UV */ + } + + MEM_freeN(el); /* Save `el` in cache? */ + curve_render_data_free(rdata); + } + + return cache->surface.shaded_triangles; +} + /* -------------------------------------------------------------------- */ diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c index 96386f82faf..87ff52c951c 100644 --- a/source/blender/draw/intern/draw_cache_impl_displist.c +++ b/source/blender/draw/intern/draw_cache_impl_displist.c @@ -31,6 +31,7 @@ #include "MEM_guardedalloc.h" +#include "BLI_alloca.h" #include "BLI_utildefines.h" #include "BLI_math_vector.h" @@ -86,7 +87,38 @@ static int curve_render_surface_tri_len_get(const ListBase *lb) return tri_len; } -Gwn_Batch *BLI_displist_batch_calc_surface(ListBase *lb) +static void displist_indexbufbuilder_set(Gwn_IndexBufBuilder *elb, const DispList *dl, const int ofs) +{ + if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) { + const int *idx = dl->index; + if (dl->type == DL_INDEX3) { + const int i_end = dl->parts; + for (int i = 0; i < i_end; i++, idx += 3) { + GWN_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs); + } + } + else if (dl->type == DL_SURF) { + const int i_end = dl->totindex; + for (int i = 0; i < i_end; i++, idx += 4) { + GWN_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs); + GWN_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs); + } + } + else { + BLI_assert(dl->type == DL_INDEX4); + const int i_end = dl->parts; + for (int i = 0; i < i_end; i++, idx += 4) { + GWN_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs); + + if (idx[2] != idx[3]) { + GWN_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs); + } + } + } + } +} + +Gwn_VertBuf *DRW_displist_vertbuf_calc_pos_with_normals(ListBase *lb) { const int tri_len = curve_render_surface_tri_len_get(lb); if (tri_len == 0) { @@ -131,44 +163,64 @@ Gwn_Batch *BLI_displist_batch_calc_surface(ListBase *lb) } } + return vbo; +} + +Gwn_IndexBuf *DRW_displist_indexbuf_calc_triangles_in_order(ListBase *lb) +{ + const int tri_len = curve_render_surface_tri_len_get(lb); + if (tri_len == 0) { + return NULL; + } + + const int vert_len = curve_render_surface_vert_len_get(lb); + { Gwn_IndexBufBuilder elb; GWN_indexbuf_init(&elb, GWN_PRIM_TRIS, tri_len, vert_len); int ofs = 0; for (const DispList *dl = lb->first; dl; dl = dl->next) { - if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) { - const int *idx = dl->index; - if (dl->type == DL_INDEX3) { - const int i_end = dl->parts; - for (int i = 0; i < i_end; i++, idx += 3) { - GWN_indexbuf_add_tri_verts(&elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs); - } - } - else if (dl->type == DL_SURF) { - const int i_end = dl->totindex; - for (int i = 0; i < i_end; i++, idx += 4) { - GWN_indexbuf_add_tri_verts(&elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs); - GWN_indexbuf_add_tri_verts(&elb, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs); - } - } - else { - BLI_assert(dl->type == DL_INDEX4); - const int i_end = dl->parts; - for (int i = 0; i < i_end; i++, idx += 4) { - GWN_indexbuf_add_tri_verts(&elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs); - - if (idx[2] != idx[3]) { - GWN_indexbuf_add_tri_verts(&elb, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs); - } - } - } - ofs += dl_vert_len(dl); - } + displist_indexbufbuilder_set(&elb, dl, ofs); + ofs += dl_vert_len(dl); + } + + return GWN_indexbuf_build(&elb); + } +} + +Gwn_IndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_material(ListBase *lb, uint gpumat_array_len) +{ + const int tri_len = curve_render_surface_tri_len_get(lb); + if (tri_len == 0) { + return NULL; + } + + const int vert_len = curve_render_surface_vert_len_get(lb); + + Gwn_IndexBuf **shaded_triangles_in_order = MEM_callocN(sizeof(*shaded_triangles_in_order) * gpumat_array_len, __func__); + + { + int i; + Gwn_IndexBufBuilder *elb = BLI_array_alloca(elb, gpumat_array_len); + + /* Init each index buffer builder */ + for (i = 0; i < gpumat_array_len; i++) { + GWN_indexbuf_init(&elb[i], GWN_PRIM_TRIS, tri_len, vert_len); } - return GWN_batch_create_ex( - GWN_PRIM_TRIS, vbo, GWN_indexbuf_build(&elb), - GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX); + /* calc each index buffer builder */ + int ofs = 0; + for (const DispList *dl = lb->first; dl; dl = dl->next) { + displist_indexbufbuilder_set(&elb[dl->col], dl, ofs); + ofs += dl_vert_len(dl); + } + + /* build each indexbuf */ + for (i = 0; i < gpumat_array_len; i++) { + shaded_triangles_in_order[i] = GWN_indexbuf_build(&elb[i]); + } } + + return shaded_triangles_in_order; } diff --git a/source/blender/draw/intern/draw_cache_impl_metaball.c b/source/blender/draw/intern/draw_cache_impl_metaball.c index e2dba8e626e..762564cc2a5 100644 --- a/source/blender/draw/intern/draw_cache_impl_metaball.c +++ b/source/blender/draw/intern/draw_cache_impl_metaball.c @@ -132,7 +132,15 @@ Gwn_Batch *DRW_metaball_batch_cache_get_triangles_with_normals(Object *ob) MetaBallBatchCache *cache = metaball_batch_cache_get(mb); if (cache->batch == NULL) { - cache->batch = BLI_displist_batch_calc_surface(&ob->curve_cache->disp); + ListBase *lb = &ob->curve_cache->disp; + Gwn_VertBuf *verts = DRW_displist_vertbuf_calc_pos_with_normals(lb); + if (verts) { + cache->batch = GWN_batch_create_ex( + GWN_PRIM_TRIS, + verts, + DRW_displist_indexbuf_calc_triangles_in_order(lb), + GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX); + } } return cache->batch; |