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
254254 _buffer.release();
255255 }
256256
257−HeightfieldBuffer::HeightfieldBuffer(const QByteArray& height, const QByteArray& color, const QByteArray& normal) :
257+HeightfieldBuffer::HeightfieldBuffer(const glm::vec3& translation, float scale,
258+ const QByteArray& height, const QByteArray& color) :
259+ _translation(translation),
260+ _scale(scale),
258261 _height(height),
259262 _color(color),
260− _normal(normal),
261263 _heightTexture(QOpenGLTexture::Target2D),
262− _colorTexture(QOpenGLTexture::Target2D),
263− _normalTexture(QOpenGLTexture::Target2D) {
264+ _colorTexture(QOpenGLTexture::Target2D) {
264265 }
265266
267+class HeightfieldPoint {
268+public:
269+ glm::vec2 textureCoord;
270+ glm::vec3 vertex;
271+};
272+
266273 void HeightfieldBuffer::render() {
267274 // initialize textures, etc. on first render
268275 if (!_heightTexture.isCreated()) {
@@ -273,21 +280,116 @@ void HeightfieldBuffer::render() { · 4 unmodified lines
273280 _heightTexture.setData(QOpenGLTexture::Luminance, QOpenGLTexture::UInt8, _height.data());
274281 _height.clear();
275282
276− int colorSize = glm::sqrt(_color.size() / 3);
277− _colorTexture.setSize(colorSize, colorSize);
283+ if (!_color.isEmpty()) {
284+ int colorSize = glm::sqrt(_color.size() / 3);
285+ _colorTexture.setSize(colorSize, colorSize);
286+ }
278287 _colorTexture.setFormat(QOpenGLTexture::RGBFormat);
279288 _colorTexture.allocateStorage();
280− _colorTexture.setData(QOpenGLTexture::BGR, QOpenGLTexture::UInt8, _color.data());
281− _color.clear();
289+ if (!_color.isEmpty()) {
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));
282343
283− int normalSize = glm::sqrt(_normal.size() / 3);
284− _normalTexture.setSize(normalSize, normalSize);
285− _normalTexture.setFormat(QOpenGLTexture::RGBFormat);
286− _normalTexture.allocateStorage();
287− _normalTexture.setData(QOpenGLTexture::BGR, QOpenGLTexture::UInt8, _normal.data());
288− _normal.clear();
344+ } else {
345+ bufferPair.first.bind();
346+ bufferPair.second.bind();
347+ }
348+
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+
371+QHash<int, HeightfieldBuffer::BufferPair> HeightfieldBuffer::_bufferPairs;
372+
373+void 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();
289385 }
290386
387+ glPopMatrix();
388+
389+ DefaultMetavoxelRendererImplementation::getHeightfieldProgram().release();
390+
391+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
392+ glDisableClientState(GL_VERTEX_ARRAY);
291393 }
292394
293395 BufferDataAttribute::BufferDataAttribute(const QString& name) :
@@ -368,11 +470,14 @@ int PointAugmentVisitor::visit(MetavoxelInfo& info) { · 74 unmodified lines
368470 { quint8(qRed(normal)), quint8(qGreen(normal)), quint8(qBlue(normal)) } };
369471 _points.append(point);
370472 }
371− if (info.size >= _pointLeafSize) {
372− BufferPointVector swapPoints;
373− _points.swap(swapPoints);
374− info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(
375− new PointBuffer(swapPoints))));
473+ if (info.size >= _pointLeafSize) {
474+ PointBuffer* buffer = NULL;
475+ if (!_points.isEmpty()) {
476+ BufferPointVector swapPoints;
477+ _points.swap(swapPoints);
478+ buffer = new PointBuffer(swapPoints);
479+ }
480+ info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(buffer)));
376481 }
377482 return STOP_RECURSION;
378483 }
@@ -381,10 +486,13 @@ bool PointAugmentVisitor::postVisit(MetavoxelInfo& info) { · 2 unmodified lines
381486 if (info.size != _pointLeafSize) {
382487 return false;
383488 }
384− BufferPointVector swapPoints;
385− _points.swap(swapPoints);
386− info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(
387− new PointBuffer(swapPoints))));
489+ PointBuffer* buffer = NULL;
490+ if (!_points.isEmpty()) {
491+ BufferPointVector swapPoints;
492+ _points.swap(swapPoints);
493+ buffer = new PointBuffer(swapPoints);
494+ }
495+ info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(buffer)));
388496 return true;
389497 }
390498
@@ -403,7 +511,18 @@ HeightfieldAugmentVisitor::HeightfieldAugmentVisitor(const MetavoxelLOD& lod) : · 12 unmodified lines
403511 }
404512
405513 int 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;
407526 }
408527
409528 void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const MetavoxelData& previous,
@@ -419,11 +538,19 @@ void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const · 9 unmodified lines
419538 data.setRoot(pointBufferAttribute, root);
420539 root->incrementReferenceCount();
421540 }
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+ }
422548
423− PointAugmentVisitor visitor(lod);
424− data.guideToDifferent(expandedPrevious, visitor);
425−
549+ PointAugmentVisitor pointAugmentVisitor(lod);
550+ data.guideToDifferent(expandedPrevious, pointAugmentVisitor);
426551
552+ HeightfieldAugmentVisitor heightfieldAugmentVisitor(lod);
553+ data.guideToDifferent(expandedPrevious, heightfieldAugmentVisitor);
427554 }
428555
429556 class SpannerSimulateVisitor : public SpannerVisitor {
@@ -530,16 +657,24 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox · 100 unmodified lines
530657
531658 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
532659
533− glDisableClientState(GL_VERTEX_ARRAY);
534660 glDisableClientState(GL_COLOR_ARRAY);
535661 glDisableClientState(GL_NORMAL_ARRAY);
536662
537663 _pointProgram.release();
538664
665+ _heightfieldProgram.bind();
666+
667+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
668+
539669 BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(),
540670 lod);
541671 data.guide(heightfieldRenderVisitor);
542672
673+ _heightfieldProgram.release();
674+
675+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
676+ glDisableClientState(GL_VERTEX_ARRAY);
677+
543678 glEnable(GL_BLEND);
544679 }
545680