Working on heightfield implementation.

This commit is contained in:
Andrzej Kapolka 2014-07-28 19:10:59 -07:00
parent cc909e2286
commit aeee369286
8 changed files with 337 additions and 93 deletions

View file

@ -0,0 +1,16 @@
#version 120
//
// metavoxel_heightfield.frag
// fragment shader
//
// Created by Andrzej Kapolka on 7/28/14.
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
void main(void) {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}

View file

@ -0,0 +1,16 @@
#version 120
//
// metavoxel_heighfield.vert
// vertex shader
//
// Created by Andrzej Kapolka on 7/28/14.
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
void main(void) {
gl_Position = ftransform();
}

View file

@ -25,7 +25,7 @@
#include "MetavoxelSystem.h" #include "MetavoxelSystem.h"
#include "renderer/Model.h" #include "renderer/Model.h"
REGISTER_META_OBJECT(PointMetavoxelRendererImplementation) REGISTER_META_OBJECT(DefaultMetavoxelRendererImplementation)
REGISTER_META_OBJECT(SphereRenderer) REGISTER_META_OBJECT(SphereRenderer)
REGISTER_META_OBJECT(StaticModelRenderer) REGISTER_META_OBJECT(StaticModelRenderer)
@ -33,8 +33,10 @@ static int bufferPointVectorMetaTypeId = qRegisterMetaType<BufferPointVector>();
void MetavoxelSystem::init() { void MetavoxelSystem::init() {
MetavoxelClientManager::init(); MetavoxelClientManager::init();
PointMetavoxelRendererImplementation::init(); DefaultMetavoxelRendererImplementation::init();
_pointBufferAttribute = AttributeRegistry::getInstance()->registerAttribute(new PointBufferAttribute()); _pointBufferAttribute = AttributeRegistry::getInstance()->registerAttribute(new BufferDataAttribute("pointBuffer"));
_heightfieldBufferAttribute = AttributeRegistry::getInstance()->registerAttribute(
new BufferDataAttribute("heightfieldBuffer"));
} }
MetavoxelLOD MetavoxelSystem::getLOD() { MetavoxelLOD MetavoxelSystem::getLOD() {
@ -42,28 +44,31 @@ MetavoxelLOD MetavoxelSystem::getLOD() {
return _lod; return _lod;
} }
class SpannerSimulateVisitor : public SpannerVisitor { class SimulateVisitor : public MetavoxelVisitor {
public: public:
SpannerSimulateVisitor(float deltaTime); SimulateVisitor(float deltaTime, const MetavoxelLOD& lod);
virtual bool visit(Spanner* spanner, const glm::vec3& clipMinimum, float clipSize); virtual int visit(MetavoxelInfo& info);
private: private:
float _deltaTime; float _deltaTime;
}; };
SpannerSimulateVisitor::SpannerSimulateVisitor(float deltaTime) : SimulateVisitor::SimulateVisitor(float deltaTime, const MetavoxelLOD& lod) :
SpannerVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getSpannersAttribute(), MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getRendererAttribute(),
QVector<AttributePointer>(), QVector<AttributePointer>(), QVector<AttributePointer>(), QVector<AttributePointer>(), lod),
Application::getInstance()->getMetavoxels()->getLOD()),
_deltaTime(deltaTime) { _deltaTime(deltaTime) {
} }
bool SpannerSimulateVisitor::visit(Spanner* spanner, const glm::vec3& clipMinimum, float clipSize) { int SimulateVisitor::visit(MetavoxelInfo& info) {
spanner->getRenderer()->simulate(_deltaTime); if (!info.isLeaf) {
return true; return DEFAULT_ORDER;
}
static_cast<MetavoxelRenderer*>(info.inputValues.at(0).getInlineValue<
SharedObjectPointer>().data())->getImplementation()->simulate(*_data, _deltaTime, info, _lod);
return STOP_RECURSION;
} }
void MetavoxelSystem::simulate(float deltaTime) { void MetavoxelSystem::simulate(float deltaTime) {
@ -76,28 +81,8 @@ void MetavoxelSystem::simulate(float deltaTime) {
BASE_LOD_THRESHOLD * Menu::getInstance()->getAvatarLODDistanceMultiplier()); BASE_LOD_THRESHOLD * Menu::getInstance()->getAvatarLODDistanceMultiplier());
} }
SpannerSimulateVisitor spannerSimulateVisitor(deltaTime); SimulateVisitor simulateVisitor(deltaTime, getLOD());
guide(spannerSimulateVisitor); guideToAugmented(simulateVisitor);
}
class SpannerRenderVisitor : public SpannerVisitor {
public:
SpannerRenderVisitor();
virtual bool visit(Spanner* spanner, const glm::vec3& clipMinimum, float clipSize);
};
SpannerRenderVisitor::SpannerRenderVisitor() :
SpannerVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getSpannersAttribute(),
QVector<AttributePointer>(), QVector<AttributePointer>(), QVector<AttributePointer>(),
Application::getInstance()->getMetavoxels()->getLOD(),
encodeOrder(Application::getInstance()->getViewFrustum()->getDirection())) {
}
bool SpannerRenderVisitor::visit(Spanner* spanner, const glm::vec3& clipMinimum, float clipSize) {
spanner->getRenderer()->render(1.0f, SpannerRenderer::DEFAULT_MODE, clipMinimum, clipSize);
return true;
} }
class RenderVisitor : public MetavoxelVisitor { class RenderVisitor : public MetavoxelVisitor {
@ -125,9 +110,6 @@ int RenderVisitor::visit(MetavoxelInfo& info) {
void MetavoxelSystem::render() { void MetavoxelSystem::render() {
RenderVisitor renderVisitor(getLOD()); RenderVisitor renderVisitor(getLOD());
guideToAugmented(renderVisitor); guideToAugmented(renderVisitor);
SpannerRenderVisitor spannerRenderVisitor;
guide(spannerRenderVisitor);
} }
MetavoxelClient* MetavoxelSystem::createClient(const SharedNodePointer& node) { MetavoxelClient* MetavoxelSystem::createClient(const SharedNodePointer& node) {
@ -239,6 +221,9 @@ void MetavoxelSystemClient::sendDatagram(const QByteArray& data) {
Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::METAVOXELS).updateValue(data.size()); Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::METAVOXELS).updateValue(data.size());
} }
BufferData::~BufferData() {
}
PointBuffer::PointBuffer(const BufferPointVector& points) : PointBuffer::PointBuffer(const BufferPointVector& points) :
_points(points) { _points(points) {
} }
@ -269,34 +254,76 @@ void PointBuffer::render() {
_buffer.release(); _buffer.release();
} }
PointBufferAttribute::PointBufferAttribute() : HeightfieldBuffer::HeightfieldBuffer(const QByteArray& height, const QByteArray& color, const QByteArray& normal) :
InlineAttribute<PointBufferPointer>("pointBuffer") { _height(height),
_color(color),
_normal(normal),
_heightTexture(QOpenGLTexture::Target2D),
_colorTexture(QOpenGLTexture::Target2D),
_normalTexture(QOpenGLTexture::Target2D) {
} }
bool PointBufferAttribute::merge(void*& parent, void* children[], bool postRead) const { void HeightfieldBuffer::render() {
PointBufferPointer firstChild = decodeInline<PointBufferPointer>(children[0]); // initialize textures, etc. on first render
if (!_heightTexture.isCreated()) {
int heightSize = glm::sqrt(_height.size());
_heightTexture.setSize(heightSize, heightSize);
_heightTexture.setFormat(QOpenGLTexture::LuminanceFormat);
_heightTexture.allocateStorage();
_heightTexture.setData(QOpenGLTexture::Luminance, QOpenGLTexture::UInt8, _height.data());
_height.clear();
int colorSize = glm::sqrt(_color.size() / 3);
_colorTexture.setSize(colorSize, colorSize);
_colorTexture.setFormat(QOpenGLTexture::RGBFormat);
_colorTexture.allocateStorage();
_colorTexture.setData(QOpenGLTexture::BGR, QOpenGLTexture::UInt8, _color.data());
_color.clear();
int normalSize = glm::sqrt(_normal.size() / 3);
_normalTexture.setSize(normalSize, normalSize);
_normalTexture.setFormat(QOpenGLTexture::RGBFormat);
_normalTexture.allocateStorage();
_normalTexture.setData(QOpenGLTexture::BGR, QOpenGLTexture::UInt8, _normal.data());
_normal.clear();
}
}
BufferDataAttribute::BufferDataAttribute(const QString& name) :
InlineAttribute<BufferDataPointer>(name) {
}
bool BufferDataAttribute::merge(void*& parent, void* children[], bool postRead) const {
BufferDataPointer firstChild = decodeInline<BufferDataPointer>(children[0]);
for (int i = 1; i < MERGE_COUNT; i++) { for (int i = 1; i < MERGE_COUNT; i++) {
if (firstChild != decodeInline<PointBufferPointer>(children[i])) { if (firstChild != decodeInline<BufferDataPointer>(children[i])) {
*(PointBufferPointer*)&parent = _defaultValue; *(BufferDataPointer*)&parent = _defaultValue;
return false; return false;
} }
} }
*(PointBufferPointer*)&parent = firstChild; *(BufferDataPointer*)&parent = firstChild;
return true; return true;
} }
void PointMetavoxelRendererImplementation::init() { void DefaultMetavoxelRendererImplementation::init() {
if (!_program.isLinked()) { if (!_pointProgram.isLinked()) {
_program.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/metavoxel_point.vert"); _pointProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/metavoxel_point.vert");
_program.link(); _pointProgram.link();
_program.bind(); _pointProgram.bind();
_pointScaleLocation = _program.uniformLocation("pointScale"); _pointScaleLocation = _pointProgram.uniformLocation("pointScale");
_program.release(); _pointProgram.release();
_heightfieldProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
"shaders/metavoxel_heightfield.vert");
_heightfieldProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
"shaders/metavoxel_heightfield.frag");
_heightfieldProgram.link();
} }
} }
PointMetavoxelRendererImplementation::PointMetavoxelRendererImplementation() { DefaultMetavoxelRendererImplementation::DefaultMetavoxelRendererImplementation() {
} }
class PointAugmentVisitor : public MetavoxelVisitor { class PointAugmentVisitor : public MetavoxelVisitor {
@ -344,7 +371,7 @@ int PointAugmentVisitor::visit(MetavoxelInfo& info) {
if (info.size >= _pointLeafSize) { if (info.size >= _pointLeafSize) {
BufferPointVector swapPoints; BufferPointVector swapPoints;
_points.swap(swapPoints); _points.swap(swapPoints);
info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(PointBufferPointer( info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(
new PointBuffer(swapPoints)))); new PointBuffer(swapPoints))));
} }
return STOP_RECURSION; return STOP_RECURSION;
@ -356,12 +383,30 @@ bool PointAugmentVisitor::postVisit(MetavoxelInfo& info) {
} }
BufferPointVector swapPoints; BufferPointVector swapPoints;
_points.swap(swapPoints); _points.swap(swapPoints);
info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(PointBufferPointer( info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer(
new PointBuffer(swapPoints)))); new PointBuffer(swapPoints))));
return true; return true;
} }
void PointMetavoxelRendererImplementation::augment(MetavoxelData& data, const MetavoxelData& previous, class HeightfieldAugmentVisitor : public MetavoxelVisitor {
public:
HeightfieldAugmentVisitor(const MetavoxelLOD& lod);
virtual int visit(MetavoxelInfo& info);
};
HeightfieldAugmentVisitor::HeightfieldAugmentVisitor(const MetavoxelLOD& lod) :
MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getHeightfieldAttribute() <<
AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), QVector<AttributePointer>() <<
Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), lod) {
}
int HeightfieldAugmentVisitor::visit(MetavoxelInfo& info) {
return STOP_RECURSION;
}
void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const MetavoxelData& previous,
MetavoxelInfo& info, const MetavoxelLOD& lod) { MetavoxelInfo& info, const MetavoxelLOD& lod) {
// copy the previous buffers // copy the previous buffers
MetavoxelData expandedPrevious = previous; MetavoxelData expandedPrevious = previous;
@ -377,12 +422,62 @@ void PointMetavoxelRendererImplementation::augment(MetavoxelData& data, const Me
PointAugmentVisitor visitor(lod); PointAugmentVisitor visitor(lod);
data.guideToDifferent(expandedPrevious, visitor); data.guideToDifferent(expandedPrevious, visitor);
} }
class PointRenderVisitor : public MetavoxelVisitor { class SpannerSimulateVisitor : public SpannerVisitor {
public: public:
PointRenderVisitor(const MetavoxelLOD& lod); SpannerSimulateVisitor(float deltaTime, const MetavoxelLOD& lod);
virtual bool visit(Spanner* spanner, const glm::vec3& clipMinimum, float clipSize);
private:
float _deltaTime;
};
SpannerSimulateVisitor::SpannerSimulateVisitor(float deltaTime, const MetavoxelLOD& lod) :
SpannerVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getSpannersAttribute(),
QVector<AttributePointer>(), QVector<AttributePointer>(), QVector<AttributePointer>(), lod),
_deltaTime(deltaTime) {
}
bool SpannerSimulateVisitor::visit(Spanner* spanner, const glm::vec3& clipMinimum, float clipSize) {
spanner->getRenderer()->simulate(_deltaTime);
return true;
}
void DefaultMetavoxelRendererImplementation::simulate(MetavoxelData& data, float deltaTime,
MetavoxelInfo& info, const MetavoxelLOD& lod) {
SpannerSimulateVisitor spannerSimulateVisitor(deltaTime, lod);
data.guide(spannerSimulateVisitor);
}
class SpannerRenderVisitor : public SpannerVisitor {
public:
SpannerRenderVisitor(const MetavoxelLOD& lod);
virtual bool visit(Spanner* spanner, const glm::vec3& clipMinimum, float clipSize);
};
SpannerRenderVisitor::SpannerRenderVisitor(const MetavoxelLOD& lod) :
SpannerVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getSpannersAttribute(),
QVector<AttributePointer>(), QVector<AttributePointer>(), QVector<AttributePointer>(),
lod, encodeOrder(Application::getInstance()->getViewFrustum()->getDirection())) {
}
bool SpannerRenderVisitor::visit(Spanner* spanner, const glm::vec3& clipMinimum, float clipSize) {
spanner->getRenderer()->render(1.0f, SpannerRenderer::DEFAULT_MODE, clipMinimum, clipSize);
return true;
}
class BufferRenderVisitor : public MetavoxelVisitor {
public:
BufferRenderVisitor(const AttributePointer& attribute, const MetavoxelLOD& lod);
virtual int visit(MetavoxelInfo& info); virtual int visit(MetavoxelInfo& info);
@ -391,21 +486,23 @@ private:
int _order; int _order;
}; };
PointRenderVisitor::PointRenderVisitor(const MetavoxelLOD& lod) : BufferRenderVisitor::BufferRenderVisitor(const AttributePointer& attribute, const MetavoxelLOD& lod) :
MetavoxelVisitor(QVector<AttributePointer>() << Application::getInstance()->getMetavoxels()->getPointBufferAttribute(), MetavoxelVisitor(QVector<AttributePointer>() << attribute, QVector<AttributePointer>(), lod),
QVector<AttributePointer>(), lod),
_order(encodeOrder(Application::getInstance()->getViewFrustum()->getDirection())) { _order(encodeOrder(Application::getInstance()->getViewFrustum()->getDirection())) {
} }
int PointRenderVisitor::visit(MetavoxelInfo& info) { int BufferRenderVisitor::visit(MetavoxelInfo& info) {
PointBufferPointer buffer = info.inputValues.at(0).getInlineValue<PointBufferPointer>(); BufferDataPointer buffer = info.inputValues.at(0).getInlineValue<BufferDataPointer>();
if (buffer) { if (buffer) {
buffer->render(); buffer->render();
} }
return info.isLeaf ? STOP_RECURSION : _order; return info.isLeaf ? STOP_RECURSION : _order;
} }
void PointMetavoxelRendererImplementation::render(MetavoxelData& data, MetavoxelInfo& info, const MetavoxelLOD& lod) { void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, MetavoxelInfo& info, const MetavoxelLOD& lod) {
SpannerRenderVisitor spannerRenderVisitor(lod);
data.guide(spannerRenderVisitor);
int viewport[4]; int viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport); glGetIntegerv(GL_VIEWPORT, viewport);
const int VIEWPORT_WIDTH_INDEX = 2; const int VIEWPORT_WIDTH_INDEX = 2;
@ -416,8 +513,8 @@ void PointMetavoxelRendererImplementation::render(MetavoxelData& data, Metavoxel
float worldDiagonal = glm::distance(Application::getInstance()->getViewFrustum()->getNearBottomLeft(), float worldDiagonal = glm::distance(Application::getInstance()->getViewFrustum()->getNearBottomLeft(),
Application::getInstance()->getViewFrustum()->getNearTopRight()); Application::getInstance()->getViewFrustum()->getNearTopRight());
_program.bind(); _pointProgram.bind();
_program.setUniformValue(_pointScaleLocation, viewportDiagonal * _pointProgram.setUniformValue(_pointScaleLocation, viewportDiagonal *
Application::getInstance()->getViewFrustum()->getNearClip() / worldDiagonal); Application::getInstance()->getViewFrustum()->getNearClip() / worldDiagonal);
glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
@ -428,10 +525,8 @@ void PointMetavoxelRendererImplementation::render(MetavoxelData& data, Metavoxel
glDisable(GL_BLEND); glDisable(GL_BLEND);
PointRenderVisitor visitor(lod); BufferRenderVisitor pointRenderVisitor(Application::getInstance()->getMetavoxels()->getPointBufferAttribute(), lod);
data.guide(visitor); data.guide(pointRenderVisitor);
glEnable(GL_BLEND);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
@ -439,11 +534,18 @@ void PointMetavoxelRendererImplementation::render(MetavoxelData& data, Metavoxel
glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_NORMAL_ARRAY);
_program.release(); _pointProgram.release();
BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(),
lod);
data.guide(heightfieldRenderVisitor);
glEnable(GL_BLEND);
} }
ProgramObject PointMetavoxelRendererImplementation::_program; ProgramObject DefaultMetavoxelRendererImplementation::_pointProgram;
int PointMetavoxelRendererImplementation::_pointScaleLocation; int DefaultMetavoxelRendererImplementation::_pointScaleLocation;
ProgramObject DefaultMetavoxelRendererImplementation::_heightfieldProgram;
static void enableClipPlane(GLenum plane, float x, float y, float z, float w) { static void enableClipPlane(GLenum plane, float x, float y, float z, float w) {
GLdouble coefficients[] = { x, y, z, w }; GLdouble coefficients[] = { x, y, z, w };

View file

@ -14,6 +14,7 @@
#include <QList> #include <QList>
#include <QOpenGLBuffer> #include <QOpenGLBuffer>
#include <QOpenGLTexture>
#include <QReadWriteLock> #include <QReadWriteLock>
#include <QVector> #include <QVector>
@ -36,6 +37,7 @@ public:
virtual MetavoxelLOD getLOD(); virtual MetavoxelLOD getLOD();
const AttributePointer& getPointBufferAttribute() { return _pointBufferAttribute; } const AttributePointer& getPointBufferAttribute() { return _pointBufferAttribute; }
const AttributePointer& getHeightfieldBufferAttribute() { return _heightfieldBufferAttribute; }
void simulate(float deltaTime); void simulate(float deltaTime);
void render(); void render();
@ -49,6 +51,7 @@ private:
void guideToAugmented(MetavoxelVisitor& visitor); void guideToAugmented(MetavoxelVisitor& visitor);
AttributePointer _pointBufferAttribute; AttributePointer _pointBufferAttribute;
AttributePointer _heightfieldBufferAttribute;
MetavoxelLOD _lod; MetavoxelLOD _lod;
QReadWriteLock _lodLock; QReadWriteLock _lodLock;
@ -92,13 +95,24 @@ private:
QReadWriteLock _augmentedDataLock; QReadWriteLock _augmentedDataLock;
}; };
/// Base class for cached static buffers.
class BufferData : public QSharedData {
public:
virtual ~BufferData();
virtual void render() = 0;
};
typedef QExplicitlySharedDataPointer<BufferData> BufferDataPointer;
/// Contains the information necessary to render a group of points. /// Contains the information necessary to render a group of points.
class PointBuffer : public QSharedData { class PointBuffer : public BufferData {
public: public:
PointBuffer(const BufferPointVector& points); PointBuffer(const BufferPointVector& points);
void render(); virtual void render();
private: private:
@ -107,36 +121,55 @@ private:
int _pointCount; int _pointCount;
}; };
typedef QExplicitlySharedDataPointer<PointBuffer> PointBufferPointer; /// Contains the information necessary to render a heightfield block.
class HeightfieldBuffer : public BufferData {
public:
/// A client-side attribute that stores point buffers. HeightfieldBuffer(const QByteArray& height, const QByteArray& color, const QByteArray& normal);
class PointBufferAttribute : public InlineAttribute<PointBufferPointer> {
virtual void render();
private:
QByteArray _height;
QByteArray _color;
QByteArray _normal;
QOpenGLTexture _heightTexture;
QOpenGLTexture _colorTexture;
QOpenGLTexture _normalTexture;
};
/// A client-side attribute that stores renderable buffers.
class BufferDataAttribute : public InlineAttribute<BufferDataPointer> {
Q_OBJECT Q_OBJECT
public: public:
Q_INVOKABLE PointBufferAttribute(); Q_INVOKABLE BufferDataAttribute(const QString& name = QString());
virtual bool merge(void*& parent, void* children[], bool postRead = false) const; virtual bool merge(void*& parent, void* children[], bool postRead = false) const;
}; };
/// Renders metavoxels as points. /// Renders metavoxels as points.
class PointMetavoxelRendererImplementation : public MetavoxelRendererImplementation { class DefaultMetavoxelRendererImplementation : public MetavoxelRendererImplementation {
Q_OBJECT Q_OBJECT
public: public:
static void init(); static void init();
Q_INVOKABLE PointMetavoxelRendererImplementation(); Q_INVOKABLE DefaultMetavoxelRendererImplementation();
virtual void augment(MetavoxelData& data, const MetavoxelData& previous, MetavoxelInfo& info, const MetavoxelLOD& lod); virtual void augment(MetavoxelData& data, const MetavoxelData& previous, MetavoxelInfo& info, const MetavoxelLOD& lod);
virtual void simulate(MetavoxelData& data, float deltaTime, MetavoxelInfo& info, const MetavoxelLOD& lod);
virtual void render(MetavoxelData& data, MetavoxelInfo& info, const MetavoxelLOD& lod); virtual void render(MetavoxelData& data, MetavoxelInfo& info, const MetavoxelLOD& lod);
private: private:
static ProgramObject _program; static ProgramObject _pointProgram;
static int _pointScaleLocation; static int _pointScaleLocation;
static ProgramObject _heightfieldProgram;
}; };
/// Base class for spanner renderers; provides clipping. /// Base class for spanner renderers; provides clipping.

View file

@ -21,6 +21,8 @@ REGISTER_META_OBJECT(QRgbAttribute)
REGISTER_META_OBJECT(PackedNormalAttribute) REGISTER_META_OBJECT(PackedNormalAttribute)
REGISTER_META_OBJECT(SpannerQRgbAttribute) REGISTER_META_OBJECT(SpannerQRgbAttribute)
REGISTER_META_OBJECT(SpannerPackedNormalAttribute) REGISTER_META_OBJECT(SpannerPackedNormalAttribute)
REGISTER_META_OBJECT(HeightfieldAttribute)
REGISTER_META_OBJECT(HeightfieldColorAttribute)
REGISTER_META_OBJECT(SharedObjectAttribute) REGISTER_META_OBJECT(SharedObjectAttribute)
REGISTER_META_OBJECT(SharedObjectSetAttribute) REGISTER_META_OBJECT(SharedObjectSetAttribute)
REGISTER_META_OBJECT(SpannerSetAttribute) REGISTER_META_OBJECT(SpannerSetAttribute)
@ -37,13 +39,15 @@ AttributeRegistry::AttributeRegistry() :
_guideAttribute(registerAttribute(new SharedObjectAttribute("guide", &MetavoxelGuide::staticMetaObject, _guideAttribute(registerAttribute(new SharedObjectAttribute("guide", &MetavoxelGuide::staticMetaObject,
new DefaultMetavoxelGuide()))), new DefaultMetavoxelGuide()))),
_rendererAttribute(registerAttribute(new SharedObjectAttribute("renderer", &MetavoxelRenderer::staticMetaObject, _rendererAttribute(registerAttribute(new SharedObjectAttribute("renderer", &MetavoxelRenderer::staticMetaObject,
new PointMetavoxelRenderer()))), new DefaultMetavoxelRenderer()))),
_spannersAttribute(registerAttribute(new SpannerSetAttribute("spanners", &Spanner::staticMetaObject))), _spannersAttribute(registerAttribute(new SpannerSetAttribute("spanners", &Spanner::staticMetaObject))),
_colorAttribute(registerAttribute(new QRgbAttribute("color"))), _colorAttribute(registerAttribute(new QRgbAttribute("color"))),
_normalAttribute(registerAttribute(new PackedNormalAttribute("normal"))), _normalAttribute(registerAttribute(new PackedNormalAttribute("normal"))),
_spannerColorAttribute(registerAttribute(new SpannerQRgbAttribute("spannerColor"))), _spannerColorAttribute(registerAttribute(new SpannerQRgbAttribute("spannerColor"))),
_spannerNormalAttribute(registerAttribute(new SpannerPackedNormalAttribute("spannerNormal"))), _spannerNormalAttribute(registerAttribute(new SpannerPackedNormalAttribute("spannerNormal"))),
_spannerMaskAttribute(registerAttribute(new FloatAttribute("spannerMask"))) { _spannerMaskAttribute(registerAttribute(new FloatAttribute("spannerMask"))),
_heightfieldAttribute(registerAttribute(new HeightfieldAttribute("heightfield"))),
_heightfieldColorAttribute(registerAttribute(new HeightfieldColorAttribute("heightfieldColor"))) {
// our baseline LOD threshold is for voxels; spanners are a different story // our baseline LOD threshold is for voxels; spanners are a different story
const float SPANNER_LOD_THRESHOLD_MULTIPLIER = 8.0f; const float SPANNER_LOD_THRESHOLD_MULTIPLIER = 8.0f;
@ -451,6 +455,26 @@ AttributeValue SpannerPackedNormalAttribute::inherit(const AttributeValue& paren
return AttributeValue(parentValue.getAttribute()); return AttributeValue(parentValue.getAttribute());
} }
HeightfieldData::HeightfieldData(const QByteArray& contents) :
_contents(contents) {
}
HeightfieldAttribute::HeightfieldAttribute(const QString& name) :
InlineAttribute<HeightfieldDataPointer>(name) {
}
bool HeightfieldAttribute::merge(void*& parent, void* children[], bool postRead) const {
return false;
}
HeightfieldColorAttribute::HeightfieldColorAttribute(const QString& name) :
InlineAttribute<HeightfieldDataPointer>(name) {
}
bool HeightfieldColorAttribute::merge(void*& parent, void* children[], bool postRead) const {
return false;
}
SharedObjectAttribute::SharedObjectAttribute(const QString& name, const QMetaObject* metaObject, SharedObjectAttribute::SharedObjectAttribute(const QString& name, const QMetaObject* metaObject,
const SharedObjectPointer& defaultValue) : const SharedObjectPointer& defaultValue) :
InlineAttribute<SharedObjectPointer>(name, defaultValue), InlineAttribute<SharedObjectPointer>(name, defaultValue),

View file

@ -94,6 +94,12 @@ public:
/// Returns a reference to the standard "spannerMask" attribute. /// Returns a reference to the standard "spannerMask" attribute.
const AttributePointer& getSpannerMaskAttribute() const { return _spannerMaskAttribute; } const AttributePointer& getSpannerMaskAttribute() const { return _spannerMaskAttribute; }
/// Returns a reference to the standard HeightfieldPointer "heightfield" attribute.
const AttributePointer& getHeightfieldAttribute() const { return _heightfieldAttribute; }
/// Returns a reference to the standard HeightfieldColorPointer "heightfieldColor" attribute.
const AttributePointer& getHeightfieldColorAttribute() const { return _heightfieldColorAttribute; }
private: private:
static QScriptValue getAttribute(QScriptContext* context, QScriptEngine* engine); static QScriptValue getAttribute(QScriptContext* context, QScriptEngine* engine);
@ -109,6 +115,8 @@ private:
AttributePointer _spannerColorAttribute; AttributePointer _spannerColorAttribute;
AttributePointer _spannerNormalAttribute; AttributePointer _spannerNormalAttribute;
AttributePointer _spannerMaskAttribute; AttributePointer _spannerMaskAttribute;
AttributePointer _heightfieldAttribute;
AttributePointer _heightfieldColorAttribute;
}; };
/// Converts a value to a void pointer. /// Converts a value to a void pointer.
@ -408,6 +416,43 @@ public:
virtual AttributeValue inherit(const AttributeValue& parentValue) const; virtual AttributeValue inherit(const AttributeValue& parentValue) const;
}; };
/// Contains a block of heightfield data.
class HeightfieldData : public QSharedData {
public:
HeightfieldData(const QByteArray& contents);
const QByteArray& getContents() const { return _contents; }
private:
QByteArray _contents;
};
typedef QExplicitlySharedDataPointer<HeightfieldData> HeightfieldDataPointer;
/// An attribute that stores heightfield data.
class HeightfieldAttribute : public InlineAttribute<HeightfieldDataPointer> {
Q_OBJECT
public:
Q_INVOKABLE HeightfieldAttribute(const QString& name = QString());
virtual bool merge(void*& parent, void* children[], bool postRead = false) const;
};
/// An attribute that stores heightfield colors.
class HeightfieldColorAttribute : public InlineAttribute<HeightfieldDataPointer> {
Q_OBJECT
public:
Q_INVOKABLE HeightfieldColorAttribute(const QString& name = QString());
virtual bool merge(void*& parent, void* children[], bool postRead = false) const;
};
/// An attribute that takes the form of QObjects of a given meta-type (a subclass of SharedObject). /// An attribute that takes the form of QObjects of a given meta-type (a subclass of SharedObject).
class SharedObjectAttribute : public InlineAttribute<SharedObjectPointer> { class SharedObjectAttribute : public InlineAttribute<SharedObjectPointer> {
Q_OBJECT Q_OBJECT

View file

@ -26,7 +26,7 @@ REGISTER_META_OBJECT(DefaultMetavoxelGuide)
REGISTER_META_OBJECT(ScriptedMetavoxelGuide) REGISTER_META_OBJECT(ScriptedMetavoxelGuide)
REGISTER_META_OBJECT(ThrobbingMetavoxelGuide) REGISTER_META_OBJECT(ThrobbingMetavoxelGuide)
REGISTER_META_OBJECT(MetavoxelRenderer) REGISTER_META_OBJECT(MetavoxelRenderer)
REGISTER_META_OBJECT(PointMetavoxelRenderer) REGISTER_META_OBJECT(DefaultMetavoxelRenderer)
REGISTER_META_OBJECT(Spanner) REGISTER_META_OBJECT(Spanner)
REGISTER_META_OBJECT(Sphere) REGISTER_META_OBJECT(Sphere)
REGISTER_META_OBJECT(StaticModel) REGISTER_META_OBJECT(StaticModel)
@ -1879,20 +1879,27 @@ void MetavoxelRendererImplementation::init(MetavoxelRenderer* renderer) {
void MetavoxelRendererImplementation::augment(MetavoxelData& data, const MetavoxelData& previous, void MetavoxelRendererImplementation::augment(MetavoxelData& data, const MetavoxelData& previous,
MetavoxelInfo& info, const MetavoxelLOD& lod) { MetavoxelInfo& info, const MetavoxelLOD& lod) {
// nothing by default
}
void MetavoxelRendererImplementation::simulate(MetavoxelData& data, float deltaTime,
MetavoxelInfo& info, const MetavoxelLOD& lod) {
// nothing by default
} }
void MetavoxelRendererImplementation::render(MetavoxelData& data, MetavoxelInfo& info, const MetavoxelLOD& lod) { void MetavoxelRendererImplementation::render(MetavoxelData& data, MetavoxelInfo& info, const MetavoxelLOD& lod) {
// nothing by default
} }
QByteArray MetavoxelRenderer::getImplementationClassName() const { QByteArray MetavoxelRenderer::getImplementationClassName() const {
return "MetavoxelRendererImplementation"; return "MetavoxelRendererImplementation";
} }
PointMetavoxelRenderer::PointMetavoxelRenderer() { DefaultMetavoxelRenderer::DefaultMetavoxelRenderer() {
} }
QByteArray PointMetavoxelRenderer::getImplementationClassName() const { QByteArray DefaultMetavoxelRenderer::getImplementationClassName() const {
return "PointMetavoxelRendererImplementation"; return "DefaultMetavoxelRendererImplementation";
} }
const float DEFAULT_PLACEMENT_GRANULARITY = 0.01f; const float DEFAULT_PLACEMENT_GRANULARITY = 0.01f;

View file

@ -555,6 +555,7 @@ public:
virtual void init(MetavoxelRenderer* renderer); virtual void init(MetavoxelRenderer* renderer);
virtual void augment(MetavoxelData& data, const MetavoxelData& previous, MetavoxelInfo& info, const MetavoxelLOD& lod); virtual void augment(MetavoxelData& data, const MetavoxelData& previous, MetavoxelInfo& info, const MetavoxelLOD& lod);
virtual void simulate(MetavoxelData& data, float deltaTime, MetavoxelInfo& info, const MetavoxelLOD& lod);
virtual void render(MetavoxelData& data, MetavoxelInfo& info, const MetavoxelLOD& lod); virtual void render(MetavoxelData& data, MetavoxelInfo& info, const MetavoxelLOD& lod);
protected: protected:
@ -562,13 +563,13 @@ protected:
MetavoxelRenderer* _renderer; MetavoxelRenderer* _renderer;
}; };
/// Renders metavoxels as points. /// The standard, usual renderer.
class PointMetavoxelRenderer : public MetavoxelRenderer { class DefaultMetavoxelRenderer : public MetavoxelRenderer {
Q_OBJECT Q_OBJECT
public: public:
Q_INVOKABLE PointMetavoxelRenderer(); Q_INVOKABLE DefaultMetavoxelRenderer();
virtual QByteArray getImplementationClassName() const; virtual QByteArray getImplementationClassName() const;
}; };