diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-11-23 18:44:16 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-11-23 18:44:53 +0300 |
commit | 1ec21ed41a48ba41410edee229be06be82ccec2d (patch) | |
tree | 8761a0f5dbeb8cd76995fe0c4224955fb9d16ba8 /source/blender | |
parent | 1cc7bcd8d8495e68160501d099defbb3986ba314 (diff) |
DRW: Support Wireframe for cruve/surface/text objects
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 57 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.h | 8 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl.h | 4 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_curve.c | 69 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_displist.c | 73 |
5 files changed, 198 insertions, 13 deletions
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index f2f99953418..a2430d12f41 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -698,9 +698,18 @@ void DRW_cache_object_face_wireframe_get( { switch (ob->type) { case OB_MESH: - DRW_mesh_batch_cache_get_wireframes_face_texbuf(ob->data, r_vert_tx, r_faceid_tx, r_tri_count); - - /* TODO, should match 'DRW_cache_object_surface_get' */ + DRW_cache_mesh_face_wireframe_get(ob, r_vert_tx, r_faceid_tx, r_tri_count); + break; + case OB_CURVE: + DRW_cache_curve_face_wireframe_get(ob, r_vert_tx, r_faceid_tx, r_tri_count); + break; + case OB_SURF: + DRW_cache_surf_face_wireframe_get(ob, r_vert_tx, r_faceid_tx, r_tri_count); + break; + case OB_FONT: + DRW_cache_text_face_wireframe_get(ob, r_vert_tx, r_faceid_tx, r_tri_count); + break; + /* TODO, metaballs' */ } } @@ -3046,6 +3055,15 @@ GPUBatch *DRW_cache_mesh_surface_get(Object *ob) return DRW_mesh_batch_cache_get_triangles_with_normals(me); } +void DRW_cache_mesh_face_wireframe_get( + Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count) +{ + BLI_assert(ob->type == OB_MESH); + + Mesh *me = ob->data; + DRW_mesh_batch_cache_get_wireframes_face_texbuf(me, r_vert_tx, r_faceid_tx, r_tri_count); +} + GPUBatch *DRW_cache_mesh_loose_edges_get(Object *ob) { BLI_assert(ob->type == OB_MESH); @@ -3237,6 +3255,15 @@ GPUBatch *DRW_cache_curve_surface_get(Object *ob) return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->runtime.curve_cache); } +void DRW_cache_curve_face_wireframe_get( + Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count) +{ + BLI_assert(ob->type == OB_CURVE); + + struct Curve *cu = ob->data; + DRW_curve_batch_cache_get_wireframes_face_texbuf(cu, ob->runtime.curve_cache, r_vert_tx, r_faceid_tx, r_tri_count); +} + /* Return list of batches */ GPUBatch **DRW_cache_curve_surface_shaded_get( Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len) @@ -3293,6 +3320,21 @@ GPUBatch *DRW_cache_text_surface_get(Object *ob) return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->runtime.curve_cache); } +void DRW_cache_text_face_wireframe_get( + Object *ob, + struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count) +{ + BLI_assert(ob->type == OB_FONT); + struct Curve *cu = ob->data; + if (cu->editfont && (cu->flag & CU_FAST)) { + *r_vert_tx = NULL; + *r_faceid_tx = NULL; + *r_tri_count = 0; + return; + } + DRW_curve_batch_cache_get_wireframes_face_texbuf(cu, ob->runtime.curve_cache, r_vert_tx, r_faceid_tx, r_tri_count); +} + GPUBatch **DRW_cache_text_surface_shaded_get( Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len) { @@ -3333,6 +3375,15 @@ GPUBatch *DRW_cache_surf_surface_get(Object *ob) return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->runtime.curve_cache); } +void DRW_cache_surf_face_wireframe_get( + Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count) +{ + BLI_assert(ob->type == OB_SURF); + + struct Curve *cu = ob->data; + DRW_curve_batch_cache_get_wireframes_face_texbuf(cu, ob->runtime.curve_cache, r_vert_tx, r_faceid_tx, r_tri_count); +} + /* Return list of batches */ GPUBatch **DRW_cache_surf_surface_shaded_get( Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len) diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 0656783ea29..39bbcf2c93a 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -152,6 +152,8 @@ struct GPUBatch **DRW_cache_mesh_surface_shaded_get( char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count); struct GPUBatch **DRW_cache_mesh_surface_texpaint_get(struct Object *ob); struct GPUBatch *DRW_cache_mesh_surface_texpaint_single_get(struct Object *ob); +void DRW_cache_mesh_face_wireframe_get( + Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count); void DRW_cache_mesh_sculpt_coords_ensure(struct Object *ob); @@ -161,6 +163,8 @@ struct GPUBatch **DRW_cache_curve_surface_shaded_get( struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len); struct GPUBatch *DRW_cache_curve_surface_verts_get(struct Object *ob); struct GPUBatch *DRW_cache_curve_edge_wire_get(struct Object *ob); +void DRW_cache_curve_face_wireframe_get( + Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count); /* edit-mode */ struct GPUBatch *DRW_cache_curve_edge_normal_get(struct Object *ob, float normal_size); struct GPUBatch *DRW_cache_curve_edge_overlay_get(struct Object *ob); @@ -171,6 +175,8 @@ struct GPUBatch *DRW_cache_text_edge_wire_get(struct Object *ob); struct GPUBatch *DRW_cache_text_surface_get(struct Object *ob); struct GPUBatch **DRW_cache_text_surface_shaded_get( struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len); +void DRW_cache_text_face_wireframe_get( + Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count); /* edit-mode */ struct GPUBatch *DRW_cache_text_cursor_overlay_get(struct Object *ob); struct GPUBatch *DRW_cache_text_select_overlay_get(struct Object *ob); @@ -179,6 +185,8 @@ struct GPUBatch *DRW_cache_text_select_overlay_get(struct Object *ob); struct GPUBatch *DRW_cache_surf_surface_get(struct Object *ob); struct GPUBatch **DRW_cache_surf_surface_shaded_get( struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len); +void DRW_cache_surf_face_wireframe_get( + Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count); /* Lattice */ struct GPUBatch *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 3805cccd9c0..97e7cd240ff 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -75,6 +75,9 @@ struct GPUBatch *DRW_curve_batch_cache_get_triangles_with_normals( struct GPUBatch **DRW_curve_batch_cache_get_surface_shaded( struct Curve *cu, struct CurveCache *ob_curve_cache, struct GPUMaterial **gpumat_array, uint gpumat_array_len); +void DRW_curve_batch_cache_get_wireframes_face_texbuf( + struct Curve *cu, struct CurveCache *ob_curve_cache, + struct GPUTexture **verts_data, struct GPUTexture **face_indices, int *tri_count); /* Metaball */ struct GPUBatch *DRW_metaball_batch_cache_get_triangles_with_normals(struct Object *ob); @@ -91,6 +94,7 @@ struct GPUIndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_mate struct ListBase *lb, uint gpumat_array_len); struct GPUBatch **DRW_displist_batch_calc_tri_pos_normals_and_uv_split_by_material( struct ListBase *lb, uint gpumat_array_len); +struct GPUVertBuf *DRW_displist_create_edges_overlay_texture_buf(ListBase *lb); /* Lattice */ struct GPUBatch *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 4702319364c..f214f722c0b 100644 --- a/source/blender/draw/intern/draw_cache_impl_curve.c +++ b/source/blender/draw/intern/draw_cache_impl_curve.c @@ -39,9 +39,12 @@ #include "BKE_font.h" #include "GPU_batch.h" +#include "GPU_texture.h" #include "UI_resources.h" +#include "DRW_render.h" + #include "draw_cache_impl.h" /* own include */ #define SELECT 1 @@ -320,6 +323,14 @@ typedef struct CurveBatchCache { int mat_len; } surface; + /* Wireframes */ + struct { + GPUVertBuf *elem_vbo; + GPUTexture *elem_tx; + GPUTexture *verts_tx; + uint tri_count; + } face_wire; + /* 3d text */ struct { GPUBatch *select; @@ -439,6 +450,11 @@ static void curve_batch_cache_clear(Curve *cu) GPU_BATCH_DISCARD_ARRAY_SAFE(cache->surface.shaded_triangles, cache->surface.mat_len); GPU_BATCH_DISCARD_SAFE(cache->surface.batch); + GPU_VERTBUF_DISCARD_SAFE(cache->face_wire.elem_vbo); + DRW_TEXTURE_FREE_SAFE(cache->face_wire.elem_tx); + DRW_TEXTURE_FREE_SAFE(cache->face_wire.verts_tx); + cache->face_wire.tri_count = 0; + /* don't own vbo & elems */ GPU_BATCH_DISCARD_SAFE(cache->wire.batch); GPU_VERTBUF_DISCARD_SAFE(cache->wire.verts); @@ -785,6 +801,40 @@ static GPUBatch *curve_batch_cache_get_pos_and_normals(CurveRenderData *rdata, C return cache->surface.batch; } +static GPUTexture *curve_batch_cache_get_edges_overlay_texture_buf(CurveRenderData *rdata, CurveBatchCache *cache) +{ + BLI_assert(rdata->types & CU_DATATYPE_SURFACE); + + if (cache->face_wire.elem_tx != NULL) { + return cache->face_wire.elem_tx; + } + + ListBase *lb = &rdata->ob_curve_cache->disp; + + /* We need a special index buffer. */ + GPUVertBuf *vbo = cache->face_wire.elem_vbo = DRW_displist_create_edges_overlay_texture_buf(lb); + + /* Upload data early because we need to create the texture for it. */ + GPU_vertbuf_use(vbo); + cache->face_wire.elem_tx = GPU_texture_create_from_vertbuf(vbo); + cache->face_wire.tri_count = vbo->vertex_alloc / 3; + + return cache->face_wire.elem_tx; +} + +static GPUTexture *curve_batch_cache_get_vert_pos_and_nor_in_order_buf(CurveRenderData *rdata, CurveBatchCache *cache) +{ + BLI_assert(rdata->types & CU_DATATYPE_SURFACE); + + if (cache->face_wire.verts_tx == NULL) { + curve_batch_cache_get_pos_and_normals(rdata, cache); + GPU_vertbuf_use(cache->surface.verts); /* Upload early for buffer texture creation. */ + cache->face_wire.verts_tx = GPU_texture_create_buffer(GPU_R32F, cache->surface.verts->vbo_id); + } + + return cache->face_wire.verts_tx; +} + /** \} */ @@ -1024,6 +1074,25 @@ GPUBatch **DRW_curve_batch_cache_get_surface_shaded( return cache->surface.shaded_triangles; } +void DRW_curve_batch_cache_get_wireframes_face_texbuf( + Curve *cu, CurveCache *ob_curve_cache, + GPUTexture **verts_data, GPUTexture **face_indices, int *tri_count) +{ + CurveBatchCache *cache = curve_batch_cache_get(cu); + + if (cache->face_wire.elem_tx == NULL || cache->face_wire.verts_tx == NULL) { + CurveRenderData *rdata = curve_render_data_create(cu, ob_curve_cache, CU_DATATYPE_SURFACE); + + curve_batch_cache_get_edges_overlay_texture_buf(rdata, cache); + curve_batch_cache_get_vert_pos_and_nor_in_order_buf(rdata, cache); + + curve_render_data_free(rdata); + } + + *tri_count = cache->face_wire.tri_count; + *face_indices = cache->face_wire.elem_tx; + *verts_data = cache->face_wire.verts_tx; +} /* -------------------------------------------------------------------- */ diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c index 5ea0f6fb05d..1053e8fa4f7 100644 --- a/source/blender/draw/intern/draw_cache_impl_displist.c +++ b/source/blender/draw/intern/draw_cache_impl_displist.c @@ -87,31 +87,35 @@ static int curve_render_surface_tri_len_get(const ListBase *lb) return tri_len; } -static void displist_indexbufbuilder_set(GPUIndexBufBuilder *elb, const DispList *dl, const int ofs) +typedef void (setTriIndicesFn)(void *thunk, uint v1, uint v2, uint v3); + +static void displist_indexbufbuilder_set( + setTriIndicesFn *set_tri_indices, + void *thunk, 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) { - GPU_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[2] + ofs, idx[1] + ofs); + set_tri_indices(thunk, idx[0] + ofs, idx[2] + ofs, idx[1] + ofs); } } else if (dl->type == DL_SURF) { const int i_end = dl->totindex; for (int i = 0; i < i_end; i++, idx += 4) { - GPU_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[2] + ofs, idx[1] + ofs); - GPU_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[3] + ofs, idx[2] + ofs); + set_tri_indices(thunk, idx[0] + ofs, idx[2] + ofs, idx[1] + ofs); + set_tri_indices(thunk, idx[2] + ofs, idx[0] + 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) { - GPU_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs); + set_tri_indices(thunk, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs); if (idx[2] != idx[3]) { - GPU_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs); + set_tri_indices(thunk, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs); } } } @@ -125,7 +129,7 @@ GPUVertBuf *DRW_displist_vertbuf_calc_pos_with_normals(ListBase *lb) 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_F32, 3, GPU_FETCH_FLOAT); + attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); } GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); @@ -143,7 +147,9 @@ GPUVertBuf *DRW_displist_vertbuf_calc_pos_with_normals(ListBase *lb) while (vbo_len_used < vbo_end) { GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, fp_co); if (fp_no) { - GPU_vertbuf_attr_set(vbo, attr_id.nor, vbo_len_used, fp_no); + static short short_no[4]; + normal_float_to_short_v3(short_no, fp_no); + GPU_vertbuf_attr_set(vbo, attr_id.nor, vbo_len_used, short_no); if (ndata_is_single == false) { fp_no += 3; } @@ -167,7 +173,7 @@ GPUIndexBuf *DRW_displist_indexbuf_calc_triangles_in_order(ListBase *lb) int ofs = 0; for (const DispList *dl = lb->first; dl; dl = dl->next) { - displist_indexbufbuilder_set(&elb, dl, ofs); + displist_indexbufbuilder_set((setTriIndicesFn *)GPU_indexbuf_add_tri_verts, &elb, dl, ofs); ofs += dl_vert_len(dl); } @@ -192,7 +198,7 @@ GPUIndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_material(Li /* 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); + displist_indexbufbuilder_set((setTriIndicesFn *)GPU_indexbuf_add_tri_verts, &elb[dl->col], dl, ofs); ofs += dl_vert_len(dl); } @@ -204,6 +210,53 @@ GPUIndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_material(Li return shaded_triangles_in_order; } +typedef struct DRWDisplistWireThunk { + uint index_id, vidx; + short dl_type; + GPUVertBuf *vbo; +} DRWDisplistWireThunk; + +static void set_overlay_wires_tri_indices(void *thunk, uint v1, uint v2, uint v3) +{ + DRWDisplistWireThunk *dwt = (DRWDisplistWireThunk *)thunk; + /* TODO consider non-manifold edges correctly. */ + if (dwt->dl_type == DL_SURF) { + /* Tag real edges. */ + v2 |= (1 << 30); + v3 |= (1 << 30); + } + else { + /* Tag real edges. */ + v1 |= (1 << 30); + v2 |= (1 << 30); + v3 |= (1 << 30); + } + GPU_vertbuf_attr_set(dwt->vbo, dwt->index_id, dwt->vidx++, &v1); + GPU_vertbuf_attr_set(dwt->vbo, dwt->index_id, dwt->vidx++, &v2); + GPU_vertbuf_attr_set(dwt->vbo, dwt->index_id, dwt->vidx++, &v3); +} + +GPUVertBuf *DRW_displist_create_edges_overlay_texture_buf(ListBase *lb) +{ + GPUVertFormat format = {0}; + uint index_id = GPU_vertformat_attr_add(&format, "index", GPU_COMP_U32, 1, GPU_FETCH_INT); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + + GPU_vertbuf_data_alloc(vbo, curve_render_surface_tri_len_get(lb) * 3); + + DRWDisplistWireThunk thunk = {.index_id = index_id, .vbo = vbo, .vidx = 0}; + + int ofs = 0; + for (const DispList *dl = lb->first; dl; dl = dl->next) { + thunk.dl_type = dl->type; + displist_indexbufbuilder_set(set_overlay_wires_tri_indices, &thunk, dl, ofs); + ofs += dl_vert_len(dl); + } + + return vbo; +} + + static void displist_vertbuf_attr_set_tri_pos_normals_and_uv( GPUVertBufRaw *pos_step, GPUVertBufRaw *nor_step, GPUVertBufRaw *uv_step, const float v1[3], const float v2[3], const float v3[3], |