[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [25245] branches/sculpt25/source/blender/ gpu/intern/gpu_buffers.c: Sculpt Branch:

Brecht Van Lommel brecht at blender.org
Wed Dec 9 16:20:47 CET 2009


Revision: 25245
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=25245
Author:   blendix
Date:     2009-12-09 16:20:47 +0100 (Wed, 09 Dec 2009)

Log Message:
-----------
Sculpt Branch:
* Fallback code in case VBO allocation fails.

Modified Paths:
--------------
    branches/sculpt25/source/blender/gpu/intern/gpu_buffers.c

Modified: branches/sculpt25/source/blender/gpu/intern/gpu_buffers.c
===================================================================
--- branches/sculpt25/source/blender/gpu/intern/gpu_buffers.c	2009-12-09 15:13:03 UTC (rev 25244)
+++ branches/sculpt25/source/blender/gpu/intern/gpu_buffers.c	2009-12-09 15:20:47 UTC (rev 25245)
@@ -386,8 +386,22 @@
 } VertexBufferFormat;
 
 typedef struct {
+	/* opengl buffer handles */
 	GLuint vert_buf, index_buf;
 	GLenum index_type;
+
+	/* mesh pointers in case buffer allocation fails */
+	MFace *mface;
+	MVert *mvert;
+	int *face_indices;
+	int totface;
+
+	/* grid pointers */
+	DMGridData **grids;
+	int *grid_indices;
+	int totgrid;
+	int gridsize;
+
 	unsigned int tot_tri, tot_quad;
 } GPU_Buffers;
 
@@ -398,21 +412,34 @@
 	VertexBufferFormat *vert_data;
 	int i;
 
-	/* Build VBO */
-	glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
-	glBufferDataARB(GL_ARRAY_BUFFER_ARB,
-		     sizeof(VertexBufferFormat) * totvert,
-		     NULL, GL_STATIC_DRAW_ARB);
-	vert_data = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+	if(buffers->vert_buf) {
+		/* Build VBO */
+		glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
+		glBufferDataARB(GL_ARRAY_BUFFER_ARB,
+				 sizeof(VertexBufferFormat) * totvert,
+				 NULL, GL_STATIC_DRAW_ARB);
+		vert_data = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
 
-	for(i = 0; i < totvert; ++i) {
-		MVert *v = mvert + vert_indices[i];
-		VertexBufferFormat *out = vert_data + i;
+		if(vert_data) {
+			for(i = 0; i < totvert; ++i) {
+				MVert *v = mvert + vert_indices[i];
+				VertexBufferFormat *out = vert_data + i;
 
-		copy_v3_v3(out->co, v->co);
-		memcpy(out->no, v->no, sizeof(short) * 3);
+				copy_v3_v3(out->co, v->co);
+				memcpy(out->no, v->no, sizeof(short) * 3);
+			}
+
+			glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+		}
+		else {
+			glDeleteBuffersARB(1, &buffers->vert_buf);
+			buffers->vert_buf = 0;
+		}
+
+		glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
 	}
-	glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+
+	buffers->mvert = mvert;
 }
 
 void *GPU_build_mesh_buffers(GHash *map, MVert *mvert, MFace *mface,
@@ -431,47 +458,61 @@
 	for(i = 0, tottri = 0; i < totface; ++i)
 		tottri += mface[face_indices[i]].v4 ? 2 : 1;
 
-	/* Generate index buffer object */
-	glGenBuffersARB(1, &buffers->index_buf);
-	glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
-	glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
-		     sizeof(unsigned short) * tottri * 3, NULL, GL_STATIC_DRAW_ARB);
+	if(buffers->index_buf) {
+		/* Generate index buffer object */
+		glGenBuffersARB(1, &buffers->index_buf);
+		glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
+		glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
+				 sizeof(unsigned short) * tottri * 3, NULL, GL_STATIC_DRAW_ARB);
 
-	/* Fill the triangle buffer */
-	tri_data = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
-	for(i = 0; i < totface; ++i) {
-		MFace *f = mface + face_indices[i];
-		int v[3] = {f->v1, f->v2, f->v3};
+		/* Fill the triangle buffer */
+		tri_data = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+		if(tri_data) {
+			for(i = 0; i < totface; ++i) {
+				MFace *f = mface + face_indices[i];
+				int v[3] = {f->v1, f->v2, f->v3};
 
-		for(j = 0; j < (f->v4 ? 2 : 1); ++j) {
-			for(k = 0; k < 3; ++k) {
-				void *value, *key = SET_INT_IN_POINTER(v[k]);
-				int vbo_index;
+				for(j = 0; j < (f->v4 ? 2 : 1); ++j) {
+					for(k = 0; k < 3; ++k) {
+						void *value, *key = SET_INT_IN_POINTER(v[k]);
+						int vbo_index;
 
-				value = BLI_ghash_lookup(map, key);
-				vbo_index = GET_INT_FROM_POINTER(value);
+						value = BLI_ghash_lookup(map, key);
+						vbo_index = GET_INT_FROM_POINTER(value);
 
-				if(vbo_index < 0) {
-					vbo_index = -vbo_index +
-						tot_uniq_verts - 1;
+						if(vbo_index < 0) {
+							vbo_index = -vbo_index +
+								tot_uniq_verts - 1;
+						}
+
+						*tri_data = vbo_index;
+						++tri_data;
+					}
+					v[0] = f->v4;
+					v[1] = f->v1;
+					v[2] = f->v3;
 				}
-
-				*tri_data = vbo_index;
-				++tri_data;
 			}
-			v[0] = f->v4;
-			v[1] = f->v1;
-			v[2] = f->v3;
+			glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
 		}
+		else {
+			glDeleteBuffersARB(1, &buffers->index_buf);
+			buffers->index_buf = 0;
+		}
+
+		glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
 	}
-	glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
 
-	/* Build VBO */
-	glGenBuffersARB(1, &buffers->vert_buf);
+	if(buffers->vert_buf)
+		glGenBuffersARB(1, &buffers->vert_buf);
 	GPU_update_mesh_buffers(buffers, mvert, vert_indices, totvert);
 
 	buffers->tot_tri = tottri;
 
+	buffers->mface = mface;
+	buffers->face_indices = face_indices;
+	buffers->totface = totface;
+
 	return buffers;
 }
 
@@ -485,19 +526,32 @@
 	totvert= gridsize*gridsize*totgrid;
 
 	/* Build VBO */
-	glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
-	glBufferDataARB(GL_ARRAY_BUFFER_ARB,
-		     sizeof(DMGridData) * totvert,
-		     NULL, GL_STATIC_DRAW_ARB);
-	vert_data = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
-
-	for(i = 0; i < totgrid; ++i) {
-		DMGridData *grid= grids[grid_indices[i]];
-		memcpy(vert_data, grid, sizeof(DMGridData)*gridsize*gridsize);
-		vert_data += gridsize*gridsize;
+	if(buffers->vert_buf) {
+		glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
+		glBufferDataARB(GL_ARRAY_BUFFER_ARB,
+				 sizeof(DMGridData) * totvert,
+				 NULL, GL_STATIC_DRAW_ARB);
+		vert_data = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+		if(vert_data) {
+			for(i = 0; i < totgrid; ++i) {
+				DMGridData *grid= grids[grid_indices[i]];
+				memcpy(vert_data, grid, sizeof(DMGridData)*gridsize*gridsize);
+				vert_data += gridsize*gridsize;
+			}
+			glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+		}
+		else {
+			glDeleteBuffersARB(1, &buffers->vert_buf);
+			buffers->vert_buf = 0;
+		}
+		glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
 	}
-	glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
 
+	buffers->grids = grids;
+	buffers->grid_indices = grid_indices;
+	buffers->totgrid = totgrid;
+	buffers->gridsize = gridsize;
+
 	//printf("node updated %p\n", buffers_v);
 }
 
@@ -514,57 +568,75 @@
 
 	/* Generate index buffer object */
 	glGenBuffersARB(1, &buffers->index_buf);
-	glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
+	if(buffers->index_buf) {
+		glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
 
-	if(totquad < USHRT_MAX) {
-		unsigned short *quad_data;
+		if(totquad < USHRT_MAX) {
+			unsigned short *quad_data;
 
-		buffers->index_type = GL_UNSIGNED_SHORT;
-		glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
-				 sizeof(unsigned short) * totquad * 4, NULL, GL_STATIC_DRAW_ARB);
+			buffers->index_type = GL_UNSIGNED_SHORT;
+			glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
+					 sizeof(unsigned short) * totquad * 4, NULL, GL_STATIC_DRAW_ARB);
 
-		/* Fill the quad buffer */
-		quad_data = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
-		for(i = 0; i < totgrid; ++i) {
-			for(j = 0; j < gridsize-1; ++j) {
-				for(k = 0; k < gridsize-1; ++k) {
-					*(quad_data++)= offset + j*gridsize + k;
-					*(quad_data++)= offset + (j+1)*gridsize + k;
-					*(quad_data++)= offset + (j+1)*gridsize + k+1;
-					*(quad_data++)= offset + j*gridsize + k+1;
+			/* Fill the quad buffer */
+			quad_data = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+			if(quad_data) {
+				for(i = 0; i < totgrid; ++i) {
+					for(j = 0; j < gridsize-1; ++j) {
+						for(k = 0; k < gridsize-1; ++k) {
+							*(quad_data++)= offset + j*gridsize + k;
+							*(quad_data++)= offset + (j+1)*gridsize + k;
+							*(quad_data++)= offset + (j+1)*gridsize + k+1;
+							*(quad_data++)= offset + j*gridsize + k+1;
+						}
+					}
+
+					offset += gridsize*gridsize;
 				}
+				glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
 			}
-
-			offset += gridsize*gridsize;
+			else {
+				glDeleteBuffersARB(1, &buffers->index_buf);
+				buffers->index_buf = 0;
+			}
 		}
-		glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
-	}
-	else {
-		unsigned int *quad_data;
+		else {
+			unsigned int *quad_data;
 
-		buffers->index_type = GL_UNSIGNED_INT;
-		glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
-				 sizeof(unsigned int) * totquad * 4, NULL, GL_STATIC_DRAW_ARB);
+			buffers->index_type = GL_UNSIGNED_INT;
+			glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
+					 sizeof(unsigned int) * totquad * 4, NULL, GL_STATIC_DRAW_ARB);
 
-		/* Fill the quad buffer */
-		quad_data = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
-		for(i = 0; i < totgrid; ++i) {
-			for(j = 0; j < gridsize-1; ++j) {
-				for(k = 0; k < gridsize-1; ++k) {
-					*(quad_data++)= offset + j*gridsize + k;
-					*(quad_data++)= offset + (j+1)*gridsize + k;
-					*(quad_data++)= offset + (j+1)*gridsize + k+1;
-					*(quad_data++)= offset + j*gridsize + k+1;
+			/* Fill the quad buffer */
+			quad_data = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+
+			if(quad_data) {
+				for(i = 0; i < totgrid; ++i) {
+					for(j = 0; j < gridsize-1; ++j) {
+						for(k = 0; k < gridsize-1; ++k) {
+							*(quad_data++)= offset + j*gridsize + k;
+							*(quad_data++)= offset + (j+1)*gridsize + k;
+							*(quad_data++)= offset + (j+1)*gridsize + k+1;
+							*(quad_data++)= offset + j*gridsize + k+1;
+						}
+					}
+
+					offset += gridsize*gridsize;
 				}
+				glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
 			}
+			else {
+				glDeleteBuffersARB(1, &buffers->index_buf);
+				buffers->index_buf = 0;
+			}
+		}
 
-			offset += gridsize*gridsize;
-		}
-		glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
+		glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
 	}
 
 	/* Build VBO */
-	glGenBuffersARB(1, &buffers->vert_buf);
+	if(buffers->index_buf)
+		glGenBuffersARB(1, &buffers->vert_buf);
 	GPU_update_grid_buffers(buffers, grids, grid_indices, totgrid, gridsize);
 
 	buffers->tot_quad = totquad;
@@ -576,21 +648,71 @@
 {
 	GPU_Buffers *buffers = buffers_v;
 
-	glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
-	glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
+	if(buffers->vert_buf && buffers->index_buf) {
+		glEnableClientState(GL_VERTEX_ARRAY);
+		glEnableClientState(GL_NORMAL_ARRAY);
 
-	if(buffers->tot_quad) {
-		glVertexPointer(3, GL_FLOAT, sizeof(DMGridData), 0);
-		glNormalPointer(GL_FLOAT, sizeof(DMGridData), (void*)offsetof(DMGridData, no));
+		glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
+		glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list