diff options
author | Antony Riakiotakis <kalast@gmail.com> | 2015-08-03 20:08:50 +0300 |
---|---|---|
committer | Antony Riakiotakis <kalast@gmail.com> | 2015-08-03 20:09:21 +0300 |
commit | 2411027a7996170188c49e4eac0a6762f3a2599f (patch) | |
tree | 2a2ef6a61e21b1cdeef861065c23e700008977f8 /source/blender/gpu/intern/gpu_buffers.c | |
parent | 7667ad2d4e616ea0d412ac63e76c220a7106d065 (diff) |
Multires sculpting drawing optimization:
Use OpenGL 3.2 extension ARB_draw_elements_base_vertex, which allows us
to add offset in index buffer indices automatically. This should reduce
the number of draw calls significantly.
We may have some errors on the Mac with VBO setting off.
OSX OpenGL extensions don't play well with vertex arrays.
Will test that more later.
We might also use a full element buffer here, like we do when hiding
some quads, but this approach keeps the memory savings intended
originally.
Diffstat (limited to 'source/blender/gpu/intern/gpu_buffers.c')
-rw-r--r-- | source/blender/gpu/intern/gpu_buffers.c | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 16dfa184f47..997f294ce17 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -1121,6 +1121,9 @@ struct GPU_PBVH_Buffers { GPUBuffer *vert_buf, *index_buf, *index_buf_fast; GLenum index_type; + int *baseelemarray; + void **baseindex; + /* mesh pointers in case buffer allocation fails */ const MPoly *mpoly; const MLoop *mloop; @@ -1681,6 +1684,18 @@ GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid, if (buffers->index_buf) buffers->vert_buf = GPU_buffer_alloc(sizeof(VertexBufferFormat) * totgrid * key->grid_area, false); + if (GLEW_ARB_draw_elements_base_vertex) { + int i; + buffers->baseelemarray = MEM_mallocN(sizeof(int) * totgrid * 2, "GPU_PBVH_Buffers.baseelemarray"); + buffers->baseindex = MEM_mallocN(sizeof(void *) * totgrid, "GPU_PBVH_Buffers.baseindex"); + for (i = 0; i < totgrid; i++) { + buffers->baseelemarray[i] = buffers->tot_quad * 6; + buffers->baseelemarray[i + totgrid] = i * key->grid_area; + buffers->baseindex[i] = buffers->index_buf && !buffers->index_buf->use_vbo ? + buffers->index_buf->pointer : NULL; + } + } + return buffers; } @@ -2012,21 +2027,40 @@ void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial, if (buffers->tot_quad) { const char *offset = base; - int i, last = (buffers->has_hidden || do_fast) ? 1 : buffers->totgrid; - for (i = 0; i < last; i++) { + const bool drawall = !(buffers->has_hidden || do_fast); + + if (GLEW_ARB_draw_elements_base_vertex && drawall) { + glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat), offset + offsetof(VertexBufferFormat, co)); glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat), offset + offsetof(VertexBufferFormat, no)); glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat), offset + offsetof(VertexBufferFormat, color)); - - if (do_fast) - glDrawElements(GL_TRIANGLES, buffers->totgrid * 6, buffers->index_type, index_base); - else - glDrawElements(GL_TRIANGLES, buffers->tot_quad * 6, buffers->index_type, index_base); - offset += buffers->gridkey.grid_area * sizeof(VertexBufferFormat); + glMultiDrawElementsBaseVertex(GL_TRIANGLES, buffers->baseelemarray, buffers->index_type, + (const void * const *)buffers->baseindex, + buffers->totgrid, &buffers->baseelemarray[buffers->totgrid]); + } + else { + int i, last = drawall ? buffers->totgrid : 1; + + /* we could optimize this to one draw call, but it would need more memory */ + for (i = 0; i < last; i++) { + glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat), + offset + offsetof(VertexBufferFormat, co)); + glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat), + offset + offsetof(VertexBufferFormat, no)); + glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat), + offset + offsetof(VertexBufferFormat, color)); + + if (do_fast) + glDrawElements(GL_TRIANGLES, buffers->totgrid * 6, buffers->index_type, index_base); + else + glDrawElements(GL_TRIANGLES, buffers->tot_quad * 6, buffers->index_type, index_base); + + offset += buffers->gridkey.grid_area * sizeof(VertexBufferFormat); + } } } else if (buffers->tot_tri) { @@ -2112,6 +2146,10 @@ void GPU_free_pbvh_buffers(GPU_PBVH_Buffers *buffers) GPU_buffer_free(buffers->index_buf); if (buffers->index_buf_fast) GPU_buffer_free(buffers->index_buf_fast); + if (buffers->baseelemarray) + MEM_freeN(buffers->baseelemarray); + if (buffers->baseindex) + MEM_freeN(buffers->baseindex); MEM_freeN(buffers); } |