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:
-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)