[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20758] branches/soc-2009-imbusy: improved buffer allocator, starting to split derived mesh into required buffers

Lukas Steiblys imbusy at imbusy.org
Tue Jun 9 17:31:17 CEST 2009


Revision: 20758
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20758
Author:   imbusy
Date:     2009-06-09 17:31:17 +0200 (Tue, 09 Jun 2009)

Log Message:
-----------
improved buffer allocator, starting to split derived mesh into required buffers

Modified Paths:
--------------
    branches/soc-2009-imbusy/projectfiles_vc9/blender/gpu/BL_gpu.vcproj
    branches/soc-2009-imbusy/source/blender/gpu/gpu_buffers.h
    branches/soc-2009-imbusy/source/blender/gpu/intern/gpu_buffers.c

Modified: branches/soc-2009-imbusy/projectfiles_vc9/blender/gpu/BL_gpu.vcproj
===================================================================
--- branches/soc-2009-imbusy/projectfiles_vc9/blender/gpu/BL_gpu.vcproj	2009-06-09 14:53:19 UTC (rev 20757)
+++ branches/soc-2009-imbusy/projectfiles_vc9/blender/gpu/BL_gpu.vcproj	2009-06-09 15:31:17 UTC (rev 20758)
@@ -474,7 +474,7 @@
 			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
 			>
 			<File
-				RelativePath=".\gpu_buffers.c"
+				RelativePath="..\..\..\source\blender\gpu\intern\gpu_buffers.c"
 				>
 			</File>
 			<File
@@ -507,7 +507,7 @@
 			Filter="h;hpp;hxx;hm;inl"
 			>
 			<File
-				RelativePath=".\gpu_buffers.h"
+				RelativePath="..\..\..\source\blender\gpu\gpu_buffers.h"
 				>
 			</File>
 			<File

Modified: branches/soc-2009-imbusy/source/blender/gpu/gpu_buffers.h
===================================================================
--- branches/soc-2009-imbusy/source/blender/gpu/gpu_buffers.h	2009-06-09 14:53:19 UTC (rev 20757)
+++ branches/soc-2009-imbusy/source/blender/gpu/gpu_buffers.h	2009-06-09 15:31:17 UTC (rev 20758)
@@ -35,6 +35,8 @@
 
 #define MAX_FREE_GPU_BUFFERS 8
 
+struct DerivedMesh;
+
 typedef struct GPUBuffer
 {
 	int size;	/* in bytes */
@@ -52,10 +54,38 @@
 	GPUBuffer* buffers[MAX_FREE_GPU_BUFFERS];
 } GPUBufferPool;
 
+typedef struct GPUBufferMaterial
+{
+	int start;	/* at which vertex in the buffer the material starts */
+	int end;	/* at which vertex it ends */
+	char mat_nr;
+} GPUBufferMaterial;
+
+typedef struct GPUDrawObject
+{
+	GPUBuffer *vertices;
+	GPUBuffer *normals;
+	GPUBuffer *uv;
+	GPUBuffer *colors;
+
+	GPUBufferMaterial *materials;
+
+	int nmaterials;
+	int nelements;
+} GPUDrawObject;
+
 GPUBufferPool *GPU_buffer_pool_new();
 void GPU_buffer_pool_free( GPUBufferPool *pool );
 
 GPUBuffer *GPU_buffer_alloc( int size, GPUBufferPool *pool );
 void GPU_buffer_free( GPUBuffer *buffer, GPUBufferPool *pool );
 
+GPUDrawObject *GPU_drawobject_new( struct DerivedMesh *dm );
+void GPU_drawobject_free( GPUDrawObject *object );
+
+GPUBuffer *GPU_buffer_vertex( struct DerivedMesh *dm, GPUDrawObject *object );
+GPUBuffer *GPU_buffer_normal( struct DerivedMesh *dm, GPUDrawObject *object );
+GPUBuffer *GPU_buffer_color( struct DerivedMesh *dm, GPUDrawObject *object );
+GPUBuffer *GPU_buffer_uv( struct DerivedMesh *dm, GPUDrawObject *object );
+
 #endif

Modified: branches/soc-2009-imbusy/source/blender/gpu/intern/gpu_buffers.c
===================================================================
--- branches/soc-2009-imbusy/source/blender/gpu/intern/gpu_buffers.c	2009-06-09 14:53:19 UTC (rev 20757)
+++ branches/soc-2009-imbusy/source/blender/gpu/intern/gpu_buffers.c	2009-06-09 15:31:17 UTC (rev 20758)
@@ -30,13 +30,18 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
+#include <string.h>
+
 #include "GL/glew.h"
 
 #include "gpu_buffers.h"
 #include "MEM_guardedalloc.h"
+#include "BKE_DerivedMesh.h"
+#include "DNA_meshdata_types.h"
 
 /* -1 - undefined, 0 - vertex arrays, 1 - VBOs */
 int useVBOs = -1;
+GPUBufferPool *globalPool = 0;
 
 GPUBufferPool *GPU_buffer_pool_new()
 {
@@ -84,6 +89,25 @@
 	pool->size--;
 }
 
+void GPU_buffer_pool_delete_last( GPUBufferPool *pool )
+{
+	int last;
+
+	while( pool->start < 0 )
+		pool->start += MAX_FREE_GPU_BUFFERS;
+	last = (pool->start+pool->size)%MAX_FREE_GPU_BUFFERS;
+
+	if( useVBOs ) {
+		glDeleteBuffersARB(1,&pool->buffers[last]->id);
+		MEM_freeN( pool->buffers[last] );
+	}
+	else {
+		MEM_freeN( pool->buffers[last]->pointer );
+		MEM_freeN( pool->buffers[last] );
+	}
+	pool->size--;
+}
+
 GPUBuffer *GPU_buffer_alloc( int size, GPUBufferPool *pool )
 {
 	int i;
@@ -117,6 +141,13 @@
 		}
 		else {
 			allocated->pointer = MEM_mallocN(size, "GPU_buffer_alloc_vertexarray");
+			while( allocated->pointer == 0 && pool->size > 0 ) {
+				GPU_buffer_pool_delete_last(pool);
+				allocated->pointer = MEM_mallocN(size, "GPU_buffer_alloc_vertexarray");
+			}
+			if( allocated->pointer == 0 && pool->size == 0 ) {
+				/* report an out of memory error. not sure how to do that */
+			}
 		}
 	}
 	else {
@@ -130,23 +161,144 @@
 {
 	int place;
 
+	if( buffer == 0 )
+		return;
+
 	while( pool->start < 0 )
 		pool->start += MAX_FREE_GPU_BUFFERS;
 	place = (pool->start-1 + MAX_FREE_GPU_BUFFERS)%MAX_FREE_GPU_BUFFERS;
 
 	/* free the last used buffer in the queue if no more space */
 	if( pool->size == MAX_FREE_GPU_BUFFERS ) {
-		if( useVBOs ) {
-			glDeleteBuffersARB(1,&pool->buffers[place]->id);
-			MEM_freeN( pool->buffers[place] );
+		GPU_buffer_pool_delete_last( pool );
+	}
+
+	pool->start = place;
+	pool->buffers[place] = buffer;
+}
+
+GPUDrawObject *GPU_drawobject_new( DerivedMesh *dm )
+{
+	GPUDrawObject *object;
+	MVert *mvert;
+	MFace *mface;
+	int numverts[256];	/* material number is an 8-bit char so there's at most 256 materials */
+	int i;
+	int curmat, curverts;
+
+	object = MEM_mallocN(sizeof(GPUDrawObject),"GPU_drawobject_new");
+	memset(object,0,sizeof(GPUDrawObject));
+
+	memset(numverts,0,sizeof(int)*256);
+
+	mvert = dm->getVertArray(dm);
+	mface = dm->getFaceArray(dm);
+
+	for( i=0; i < dm->getNumFaces(dm); i++ ) {
+		if( mface[i].v4 )
+			numverts[mface[i].mat_nr] += 6;	/* split every quad into two triangles */
+		else
+			numverts[mface[i].mat_nr] += 3;
+	}
+
+	//float *array = MEM_calloc(dm->getNumVerts(dm)*sizeof(float)*3); for(i = 0; i < dm->getNumVerts(dm); i++) { VECCOPY(array[i], mvert[i].co);}
+
+	for( i = 0; i < 256; i++ ) {
+		if( numverts[i] > 0 ) {
+			object->nmaterials++;
+			object->nelements += numverts[i];
 		}
-		else {
-			MEM_freeN( pool->buffers[place]->pointer );
-			MEM_freeN( pool->buffers[place] );
+	}
+	object->materials = MEM_mallocN(sizeof(GPUBufferMaterial)*object->nmaterials,"GPU_drawobject_new_materials");
+
+	curmat = curverts = 0;
+	for( i = 0; i < 256; i++ ) {
+		if( numverts[i] > 0 ) {
+			object->materials[curmat].mat_nr = i;
+			object->materials[curmat].start = curverts;
+			object->materials[curmat].end = curverts+numverts[i];
+			curverts += numverts[i];
+			curmat++;
 		}
-		pool->size--;
 	}
 
-	pool->start = place;
-	pool->buffers[pool->start] = buffer;
+	return object;
 }
+
+void GPU_drawobject_free( GPUDrawObject *object )
+{
+	if( object == 0 )
+		return;
+
+	MEM_freeN(object->materials);
+
+	GPU_buffer_free( object->vertices, globalPool );
+	GPU_buffer_free( object->normals, globalPool );
+	GPU_buffer_free( object->uv, globalPool );
+	GPU_buffer_free( object->colors, globalPool );
+
+	MEM_freeN(object);
+}
+
+GPUBuffer *GPU_buffer_vertex( DerivedMesh *dm, GPUDrawObject *object )
+{
+	GPUBuffer *buffer;
+	MVert *mvert;
+	MFace *mface;
+	float *varray;
+	int start;
+	int redir[256];
+	int *index;
+	int i;
+
+	index = MEM_mallocN(sizeof(int)*object->nmaterials,"GPU_buffer_vertex");
+	for( i = 0; i < object->nmaterials; i++ )
+	{
+		index[i] = object->materials[i].start;
+		redir[object->materials[i].mat_nr] = i;
+	}
+	mvert = dm->getVertArray(dm);
+	mface = dm->getFaceArray(dm);
+
+	buffer = GPU_buffer_alloc(sizeof(float)*3*object->nelements,globalPool);
+
+	if( useVBOs ) {
+		printf("GPU_buffer_vertex VBO not implemented yet");
+	}
+	else {
+		varray = buffer->pointer;
+		for( i=0; i < dm->getNumFaces(dm); i++ ) {
+			start = index[redir[mface[i].mat_nr]];
+			if( mface[i].v4 )
+				index[redir[mface[i].mat_nr]] += 18;
+			else
+				index[redir[mface[i].mat_nr]] += 9;
+
+			varray[start] = mvert[mface[i].v1].co[0];
+			varray[start+1] = mvert[mface[i].v1].co[1];
+			varray[start+2] = mvert[mface[i].v1].co[2];
+			varray[start+3] = mvert[mface[i].v2].co[0];
+			varray[start+4] = mvert[mface[i].v2].co[1];
+			varray[start+5] = mvert[mface[i].v2].co[2];
+			varray[start+6] = mvert[mface[i].v3].co[0];
+			varray[start+7] = mvert[mface[i].v3].co[1];
+			varray[start+8] = mvert[mface[i].v3].co[2];
+
+			if( mface[i].v4 ) {
+				varray[start+9] = mvert[mface[i].v3].co[0];
+				varray[start+10] = mvert[mface[i].v3].co[1];
+				varray[start+11] = mvert[mface[i].v3].co[2];
+				varray[start+12] = mvert[mface[i].v4].co[0];
+				varray[start+13] = mvert[mface[i].v4].co[1];
+				varray[start+14] = mvert[mface[i].v4].co[2];
+				varray[start+15] = mvert[mface[i].v1].co[0];
+				varray[start+16] = mvert[mface[i].v1].co[1];
+				varray[start+17] = mvert[mface[i].v1].co[2];
+			}
+		}
+	}
+
+	MEM_freeN(index);
+
+	return buffer;
+}
\ No newline at end of file





More information about the Bf-blender-cvs mailing list