hook up mesh renderer

This commit is contained in:
Seth Alves 2015-05-20 18:22:07 -07:00
parent f2c1c43da3
commit 138077ede9
4 changed files with 76 additions and 103 deletions

View file

@ -22,6 +22,8 @@
#include <PolyVoxCore/SurfaceMesh.h>
#include <PolyVoxCore/SimpleVolume.h>
#include "model/Geometry.h"
#include "gpu/GLBackend.h"
#include "EntityTreeRenderer.h"
#include "RenderablePolyVoxEntityItem.h"
@ -59,116 +61,88 @@ void createSphereInVolume(PolyVox::SimpleVolume<uint8_t>& volData, float fRadius
}
void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
PerformanceTimer perfTimer("PolyVoxrender");
assert(getType() == EntityTypes::PolyVox);
bool drawAsModel = hasModel();
glm::vec3 position = getPosition();
glm::vec3 dimensions = getDimensions();
bool didDraw = false;
if (drawAsModel) {
glPushMatrix();
{
float alpha = getLocalRenderAlpha();
if (!_model || _needsModelReload) {
// TODO: this getModel() appears to be about 3% of model render time. We should optimize
PerformanceTimer perfTimer("getModel");
EntityTreeRenderer* renderer = static_cast<EntityTreeRenderer*>(args->_renderer);
getModel(renderer);
}
if (_model) {
glm::quat rotation = getRotation();
bool movingOrAnimating = isMoving();
if ((movingOrAnimating || _needsInitialSimulation) && _model->isActive()) {
_model->setScaleToFit(true, dimensions);
_model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
_model->setRotation(rotation);
_model->setTranslation(position);
// make sure to simulate so everything gets set up correctly for rendering
{
PerformanceTimer perfTimer("_model->simulate");
_model->simulate(0.0f);
}
_needsInitialSimulation = false;
}
if (_model->isActive()) {
// TODO: this is the majority of model render time. And rendering of a cube model vs the basic Box render
// is significantly more expensive. Is there a way to call this that doesn't cost us as much?
PerformanceTimer perfTimer("model->render");
// filter out if not needed to render
if (args && (args->_renderMode == RenderArgs::SHADOW_RENDER_MODE)) {
if (movingOrAnimating) {
_model->renderInScene(alpha, args);
didDraw = true;
}
} else {
_model->renderInScene(alpha, args);
didDraw = true;
}
}
}
}
glPopMatrix();
}
if (!didDraw) {
glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f);
RenderableDebugableEntityItem::renderBoundingBox(this, args, 0.0f, greenColor);
}
RenderableDebugableEntityItem::render(this, args);
}
Model* RenderablePolyVoxEntityItem::getModel(EntityTreeRenderer* renderer) {
void RenderablePolyVoxEntityItem::getModel() {
PolyVox::SimpleVolume<uint8_t> volData(PolyVox::Region(PolyVox::Vector3DInt32(0,0,0),
PolyVox::Vector3DInt32(63, 63, 63)));
createSphereInVolume(volData, 15);
// A mesh object to hold the result of surface extraction
PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal> mesh;
PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal> polyVoxMesh;
//Create a surface extractor. Comment out one of the following two lines to decide which type gets created.
PolyVox::CubicSurfaceExtractorWithNormals<PolyVox::SimpleVolume<uint8_t>> surfaceExtractor
(&volData, volData.getEnclosingRegion(), &mesh);
(&volData, volData.getEnclosingRegion(), &polyVoxMesh);
// MarchingCubesSurfaceExtractor<SimpleVolume<uint8_t>> surfaceExtractor(&volData,
// volData.getEnclosingRegion(),
// &mesh);
// &polyVoxMesh);
//Execute the surface extractor.
surfaceExtractor.execute();
const std::vector<uint32_t>& vecIndices = mesh.getIndices();
const std::vector<PolyVox::PositionMaterialNormal>& vecVertices = mesh.getVertices();
const std::vector<uint32_t>& vecIndices = polyVoxMesh.getIndices();
const std::vector<PolyVox::PositionMaterialNormal>& vecVertices = polyVoxMesh.getVertices();
qDebug() << "-------------XXXXXXXXXXXXXXXXXXXX-------------------";
qDebug() << "---- vecIndices.size() =" << vecIndices.size();
qDebug() << "---- vecVertices.size() =" << vecVertices.size();
// [DEBUG] [05/19 20:46:38] ---- vecIndices.size() = 101556
// [DEBUG] [05/19 20:46:38] ---- vecVertices.size() = 67704
model::Mesh* mesh = new model::Mesh();
model::MeshPointer meshPtr(mesh);
Model* result = NULL;
// make sure our renderer is setup
if (!_myRenderer) {
_myRenderer = renderer;
}
assert(_myRenderer == renderer); // you should only ever render on one renderer
auto indexBuffer = gpu::BufferPointer (new gpu::Buffer(vecIndices.size() * sizeof(uint32_t),
(gpu::Byte*)vecIndices.data()));
auto vertexBuffer = gpu::BufferPointer(new gpu::Buffer(vecVertices.size() * sizeof(PolyVox::PositionMaterialNormal),
(gpu::Byte*)vecVertices.data()));
// result = _model = _myRenderer->allocateModel("", "");
// assert(_model);
mesh->setIndexBuffer(gpu::BufferView(indexBuffer, gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::RAW)));
mesh->setVertexBuffer(gpu::BufferView(vertexBuffer,
0,
vertexBuffer->getSize() - sizeof(float) * 3,
sizeof(float) * 6, // MAGIC NUMBER!
gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW)));
mesh->addAttribute(gpu::Stream::NORMAL,
gpu::BufferView(vertexBuffer,
sizeof(float) * 3, // MAGIC NUMBER!
vertexBuffer->getSize() - sizeof(float) * 3,
sizeof(float) * 6, // MAGIC NUMBER!
gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW)));
_needsInitialSimulation = true;
return result;
_modelGeometry.setMesh(meshPtr);
_needsModelReload = false;
}
void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render");
assert(getType() == EntityTypes::PolyVox);
if (_needsModelReload) {
getModel();
}
glm::vec3 position = getPosition();
// glm::vec3 dimensions = getDimensions();
glm::quat rotation = getRotation();
glm::vec4 lineColor(toGlm(getXColor()), getLocalRenderAlpha());
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
// DependencyManager::get<DeferredLightingEffect>()->renderLine(p1, p2, lineColor, lineColor);
gpu::Batch batch;
batch.setInputFormat(_modelGeometry.getMesh()->getVertexFormat());
batch.setIndexBuffer(gpu::UINT32, _modelGeometry.getMesh()->getIndexBuffer()._buffer, 0);
batch.setInputStream(0, _modelGeometry.getMesh()->makeBufferStream());
batch.drawIndexed(gpu::TRIANGLES, _modelGeometry.getMesh()->getNumIndices(), 0);
gpu::GLBackend::renderBatch(batch);
glPopMatrix();
RenderableDebugableEntityItem::render(this, args);
}

View file

@ -26,17 +26,16 @@ public:
void render(RenderArgs* args);
virtual bool hasModel() const { return true; }
virtual Model* getModel(EntityTreeRenderer* renderer);
void getModel();
private:
Model* _model = nullptr;
bool _needsInitialSimulation = true;
// Model* _model = nullptr;
// bool _needsInitialSimulation = true;
// bool _needsModelReload = true;
// EntityTreeRenderer* _myRenderer = nullptr;
model::Geometry _modelGeometry;
bool _needsModelReload = true;
EntityTreeRenderer* _myRenderer = nullptr;
// QString _currentTextures;
// QStringList _originalTextures;
// bool _originalTexturesRead;
// QVector<QVector<glm::vec3>> _points;
};

View file

@ -43,18 +43,18 @@ void Mesh::addAttribute(Slot slot, const BufferView& buffer) {
}
void Mesh::evalVertexFormat() {
VertexFormat vf;
auto vf = new VertexFormat();
int channelNum = 0;
if (hasVertexData()) {
vf.setAttribute(gpu::Stream::POSITION, channelNum, _vertexBuffer._element, 0);
vf->setAttribute(gpu::Stream::POSITION, channelNum, _vertexBuffer._element, 0);
channelNum++;
}
for (auto attrib : _attributeBuffers) {
vf.setAttribute(attrib.first, channelNum, attrib.second._element, 0);
vf->setAttribute(attrib.first, channelNum, attrib.second._element, 0);
channelNum++;
}
_vertexFormat = vf;
_vertexFormat.reset(vf);
}
void Mesh::setIndexBuffer(const BufferView& buffer) {
@ -112,12 +112,12 @@ const gpu::BufferStream Mesh::makeBufferStream() const {
int channelNum = 0;
if (hasVertexData()) {
stream.addBuffer(_vertexBuffer._buffer, _vertexBuffer._offset, _vertexFormat.getChannelStride(channelNum));
stream.addBuffer(_vertexBuffer._buffer, _vertexBuffer._offset, _vertexFormat->getChannelStride(channelNum));
channelNum++;
}
for (auto attrib : _attributeBuffers) {
BufferView& view = attrib.second;
stream.addBuffer(view._buffer, view._offset, _vertexFormat.getChannelStride(channelNum));
stream.addBuffer(view._buffer, view._offset, _vertexFormat->getChannelStride(channelNum));
channelNum++;
}

View file

@ -54,7 +54,7 @@ public:
void addAttribute(Slot slot, const BufferView& buffer);
// Stream format
const VertexFormat& getVertexFormat() const { return _vertexFormat; }
const gpu::Stream::FormatPointer getVertexFormat() const { return _vertexFormat; }
// Index Buffer
void setIndexBuffer(const BufferView& buffer);
@ -114,7 +114,7 @@ public:
protected:
VertexFormat _vertexFormat;
gpu::Stream::FormatPointer _vertexFormat;
BufferView _vertexBuffer;
BufferViewMap _attributeBuffers;