Showing the changes to interface/src/VoxelSystem.cpp (1 of 2 files). Show all
Unified · Split
| @@ -39,12 +39,16 @@ GLubyte identityIndices[] = { 0,1,2, 0,2,3, · 38 unmodified lines | ||
| 39 | 39 | VoxelSystem::VoxelSystem() { |
| 40 | 40 | voxelsRendered = 0; |
| 41 | 41 | tree = new VoxelTree(); |
| 42 | + pthread_mutex_init(&bufferWriteLock, NULL); | |
| 42 | 43 | } |
| 43 | 44 | |
| 44 | 45 | VoxelSystem::~VoxelSystem() { |
| 45 | − delete[] verticesArray; | |
| 46 | − delete[] colorsArray; | |
| 46 | + delete[] readVerticesArray; | |
| 47 | + delete[] writeVerticesArray; | |
| 48 | + delete[] readColorsArray; | |
| 49 | + delete[] writeColorsArray; | |
| 47 | 50 | delete tree; |
| 51 | + pthread_mutex_destroy(&bufferWriteLock); | |
| 48 | 52 | } |
| 49 | 53 | |
| 50 | 54 | ////////////////////////////////////////////////////////////////////////////////////////// |
| @@ -57,14 +61,8 @@ VoxelSystem::~VoxelSystem() { · 6 unmodified lines | ||
| 57 | 61 | void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) { |
| 58 | 62 | |
| 59 | 63 | tree->loadVoxelsFile(fileName,wantColorRandomizer); |
| 60 | − | |
| 61 | − // reset the verticesEndPointer so we're writing to the beginning of the array | |
| 62 | − verticesEndPointer = verticesArray; | |
| 63 | − // call recursive function to populate in memory arrays | |
| 64 | − // it will return the number of voxels added | |
| 65 | − voxelsRendered = treeToArrays(tree->rootNode); | |
| 66 | − // set the boolean if there are any voxels to be rendered so we re-fill the VBOs | |
| 67 | − voxelsToRender = (voxelsRendered > 0); | |
| 64 | + | |
| 65 | + copyWrittenDataToReadArrays(); | |
| 68 | 66 | } |
| 69 | 67 | |
| 70 | 68 | ////////////////////////////////////////////////////////////////////////////////////////// |
| @@ -77,14 +75,7 @@ void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) · 6 unmodified lines | ||
| 77 | 75 | void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer) { |
| 78 | 76 | |
| 79 | 77 | tree->createSphere(r,xc,yc,zc,s,solid,wantColorRandomizer); |
| 80 | − | |
| 81 | − // reset the verticesEndPointer so we're writing to the beginning of the array | |
| 82 | − verticesEndPointer = verticesArray; | |
| 83 | − // call recursive function to populate in memory arrays | |
| 84 | − // it will return the number of voxels added | |
| 85 | − voxelsRendered = treeToArrays(tree->rootNode); | |
| 86 | − // set the boolean if there are any voxels to be rendered so we re-fill the VBOs | |
| 87 | − voxelsToRender = (voxelsRendered > 0); | |
| 78 | + setupNewVoxelsForDrawing(); | |
| 88 | 79 | } |
| 89 | 80 | |
| 90 | 81 | |
| @@ -95,20 +86,32 @@ void VoxelSystem::parseData(void *data, int size) { · 4 unmodified lines | ||
| 95 | 86 | // ask the VoxelTree to read the bitstream into the tree |
| 96 | 87 | tree->readBitstreamToTree(voxelData, size - 1); |
| 97 | 88 | |
| 89 | + setupNewVoxelsForDrawing(); | |
| 90 | +} | |
| 91 | + | |
| 92 | +void VoxelSystem::setupNewVoxelsForDrawing() { | |
| 98 | 93 | // reset the verticesEndPointer so we're writing to the beginning of the array |
| 99 | − verticesEndPointer = verticesArray; | |
| 100 | − | |
| 94 | + writeVerticesEndPointer = writeVerticesArray; | |
| 101 | 95 | // call recursive function to populate in memory arrays |
| 102 | 96 | // it will return the number of voxels added |
| 103 | − int newVoxels = treeToArrays(tree->rootNode); | |
| 97 | + voxelsRendered = treeToArrays(tree->rootNode); | |
| 104 | 98 | |
| 105 | − if (newVoxels > voxelsRendered) { | |
| 106 | − | |
| 107 | − voxelsRendered = newVoxels; | |
| 108 | − | |
| 109 | − // set the boolean if there are any voxels to be rendered so we re-fill the VBOs | |
| 110 | − voxelsToRender = true; | |
| 111 | − } | |
| 99 | + // copy the newly written data to the arrays designated for reading | |
| 100 | + copyWrittenDataToReadArrays(); | |
| 101 | +} | |
| 102 | + | |
| 103 | +void VoxelSystem::copyWrittenDataToReadArrays() { | |
| 104 | + // lock on the buffer write lock so we can't modify the data when the GPU is reading it | |
| 105 | + pthread_mutex_lock(&bufferWriteLock); | |
| 106 | + // store a pointer to the current end so it doesn't change during copy | |
| 107 | + GLfloat *endOfCurrentVerticesData = writeVerticesEndPointer; | |
| 108 | + // copy the vertices and colors | |
| 109 | + memcpy(readVerticesArray, writeVerticesArray, (endOfCurrentVerticesData - writeVerticesArray) * sizeof(GLfloat)); | |
| 110 | + memcpy(readColorsArray, writeColorsArray, (endOfCurrentVerticesData - writeVerticesArray) * sizeof(GLubyte)); | |
| 111 | + | |
| 112 | + // set the read vertices end pointer to the correct spot so the GPU knows how much to pull | |
| 113 | + readVerticesEndPointer = readVerticesArray + (endOfCurrentVerticesData - writeVerticesArray); | |
| 114 | + pthread_mutex_unlock(&bufferWriteLock); | |
| 112 | 115 | } |
| 113 | 116 | |
| 114 | 117 | int VoxelSystem::treeToArrays(VoxelNode *currentNode) { |
| @@ -130,10 +133,10 @@ int VoxelSystem::treeToArrays(VoxelNode *currentNode) { · 15 unmodified lines | ||
| 130 | 133 | // populate the array with points for the 8 vertices |
| 131 | 134 | // and RGB color for each added vertex |
| 132 | 135 | for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) { |
| 133 | − *verticesEndPointer = startVertex[j % 3] + (identityVertices[j] * voxelScale); | |
| 134 | − *(colorsArray + (verticesEndPointer - verticesArray)) = currentNode->color[j % 3]; | |
| 136 | + *writeVerticesEndPointer = startVertex[j % 3] + (identityVertices[j] * voxelScale); | |
| 137 | + *(writeColorsArray + (writeVerticesEndPointer - writeVerticesArray)) = currentNode->color[j % 3]; | |
| 135 | 138 | |
| 136 | − verticesEndPointer++; | |
| 139 | + writeVerticesEndPointer++; | |
| 137 | 140 | } |
| 138 | 141 | |
| 139 | 142 | voxelsAdded++; |
| @@ -151,8 +154,10 @@ VoxelSystem* VoxelSystem::clone() const { · 11 unmodified lines | ||
| 151 | 154 | |
| 152 | 155 | void VoxelSystem::init() { |
| 153 | 156 | // prep the data structures for incoming voxel data |
| 154 | − verticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM]; | |
| 155 | − colorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM]; | |
| 157 | + writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM]; | |
| 158 | + readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM]; | |
| 159 | + writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM]; | |
| 160 | + readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM]; | |
| 156 | 161 | |
| 157 | 162 | GLuint *indicesArray = new GLuint[INDICES_PER_VOXEL * MAX_VOXELS_PER_SYSTEM]; |
| 158 | 163 | |
| @@ -195,16 +200,24 @@ void VoxelSystem::render() { · 36 unmodified lines | ||
| 195 | 200 | |
| 196 | 201 | glPushMatrix(); |
| 197 | 202 | |
| 198 | − if (voxelsToRender) { | |
| 199 | − glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID); | |
| 200 | − glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW); | |
| 201 | − glBufferSubData(GL_ARRAY_BUFFER, 0, (verticesEndPointer - verticesArray) * sizeof(GLfloat), verticesArray); | |
| 202 | − | |
| 203 | − glBindBuffer(GL_ARRAY_BUFFER, vboColorsID); | |
| 204 | − glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW); | |
| 205 | − glBufferSubData(GL_ARRAY_BUFFER, 0, (verticesEndPointer - verticesArray) * sizeof(GLubyte), colorsArray); | |
| 206 | − | |
| 207 | − voxelsToRender = false; | |
| 203 | + | |
| 204 | + if (readVerticesEndPointer != readVerticesArray) { | |
| 205 | + // try to lock on the buffer write | |
| 206 | + // just avoid pulling new data if it is currently being written | |
| 207 | + if (pthread_mutex_trylock(&bufferWriteLock) == 0) { | |
| 208 | + | |
| 209 | + glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID); | |
| 210 | + glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW); | |
| 211 | + glBufferSubData(GL_ARRAY_BUFFER, 0, (readVerticesEndPointer - readVerticesArray) * sizeof(GLfloat), readVerticesArray); | |
| 212 | + | |
| 213 | + glBindBuffer(GL_ARRAY_BUFFER, vboColorsID); | |
| 214 | + glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW); | |
| 215 | + glBufferSubData(GL_ARRAY_BUFFER, 0, (readVerticesEndPointer - readVerticesArray) * sizeof(GLubyte), readColorsArray); | |
| 216 | + | |
| 217 | + readVerticesEndPointer = readVerticesArray; | |
| 218 | + | |
| 219 | + pthread_mutex_unlock(&bufferWriteLock); | |
| 220 | + } | |
| 208 | 221 | } |
| 209 | 222 | |
| 210 | 223 | // tell OpenGL where to find vertex and color information |