[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [27265] trunk/blender/source/blender/ editors/space_view3d/view3d_draw.c: using displist with dupli objects logic was flawed, it would only try and use a displist with a new object if the previous one worked with a displist .

Campbell Barton ideasman42 at gmail.com
Thu Mar 4 16:58:27 CET 2010


Revision: 27265
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=27265
Author:   campbellbarton
Date:     2010-03-04 16:58:27 +0100 (Thu, 04 Mar 2010)

Log Message:
-----------
using displist with dupli objects logic was flawed, it would only try and use a displist with a new object if the previous one worked with a displist.
rather then this, if the object changes, re-test if a displist is possible.
also check if the next object matches before making a displist else there is no point since it will be freed right after.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/space_view3d/view3d_draw.c

Modified: trunk/blender/source/blender/editors/space_view3d/view3d_draw.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/view3d_draw.c	2010-03-04 14:59:20 UTC (rev 27264)
+++ trunk/blender/source/blender/editors/space_view3d/view3d_draw.c	2010-03-04 15:58:27 UTC (rev 27265)
@@ -1491,12 +1491,27 @@
 }
 #endif
 
+
+static int draw_dupli_objects_step(DupliObject **dob_prev, DupliObject **dob, DupliObject **dob_next)
+{
+	(*dob_prev) = (*dob);
+	(*dob) = (*dob_next);
+
+	if((*dob_next)) {
+		(*dob_next) = (*dob_next)->next;
+		while((*dob_next) && (*dob_next)->no_draw) {
+			(*dob_next)= (*dob_next)->next;
+		}
+	}
+
+	return (*dob) != NULL;
+}
+
 static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int color)
-{	
+{
 	RegionView3D *rv3d= ar->regiondata;
 	ListBase *lb;
-	DupliObject *dob;
-	Object *ob_prev= NULL;
+	DupliObject *dob_prev= NULL, *dob= NULL, *dob_next= NULL;
 	Base tbase;
 	BoundBox bb, *bb_tmp; /* use a copy because draw_object, calls clear_mesh_caches */
 	GLuint displist=0;
@@ -1509,78 +1524,82 @@
 	lb= object_duplilist(scene, base->object);
 	// BLI_sortlist(lb, dupli_ob_sort); // might be nice to have if we have a dupli list with mixed objects.
 	
-	for(dob= lb->first; dob; dob= dob->next) {
-		if(dob->no_draw);
-		else {
-			tbase.object= dob->ob;
-			
-			/* extra service: draw the duplicator in drawtype of parent */
-			/* MIN2 for the drawtype to allow bounding box objects in groups for lods */
-			dt= tbase.object->dt;	tbase.object->dt= MIN2(tbase.object->dt, base->object->dt);
-			dtx= tbase.object->dtx; tbase.object->dtx= base->object->dtx;
-			
-			/* negative scale flag has to propagate */
-			transflag= tbase.object->transflag;
-			if(base->object->transflag & OB_NEG_SCALE)
-				tbase.object->transflag ^= OB_NEG_SCALE;
-			
-			UI_ThemeColorBlend(color, TH_BACK, 0.5);
-			
-			/* generate displist, test for new object */
-			if(use_displist==1 && ob_prev != dob->ob) {
-				use_displist= -1;
+	dob_next= lb->first;
+	while(dob_next && dob_next->no_draw) {
+		dob_next= dob_next->next;
+	}
+
+	while(draw_dupli_objects_step(&dob_prev, &dob, &dob_next)) {
+		tbase.object= dob->ob;
+
+		/* extra service: draw the duplicator in drawtype of parent */
+		/* MIN2 for the drawtype to allow bounding box objects in groups for lods */
+		dt= tbase.object->dt;	tbase.object->dt= MIN2(tbase.object->dt, base->object->dt);
+		dtx= tbase.object->dtx; tbase.object->dtx= base->object->dtx;
+
+		/* negative scale flag has to propagate */
+		transflag= tbase.object->transflag;
+		if(base->object->transflag & OB_NEG_SCALE)
+			tbase.object->transflag ^= OB_NEG_SCALE;
+
+		UI_ThemeColorBlend(color, TH_BACK, 0.5);
+
+		/* generate displist, test for new object */
+		if(dob_prev && dob_prev->ob != dob->ob) {
+			if(use_displist==1)
 				glDeleteLists(displist, 1);
-			}
-			/* generate displist */
-			if(use_displist == -1) {
 
-				/* note, since this was added, its checked dob->type==OB_DUPLIGROUP
-				 * however this is very slow, it was probably needed for the NLA
-				 * offset feature (used in group-duplicate.blend but no longer works in 2.5)
-				 * so for now it should be ok to - campbell */
+			use_displist= -1;
+		}
 
-				if(		(dob->next==NULL) || /* if this is the last no need  to make a displist */
-						(dob->ob->type == OB_LAMP) || /* lamp drawing messes with matrices, could be handled smarter... but this works */
-						(dob->type == OB_DUPLIGROUP && dob->animated) ||
-						!(bb_tmp= object_get_boundbox(dob->ob))
-				) {
-					use_displist= 0;
-				}
-				else {
-					bb= *bb_tmp; /* must make a copy  */
+		/* generate displist */
+		if(use_displist == -1) {
 
-					/* disable boundbox check for list creation */
-					object_boundbox_flag(dob->ob, OB_BB_DISABLED, 1);
-					/* need this for next part of code */
-					unit_m4(dob->ob->obmat);	/* obmat gets restored */
-					
-					displist= glGenLists(1);
-					glNewList(displist, GL_COMPILE);
-					draw_object(scene, ar, v3d, &tbase, DRAW_CONSTCOLOR);
-					glEndList();
-					
-					use_displist= 1;
-					object_boundbox_flag(dob->ob, OB_BB_DISABLED, 0);
-				}
+			/* note, since this was added, its checked dob->type==OB_DUPLIGROUP
+			 * however this is very slow, it was probably needed for the NLA
+			 * offset feature (used in group-duplicate.blend but no longer works in 2.5)
+			 * so for now it should be ok to - campbell */
+
+			if(		(dob_next==NULL || dob_next->ob != dob->ob) || /* if this is the last no need  to make a displist */
+					(dob->ob->type == OB_LAMP) || /* lamp drawing messes with matrices, could be handled smarter... but this works */
+					(dob->type == OB_DUPLIGROUP && dob->animated) ||
+					!(bb_tmp= object_get_boundbox(dob->ob))
+			) {
+				// printf("draw_dupli_objects_color: skipping displist for %s\n", dob->ob->id.name+2);
+				use_displist= 0;
 			}
-			if(use_displist) {
-				glMultMatrixf(dob->mat);
-				if(boundbox_clip(rv3d, dob->mat, &bb))
-					glCallList(displist);
-				glLoadMatrixf(rv3d->viewmat);
-			}
 			else {
-				copy_m4_m4(dob->ob->obmat, dob->mat);
+				// printf("draw_dupli_objects_color: using displist for %s\n", dob->ob->id.name+2);
+				bb= *bb_tmp; /* must make a copy  */
+
+				/* disable boundbox check for list creation */
+				object_boundbox_flag(dob->ob, OB_BB_DISABLED, 1);
+				/* need this for next part of code */
+				unit_m4(dob->ob->obmat);	/* obmat gets restored */
+
+				displist= glGenLists(1);
+				glNewList(displist, GL_COMPILE);
 				draw_object(scene, ar, v3d, &tbase, DRAW_CONSTCOLOR);
+				glEndList();
+
+				use_displist= 1;
+				object_boundbox_flag(dob->ob, OB_BB_DISABLED, 0);
 			}
-			
-			tbase.object->dt= dt;
-			tbase.object->dtx= dtx;
-			tbase.object->transflag= transflag;
+		}
+		if(use_displist) {
+			glMultMatrixf(dob->mat);
+			if(boundbox_clip(rv3d, dob->mat, &bb))
+				glCallList(displist);
+			glLoadMatrixf(rv3d->viewmat);
+		}
+		else {
+			copy_m4_m4(dob->ob->obmat, dob->mat);
+			draw_object(scene, ar, v3d, &tbase, DRAW_CONSTCOLOR);
+		}
 
-			/* record the last object drawn since dob->prev isn't reliable due to no_draw option */
-			ob_prev= dob->ob;
-		}
+		tbase.object->dt= dt;
+		tbase.object->dtx= dtx;
+		tbase.object->transflag= transflag;
 	}
 	
 	/* Transp afterdraw disabled, afterdraw only stores base pointers, and duplis can be same obj */
@@ -1869,7 +1888,7 @@
 			}
 			if((view->drawtype == OB_TEXTURE) || ((view->drawtype == OB_SOLID) && (view->flag2 & V3D_SOLID_TEX))) {
 				mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
-				
+
 				if(scene->gm.matmode == GAME_MAT_GLSL)
 					mask |= CD_MASK_ORCO;
 			}
@@ -2089,7 +2108,7 @@
 
 	/* from now on all object derived meshes check this */
 	v3d->customdata_mask= get_viewedit_datamask(CTX_wm_screen(C), scene, obact);
-	
+
 	/* shadow buffers, before we setup matrices */
 	if(draw_glsl_material(scene, NULL, v3d, v3d->drawtype))
 		gpu_update_lamps_shadows(scene, v3d);
@@ -2150,7 +2169,7 @@
 	
 	if(rv3d->rflag & RV3D_CLIPPING)
 		view3d_set_clipping(rv3d);
-	
+
 	/* draw set first */
 	if(scene->set) {
 		for(SETLOOPER(scene->set, base)) {
@@ -2171,7 +2190,7 @@
 	
 	/* extra service in layerbuttons, showing used layers */
 	v3d->lay_used = 0;
-	
+
 	/* then draw not selected and the duplis, but skip editmode object */
 	for(base= scene->base.first; base; base= base->next) {
 		v3d->lay_used |= base->lay;





More information about the Bf-blender-cvs mailing list