History

don't do gross things if data is being written while GPU is copying it

Stephen Birarda committed 13 years ago

Commit 80170bd1 parent b50f10f2 files · +65 −47Browse files

Showing the changes to interface/src/VoxelSystem.cpp (1 of 2 files). Show all

Unified · Split

interface/src/VoxelSystem.cpp+56−43
@@ -39,12 +39,16 @@ GLubyte identityIndices[] = { 0,1,2, 0,2,3, · 38 unmodified lines
39VoxelSystem::VoxelSystem() {39VoxelSystem::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
44VoxelSystem::~VoxelSystem() { 45VoxelSystem::~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
57void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) {61void 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 array65 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
77void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer) {75void 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 tree86 // 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
92void VoxelSystem::setupNewVoxelsForDrawing() {
98 // reset the verticesEndPointer so we're writing to the beginning of the array93 // 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 arrays95 // call recursive function to populate in memory arrays
102 // it will return the number of voxels added96 // 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 VBOs103void 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
114int VoxelSystem::treeToArrays(VoxelNode *currentNode) {117int 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 vertices133 // populate the array with points for the 8 vertices
131 // and RGB color for each added vertex134 // 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
152void VoxelSystem::init() {155void VoxelSystem::init() {
153 // prep the data structures for incoming voxel data156 // 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 information223 // tell OpenGL where to find vertex and color information