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 | VoxelSystem::VoxelSystem() { | 39 | VoxelSystem::VoxelSystem() { |
| 40 | voxelsRendered = 0; | 40 | voxelsRendered = 0; |
| 41 | tree = new VoxelTree(); | 41 | tree = new VoxelTree(); |
| 42 | pthread_mutex_init(&bufferWriteLock, NULL); | ||
| 42 | } | 43 | } |
| 43 | 44 | ||
| 44 | VoxelSystem::~VoxelSystem() { | 45 | VoxelSystem::~VoxelSystem() { |
| 45 | delete[] verticesArray; | 46 | delete[] readVerticesArray; |
| 46 | delete[] colorsArray; | 47 | delete[] writeVerticesArray; |
| 48 | delete[] readColorsArray; | ||
| 49 | delete[] writeColorsArray; | ||
| 47 | delete tree; | 50 | delete tree; |
| 51 | pthread_mutex_destroy(&bufferWriteLock); | ||
| 48 | } | 52 | } |
| 49 | 53 | ||
| 50 | ////////////////////////////////////////////////////////////////////////////////////////// | 54 | ////////////////////////////////////////////////////////////////////////////////////////// |
| @@ -57,14 +61,8 @@ VoxelSystem::~VoxelSystem() { · 6 unmodified lines | |||
| 57 | void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) { | 61 | void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) { |
| 58 | 62 | ||
| 59 | tree->loadVoxelsFile(fileName,wantColorRandomizer); | 63 | tree->loadVoxelsFile(fileName,wantColorRandomizer); |
| 60 | 64 | ||
| 61 | // reset the verticesEndPointer so we're writing to the beginning of the array | 65 | copyWrittenDataToReadArrays(); |
| 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); | ||
| 68 | } | 66 | } |
| 69 | 67 | ||
| 70 | ////////////////////////////////////////////////////////////////////////////////////////// | 68 | ////////////////////////////////////////////////////////////////////////////////////////// |
| @@ -77,14 +75,7 @@ void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) · 6 unmodified lines | |||
| 77 | void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer) { | 75 | void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer) { |
| 78 | 76 | ||
| 79 | tree->createSphere(r,xc,yc,zc,s,solid,wantColorRandomizer); | 77 | tree->createSphere(r,xc,yc,zc,s,solid,wantColorRandomizer); |
| 80 | 78 | setupNewVoxelsForDrawing(); | |
| 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); | ||
| 88 | } | 79 | } |
| 89 | 80 | ||
| 90 | 81 | ||
| @@ -95,20 +86,32 @@ void VoxelSystem::parseData(void *data, int size) { · 4 unmodified lines | |||
| 95 | // ask the VoxelTree to read the bitstream into the tree | 86 | // ask the VoxelTree to read the bitstream into the tree |
| 96 | tree->readBitstreamToTree(voxelData, size - 1); | 87 | tree->readBitstreamToTree(voxelData, size - 1); |
| 97 | 88 | ||
| 89 | setupNewVoxelsForDrawing(); | ||
| 90 | } | ||
| 91 | |||
| 92 | void VoxelSystem::setupNewVoxelsForDrawing() { | ||
| 98 | // reset the verticesEndPointer so we're writing to the beginning of the array | 93 | // reset the verticesEndPointer so we're writing to the beginning of the array |
| 99 | verticesEndPointer = verticesArray; | 94 | writeVerticesEndPointer = writeVerticesArray; |
| 100 | |||
| 101 | // call recursive function to populate in memory arrays | 95 | // call recursive function to populate in memory arrays |
| 102 | // it will return the number of voxels added | 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) { | 99 | // copy the newly written data to the arrays designated for reading |
| 106 | 100 | copyWrittenDataToReadArrays(); | |
| 107 | voxelsRendered = newVoxels; | 101 | } |
| 108 | 102 | ||
| 109 | // set the boolean if there are any voxels to be rendered so we re-fill the VBOs | 103 | void VoxelSystem::copyWrittenDataToReadArrays() { |
| 110 | voxelsToRender = true; | 104 | // lock on the buffer write lock so we can't modify the data when the GPU is reading it |
| 111 | } | 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 | int VoxelSystem::treeToArrays(VoxelNode *currentNode) { | 117 | int VoxelSystem::treeToArrays(VoxelNode *currentNode) { |
| @@ -130,10 +133,10 @@ int VoxelSystem::treeToArrays(VoxelNode *currentNode) { · 15 unmodified lines | |||
| 130 | // populate the array with points for the 8 vertices | 133 | // populate the array with points for the 8 vertices |
| 131 | // and RGB color for each added vertex | 134 | // and RGB color for each added vertex |
| 132 | for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) { | 135 | for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) { |
| 133 | *verticesEndPointer = startVertex[j % 3] + (identityVertices[j] * voxelScale); | 136 | *writeVerticesEndPointer = startVertex[j % 3] + (identityVertices[j] * voxelScale); |
| 134 | *(colorsArray + (verticesEndPointer - verticesArray)) = currentNode->color[j % 3]; | 137 | *(writeColorsArray + (writeVerticesEndPointer - writeVerticesArray)) = currentNode->color[j % 3]; |
| 135 | 138 | ||
| 136 | verticesEndPointer++; | 139 | writeVerticesEndPointer++; |
| 137 | } | 140 | } |
| 138 | 141 | ||
| 139 | voxelsAdded++; | 142 | voxelsAdded++; |
| @@ -151,8 +154,10 @@ VoxelSystem* VoxelSystem::clone() const { · 11 unmodified lines | |||
| 151 | 154 | ||
| 152 | void VoxelSystem::init() { | 155 | void VoxelSystem::init() { |
| 153 | // prep the data structures for incoming voxel data | 156 | // prep the data structures for incoming voxel data |
| 154 | verticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM]; | 157 | writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM]; |
| 155 | colorsArray = new GLubyte[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 | GLuint *indicesArray = new GLuint[INDICES_PER_VOXEL * MAX_VOXELS_PER_SYSTEM]; | 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 | glPushMatrix(); | 201 | glPushMatrix(); |
| 197 | 202 | ||
| 198 | if (voxelsToRender) { | 203 | |
| 199 | glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID); | 204 | if (readVerticesEndPointer != readVerticesArray) { |
| 200 | glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW); | 205 | // try to lock on the buffer write |
| 201 | glBufferSubData(GL_ARRAY_BUFFER, 0, (verticesEndPointer - verticesArray) * sizeof(GLfloat), verticesArray); | 206 | // just avoid pulling new data if it is currently being written |
| 202 | 207 | if (pthread_mutex_trylock(&bufferWriteLock) == 0) { | |
| 203 | glBindBuffer(GL_ARRAY_BUFFER, vboColorsID); | 208 | |
| 204 | glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW); | 209 | glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID); |
| 205 | glBufferSubData(GL_ARRAY_BUFFER, 0, (verticesEndPointer - verticesArray) * sizeof(GLubyte), colorsArray); | 210 | glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW); |
| 206 | 211 | glBufferSubData(GL_ARRAY_BUFFER, 0, (readVerticesEndPointer - readVerticesArray) * sizeof(GLfloat), readVerticesArray); | |
| 207 | voxelsToRender = false; | 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 | // tell OpenGL where to find vertex and color information | 223 | // tell OpenGL where to find vertex and color information |