[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15679] branches/apricot/source: Apricot Branch

Brecht Van Lommel brechtvanlommel at pandora.be
Mon Jul 21 21:28:00 CEST 2008


Revision: 15679
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15679
Author:   blendix
Date:     2008-07-21 21:27:59 +0200 (Mon, 21 Jul 2008)

Log Message:
-----------
Apricot Branch
==============

* More refactoring related to opengl lights, material state switching.
  Also moved init_gl_stuff into the gpu module and removed the copy in
  the game engine code.
* Fixed some issues with alpha drawing of GLSL materials in the 3d
  viewport, and fix a bug with alpha + xray drawing in the same scene,
  it should first do alpha, then xray, otherwise alpha doesn't blend
  correct with solid.

Modified Paths:
--------------
    branches/apricot/source/blender/gpu/GPU_draw.h
    branches/apricot/source/blender/gpu/GPU_material.h
    branches/apricot/source/blender/gpu/intern/gpu_draw.c
    branches/apricot/source/blender/gpu/intern/gpu_material.c
    branches/apricot/source/blender/include/BSE_drawview.h
    branches/apricot/source/blender/nodes/intern/SHD_nodes/SHD_output.c
    branches/apricot/source/blender/src/drawmesh.c
    branches/apricot/source/blender/src/drawobject.c
    branches/apricot/source/blender/src/drawview.c
    branches/apricot/source/blender/src/renderwin.c
    branches/apricot/source/blender/src/sculptmode.c
    branches/apricot/source/blender/src/space.c
    branches/apricot/source/blender/src/toets.c
    branches/apricot/source/blender/src/usiblender.c
    branches/apricot/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
    branches/apricot/source/gameengine/Ketsji/KX_Scene.cpp
    branches/apricot/source/gameengine/Rasterizer/RAS_BucketManager.cpp
    branches/apricot/source/gameengine/Rasterizer/RAS_BucketManager.h
    branches/apricot/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp

Modified: branches/apricot/source/blender/gpu/GPU_draw.h
===================================================================
--- branches/apricot/source/blender/gpu/GPU_draw.h	2008-07-21 19:11:38 UTC (rev 15678)
+++ branches/apricot/source/blender/gpu/GPU_draw.h	2008-07-21 19:27:59 UTC (rev 15679)
@@ -41,24 +41,49 @@
 struct Image;
 struct Scene;
 struct Object;
-struct GPUVertexAttribs;
 
-/* OpenGL drawing functions shared with the game engine,
- * previously these were duplicated. */
+/* OpenGL drawing functions. These are also shared with
+ * the game engine, whereas they were previously duplicated. */
 
+/* Initialize */
+
+void GPU_state_init(void);
+
+/* Material drawing
+ * - first the state is initialized by a particular object and it's materials
+ * - after this, materials can be quickly enabled by their number,
+ *   GPU_enable_material returns 0 if drawing should be skipped
+ * - after drawing, the material must be disabled again */
+
+void GPU_set_object_materials(struct Scene *scene, struct Object *ob,
+	int glsl, int *do_alpha_pass);
+int GPU_enable_material(int nr, void *attribs);
+void GPU_disable_material(void);
+
+/* Lights
+ * - returns how many lights were enabled */
+
+int GPU_default_lights(void);
+int GPU_scene_object_lights(struct Scene *scene, struct Object *ob,
+	int lay, float viewmat[][4]);
+
+/* Text render */
+
 void GPU_render_text(struct MTFace *tface, int mode,
 	const char *textstr, int textlen, unsigned int *col,
 	float *v1, float *v2, float *v3, float *v4, int glattrib);
 
+/* TexFace state setting, NULL clears it */
+
 int GPU_set_tpage(struct MTFace *tface);
 
-/* Mipmap settings */
+/* Mipmap settings, these free textures on changes */
 
 void GPU_set_mipmap(int mipmap);
 void GPU_set_linear_mipmap(int linear);
 void GPU_paint_set_mipmap(int mipmap);
 
-/* Image free and update */
+/* Image opengl free and update */
 
 void GPU_paint_update_image(struct Image *ima, int x, int y, int w, int h);
 void GPU_update_images_framechange(void);
@@ -66,16 +91,6 @@
 void GPU_free_image(struct Image *ima);
 void GPU_free_images(void);
 
-/* Material drawing
- * - first the state is initialized by a particular object and it's materials
- * - after this, materials can be quickly enabled by their number
- * - after drawing, the material must be disabled again */
-
-void GPU_set_object_materials(struct Scene *scene, struct Object *ob,
-	int check_alpha, int glsl, int *has_alpha);
-int GPU_enable_material(int nr, void *attribs);
-void GPU_disable_material(void);
-
 #ifdef __cplusplus
 }
 #endif

Modified: branches/apricot/source/blender/gpu/GPU_material.h
===================================================================
--- branches/apricot/source/blender/gpu/GPU_material.h	2008-07-21 19:11:38 UTC (rev 15678)
+++ branches/apricot/source/blender/gpu/GPU_material.h	2008-07-21 19:27:59 UTC (rev 15679)
@@ -83,6 +83,13 @@
 	GPU_VIEW_NORMAL = 32
 } GPUBuiltin;
 
+typedef enum GPUBlendMode {
+	GPU_BLEND_SOLID,
+	GPU_BLEND_ALPHA,
+	GPU_BLEND_ADD,
+	GPU_BLEND_CLIPALPHA
+} GPUBlendMode;
+
 typedef struct GPUNodeStack {
 	GPUType type;
 	char *name;
@@ -107,6 +114,7 @@
 
 void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link);
 void GPU_material_enable_alpha(GPUMaterial *material);
+GPUBlendMode GPU_material_blend_mode(GPUMaterial *material);
 
 /* High level functions to create and use GPU materials */
 

Modified: branches/apricot/source/blender/gpu/intern/gpu_draw.c
===================================================================
--- branches/apricot/source/blender/gpu/intern/gpu_draw.c	2008-07-21 19:11:38 UTC (rev 15678)
+++ branches/apricot/source/blender/gpu/intern/gpu_draw.c	2008-07-21 19:27:59 UTC (rev 15679)
@@ -35,6 +35,7 @@
 #include "GL/glew.h"
 
 #include "DNA_image_types.h"
+#include "DNA_lamp_types.h"
 #include "DNA_material_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_node_types.h"
@@ -54,6 +55,7 @@
 #include "BKE_main.h"
 #include "BKE_material.h"
 #include "BKE_node.h"
+#include "BKE_object.h"
 #include "BKE_utildefines.h"
 
 #include "GPU_extensions.h"
@@ -756,8 +758,11 @@
 	Object *gob;
 	Scene *gscene;
 
+	int hasalpha[MAXMATBUF];
+	int alphapass;
+
 	int lastmatnr, lastretval;
-} GMS = {{{{0}}}, 0, {NULL}, NULL, NULL, NULL, -1, -1};
+} GMS;
 
 Material *gpu_active_node_material(Material *ma)
 {
@@ -773,18 +778,27 @@
 	return ma;
 }
 
-void GPU_set_object_materials(Scene *scene, Object *ob, int check_alpha, int glsl, int *has_alpha)
+void GPU_set_object_materials(Scene *scene, Object *ob, int glsl, int *do_alpha_pass)
 {
 	extern Material defmaterial; /* from material.c */
 	Material *ma;
-	int a;
+	GPUBlendMode blendmode;
+	int a, has_alpha;
+	
+	/* initialize state */
+	memset(&GMS, 0, sizeof(GMS));
+	GMS.lastmatnr = -1;
+	GMS.lastretval = -1;
 
-	if(has_alpha)
-		*has_alpha = 0;
-	
 	GMS.gob = ob;
 	GMS.gscene = scene;
+	GMS.totmat= ob->totcol;
 
+	GMS.alphapass = (G.vd && G.vd->transp);
+	if(do_alpha_pass)
+		*do_alpha_pass = 0;
+
+	/* no materials assigned? */
 	if(ob->totcol==0) {
 		GMS.matbuf[0][0][0]= defmaterial.r;
 		GMS.matbuf[0][0][1]= defmaterial.g;
@@ -803,12 +817,29 @@
 		GMS.gmatbuf[0]= NULL;
 	}
 	
+	/* setup materials */
 	for(a=1; a<=ob->totcol; a++) {
+		/* find a suitable material */
 		ma= give_current_material(ob, a);
 		if(!glsl) ma= gpu_active_node_material(ma);
 		if(ma==NULL) ma= &defmaterial;
 
-		if(a<MAXMATBUF) {
+		/* this shouldn't happen .. */
+		if(a>=MAXMATBUF)
+			continue;
+
+		/* create glsl material if requested */
+		if(glsl)
+			GPU_material_from_blender(GMS.gscene, ma);
+
+		if(glsl && ma->gpumaterial) {
+			/* do glsl only if creating it succeed, else fallback */
+			GMS.gmatbuf[a]= ma;
+			blendmode = GPU_material_blend_mode(ma->gpumaterial);
+			has_alpha = ELEM(blendmode, GPU_BLEND_ALPHA, GPU_BLEND_ADD);
+		}
+		else {
+			/* fixed function opengl materials */
 			if (ma->mode & MA_SHLESS) {
 				GMS.matbuf[a][0][0]= ma->r;
 				GMS.matbuf[a][0][1]= ma->g;
@@ -817,38 +848,29 @@
 				GMS.matbuf[a][0][0]= (ma->ref+ma->emit)*ma->r;
 				GMS.matbuf[a][0][1]= (ma->ref+ma->emit)*ma->g;
 				GMS.matbuf[a][0][2]= (ma->ref+ma->emit)*ma->b;
-			}
 
-			/* draw transparent, not in pick-select, nor editmode */
-			if(check_alpha) {
-				if(G.vd && G.vd->transp) {	// drawing the transparent pass
-					if(ma->alpha==1.0) GMS.matbuf[a][0][3]= 0.0;	// means skip solid
-					else GMS.matbuf[a][0][3]= ma->alpha;
-				}
-				else {	// normal pass
-					if(ma->alpha==1.0) GMS.matbuf[a][0][3]= 1.0;
-					else {
-						GMS.matbuf[a][0][3]= 0.0;	// means skip transparent
-						if(has_alpha)
-							*has_alpha= 1;			// return value, to indicate adding to after-draw queue
-					}
-				}
-			}
-			else
-				GMS.matbuf[a][0][3]= 1.0;
-			
-			if (!(ma->mode & MA_SHLESS)) {
 				GMS.matbuf[a][1][0]= ma->spec*ma->specr;
 				GMS.matbuf[a][1][1]= ma->spec*ma->specg;
 				GMS.matbuf[a][1][2]= ma->spec*ma->specb;
 				GMS.matbuf[a][1][3]= 1.0;
 			}
 
-			GMS.gmatbuf[a]= (glsl)? ma: NULL;
+			has_alpha = (ma->alpha != 1.0f);
+			if(do_alpha_pass && GMS.alphapass)
+				GMS.matbuf[a][0][3]= ma->alpha;
+			else
+				GMS.matbuf[a][0][3]= 1.0f;
 		}
+
+		/* setting do_alpha_pass = 1 indicates this object needs to be
+		 * drawn in a second alpha pass for improved blending */
+		if(do_alpha_pass) {
+			GMS.hasalpha[a] = has_alpha;
+			*do_alpha_pass |= has_alpha && !GMS.alphapass;
+		}
 	}
 
-	GMS.totmat= ob->totcol;
+	/* let's start with a clean state */
 	GPU_disable_material();
 }
 
@@ -863,43 +885,44 @@
 	if(gattribs)
 		memset(gattribs, 0, sizeof(*gattribs));
 
-	if(nr<MAXMATBUF && nr!=GMS.lastmatnr) {
-		if(GMS.gboundmat) {
-			GPU_material_unbind(GMS.gboundmat->gpumaterial);
-			GMS.gboundmat= NULL;
-		}
+	/* keep current material */
+	if(nr>=MAXMATBUF || nr==GMS.lastmatnr)
+		return GMS.lastretval;
 
-		if(gattribs) {
+	/* unbind glsl material */
+	if(GMS.gboundmat) {
+		GPU_material_unbind(GMS.gboundmat->gpumaterial);
+		GMS.gboundmat= NULL;
+	}
+
+	/* draw materials with alpha in alpha pass */
+	GMS.lastmatnr = nr;
+	GMS.lastretval = (GMS.alphapass)? GMS.hasalpha[nr]: !GMS.hasalpha[nr];
+
+	if(GMS.lastretval) {
+		if(gattribs && GMS.gmatbuf[nr]) {
+			/* bind glsl material and get attributes */
 			Material *mat = GMS.gmatbuf[nr];
 
-			if(mat) {
-				GPU_material_from_blender(GMS.gscene, mat);
-
-				if(mat->gpumaterial) {
-					GPU_material_vertex_attributes(mat->gpumaterial, gattribs);
-					GPU_material_bind(mat->gpumaterial, GMS.gob->lay);
-					GPU_material_bind_uniforms(mat->gpumaterial, GMS.gob->obmat, G.vd->viewmat, G.vd->viewinv);
-					GMS.gboundmat= mat;
-				}
-			}
+			GPU_material_vertex_attributes(mat->gpumaterial, gattribs);
+			GPU_material_bind(mat->gpumaterial, GMS.gob->lay);
+			GPU_material_bind_uniforms(mat->gpumaterial, GMS.gob->obmat, G.vd->viewmat, G.vd->viewinv);
+			GMS.gboundmat= mat;
 		}
-
-		if(!GMS.gboundmat) {
+		else {
+			/* or do fixed function opengl material */
 			glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, GMS.matbuf[nr][0]);
 			glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, GMS.matbuf[nr][1]);
-			GMS.lastmatnr = nr;
-			GMS.lastretval= GMS.matbuf[nr][0][3]!=0.0;
-			
-			/* matbuf alpha: 0.0 = skip draw, 1.0 = no blending, else blend */
-			if(GMS.matbuf[nr][0][3]!= 0.0 && GMS.matbuf[nr][0][3]!= 1.0) {
-				glEnable(GL_BLEND);
-			}
-			else
-				glDisable(GL_BLEND);
 		}
+
+		/* enable alpha blending if needed */
+		if(GMS.alphapass)
+			glEnable(GL_BLEND);
+		else
+			glDisable(GL_BLEND);
 	}
-	
-	return GMS.lastretval; /* TODO: what is this used for */
+
+	return GMS.lastretval;
 }
 
 void GPU_disable_material(void)
@@ -913,3 +936,220 @@
 	}
 }
 
+/* Lights */
+
+int GPU_default_lights(void)
+{
+	int a, count = 0;
+	
+	/* initialize */
+	if(U.light[0].flag==0 && U.light[1].flag==0 && U.light[2].flag==0) {
+		U.light[0].flag= 1;
+		U.light[0].vec[0]= -0.3; U.light[0].vec[1]= 0.3; U.light[0].vec[2]= 0.9;
+		U.light[0].col[0]= 0.8; U.light[0].col[1]= 0.8; U.light[0].col[2]= 0.8;
+		U.light[0].spec[0]= 0.5; U.light[0].spec[1]= 0.5; U.light[0].spec[2]= 0.5;
+		U.light[0].spec[3]= 1.0;
+		
+		U.light[1].flag= 0;
+		U.light[1].vec[0]= 0.5; U.light[1].vec[1]= 0.5; U.light[1].vec[2]= 0.1;
+		U.light[1].col[0]= 0.4; U.light[1].col[1]= 0.4; U.light[1].col[2]= 0.8;
+		U.light[1].spec[0]= 0.3; U.light[1].spec[1]= 0.3; U.light[1].spec[2]= 0.5;
+		U.light[1].spec[3]= 1.0;
+	
+		U.light[2].flag= 0;
+		U.light[2].vec[0]= 0.3; U.light[2].vec[1]= -0.3; U.light[2].vec[2]= -0.2;
+		U.light[2].col[0]= 0.8; U.light[2].col[1]= 0.5; U.light[2].col[2]= 0.4;

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list