[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [42034] trunk/blender/source/blender/ blenkernel/intern/subsurf_ccg.c: Fix #29348: subsurf modifier causing mesh to draw slower than with modifier

Brecht Van Lommel brechtvanlommel at pandora.be
Mon Nov 21 15:59:26 CET 2011


Revision: 42034
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=42034
Author:   blendix
Date:     2011-11-21 14:59:26 +0000 (Mon, 21 Nov 2011)
Log Message:
-----------
Fix #29348: subsurf modifier causing mesh to draw slower than with modifier
applied in some cases, due to more opengl state switching. There are still
some differences in performance, but that's expected due to different opengl
draw commands used.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c

Modified: trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c	2011-11-21 14:52:05 UTC (rev 42033)
+++ trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c	2011-11-21 14:59:26 UTC (rev 42034)
@@ -1173,8 +1173,6 @@
 static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int UNUSED(drawAllEdges)) {
 	CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
 	CCGSubSurf *ss = ccgdm->ss;
-	CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
-	CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
 	int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
 	int totedge = ccgSubSurf_getNumEdges(ss);
 	int gridSize = ccgSubSurf_getGridSize(ss);
@@ -1212,8 +1210,10 @@
 	}
 
 	if (ccgdm->drawInteriorEdges) {
-		for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
-			CCGFace *f = ccgFaceIterator_getCurrent(fi);
+		int totface = ccgSubSurf_getNumFaces(ss);
+
+		for(j = 0; j < totface; j++) {
+			CCGFace *f = ccgdm->faceMap[j].face;
 			int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
 
 			for (S=0; S<numVerts; S++) {
@@ -1238,18 +1238,15 @@
 			}
 		}
 	}
-
-	ccgFaceIterator_free(fi);
-	ccgEdgeIterator_free(ei);
 }
 static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
 	CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
 	CCGSubSurf *ss = ccgdm->ss;
-	CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
-	int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
+	int totedge = ccgSubSurf_getNumEdges(ss);
+	int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
 
-	for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
-		CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
+	for (j=0; j< totedge; j++) {
+		CCGEdge *e = ccgdm->edgeMap[j].edge;
 		DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
 
 		if (!ccgSubSurf_getEdgeNumFaces(e)) {
@@ -1261,8 +1258,6 @@
 			glEnd();
 		}
 	}
-
-	ccgEdgeIterator_free(ei);
 }
 
 static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
@@ -1283,10 +1278,11 @@
 static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], int fast, int (*setMaterial)(int, void *attribs)) {
 	CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
 	CCGSubSurf *ss = ccgdm->ss;
-	CCGFaceIterator *fi;
 	int gridSize = ccgSubSurf_getGridSize(ss);
 	char *faceFlags = ccgdm->faceFlags;
 	int step = (fast)? gridSize-1: 1;
+	int i, totface = ccgSubSurf_getNumFaces(ss);
+	int drawcurrent = 0, matnr = -1, shademodel = -1;
 
 	ccgdm_pbvh_update(ccgdm);
 
@@ -1304,30 +1300,37 @@
 		return;
 	}
 
-	fi = ccgSubSurf_getFaceIterator(ss);
-	for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
-		CCGFace *f = ccgFaceIterator_getCurrent(fi);
+	for(i = 0; i < totface; i++) {
+		CCGFace *f = ccgdm->faceMap[i].face;
 		int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
 		int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
-		int drawSmooth, mat_nr;
+		int new_matnr, new_shademodel;
 
 		if(faceFlags) {
-			drawSmooth = (faceFlags[index*2] & ME_SMOOTH);
-			mat_nr= faceFlags[index*2 + 1];
+			new_shademodel = (faceFlags[index*2] & ME_SMOOTH)? GL_SMOOTH: GL_FLAT;
+			new_matnr= faceFlags[index*2 + 1];
 		}
 		else {
-			drawSmooth = 1;
-			mat_nr= 0;
+			new_shademodel = GL_SMOOTH;
+			new_matnr= 0;
 		}
 		
-		if (!setMaterial(mat_nr+1, NULL))
+		if(shademodel != new_shademodel || matnr != new_matnr) {
+			matnr= new_matnr;
+			shademodel= new_shademodel;
+
+			drawcurrent= setMaterial(matnr+1, NULL);
+
+			glShadeModel(shademodel);
+		}
+
+		if(!drawcurrent)
 			continue;
 
-		glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
 		for (S=0; S<numVerts; S++) {
 			DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
 
-			if (drawSmooth) {
+			if (shademodel == GL_SMOOTH) {
 				for (y=0; y<gridSize-1; y+=step) {
 					glBegin(GL_QUAD_STRIP);
 					for (x=0; x<gridSize; x+=step) {
@@ -1362,15 +1365,12 @@
 			}
 		}
 	}
-
-	ccgFaceIterator_free(fi);
 }
 
 	/* Only used by non-editmesh types */
 static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData) {
 	CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
 	CCGSubSurf *ss = ccgdm->ss;
-	CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
 	GPUVertexAttribs gattribs;
 	DMVertexAttribs attribs= {{{NULL}}};
 	/* MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
@@ -1503,8 +1503,6 @@
 	}
 
 #undef PASSATTRIB
-
-	ccgFaceIterator_free(fi);
 }
 
 static void ccgDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
@@ -1515,7 +1513,6 @@
 static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void *userData, int, void *attribs), int (*setFace)(void *userData, int index), void *userData) {
 	CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
 	CCGSubSurf *ss = ccgdm->ss;
-	CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
 	GPUVertexAttribs gattribs;
 	DMVertexAttribs attribs= {{{NULL}}};
 	int gridSize = ccgSubSurf_getGridSize(ss);
@@ -1655,18 +1652,15 @@
 	}
 
 #undef PASSATTRIB
-
-	ccgFaceIterator_free(fi);
 }
 
 
 static void ccgDM_drawFacesColored(DerivedMesh *dm, int UNUSED(useTwoSided), unsigned char *col1, unsigned char *col2) {
 	CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
 	CCGSubSurf *ss = ccgdm->ss;
-	CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
 	int gridSize = ccgSubSurf_getGridSize(ss);
 	unsigned char *cp1, *cp2;
-	int useTwoSide=1;
+	int useTwoSide=1, i, totface;
 
 	ccgdm_pbvh_update(ccgdm);
 
@@ -1685,8 +1679,9 @@
 	}
 
 	glBegin(GL_QUADS);
-	for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
-		CCGFace *f = ccgFaceIterator_getCurrent(fi);
+	totface = ccgSubSurf_getNumFaces(ss);
+	for(i = 0; i < totface; i++) {
+		CCGFace *f = ccgdm->faceMap[i].face;
 		int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
 
 		for (S=0; S<numVerts; S++) {
@@ -1725,8 +1720,6 @@
 		}
 	}
 	glEnd();
-
-	ccgFaceIterator_free(fi);
 }
 
 static void ccgDM_drawFacesTex_common(DerivedMesh *dm,




More information about the Bf-blender-cvs mailing list