[Bf-blender-cvs] [53f6a31] master: GPU Buffers:

Antony Riakiotakis noreply at git.blender.org
Sat Jul 25 20:01:08 CEST 2015


Commit: 53f6a31c4de18fb3db8cdd34c0f9b0495319183f
Author: Antony Riakiotakis
Date:   Sat Jul 25 20:00:49 2015 +0200
Branches: master
https://developer.blender.org/rB53f6a31c4de18fb3db8cdd34c0f9b0495319183f

GPU Buffers:

This commit begins implementation of the idea about hidden face
separation outlined in

http://code.blender.org/2015/06/optimizing-blenders-real-time-mesh-

We split hidden and visible faces to different parts of the triangle
buffer.
Mapped drawing will now skip iterating through hidden polys.
Of course the final target, when all derived mesh types use
VBO sorting, is to skip checking for hide flag per face
completely. All faces will be pre-sorted anyway and we'll
be able to draw them with one draw call.

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

M	source/blender/blenkernel/intern/cdderivedmesh.c
M	source/blender/editors/space_view3d/drawmesh.c
M	source/blender/editors/space_view3d/drawobject.c
M	source/blender/gpu/GPU_buffers.h

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

diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 060ffff..8f04c19 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -719,7 +719,7 @@ static void cdDM_drawMappedFaces(
 			GPUBufferMaterial *bufmat = dm->drawObject->materials + mat_index;
 			DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
 			int next_actualFace = bufmat->polys[0];
-			totpoly = bufmat->totpolys;
+			totpoly = useHide ? bufmat->totvisiblepolys : bufmat->totpolys;
 
 			tot_element = 0;
 			start_element = 0;
@@ -1229,32 +1229,70 @@ static void cdDM_drawMappedEdges(DerivedMesh *dm, DMSetDrawOptions setDrawOption
 	glEnd();
 }
 
+typedef struct FaceCount {
+	unsigned int i_visible;
+	unsigned int i_hidden;
+	unsigned int i_tri_visible;
+	unsigned int i_tri_hidden;
+} FaceCount;
+
 static void cdDM_buffer_copy_triangles(
         DerivedMesh *dm, unsigned int *varray,
         const int *mat_orig_to_new)
 {
-	GPUBufferMaterial *gpumat;
-	int i, findex = 0;
+	GPUBufferMaterial *gpumat, *gpumaterials = dm->drawObject->materials;
+	int i, j, start;
 
-	const MPoly *mpoly;
+	const int totmat = dm->drawObject->totmaterial;
+	const MPoly *mpoly = dm->getPolyArray(dm);
 	const MLoopTri *lt = dm->getLoopTriArray(dm);
-	const int tottri = dm->getNumLoopTri(dm);
+	const int totpoly = dm->getNumPolys(dm);
 
-	mpoly = dm->getPolyArray(dm);
+	FaceCount *fc = MEM_mallocN(sizeof(*fc) * totmat, "gpumaterial.facecount");
 
-	for (i = 0; i < tottri; i++, lt++) {
-		int start;
-		gpumat = dm->drawObject->materials + mat_orig_to_new[mpoly[lt->poly].mat_nr];
-		start = gpumat->counter;
+	for (i = 0; i < totmat; i++) {
+		fc[i].i_visible = 0;
+		fc[i].i_tri_visible = 0;
+		fc[i].i_hidden = gpumaterials[i].totpolys - 1;
+		fc[i].i_tri_hidden = gpumaterials[i].totelements - 1;
+	}
 
-		/* v1 v2 v3 */
-		varray[start++] = lt->tri[0];
-		varray[start++] = lt->tri[1];
-		varray[start++] = lt->tri[2];
+	for (i = 0; i < totpoly; i++) {
+		int tottri = ME_POLY_TRI_TOT(&mpoly[i]);
+		int mati = mat_orig_to_new[mpoly[i].mat_nr];
+		gpumat = gpumaterials + mati;
 
-		gpumat->counter += 3;
-		findex += 3;
+		if (mpoly[i].flag & ME_HIDE) {
+			for (j = 0; j < tottri; j++, lt++) {
+				start = gpumat->start + fc[mati].i_tri_hidden;
+				/* v1 v2 v3 */
+				varray[start--] = lt->tri[2];
+				varray[start--] = lt->tri[1];
+				varray[start--] = lt->tri[0];
+				fc[mati].i_tri_hidden -= 3;
+			}
+			gpumat->polys[fc[mati].i_hidden--] = i;
+		}
+		else {
+			for (j = 0; j < tottri; j++, lt++) {
+				start = gpumat->start + fc[mati].i_tri_visible;
+				/* v1 v2 v3 */
+				varray[start++] = lt->tri[0];
+				varray[start++] = lt->tri[1];
+				varray[start++] = lt->tri[2];
+				fc[mati].i_tri_visible += 3;
+			}
+			gpumat->polys[fc[mati].i_visible++] = i;
+		}
+	}
+
+	/* set the visible polygons */
+	for (i = 0; i < totmat; i++) {
+		gpumaterials[i].totvisiblepolys = fc[i].i_visible;
 	}
+
+
+	MEM_freeN(fc);
 }
 
 static void cdDM_buffer_copy_vertex(
@@ -1594,15 +1632,11 @@ static void cdDM_drawobject_add_vert_point(GPUDrawObject *gdo, int vert_index, i
 static void cdDM_drawobject_init_vert_points(
         GPUDrawObject *gdo,
         const MPoly *mpoly, const MLoop *mloop,
-        int tot_poly,
-        int totmat)
+        int tot_poly)
 {
-	GPUBufferMaterial *mat;
-	int i, *mat_orig_to_new;
+	int i;
 	int tot_loops = 0;
 
-	mat_orig_to_new = MEM_callocN(sizeof(*mat_orig_to_new) * totmat,
-	                                             "GPUDrawObject.mat_orig_to_new");
 	/* allocate the array and space for links */
 	gdo->vert_points = MEM_mallocN(sizeof(GPUVertPointLink) * gdo->totvert,
 	                               "GPUDrawObject.vert_points");
@@ -1612,13 +1646,6 @@ static void cdDM_drawobject_init_vert_points(
 	gdo->vert_points_usage = 0;
 #endif
 
-	/* build a map from the original material indices to the new
-	 * GPUBufferMaterial indices */
-	for (i = 0; i < gdo->totmaterial; i++) {
-		mat_orig_to_new[gdo->materials[i].mat_nr] = i;
-		gdo->materials[i].counter = 0;
-	}
-
 	/* -1 indicates the link is not yet used */
 	for (i = 0; i < gdo->totvert; i++) {
 #ifdef USE_GPU_POINT_LINK
@@ -1630,9 +1657,6 @@ static void cdDM_drawobject_init_vert_points(
 	for (i = 0; i < tot_poly; i++) {
 		int j;
 		const MPoly *mp = &mpoly[i];
-		mat = &gdo->materials[mat_orig_to_new[mp->mat_nr]];
-
-		mat->polys[mat->counter++] = i;
 
 		/* assign unique indices to vertices of the mesh */
 		for (j = 0; j < mp->totloop; j++) {
@@ -1648,8 +1672,6 @@ static void cdDM_drawobject_init_vert_points(
 			gdo->tot_loose_point++;
 		}
 	}
-
-	MEM_freeN(mat_orig_to_new);
 }
 
 /* see GPUDrawObject's structure definition for a description of the
@@ -1692,9 +1714,9 @@ static GPUDrawObject *cdDM_GPUobject_new(DerivedMesh *dm)
 	gdo->tot_loop_verts = totloops;
 
 	/* store total number of points used for triangles */
-	gdo->tot_triangle_point = dm->getNumLoopTri(dm) * 3;
+	gdo->tot_triangle_point = poly_to_tri_count(totpolys, totloops) * 3;
 
-	cdDM_drawobject_init_vert_points(gdo, mpoly, mloop, totpolys, totmat);
+	cdDM_drawobject_init_vert_points(gdo, mpoly, mloop, totpolys);
 
 	return gdo;
 }
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index ea1e317..6085f0c 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -194,7 +194,7 @@ void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm, bool d
 		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 		/* dull unselected faces so as not to get in the way of seeing color */
 		glColor4ub(96, 96, 96, 64);
-		dm->drawMappedFaces(dm, draw_mesh_face_select__drawFaceOptsInv, NULL, NULL, (void *)me, 0);
+		dm->drawMappedFaces(dm, draw_mesh_face_select__drawFaceOptsInv, NULL, NULL, (void *)me, DM_DRAW_SKIP_HIDDEN);
 		glDisable(GL_BLEND);
 	}
 	
@@ -959,7 +959,7 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d
 	else if (draw_flags & DRAW_FACE_SELECT) {
 		if (ob->mode & OB_MODE_WEIGHT_PAINT)
 			dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions_facemask, GPU_enable_material, NULL, me,
-			                    DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
+			                    DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH | DM_DRAW_SKIP_HIDDEN);
 		else {
 			drawTFace_userData userData;
 
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 147c714..fee6805 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -3063,7 +3063,7 @@ static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *ba
 	/* double lookup */
 	data.orig_index_mp_to_orig  = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
 
-	dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, NULL, draw_dm_faces_sel__compareDrawOptions, &data, 0);
+	dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, NULL, draw_dm_faces_sel__compareDrawOptions, &data, DM_DRAW_SKIP_HIDDEN);
 }
 
 static DMDrawOption draw_dm_creases__setDrawOptions(void *userData, int index)
@@ -3763,7 +3763,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
 			/* use the cageDM since it always overlaps the editmesh faces */
 			glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
 			cageDM->drawMappedFaces(cageDM, draw_em_fancy__setFaceOpts,
-			                        GPU_enable_material, NULL, me->edit_btmesh, 0);
+			                        GPU_enable_material, NULL, me->edit_btmesh, DM_DRAW_SKIP_HIDDEN);
 			glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
 		}
 		else if (check_object_draw_texture(scene, v3d, dt)) {
@@ -3787,7 +3787,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
 
 			glEnable(GL_LIGHTING);
 			glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
-			finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, GPU_enable_material, NULL, me->edit_btmesh, 0);
+			finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, GPU_enable_material, NULL, me->edit_btmesh, DM_DRAW_SKIP_HIDDEN);
 
 			glFrontFace(GL_CCW);
 			glDisable(GL_LIGHTING);
@@ -8445,7 +8445,7 @@ static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d,
 	cpack(0);
 
 	if (use_faceselect) {
-		dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, NULL, NULL, em->bm, 0);
+		dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, NULL, NULL, em->bm, DM_DRAW_SKIP_HIDDEN);
 
 		if (check_ob_drawface_dot(scene, v3d, ob->dt)) {
 			glPointSize(UI_GetThemeValuef(TH_FACEDOT_SIZE));
@@ -8457,7 +8457,7 @@ static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d,
 
 	}
 	else {
-		dm->drawMappedFaces(dm, bbs_mesh_mask__setSolidDrawOptions, NULL, NULL, em->bm, DM_DRAW_SKIP_SELECT);
+		dm->drawMappedFaces(dm, bbs_mesh_mask__setSolidDrawOptions, NULL, NULL, em->bm, DM_DRAW_SKIP_SELECT | DM_DRAW_SKIP_HIDDEN);
 	}
 }
 
@@ -8501,7 +8501,7 @@ static void bbs_mesh_solid_verts(Scene *scene, Object *ob)
 
 	DM_update_materials(dm, ob);
 
-	dm->drawMappedFaces(dm, bbs_mesh_solid_hide2__setDrawOpts, GPU_enable_material, NULL, me, 0);
+	dm->drawMappedFaces(dm, bbs_mesh_solid_hide2__setDrawOpts, GPU_enable_material, NULL, me, DM_DRAW_SKIP_HIDDEN);
 
 	bbs_obmode_mesh_verts(ob, dm, 1);
 	bm_vertoffs = me->totvert + 1;
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index 8bb3ef4..1a85d37 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -67,6 +67,7 @@ typedef struct GPUBufferMaterial {
 	unsigned int *polys; /* array of polygons for this material */
 	unsigned int totpolys; /* total polygons in polys */
 	unsigned int counter; /* general purpose counter, initialize first! */
+	unsigned int totvisiblepolys; /* total visible polygons */
 
 	/* original material index */
 	short mat_nr;




More information about the Bf-blender-cvs mailing list