From 84a2a8b83d375f20e8758dd4b39e8fe7d541a5a9 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 29 Dec 2014 14:37:53 -0800 Subject: [PATCH] Working on rendering. --- interface/src/MetavoxelSystem.cpp | 75 ++++++++++++++++++++++++++++ interface/src/MetavoxelSystem.h | 3 ++ libraries/metavoxels/src/Spanner.cpp | 41 ++++++++++----- libraries/metavoxels/src/Spanner.h | 5 +- 4 files changed, 111 insertions(+), 13 deletions(-) diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index f91dac7d0f..d4c562a870 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + // include this before QOpenGLFramebufferObject, which includes an earlier version of OpenGL #include "InterfaceConfig.h" @@ -34,6 +36,8 @@ #include "Application.h" #include "MetavoxelSystem.h" +using namespace std; + REGISTER_META_OBJECT(DefaultMetavoxelRendererImplementation) REGISTER_META_OBJECT(SphereRenderer) REGISTER_META_OBJECT(CuboidRenderer) @@ -365,6 +369,12 @@ void MetavoxelSystem::render() { _baseVoxelProgram.bind(); foreach (const MetavoxelBatch& batch, _voxelBaseBatches) { + glPushMatrix(); + glTranslatef(batch.translation.x, batch.translation.y, batch.translation.z); + glm::vec3 axis = glm::axis(batch.rotation); + glRotatef(glm::degrees(glm::angle(batch.rotation)), axis.x, axis.y, axis.z); + glScalef(batch.scale.x, batch.scale.y, batch.scale.z); + batch.vertexBuffer->bind(); batch.indexBuffer->bind(); @@ -377,6 +387,8 @@ void MetavoxelSystem::render() { batch.vertexBuffer->release(); batch.indexBuffer->release(); + + glPopMatrix(); } _baseVoxelProgram.release(); @@ -398,6 +410,12 @@ void MetavoxelSystem::render() { _splatVoxelProgram.enableAttributeArray(_splatVoxelLocations.materialWeights); foreach (const VoxelSplatBatch& batch, _voxelSplatBatches) { + glPushMatrix(); + glTranslatef(batch.translation.x, batch.translation.y, batch.translation.z); + glm::vec3 axis = glm::axis(batch.rotation); + glRotatef(glm::degrees(glm::angle(batch.rotation)), axis.x, axis.y, axis.z); + glScalef(batch.scale.x, batch.scale.y, batch.scale.z); + batch.vertexBuffer->bind(); batch.indexBuffer->bind(); @@ -443,6 +461,8 @@ void MetavoxelSystem::render() { batch.vertexBuffer->release(); batch.indexBuffer->release(); + + glPopMatrix(); } glDisable(GL_POLYGON_OFFSET_FILL); @@ -474,6 +494,12 @@ void MetavoxelSystem::render() { DependencyManager::get()->bindSimpleProgram(); foreach (const HermiteBatch& batch, _hermiteBatches) { + glPushMatrix(); + glTranslatef(batch.translation.x, batch.translation.y, batch.translation.z); + glm::vec3 axis = glm::axis(batch.rotation); + glRotatef(glm::degrees(glm::angle(batch.rotation)), axis.x, axis.y, axis.z); + glScalef(batch.scale.x, batch.scale.y, batch.scale.z); + batch.vertexBuffer->bind(); glVertexPointer(3, GL_FLOAT, 0, 0); @@ -481,6 +507,8 @@ void MetavoxelSystem::render() { glDrawArrays(GL_LINES, 0, batch.vertexCount); batch.vertexBuffer->release(); + + glPopMatrix(); } DependencyManager::get()->releaseSimpleProgram(); @@ -1247,6 +1275,9 @@ void VoxelBuffer::render(const glm::vec3& translation, const glm::quat& rotation _hermite.clear(); } HermiteBatch hermiteBatch; + hermiteBatch.translation = translation; + hermiteBatch.rotation = rotation; + hermiteBatch.scale = scale; hermiteBatch.vertexBuffer = &_hermiteBuffer; hermiteBatch.vertexCount = _hermiteCount; Application::getInstance()->getMetavoxels()->addHermiteBatch(hermiteBatch); @@ -2267,6 +2298,50 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g QVector hermiteSegments; QMultiHash quadIndices; + int stackWidth = node->getStack()->getWidth(); + int stackHeight = node->getStack()->getContents().size() / stackWidth; + int innerStackWidth = stackWidth - HeightfieldData::SHARED_EDGE; + int innerStackHeight = stackHeight - HeightfieldData::SHARED_EDGE; + const StackArray* src = node->getStack()->getContents().constData(); + glm::vec3 pos; + glm::vec3 step(1.0f / innerStackWidth, scale.x / (innerStackWidth * scale.y), + 1.0f / innerStackHeight); + bool displayHermite = Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData); + + for (int z = 0; z < stackHeight; z++, pos.z += step.z) { + pos.x = 0.0f; + for (int x = 0; x < stackWidth; x++, src++, pos.x += step.x) { + if (src->isEmpty()) { + continue; + } + pos.y = src->getPosition() * step.y; + for (const StackArray::Entry* entry = src->getEntryData(), *end = entry + src->getEntryCount(); entry != end; + entry++, pos.y += step.y) { + if (displayHermite) { + glm::vec3 normal; + float distance = entry->getHermiteX(normal); + if (normal != glm::vec3()) { + glm::vec3 start = pos + glm::vec3(distance * step.x, 0.0f, 0.0f); + hermiteSegments.append(start); + hermiteSegments.append(start + normal * step); + } + distance = entry->getHermiteY(normal); + if (normal != glm::vec3()) { + glm::vec3 start = pos + glm::vec3(0.0f, distance * step.y, 0.0f); + hermiteSegments.append(start); + hermiteSegments.append(start + normal * step); + } + distance = entry->getHermiteZ(normal); + if (normal != glm::vec3()) { + glm::vec3 start = pos + glm::vec3(0.0f, 0.0f, distance * step.z); + hermiteSegments.append(start); + hermiteSegments.append(start + normal * step); + } + } + } + } + } + _voxels = new VoxelBuffer(vertices, indices, hermiteSegments, quadIndices, width, node->getStack()->getMaterials()); } diff --git a/interface/src/MetavoxelSystem.h b/interface/src/MetavoxelSystem.h index 51efc613a4..af6480c034 100644 --- a/interface/src/MetavoxelSystem.h +++ b/interface/src/MetavoxelSystem.h @@ -213,6 +213,9 @@ public: class HermiteBatch { public: QOpenGLBuffer* vertexBuffer; + glm::vec3 translation; + glm::quat rotation; + glm::vec3 scale; int vertexCount; }; diff --git a/libraries/metavoxels/src/Spanner.cpp b/libraries/metavoxels/src/Spanner.cpp index fc57c29edc..f4676bb33b 100644 --- a/libraries/metavoxels/src/Spanner.cpp +++ b/libraries/metavoxels/src/Spanner.cpp @@ -1166,25 +1166,42 @@ bool StackArray::Entry::isMergeable(const Entry& other) const { ::isZero(hermiteX) && ::isZero(hermiteY) && ::isZero(hermiteZ); } +static inline void setHermite(uchar values[4], const glm::vec3& normal, float position) { + values[0] = normal.x * numeric_limits::max(); + values[1] = normal.y * numeric_limits::max(); + values[2] = normal.z * numeric_limits::max(); + values[3] = position * numeric_limits::max(); +} + +static inline float getHermite(const uchar values[4], glm::vec3& normal) { + normal.x = (char)values[0] / (float)numeric_limits::max(); + normal.y = (char)values[1] / (float)numeric_limits::max(); + normal.z = (char)values[2] / (float)numeric_limits::max(); + return values[3] / (float)numeric_limits::max(); +} + void StackArray::Entry::setHermiteX(const glm::vec3& normal, float position) { - hermiteX[0] = normal.x * numeric_limits::max(); - hermiteX[1] = normal.y * numeric_limits::max(); - hermiteX[2] = normal.z * numeric_limits::max(); - hermiteX[3] = position * numeric_limits::max(); + setHermite(hermiteX, normal, position); +} + +float StackArray::Entry::getHermiteX(glm::vec3& normal) const { + return getHermite(hermiteX, normal); } void StackArray::Entry::setHermiteY(const glm::vec3& normal, float position) { - hermiteY[0] = normal.x * numeric_limits::max(); - hermiteY[1] = normal.y * numeric_limits::max(); - hermiteY[2] = normal.z * numeric_limits::max(); - hermiteY[3] = position * numeric_limits::max(); + setHermite(hermiteY, normal, position); +} + +float StackArray::Entry::getHermiteY(glm::vec3& normal) const { + return getHermite(hermiteY, normal); } void StackArray::Entry::setHermiteZ(const glm::vec3& normal, float position) { - hermiteZ[0] = normal.x * numeric_limits::max(); - hermiteZ[1] = normal.y * numeric_limits::max(); - hermiteZ[2] = normal.z * numeric_limits::max(); - hermiteZ[3] = position * numeric_limits::max(); + setHermite(hermiteZ, normal, position); +} + +float StackArray::Entry::getHermiteZ(glm::vec3& normal) const { + return getHermite(hermiteZ, normal); } HeightfieldStack::HeightfieldStack(int width, const QVector& contents, diff --git a/libraries/metavoxels/src/Spanner.h b/libraries/metavoxels/src/Spanner.h index 9c0b6947e6..d6a0f07cbd 100644 --- a/libraries/metavoxels/src/Spanner.h +++ b/libraries/metavoxels/src/Spanner.h @@ -496,14 +496,17 @@ public: void setHermiteX(int x, int y, int z, int w) { hermiteX[0] = x; hermiteX[1] = y; hermiteX[2] = z; hermiteX[3] = w; } void setHermiteX(const glm::vec3& normal, float position); void clearHermiteX() { setHermiteX(0, 0, 0, 0); } + float getHermiteX(glm::vec3& normal) const; void setHermiteY(int x, int y, int z, int w) { hermiteY[0] = x; hermiteY[1] = y; hermiteY[2] = z; hermiteY[3] = w; } void setHermiteY(const glm::vec3& normal, float position); void clearHermiteY() { setHermiteY(0, 0, 0, 0); } - + float getHermiteY(glm::vec3& normal) const; + void setHermiteZ(int x, int y, int z, int w) { hermiteZ[0] = x; hermiteZ[1] = y; hermiteZ[2] = z; hermiteZ[3] = w; } void setHermiteZ(const glm::vec3& normal, float position); void clearHermiteZ() { setHermiteZ(0, 0, 0, 0); } + float getHermiteZ(glm::vec3& normal) const; }; #pragma pack(pop)