[Bf-blender-cvs] [ff6e61f09ab] blender2.8: DRW: Support Wireframe for metaball objects

Clément Foucault noreply at git.blender.org
Fri Nov 23 18:03:20 CET 2018


Commit: ff6e61f09ab2c86edef651fc38c242f5fefdd569
Author: Clément Foucault
Date:   Fri Nov 23 18:02:34 2018 +0100
Branches: blender2.8
https://developer.blender.org/rBff6e61f09ab2c86edef651fc38c242f5fefdd569

DRW: Support Wireframe for metaball objects

===================================================================

M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache.h
M	source/blender/draw/intern/draw_cache_impl.h
M	source/blender/draw/intern/draw_cache_impl_displist.c
M	source/blender/draw/intern/draw_cache_impl_metaball.c

===================================================================

diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index a2430d12f41..d6caabcb203 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -709,7 +709,9 @@ void DRW_cache_object_face_wireframe_get(
 		case OB_FONT:
 			DRW_cache_text_face_wireframe_get(ob, r_vert_tx, r_faceid_tx, r_tri_count);
 			break;
-		/* TODO, metaballs' */
+		case OB_MBALL:
+			DRW_cache_mball_face_wireframe_get(ob, r_vert_tx, r_faceid_tx, r_tri_count);
+			break;
 	}
 }
 
@@ -3287,6 +3289,13 @@ GPUBatch *DRW_cache_mball_surface_get(Object *ob)
 	return DRW_metaball_batch_cache_get_triangles_with_normals(ob);
 }
 
+void DRW_cache_mball_face_wireframe_get(
+        Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count)
+{
+	BLI_assert(ob->type == OB_MBALL);
+	return DRW_metaball_batch_cache_get_wireframes_face_texbuf(ob, r_vert_tx, r_faceid_tx, r_tri_count);
+}
+
 GPUBatch **DRW_cache_mball_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 39bbcf2c93a..d2aa2622246 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -209,5 +209,7 @@ struct GPUBatch *DRW_cache_particles_get_prim(int type);
 /* Metaball */
 struct GPUBatch *DRW_cache_mball_surface_get(struct Object *ob);
 struct GPUBatch **DRW_cache_mball_surface_shaded_get(struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
+void DRW_cache_mball_face_wireframe_get(
+        Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count);
 
 #endif /* __DRAW_CACHE_H__ */
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 97e7cd240ff..9dc735807c0 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -82,6 +82,8 @@ void DRW_curve_batch_cache_get_wireframes_face_texbuf(
 /* Metaball */
 struct GPUBatch *DRW_metaball_batch_cache_get_triangles_with_normals(struct Object *ob);
 struct GPUBatch **DRW_metaball_batch_cache_get_surface_shaded(struct Object *ob, struct MetaBall *mb, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
+void DRW_metaball_batch_cache_get_wireframes_face_texbuf(
+        struct Object *ob, struct GPUTexture **verts_data, struct GPUTexture **face_indices, int *tri_count);
 
 /* Curve (Font) */
 struct GPUBatch *DRW_curve_batch_cache_get_overlay_cursor(struct Curve *cu);
diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c
index 1053e8fa4f7..d6a57676a8d 100644
--- a/source/blender/draw/intern/draw_cache_impl_displist.c
+++ b/source/blender/draw/intern/draw_cache_impl_displist.c
@@ -91,6 +91,7 @@ typedef void (setTriIndicesFn)(void *thunk, uint v1, uint v2, uint v3);
 
 static void displist_indexbufbuilder_set(
 	setTriIndicesFn *set_tri_indices,
+	setTriIndicesFn *set_quad_tri_indices, /* meh, find a better solution. */
 	void *thunk, const DispList *dl, const int ofs)
 {
 	if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) {
@@ -104,18 +105,20 @@ static void displist_indexbufbuilder_set(
 		else if (dl->type == DL_SURF) {
 			const int i_end = dl->totindex;
 			for (int i = 0; i < i_end; i++, idx += 4) {
-				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);
+				set_quad_tri_indices(thunk, idx[0] + ofs, idx[2] + ofs, idx[1] + ofs);
+				set_quad_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) {
-				set_tri_indices(thunk, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs);
-
 				if (idx[2] != idx[3]) {
-					set_tri_indices(thunk, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs);
+					set_quad_tri_indices(thunk, idx[2] + ofs, idx[0] + ofs, idx[1] + ofs);
+					set_quad_tri_indices(thunk, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs);
+				}
+				else {
+					set_tri_indices(thunk, idx[2] + ofs, idx[0] + ofs, idx[1] + ofs);
 				}
 			}
 		}
@@ -173,7 +176,9 @@ 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((setTriIndicesFn *)GPU_indexbuf_add_tri_verts, &elb, dl, ofs);
+		displist_indexbufbuilder_set((setTriIndicesFn *)GPU_indexbuf_add_tri_verts,
+		                             (setTriIndicesFn *)GPU_indexbuf_add_tri_verts,
+		                             &elb, dl, ofs);
 		ofs += dl_vert_len(dl);
 	}
 
@@ -198,7 +203,9 @@ 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((setTriIndicesFn *)GPU_indexbuf_add_tri_verts, &elb[dl->col], dl, ofs);
+		displist_indexbufbuilder_set((setTriIndicesFn *)GPU_indexbuf_add_tri_verts,
+		                             (setTriIndicesFn *)GPU_indexbuf_add_tri_verts,
+		                             &elb[dl->col], dl, ofs);
 		ofs += dl_vert_len(dl);
 	}
 
@@ -219,18 +226,21 @@ typedef struct 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);
-	}
+	/* 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);
+}
+
+static void set_overlay_wires_quad_tri_indices(void *thunk, uint v1, uint v2, uint v3)
+{
+	DRWDisplistWireThunk *dwt = (DRWDisplistWireThunk *)thunk;
+	/* Tag real edges. */
+	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);
@@ -249,7 +259,10 @@ GPUVertBuf *DRW_displist_create_edges_overlay_texture_buf(ListBase *lb)
 	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);
+		/* TODO consider non-manifold edges correctly. */
+		displist_indexbufbuilder_set(set_overlay_wires_tri_indices,
+		                             set_overlay_wires_quad_tri_indices,
+		                             &thunk, dl, ofs);
 		ofs += dl_vert_len(dl);
 	}
 
diff --git a/source/blender/draw/intern/draw_cache_impl_metaball.c b/source/blender/draw/intern/draw_cache_impl_metaball.c
index 6dab46ccaa0..b41b443039a 100644
--- a/source/blender/draw/intern/draw_cache_impl_metaball.c
+++ b/source/blender/draw/intern/draw_cache_impl_metaball.c
@@ -39,6 +39,8 @@
 
 #include "GPU_batch.h"
 
+#include "DRW_render.h"
+
 #include "draw_cache_impl.h"  /* own include */
 
 
@@ -50,8 +52,19 @@ static void metaball_batch_cache_clear(MetaBall *mb);
 typedef struct MetaBallBatchCache {
 	GPUBatch *batch;
 	GPUBatch **shaded_triangles;
-
 	int mat_len;
+
+	/* Shared */
+	GPUVertBuf *pos_nor_in_order;
+
+	/* Wireframe */
+	struct {
+		GPUVertBuf *elem_vbo;
+		GPUTexture *elem_tx;
+		GPUTexture *verts_tx;
+		int tri_count;
+	} face_wire;
+
 	/* settings to determine if cache is invalid */
 	bool is_dirty;
 } MetaBallBatchCache;
@@ -80,6 +93,11 @@ static void metaball_batch_cache_init(MetaBall *mb)
 	cache->mat_len = 0;
 	cache->shaded_triangles = NULL;
 	cache->is_dirty = false;
+	cache->pos_nor_in_order = NULL;
+	cache->face_wire.elem_vbo = NULL;
+	cache->face_wire.elem_tx = NULL;
+	cache->face_wire.verts_tx = NULL;
+	cache->face_wire.tri_count = 0;
 }
 
 static MetaBallBatchCache *metaball_batch_cache_get(MetaBall *mb)
@@ -113,7 +131,12 @@ static void metaball_batch_cache_clear(MetaBall *mb)
 		return;
 	}
 
+	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);
+
 	GPU_BATCH_DISCARD_SAFE(cache->batch);
+	GPU_VERTBUF_DISCARD_SAFE(cache->pos_nor_in_order);
 	/* Note: shaded_triangles[0] is already freed by cache->batch */
 	MEM_SAFE_FREE(cache->shaded_triangles);
 	cache->mat_len = 0;
@@ -125,6 +148,45 @@ void DRW_mball_batch_cache_free(MetaBall *mb)
 	MEM_SAFE_FREE(mb->batch_cache);
 }
 
+static GPUVertBuf *mball_batch_cache_get_pos_and_normals(Object *ob, MetaBallBatchCache *cache)
+{
+	if (cache->pos_nor_in_order == NULL) {
+		ListBase *lb = &ob->runtime.curve_cache->disp;
+		cache->pos_nor_in_order = DRW_displist_vertbuf_calc_pos_with_normals(lb);
+	}
+	return cache->pos_nor_in_order;
+}
+
+static GPUTexture *mball_batch_cache_get_edges_overlay_texture_buf(Object *ob, MetaBallBatchCache *cache)
+{
+	if (cache->face_wire.elem_tx != NULL) {
+		return cache->face_wire.elem_tx;
+	}
+
+	ListBase *lb = &ob->runtime.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 *mball_batch_cache_get_vert_pos_and_nor_in_order_buf(Object *ob, MetaBallBatchCache *cache)
+{
+	if (cache->face_wire.verts_tx == NULL) {
+		GPUVertBuf *vbo = mball_batch_cache_get_pos_and_normals(ob, cache);
+		GPU_vertbuf_use(vbo); /* Upload early for buffer texture creation. */
+		cache->fac

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list