Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntony Riakiotakis <kalast@gmail.com>2015-08-03 20:08:50 +0300
committerAntony Riakiotakis <kalast@gmail.com>2015-08-03 20:09:21 +0300
commit2411027a7996170188c49e4eac0a6762f3a2599f (patch)
tree2a2ef6a61e21b1cdeef861065c23e700008977f8 /source/blender/gpu
parent7667ad2d4e616ea0d412ac63e76c220a7106d065 (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')
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c54
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);
}