[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [31927] branches/soc-2010-nicolasbishop/ source/blender: == Multires ==
Nicholas Bishop
nicholasbishop at gmail.com
Wed Sep 15 00:33:29 CEST 2010
Revision: 31927
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=31927
Author: nicholasbishop
Date: 2010-09-15 00:33:29 +0200 (Wed, 15 Sep 2010)
Log Message:
-----------
== Multires ==
Drawing optimization for VBO: only create one index buffer object for a single grid level
Modified Paths:
--------------
branches/soc-2010-nicolasbishop/source/blender/blenlib/intern/pbvh.c
branches/soc-2010-nicolasbishop/source/blender/gpu/GPU_buffers.h
branches/soc-2010-nicolasbishop/source/blender/gpu/intern/gpu_buffers.c
Modified: branches/soc-2010-nicolasbishop/source/blender/blenlib/intern/pbvh.c
===================================================================
--- branches/soc-2010-nicolasbishop/source/blender/blenlib/intern/pbvh.c 2010-09-14 16:45:24 UTC (rev 31926)
+++ branches/soc-2010-nicolasbishop/source/blender/blenlib/intern/pbvh.c 2010-09-14 22:33:29 UTC (rev 31927)
@@ -455,8 +455,7 @@
{
if(!G.background) {
node->draw_buffers =
- GPU_build_grid_buffers(bvh->grids, node->prim_indices,
- node->totprim, bvh->gridsize);
+ GPU_build_grid_buffers(bvh->gridsize);
}
node->flag |= PBVH_UpdateVertBuffers|PBVH_UpdateColorBuffers;
}
Modified: branches/soc-2010-nicolasbishop/source/blender/gpu/GPU_buffers.h
===================================================================
--- branches/soc-2010-nicolasbishop/source/blender/gpu/GPU_buffers.h 2010-09-14 16:45:24 UTC (rev 31926)
+++ branches/soc-2010-nicolasbishop/source/blender/gpu/GPU_buffers.h 2010-09-14 22:33:29 UTC (rev 31927)
@@ -147,8 +147,7 @@
struct PBVH *bvh,
struct PBVHNode *node,
enum DMDrawFlags flags);
-GPU_Buffers *GPU_build_grid_buffers(struct DMGridData **grids,
- int *grid_indices, int totgrid, int gridsize);
+GPU_Buffers *GPU_build_grid_buffers(int gridsize);
void GPU_update_grid_vert_buffers(GPU_Buffers *buffersb, struct DMGridData **grids,
int *grid_indices, int totgrid, int gridsize,
struct GridKey *gridkey, int smooth);
Modified: branches/soc-2010-nicolasbishop/source/blender/gpu/intern/gpu_buffers.c
===================================================================
--- branches/soc-2010-nicolasbishop/source/blender/gpu/intern/gpu_buffers.c 2010-09-14 16:45:24 UTC (rev 31926)
+++ branches/soc-2010-nicolasbishop/source/blender/gpu/intern/gpu_buffers.c 2010-09-14 22:33:29 UTC (rev 31927)
@@ -430,7 +430,9 @@
GLuint *ptex;
int totptex;
- unsigned int tot_tri, tot_quad;
+ int use_grids;
+ unsigned int tot_tri;
+ int gridsize;
};
static void delete_buffer(GLuint *buf)
@@ -955,90 +957,122 @@
//printf("node updated %p\n", buffers_v);
}
-GPU_Buffers *GPU_build_grid_buffers(DMGridData **grids,
- int *grid_indices, int totgrid,
- int gridsize)
+static int gpu_build_grid_ibo(int gridsize)
{
- GPU_Buffers *buffers;
- int i, j, k, totquad, offset= 0;
+ GLuint index_buf;
+ int totndx, use_ushorts, i, j;
+ unsigned short *quads_ushort;
+ unsigned int *quads_uint;
- buffers = MEM_callocN(sizeof(GPU_Buffers), "GPU_Buffers");
+ /* count the number of quads */
+ totndx = (gridsize-1)*(gridsize-1) * 4;
- /* Count the number of quads */
- totquad= (gridsize-1)*(gridsize-1)*totgrid;
-
- /* Generate index buffer object */
+ /* generate index buffer object */
if(GL_ARB_vertex_buffer_object && !(U.gameflags & USER_DISABLE_VBO))
- glGenBuffersARB(1, &buffers->index_buf);
+ glGenBuffersARB(1, &index_buf);
- if(buffers->index_buf) {
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
+ /* bad failure */
+ if(!index_buf)
+ return 0;
- if(totquad < USHRT_MAX) {
- unsigned short *quad_data;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, index_buf);
- buffers->index_type = GL_UNSIGNED_SHORT;
- glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
- sizeof(unsigned short) * totquad * 4, NULL, GL_STATIC_DRAW_ARB);
+ /* if possible, restrict indices to unsigned shorts to save space */
+ use_ushorts = totndx < USHRT_MAX;
- /* 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+1;
- *(quad_data++)= offset + j*gridsize + k;
- *(quad_data++)= offset + (j+1)*gridsize + k;
- *(quad_data++)= offset + (j+1)*gridsize + k+1;
- }
- }
+ /* allocate empty buffer data */
+ glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
+ (use_ushorts ? sizeof(unsigned short) :
+ sizeof(unsigned int)) * totndx,
+ NULL, GL_STATIC_DRAW_ARB);
- offset += gridsize*gridsize;
- }
- glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
- }
- else
- delete_buffer(&buffers->index_buf);
+ /* map the buffer into memory */
+ quads_ushort = (void*)(quads_uint =
+ glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
+ GL_WRITE_ONLY_ARB));
+ if(!quads_ushort) {
+ delete_buffer(&index_buf);
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+ return 0;
+ }
+
+ /* fill the quad buffer */
+ for(i = 0; i < gridsize-1; ++i) {
+ for(j = 0; j < gridsize-1; ++j) {
+#define IBO_ASSIGN(val) do { \
+ if(use_ushorts) \
+ *(quads_ushort++) = val; \
+ else \
+ *(quads_uint++) = val; \
+ } while(0)
+
+ IBO_ASSIGN(i*gridsize + j+1);
+ IBO_ASSIGN(i*gridsize + j);
+ IBO_ASSIGN((i+1)*gridsize + j);
+ IBO_ASSIGN((i+1)*gridsize + j+1);
+
+#undef IBO_ASSIGN
}
- 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);
+ glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
- /* Fill the quad buffer */
- quad_data = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ return index_buf;
+}
- 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+1;
- *(quad_data++)= offset + j*gridsize + k;
- *(quad_data++)= offset + (j+1)*gridsize + k;
- *(quad_data++)= offset + (j+1)*gridsize + k+1;
- }
- }
+/* cache grid IBOs, uses reference counting to free them */
+static int gpu_grid_ibo(int gridsize, int release)
+{
+ /* {reference count, buffer id} */
+ static unsigned int grid_buffers[32][2], inited = 0;
+ int lvl, i;
- offset += gridsize*gridsize;
- }
- glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
- }
- else
- delete_buffer(&buffers->index_buf);
+ if(!inited) {
+ memset(grid_buffers, 0, sizeof(int)*32*2);
+ inited = 1;
+ }
+
+ for(i = 0, --gridsize; i < 32; ++i) {
+ if(gridsize & (1 << i)) {
+ lvl = i;
+ break;
}
+ }
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+ if(release) {
+ if(grid_buffers[lvl][0] > 0) {
+ --grid_buffers[lvl][0];
+ if(!grid_buffers[lvl][0])
+ delete_buffer(&grid_buffers[lvl][1]);
+ }
+ else
+ fprintf(stderr, "gpu_grid_ibo: bad reference count\n");
}
+ else {
+ ++grid_buffers[lvl][0];
+ if(!grid_buffers[lvl][1])
+ grid_buffers[lvl][1] = gpu_build_grid_ibo(gridsize + 1);
+ }
+
+ return grid_buffers[lvl][1];
+}
+
+GPU_Buffers *GPU_build_grid_buffers(int gridsize)
+{
+ GPU_Buffers *buffers;
+
+ buffers = MEM_callocN(sizeof(GPU_Buffers), "GPU_Buffers");
+
+ buffers->index_buf = gpu_grid_ibo(gridsize, 0);
+ buffers->gridsize = gridsize;
+ buffers->use_grids = 1;
+
/* Build VBO */
if(buffers->index_buf)
glGenBuffersARB(1, &buffers->vert_buf);
- buffers->tot_quad = totquad;
-
return buffers;
}
@@ -1259,6 +1293,78 @@
glDisable(GL_COLOR_MATERIAL);
}
+static void gpu_draw_grids(GPU_Buffers *buffers, PBVH *pbvh, PBVHNode *node, DMDrawFlags flags)
+{
+ int g, totgrid, *grid_indices, gridsize, offset, totndx;
+
+ BLI_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid,
+ NULL, &gridsize, NULL, NULL, NULL);
+
+ totndx = (gridsize-1)*(gridsize-1) * 4;
+
+ for(g = 0; g < totgrid; ++g) {
+ offset = gridsize * gridsize * g;
+
+ glVertexPointer(3, GL_FLOAT, sizeof(GridVBO),
+ (char*)0 + offset*sizeof(GridVBO) + offsetof(GridVBO, co));
+ glNormalPointer(GL_FLOAT, sizeof(GridVBO),
+ (char*)0 + offset*sizeof(GridVBO) + offsetof(GridVBO, no));
+
+ if(buffers->color_buf) {
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->color_buf);
+ glColorPointer(3, GL_UNSIGNED_BYTE, 0, (char*)0 + (offset * 3));
+ }
+
+ if(buffers->uv_buf) {
+ CustomData *fdata;
+ GridToFace *gtf;
+ MPtex *mptex, *pt;
+ MPtexSubface *subface;
+ GridToFace *grid_face_map;
+
+ /* note: code here assumes there's only one
+ ptex subface per node */
+
+ BLI_pbvh_get_customdata(pbvh, NULL, &fdata);
+ mptex = CustomData_get_layer(fdata, CD_MPTEX);
+ grid_face_map = BLI_pbvh_get_grid_face_map(pbvh);
+
+ gtf = &grid_face_map[grid_indices[0]];
+ pt = &mptex[gtf->face];
+ subface = &pt->subfaces[gtf->offset];
+
+ glEnable(GL_TEXTURE_2D);
+ if(flags & DM_DRAW_PTEX_TEXELS) {
+ gpu_bind_ptex_pattern();
+ if(subface->flag & MPTEX_SUBFACE_SELECTED)
+ glColor3ub(255, 255, 255);
+ else if(subface->flag & MPTEX_SUBFACE_MASKED)
+ glColor3ub(96, 96, 96);
+ else
+ glColor3ub(128, 128, 128);
+ }
+ else {
+ glBindTexture(GL_TEXTURE_2D, buffers->ptex[0]);
+
+ if(subface->flag & MPTEX_SUBFACE_MASKED)
+ glColor3ub(128, 128, 128);
+ else
+ glColor3ub(255, 255, 255);
+ }
+
+ if(subface->flag & MPTEX_SUBFACE_HIDDEN)
+ continue;
+
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->uv_buf);
+ glTexCoordPointer(2, GL_FLOAT, 0, (void*)0);
+ }
+
+ glDrawElements(GL_QUADS, totndx,
+ (totndx < USHRT_MAX ?
+ GL_UNSIGNED_SHORT : GL_UNSIGNED_INT), 0);
+ }
+}
+
void GPU_draw_buffers(GPU_Buffers *buffers, PBVH *pbvh, PBVHNode *node, DMDrawFlags flags)
{
glShadeModel((flags & DM_DRAW_FULLY_SMOOTH) ? GL_SMOOTH: GL_FLAT);
@@ -1283,65 +1389,8 @@
glEnable(GL_COLOR_MATERIAL);
}
- if(buffers->tot_quad) {
- int skip = 0;
-
- glVertexPointer(3, GL_FLOAT, sizeof(GridVBO), (void*)offsetof(GridVBO, co));
- glNormalPointer(GL_FLOAT, sizeof(GridVBO), (void*)offsetof(GridVBO, no));
- if(buffers->color_buf) {
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->color_buf);
- glColorPointer(3, GL_UNSIGNED_BYTE, 0, (void*)0);
- }
- if(buffers->uv_buf) {
- int *grid_indices;
- CustomData *fdata;
- GridToFace *gtf;
- MPtex *mptex, *pt;
- MPtexSubface *subface;
- GridToFace *grid_face_map;
-
- /* note: code here assumes there's only one
- ptex subface per node */
-
- BLI_pbvh_get_customdata(pbvh, NULL, &fdata);
- mptex = CustomData_get_layer(fdata, CD_MPTEX);
- grid_face_map = BLI_pbvh_get_grid_face_map(pbvh);
- BLI_pbvh_node_get_grids(pbvh, node,
- &grid_indices, NULL, NULL, NULL,
- NULL, NULL, NULL);
-
- gtf = &grid_face_map[grid_indices[0]];
- pt = &mptex[gtf->face];
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list