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:
Diffstat (limited to 'source/blender/gpu/intern/gpu_buffers.c')
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c153
1 files changed, 92 insertions, 61 deletions
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index b1c869c6d8d..bc90ddb23b7 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -1,5 +1,5 @@
/**
- * $Id: gpu_buffers.c 23816 2009-10-13 19:02:30Z nicholasbishop $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -38,8 +38,9 @@
#include "MEM_guardedalloc.h"
-#include "BLI_math.h"
#include "BLI_ghash.h"
+#include "BLI_math.h"
+#include "BLI_threads.h"
#include "DNA_meshdata_types.h"
@@ -48,7 +49,7 @@
#include "DNA_userdef_types.h"
-#include "gpu_buffers.h"
+#include "GPU_buffers.h"
#define GPU_BUFFER_VERTEX_STATE 1
#define GPU_BUFFER_NORMAL_STATE 2
@@ -82,37 +83,12 @@ GPUBufferPool *GPU_buffer_pool_new()
}
pool = MEM_callocN(sizeof(GPUBufferPool), "GPU_buffer_pool_new");
+ pool->maxsize = MAX_FREE_GPU_BUFFERS;
+ pool->buffers = MEM_callocN(sizeof(GPUBuffer*)*pool->maxsize, "GPU_buffer_pool_new buffers");
return pool;
}
-void GPU_buffer_pool_free(GPUBufferPool *pool)
-{
- int i;
-
- DEBUG_VBO("GPU_buffer_pool_free\n");
-
- if( pool == 0 )
- pool = globalPool;
- if( pool == 0 )
- return;
-
- for( i = 0; i < pool->size; i++ ) {
- if( pool->buffers[i] != 0 ) {
- if( useVBOs ) {
- glDeleteBuffersARB( 1, &pool->buffers[i]->id );
- }
- else {
- MEM_freeN( pool->buffers[i]->pointer );
- }
- MEM_freeN(pool->buffers[i]);
- } else {
- ERROR_VBO("Why are we accessing a null buffer in GPU_buffer_pool_free?\n");
- }
- }
- MEM_freeN(pool);
-}
-
void GPU_buffer_pool_remove( int index, GPUBufferPool *pool )
{
int i;
@@ -159,6 +135,35 @@ void GPU_buffer_pool_delete_last( GPUBufferPool *pool )
pool->size--;
}
+void GPU_buffer_pool_free(GPUBufferPool *pool)
+{
+ DEBUG_VBO("GPU_buffer_pool_free\n");
+
+ if( pool == 0 )
+ pool = globalPool;
+ if( pool == 0 )
+ return;
+
+ while( pool->size )
+ GPU_buffer_pool_delete_last(pool);
+
+ MEM_freeN(pool->buffers);
+ MEM_freeN(pool);
+}
+
+void GPU_buffer_pool_free_unused(GPUBufferPool *pool)
+{
+ DEBUG_VBO("GPU_buffer_pool_free_unused\n");
+
+ if( pool == 0 )
+ pool = globalPool;
+ if( pool == 0 )
+ return;
+
+ while( pool->size > MAX_FREE_GPU_BUFFERS )
+ GPU_buffer_pool_delete_last(pool);
+}
+
GPUBuffer *GPU_buffer_alloc( int size, GPUBufferPool *pool )
{
char buffer[60];
@@ -226,6 +231,7 @@ GPUBuffer *GPU_buffer_alloc( int size, GPUBufferPool *pool )
void GPU_buffer_free( GPUBuffer *buffer, GPUBufferPool *pool )
{
int i;
+
DEBUG_VBO("GPU_buffer_free\n");
if( buffer == 0 )
@@ -235,9 +241,19 @@ void GPU_buffer_free( GPUBuffer *buffer, GPUBufferPool *pool )
if( pool == 0 )
globalPool = GPU_buffer_pool_new();
- /* free the last used buffer in the queue if no more space */
- if( pool->size == MAX_FREE_GPU_BUFFERS ) {
- GPU_buffer_pool_delete_last( pool );
+ /* free the last used buffer in the queue if no more space, but only
+ if we are in the main thread. for e.g. rendering or baking it can
+ happen that we are in other thread and can't call OpenGL, in that
+ case cleanup will be done GPU_buffer_pool_free_unused */
+ if( BLI_thread_is_main() ) {
+ while( pool->size >= MAX_FREE_GPU_BUFFERS )
+ GPU_buffer_pool_delete_last( pool );
+ }
+ else {
+ if( pool->maxsize == pool->size ) {
+ pool->maxsize += MAX_FREE_GPU_BUFFERS;
+ pool->buffers = MEM_reallocN(pool->buffers, sizeof(GPUBuffer*)*pool->maxsize);
+ }
}
for( i =pool->size; i > 0; i-- ) {
@@ -273,9 +289,9 @@ GPUDrawObject *GPU_drawobject_new( DerivedMesh *dm )
memset(numverts,0,sizeof(int)*32768);
mvert = dm->getVertArray(dm);
- mface = dm->getTessFaceArray(dm);
+ mface = dm->getFaceArray(dm);
- numfaces= dm->getNumTessFaces(dm);
+ numfaces= dm->getNumFaces(dm);
for( i=0; i < numfaces; i++ ) {
if( mface[i].v4 )
numverts[mface[i].mat_nr+16383] += 6; /* split every quad into two triangles */
@@ -315,11 +331,10 @@ GPUDrawObject *GPU_drawobject_new( DerivedMesh *dm )
if( object->indices[INDEX].element == -1 ) { \
object->indices[INDEX].element = ACTUAL; \
} else { \
- IndexLink *lnk = &object->indices[INDEX], *lnk2; \
- lnk2 = &object->indexMem[object->indexMemUsage]; \
- lnk2->element = ACTUAL; \
- SWAP(IndexLink, *lnk, *lnk2); \
- lnk->next = lnk2; \
+ IndexLink *lnk = &object->indices[INDEX]; \
+ while( lnk->next != 0 ) lnk = lnk->next; \
+ lnk->next = &object->indexMem[object->indexMemUsage]; \
+ lnk->next->element = ACTUAL; \
object->indexMemUsage++; \
}
@@ -460,7 +475,7 @@ void *GPU_build_mesh_buffers(GHash *map, MVert *mvert, MFace *mface,
for(i = 0, tottri = 0; i < totface; ++i)
tottri += mface[face_indices[i]].v4 ? 2 : 1;
- if(GL_ARB_vertex_buffer_object)
+ if(GL_ARB_vertex_buffer_object && !(U.gameflags & USER_DISABLE_VBO))
glGenBuffersARB(1, &buffers->index_buf);
if(buffers->index_buf) {
@@ -521,11 +536,11 @@ void *GPU_build_mesh_buffers(GHash *map, MVert *mvert, MFace *mface,
}
void GPU_update_grid_buffers(void *buffers_v, DMGridData **grids,
- int *grid_indices, int totgrid, int gridsize)
+ int *grid_indices, int totgrid, int gridsize, int smooth)
{
GPU_Buffers *buffers = buffers_v;
DMGridData *vert_data;
- int i, totvert;
+ int i, j, k, totvert;
totvert= gridsize*gridsize*totgrid;
@@ -540,6 +555,22 @@ void GPU_update_grid_buffers(void *buffers_v, DMGridData **grids,
for(i = 0; i < totgrid; ++i) {
DMGridData *grid= grids[grid_indices[i]];
memcpy(vert_data, grid, sizeof(DMGridData)*gridsize*gridsize);
+
+ if(!smooth) {
+ /* for flat shading, recalc normals and set the last vertex of
+ each quad in the index buffer to have the flat normal as
+ that is what opengl will use */
+ for(j = 0; j < gridsize-1; ++j) {
+ for(k = 0; k < gridsize-1; ++k) {
+ normal_quad_v3(vert_data[(j+1)*gridsize + (k+1)].no,
+ vert_data[(j+1)*gridsize + k].co,
+ vert_data[(j+1)*gridsize + k+1].co,
+ vert_data[j*gridsize + k+1].co,
+ vert_data[j*gridsize + k].co);
+ }
+ }
+ }
+
vert_data += gridsize*gridsize;
}
glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
@@ -571,7 +602,7 @@ void *GPU_build_grid_buffers(DMGridData **grids,
totquad= (gridsize-1)*(gridsize-1)*totgrid;
/* Generate index buffer object */
- if(GL_ARB_vertex_buffer_object)
+ if(GL_ARB_vertex_buffer_object && !(U.gameflags & USER_DISABLE_VBO))
glGenBuffersARB(1, &buffers->index_buf);
if(buffers->index_buf) {
@@ -590,10 +621,10 @@ void *GPU_build_grid_buffers(DMGridData **grids,
for(i = 0; i < totgrid; ++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++)= offset + j*gridsize + k+1;
}
}
@@ -620,10 +651,10 @@ void *GPU_build_grid_buffers(DMGridData **grids,
for(i = 0; i < totgrid; ++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++)= offset + j*gridsize + k+1;
}
}
@@ -643,7 +674,6 @@ void *GPU_build_grid_buffers(DMGridData **grids,
/* Build VBO */
if(buffers->index_buf)
glGenBuffersARB(1, &buffers->vert_buf);
- GPU_update_grid_buffers(buffers, grids, grid_indices, totgrid, gridsize);
buffers->tot_quad = totquad;
@@ -831,9 +861,9 @@ void GPU_buffer_copy_vertex( DerivedMesh *dm, float *varray, int *index, int *re
DEBUG_VBO("GPU_buffer_copy_vertex\n");
mvert = dm->getVertArray(dm);
- mface = dm->getTessFaceArray(dm);
+ mface = dm->getFaceArray(dm);
- numfaces= dm->getNumTessFaces(dm);
+ numfaces= dm->getNumFaces(dm);
for( i=0; i < numfaces; i++ ) {
start = index[redir[mface[i].mat_nr+16383]];
if( mface[i].v4 )
@@ -875,13 +905,13 @@ void GPU_buffer_copy_normal( DerivedMesh *dm, float *varray, int *index, int *re
int start;
float norm[3];
- float *nors= dm->getTessFaceDataArray(dm, CD_NORMAL);
+ float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
MVert *mvert = dm->getVertArray(dm);
- MFace *mface = dm->getTessFaceArray(dm);
+ MFace *mface = dm->getFaceArray(dm);
DEBUG_VBO("GPU_buffer_copy_normal\n");
- numfaces= dm->getNumTessFaces(dm);
+ numfaces= dm->getNumFaces(dm);
for( i=0; i < numfaces; i++ ) {
start = index[redir[mface[i].mat_nr+16383]];
if( mface[i].v4 )
@@ -943,7 +973,7 @@ void GPU_buffer_copy_uv( DerivedMesh *dm, float *varray, int *index, int *redir,
DEBUG_VBO("GPU_buffer_copy_uv\n");
- mface = dm->getTessFaceArray(dm);
+ mface = dm->getFaceArray(dm);
mtface = DM_get_face_data_layer(dm, CD_MTFACE);
if( mtface == 0 ) {
@@ -951,7 +981,7 @@ void GPU_buffer_copy_uv( DerivedMesh *dm, float *varray, int *index, int *redir,
return;
}
- numfaces= dm->getNumTessFaces(dm);
+ numfaces= dm->getNumFaces(dm);
for( i=0; i < numfaces; i++ ) {
start = index[redir[mface[i].mat_nr+16383]];
if( mface[i].v4 )
@@ -987,11 +1017,11 @@ void GPU_buffer_copy_color3( DerivedMesh *dm, float *varray_, int *index, int *r
int i, numfaces;
unsigned char *varray = (unsigned char *)varray_;
unsigned char *mcol = (unsigned char *)user;
- MFace *mface = dm->getTessFaceArray(dm);
+ MFace *mface = dm->getFaceArray(dm);
DEBUG_VBO("GPU_buffer_copy_color3\n");
- numfaces= dm->getNumTessFaces(dm);
+ numfaces= dm->getNumFaces(dm);
for( i=0; i < numfaces; i++ ) {
int start = index[redir[mface[i].mat_nr+16383]];
if( mface[i].v4 )
@@ -1017,11 +1047,11 @@ void GPU_buffer_copy_color4( DerivedMesh *dm, float *varray_, int *index, int *r
int i, numfaces;
unsigned char *varray = (unsigned char *)varray_;
unsigned char *mcol = (unsigned char *)user;
- MFace *mface = dm->getTessFaceArray(dm);
+ MFace *mface = dm->getFaceArray(dm);
DEBUG_VBO("GPU_buffer_copy_color4\n");
- numfaces= dm->getNumTessFaces(dm);
+ numfaces= dm->getNumFaces(dm);
for( i=0; i < numfaces; i++ ) {
int start = index[redir[mface[i].mat_nr+16383]];
if( mface[i].v4 )
@@ -1061,7 +1091,7 @@ GPUBuffer *GPU_buffer_color( DerivedMesh *dm )
dm->drawObject->colType = CD_MCOL;
}
- numfaces= dm->getNumTessFaces(dm);
+ numfaces= dm->getNumFaces(dm);
colors = MEM_mallocN(numfaces*12*sizeof(unsigned char), "GPU_buffer_color");
for( i=0; i < numfaces*4; i++ ) {
colors[i*3] = mcol[i].b;
@@ -1113,7 +1143,7 @@ void GPU_buffer_copy_uvedge( DerivedMesh *dm, float *varray, int *index, int *re
if(tf) {
for(i = 0; i < dm->numFaceData; i++, tf++) {
MFace mf;
- dm->getTessFace(dm,i,&mf);
+ dm->getFace(dm,i,&mf);
VECCOPY2D(&varray[j],tf->uv[0]);
VECCOPY2D(&varray[j+2],tf->uv[1]);
@@ -1501,8 +1531,9 @@ void GPU_buffer_unbind()
else
break;
}
- if( GLStates != 0 )
+ if( GLStates != 0 ) {
DEBUG_VBO( "Some weird OpenGL state is still set. Why?" );
+ }
if( useVBOs )
glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
}