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-07-16 17:22:28 +0300
committerAntony Riakiotakis <kalast@gmail.com>2015-07-16 18:12:03 +0300
commit3e3e7ee41c9c04ef1630eef46c71434d152c55dc (patch)
tree65ee42534511a7c0b29be372d5072529b8960396 /source/blender
parent6568b6d1cdcaf32487bbcd48b4d20da32954c6f5 (diff)
Sculpt draw code:
Remove legacy code completely, now dyntopo, multires et al even work on GL 1.1 for really hardcore users :p Real purpose here though is to be able to have fast multires drawing even with VBO off, since it requires using indices for vertex buffers. Also made own code elf puke an eaten normal update function which made multires not update normals in solid mode...sorry.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c8
-rw-r--r--source/blender/blenkernel/intern/pbvh.c3
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c2
-rw-r--r--source/blender/gpu/GPU_buffers.h23
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c645
-rw-r--r--source/blender/gpu/intern/gpu_init_exit.c4
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c12
7 files changed, 222 insertions, 475 deletions
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 5b25a32124d..c16af7c2412 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -666,7 +666,7 @@ static void cdDM_drawMappedFaces(
unsigned int *fi_map;
findex_buffer = GPU_buffer_alloc(dm->drawObject->tot_loop_verts * sizeof(int), false);
- fi_map = GPU_buffer_lock(findex_buffer);
+ fi_map = GPU_buffer_lock(findex_buffer, GPU_BINDING_ARRAY);
if (fi_map) {
for (i = 0; i < dm->numTessFaceData; i++, mf++) {
@@ -689,7 +689,7 @@ static void cdDM_drawMappedFaces(
start_element = 0;
mf = cddm->mface;
- GPU_buffer_unlock(findex_buffer);
+ GPU_buffer_unlock(findex_buffer, GPU_BINDING_ARRAY);
GPU_buffer_bind_as_color(findex_buffer);
}
}
@@ -1034,7 +1034,7 @@ static void cdDM_drawMappedFacesGLSL(
if (buffer == NULL) {
buffer = GPU_buffer_alloc(max_element_size * dm->drawObject->tot_loop_verts, true);
}
- varray = GPU_buffer_lock_stream(buffer);
+ varray = GPU_buffer_lock_stream(buffer, GPU_BINDING_ARRAY);
if (varray == NULL) {
GPU_buffer_unbind();
GPU_buffer_free(buffer);
@@ -1114,7 +1114,7 @@ static void cdDM_drawMappedFacesGLSL(
tot_loops += 3;
}
}
- GPU_buffer_unlock(buffer);
+ GPU_buffer_unlock(buffer, GPU_BINDING_ARRAY);
}
for (a = 0; a < tot_active_mat; a++) {
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index e5e36b24a46..edeba9fd7e6 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -1087,7 +1087,8 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
GPU_build_grid_pbvh_buffers(node->prim_indices,
node->totprim,
bvh->grid_hidden,
- bvh->gridkey.grid_size);
+ bvh->gridkey.grid_size,
+ &bvh->gridkey);
break;
case PBVH_FACES:
node->draw_buffers =
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 0b0c011bf5a..aaf631abbf0 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -2246,6 +2246,8 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
int a;
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
+ ccgdm_pbvh_update(ccgdm);
+
if (ccgdm->pbvh && ccgdm->multires.mmd) {
if (BKE_pbvh_has_faces(ccgdm->pbvh)) {
BKE_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL,
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index 8586728410c..9c2ca6c5305 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -47,6 +47,7 @@ struct DerivedMesh;
struct GSet;
struct GPUVertPointLink;
struct PBVH;
+struct MVert;
typedef struct GPUBuffer {
int size; /* in bytes */
@@ -152,6 +153,9 @@ void GPU_buffer_free(GPUBuffer *buffer);
void GPU_drawobject_free(struct DerivedMesh *dm);
+/* free special global multires grid buffer */
+void GPU_buffer_multires_free(bool force);
+
/* flag that controls data type to fill buffer with, a modifier will prepare. */
typedef enum {
GPU_BUFFER_VERTEX = 0,
@@ -164,6 +168,10 @@ typedef enum {
GPU_BUFFER_TRIANGLES
} GPUBufferType;
+typedef enum {
+ GPU_BINDING_ARRAY = 0,
+ GPU_BINDING_INDEX = 1,
+} GPUBindingType;
/* called before drawing */
void GPU_vertex_setup(struct DerivedMesh *dm);
@@ -181,10 +189,12 @@ void GPU_triangle_setup(struct DerivedMesh *dm);
int GPU_attrib_element_size(GPUAttrib data[], int numdata);
void GPU_interleaved_attrib_setup(GPUBuffer *buffer, GPUAttrib data[], int numdata, int element_size);
+void GPU_buffer_bind(GPUBuffer *buffer, GPUBindingType binding);
+
/* can't lock more than one buffer at once */
-void *GPU_buffer_lock(GPUBuffer *buffer);
-void *GPU_buffer_lock_stream(GPUBuffer *buffer);
-void GPU_buffer_unlock(GPUBuffer *buffer);
+void *GPU_buffer_lock(GPUBuffer *buffer, GPUBindingType binding);
+void *GPU_buffer_lock_stream(GPUBuffer *buffer, GPUBindingType binding);
+void GPU_buffer_unlock(GPUBuffer *buffer, GPUBindingType binding);
/* switch color rendering on=1/off=0 */
void GPU_color_switch(int mode);
@@ -202,20 +212,19 @@ void GPU_interleaved_attrib_unbind(void);
typedef struct GPU_PBVH_Buffers GPU_PBVH_Buffers;
/* build */
-GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(
- const int (*face_vert_indices)[4],
+GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(const int (*face_vert_indices)[4],
const struct MFace *mface, const struct MVert *mvert,
const int *face_indices, int totface);
GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid,
- unsigned int **grid_hidden, int gridsize);
+ unsigned int **grid_hidden, int gridsize, const struct CCGKey *key);
GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(int smooth_shading);
/* update */
void GPU_update_mesh_pbvh_buffers(
- GPU_PBVH_Buffers *buffers, const MVert *mvert,
+ GPU_PBVH_Buffers *buffers, const struct MVert *mvert,
const int *vert_indices, int totvert, const float *vmask,
const int (*face_vert_indices)[4], bool show_diffuse_color);
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 9b588512794..d30ca9f27df 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -108,6 +108,13 @@ static GPUAttrib attribData[MAX_GPU_ATTRIB_DATA] = { { -1, 0, 0 } };
static ThreadMutex buffer_mutex = BLI_MUTEX_INITIALIZER;
+/* multires global buffer, can be used for many grids having the same grid size */
+static GPUBuffer *mres_glob_buffer = NULL;
+static int mres_prev_gridsize = -1;
+static GLenum mres_prev_index_type = 0;
+static unsigned mres_prev_totquad = 0;
+
+
/* stores recently-deleted buffers so that new buffers won't have to
* be recreated as often
*
@@ -122,15 +129,11 @@ static ThreadMutex buffer_mutex = BLI_MUTEX_INITIALIZER;
typedef struct GPUBufferPool {
/* number of allocated buffers stored */
int totbuf;
- int totpbvhbufids;
/* actual allocated length of the arrays */
int maxsize;
- int maxpbvhsize;
GPUBuffer **buffers;
- GLuint *pbvhbufids;
} GPUBufferPool;
#define MAX_FREE_GPU_BUFFERS 8
-#define MAX_FREE_GPU_BUFF_IDS 100
/* create a new GPUBufferPool */
static GPUBufferPool *gpu_buffer_pool_new(void)
@@ -140,11 +143,8 @@ static GPUBufferPool *gpu_buffer_pool_new(void)
pool = MEM_callocN(sizeof(GPUBufferPool), "GPUBuffer_Pool");
pool->maxsize = MAX_FREE_GPU_BUFFERS;
- pool->maxpbvhsize = MAX_FREE_GPU_BUFF_IDS;
pool->buffers = MEM_mallocN(sizeof(*pool->buffers) * pool->maxsize,
"GPUBufferPool.buffers");
- pool->pbvhbufids = MEM_mallocN(sizeof(*pool->pbvhbufids) * pool->maxpbvhsize,
- "GPUBufferPool.pbvhbuffers");
return pool;
}
@@ -202,7 +202,6 @@ static void gpu_buffer_pool_free(GPUBufferPool *pool)
gpu_buffer_pool_delete_last(pool);
MEM_freeN(pool->buffers);
- MEM_freeN(pool->pbvhbufids);
MEM_freeN(pool);
}
@@ -216,11 +215,6 @@ static void gpu_buffer_pool_free_unused(GPUBufferPool *pool)
while (pool->totbuf)
gpu_buffer_pool_delete_last(pool);
- if (pool->totpbvhbufids > 0) {
- glDeleteBuffersARB(pool->totpbvhbufids, pool->pbvhbufids);
- pool->totpbvhbufids = 0;
- }
-
BLI_mutex_unlock(&buffer_mutex);
}
@@ -416,6 +410,35 @@ void GPU_buffer_free(GPUBuffer *buffer)
BLI_mutex_unlock(&buffer_mutex);
}
+void GPU_buffer_multires_free(bool force)
+{
+ if (!mres_glob_buffer) {
+ /* Early output, no need to lock in this case, */
+ return;
+ }
+
+ if (force && BLI_thread_is_main()) {
+ if (mres_glob_buffer) {
+ if (mres_glob_buffer->id)
+ glDeleteBuffersARB(1, &mres_glob_buffer->id);
+ else if (mres_glob_buffer->pointer)
+ MEM_freeN(mres_glob_buffer->pointer);
+ MEM_freeN(mres_glob_buffer);
+ }
+ }
+ else {
+ BLI_mutex_lock(&buffer_mutex);
+ gpu_buffer_free_intern(mres_glob_buffer);
+ BLI_mutex_unlock(&buffer_mutex);
+ }
+
+ mres_glob_buffer = NULL;
+ mres_prev_gridsize = -1;
+ mres_prev_index_type = 0;
+ mres_prev_totquad = 0;
+}
+
+
void GPU_drawobject_free(DerivedMesh *dm)
{
GPUDrawObject *gdo;
@@ -972,7 +995,13 @@ void GPU_color_switch(int mode)
}
}
-void *GPU_buffer_lock(GPUBuffer *buffer)
+static int gpu_binding_type_gl[] =
+{
+ GL_ARRAY_BUFFER_ARB,
+ GL_ELEMENT_ARRAY_BUFFER_ARB
+};
+
+void *GPU_buffer_lock(GPUBuffer *buffer, GPUBindingType binding)
{
float *varray;
@@ -980,8 +1009,9 @@ void *GPU_buffer_lock(GPUBuffer *buffer)
return 0;
if (buffer->use_vbo) {
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer->id);
- varray = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ int bindtypegl = gpu_binding_type_gl[binding];
+ glBindBufferARB(bindtypegl, buffer->id);
+ varray = glMapBufferARB(bindtypegl, GL_WRITE_ONLY_ARB);
return varray;
}
else {
@@ -989,7 +1019,7 @@ void *GPU_buffer_lock(GPUBuffer *buffer)
}
}
-void *GPU_buffer_lock_stream(GPUBuffer *buffer)
+void *GPU_buffer_lock_stream(GPUBuffer *buffer, GPUBindingType binding)
{
float *varray;
@@ -997,10 +1027,11 @@ void *GPU_buffer_lock_stream(GPUBuffer *buffer)
return 0;
if (buffer->use_vbo) {
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer->id);
+ int bindtypegl = gpu_binding_type_gl[binding];
+ glBindBufferARB(bindtypegl, buffer->id);
/* discard previous data, avoid stalling gpu */
- glBufferDataARB(GL_ARRAY_BUFFER_ARB, buffer->size, 0, GL_STREAM_DRAW_ARB);
- varray = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ glBufferDataARB(bindtypegl, buffer->size, 0, GL_STREAM_DRAW_ARB);
+ varray = glMapBufferARB(bindtypegl, GL_WRITE_ONLY_ARB);
return varray;
}
else {
@@ -1008,16 +1039,24 @@ void *GPU_buffer_lock_stream(GPUBuffer *buffer)
}
}
-void GPU_buffer_unlock(GPUBuffer *buffer)
+void GPU_buffer_unlock(GPUBuffer *buffer, GPUBindingType binding)
{
if (buffer->use_vbo) {
+ int bindtypegl = gpu_binding_type_gl[binding];
/* note: this operation can fail, could return
* an error code from this function? */
- glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+ glUnmapBufferARB(bindtypegl);
+ glBindBufferARB(bindtypegl, 0);
}
}
+void GPU_buffer_bind(GPUBuffer *buffer, GPUBindingType binding)
+{
+ if (buffer->use_vbo) {
+ int bindtypegl = gpu_binding_type_gl[binding];
+ glBindBufferARB(bindtypegl, buffer->id);
+ }
+}
/* used for drawing edges */
void GPU_buffer_draw_elements(GPUBuffer *elements, unsigned int mode, int start, int count)
@@ -1032,14 +1071,6 @@ void GPU_buffer_draw_elements(GPUBuffer *elements, unsigned int mode, int start,
/* XXX: the rest of the code in this file is used for optimized PBVH
* drawing and doesn't interact at all with the buffer code above */
-/* Return false if VBO is either unavailable or disabled by the user,
- * true otherwise */
-static int gpu_vbo_enabled(void)
-{
- return (GLEW_ARB_vertex_buffer_object &&
- !(U.gameflags & USER_DISABLE_VBO));
-}
-
/* Convenience struct for building the VBO. */
typedef struct {
float co[3];
@@ -1055,7 +1086,7 @@ typedef struct {
struct GPU_PBVH_Buffers {
/* opengl buffer handles */
- GLuint vert_buf, index_buf, index_buf_fast;
+ GPUBuffer *vert_buf, *index_buf, *index_buf_fast;
GLenum index_type;
/* mesh pointers in case buffer allocation fails */
@@ -1123,22 +1154,6 @@ static void gpu_color_from_mask_copy(float mask, const float diffuse_color[4], u
out[2] = diffuse_color[2] * mask_color;
}
-static void gpu_color_from_mask_set(float mask, float diffuse_color[4])
-{
- float color = gpu_color_from_mask(mask);
- glColor3f(diffuse_color[0] * color, diffuse_color[1] * color, diffuse_color[2] * color);
-}
-
-static float gpu_color_from_mask_quad(const CCGKey *key,
- CCGElem *a, CCGElem *b,
- CCGElem *c, CCGElem *d)
-{
- return gpu_color_from_mask((*CCG_elem_mask(key, a) +
- *CCG_elem_mask(key, b) +
- *CCG_elem_mask(key, c) +
- *CCG_elem_mask(key, d)) * 0.25f);
-}
-
static void gpu_color_from_mask_quad_copy(const CCGKey *key,
CCGElem *a, CCGElem *b,
CCGElem *c, CCGElem *d,
@@ -1156,15 +1171,6 @@ static void gpu_color_from_mask_quad_copy(const CCGKey *key,
out[2] = diffuse_color[2] * mask_color;
}
-static void gpu_color_from_mask_quad_set(const CCGKey *key,
- CCGElem *a, CCGElem *b,
- CCGElem *c, CCGElem *d,
- const float diffuse_color[4])
-{
- float color = gpu_color_from_mask_quad(key, a, b, c, d);
- glColor3f(diffuse_color[0] * color, diffuse_color[1] * color, diffuse_color[2] * color);
-}
-
void GPU_update_mesh_pbvh_buffers(
GPU_PBVH_Buffers *buffers, const MVert *mvert,
const int *vert_indices, int totvert, const float *vmask,
@@ -1177,7 +1183,7 @@ void GPU_update_mesh_pbvh_buffers(
buffers->show_diffuse_color = show_diffuse_color;
buffers->use_matcaps = GPU_material_use_matcaps_get();
- if (buffers->vert_buf) {
+ {
int totelem = (buffers->smooth ? totvert : (buffers->tot_tri * 3));
float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 0.8f};
@@ -1192,12 +1198,10 @@ void GPU_update_mesh_pbvh_buffers(
copy_v4_v4(buffers->diffuse_color, diffuse_color);
/* Build VBO */
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
- glBufferDataARB(GL_ARRAY_BUFFER_ARB,
- sizeof(VertexBufferFormat) * totelem,
- NULL, GL_STATIC_DRAW_ARB);
-
- vert_data = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ if (buffers->vert_buf)
+ GPU_buffer_free(buffers->vert_buf);
+ buffers->vert_buf = GPU_buffer_alloc(sizeof(VertexBufferFormat) * totelem, false);
+ vert_data = GPU_buffer_lock(buffers->vert_buf, GPU_BINDING_ARRAY);
if (vert_data) {
/* Vertex data is shared if smooth-shaded, but separate
@@ -1291,11 +1295,11 @@ void GPU_update_mesh_pbvh_buffers(
}
}
- glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+ GPU_buffer_unlock(buffers->vert_buf, GPU_BINDING_ARRAY);
}
else {
- glDeleteBuffersARB(1, &buffers->vert_buf);
- buffers->vert_buf = 0;
+ GPU_buffer_free(buffers->vert_buf);
+ buffers->vert_buf = NULL;
}
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
@@ -1304,8 +1308,7 @@ void GPU_update_mesh_pbvh_buffers(
buffers->mvert = mvert;
}
-GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(
- const int (*face_vert_indices)[4],
+GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(const int (*face_vert_indices)[4],
const MFace *mface, const MVert *mvert,
const int *face_indices,
int totface)
@@ -1341,17 +1344,12 @@ GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(
/* An element index buffer is used for smooth shading, but flat
* shading requires separate vertex normals so an index buffer is
* can't be used there. */
- if (gpu_vbo_enabled() && buffers->smooth)
- glGenBuffersARB(1, &buffers->index_buf);
+ if (buffers->smooth)
+ buffers->index_buf = GPU_buffer_alloc(sizeof(unsigned short) * tottri * 3, false);
if (buffers->index_buf) {
- /* Generate index buffer object */
- 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);
+ tri_data = GPU_buffer_lock(buffers->index_buf, GPU_BINDING_INDEX);
if (tri_data) {
for (i = 0; i < totface; ++i) {
const MFace *f = mface + face_indices[i];
@@ -1375,19 +1373,16 @@ GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(
v[2] = 2;
}
}
- glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
+ GPU_buffer_unlock(buffers->index_buf, GPU_BINDING_INDEX);
}
else {
- glDeleteBuffersARB(1, &buffers->index_buf);
- buffers->index_buf = 0;
+ GPU_buffer_free(buffers->index_buf);
+ buffers->index_buf = NULL;
}
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}
- if (gpu_vbo_enabled() && (buffers->index_buf || !buffers->smooth))
- glGenBuffersARB(1, &buffers->vert_buf);
-
buffers->tot_tri = tottri;
buffers->mface = mface;
@@ -1409,7 +1404,6 @@ void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
/* Build VBO */
if (buffers->vert_buf) {
- int totvert = key->grid_area * totgrid;
int smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
const int has_mask = key->has_mask;
float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
@@ -1424,11 +1418,7 @@ void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
copy_v4_v4(buffers->diffuse_color, diffuse_color);
- 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);
+ vert_data = GPU_buffer_lock_stream(buffers->vert_buf, GPU_BINDING_ARRAY);
if (vert_data) {
for (i = 0; i < totgrid; ++i) {
VertexBufferFormat *vd = vert_data;
@@ -1489,11 +1479,12 @@ void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
vert_data += key->grid_area;
}
- glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+
+ GPU_buffer_unlock(buffers->vert_buf, GPU_BINDING_ARRAY);
}
else {
- glDeleteBuffersARB(1, &buffers->vert_buf);
- buffers->vert_buf = 0;
+ GPU_buffer_free(buffers->vert_buf);
+ buffers->vert_buf = NULL;
}
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
@@ -1516,14 +1507,11 @@ void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
type_ *tri_data; \
int offset = 0; \
int i, j, k; \
- \
- glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, \
- sizeof(type_) * (tot_quad_) * 6, NULL, \
- GL_STATIC_DRAW_ARB); \
+ buffer_ = GPU_buffer_alloc(sizeof(type_) * (tot_quad_) * 6, \
+ false); \
\
/* Fill the buffer */ \
- tri_data = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, \
- GL_WRITE_ONLY_ARB); \
+ tri_data = GPU_buffer_lock(buffer_, GPU_BINDING_INDEX); \
if (tri_data) { \
for (i = 0; i < totgrid; ++i) { \
BLI_bitmap *gh = NULL; \
@@ -1550,74 +1538,58 @@ void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
\
offset += gridsize * gridsize; \
} \
- glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); \
+ GPU_buffer_unlock(buffer_, GPU_BINDING_INDEX); \
} \
else { \
- glDeleteBuffersARB(1, &(buffer_)); \
- (buffer_) = 0; \
+ GPU_buffer_free(buffer_); \
+ (buffer_) = NULL; \
} \
} (void)0
/* end FILL_QUAD_BUFFER */
-static GLuint gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned *totquad)
+static GPUBuffer *gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned *totquad)
{
- static int prev_gridsize = -1;
- static GLenum prev_index_type = 0;
- static GLuint buffer = 0;
- static unsigned prev_totquad;
-
/* used in the FILL_QUAD_BUFFER macro */
BLI_bitmap * const *grid_hidden = NULL;
const int *grid_indices = NULL;
int totgrid = 1;
- /* VBO is disabled; delete the previous buffer (if it exists) and
- * return an invalid handle */
- if (!gpu_vbo_enabled()) {
- if (buffer)
- glDeleteBuffersARB(1, &buffer);
- return 0;
- }
-
/* VBO is already built */
- if (buffer && prev_gridsize == gridsize) {
- *index_type = prev_index_type;
- *totquad = prev_totquad;
- return buffer;
+ if (mres_glob_buffer && mres_prev_gridsize == gridsize) {
+ *index_type = mres_prev_index_type;
+ *totquad = mres_prev_totquad;
+ return mres_glob_buffer;
+ }
+ /* we can't reuse old, delete the existing buffer */
+ else if (mres_glob_buffer) {
+ GPU_buffer_free(mres_glob_buffer);
}
/* Build new VBO */
- glGenBuffersARB(1, &buffer);
- if (buffer) {
- *totquad = (gridsize - 1) * (gridsize - 1);
-
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffer);
-
- if (gridsize * gridsize < USHRT_MAX) {
- *index_type = GL_UNSIGNED_SHORT;
- FILL_QUAD_BUFFER(unsigned short, *totquad, buffer);
- }
- else {
- *index_type = GL_UNSIGNED_INT;
- FILL_QUAD_BUFFER(unsigned int, *totquad, buffer);
- }
+ *totquad = (gridsize - 1) * (gridsize - 1);
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+ if (gridsize * gridsize < USHRT_MAX) {
+ *index_type = GL_UNSIGNED_SHORT;
+ FILL_QUAD_BUFFER(unsigned short, *totquad, mres_glob_buffer);
+ }
+ else {
+ *index_type = GL_UNSIGNED_INT;
+ FILL_QUAD_BUFFER(unsigned int, *totquad, mres_glob_buffer);
}
- prev_gridsize = gridsize;
- prev_index_type = *index_type;
- prev_totquad = *totquad;
- return buffer;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+
+ mres_prev_gridsize = gridsize;
+ mres_prev_index_type = *index_type;
+ mres_prev_totquad = *totquad;
+ return mres_glob_buffer;
}
#define FILL_FAST_BUFFER(type_) \
{ \
type_ *buffer; \
- glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, \
- sizeof(type_) * 6 * totgrid, NULL, \
- GL_STATIC_DRAW_ARB); \
- buffer = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); \
+ buffers->index_buf_fast = GPU_buffer_alloc(sizeof(type_) * 6 * totgrid, false); \
+ buffer = GPU_buffer_lock(buffers->index_buf_fast, GPU_BINDING_INDEX); \
if (buffer) { \
int i; \
for (i = 0; i < totgrid; i++) { \
@@ -1629,16 +1601,16 @@ static GLuint gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned *to
buffer[currentquad + 4] = i * gridsize * gridsize + gridsize - 1; \
buffer[currentquad + 5] = (i + 1) * gridsize * gridsize - gridsize; \
} \
- glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); \
+ GPU_buffer_unlock(buffers->index_buf_fast, GPU_BINDING_INDEX); \
} \
else { \
- glDeleteBuffersARB(1, &buffers->index_buf_fast); \
- buffers->index_buf_fast = 0; \
+ GPU_buffer_free(buffers->index_buf_fast); \
+ buffers->index_buf_fast = NULL; \
} \
} (void)0
GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid,
- BLI_bitmap **grid_hidden, int gridsize)
+ BLI_bitmap **grid_hidden, int gridsize, const CCGKey *key)
{
GPU_PBVH_Buffers *buffers;
int totquad;
@@ -1659,51 +1631,38 @@ GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid,
return buffers;
/* create and fill indices of the fast buffer too */
- glGenBuffersARB(1, &buffers->index_buf_fast);
-
- if (buffers->index_buf_fast) {
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf_fast);
-
- if (totgrid * gridsize * gridsize < USHRT_MAX) {
- FILL_FAST_BUFFER(unsigned short);
- }
- else {
- FILL_FAST_BUFFER(unsigned int);
- }
-
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+ if (totgrid * gridsize * gridsize < USHRT_MAX) {
+ FILL_FAST_BUFFER(unsigned short);
+ }
+ else {
+ FILL_FAST_BUFFER(unsigned int);
}
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+
if (totquad == fully_visible_totquad) {
buffers->index_buf = gpu_get_grid_buffer(gridsize, &buffers->index_type, &buffers->tot_quad);
buffers->has_hidden = 0;
}
- else if (GLEW_ARB_vertex_buffer_object && !(U.gameflags & USER_DISABLE_VBO)) {
- /* Build new VBO */
- glGenBuffersARB(1, &buffers->index_buf);
- if (buffers->index_buf) {
- buffers->tot_quad = totquad;
-
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
-
- if (totgrid * gridsize * gridsize < USHRT_MAX) {
- buffers->index_type = GL_UNSIGNED_SHORT;
- FILL_QUAD_BUFFER(unsigned short, totquad, buffers->index_buf);
- }
- else {
- buffers->index_type = GL_UNSIGNED_INT;
- FILL_QUAD_BUFFER(unsigned int, totquad, buffers->index_buf);
- }
+ else {
+ buffers->tot_quad = totquad;
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+ if (totgrid * gridsize * gridsize < USHRT_MAX) {
+ buffers->index_type = GL_UNSIGNED_SHORT;
+ FILL_QUAD_BUFFER(unsigned short, totquad, buffers->index_buf);
+ }
+ else {
+ buffers->index_type = GL_UNSIGNED_INT;
+ FILL_QUAD_BUFFER(unsigned int, totquad, buffers->index_buf);
}
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
buffers->has_hidden = 1;
}
/* Build coord/normal VBO */
if (buffers->index_buf)
- glGenBuffersARB(1, &buffers->vert_buf);
+ buffers->vert_buf = GPU_buffer_alloc(sizeof(VertexBufferFormat) * totgrid * key->grid_area, false);
return buffers;
}
@@ -1802,9 +1761,6 @@ void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
buffers->show_diffuse_color = show_diffuse_color;
buffers->use_matcaps = GPU_material_use_matcaps_get();
- if (!buffers->vert_buf || (buffers->smooth && !buffers->index_buf))
- return;
-
/* Count visible triangles */
tottri = gpu_bmesh_face_visible_count(bm_faces);
@@ -1834,13 +1790,12 @@ void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
copy_v4_v4(buffers->diffuse_color, diffuse_color);
/* Initialize vertex buffer */
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
- glBufferDataARB(GL_ARRAY_BUFFER_ARB,
- sizeof(VertexBufferFormat) * totvert,
- NULL, GL_STATIC_DRAW_ARB);
+ if (buffers->vert_buf)
+ GPU_buffer_free(buffers->vert_buf);
+ buffers->vert_buf = GPU_buffer_alloc(sizeof(VertexBufferFormat) * totvert, false);
/* Fill vertex buffer */
- vert_data = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ vert_data = GPU_buffer_lock(buffers->vert_buf, GPU_BINDING_ARRAY);
if (vert_data) {
int v_index = 0;
@@ -1900,15 +1855,15 @@ void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
buffers->tot_tri = tottri;
}
- glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+ GPU_buffer_unlock(buffers->vert_buf, GPU_BINDING_ARRAY);
/* gpu_bmesh_vert_to_buffer_copy sets dirty index values */
bm->elem_index_dirty |= BM_VERT;
}
else {
/* Memory map failed */
- glDeleteBuffersARB(1, &buffers->vert_buf);
- buffers->vert_buf = 0;
+ GPU_buffer_free(buffers->vert_buf);
+ buffers->vert_buf = NULL;
return;
}
@@ -1916,15 +1871,14 @@ void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
const int use_short = (maxvert < USHRT_MAX);
/* Initialize triangle index buffer */
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
- glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
- (use_short ?
- sizeof(unsigned short) :
- sizeof(unsigned int)) * 3 * tottri,
- NULL, GL_STATIC_DRAW_ARB);
+ if (buffers->index_buf)
+ GPU_buffer_free(buffers->index_buf);
+ buffers->index_buf = GPU_buffer_alloc((use_short ?
+ sizeof(unsigned short) :
+ sizeof(unsigned int)) * 3 * tottri, false);
/* Fill triangle index buffer */
- tri_data = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ tri_data = GPU_buffer_lock(buffers->index_buf, GPU_BINDING_INDEX);
if (tri_data) {
GSetIterator gs_iter;
@@ -1954,7 +1908,7 @@ void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
}
}
- glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
+ GPU_buffer_unlock(buffers->index_buf, GPU_BINDING_INDEX);
buffers->tot_tri = tottri;
buffers->index_type = (use_short ?
@@ -1963,10 +1917,13 @@ void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
}
else {
/* Memory map failed */
- glDeleteBuffersARB(1, &buffers->index_buf);
- buffers->index_buf = 0;
+ GPU_buffer_free(buffers->index_buf);
+ buffers->index_buf = NULL;
}
}
+ else if (buffers->index_buf) {
+ GPU_buffer_free(buffers->index_buf);
+ }
}
GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(int smooth_shading)
@@ -1974,9 +1931,6 @@ GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(int smooth_shading)
GPU_PBVH_Buffers *buffers;
buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
- if (smooth_shading)
- glGenBuffersARB(1, &buffers->index_buf);
- glGenBuffersARB(1, &buffers->vert_buf);
buffers->use_bmesh = true;
buffers->smooth = smooth_shading;
buffers->show_diffuse_color = false;
@@ -1985,208 +1939,6 @@ GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(int smooth_shading)
return buffers;
}
-static void gpu_draw_buffers_legacy_mesh(GPU_PBVH_Buffers *buffers)
-{
- const MVert *mvert = buffers->mvert;
- int i, j;
- const int has_mask = (buffers->vmask != NULL);
- const MFace *face = &buffers->mface[buffers->face_indices[0]];
- float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
-
- if (buffers->use_matcaps)
- diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
- else if (buffers->show_diffuse_color)
- GPU_material_diffuse_get(face->mat_nr + 1, diffuse_color);
-
- if (has_mask) {
- gpu_colors_enable(VBO_DISABLED);
- }
-
- for (i = 0; i < buffers->totface; ++i) {
- const MFace *f = &buffers->mface[buffers->face_indices[i]];
- int S = f->v4 ? 4 : 3;
- const unsigned int *fv = &f->v1;
-
- if (paint_is_face_hidden(f, buffers->mvert))
- continue;
-
- glBegin((f->v4) ? GL_QUADS : GL_TRIANGLES);
-
- if (buffers->smooth) {
- for (j = 0; j < S; j++) {
- if (has_mask) {
- gpu_color_from_mask_set(buffers->vmask[fv[j]], diffuse_color);
- }
- glNormal3sv(mvert[fv[j]].no);
- glVertex3fv(mvert[fv[j]].co);
- }
- }
- else {
- float fno[3];
-
- /* calculate face normal */
- if (f->v4) {
- normal_quad_v3(fno, mvert[fv[0]].co, mvert[fv[1]].co,
- mvert[fv[2]].co, mvert[fv[3]].co);
- }
- else
- normal_tri_v3(fno, mvert[fv[0]].co, mvert[fv[1]].co, mvert[fv[2]].co);
- glNormal3fv(fno);
-
- if (has_mask) {
- float fmask;
-
- /* calculate face mask color */
- fmask = (buffers->vmask[fv[0]] +
- buffers->vmask[fv[1]] +
- buffers->vmask[fv[2]]);
- if (f->v4)
- fmask = (fmask + buffers->vmask[fv[3]]) * 0.25f;
- else
- fmask /= 3.0f;
- gpu_color_from_mask_set(fmask, diffuse_color);
- }
-
- for (j = 0; j < S; j++)
- glVertex3fv(mvert[fv[j]].co);
- }
-
- glEnd();
- }
-
- if (has_mask) {
- gpu_colors_disable(VBO_DISABLED);
- }
-}
-
-static void gpu_draw_buffers_legacy_grids(GPU_PBVH_Buffers *buffers)
-{
- const CCGKey *key = &buffers->gridkey;
- int i, j, x, y, gridsize = buffers->gridkey.grid_size;
- const int has_mask = key->has_mask;
- const DMFlagMat *flags = &buffers->grid_flag_mats[buffers->grid_indices[0]];
- float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
-
- if (buffers->use_matcaps)
- diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
- else if (buffers->show_diffuse_color)
- GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color);
-
- if (has_mask) {
- gpu_colors_enable(VBO_DISABLED);
- }
-
- for (i = 0; i < buffers->totgrid; ++i) {
- int g = buffers->grid_indices[i];
- CCGElem *grid = buffers->grids[g];
- BLI_bitmap *gh = buffers->grid_hidden[g];
-
- /* TODO: could use strips with hiding as well */
-
- if (gh) {
- glBegin(GL_QUADS);
-
- for (y = 0; y < gridsize - 1; y++) {
- for (x = 0; x < gridsize - 1; x++) {
- CCGElem *e[4] = {
- CCG_grid_elem(key, grid, x + 1, y + 1),
- CCG_grid_elem(key, grid, x + 1, y),
- CCG_grid_elem(key, grid, x, y),
- CCG_grid_elem(key, grid, x, y + 1)
- };
-
- /* skip face if any of its corners are hidden */
- if (paint_is_grid_face_hidden(gh, gridsize, x, y))
- continue;
-
- if (buffers->smooth) {
- for (j = 0; j < 4; j++) {
- if (has_mask) {
- gpu_color_from_mask_set(*CCG_elem_mask(key, e[j]), diffuse_color);
- }
- glNormal3fv(CCG_elem_no(key, e[j]));
- glVertex3fv(CCG_elem_co(key, e[j]));
- }
- }
- else {
- float fno[3];
- normal_quad_v3(fno,
- CCG_elem_co(key, e[0]),
- CCG_elem_co(key, e[1]),
- CCG_elem_co(key, e[2]),
- CCG_elem_co(key, e[3]));
- glNormal3fv(fno);
-
- if (has_mask) {
- gpu_color_from_mask_quad_set(key, e[0], e[1], e[2], e[3], diffuse_color);
- }
-
- for (j = 0; j < 4; j++)
- glVertex3fv(CCG_elem_co(key, e[j]));
- }
- }
- }
-
- glEnd();
- }
- else if (buffers->smooth) {
- for (y = 0; y < gridsize - 1; y++) {
- glBegin(GL_QUAD_STRIP);
- for (x = 0; x < gridsize; x++) {
- CCGElem *a = CCG_grid_elem(key, grid, x, y);
- CCGElem *b = CCG_grid_elem(key, grid, x, y + 1);
-
- if (has_mask) {
- gpu_color_from_mask_set(*CCG_elem_mask(key, a), diffuse_color);
- }
- glNormal3fv(CCG_elem_no(key, a));
- glVertex3fv(CCG_elem_co(key, a));
- if (has_mask) {
- gpu_color_from_mask_set(*CCG_elem_mask(key, b), diffuse_color);
- }
- glNormal3fv(CCG_elem_no(key, b));
- glVertex3fv(CCG_elem_co(key, b));
- }
- glEnd();
- }
- }
- else {
- for (y = 0; y < gridsize - 1; y++) {
- glBegin(GL_QUAD_STRIP);
- for (x = 0; x < gridsize; x++) {
- CCGElem *a = CCG_grid_elem(key, grid, x, y);
- CCGElem *b = CCG_grid_elem(key, grid, x, y + 1);
-
- if (x > 0) {
- CCGElem *c = CCG_grid_elem(key, grid, x - 1, y);
- CCGElem *d = CCG_grid_elem(key, grid, x - 1, y + 1);
-
- float fno[3];
- normal_quad_v3(fno,
- CCG_elem_co(key, d),
- CCG_elem_co(key, b),
- CCG_elem_co(key, a),
- CCG_elem_co(key, c));
- glNormal3fv(fno);
-
- if (has_mask) {
- gpu_color_from_mask_quad_set(key, a, b, c, d, diffuse_color);
- }
- }
-
- glVertex3fv(CCG_elem_co(key, a));
- glVertex3fv(CCG_elem_co(key, b));
- }
- glEnd();
- }
- }
- }
-
- if (has_mask) {
- gpu_colors_disable(VBO_DISABLED);
- }
-}
-
void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
bool wireframe, bool fast)
{
@@ -2213,24 +1965,35 @@ void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
glShadeModel((buffers->smooth || buffers->totface) ? GL_SMOOTH : GL_FLAT);
if (buffers->vert_buf) {
+ char *base = NULL;
+ char *index_base = NULL;
glEnableClientState(GL_VERTEX_ARRAY);
if (!wireframe) {
glEnableClientState(GL_NORMAL_ARRAY);
gpu_colors_enable(VBO_ENABLED);
}
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
+ GPU_buffer_bind(buffers->vert_buf, GPU_BINDING_ARRAY);
+
+ if (!buffers->vert_buf->use_vbo)
+ base = (char *)buffers->vert_buf->pointer;
- if (do_fast)
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf_fast);
- else if (buffers->index_buf)
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
+ if (do_fast) {
+ GPU_buffer_bind(buffers->index_buf_fast, GPU_BINDING_INDEX);
+ if (!buffers->index_buf_fast->use_vbo)
+ index_base = buffers->index_buf_fast->pointer;
+ }
+ else if (buffers->index_buf) {
+ GPU_buffer_bind(buffers->index_buf, GPU_BINDING_INDEX);
+ if (!buffers->index_buf->use_vbo)
+ index_base = buffers->index_buf->pointer;
+ }
if (wireframe)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
if (buffers->tot_quad) {
- const char *offset = 0;
+ const char *offset = base;
int i, last = buffers->has_hidden ? 1 : buffers->totgrid;
for (i = 0; i < last; i++) {
glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat),
@@ -2241,9 +2004,9 @@ void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
offset + offsetof(VertexBufferFormat, color));
if (do_fast)
- glDrawElements(GL_TRIANGLES, buffers->totgrid * 6, buffers->index_type, 0);
+ glDrawElements(GL_TRIANGLES, buffers->totgrid * 6, buffers->index_type, index_base);
else
- glDrawElements(GL_TRIANGLES, buffers->tot_quad * 6, buffers->index_type, 0);
+ glDrawElements(GL_TRIANGLES, buffers->tot_quad * 6, buffers->index_type, index_base);
offset += buffers->gridkey.grid_area * sizeof(VertexBufferFormat);
}
@@ -2252,14 +2015,14 @@ void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
int totelem = buffers->tot_tri * 3;
glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat),
- (void *)offsetof(VertexBufferFormat, co));
+ (void *)(base + offsetof(VertexBufferFormat, co)));
glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat),
- (void *)offsetof(VertexBufferFormat, no));
+ (void *)(base + offsetof(VertexBufferFormat, no)));
glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
- (void *)offsetof(VertexBufferFormat, color));
+ (void *)(base + offsetof(VertexBufferFormat, color)));
if (buffers->index_buf)
- glDrawElements(GL_TRIANGLES, totelem, buffers->index_type, 0);
+ glDrawElements(GL_TRIANGLES, totelem, buffers->index_type, index_base);
else
glDrawArrays(GL_TRIANGLES, 0, totelem);
}
@@ -2268,7 +2031,7 @@ void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
- if (buffers->index_buf)
+ if (buffers->index_buf || do_fast)
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
glDisableClientState(GL_VERTEX_ARRAY);
@@ -2277,13 +2040,6 @@ void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
gpu_colors_disable(VBO_ENABLED);
}
}
- /* fallbacks if we are out of memory or VBO is disabled */
- else if (buffers->totface) {
- gpu_draw_buffers_legacy_mesh(buffers);
- }
- else if (buffers->totgrid) {
- gpu_draw_buffers_legacy_grids(buffers);
- }
}
bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, GSet *bm_faces, bool show_diffuse_color)
@@ -2328,52 +2084,15 @@ bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, GSet *bm_faces,
return !equals_v3v3(diffuse_color, buffers->diffuse_color);
}
-/* release a GPU_PBVH_Buffers id;
- *
- * Thread-unsafe version for internal usage only.
- */
-static void gpu_pbvh_buffer_free_intern(GLuint id)
-{
- GPUBufferPool *pool;
-
- /* zero id is vertex buffers off */
- if (!id)
- return;
-
- pool = gpu_get_global_buffer_pool();
-
- /* free the buffers immediately if we are on main thread */
- if (BLI_thread_is_main()) {
- glDeleteBuffersARB(1, &id);
-
- if (pool->totpbvhbufids > 0) {
- glDeleteBuffersARB(pool->totpbvhbufids, pool->pbvhbufids);
- pool->totpbvhbufids = 0;
- }
- return;
- }
- /* outside of main thread, can't safely delete the
- * buffer, so increase pool size */
- if (pool->maxpbvhsize == pool->totpbvhbufids) {
- pool->maxpbvhsize += MAX_FREE_GPU_BUFF_IDS;
- pool->pbvhbufids = MEM_reallocN(pool->pbvhbufids,
- sizeof(*pool->pbvhbufids) * pool->maxpbvhsize);
- }
-
- /* insert the buffer into the beginning of the pool */
- pool->pbvhbufids[pool->totpbvhbufids++] = id;
-}
-
-
void GPU_free_pbvh_buffers(GPU_PBVH_Buffers *buffers)
{
if (buffers) {
if (buffers->vert_buf)
- gpu_pbvh_buffer_free_intern(buffers->vert_buf);
+ GPU_buffer_free(buffers->vert_buf);
if (buffers->index_buf && (buffers->tot_tri || buffers->has_hidden))
- gpu_pbvh_buffer_free_intern(buffers->index_buf);
+ GPU_buffer_free(buffers->index_buf);
if (buffers->index_buf_fast)
- gpu_pbvh_buffer_free_intern(buffers->index_buf_fast);
+ GPU_buffer_free(buffers->index_buf_fast);
MEM_freeN(buffers);
}
diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c
index aefddc774be..3a8a6fca23b 100644
--- a/source/blender/gpu/intern/gpu_init_exit.c
+++ b/source/blender/gpu/intern/gpu_init_exit.c
@@ -29,8 +29,11 @@
* \ingroup gpu
*/
+#include "BKE_DerivedMesh.h"
+
#include "BLI_sys_types.h"
#include "GPU_init_exit.h" /* interface */
+#include "GPU_buffers.h"
#include "BKE_global.h"
@@ -70,6 +73,7 @@ void GPU_exit(void)
gpu_codegen_exit();
gpu_extensions_exit(); /* must come last */
+ GPU_buffer_multires_free(true);
initialized = false;
}
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 9604f643149..cf327583d47 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -91,6 +91,8 @@ EnumPropertyItem navigation_mode_items[] = {
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_idprop.h"
+#include "BKE_pbvh.h"
+#include "BKE_paint.h"
#include "GPU_draw.h"
#include "GPU_select.h"
@@ -141,13 +143,23 @@ static void rna_userdef_language_update(Main *UNUSED(bmain), Scene *UNUSED(scene
UI_reinit_font();
}
+static void update_cb(PBVHNode *node, void *UNUSED(rebuild))
+{
+ BKE_pbvh_node_mark_rebuild_draw(node);
+}
+
static void rna_userdef_vbo_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
{
Object *ob;
for (ob = bmain->object.first; ob; ob = ob->id.next) {
GPU_drawobject_free(ob->derivedFinal);
+
+ if (ob->sculpt && ob->sculpt->pbvh) {
+ BKE_pbvh_search_callback(ob->sculpt->pbvh, NULL, NULL, update_cb, NULL);
+ }
}
+ GPU_buffer_multires_free(false);
}
static void rna_userdef_show_manipulator_update(Main *bmain, Scene *scene, PointerRNA *ptr)