[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [42503] trunk/blender/source/blender: Fix #29520: issue drawing with VBO + GLSL + alpha pass.

Brecht Van Lommel brechtvanlommel at pandora.be
Wed Dec 7 23:03:49 CET 2011


Revision: 42503
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=42503
Author:   blendix
Date:     2011-12-07 22:03:49 +0000 (Wed, 07 Dec 2011)
Log Message:
-----------
Fix #29520: issue drawing with VBO + GLSL + alpha pass. Includes some refactoring
to hopefully make alpha material drawing code more clear.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
    trunk/blender/source/blender/editors/space_view3d/drawobject.c
    trunk/blender/source/blender/gpu/GPU_draw.h
    trunk/blender/source/blender/gpu/intern/gpu_draw.c

Modified: trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c	2011-12-07 21:55:59 UTC (rev 42502)
+++ trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c	2011-12-07 22:03:49 UTC (rev 42503)
@@ -1243,11 +1243,8 @@
 						}
 					}
 				}
-				if(!dodraw) {
-					continue;
-				}
 
-				if( numdata != 0 ) {
+				if(dodraw && numdata != 0 ) {
 					offset = 0;
 					if(attribs.totorco) {
 						copy_v3_v3((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v1]);
@@ -1289,7 +1286,7 @@
 				}
 				curface++;
 				if(mface->v4) {
-					if( numdata != 0 ) {
+					if(dodraw && numdata != 0 ) {
 						offset = 0;
 						if(attribs.totorco) {
 							copy_v3_v3((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v3]);

Modified: trunk/blender/source/blender/editors/space_view3d/drawobject.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/drawobject.c	2011-12-07 21:55:59 UTC (rev 42502)
+++ trunk/blender/source/blender/editors/space_view3d/drawobject.c	2011-12-07 22:03:49 UTC (rev 42503)
@@ -265,7 +265,7 @@
 	return (scene->gm.matmode == GAME_MAT_GLSL) && (dt > OB_SOLID);
 }
 
-static int check_material_alpha(Base *base, int glsl)
+static int check_alpha_pass(Base *base)
 {
 	if(base->flag & OB_FROMDUPLI)
 		return 0;
@@ -273,7 +273,7 @@
 	if(G.f & G_PICKSEL)
 		return 0;
 	
-	return (glsl || (base->object->dtx & OB_DRAWTRANSP));
+	return (base->object->dtx & OB_DRAWTRANSP);
 }
 
 	/***/
@@ -3294,7 +3294,7 @@
 	Object *obedit= scene->obedit;
 	Mesh *me= ob->data;
 	EditMesh *em= me->edit_mesh;
-	int do_alpha_pass= 0, drawlinked= 0, retval= 0, glsl, check_alpha, i;
+	int do_alpha_after= 0, drawlinked= 0, retval= 0, glsl, check_alpha, i;
 
 	/* If we are drawing shadows and any of the materials don't cast a shadow,
 	 * then don't draw the object */
@@ -3339,11 +3339,11 @@
 		/* don't create boundbox here with mesh_get_bb(), the derived system will make it, puts deformed bb's OK */
 		if(me->totface<=4 || ED_view3d_boundbox_clip(rv3d, ob->obmat, (ob->bb)? ob->bb: me->bb)) {
 			glsl = draw_glsl_material(scene, ob, v3d, dt);
-			check_alpha = check_material_alpha(base, glsl);
+			check_alpha = check_alpha_pass(base);
 
 			if(dt==OB_SOLID || glsl) {
 				GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl,
-					(check_alpha)? &do_alpha_pass: NULL);
+					(check_alpha)? &do_alpha_after: NULL);
 			}
 
 			draw_mesh_fancy(scene, ar, v3d, rv3d, base, dt, flag);
@@ -3355,7 +3355,7 @@
 	}
 	
 	/* GPU_begin_object_materials checked if this is needed */
-	if(do_alpha_pass) {
+	if(do_alpha_after) {
 		if(ob->dtx & OB_DRAWXRAY) {
 			add_view3d_after(&v3d->afterdraw_xraytransp, base, flag);
 		}

Modified: trunk/blender/source/blender/gpu/GPU_draw.h
===================================================================
--- trunk/blender/source/blender/gpu/GPU_draw.h	2011-12-07 21:55:59 UTC (rev 42502)
+++ trunk/blender/source/blender/gpu/GPU_draw.h	2011-12-07 22:03:49 UTC (rev 42503)
@@ -69,7 +69,7 @@
  * - after drawing, the material must be disabled again */
 
 void GPU_begin_object_materials(struct View3D *v3d, struct RegionView3D *rv3d, 
-	struct Scene *scene, struct Object *ob, int glsl, int *do_alpha_pass);
+	struct Scene *scene, struct Object *ob, int glsl, int *do_alpha_after);
 void GPU_end_object_materials(void);
 
 int GPU_enable_material(int nr, void *attribs);

Modified: trunk/blender/source/blender/gpu/intern/gpu_draw.c
===================================================================
--- trunk/blender/source/blender/gpu/intern/gpu_draw.c	2011-12-07 21:55:59 UTC (rev 42502)
+++ trunk/blender/source/blender/gpu/intern/gpu_draw.c	2011-12-07 22:03:49 UTC (rev 42503)
@@ -942,7 +942,7 @@
 
 	GPUBlendMode *alphablend;
 	GPUBlendMode alphablend_fixed[FIXEDMAT];
-	int alphapass;
+	int use_alpha_pass, is_alpha_pass;
 
 	int lastmatnr, lastretval;
 	GPUBlendMode lastalphablend;
@@ -993,7 +993,7 @@
 	return ma;
 }
 
-void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, Object *ob, int glsl, int *do_alpha_pass)
+void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, Object *ob, int glsl, int *do_alpha_after)
 {
 	Material *ma;
 	GPUMaterial *gpumat;
@@ -1015,9 +1015,15 @@
 	GMS.gviewmat= rv3d->viewmat;
 	GMS.gviewinv= rv3d->viewinv;
 
-	GMS.alphapass = (v3d && v3d->transp);
-	if(do_alpha_pass)
-		*do_alpha_pass = 0;
+	/* alpha pass setup. there's various cases to handle here:
+	   * object transparency on: only solid materials draw in the first pass,
+	   and only transparent in the second 'alpha' pass.
+	   * object transparency off: for glsl we draw both in a single pass, and
+	   for solid we don't use transparency at all. */
+	GMS.use_alpha_pass = (do_alpha_after != NULL);
+	GMS.is_alpha_pass = (v3d && v3d->transp);
+	if(GMS.use_alpha_pass)
+		*do_alpha_after = 0;
 	
 	if(GMS.totmat > FIXEDMAT) {
 		GMS.matbuf= MEM_callocN(sizeof(GPUMaterialFixed)*GMS.totmat, "GMS.matbuf");
@@ -1064,20 +1070,23 @@
 			/* fixed function opengl materials */
 			gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob, new_shading_nodes);
 
-			alphablend = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
-			if(do_alpha_pass && GMS.alphapass)
+			if(GMS.use_alpha_pass) {
 				GMS.matbuf[a].diff[3]= ma->alpha;
-			else
+				alphablend = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
+			}
+			else {
 				GMS.matbuf[a].diff[3]= 1.0f;
+				alphablend = GPU_BLEND_SOLID;
+			}
 		}
 
-		/* setting do_alpha_pass = 1 indicates this object needs to be
+		/* setting do_alpha_after = 1 indicates this object needs to be
 		 * drawn in a second alpha pass for improved blending */
-		if(do_alpha_pass) {
-			GMS.alphablend[a]= alphablend;
-			if(ELEM3(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ADD, GPU_BLEND_ALPHA_SORT) && !GMS.alphapass)
-				*do_alpha_pass= 1;
-		}
+		if(GMS.use_alpha_pass && !GMS.is_alpha_pass)
+			if(ELEM3(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ADD, GPU_BLEND_ALPHA_SORT))
+				*do_alpha_after= 1;
+
+		GMS.alphablend[a]= alphablend;
 	}
 
 	/* let's start with a clean state */
@@ -1122,20 +1131,26 @@
 
 	/* unbind glsl material */
 	if(GMS.gboundmat) {
-		if(GMS.alphapass) glDepthMask(0);
+		if(GMS.is_alpha_pass) glDepthMask(0);
 		GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat));
 		GMS.gboundmat= NULL;
 	}
 
 	/* draw materials with alpha in alpha pass */
 	GMS.lastmatnr = nr;
-	GMS.lastretval = ELEM(GMS.alphablend[nr], GPU_BLEND_SOLID, GPU_BLEND_CLIP);
-	if(GMS.alphapass)
-		GMS.lastretval = !GMS.lastretval;
+	GMS.lastretval = 1;
 
+	if(GMS.use_alpha_pass) {
+		GMS.lastretval = ELEM(GMS.alphablend[nr], GPU_BLEND_SOLID, GPU_BLEND_CLIP);
+		if(GMS.is_alpha_pass)
+			GMS.lastretval = !GMS.lastretval;
+	}
+	else
+		GMS.lastretval = !GMS.is_alpha_pass;
+
 	if(GMS.lastretval) {
 		/* for alpha pass, use alpha blend */
-		alphablend = (GMS.alphapass)? GPU_BLEND_ALPHA: GPU_BLEND_SOLID;
+		alphablend = GMS.alphablend[nr];
 
 		if(gattribs && GMS.gmatbuf[nr]) {
 			/* bind glsl material and get attributes */
@@ -1152,7 +1167,7 @@
 			if(mat->game.alpha_blend != GPU_BLEND_SOLID)
 				alphablend= mat->game.alpha_blend;
 
-			if(GMS.alphapass) glDepthMask(1);
+			if(GMS.is_alpha_pass) glDepthMask(1);
 		}
 		else {
 			/* or do fixed function opengl material */
@@ -1188,7 +1203,7 @@
 	GMS.lastretval= 1;
 
 	if(GMS.gboundmat) {
-		if(GMS.alphapass) glDepthMask(0);
+		if(GMS.is_alpha_pass) glDepthMask(0);
 		GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat));
 		GMS.gboundmat= NULL;
 	}




More information about the Bf-blender-cvs mailing list