[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [38241] trunk/blender/source/blender: == GPU Buffers ==

Nicholas Bishop nicholasbishop at gmail.com
Fri Jul 8 21:58:03 CEST 2011


Revision: 38241
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=38241
Author:   nicholasbishop
Date:     2011-07-08 19:58:02 +0000 (Fri, 08 Jul 2011)
Log Message:
-----------
== GPU Buffers ==

This patch attempts to clean up and document the GPU buffers
code. There are a few bug fixes as well.

Patch reviewed here: http://codereview.appspot.com/4631052/

Summary:

* Bugfix: make GPU_buffer_copy_normal convert from shorts to floats
  correctly, also fixed the use of cached face normal CustomData.

* Bugfix: changed the `mat_nr' field of GPUBufferMaterial from char to
  short.

* Changed color buffer setup to not alloc a temporary copy of color
  data, just passes the MCol data in directly.

* Changed the GPU buffer pool code to make clearer what operates
  specifically on the global pool.

* Lots of refactoring for GPU_drawobject_new; should operate mostly
  the same (except got rid of one unecessary allocation), just split
  into more functions and without macros now.

* Converted some #defines into enumerations.

* Made some stuff private, pulled out of header file.

* Deleted unused function GPU_buffer_pool_free_unused().

* Removed GPU_interleaved_setup and related #defines. (I think this
  was used for editmode VBOs, but those were disabled.)

* Added lots of comments.

* Added a few comments in the code signed `--nicholas' to note places
  where I am unsure about design or usage, would be good to address
  these better.

* Code formatting changed to be more consistent with the rest of
  Blender.

* Renamed some fields and variables to be more consistent with
  Blender's naming conventions.

* Renamed some fields and variables to use more descriptive names,
  e.g. renamed `redir' to `mat_orig_to_new'.

* Removed print outs with DEBUG_VBO -- don't feel too strongly about
  this one, just not used elsewhere in Blender, could be easily added
  back if others disagree though.

* Moved the PBVH drawing code down to the bottom of the file, before
  was sitting in the middle of the other VBO code

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
    trunk/blender/source/blender/gpu/GPU_buffers.h
    trunk/blender/source/blender/gpu/intern/gpu_buffers.c
    trunk/blender/source/blender/windowmanager/intern/wm_init_exit.c

Modified: trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c	2011-07-08 18:09:51 UTC (rev 38240)
+++ trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c	2011-07-08 19:58:02 UTC (rev 38241)
@@ -284,8 +284,10 @@
 	else {	/* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
 		GPU_vertex_setup(dm);
 		if( !GPU_buffer_legacy(dm) ) {
-			if(dm->drawObject->nelements)	glDrawArrays(GL_POINTS,0, dm->drawObject->nelements);
-			else							glDrawArrays(GL_POINTS,0, dm->drawObject->nlooseverts);
+			if(dm->drawObject->tot_triangle_point)
+				glDrawArrays(GL_POINTS,0, dm->drawObject->tot_triangle_point);
+			else
+				glDrawArrays(GL_POINTS,0, dm->drawObject->tot_loose_point);
 		}
 		GPU_buffer_unbind();
 	}
@@ -547,9 +549,10 @@
 		GPU_normal_setup( dm );
 		if( !GPU_buffer_legacy(dm) ) {
 			glShadeModel(GL_SMOOTH);
-			for( a = 0; a < dm->drawObject->nmaterials; a++ ) {
+			for( a = 0; a < dm->drawObject->totmaterial; a++ ) {
 				if( setMaterial(dm->drawObject->materials[a].mat_nr+1, NULL) )
-					glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start, dm->drawObject->materials[a].end-dm->drawObject->materials[a].start);
+					glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start,
+						     dm->drawObject->materials[a].totpoint);
 			}
 		}
 		GPU_buffer_unbind( );
@@ -629,13 +632,13 @@
 		GPU_color_setup(dm);
 		if( !GPU_buffer_legacy(dm) ) {
 			glShadeModel(GL_SMOOTH);
-			glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->nelements);
+			glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->tot_triangle_point);
 
 			if( useTwoSided ) {
 				GPU_color4_upload(dm,cp2);
 				GPU_color_setup(dm);
 				glCullFace(GL_FRONT);
-				glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->nelements);
+				glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->tot_triangle_point);
 				glCullFace(GL_BACK);
 			}
 		}
@@ -787,8 +790,8 @@
 			
 			glShadeModel( GL_SMOOTH );
 			lastFlag = 0;
-			for(i = 0; i < dm->drawObject->nelements/3; i++) {
-				int actualFace = dm->drawObject->faceRemap[i];
+			for(i = 0; i < dm->drawObject->tot_triangle_point/3; i++) {
+				int actualFace = dm->drawObject->triangle_to_mface[i];
 				int flag = 1;
 
 				if(drawParams) {
@@ -819,13 +822,13 @@
 					startFace = i;
 				}
 			}
-			if( startFace < dm->drawObject->nelements/3 ) {
+			if( startFace < dm->drawObject->tot_triangle_point/3 ) {
 				if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */
 					if (lastFlag==1 && col)
 						GPU_color_switch(1);
 					else
 						GPU_color_switch(0);
-					glDrawArrays(GL_TRIANGLES,startFace*3,dm->drawObject->nelements-startFace*3);
+					glDrawArrays(GL_TRIANGLES, startFace*3, dm->drawObject->tot_triangle_point - startFace*3);
 				}
 			}
 		}
@@ -935,7 +938,7 @@
 		if( useColors && mc )
 			GPU_color_setup(dm);
 		if( !GPU_buffer_legacy(dm) ) {
-			int tottri = dm->drawObject->nelements/3;
+			int tottri = dm->drawObject->tot_triangle_point/3;
 			glShadeModel(GL_SMOOTH);
 			
 			if(tottri == 0) {
@@ -947,17 +950,17 @@
 			}
 			else {
 				/* we need to check if the next material changes */
-				int next_actualFace= dm->drawObject->faceRemap[0];
+				int next_actualFace= dm->drawObject->triangle_to_mface[0];
 				
 				for( i = 0; i < tottri; i++ ) {
-					//int actualFace = dm->drawObject->faceRemap[i];
+					//int actualFace = dm->drawObject->triangle_to_mface[i];
 					int actualFace = next_actualFace;
 					MFace *mface= mf + actualFace;
 					int drawSmooth= (mface->flag & ME_SMOOTH);
 					int draw = 1;
 
 					if(i != tottri-1)
-						next_actualFace= dm->drawObject->faceRemap[i+1];
+						next_actualFace= dm->drawObject->triangle_to_mface[i+1];
 
 					orig= (index==NULL) ? actualFace : index[actualFace];
 
@@ -1129,9 +1132,9 @@
 		GPU_normal_setup(dm);
 
 		if( !GPU_buffer_legacy(dm) ) {
-			for( i = 0; i < dm->drawObject->nelements/3; i++ ) {
+			for( i = 0; i < dm->drawObject->tot_triangle_point/3; i++ ) {
 
-				a = dm->drawObject->faceRemap[i];
+				a = dm->drawObject->triangle_to_mface[i];
 
 				mface = mf + a;
 				new_matnr = mface->mat_nr + 1;
@@ -1153,7 +1156,7 @@
 
 							if( numdata != 0 ) {
 
-								GPU_buffer_free(buffer, NULL);
+								GPU_buffer_free(buffer);
 
 								buffer = NULL;
 							}
@@ -1193,7 +1196,7 @@
 						}
 						if( numdata != 0 ) {
 							elementsize = GPU_attrib_element_size( datatypes, numdata );
-							buffer = GPU_buffer_alloc( elementsize*dm->drawObject->nelements, NULL );
+							buffer = GPU_buffer_alloc( elementsize*dm->drawObject->tot_triangle_point);
 							if( buffer == NULL ) {
 								GPU_buffer_unbind();
 								dm->drawObject->legacy = 1;
@@ -1202,7 +1205,7 @@
 							varray = GPU_buffer_lock_stream(buffer);
 							if( varray == NULL ) {
 								GPU_buffer_unbind();
-								GPU_buffer_free(buffer, NULL);
+								GPU_buffer_free(buffer);
 								dm->drawObject->legacy = 1;
 								return;
 							}
@@ -1341,7 +1344,7 @@
 			}
 			GPU_buffer_unbind();
 		}
-		GPU_buffer_free( buffer, NULL );
+		GPU_buffer_free(buffer);
 	}
 
 	glShadeModel(GL_FLAT);

Modified: trunk/blender/source/blender/gpu/GPU_buffers.h
===================================================================
--- trunk/blender/source/blender/gpu/GPU_buffers.h	2011-07-08 18:09:51 UTC (rev 38240)
+++ trunk/blender/source/blender/gpu/GPU_buffers.h	2011-07-08 19:58:02 UTC (rev 38241)
@@ -37,8 +37,6 @@
 #ifndef __GPU_BUFFERS_H__
 #define __GPU_BUFFERS_H__
 
-#define MAX_FREE_GPU_BUFFERS 8
-
 #ifdef _DEBUG
 /*#define DEBUG_VBO(X) printf(X)*/
 #define DEBUG_VBO(X)
@@ -46,112 +44,92 @@
 #define DEBUG_VBO(X)
 #endif
 
-#ifdef _DEBUG
-#define ERROR_VBO(X) printf(X)
-#else
-#define ERROR_VBO(X)
-#endif
-
 struct DerivedMesh;
 struct DMGridData;
 struct GHash;
 struct DMGridData;
+struct GPUVertPointLink;
 
-/* V - vertex, N - normal, T - uv, C - color
-   F - float, UB - unsigned byte */
-#define GPU_BUFFER_INTER_V3F	1
-#define GPU_BUFFER_INTER_N3F	2
-#define GPU_BUFFER_INTER_T2F	3
-#define GPU_BUFFER_INTER_C3UB	4
-#define GPU_BUFFER_INTER_C4UB	5
-#define GPU_BUFFER_INTER_END	-1
-
-typedef struct GPUBuffer
-{
+typedef struct GPUBuffer {
 	int size;	/* in bytes */
 	void *pointer;	/* used with vertex arrays */
 	unsigned int id;	/* used with vertex buffer objects */
 } GPUBuffer;
 
-/* stores deleted buffers so that new buffers wouldn't have to 
-be recreated that often. */
-typedef struct GPUBufferPool
-{
-	int size;		/* number of allocated buffers stored */
-	int maxsize;	/* size of the array */
-	GPUBuffer **buffers;
-} GPUBufferPool;
+typedef struct GPUBufferMaterial {
+	/* range of points used for this material */
+	int start;
+	int totpoint;
 
-typedef struct GPUBufferMaterial
-{
-	int start;	/* at which vertex in the buffer the material starts */
-	int end;	/* at which vertex it ends */
-	char mat_nr;
+	/* original material index */
+	short mat_nr;
 } GPUBufferMaterial;
 
-typedef struct IndexLink {
-	int element;
-	struct IndexLink *next;
-} IndexLink;
+/* meshes are split up by material since changing materials requires
+   GL state changes that can't occur in the middle of drawing an
+   array.
 
-typedef struct GPUDrawObject
-{
-	GPUBuffer *vertices;
+   some simplifying assumptions are made:
+   * all quads are treated as two triangles.
+   * no vertex sharing is used; each triangle gets its own copy of the
+     vertices it uses (this makes it easy to deal with a vertex used
+     by faces with different properties, such as smooth/solid shading,
+     different MCols, etc.)
+
+   to avoid confusion between the original MVert vertices and the
+   arrays of OpenGL vertices, the latter are referred to here and in
+   the source as `points'. similarly, the OpenGL triangles generated
+   for MFaces are referred to as triangles rather than faces.
+ */
+typedef struct GPUDrawObject {
+	GPUBuffer *points;
 	GPUBuffer *normals;
 	GPUBuffer *uv;
 	GPUBuffer *colors;
 	GPUBuffer *edges;
 	GPUBuffer *uvedges;
 
-	int	*faceRemap;			/* at what index was the face originally in DerivedMesh */
-	IndexLink *indices;		/* given an index, find all elements using it */
-	IndexLink *indexMem;	/* for faster memory allocation/freeing */
-	int indexMemUsage;		/* how many are already allocated */
+	/* for each triangle, the original MFace index */
+	int *triangle_to_mface;
+
+	/* for each original vertex, the list of related points */
+	struct GPUVertPointLink *vert_points;
+	/* storage for the vert_points lists */
+	struct GPUVertPointLink *vert_points_mem;
+	int vert_points_usage;
+	
 	int colType;
 
 	GPUBufferMaterial *materials;
+	int totmaterial;
+	
+	int tot_triangle_point;
+	int tot_loose_point;
+	
+	/* caches of the original DerivedMesh values */
+	int totvert;
+	int totedge;
 
-	int nmaterials;
-	int nelements;	/* (number of faces) * 3 */
-	int nlooseverts;
-	int nedges;
-	int nindices;
-	int legacy;	/* if there was a failure allocating some buffer, use old rendering code */
-
+	/* if there was a failure allocating some buffer, use old
+	   rendering code */
+	int legacy;
 } GPUDrawObject;
 
 /* used for GLSL materials */
-typedef struct GPUAttrib
-{
+typedef struct GPUAttrib {
 	int index;
 	int size;
 	int type;
 } GPUAttrib;
 
-GPUBufferPool *GPU_buffer_pool_new(void);
-void GPU_buffer_pool_free( GPUBufferPool *pool );
-void GPU_buffer_pool_free_unused( GPUBufferPool *pool );
+void GPU_global_buffer_pool_free(void);
 
-GPUBuffer *GPU_buffer_alloc( int size, GPUBufferPool *pool );
-void GPU_buffer_free( GPUBuffer *buffer, GPUBufferPool *pool );
+GPUBuffer *GPU_buffer_alloc(int size);
+void GPU_buffer_free(GPUBuffer *buffer);
 
 GPUDrawObject *GPU_drawobject_new( struct DerivedMesh *dm );
 void GPU_drawobject_free( struct DerivedMesh *dm );
 
-/* Buffers for non-DerivedMesh drawing */
-void *GPU_build_mesh_buffers(struct GHash *map, struct MVert *mvert,
-			struct MFace *mface, int *face_indices,
-			int totface, int *vert_indices, int uniq_verts,
-			int totvert);
-void GPU_update_mesh_buffers(void *buffers, struct MVert *mvert,
-			int *vert_indices, int totvert);
-void *GPU_build_grid_buffers(struct DMGridData **grids,
-	int *grid_indices, int totgrid, int gridsize);
-void GPU_update_grid_buffers(void *buffers_v, struct DMGridData **grids,
-	int *grid_indices, int totgrid, int gridsize, int smooth);
-void GPU_draw_buffers(void *buffers);
-void GPU_free_buffers(void *buffers);
-
 /* called before drawing */

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list