History

More work on heightfields.

Andrzej Kapolka committed 12 years ago

Commit d04eb621 parent aeee3694 files · +308 −33Browse files

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

Unified · Split

interface/src/MetavoxelSystem.cpp+163−28
@@ -254,15 +254,22 @@ void PointBuffer::render() { · 253 unmodified lines
254 _buffer.release();254 _buffer.release();
255}255}
256 256
257HeightfieldBuffer::HeightfieldBuffer(const QByteArray& height, const QByteArray& color, const QByteArray& normal) :257HeightfieldBuffer::HeightfieldBuffer(const glm::vec3& translation, float scale,
258 const QByteArray& height, const QByteArray& color) :
259 _translation(translation),
260 _scale(scale),
258 _height(height),261 _height(height),
259 _color(color),262 _color(color),
260 _normal(normal),
261 _heightTexture(QOpenGLTexture::Target2D),263 _heightTexture(QOpenGLTexture::Target2D),
262 _colorTexture(QOpenGLTexture::Target2D),264 _colorTexture(QOpenGLTexture::Target2D) {
263 _normalTexture(QOpenGLTexture::Target2D) {
264}265}
265 266
267class HeightfieldPoint {
268public:
269 glm::vec2 textureCoord;
270 glm::vec3 vertex;
271};
272
266void HeightfieldBuffer::render() {273void HeightfieldBuffer::render() {
267 // initialize textures, etc. on first render274 // initialize textures, etc. on first render
268 if (!_heightTexture.isCreated()) {275 if (!_heightTexture.isCreated()) {
@@ -273,21 +280,116 @@ void HeightfieldBuffer::render() { · 4 unmodified lines
273 _heightTexture.setData(QOpenGLTexture::Luminance, QOpenGLTexture::UInt8, _height.data());280 _heightTexture.setData(QOpenGLTexture::Luminance, QOpenGLTexture::UInt8, _height.data());
274 _height.clear();281 _height.clear();
275 282
276 int colorSize = glm::sqrt(_color.size() / 3);283 if (!_color.isEmpty()) {
277 _colorTexture.setSize(colorSize, colorSize);284 int colorSize = glm::sqrt(_color.size() / 3);
285 _colorTexture.setSize(colorSize, colorSize);
286 }
278 _colorTexture.setFormat(QOpenGLTexture::RGBFormat);287 _colorTexture.setFormat(QOpenGLTexture::RGBFormat);
279 _colorTexture.allocateStorage();288 _colorTexture.allocateStorage();
280 _colorTexture.setData(QOpenGLTexture::BGR, QOpenGLTexture::UInt8, _color.data());289 if (!_color.isEmpty()) {
281 _color.clear();290 _colorTexture.setData(QOpenGLTexture::BGR, QOpenGLTexture::UInt8, _color.data());
291 _color.clear();
292
293 } else {
294 const quint8 WHITE_COLOR[] = { 255, 255, 255 };
295 _colorTexture.setData(QOpenGLTexture::BGR, QOpenGLTexture::UInt8, const_cast<quint8*>(WHITE_COLOR));
296 }
297 }
298 // create the buffer objects lazily
299 int size = _heightTexture.width();
300 int sizeWithSkirt = size + 2;
301 int vertexCount = sizeWithSkirt * sizeWithSkirt;
302 int rows = sizeWithSkirt - 1;
303 int indexCount = rows * rows * 4;
304 BufferPair& bufferPair = _bufferPairs[size];
305 if (!bufferPair.first.isCreated()) {
306 QVector<HeightfieldPoint> vertices(vertexCount);
307 HeightfieldPoint* point = vertices.data();
308
309 float step = 1.0f / (size - 1);
310 float z = -step;
311 for (int i = 0; i < sizeWithSkirt; i++, z += step) {
312 float x = -step;
313 const float SKIRT_LENGTH = 1.0f;
314 float baseY = (i == 0 || i == sizeWithSkirt - 1) ? -SKIRT_LENGTH : 0.0f;
315 for (int j = 0; j < sizeWithSkirt; j++, point++, x += step) {
316 point->vertex = glm::vec3(x, (j == 0 || j == sizeWithSkirt - 1) ? -SKIRT_LENGTH : baseY, z);
317 point->textureCoord = glm::vec2(x, z);
318 }
319 }
320
321 bufferPair.first.setUsagePattern(QOpenGLBuffer::StaticDraw);
322 bufferPair.first.create();
323 bufferPair.first.bind();
324 bufferPair.first.allocate(vertices.constData(), vertexCount * sizeof(HeightfieldPoint));
325
326 QVector<int> indices(indexCount);
327 int* index = indices.data();
328 for (int i = 0; i < rows; i++) {
329 int lineIndex = i * sizeWithSkirt;
330 int nextLineIndex = (i + 1) * sizeWithSkirt;
331 for (int j = 0; j < rows; j++) {
332 *index++ = lineIndex + j;
333 *index++ = lineIndex + j + 1;
334 *index++ = nextLineIndex + j;
335 *index++ = nextLineIndex + j + 1;
336 }
337 }
338
339 bufferPair.second = QOpenGLBuffer(QOpenGLBuffer::IndexBuffer);
340 bufferPair.second.create();
341 bufferPair.second.bind();
342 bufferPair.second.allocate(indices.constData(), indexCount * sizeof(int));
282 343
283 int normalSize = glm::sqrt(_normal.size() / 3);344 } else {
284 _normalTexture.setSize(normalSize, normalSize);345 bufferPair.first.bind();
285 _normalTexture.setFormat(QOpenGLTexture::RGBFormat);346 bufferPair.second.bind();
286 _normalTexture.allocateStorage();347 }
287 _normalTexture.setData(QOpenGLTexture::BGR, QOpenGLTexture::UInt8, _normal.data());348
288 _normal.clear();349 HeightfieldPoint* point = 0;
350 glVertexPointer(3, GL_FLOAT, sizeof(HeightfieldPoint), &point->vertex);
351 glTexCoordPointer(2, GL_FLOAT, sizeof(HeightfieldPoint), &point->textureCoord);
352
353 glPushMatrix();
354 glTranslatef(_translation.x, _translation.y, _translation.z);
355 glScalef(_scale, _scale, _scale);
356
357 _heightTexture.bind(0);
358 _colorTexture.bind(1);
359
360 glDrawRangeElements(GL_QUADS, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0);
361
362 _colorTexture.release(1);
363 _heightTexture.release(0);
364
365 glPopMatrix();
366
367 bufferPair.first.release();
368 bufferPair.second.release();
369}
370
371QHash<int, HeightfieldBuffer::BufferPair> HeightfieldBuffer::_bufferPairs;
372
373void HeightfieldPreview::render(const glm::vec3& translation, float scale) const {
374 glEnableClientState(GL_VERTEX_ARRAY);
375 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
376
377 DefaultMetavoxelRendererImplementation::getHeightfieldProgram().bind();
378
379 glPushMatrix();
380 glTranslatef(translation.x, translation.y, translation.z);
381 glScalef(scale, scale, scale);
382
383 foreach (const BufferDataPointer& buffer, _buffers) {
384 buffer->render();
289 }385 }
290 386
387 glPopMatrix();
388
389 DefaultMetavoxelRendererImplementation::getHeightfieldProgram().release();
390
391 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
392 glDisableClientState(GL_VERTEX_ARRAY);
291}393}
292 394
293BufferDataAttribute::BufferDataAttribute(const QString& name) :395BufferDataAttribute::BufferDataAttribute(const QString& name) :
@@ -368,11 +470,14 @@ int PointAugmentVisitor::visit(MetavoxelInfo& info) { · 74 unmodified lines
368 { quint8(qRed(normal)), quint8(qGreen(normal)), quint8(qBlue(normal)) } };470 { quint8(qRed(normal)), quint8(qGreen(normal)), quint8(qBlue(normal)) } };
369 _points.append(point);471 _points.append(point);
370 }472 }
371 if (info.size >= _pointLeafSize) { 473 if (info.size >= _pointLeafSize) {
372 BufferPointVector swapPoints;474 PointBuffer* buffer = NULL;
373 _points.swap(swapPoints);475 if (!_points.isEmpty()) {
374 info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(476 BufferPointVector swapPoints;
375 new PointBuffer(swapPoints))));477 _points.swap(swapPoints);
478 buffer = new PointBuffer(swapPoints);
479 }
480 info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(buffer)));
376 }481 }
377 return STOP_RECURSION;482 return STOP_RECURSION;
378}483}
@@ -381,10 +486,13 @@ bool PointAugmentVisitor::postVisit(MetavoxelInfo& info) { · 2 unmodified lines
381 if (info.size != _pointLeafSize) {486 if (info.size != _pointLeafSize) {
382 return false;487 return false;
383 }488 }
384 BufferPointVector swapPoints;489 PointBuffer* buffer = NULL;
385 _points.swap(swapPoints);490 if (!_points.isEmpty()) {
386 info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(491 BufferPointVector swapPoints;
387 new PointBuffer(swapPoints))));492 _points.swap(swapPoints);
493 buffer = new PointBuffer(swapPoints);
494 }
495 info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(buffer)));
388 return true;496 return true;
389}497}
390 498
@@ -403,7 +511,18 @@ HeightfieldAugmentVisitor::HeightfieldAugmentVisitor(const MetavoxelLOD& lod) : · 12 unmodified lines
403}511}
404 512
405int HeightfieldAugmentVisitor::visit(MetavoxelInfo& info) {513int HeightfieldAugmentVisitor::visit(MetavoxelInfo& info) {
406 return STOP_RECURSION;514 if (info.isLeaf) {
515 HeightfieldBuffer* buffer = NULL;
516 HeightfieldDataPointer height = info.inputValues.at(0).getInlineValue<HeightfieldDataPointer>();
517 if (height) {
518 HeightfieldDataPointer color = info.inputValues.at(1).getInlineValue<HeightfieldDataPointer>();
519 buffer = new HeightfieldBuffer(info.minimum, info.size, height->getContents(),
520 color ? color->getContents() : QByteArray());
521 }
522 info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(buffer)));
523 return STOP_RECURSION;
524 }
525 return DEFAULT_ORDER;
407}526}
408 527
409void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const MetavoxelData& previous,528void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const MetavoxelData& previous,
@@ -419,11 +538,19 @@ void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const · 9 unmodified lines
419 data.setRoot(pointBufferAttribute, root);538 data.setRoot(pointBufferAttribute, root);
420 root->incrementReferenceCount();539 root->incrementReferenceCount();
421 }540 }
541 const AttributePointer& heightfieldBufferAttribute =
542 Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute();
543 root = expandedPrevious.getRoot(heightfieldBufferAttribute);
544 if (root) {
545 data.setRoot(heightfieldBufferAttribute, root);
546 root->incrementReferenceCount();
547 }
422 548
423 PointAugmentVisitor visitor(lod);549 PointAugmentVisitor pointAugmentVisitor(lod);
424 data.guideToDifferent(expandedPrevious, visitor);550 data.guideToDifferent(expandedPrevious, pointAugmentVisitor);
425
426 551
552 HeightfieldAugmentVisitor heightfieldAugmentVisitor(lod);
553 data.guideToDifferent(expandedPrevious, heightfieldAugmentVisitor);
427}554}
428 555
429class SpannerSimulateVisitor : public SpannerVisitor {556class SpannerSimulateVisitor : public SpannerVisitor {
@@ -530,16 +657,24 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox · 100 unmodified lines
530 657
531 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);658 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
532 659
533 glDisableClientState(GL_VERTEX_ARRAY);
534 glDisableClientState(GL_COLOR_ARRAY);660 glDisableClientState(GL_COLOR_ARRAY);
535 glDisableClientState(GL_NORMAL_ARRAY);661 glDisableClientState(GL_NORMAL_ARRAY);
536 662
537 _pointProgram.release();663 _pointProgram.release();
538 664
665 _heightfieldProgram.bind();
666
667 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
668
539 BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(),669 BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(),
540 lod);670 lod);
541 data.guide(heightfieldRenderVisitor);671 data.guide(heightfieldRenderVisitor);
542 672
673 _heightfieldProgram.release();
674
675 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
676 glDisableClientState(GL_VERTEX_ARRAY);
677
543 glEnable(GL_BLEND);678 glEnable(GL_BLEND);
544}679}
545 680