More work on point rendering.

This commit is contained in:
Andrzej Kapolka 2014-07-18 18:51:01 -07:00
parent cda1a7f32a
commit 38f3f80398
3 changed files with 54 additions and 32 deletions

View file

@ -225,13 +225,17 @@ private:
BufferBuilder::BufferBuilder(const MetavoxelLOD& lod) :
MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getColorAttribute() <<
AttributeRegistry::getInstance()->getNormalAttribute(), QVector<AttributePointer>() <<
Application::getInstance()->getMetavoxels()->getPointBufferAttribute(), lod) {
AttributeRegistry::getInstance()->getNormalAttribute() <<
Application::getInstance()->getMetavoxels()->getPointBufferAttribute(), QVector<AttributePointer>() <<
Application::getInstance()->getMetavoxels()->getPointBufferAttribute(), lod) {
}
const int ALPHA_RENDER_THRESHOLD = 0;
int BufferBuilder::visit(MetavoxelInfo& info) {
if (info.inputValues.at(2).getInlineValue<PointBufferPointer>()) {
info.outputValues[0] = AttributeValue(_outputs.at(0));
}
if (_depth >= _depthPoints.size()) {
_depthPoints.resize(_depth + 1);
}
@ -252,10 +256,51 @@ int BufferBuilder::visit(MetavoxelInfo& info) {
return DEFAULT_ORDER;
}
const int BUFFER_LEAF_THRESHOLD = 1024;
const int BUFFER_LEVELS = 5;
bool BufferBuilder::postVisit(MetavoxelInfo& info) {
return false;
if (_depth % BUFFER_LEVELS != 0) {
return false;
}
QVector<int> offsets;
offsets.append(0);
int leafCount = 0;
int totalPoints = 0;
int lastDepth = qMin(_depth + BUFFER_LEVELS, _depthPoints.size());
for (int i = _depth; i < lastDepth; i++) {
const BufferPointVectorPair& pair = _depthPoints.at(i);
offsets.append(totalPoints += ((leafCount += pair.first.size()) + pair.second.size()));
}
QOpenGLBuffer buffer;
buffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
buffer.create();
buffer.bind();
buffer.allocate(totalPoints * sizeof(BufferPoint));
int offset = 0;
for (int i = _depth; i < lastDepth; i++) {
// write the internal nodes from the current level
BufferPointVector& internal = _depthPoints[i].second;
int length = internal.size() * sizeof(BufferPoint);
buffer.write(offset, internal.constData(), length);
offset += length;
internal.clear();
// and the leaves from the top down
for (int j = _depth; j <= i; j++) {
const BufferPointVector& leaves = _depthPoints.at(j).first;
length = leaves.size() * sizeof(BufferPoint);
buffer.write(offset, leaves.constData(), length);
offset += length;
}
}
// clear the leaves now that we're done with them
for (int i = _depth; i < lastDepth; i++) {
_depthPoints[i].first.clear();
}
buffer.release();
info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(PointBufferPointer(
new PointBuffer(buffer, offsets, leafCount))));
return true;
}
void MetavoxelSystemClient::dataChanged(const MetavoxelData& oldData) {
@ -294,7 +339,7 @@ void PointBuffer::render(int level) {
}
PointBufferAttribute::PointBufferAttribute() :
SharedPointerAttribute<PointBuffer>("pointBuffer") {
InlineAttribute<PointBufferPointer>("pointBuffer") {
}
MetavoxelNode* PointBufferAttribute::createMetavoxelNode(const AttributeValue& value, const MetavoxelNode* original) const {
@ -303,7 +348,7 @@ MetavoxelNode* PointBufferAttribute::createMetavoxelNode(const AttributeValue& v
bool PointBufferAttribute::merge(void*& parent, void* children[], bool postRead) const {
for (int i = 0; i < MERGE_COUNT; i++) {
if (!decodeInline<PointBufferPointer>(children[i]).isNull()) {
if (decodeInline<PointBufferPointer>(children[i])) {
return false;
}
}

View file

@ -113,7 +113,7 @@ typedef QVector<BufferPoint> BufferPointVector;
typedef QPair<BufferPointVector, BufferPointVector> BufferPointVectorPair;
/// Contains the information necessary to render a group of points at variable detail levels.
class PointBuffer {
class PointBuffer : public QSharedData {
public:
PointBuffer(const QOpenGLBuffer& buffer, const QVector<int>& offsets, int lastLeafCount);
@ -127,10 +127,10 @@ private:
int _lastLeafCount;
};
typedef QSharedPointer<PointBuffer> PointBufferPointer;
typedef QExplicitlySharedDataPointer<PointBuffer> PointBufferPointer;
/// A client-side attribute that stores point buffers.
class PointBufferAttribute : public SharedPointerAttribute<PointBuffer> {
class PointBufferAttribute : public InlineAttribute<PointBufferPointer> {
Q_OBJECT
public:

View file

@ -404,29 +404,6 @@ public:
virtual AttributeValue inherit(const AttributeValue& parentValue) const;
};
/// Template for attributes that take the form of shared pointers.
template<class T> class SharedPointerAttribute : public InlineAttribute<QSharedPointer<T> > {
public:
SharedPointerAttribute(const QString& name, const QSharedPointer<T>& defaultValue = QSharedPointer<T>()) :
InlineAttribute<QSharedPointer<T> >(name, defaultValue) { }
virtual bool merge(void*& parent, void* children[], bool postRead = false) const;
};
template<class T> inline bool SharedPointerAttribute<T>::merge(
void*& parent, void* children[], bool postRead) const {
QSharedPointer<T> firstChild = decodeInline<QSharedPointer<T> >(children[0]);
for (int i = 1; i < Attribute::MERGE_COUNT; i++) {
if (firstChild != decodeInline<QSharedPointer<T> >(children[i])) {
*(QSharedPointer<T>*)&parent = InlineAttribute<QSharedPointer<T> >::_defaultValue;
return false;
}
}
*(QSharedPointer<T>*)&parent = firstChild;
return true;
}
/// An attribute that takes the form of QObjects of a given meta-type (a subclass of SharedObject).
class SharedObjectAttribute : public InlineAttribute<SharedObjectPointer> {
Q_OBJECT