History

first cut at improved render pipeline

ZappoMan committed 13 years ago

Commit 4f86b551 parent 04b291810 files · +1226 −241Browse files

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

Unified · Split

interface/src/VoxelSystem.cpp+174−181
@@ -41,69 +41,53 @@ GLubyte identityIndices[] = { 0,2,1, 0,3,2, // Z- . · 40 unmodified lines
41 4,5,6, 4,6,7 }; // Z+ .41 4,5,6, 4,6,7 }; // Z+ .
42 42
43VoxelSystem::VoxelSystem() {43VoxelSystem::VoxelSystem() {
44 voxelsRendered = 0;44 _voxelsInArrays = _voxelsUpdated = 0;
45 tree = new VoxelTree();45 _tree = new VoxelTree();
46 pthread_mutex_init(&bufferWriteLock, NULL);46 pthread_mutex_init(&_bufferWriteLock, NULL);
47}47}
48 48
49VoxelSystem::~VoxelSystem() {49VoxelSystem::~VoxelSystem() {
50 delete[] readVerticesArray;50 delete[] _readVerticesArray;
51 delete[] writeVerticesArray;51 delete[] _writeVerticesArray;
52 delete[] readColorsArray;52 delete[] _readColorsArray;
53 delete[] writeColorsArray;53 delete[] _writeColorsArray;
54 delete tree;54 delete[] _voxelDirtyArray;
55 pthread_mutex_destroy(&bufferWriteLock);55 delete _tree;
56 pthread_mutex_destroy(&_bufferWriteLock);
56}57}
57 58
58//////////////////////////////////////////////////////////////////////////////////////////
59// Method: VoxelSystem::loadVoxelsFile()
60// Description: Loads HiFidelity encoded Voxels from a binary file. The current file
61// format is a stream of single voxels with NO color data. Currently
62// colors are set randomly
63// Complaints: Brad :)
64// To Do: Need to add color data to the file.
65void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) {59void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) {
66 60 _tree->loadVoxelsFile(fileName, wantColorRandomizer);
67 tree->loadVoxelsFile(fileName,wantColorRandomizer);
68
69 copyWrittenDataToReadArrays();61 copyWrittenDataToReadArrays();
70}62}
71 63
72//////////////////////////////////////////////////////////////////////////////////////////
73// Method: VoxelSystem::createSphere()
74// Description: Creates a sphere of voxels in the local system at a given location/radius
75// To Do: Move this function someplace better? I put it here because we need a
76// mechanism to tell the system to redraw it's arrays after voxels are done
77// being added. This is a concept mostly only understood by VoxelSystem.
78// Complaints: Brad :)
79void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer) {64void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer) {
80 65 _tree->createSphere(r, xc, yc, zc, s, solid, wantColorRandomizer);
81 tree->createSphere(r,xc,yc,zc,s,solid,wantColorRandomizer);
82 setupNewVoxelsForDrawing();66 setupNewVoxelsForDrawing();
83}67}
84 68
85long int VoxelSystem::getVoxelsCreated() {69long int VoxelSystem::getVoxelsCreated() {
86 return tree->voxelsCreated;70 return _tree->voxelsCreated;
87}71}
88 72
89float VoxelSystem::getVoxelsCreatedPerSecondAverage() {73float VoxelSystem::getVoxelsCreatedPerSecondAverage() {
90 return (1 / tree->voxelsCreatedStats.getEventDeltaAverage());74 return (1 / _tree->voxelsCreatedStats.getEventDeltaAverage());
91}75}
92 76
93long int VoxelSystem::getVoxelsColored() {77long int VoxelSystem::getVoxelsColored() {
94 return tree->voxelsColored;78 return _tree->voxelsColored;
95}79}
96 80
97float VoxelSystem::getVoxelsColoredPerSecondAverage() {81float VoxelSystem::getVoxelsColoredPerSecondAverage() {
98 return (1 / tree->voxelsColoredStats.getEventDeltaAverage());82 return (1 / _tree->voxelsColoredStats.getEventDeltaAverage());
99}83}
100 84
101long int VoxelSystem::getVoxelsBytesRead() {85long int VoxelSystem::getVoxelsBytesRead() {
102 return tree->voxelsBytesRead;86 return _tree->voxelsBytesRead;
103}87}
104 88
105float VoxelSystem::getVoxelsBytesReadPerSecondAverage() {89float VoxelSystem::getVoxelsBytesReadPerSecondAverage() {
106 return tree->voxelsBytesReadStats.getAverageSampleValuePerSecond();90 return _tree->voxelsBytesReadStats.getAverageSampleValuePerSecond();
107}91}
108 92
109int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {93int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
@@ -114,11 +98,11 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 4 unmodified lines
114 switch(command) {98 switch(command) {
115 case PACKET_HEADER_VOXEL_DATA:99 case PACKET_HEADER_VOXEL_DATA:
116 // ask the VoxelTree to read the bitstream into the tree100 // ask the VoxelTree to read the bitstream into the tree
117 tree->readBitstreamToTree(voxelData, numBytes - 1);101 _tree->readBitstreamToTree(voxelData, numBytes - 1);
118 break;102 break;
119 case PACKET_HEADER_ERASE_VOXEL:103 case PACKET_HEADER_ERASE_VOXEL:
120 // ask the tree to read the "remove" bitstream104 // ask the tree to read the "remove" bitstream
121 tree->processRemoveVoxelBitstream(sourceBuffer, numBytes);105 _tree->processRemoveVoxelBitstream(sourceBuffer, numBytes);
122 break;106 break;
123 case PACKET_HEADER_Z_COMMAND:107 case PACKET_HEADER_Z_COMMAND:
124 108
@@ -135,7 +119,8 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 10 unmodified lines
135 while (totalLength <= numBytes) {119 while (totalLength <= numBytes) {
136 if (0==strcmp(command,(char*)"erase all")) {120 if (0==strcmp(command,(char*)"erase all")) {
137 printLog("got Z message == erase all\n");121 printLog("got Z message == erase all\n");
138 tree->eraseAllVoxels();122 _tree->eraseAllVoxels();
123 _voxelsInArrays = 0; // better way to do this??
139 }124 }
140 if (0==strcmp(command,(char*)"add scene")) {125 if (0==strcmp(command,(char*)"add scene")) {
141 printLog("got Z message == add scene - NOT SUPPORTED ON INTERFACE\n");126 printLog("got Z message == add scene - NOT SUPPORTED ON INTERFACE\n");
@@ -150,78 +135,87 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 8 unmodified lines
150}135}
151 136
152void VoxelSystem::setupNewVoxelsForDrawing() {137void VoxelSystem::setupNewVoxelsForDrawing() {
153 // reset the verticesEndPointer so we're writing to the beginning of the array138 _voxelsUpdated = newTreeToArrays(_tree->rootNode);
154 writeVerticesEndPointer = writeVerticesArray;139 if (_voxelsUpdated) {
155 // call recursive function to populate in memory arrays140 _voxelsDirty=true;
156 // it will return the number of voxels added141 }
157 glm::vec3 treeRoot = glm::vec3(0,0,0);142
158 voxelsRendered = treeToArrays(tree->rootNode, treeRoot);
159 // copy the newly written data to the arrays designated for reading143 // copy the newly written data to the arrays designated for reading
160 copyWrittenDataToReadArrays();144 copyWrittenDataToReadArrays();
161}145}
162 146
163void VoxelSystem::copyWrittenDataToReadArrays() {147void VoxelSystem::copyWrittenDataToReadArrays() {
164 // lock on the buffer write lock so we can't modify the data when the GPU is reading it148 if (_voxelsDirty) {
165 pthread_mutex_lock(&bufferWriteLock);149 // lock on the buffer write lock so we can't modify the data when the GPU is reading it
166 // store a pointer to the current end so it doesn't change during copy150 pthread_mutex_lock(&_bufferWriteLock);
167 GLfloat *endOfCurrentVerticesData = writeVerticesEndPointer;151 int bytesOfVertices = (_voxelsInArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLfloat);
168 // copy the vertices and colors152 int bytesOfColors = (_voxelsInArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLubyte);
169 memcpy(readVerticesArray, writeVerticesArray, (endOfCurrentVerticesData - writeVerticesArray) * sizeof(GLfloat));153 memcpy(_readVerticesArray, _writeVerticesArray, bytesOfVertices);
170 memcpy(readColorsArray, writeColorsArray, (endOfCurrentVerticesData - writeVerticesArray) * sizeof(GLubyte));154 memcpy(_readColorsArray, _writeColorsArray, bytesOfColors );
171 // set the read vertices end pointer to the correct spot so the GPU knows how much to pull155 pthread_mutex_unlock(&_bufferWriteLock);
172 readVerticesEndPointer = readVerticesArray + (endOfCurrentVerticesData - writeVerticesArray);156 }
173 pthread_mutex_unlock(&bufferWriteLock);
174}157}
175 158
176int VoxelSystem::treeToArrays(VoxelNode* currentNode, const glm::vec3& nodePosition) {159int VoxelSystem::newTreeToArrays(VoxelNode* node) {
177 int voxelsAdded = 0;160 assert(_viewFrustum); // you must set up _viewFrustum before calling this
178 float halfUnitForVoxel = powf(0.5, *currentNode->octalCode) * (0.5 * TREE_SCALE);161 int voxelsUpdated = 0;
179 glm::vec3 viewerPosition = _camera->getPosition(); //_viewerAvatar->getPosition();162 float distanceToNode = node->distanceToCamera(*_viewFrustum);
180 163 float boundary = boundaryDistanceForRenderLevel(*node->octalCode + 1);
181 // debug LOD code164 float childBoundary = boundaryDistanceForRenderLevel(*node->octalCode + 2);
182 glm::vec3 debugNodePosition;165 bool inBoundary = (distanceToNode <= boundary);
183 copyFirstVertexForCode(currentNode->octalCode,(float*)&debugNodePosition);166 bool inChildBoundary = (distanceToNode <= childBoundary);
184 167 bool shouldRender = node->isColored() && ((node->isLeaf() && inChildBoundary) || (inBoundary && !inChildBoundary));
185 float distanceToVoxelCenter = sqrtf(powf(viewerPosition.x - nodePosition[0] - halfUnitForVoxel, 2) +168
186 powf(viewerPosition.y - nodePosition[1] - halfUnitForVoxel, 2) +169 node->setShouldRender(shouldRender);
187 powf(viewerPosition.z - nodePosition[2] - halfUnitForVoxel, 2));170 // let children figure out their renderness
188 171 for (int i = 0; i < 8; i++) {
189 int renderLevel = *currentNode->octalCode + 1;172 if (node->children[i]) {
190 int boundaryPosition = boundaryDistanceForRenderLevel(renderLevel);173 voxelsUpdated += newTreeToArrays(node->children[i]);
191 bool alwaysDraw = false; // XXXBHG - temporary debug code. Flip this to true to disable LOD blurring
192
193 if (alwaysDraw || distanceToVoxelCenter < boundaryPosition) {
194 for (int i = 0; i < 8; i++) {
195 // check if there is a child here
196 if (currentNode->children[i] != NULL) {
197
198 glm::vec3 childNodePosition;
199 copyFirstVertexForCode(currentNode->children[i]->octalCode,(float*)&childNodePosition);
200 childNodePosition *= (float)TREE_SCALE; // scale it up
201 voxelsAdded += treeToArrays(currentNode->children[i], childNodePosition);
202 }
203 }174 }
204 }175 }
176
177 // Now, if we've changed any attributes (our renderness, our color, etc) then update the Arrays... for us
178 if (node->isDirty() && (shouldRender || node->isKnownBufferIndex())) {
179 glm::vec3 startVertex;
180 float voxelScale = 0;
181
182 // If we're should render, use our legit location and scale,
183 if (node->getShouldRender()) {
184 copyFirstVertexForCode(node->octalCode, (float*)&startVertex);
185 voxelScale = (1 / powf(2, *node->octalCode));
186 } else {
187 // if we shouldn't render then set out location to some infinitely distant location,
188 // and our scale as infinitely small
189 startVertex[0] = startVertex[1] = startVertex[2] = FLT_MAX;
190 voxelScale = 0;
191 }
205 192
206 // if we didn't get any voxels added then we're a leaf193 // If this node has not yet been written to the array, then add it to the end of the array.
207 // add our vertex and color information to the interleaved array194 glBufferIndex nodeIndex;
208 if (voxelsAdded == 0 && currentNode->isColored()) {195 if (node->isKnownBufferIndex()) {
209 float startVertex[3];196 nodeIndex = node->getBufferIndex();
210 copyFirstVertexForCode(currentNode->octalCode,(float*)&startVertex);197 } else {
211 float voxelScale = 1 / powf(2, *currentNode->octalCode);198 nodeIndex = _voxelsInArrays;
199 }
200
201 _voxelDirtyArray[nodeIndex] = true;
212 202
213 // populate the array with points for the 8 vertices203 // populate the array with points for the 8 vertices
214 // and RGB color for each added vertex204 // and RGB color for each added vertex
215 for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) {205 for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) {
216 *writeVerticesEndPointer = startVertex[j % 3] + (identityVertices[j] * voxelScale);206 GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
217 *(writeColorsArray + (writeVerticesEndPointer - writeVerticesArray)) = currentNode->getColor()[j % 3];207 GLubyte* writeColorsAt = _writeColorsArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
218 208 *(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale);
219 writeVerticesEndPointer++;209 *(writeColorsAt +j) = node->getColor()[j % 3];
210 }
211 if (!node->isKnownBufferIndex()) {
212 node->setBufferIndex(nodeIndex);
213 _voxelsInArrays++; // our know vertices in the arrays
220 }214 }
221 voxelsAdded++;215 voxelsUpdated++;
216 node->clearDirtyBit();
222 }217 }
223 218 return voxelsUpdated;
224 return voxelsAdded;
225}219}
226 220
227VoxelSystem* VoxelSystem::clone() const {221VoxelSystem* VoxelSystem::clone() const {
@@ -230,20 +224,30 @@ VoxelSystem* VoxelSystem::clone() const { · 2 unmodified lines
230}224}
231 225
232void VoxelSystem::init() {226void VoxelSystem::init() {
227
228 // When we change voxels representations in the arrays, we'll update this
229 _voxelsDirty = false;
230 _voxelsInArrays = 0;
231
232 // we will track individual dirty sections with this array of bools
233 _voxelDirtyArray = new bool[MAX_VOXELS_PER_SYSTEM];
234 memset(_voxelDirtyArray, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool));
235
233 // prep the data structures for incoming voxel data236 // prep the data structures for incoming voxel data
234 writeVerticesEndPointer = writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];237 _writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
235 readVerticesEndPointer = readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];238 _readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
236 writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];239
237 readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];240 _writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
241 _readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
238 242
239 GLuint *indicesArray = new GLuint[INDICES_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];243 GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
240 244
241 // populate the indicesArray245 // populate the indicesArray
242 // this will not change given new voxels, so we can set it all up now246 // this will not change given new voxels, so we can set it all up now
243 for (int n = 0; n < MAX_VOXELS_PER_SYSTEM; n++) {247 for (int n = 0; n < MAX_VOXELS_PER_SYSTEM; n++) {
244 // fill the indices array248 // fill the indices array
245 int voxelIndexOffset = n * INDICES_PER_VOXEL;249 int voxelIndexOffset = n * INDICES_PER_VOXEL;
246 GLuint *currentIndicesPos = indicesArray + voxelIndexOffset;250 GLuint* currentIndicesPos = indicesArray + voxelIndexOffset;
247 int startIndex = (n * VERTICES_PER_VOXEL);251 int startIndex = (n * VERTICES_PER_VOXEL);
248 252
249 for (int i = 0; i < INDICES_PER_VOXEL; i++) {253 for (int i = 0; i < INDICES_PER_VOXEL; i++) {
@@ -252,8 +256,8 @@ void VoxelSystem::init() { · 2 unmodified lines
252 }256 }
253 }257 }
254 258
255 GLfloat *normalsArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];259 GLfloat* normalsArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
256 GLfloat *normalsArrayEndPointer = normalsArray;260 GLfloat* normalsArrayEndPointer = normalsArray;
257 261
258 // populate the normalsArray262 // populate the normalsArray
259 for (int n = 0; n < MAX_VOXELS_PER_SYSTEM; n++) {263 for (int n = 0; n < MAX_VOXELS_PER_SYSTEM; n++) {
@@ -263,25 +267,25 @@ void VoxelSystem::init() { · 3 unmodified lines
263 }267 }
264 268
265 // VBO for the verticesArray269 // VBO for the verticesArray
266 glGenBuffers(1, &vboVerticesID);270 glGenBuffers(1, &_vboVerticesID);
267 glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);271 glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
268 glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW);272 glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW);
269 273
270 // VBO for the normalsArray274 // VBO for the normalsArray
271 glGenBuffers(1, &vboNormalsID);275 glGenBuffers(1, &_vboNormalsID);
272 glBindBuffer(GL_ARRAY_BUFFER, vboNormalsID);276 glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID);
273 glBufferData(GL_ARRAY_BUFFER,277 glBufferData(GL_ARRAY_BUFFER,
274 VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * MAX_VOXELS_PER_SYSTEM,278 VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * MAX_VOXELS_PER_SYSTEM,
275 normalsArray, GL_STATIC_DRAW);279 normalsArray, GL_STATIC_DRAW);
276 280
277 // VBO for colorsArray281 // VBO for colorsArray
278 glGenBuffers(1, &vboColorsID);282 glGenBuffers(1, &_vboColorsID);
279 glBindBuffer(GL_ARRAY_BUFFER, vboColorsID);283 glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
280 glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW);284 glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW);
281 285
282 // VBO for the indicesArray286 // VBO for the indicesArray
283 glGenBuffers(1, &vboIndicesID);287 glGenBuffers(1, &_vboIndicesID);
284 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndicesID);288 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID);
285 glBufferData(GL_ELEMENT_ARRAY_BUFFER,289 glBufferData(GL_ELEMENT_ARRAY_BUFFER,
286 INDICES_PER_VOXEL * sizeof(GLuint) * MAX_VOXELS_PER_SYSTEM,290 INDICES_PER_VOXEL * sizeof(GLuint) * MAX_VOXELS_PER_SYSTEM,
287 indicesArray, GL_STATIC_DRAW);291 indicesArray, GL_STATIC_DRAW);
@@ -291,45 +295,68 @@ void VoxelSystem::init() { · 3 unmodified lines
291 delete[] normalsArray;295 delete[] normalsArray;
292}296}
293 297
294void VoxelSystem::render() {298void VoxelSystem::updateVBOs() {
295 299 if (_voxelsDirty) {
296 glPushMatrix();300 glBufferIndex segmentStart = 0;
297 301 glBufferIndex segmentEnd = 0;
298 if (readVerticesEndPointer != readVerticesArray) {302
299 // try to lock on the buffer write303 bool inSegment = false;
300 // just avoid pulling new data if it is currently being written304 for (glBufferIndex i = 0; i < _voxelsInArrays; i++) {
301 if (pthread_mutex_trylock(&bufferWriteLock) == 0) {305 if (!inSegment) {
302 306 if (_voxelDirtyArray[i]) {
303 glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);307 segmentStart = i;
304 glBufferSubData(GL_ARRAY_BUFFER, 0, (readVerticesEndPointer - readVerticesArray) * sizeof(GLfloat), readVerticesArray);308 inSegment = true;
305 309 _voxelDirtyArray[i] = false; // consider us clean!
306 glBindBuffer(GL_ARRAY_BUFFER, vboColorsID);310 }
307 glBufferSubData(GL_ARRAY_BUFFER, 0, (readVerticesEndPointer - readVerticesArray) * sizeof(GLubyte), readColorsArray);311 } else {
308 312 if (!_voxelDirtyArray[i] || (i == (_voxelsInArrays - 1)) ) {
309 readVerticesEndPointer = readVerticesArray;313 segmentEnd = i;
310 314 inSegment = false;
311 pthread_mutex_unlock(&bufferWriteLock);315 int segmentLength = (segmentEnd - segmentStart) + 1;
316
317 // vertices for segment - note: we might not need to do this
318 GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
319 GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
320 GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
321
322 glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
323 glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom);
324
325 // colors for segment
326 segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
327 segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
328 GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
329
330 glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
331 glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
332 }
333 }
312 }334 }
335 _voxelsDirty = false;
313 }336 }
337}
314 338
339void VoxelSystem::render() {
340 glPushMatrix();
341 updateVBOs();
315 // tell OpenGL where to find vertex and color information342 // tell OpenGL where to find vertex and color information
316 glEnableClientState(GL_VERTEX_ARRAY);343 glEnableClientState(GL_VERTEX_ARRAY);
317 glEnableClientState(GL_NORMAL_ARRAY);344 glEnableClientState(GL_NORMAL_ARRAY);
318 glEnableClientState(GL_COLOR_ARRAY);345 glEnableClientState(GL_COLOR_ARRAY);
319 346
320 glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);347 glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
321 glVertexPointer(3, GL_FLOAT, 0, 0);348 glVertexPointer(3, GL_FLOAT, 0, 0);
322 349
323 glBindBuffer(GL_ARRAY_BUFFER, vboNormalsID);350 glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID);
324 glNormalPointer(GL_FLOAT, 0, 0);351 glNormalPointer(GL_FLOAT, 0, 0);
325 352
326 glBindBuffer(GL_ARRAY_BUFFER, vboColorsID);353 glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
327 glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0);354 glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0);
328 355
329 // draw the number of voxels we have356 // draw the number of voxels we have
330 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndicesID);357 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID);
331 glScalef(10, 10, 10);358 glScalef(10, 10, 10);
332 glDrawElements(GL_TRIANGLES, 36 * voxelsRendered, GL_UNSIGNED_INT, 0);359 glDrawElements(GL_TRIANGLES, 36 * _voxelsInArrays, GL_UNSIGNED_INT, 0);
333 360
334 // deactivate vertex and color arrays after drawing361 // deactivate vertex and color arrays after drawing
335 glDisableClientState(GL_VERTEX_ARRAY);362 glDisableClientState(GL_VERTEX_ARRAY);
@@ -350,12 +377,7 @@ void VoxelSystem::simulate(float deltaTime) { · 14 unmodified lines
350 377
351int VoxelSystem::_nodeCount = 0;378int VoxelSystem::_nodeCount = 0;
352 379
353bool VoxelSystem::randomColorOperation(VoxelNode* node, bool down, void* extraData) {380bool VoxelSystem::randomColorOperation(VoxelNode* node, void* extraData) {
354
355 // we do our operations on the way up!
356 if (down) {
357 return true;
358 }
359 381
360 _nodeCount++;382 _nodeCount++;
361 if (node->isColored()) {383 if (node->isColored()) {
@@ -370,17 +392,12 @@ bool VoxelSystem::randomColorOperation(VoxelNode* node, bool down, void* extraDa · 8 unmodified lines
370 392
371void VoxelSystem::randomizeVoxelColors() {393void VoxelSystem::randomizeVoxelColors() {
372 _nodeCount = 0;394 _nodeCount = 0;
373 tree->recurseTreeWithOperation(randomColorOperation);395 _tree->recurseTreeWithOperation(randomColorOperation);
374 printLog("setting randomized true color for %d nodes\n",_nodeCount);396 printLog("setting randomized true color for %d nodes\n",_nodeCount);
375 setupNewVoxelsForDrawing();397 setupNewVoxelsForDrawing();
376}398}
377 399
378bool VoxelSystem::falseColorizeRandomOperation(VoxelNode* node, bool down, void* extraData) {400bool VoxelSystem::falseColorizeRandomOperation(VoxelNode* node, void* extraData) {
379
380 // we do our operations on the way up!
381 if (down) {
382 return true;
383 }
384 401
385 _nodeCount++;402 _nodeCount++;
386 403
@@ -395,18 +412,12 @@ bool VoxelSystem::falseColorizeRandomOperation(VoxelNode* node, bool down, void* · 8 unmodified lines
395 412
396void VoxelSystem::falseColorizeRandom() {413void VoxelSystem::falseColorizeRandom() {
397 _nodeCount = 0;414 _nodeCount = 0;
398 tree->recurseTreeWithOperation(falseColorizeRandomOperation);415 _tree->recurseTreeWithOperation(falseColorizeRandomOperation);
399 printLog("setting randomized false color for %d nodes\n",_nodeCount);416 printLog("setting randomized false color for %d nodes\n",_nodeCount);
400 setupNewVoxelsForDrawing();417 setupNewVoxelsForDrawing();
401}418}
402 419
403bool VoxelSystem::trueColorizeOperation(VoxelNode* node, bool down, void* extraData) {420bool VoxelSystem::trueColorizeOperation(VoxelNode* node, void* extraData) {
404
405 // we do our operations on the way up!
406 if (down) {
407 return true;
408 }
409
410 _nodeCount++;421 _nodeCount++;
411 node->setFalseColored(false);422 node->setFalseColored(false);
412 return true;423 return true;
@@ -414,19 +425,13 @@ bool VoxelSystem::trueColorizeOperation(VoxelNode* node, bool down, void* extraD · 1 unmodified line
414 425
415void VoxelSystem::trueColorize() {426void VoxelSystem::trueColorize() {
416 _nodeCount = 0;427 _nodeCount = 0;
417 tree->recurseTreeWithOperation(trueColorizeOperation);428 _tree->recurseTreeWithOperation(trueColorizeOperation);
418 printLog("setting true color for %d nodes\n",_nodeCount);429 printLog("setting true color for %d nodes\n",_nodeCount);
419 setupNewVoxelsForDrawing();430 setupNewVoxelsForDrawing();
420}431}
421 432
422// Will false colorize voxels that are not in view433// Will false colorize voxels that are not in view
423bool VoxelSystem::falseColorizeInViewOperation(VoxelNode* node, bool down, void* extraData) {434bool VoxelSystem::falseColorizeInViewOperation(VoxelNode* node, void* extraData) {
424
425 // we do our operations on the way up!
426 if (down) {
427 return true;
428 }
429
430 const ViewFrustum* viewFrustum = (const ViewFrustum*) extraData;435 const ViewFrustum* viewFrustum = (const ViewFrustum*) extraData;
431 436
432 _nodeCount++;437 _nodeCount++;
@@ -448,25 +453,17 @@ bool VoxelSystem::falseColorizeInViewOperation(VoxelNode* node, bool down, void* · 15 unmodified lines
448 453
449void VoxelSystem::falseColorizeInView(ViewFrustum* viewFrustum) {454void VoxelSystem::falseColorizeInView(ViewFrustum* viewFrustum) {
450 _nodeCount = 0;455 _nodeCount = 0;
451 tree->recurseTreeWithOperation(falseColorizeInViewOperation,(void*)viewFrustum);456 _tree->recurseTreeWithOperation(falseColorizeInViewOperation,(void*)viewFrustum);
452 printLog("setting in view false color for %d nodes\n",_nodeCount);457 printLog("setting in view false color for %d nodes\n",_nodeCount);
453 setupNewVoxelsForDrawing();458 setupNewVoxelsForDrawing();
454}459}
455 460
456// Will false colorize voxels based on distance from view461// Will false colorize voxels based on distance from view
457bool VoxelSystem::falseColorizeDistanceFromViewOperation(VoxelNode* node, bool down, void* extraData) {462bool VoxelSystem::falseColorizeDistanceFromViewOperation(VoxelNode* node, void* extraData) {
458
459 // we do our operations on the way up!
460 if (down) {
461 return true;
462 }
463
464 ViewFrustum* viewFrustum = (ViewFrustum*) extraData;463 ViewFrustum* viewFrustum = (ViewFrustum*) extraData;
465 464
466 // only do this for truly colored voxels...465 // only do this for truly colored voxels...
467 if (node->isColored()) {466 if (node->isColored()) {
468
469 // We need our distance for both up and down
470 glm::vec3 nodePosition;467 glm::vec3 nodePosition;
471 float* startVertex = firstVertexForCode(node->octalCode);468 float* startVertex = firstVertexForCode(node->octalCode);
472 nodePosition.x = startVertex[0];469 nodePosition.x = startVertex[0];
@@ -508,13 +505,7 @@ float VoxelSystem::_minDistance = FLT_MAX; · 35 unmodified lines
508// Helper function will get the distance from view range, would be nice if you could just keep track505// Helper function will get the distance from view range, would be nice if you could just keep track
509// of this as voxels are created and/or colored... seems like some transform math could do that so506// of this as voxels are created and/or colored... seems like some transform math could do that so
510// we wouldn't need to do two passes of the tree507// we wouldn't need to do two passes of the tree
511bool VoxelSystem::getDistanceFromViewRangeOperation(VoxelNode* node, bool down, void* extraData) {508bool VoxelSystem::getDistanceFromViewRangeOperation(VoxelNode* node, void* extraData) {
512
513 // we do our operations on the way up!
514 if (down) {
515 return true;
516 }
517
518 ViewFrustum* viewFrustum = (ViewFrustum*) extraData;509 ViewFrustum* viewFrustum = (ViewFrustum*) extraData;
519 510
520 // only do this for truly colored voxels...511 // only do this for truly colored voxels...
@@ -538,7 +529,7 @@ bool VoxelSystem::getDistanceFromViewRangeOperation(VoxelNode* node, bool down, · 17 unmodified lines
538 powf(viewerPosition.y - nodePosition.y - halfUnitForVoxel, 2) +529 powf(viewerPosition.y - nodePosition.y - halfUnitForVoxel, 2) +
539 powf(viewerPosition.z - nodePosition.z - halfUnitForVoxel, 2));530 powf(viewerPosition.z - nodePosition.z - halfUnitForVoxel, 2));
540 531
541 // on way down, calculate the range of distances532 // calculate the range of distances
542 if (distance > _maxDistance) {533 if (distance > _maxDistance) {
543 _maxDistance = distance;534 _maxDistance = distance;
544 }535 }
@@ -556,12 +547,14 @@ void VoxelSystem::falseColorizeDistanceFromView(ViewFrustum* viewFrustum) { · 11 unmodified lines
556 547
557 _maxDistance = 0.0;548 _maxDistance = 0.0;
558 _minDistance = FLT_MAX;549 _minDistance = FLT_MAX;
559 tree->recurseTreeWithOperation(getDistanceFromViewRangeOperation,(void*)viewFrustum);550 _tree->recurseTreeWithOperation(getDistanceFromViewRangeOperation,(void*)viewFrustum);
560 printLog("determining distance range for %d nodes\n",_nodeCount);551 printLog("determining distance range for %d nodes\n",_nodeCount);
561 552
562 _nodeCount = 0;553 _nodeCount = 0;
563 554
564 tree->recurseTreeWithOperation(falseColorizeDistanceFromViewOperation,(void*)viewFrustum);555 _tree->recurseTreeWithOperation(falseColorizeDistanceFromViewOperation,(void*)viewFrustum);
565 printLog("setting in distance false color for %d nodes\n",_nodeCount);556 printLog("setting in distance false color for %d nodes\n",_nodeCount);
566 setupNewVoxelsForDrawing();557 setupNewVoxelsForDrawing();
567}558}
559
560