diff options
-rw-r--r-- | source/blender/gpu/intern/gpu_buffers.c | 102 |
1 files changed, 65 insertions, 37 deletions
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 770b8fc0adf..23bc79e4187 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -1453,73 +1453,95 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, DMGridData **grids, #define FILL_QUAD_BUFFER(type_) \ { \ type_ *quad_data; \ - int offset = 0; \ - int i, j, k; \ + int i, j; \ \ glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, \ - sizeof(type_) * totquad * 4, NULL, \ + sizeof(type_) * (*totquad) * 4, NULL, \ GL_STATIC_DRAW_ARB); \ \ /* 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(i = 0; i < gridsize-1; ++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; \ - } \ + *(quad_data++)= i*gridsize + j+1; \ + *(quad_data++)= i*gridsize + j; \ + *(quad_data++)= (i+1)*gridsize + j; \ + *(quad_data++)= (i+1)*gridsize + j+1; \ } \ - \ - offset += gridsize*gridsize; \ } \ glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); \ } \ else { \ - glDeleteBuffersARB(1, &buffers->index_buf); \ - buffers->index_buf = 0; \ + glDeleteBuffersARB(1, &buffer); \ + buffer = 0; \ } \ } /* end FILL_QUAD_BUFFER */ -GPU_Buffers *GPU_build_grid_buffers(int totgrid, int gridsize) +static GLuint gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned *totquad) { - GPU_Buffers *buffers; - int totquad; - - buffers = MEM_callocN(sizeof(GPU_Buffers), "GPU_Buffers"); + static int prev_gridsize = -1; + static GLenum prev_index_type = 0; + static GLuint buffer = 0; + static unsigned prev_totquad; + + /* VBO is disabled; delete the previous buffer (if it exists) and + return an invalid handle */ + if(!GLEW_ARB_vertex_buffer_object || (U.gameflags & USER_DISABLE_VBO)) { + if(buffer) + glDeleteBuffersARB(1, &buffer); + return 0; + } - /* Count the number of quads */ - totquad= (gridsize-1)*(gridsize-1)*totgrid; + /* VBO is already built */ + if(buffer && prev_gridsize == gridsize) { + *index_type = prev_index_type; + *totquad = prev_totquad; + return buffer; + } - /* Generate index buffer object */ - if(GLEW_ARB_vertex_buffer_object && !(U.gameflags & USER_DISABLE_VBO)) - glGenBuffersARB(1, &buffers->index_buf); + /* Build new VBO */ + glGenBuffersARB(1, &buffer); + if(buffer) { + *totquad= (gridsize-1)*(gridsize-1); - if(buffers->index_buf) { - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffer); - if(totquad < USHRT_MAX) { - buffers->index_type = GL_UNSIGNED_SHORT; + if(*totquad < USHRT_MAX) { + *index_type = GL_UNSIGNED_SHORT; FILL_QUAD_BUFFER(unsigned short); } else { - buffers->index_type = GL_UNSIGNED_INT; + *index_type = GL_UNSIGNED_INT; FILL_QUAD_BUFFER(unsigned int); } glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); } - /* Build VBO */ + prev_gridsize = gridsize; + prev_index_type = *index_type; + prev_totquad = *totquad; + return buffer; +} + +GPU_Buffers *GPU_build_grid_buffers(int totgrid, int gridsize) +{ + GPU_Buffers *buffers; + + buffers = MEM_callocN(sizeof(GPU_Buffers), "GPU_Buffers"); + + /* Build index VBO */ + buffers->index_buf = gpu_get_grid_buffer(gridsize, &buffers->index_type, &buffers->tot_quad); + buffers->totgrid = totgrid; + buffers->gridsize = gridsize; + + /* Build coord/normal VBO */ if(buffers->index_buf) glGenBuffersARB(1, &buffers->vert_buf); - buffers->tot_quad = totquad; - return buffers; } @@ -1642,10 +1664,16 @@ void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial) glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf); if(buffers->tot_quad) { - glVertexPointer(3, GL_FLOAT, sizeof(DMGridData), (void*)offsetof(DMGridData, co)); - glNormalPointer(GL_FLOAT, sizeof(DMGridData), (void*)offsetof(DMGridData, no)); - - glDrawElements(GL_QUADS, buffers->tot_quad * 4, buffers->index_type, 0); + unsigned offset = 0; + int i; + for(i = 0; i < buffers->totgrid; i++) { + glVertexPointer(3, GL_FLOAT, sizeof(DMGridData), offset + (char*)offsetof(DMGridData, co)); + glNormalPointer(GL_FLOAT, sizeof(DMGridData), offset + (char*)offsetof(DMGridData, no)); + + glDrawElements(GL_QUADS, buffers->tot_quad * 4, buffers->index_type, 0); + + offset += buffers->gridsize * buffers->gridsize * sizeof(DMGridData); + } } else { glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat), (void*)offsetof(VertexBufferFormat, co)); @@ -1674,7 +1702,7 @@ void GPU_free_buffers(GPU_Buffers *buffers) if(buffers) { if(buffers->vert_buf) glDeleteBuffersARB(1, &buffers->vert_buf); - if(buffers->index_buf) + if(buffers->index_buf && buffers->tot_tri) glDeleteBuffersARB(1, &buffers->index_buf); MEM_freeN(buffers); |