History

second cut at view culling voxels

ZappoMan committed 13 years ago

Commit 09923d11 parent 89226b12 files · +115 −51Browse files

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

Unified · Split

interface/src/VoxelSystem.cpp+107−49
@@ -42,7 +42,8 @@ GLubyte identityIndices[] = { 0,2,1, 0,3,2, // Z- . · 41 unmodified lines
4242 4,5,6, 4,6,7 }; // Z+ .
4343
4444 VoxelSystem::VoxelSystem() {
45− _voxelsInArrays = _voxelsUpdated = 0;
45+ _voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0;
46+ _alwaysRenderFullVBO = true;
4647 _tree = new VoxelTree();
4748 pthread_mutex_init(&_bufferWriteLock, NULL);
4849 pthread_mutex_init(&_voxelCleanupLock, NULL);
@@ -61,7 +62,7 @@ VoxelSystem::~VoxelSystem() { · 12 unmodified lines
6162
6263 void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) {
6364 _tree->loadVoxelsFile(fileName, wantColorRandomizer);
64− copyWrittenDataToReadArrays();
65+ setupNewVoxelsForDrawing();
6566 }
6667
6768 void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer) {
@@ -130,7 +131,7 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 62 unmodified lines
130131 if (0==strcmp(command,(char*)"erase all")) {
131132 printLog("got Z message == erase all\n");
132133 _tree->eraseAllVoxels();
133− _voxelsInArrays = 0; // better way to do this??
134+ _voxelsInReadArrays = _voxelsInWriteArrays = 0; // better way to do this??
134135 }
135136 if (0==strcmp(command,(char*)"add scene")) {
136137 printLog("got Z message == add scene - NOT SUPPORTED ON INTERFACE\n");
@@ -145,34 +146,41 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 8 unmodified lines
145146 }
146147
147148 void VoxelSystem::setupNewVoxelsForDrawing() {
148− PerformanceWarning warn(_renderWarningsOn, "copyWrittenDataToReadArrays()"); // would like to include _voxelsInArrays, _voxelsUpdated
149+ PerformanceWarning warn(_renderWarningsOn, "setupNewVoxelsForDrawing()"); // would like to include _voxelsInArrays, _voxelsUpdated
149150 double start = usecTimestampNow();
150− double sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished);
151+ double sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000.0;
151152
152153 if (sinceLastTime <= std::max(_setupNewVoxelsForDrawingLastElapsed,SIXTY_FPS_IN_MILLISECONDS)) {
153154 return; // bail early, it hasn't been long enough since the last time we ran
154155 }
156+
157+ double sinceLastViewCulling = (start - _lastViewCulling) / 1000.0;
155158
156159 // If the view frustum has changed, since last time, then remove nodes that are out of view
157− //if (hasViewChanged()) {
158− // removeOutOfView();
159− //}
160+ if ((sinceLastViewCulling >= VIEW_CULLING_RATE_IN_MILLISECONDS) && hasViewChanged()) {
161+ _lastViewCulling = start;
162+ removeOutOfView();
163+ }
160164
161165 if (_tree->isDirty()) {
166+ PerformanceWarning warn(_renderWarningsOn, "calling... newTreeToArrays()");
162167 _callsToTreesToArrays++;
168+
169+ if (_alwaysRenderFullVBO) {
170+ _voxelsInWriteArrays = 0; // reset our VBO
171+ }
163172 _voxelsUpdated = newTreeToArrays(_tree->rootNode);
164173 _tree->clearDirtyBit(); // after we pull the trees into the array, we can consider the tree clean
165174 } else {
166175 _voxelsUpdated = 0;
167176 }
177+ //printLog("setupNewVoxelsForDrawing() AFTER treeToArray _voxelsUpdated=%ld _voxelsDirty=%s\n", _voxelsUpdated, (_voxelsDirty ? "yes" : "no"));
168178 if (_voxelsUpdated) {
169179 _voxelsDirty=true;
170180 }
171181
172− if (_voxelsDirty) {
173− // copy the newly written data to the arrays designated for reading
174− copyWrittenDataToReadArrays();
175− }
182+ // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated
183+ copyWrittenDataToReadArrays();
176184
177185 double end = usecTimestampNow();
178186 double elapsedmsec = (end - start)/1000.0;
@@ -185,16 +193,18 @@ void VoxelSystem::copyWrittenDataToReadArrays() { · 6 unmodified lines
185193 if (_voxelsDirty && _voxelsUpdated) {
186194 // lock on the buffer write lock so we can't modify the data when the GPU is reading it
187195 pthread_mutex_lock(&_bufferWriteLock);
188− int bytesOfVertices = (_voxelsInArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLfloat);
189− int bytesOfColors = (_voxelsInArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLubyte);
196+ int bytesOfVertices = (_voxelsInWriteArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLfloat);
197+ int bytesOfColors = (_voxelsInWriteArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLubyte);
190198 memcpy(_readVerticesArray, _writeVerticesArray, bytesOfVertices);
191199 memcpy(_readColorsArray, _writeColorsArray, bytesOfColors );
200+ _voxelsInReadArrays = _voxelsInWriteArrays;
192201 pthread_mutex_unlock(&_bufferWriteLock);
193202 }
194203 }
195204
196205 int VoxelSystem::newTreeToArrays(VoxelNode* node) {
197206 assert(_viewFrustum); // you must set up _viewFrustum before calling this
207+
198208 int voxelsUpdated = 0;
199209 bool shouldRender = false; // assume we don't need to render it
200210
@@ -217,9 +227,39 @@ int VoxelSystem::newTreeToArrays(VoxelNode* node) { · 16 unmodified lines
217227 voxelsUpdated += newTreeToArrays(node->getChildAtIndex(i));
218228 }
219229 }
220−
230+
231+ if (_alwaysRenderFullVBO) {
232+ voxelsUpdated += newway__updateNodeInArray(node);
233+ } else {
234+ voxelsUpdated += oldway__updateNodeInArray(node);
235+ }
236+ node->clearDirtyBit(); // always clear the dirty bit, even if it doesn't need to be rendered
237+ return voxelsUpdated;
238+}
239+
240+int VoxelSystem::newway__updateNodeInArray(VoxelNode* node) {
241+ if (node->getShouldRender()) {
242+ glm::vec3 startVertex = node->getCorner();
243+ float voxelScale = node->getScale();
244+ glBufferIndex nodeIndex = _voxelsInWriteArrays;
245+
246+ // populate the array with points for the 8 vertices
247+ // and RGB color for each added vertex
248+ for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) {
249+ GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
250+ GLubyte* writeColorsAt = _writeColorsArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
251+ *(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale);
252+ *(writeColorsAt +j) = node->getColor()[j % 3];
253+ }
254+ _voxelsInWriteArrays++; // our know vertices in the arrays
255+ return 1; // rendered
256+ }
257+ return 0; // not-rendered
258+}
259+
260+int VoxelSystem::oldway__updateNodeInArray(VoxelNode* node) {
221261 // Now, if we've changed any attributes (our renderness, our color, etc) then update the Arrays... for us
222− if (node->isDirty() && (shouldRender || node->isKnownBufferIndex())) {
262+ if (node->isDirty() && (node->getShouldRender() || node->isKnownBufferIndex())) {
223263 glm::vec3 startVertex;
224264 float voxelScale = 0;
225265
@@ -239,7 +279,7 @@ int VoxelSystem::newTreeToArrays(VoxelNode* node) { · 13 unmodified lines
239279 if (node->isKnownBufferIndex()) {
240280 nodeIndex = node->getBufferIndex();
241281 } else {
242− nodeIndex = _voxelsInArrays;
282+ nodeIndex = _voxelsInWriteArrays;
243283 }
244284
245285 _voxelDirtyArray[nodeIndex] = true;
@@ -254,12 +294,11 @@ int VoxelSystem::newTreeToArrays(VoxelNode* node) { · 8 unmodified lines
254294 }
255295 if (!node->isKnownBufferIndex()) {
256296 node->setBufferIndex(nodeIndex);
257− _voxelsInArrays++; // our know vertices in the arrays
297+ _voxelsInWriteArrays++; // our know vertices in the arrays
258298 }
259− voxelsUpdated++;
299+ return 1; // updated!
260300 }
261− node->clearDirtyBit(); // always clear the dirty bit, even if it doesn't need to be rendered
262− return voxelsUpdated;
301+ return 0; // not-updated
263302 }
264303
265304 VoxelSystem* VoxelSystem::clone() const {
@@ -273,10 +312,12 @@ void VoxelSystem::init() { · 7 unmodified lines
273312 _callsToTreesToArrays = 0;
274313 _setupNewVoxelsForDrawingLastFinished = 0;
275314 _setupNewVoxelsForDrawingLastElapsed = 0;
315+ _lastViewCulling = 0;
276316
277317 // When we change voxels representations in the arrays, we'll update this
278318 _voxelsDirty = false;
279− _voxelsInArrays = 0;
319+ _voxelsInWriteArrays = 0;
320+ _voxelsInReadArrays = 0;
280321 _unusedArraySpace = 0;
281322
282323 // we will track individual dirty sections with this array of bools
@@ -348,31 +389,48 @@ void VoxelSystem::init() { · 65 unmodified lines
348389 void VoxelSystem::updateVBOs() {
349390 PerformanceWarning warn(_renderWarningsOn, "updateVBOs()"); // would like to include _callsToTreesToArrays
350391 if (_voxelsDirty) {
351− glBufferIndex segmentStart = 0;
352− glBufferIndex segmentEnd = 0;
353− bool inSegment = false;
354− for (glBufferIndex i = 0; i < _voxelsInArrays; i++) {
355− if (!inSegment) {
356− if (_voxelDirtyArray[i]) {
357− segmentStart = i;
358− inSegment = true;
359− _voxelDirtyArray[i] = false; // consider us clean!
360− }
361− } else {
362− if (!_voxelDirtyArray[i] || (i == (_voxelsInArrays - 1)) ) {
363− segmentEnd = i;
364− inSegment = false;
365− int segmentLength = (segmentEnd - segmentStart) + 1;
366− GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
367− GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
368− GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
369− glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
370− glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom);
371− segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
372− segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
373− GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
374− glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
375− glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
392+ if (_alwaysRenderFullVBO) {
393+ glBufferIndex segmentStart = 0;
394+ glBufferIndex segmentEnd = _voxelsInWriteArrays;
395+
396+ int segmentLength = (segmentEnd - segmentStart) + 1;
397+ GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
398+ GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
399+ GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
400+ glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
401+ glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom);
402+ segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
403+ segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
404+ GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
405+ glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
406+ glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
407+ } else {
408+ glBufferIndex segmentStart = 0;
409+ glBufferIndex segmentEnd = 0;
410+ bool inSegment = false;
411+ for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) {
412+ if (!inSegment) {
413+ if (_voxelDirtyArray[i]) {
414+ segmentStart = i;
415+ inSegment = true;
416+ _voxelDirtyArray[i] = false; // consider us clean!
417+ }
418+ } else {
419+ if (!_voxelDirtyArray[i] || (i == (_voxelsInWriteArrays - 1)) ) {
420+ segmentEnd = i;
421+ inSegment = false;
422+ int segmentLength = (segmentEnd - segmentStart) + 1;
423+ GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
424+ GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
425+ GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
426+ glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
427+ glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom);
428+ segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
429+ segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
430+ GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
431+ glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
432+ glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
433+ }
376434 }
377435 }
378436 }
@@ -403,7 +461,7 @@ void VoxelSystem::render() { · 24 unmodified lines
403461 // draw the number of voxels we have
404462 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID);
405463 glScalef(TREE_SCALE, TREE_SCALE, TREE_SCALE);
406− glDrawElements(GL_TRIANGLES, 36 * _voxelsInArrays, GL_UNSIGNED_INT, 0);
464+ glDrawElements(GL_TRIANGLES, 36 * _voxelsInReadArrays, GL_UNSIGNED_INT, 0);
407465
408466 // deactivate vertex and color arrays after drawing
409467 glDisableClientState(GL_VERTEX_ARRAY);
@@ -422,7 +480,7 @@ int VoxelSystem::_nodeCount = 0; · 12 unmodified lines
422480
423481 void VoxelSystem::killLocalVoxels() {
424482 _tree->eraseAllVoxels();
425− _voxelsInArrays = 0; // better way to do this??
483+ _voxelsInWriteArrays = _voxelsInReadArrays = 0; // better way to do this??
426484 //setupNewVoxelsForDrawing();
427485 }
428486