mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 11:42:55 +02:00
don't do gross things if data is being written while GPU is copying it
This commit is contained in:
parent
b50f10fde4
commit
80170bd4c4
2 changed files with 65 additions and 47 deletions
|
@ -39,12 +39,16 @@ GLubyte identityIndices[] = { 0,1,2, 0,2,3,
|
||||||
VoxelSystem::VoxelSystem() {
|
VoxelSystem::VoxelSystem() {
|
||||||
voxelsRendered = 0;
|
voxelsRendered = 0;
|
||||||
tree = new VoxelTree();
|
tree = new VoxelTree();
|
||||||
|
pthread_mutex_init(&bufferWriteLock, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
VoxelSystem::~VoxelSystem() {
|
VoxelSystem::~VoxelSystem() {
|
||||||
delete[] verticesArray;
|
delete[] readVerticesArray;
|
||||||
delete[] colorsArray;
|
delete[] writeVerticesArray;
|
||||||
|
delete[] readColorsArray;
|
||||||
|
delete[] writeColorsArray;
|
||||||
delete tree;
|
delete tree;
|
||||||
|
pthread_mutex_destroy(&bufferWriteLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -57,14 +61,8 @@ VoxelSystem::~VoxelSystem() {
|
||||||
void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) {
|
void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) {
|
||||||
|
|
||||||
tree->loadVoxelsFile(fileName,wantColorRandomizer);
|
tree->loadVoxelsFile(fileName,wantColorRandomizer);
|
||||||
|
|
||||||
// reset the verticesEndPointer so we're writing to the beginning of the array
|
copyWrittenDataToReadArrays();
|
||||||
verticesEndPointer = verticesArray;
|
|
||||||
// call recursive function to populate in memory arrays
|
|
||||||
// it will return the number of voxels added
|
|
||||||
voxelsRendered = treeToArrays(tree->rootNode);
|
|
||||||
// set the boolean if there are any voxels to be rendered so we re-fill the VBOs
|
|
||||||
voxelsToRender = (voxelsRendered > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -77,14 +75,7 @@ void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer)
|
||||||
void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer) {
|
void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer) {
|
||||||
|
|
||||||
tree->createSphere(r,xc,yc,zc,s,solid,wantColorRandomizer);
|
tree->createSphere(r,xc,yc,zc,s,solid,wantColorRandomizer);
|
||||||
|
setupNewVoxelsForDrawing();
|
||||||
// reset the verticesEndPointer so we're writing to the beginning of the array
|
|
||||||
verticesEndPointer = verticesArray;
|
|
||||||
// call recursive function to populate in memory arrays
|
|
||||||
// it will return the number of voxels added
|
|
||||||
voxelsRendered = treeToArrays(tree->rootNode);
|
|
||||||
// set the boolean if there are any voxels to be rendered so we re-fill the VBOs
|
|
||||||
voxelsToRender = (voxelsRendered > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,20 +86,32 @@ void VoxelSystem::parseData(void *data, int size) {
|
||||||
// ask the VoxelTree to read the bitstream into the tree
|
// ask the VoxelTree to read the bitstream into the tree
|
||||||
tree->readBitstreamToTree(voxelData, size - 1);
|
tree->readBitstreamToTree(voxelData, size - 1);
|
||||||
|
|
||||||
|
setupNewVoxelsForDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::setupNewVoxelsForDrawing() {
|
||||||
// reset the verticesEndPointer so we're writing to the beginning of the array
|
// reset the verticesEndPointer so we're writing to the beginning of the array
|
||||||
verticesEndPointer = verticesArray;
|
writeVerticesEndPointer = writeVerticesArray;
|
||||||
|
|
||||||
// call recursive function to populate in memory arrays
|
// call recursive function to populate in memory arrays
|
||||||
// it will return the number of voxels added
|
// it will return the number of voxels added
|
||||||
int newVoxels = treeToArrays(tree->rootNode);
|
voxelsRendered = treeToArrays(tree->rootNode);
|
||||||
|
|
||||||
if (newVoxels > voxelsRendered) {
|
// copy the newly written data to the arrays designated for reading
|
||||||
|
copyWrittenDataToReadArrays();
|
||||||
voxelsRendered = newVoxels;
|
}
|
||||||
|
|
||||||
// set the boolean if there are any voxels to be rendered so we re-fill the VBOs
|
void VoxelSystem::copyWrittenDataToReadArrays() {
|
||||||
voxelsToRender = true;
|
// lock on the buffer write lock so we can't modify the data when the GPU is reading it
|
||||||
}
|
pthread_mutex_lock(&bufferWriteLock);
|
||||||
|
// store a pointer to the current end so it doesn't change during copy
|
||||||
|
GLfloat *endOfCurrentVerticesData = writeVerticesEndPointer;
|
||||||
|
// copy the vertices and colors
|
||||||
|
memcpy(readVerticesArray, writeVerticesArray, (endOfCurrentVerticesData - writeVerticesArray) * sizeof(GLfloat));
|
||||||
|
memcpy(readColorsArray, writeColorsArray, (endOfCurrentVerticesData - writeVerticesArray) * sizeof(GLubyte));
|
||||||
|
|
||||||
|
// set the read vertices end pointer to the correct spot so the GPU knows how much to pull
|
||||||
|
readVerticesEndPointer = readVerticesArray + (endOfCurrentVerticesData - writeVerticesArray);
|
||||||
|
pthread_mutex_unlock(&bufferWriteLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
int VoxelSystem::treeToArrays(VoxelNode *currentNode) {
|
int VoxelSystem::treeToArrays(VoxelNode *currentNode) {
|
||||||
|
@ -130,10 +133,10 @@ int VoxelSystem::treeToArrays(VoxelNode *currentNode) {
|
||||||
// populate the array with points for the 8 vertices
|
// populate the array with points for the 8 vertices
|
||||||
// and RGB color for each added vertex
|
// and RGB color for each added vertex
|
||||||
for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) {
|
for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) {
|
||||||
*verticesEndPointer = startVertex[j % 3] + (identityVertices[j] * voxelScale);
|
*writeVerticesEndPointer = startVertex[j % 3] + (identityVertices[j] * voxelScale);
|
||||||
*(colorsArray + (verticesEndPointer - verticesArray)) = currentNode->color[j % 3];
|
*(writeColorsArray + (writeVerticesEndPointer - writeVerticesArray)) = currentNode->color[j % 3];
|
||||||
|
|
||||||
verticesEndPointer++;
|
writeVerticesEndPointer++;
|
||||||
}
|
}
|
||||||
|
|
||||||
voxelsAdded++;
|
voxelsAdded++;
|
||||||
|
@ -151,8 +154,10 @@ VoxelSystem* VoxelSystem::clone() const {
|
||||||
|
|
||||||
void VoxelSystem::init() {
|
void VoxelSystem::init() {
|
||||||
// prep the data structures for incoming voxel data
|
// prep the data structures for incoming voxel data
|
||||||
verticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
|
writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
|
||||||
colorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
|
readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
|
||||||
|
writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
|
||||||
|
readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
|
||||||
|
|
||||||
GLuint *indicesArray = new GLuint[INDICES_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
|
GLuint *indicesArray = new GLuint[INDICES_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
|
||||||
|
|
||||||
|
@ -195,16 +200,24 @@ void VoxelSystem::render() {
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
||||||
if (voxelsToRender) {
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);
|
if (readVerticesEndPointer != readVerticesArray) {
|
||||||
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW);
|
// try to lock on the buffer write
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, 0, (verticesEndPointer - verticesArray) * sizeof(GLfloat), verticesArray);
|
// just avoid pulling new data if it is currently being written
|
||||||
|
if (pthread_mutex_trylock(&bufferWriteLock) == 0) {
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vboColorsID);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW);
|
glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, 0, (verticesEndPointer - verticesArray) * sizeof(GLubyte), colorsArray);
|
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, 0, (readVerticesEndPointer - readVerticesArray) * sizeof(GLfloat), readVerticesArray);
|
||||||
voxelsToRender = false;
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vboColorsID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, 0, (readVerticesEndPointer - readVerticesArray) * sizeof(GLubyte), readColorsArray);
|
||||||
|
|
||||||
|
readVerticesEndPointer = readVerticesArray;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&bufferWriteLock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// tell OpenGL where to find vertex and color information
|
// tell OpenGL where to find vertex and color information
|
||||||
|
|
|
@ -38,15 +38,20 @@ public:
|
||||||
private:
|
private:
|
||||||
int voxelsRendered;
|
int voxelsRendered;
|
||||||
VoxelTree *tree;
|
VoxelTree *tree;
|
||||||
bool voxelsToRender;
|
GLfloat *readVerticesArray;
|
||||||
GLfloat *verticesArray;
|
GLubyte *readColorsArray;
|
||||||
GLubyte *colorsArray;
|
GLfloat *readVerticesEndPointer;
|
||||||
GLfloat *verticesEndPointer;
|
GLfloat *writeVerticesArray;
|
||||||
|
GLubyte *writeColorsArray;
|
||||||
|
GLfloat *writeVerticesEndPointer;
|
||||||
GLuint vboVerticesID;
|
GLuint vboVerticesID;
|
||||||
GLuint vboColorsID;
|
GLuint vboColorsID;
|
||||||
GLuint vboIndicesID;
|
GLuint vboIndicesID;
|
||||||
|
pthread_mutex_t bufferWriteLock;
|
||||||
|
|
||||||
int treeToArrays(VoxelNode *currentNode);
|
int treeToArrays(VoxelNode *currentNode);
|
||||||
|
void setupNewVoxelsForDrawing();
|
||||||
|
void copyWrittenDataToReadArrays();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue