[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [40120] trunk/blender/source/blender/ blenkernel/intern/DerivedMesh.c: speedup for editmesh drawing.

Campbell Barton ideasman42 at gmail.com
Sun Sep 11 12:23:26 CEST 2011


Revision: 40120
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=40120
Author:   campbellbarton
Date:     2011-09-11 10:23:26 +0000 (Sun, 11 Sep 2011)
Log Message:
-----------
speedup for editmesh drawing.
- avoid needless context switching quad/tri, flat/smooth.
- dont call glNormal3vf() lighting is disabled.

gives ~2x speedup with a subdivided cube, but thats probably the best case, quad/tri smooth/flat mix will slow down a bit.

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

Modified: trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c	2011-09-11 10:00:43 UTC (rev 40119)
+++ trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c	2011-09-11 10:23:26 UTC (rev 40120)
@@ -643,13 +643,22 @@
 	EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
 	EditFace *efa;
 	int i, draw;
-	
+	const int skip_normals= !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */
+
+	/* GL_ZERO is used to detect if drawing has started or not */
+	GLenum poly_prev= GL_ZERO;
+	GLenum shade_prev= GL_ZERO;
+
 	(void)setMaterial; /* unused */
 
 	/* currently unused -- each original face is handled separately */
 	(void)compareDrawOptions;
 
 	if (emdm->vertexCos) {
+		/* add direct access */
+		const float (*vertexCos)[3]= emdm->vertexCos;
+		const float (*vertexNos)[3]= emdm->vertexNos;
+		const float (*faceNos)[3]=   emdm->faceNos;
 		EditVert *eve;
 
 		for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
@@ -659,75 +668,134 @@
 			int drawSmooth = (efa->flag & ME_SMOOTH);
 			draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
 			if(draw) {
+				const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES;
 				if (draw==2) { /* enabled with stipple */
-					  glEnable(GL_POLYGON_STIPPLE);
-					  glPolygonStipple(stipple_quarttone);
+
+					if(poly_prev != GL_ZERO) glEnd();
+					poly_prev= GL_ZERO; /* force glBegin */
+
+					glEnable(GL_POLYGON_STIPPLE);
+					glPolygonStipple(stipple_quarttone);
 				}
 				
-				glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
+				if(skip_normals) {
+					if(poly_type != poly_prev) {
+						if(poly_prev != GL_ZERO) glEnd();
+						glBegin((poly_prev= poly_type));
+					}
+					glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
+					glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
+					glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
+					if(poly_type == GL_QUADS) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
+				}
+				else {
+					const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT;
+					if (shade_type != shade_prev) {
+						glShadeModel((shade_prev= shade_type));
+					}
+					if(poly_type != poly_prev) {
+						if(poly_prev != GL_ZERO) glEnd();
+						glBegin((poly_prev= poly_type));
+					}
 
-				glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
-				if (!drawSmooth) {
-					glNormal3fv(emdm->faceNos[i]);
-					glVertex3fv(emdm->vertexCos[(int) efa->v1->tmp.l]);
-					glVertex3fv(emdm->vertexCos[(int) efa->v2->tmp.l]);
-					glVertex3fv(emdm->vertexCos[(int) efa->v3->tmp.l]);
-					if(efa->v4) glVertex3fv(emdm->vertexCos[(int) efa->v4->tmp.l]);
-				} else {
-					glNormal3fv(emdm->vertexNos[(int) efa->v1->tmp.l]);
-					glVertex3fv(emdm->vertexCos[(int) efa->v1->tmp.l]);
-					glNormal3fv(emdm->vertexNos[(int) efa->v2->tmp.l]);
-					glVertex3fv(emdm->vertexCos[(int) efa->v2->tmp.l]);
-					glNormal3fv(emdm->vertexNos[(int) efa->v3->tmp.l]);
-					glVertex3fv(emdm->vertexCos[(int) efa->v3->tmp.l]);
-					if(efa->v4) {
-						glNormal3fv(emdm->vertexNos[(int) efa->v4->tmp.l]);
-						glVertex3fv(emdm->vertexCos[(int) efa->v4->tmp.l]);
+					if (!drawSmooth) {
+						glNormal3fv(faceNos[i]);
+						glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
+						glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
+						glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
+						if(poly_type == GL_QUADS) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
+					} else {
+						glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
+						glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
+						glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
+						glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
+						glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
+						glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
+						if(poly_type == GL_QUADS) {
+							glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
+							glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
+						}
 					}
 				}
-				glEnd();
+
 				
-				if (draw==2)
+				if (draw==2) {
+					glEnd();
+					poly_prev= GL_ZERO; /* force glBegin */
+
 					glDisable(GL_POLYGON_STIPPLE);
+				}
 			}
 		}
-	} else {
+	}
+	else {
 		for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
 			int drawSmooth = (efa->flag & ME_SMOOTH);
 			draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
 			if(draw) {
+				const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES;
 				if (draw==2) { /* enabled with stipple */
+
+					if(poly_prev != GL_ZERO) glEnd();
+					poly_prev= GL_ZERO; /* force glBegin */
+
 					glEnable(GL_POLYGON_STIPPLE);
 					glPolygonStipple(stipple_quarttone);
 				}
-				glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
 
-				glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
-				if (!drawSmooth) {
-					glNormal3fv(efa->n);
+				if(skip_normals) {
+					if(poly_type != poly_prev) {
+						if(poly_prev != GL_ZERO) glEnd();
+						glBegin((poly_prev= poly_type));
+					}
 					glVertex3fv(efa->v1->co);
 					glVertex3fv(efa->v2->co);
 					glVertex3fv(efa->v3->co);
-					if(efa->v4) glVertex3fv(efa->v4->co);
-				} else {
-					glNormal3fv(efa->v1->no);
-					glVertex3fv(efa->v1->co);
-					glNormal3fv(efa->v2->no);
-					glVertex3fv(efa->v2->co);
-					glNormal3fv(efa->v3->no);
-					glVertex3fv(efa->v3->co);
-					if(efa->v4) {
-						glNormal3fv(efa->v4->no);
-						glVertex3fv(efa->v4->co);
+					if(poly_type == GL_QUADS) glVertex3fv(efa->v4->co);
+				}
+				else {
+					const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT;
+					if (shade_type != shade_prev) {
+						glShadeModel((shade_prev= shade_type));
 					}
+					if(poly_type != poly_prev) {
+						if(poly_prev != GL_ZERO) glEnd();
+						glBegin((poly_prev= poly_type));
+					}
+
+					if (!drawSmooth) {
+						glNormal3fv(efa->n);
+						glVertex3fv(efa->v1->co);
+						glVertex3fv(efa->v2->co);
+						glVertex3fv(efa->v3->co);
+						if(poly_type == GL_QUADS) glVertex3fv(efa->v4->co);
+					} else {
+						glNormal3fv(efa->v1->no);
+						glVertex3fv(efa->v1->co);
+						glNormal3fv(efa->v2->no);
+						glVertex3fv(efa->v2->co);
+						glNormal3fv(efa->v3->no);
+						glVertex3fv(efa->v3->co);
+						if(poly_type == GL_QUADS) {
+							glNormal3fv(efa->v4->no);
+							glVertex3fv(efa->v4->co);
+						}
+					}
 				}
-				glEnd();
+
 				
-				if (draw==2)
+				if (draw==2) {
+					glEnd();
+					poly_prev= GL_ZERO;
+
 					glDisable(GL_POLYGON_STIPPLE);
+				}
 			}
 		}
 	}
+
+	/* if non zero we know a face was rendered */
+	if(poly_prev != GL_ZERO) glEnd();
 }
 
 static void emDM_drawFacesTex_common(DerivedMesh *dm,




More information about the Bf-blender-cvs mailing list