From 443b9e1e786bea74491ec273470129524d7b2e4a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 31 Jul 2015 21:58:43 -0700 Subject: [PATCH 1/5] attempt to give polyvox its own rendering bung --- .../src/RenderablePolyVoxEntityItem.cpp | 285 +++++++++++------- .../src/RenderablePolyVoxEntityItem.h | 31 +- libraries/entities-renderer/src/polyvox.slf | 56 ++++ libraries/entities-renderer/src/polyvox.slv | 44 +++ 4 files changed, 300 insertions(+), 116 deletions(-) create mode 100644 libraries/entities-renderer/src/polyvox.slf create mode 100644 libraries/entities-renderer/src/polyvox.slv diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 21911618b0..d8d1975c0b 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -37,8 +38,12 @@ #include "model/Geometry.h" #include "gpu/Context.h" #include "EntityTreeRenderer.h" +#include "polyvox_vert.h" +#include "polyvox_frag.h" #include "RenderablePolyVoxEntityItem.h" +// gpu::PipelinePointer RenderablePolyVoxEntityItem::_pipeline = nullptr; + EntityItemPointer RenderablePolyVoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { return std::make_shared(entityID, properties); } @@ -327,120 +332,6 @@ void RenderablePolyVoxEntityItem::setSphere(glm::vec3 centerWorldCoords, float r setSphereInVolume(glm::vec3(centerVoxelCoords), radiusVoxelCoords, toValue); } -void RenderablePolyVoxEntityItem::getModel() { - // A mesh object to hold the result of surface extraction - PolyVox::SurfaceMesh polyVoxMesh; - - switch (_voxelSurfaceStyle) { - case PolyVoxEntityItem::SURFACE_MARCHING_CUBES: { - PolyVox::MarchingCubesSurfaceExtractor> surfaceExtractor - (_volData, _volData->getEnclosingRegion(), &polyVoxMesh); - surfaceExtractor.execute(); - break; - } - case PolyVoxEntityItem::SURFACE_EDGED_CUBIC: - case PolyVoxEntityItem::SURFACE_CUBIC: { - PolyVox::CubicSurfaceExtractorWithNormals> surfaceExtractor - (_volData, _volData->getEnclosingRegion(), &polyVoxMesh); - surfaceExtractor.execute(); - break; - } - } - - // convert PolyVox mesh to a Sam mesh - auto mesh = _modelGeometry.getMesh(); - - const std::vector& vecIndices = polyVoxMesh.getIndices(); - auto indexBuffer = std::make_shared(vecIndices.size() * sizeof(uint32_t), - (gpu::Byte*)vecIndices.data()); - auto indexBufferPtr = gpu::BufferPointer(indexBuffer); - auto indexBufferView = new gpu::BufferView(indexBufferPtr, gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::RAW)); - mesh->setIndexBuffer(*indexBufferView); - - - const std::vector& vecVertices = polyVoxMesh.getVertices(); - auto vertexBuffer = std::make_shared(vecVertices.size() * sizeof(PolyVox::PositionMaterialNormal), - (gpu::Byte*)vecVertices.data()); - auto vertexBufferPtr = gpu::BufferPointer(vertexBuffer); - auto vertexBufferView = new gpu::BufferView(vertexBufferPtr, - 0, - vertexBufferPtr->getSize() - sizeof(float) * 3, - sizeof(PolyVox::PositionMaterialNormal), - gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW)); - mesh->setVertexBuffer(*vertexBufferView); - mesh->addAttribute(gpu::Stream::NORMAL, - gpu::BufferView(vertexBufferPtr, - sizeof(float) * 3, - vertexBufferPtr->getSize() - sizeof(float) * 3, - sizeof(PolyVox::PositionMaterialNormal), - gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW))); - - - - // auto normalAttrib = mesh->getAttributeBuffer(gpu::Stream::NORMAL); - // for (auto normal = normalAttrib.begin(); normal != normalAttrib.end(); normal++) { - // (*normal) = -(*normal); - // } - - - // mesh->addAttribute(gpu::Stream::TEXCOORD, - // gpu::BufferView(vertexBufferPtr, - // sizeof(float) * 2, - // vertexBufferPtr->getSize() - sizeof(float) * 2, - // sizeof(PolyVox::PositionMaterialNormal), - // gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::RAW))); - - - - #ifdef WANT_DEBUG - qDebug() << "---- vecIndices.size() =" << vecIndices.size(); - qDebug() << "---- vecVertices.size() =" << vecVertices.size(); - #endif - - _needsModelReload = false; -} - -void RenderablePolyVoxEntityItem::render(RenderArgs* args) { - PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render"); - assert(getType() == EntityTypes::PolyVox); - - if (_needsModelReload) { - getModel(); - } - - Transform transform(voxelToWorldMatrix()); - - auto mesh = _modelGeometry.getMesh(); - Q_ASSERT(args->_batch); - gpu::Batch& batch = *args->_batch; - DependencyManager::get()->bindSimpleProgram(batch, true); - batch.setModelTransform(transform); - batch.setInputFormat(mesh->getVertexFormat()); - batch.setInputBuffer(gpu::Stream::POSITION, mesh->getVertexBuffer()); - batch.setInputBuffer(gpu::Stream::NORMAL, - mesh->getVertexBuffer()._buffer, - sizeof(float) * 3, - mesh->getVertexBuffer()._stride); - batch.setIndexBuffer(gpu::UINT32, mesh->getIndexBuffer()._buffer, 0); - batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0); - - if (!_xTextureURL.isEmpty() && !_xTexture) { - _xTexture = DependencyManager::get()->getTexture(_xTextureURL); - } - if (!_yTextureURL.isEmpty() && !_yTexture) { - _yTexture = DependencyManager::get()->getTexture(_yTextureURL); - } - if (!_zTextureURL.isEmpty() && !_zTexture) { - _zTexture = DependencyManager::get()->getTexture(_zTextureURL); - } - - if (_xTexture) { - batch.setResourceTexture(0, _xTexture->getGPUTexture()); - } - - RenderableDebugableEntityItem::render(this, args); -} - class RaycastFunctor { public: @@ -737,3 +628,169 @@ void RenderablePolyVoxEntityItem::setYTextureURL(QString yTextureURL) { void RenderablePolyVoxEntityItem::setZTextureURL(QString zTextureURL) { PolyVoxEntityItem::setZTextureURL(zTextureURL); } + +void RenderablePolyVoxEntityItem::getModel() { + // A mesh object to hold the result of surface extraction + PolyVox::SurfaceMesh polyVoxMesh; + + switch (_voxelSurfaceStyle) { + case PolyVoxEntityItem::SURFACE_MARCHING_CUBES: { + PolyVox::MarchingCubesSurfaceExtractor> surfaceExtractor + (_volData, _volData->getEnclosingRegion(), &polyVoxMesh); + surfaceExtractor.execute(); + break; + } + case PolyVoxEntityItem::SURFACE_EDGED_CUBIC: + case PolyVoxEntityItem::SURFACE_CUBIC: { + PolyVox::CubicSurfaceExtractorWithNormals> surfaceExtractor + (_volData, _volData->getEnclosingRegion(), &polyVoxMesh); + surfaceExtractor.execute(); + break; + } + } + + // convert PolyVox mesh to a Sam mesh + auto mesh = _modelGeometry.getMesh(); + + const std::vector& vecIndices = polyVoxMesh.getIndices(); + auto indexBuffer = std::make_shared(vecIndices.size() * sizeof(uint32_t), + (gpu::Byte*)vecIndices.data()); + auto indexBufferPtr = gpu::BufferPointer(indexBuffer); + auto indexBufferView = new gpu::BufferView(indexBufferPtr, gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::RAW)); + mesh->setIndexBuffer(*indexBufferView); + + + const std::vector& vecVertices = polyVoxMesh.getVertices(); + auto vertexBuffer = std::make_shared(vecVertices.size() * sizeof(PolyVox::PositionMaterialNormal), + (gpu::Byte*)vecVertices.data()); + auto vertexBufferPtr = gpu::BufferPointer(vertexBuffer); + auto vertexBufferView = new gpu::BufferView(vertexBufferPtr, + 0, + vertexBufferPtr->getSize() - sizeof(float) * 3, + sizeof(PolyVox::PositionMaterialNormal), + gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW)); + mesh->setVertexBuffer(*vertexBufferView); + mesh->addAttribute(gpu::Stream::NORMAL, + gpu::BufferView(vertexBufferPtr, + sizeof(float) * 3, + vertexBufferPtr->getSize() - sizeof(float) * 3, + sizeof(PolyVox::PositionMaterialNormal), + gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW))); + + + + // mesh->addAttribute(gpu::Stream::TEXCOORD, + // gpu::BufferView(vertexBufferPtr, + // sizeof(float) * 2, + // vertexBufferPtr->getSize() - sizeof(float) * 2, + // sizeof(PolyVox::PositionMaterialNormal), + // gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::RAW))); + + + + #ifdef WANT_DEBUG + qDebug() << "---- vecIndices.size() =" << vecIndices.size(); + qDebug() << "---- vecVertices.size() =" << vecVertices.size(); + #endif + + _needsModelReload = false; +} + +void RenderablePolyVoxEntityItem::render(RenderArgs* args) { + PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render"); + assert(getType() == EntityTypes::PolyVox); + Q_ASSERT(args->_batch); + + if (!_pipeline) { + gpu::ShaderPointer vertexShader = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(polyvox_vert))); + gpu::ShaderPointer pixelShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(polyvox_frag))); + + gpu::Shader::BindingSet slotBindings; + // slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT)); + + gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vertexShader, pixelShader)); + gpu::Shader::makeProgram(*program, slotBindings); + + auto state = std::make_shared(); + state->setCullMode(gpu::State::CULL_BACK); + state->setDepthTest(true, true, gpu::LESS_EQUAL); + + _pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); + } + + if (_needsModelReload) { + getModel(); + } + + gpu::Batch& batch = *args->_batch; + batch.setPipeline(_pipeline); + + auto mesh = _modelGeometry.getMesh(); + Transform transform(voxelToWorldMatrix()); + batch.setModelTransform(transform); + batch.setInputFormat(mesh->getVertexFormat()); + batch.setInputBuffer(gpu::Stream::POSITION, mesh->getVertexBuffer()); + batch.setInputBuffer(gpu::Stream::NORMAL, + mesh->getVertexBuffer()._buffer, + sizeof(float) * 3, + mesh->getVertexBuffer()._stride); + batch.setIndexBuffer(gpu::UINT32, mesh->getIndexBuffer()._buffer, 0); + batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0); + + if (!_xTextureURL.isEmpty() && !_xTexture) { + _xTexture = DependencyManager::get()->getTexture(_xTextureURL); + } + if (!_yTextureURL.isEmpty() && !_yTexture) { + _yTexture = DependencyManager::get()->getTexture(_yTextureURL); + } + if (!_zTextureURL.isEmpty() && !_zTexture) { + _zTexture = DependencyManager::get()->getTexture(_zTextureURL); + } + + // batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + + if (_xTexture) { + batch.setResourceTexture(0, _xTexture->getGPUTexture()); + } + + RenderableDebugableEntityItem::render(this, args); +} + +bool RenderablePolyVoxEntityItem::addToScene(EntityItemPointer self, + std::shared_ptr scene, + render::PendingChanges& pendingChanges) { + _myItem = scene->allocateID(); + + auto renderItem = std::make_shared(shared_from_this()); + auto renderData = PolyVoxPayload::Pointer(renderItem); + auto renderPayload = std::make_shared(renderData); + + pendingChanges.resetItem(_myItem, renderPayload); + + return true; +} + +void RenderablePolyVoxEntityItem::removeFromScene(EntityItemPointer self, + std::shared_ptr scene, + render::PendingChanges& pendingChanges) { + pendingChanges.removeItem(_myItem); +} + +namespace render { + template <> const ItemKey payloadGetKey(const PolyVoxPayload::Pointer& payload) { + return ItemKey::Builder::opaqueShape(); + } + + template <> const Item::Bound payloadGetBound(const PolyVoxPayload::Pointer& payload) { + if (payload) { + return payload->_bounds; + } + return render::Item::Bound(); + } + + template <> void payloadRender(const PolyVoxPayload::Pointer& payload, RenderArgs* args) { + if (args) { + payload->_owner->render(args); + } + } +} diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index d3fac2a7a9..6b65d834cc 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -19,6 +19,24 @@ #include "RenderableDebugableEntityItem.h" #include "RenderableEntityItem.h" + +class PolyVoxPayload { +public: + PolyVoxPayload(EntityItemPointer owner) : _owner(owner), _bounds(AABox()) { } + typedef render::Payload Payload; + typedef Payload::DataPointer Pointer; + + EntityItemPointer _owner; + AABox _bounds; +}; + +namespace render { + template <> const ItemKey payloadGetKey(const PolyVoxPayload::Pointer& payload); + template <> const Item::Bound payloadGetBound(const PolyVoxPayload::Pointer& payload); + template <> void payloadRender(const PolyVoxPayload::Pointer& payload, RenderArgs* args); +} + + class RenderablePolyVoxEntityItem : public PolyVoxEntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); @@ -71,12 +89,17 @@ public: virtual void setVoxelInVolume(glm::vec3 position, uint8_t toValue); - SIMPLE_RENDERABLE(); - virtual void setXTextureURL(QString xTextureURL); virtual void setYTextureURL(QString yTextureURL); virtual void setZTextureURL(QString zTextureURL); + virtual bool addToScene(EntityItemPointer self, + std::shared_ptr scene, + render::PendingChanges& pendingChanges); + virtual void removeFromScene(EntityItemPointer self, + std::shared_ptr scene, + render::PendingChanges& pendingChanges); + protected: virtual void updateVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle); @@ -100,6 +123,10 @@ private: NetworkTexturePointer _zTexture; int _onCount = 0; // how many non-zero voxels are in _volData + + const int MATERIAL_GPU_SLOT = 3; + render::ItemID _myItem; + /*static*/ gpu::PipelinePointer _pipeline; }; diff --git a/libraries/entities-renderer/src/polyvox.slf b/libraries/entities-renderer/src/polyvox.slf new file mode 100644 index 0000000000..28433a70ca --- /dev/null +++ b/libraries/entities-renderer/src/polyvox.slf @@ -0,0 +1,56 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// model.frag +// fragment shader +// +// Copyright 2015 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 +// + + +// the glow intensity +uniform float glowIntensity; + +// the alpha threshold +uniform float alphaThreshold; + +float evalOpaqueFinalAlpha(float alpha, float mapAlpha) { + return mix(alpha * glowIntensity, 1.0 - alpha * glowIntensity, step(mapAlpha, alphaThreshold)); +} + +void packDeferredFragment(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess) { + if (alpha != glowIntensity) { + discard; + } + gl_FragData[0] = vec4(diffuse.rgb, alpha); + gl_FragData[1] = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); + gl_FragData[2] = vec4(specular, shininess / 128.0); +} + +<@include model/Material.slh@> + +// the diffuse texture +uniform sampler2D diffuseMap; + +// the interpolated normal +varying vec4 interpolatedNormal; + +varying vec3 color; + + +void main(void) { + // Fetch diffuse map + vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); + + Material mat = getMaterial(); + + packDeferredFragment( + normalize(interpolatedNormal.xyz), + evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), + getMaterialDiffuse(mat) * diffuse.rgb * color, + getMaterialSpecular(mat), + getMaterialShininess(mat)); +} diff --git a/libraries/entities-renderer/src/polyvox.slv b/libraries/entities-renderer/src/polyvox.slv new file mode 100644 index 0000000000..e413b852dc --- /dev/null +++ b/libraries/entities-renderer/src/polyvox.slv @@ -0,0 +1,44 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// polyvox.vert +// vertex shader +// +// Copyright 2015 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 +// + +<@include gpu/Transform.slh@> + +<$declareStandardTransform()$> + +const int MAX_TEXCOORDS = 2; + +uniform mat4 texcoordMatrices[MAX_TEXCOORDS]; + +// interpolated eye position +varying vec4 interpolatedPosition; + +// the interpolated normal +varying vec4 interpolatedNormal; + +varying vec3 color; + +void main(void) { + + // pass along the diffuse color + color = gl_Color.xyz; + + // and the texture coordinates + gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); + + // standard transform + TransformCamera cam = getTransformCamera(); + TransformObject obj = getTransformObject(); + <$transformModelToEyeAndClipPos(cam, obj, gl_Vertex, interpolatedPosition, gl_Position)$> + <$transformModelToEyeDir(cam, obj, gl_Normal, interpolatedNormal.xyz)$> + + interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0); +} From dbca3fe2fbda2297e466b32ac9573e147dde21da Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 1 Aug 2015 05:58:22 -0700 Subject: [PATCH 2/5] attempt to give polyvox its own rendering bung --- .../src/RenderablePolyVoxEntityItem.cpp | 21 ++++++++++++------- .../src/RenderablePolyVoxEntityItem.h | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index d8d1975c0b..4f21fec4d3 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -42,7 +42,7 @@ #include "polyvox_frag.h" #include "RenderablePolyVoxEntityItem.h" -// gpu::PipelinePointer RenderablePolyVoxEntityItem::_pipeline = nullptr; +gpu::PipelinePointer RenderablePolyVoxEntityItem::_pipeline = nullptr; EntityItemPointer RenderablePolyVoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { return std::make_shared(entityID, properties); @@ -54,7 +54,6 @@ RenderablePolyVoxEntityItem::RenderablePolyVoxEntityItem(const EntityItemID& ent _xTexture(nullptr), _yTexture(nullptr), _zTexture(nullptr) { - model::Mesh* mesh = new model::Mesh(); model::MeshPointer meshPtr(mesh); _modelGeometry.setMesh(meshPtr); @@ -706,7 +705,12 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) { gpu::ShaderPointer pixelShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(polyvox_frag))); gpu::Shader::BindingSet slotBindings; - // slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT)); + slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT)); + // slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), 0)); + // slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), 1)); + // slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), 2)); + // slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), 3)); + // slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), 4)); gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vertexShader, pixelShader)); gpu::Shader::makeProgram(*program, slotBindings); @@ -747,7 +751,7 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) { _zTexture = DependencyManager::get()->getTexture(_zTextureURL); } - // batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f); if (_xTexture) { batch.setResourceTexture(0, _xTexture->getGPUTexture()); @@ -782,14 +786,15 @@ namespace render { } template <> const Item::Bound payloadGetBound(const PolyVoxPayload::Pointer& payload) { - if (payload) { - return payload->_bounds; - } + // if (payload && payload->_owner) { + // auto polyVoxEntity = std::dynamic_pointer_cast(payload->_owner); + // return polyVoxEntity->getBoundingBox(); + // } return render::Item::Bound(); } template <> void payloadRender(const PolyVoxPayload::Pointer& payload, RenderArgs* args) { - if (args) { + if (args && payload && payload->_owner) { payload->_owner->render(args); } } diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index 6b65d834cc..d495900ce9 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -126,7 +126,7 @@ private: const int MATERIAL_GPU_SLOT = 3; render::ItemID _myItem; - /*static*/ gpu::PipelinePointer _pipeline; + static gpu::PipelinePointer _pipeline; }; From dbda5ba40e0f08dfd502b174611fa1e16e02fe7e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 4 Aug 2015 11:26:29 -0700 Subject: [PATCH 3/5] change polyvox rendering --- examples/voxels.js | 2 +- .../src/RenderablePolyVoxEntityItem.cpp | 138 ++++++++++++++++++ .../src/RenderablePolyVoxEntityItem.h | 10 ++ 3 files changed, 149 insertions(+), 1 deletion(-) diff --git a/examples/voxels.js b/examples/voxels.js index e110f15260..9627b40701 100644 --- a/examples/voxels.js +++ b/examples/voxels.js @@ -44,7 +44,7 @@ function mousePressEvent(event) { } } - // if the PolyVox entity is empty, we can't pick against its voxel. try picking against its + // if the PolyVox entity is empty, we can't pick against its "on" voxels. try picking against its // bounding box, instead. intersection = Entities.findRayIntersection(pickRay, false); // bounding box picking if (intersection.intersects) { diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 4f21fec4d3..ca049e45b1 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -331,6 +331,144 @@ void RenderablePolyVoxEntityItem::setSphere(glm::vec3 centerWorldCoords, float r setSphereInVolume(glm::vec3(centerVoxelCoords), radiusVoxelCoords, toValue); } +void RenderablePolyVoxEntityItem::getModel() { + // A mesh object to hold the result of surface extraction + PolyVox::SurfaceMesh polyVoxMesh; + + switch (_voxelSurfaceStyle) { + case PolyVoxEntityItem::SURFACE_MARCHING_CUBES: { + PolyVox::MarchingCubesSurfaceExtractor> surfaceExtractor + (_volData, _volData->getEnclosingRegion(), &polyVoxMesh); + surfaceExtractor.execute(); + break; + } + case PolyVoxEntityItem::SURFACE_EDGED_CUBIC: + case PolyVoxEntityItem::SURFACE_CUBIC: { + PolyVox::CubicSurfaceExtractorWithNormals> surfaceExtractor + (_volData, _volData->getEnclosingRegion(), &polyVoxMesh); + surfaceExtractor.execute(); + break; + } + } + + // convert PolyVox mesh to a Sam mesh + auto mesh = _modelGeometry.getMesh(); + + const std::vector& vecIndices = polyVoxMesh.getIndices(); + auto indexBuffer = std::make_shared(vecIndices.size() * sizeof(uint32_t), + (gpu::Byte*)vecIndices.data()); + auto indexBufferPtr = gpu::BufferPointer(indexBuffer); + auto indexBufferView = new gpu::BufferView(indexBufferPtr, gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::RAW)); + mesh->setIndexBuffer(*indexBufferView); + + + const std::vector& vecVertices = polyVoxMesh.getVertices(); + auto vertexBuffer = std::make_shared(vecVertices.size() * sizeof(PolyVox::PositionMaterialNormal), + (gpu::Byte*)vecVertices.data()); + auto vertexBufferPtr = gpu::BufferPointer(vertexBuffer); + auto vertexBufferView = new gpu::BufferView(vertexBufferPtr, + 0, + vertexBufferPtr->getSize() - sizeof(float) * 3, + sizeof(PolyVox::PositionMaterialNormal), + gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW)); + mesh->setVertexBuffer(*vertexBufferView); + mesh->addAttribute(gpu::Stream::NORMAL, + gpu::BufferView(vertexBufferPtr, + sizeof(float) * 3, + vertexBufferPtr->getSize() - sizeof(float) * 3, + sizeof(PolyVox::PositionMaterialNormal), + gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW))); + + + + // auto normalAttrib = mesh->getAttributeBuffer(gpu::Stream::NORMAL); + // for (auto normal = normalAttrib.begin(); normal != normalAttrib.end(); normal++) { + // (*normal) = -(*normal); + // } + + + // mesh->addAttribute(gpu::Stream::TEXCOORD, + // gpu::BufferView(vertexBufferPtr, + // sizeof(float) * 2, + // vertexBufferPtr->getSize() - sizeof(float) * 2, + // sizeof(PolyVox::PositionMaterialNormal), + // gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::RAW))); + + + + #ifdef WANT_DEBUG + qDebug() << "---- vecIndices.size() =" << vecIndices.size(); + qDebug() << "---- vecVertices.size() =" << vecVertices.size(); + #endif + + _needsModelReload = false; +} + +bool RenderablePolyVoxEntityItem::addToScene(EntityItemPointer self, + std::shared_ptr scene, + render::PendingChanges& pendingChanges) { + _myItem = scene->allocateID(); + + std::shared_ptr renderData = + RenderableEntityItemProxy::Pointer(new RenderableEntityItemProxy(self)); + // render::PayloadPointer renderPayload = + std::shared_ptr renderPayload = + render::PayloadPointer(new RenderableEntityItemProxy::Payload(renderData)); + + pendingChanges.resetItem(_myItem, renderPayload); + + return true; +} + +void RenderablePolyVoxEntityItem::removeFromScene(EntityItemPointer self, + std::shared_ptr scene, + render::PendingChanges& pendingChanges) { + pendingChanges.removeItem(_myItem); +} + + + +void RenderablePolyVoxEntityItem::render(RenderArgs* args) { + PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render"); + assert(getType() == EntityTypes::PolyVox); + + if (_needsModelReload) { + getModel(); + } + + Transform transform(voxelToWorldMatrix()); + + auto mesh = _modelGeometry.getMesh(); + Q_ASSERT(args->_batch); + gpu::Batch& batch = *args->_batch; + DependencyManager::get()->bindSimpleProgram(batch, true); + batch.setModelTransform(transform); + batch.setInputFormat(mesh->getVertexFormat()); + batch.setInputBuffer(gpu::Stream::POSITION, mesh->getVertexBuffer()); + batch.setInputBuffer(gpu::Stream::NORMAL, + mesh->getVertexBuffer()._buffer, + sizeof(float) * 3, + mesh->getVertexBuffer()._stride); + batch.setIndexBuffer(gpu::UINT32, mesh->getIndexBuffer()._buffer, 0); + batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0); + + if (!_xTextureURL.isEmpty() && !_xTexture) { + _xTexture = DependencyManager::get()->getTexture(_xTextureURL); + } + if (!_yTextureURL.isEmpty() && !_yTexture) { + _yTexture = DependencyManager::get()->getTexture(_yTextureURL); + } + if (!_zTextureURL.isEmpty() && !_zTexture) { + _zTexture = DependencyManager::get()->getTexture(_zTextureURL); + } + + if (_xTexture) { + batch.setResourceTexture(0, _xTexture->getGPUTexture()); + } + + RenderableDebugableEntityItem::render(this, args); +} + class RaycastFunctor { public: diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index d495900ce9..40925cb765 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -89,6 +89,14 @@ public: virtual void setVoxelInVolume(glm::vec3 position, uint8_t toValue); + virtual bool addToScene(EntityItemPointer self, + std::shared_ptr scene, + render::PendingChanges& pendingChanges); + virtual void removeFromScene(EntityItemPointer self, + std::shared_ptr scene, + render::PendingChanges& pendingChanges); + + virtual void setXTextureURL(QString xTextureURL); virtual void setYTextureURL(QString yTextureURL); virtual void setZTextureURL(QString zTextureURL); @@ -104,6 +112,8 @@ protected: virtual void updateVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle); private: + render::ItemID _myItem; + // The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions // may not match _voxelVolumeSize. From 419caccd8ec9675ff204d203d67de81d931688ae Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 4 Aug 2015 17:06:17 -0700 Subject: [PATCH 4/5] unmangle merge --- .../src/RenderablePolyVoxEntityItem.cpp | 138 ------------------ .../src/RenderablePolyVoxEntityItem.h | 10 -- 2 files changed, 148 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index ca049e45b1..4f21fec4d3 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -331,144 +331,6 @@ void RenderablePolyVoxEntityItem::setSphere(glm::vec3 centerWorldCoords, float r setSphereInVolume(glm::vec3(centerVoxelCoords), radiusVoxelCoords, toValue); } -void RenderablePolyVoxEntityItem::getModel() { - // A mesh object to hold the result of surface extraction - PolyVox::SurfaceMesh polyVoxMesh; - - switch (_voxelSurfaceStyle) { - case PolyVoxEntityItem::SURFACE_MARCHING_CUBES: { - PolyVox::MarchingCubesSurfaceExtractor> surfaceExtractor - (_volData, _volData->getEnclosingRegion(), &polyVoxMesh); - surfaceExtractor.execute(); - break; - } - case PolyVoxEntityItem::SURFACE_EDGED_CUBIC: - case PolyVoxEntityItem::SURFACE_CUBIC: { - PolyVox::CubicSurfaceExtractorWithNormals> surfaceExtractor - (_volData, _volData->getEnclosingRegion(), &polyVoxMesh); - surfaceExtractor.execute(); - break; - } - } - - // convert PolyVox mesh to a Sam mesh - auto mesh = _modelGeometry.getMesh(); - - const std::vector& vecIndices = polyVoxMesh.getIndices(); - auto indexBuffer = std::make_shared(vecIndices.size() * sizeof(uint32_t), - (gpu::Byte*)vecIndices.data()); - auto indexBufferPtr = gpu::BufferPointer(indexBuffer); - auto indexBufferView = new gpu::BufferView(indexBufferPtr, gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::RAW)); - mesh->setIndexBuffer(*indexBufferView); - - - const std::vector& vecVertices = polyVoxMesh.getVertices(); - auto vertexBuffer = std::make_shared(vecVertices.size() * sizeof(PolyVox::PositionMaterialNormal), - (gpu::Byte*)vecVertices.data()); - auto vertexBufferPtr = gpu::BufferPointer(vertexBuffer); - auto vertexBufferView = new gpu::BufferView(vertexBufferPtr, - 0, - vertexBufferPtr->getSize() - sizeof(float) * 3, - sizeof(PolyVox::PositionMaterialNormal), - gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW)); - mesh->setVertexBuffer(*vertexBufferView); - mesh->addAttribute(gpu::Stream::NORMAL, - gpu::BufferView(vertexBufferPtr, - sizeof(float) * 3, - vertexBufferPtr->getSize() - sizeof(float) * 3, - sizeof(PolyVox::PositionMaterialNormal), - gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RAW))); - - - - // auto normalAttrib = mesh->getAttributeBuffer(gpu::Stream::NORMAL); - // for (auto normal = normalAttrib.begin(); normal != normalAttrib.end(); normal++) { - // (*normal) = -(*normal); - // } - - - // mesh->addAttribute(gpu::Stream::TEXCOORD, - // gpu::BufferView(vertexBufferPtr, - // sizeof(float) * 2, - // vertexBufferPtr->getSize() - sizeof(float) * 2, - // sizeof(PolyVox::PositionMaterialNormal), - // gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::RAW))); - - - - #ifdef WANT_DEBUG - qDebug() << "---- vecIndices.size() =" << vecIndices.size(); - qDebug() << "---- vecVertices.size() =" << vecVertices.size(); - #endif - - _needsModelReload = false; -} - -bool RenderablePolyVoxEntityItem::addToScene(EntityItemPointer self, - std::shared_ptr scene, - render::PendingChanges& pendingChanges) { - _myItem = scene->allocateID(); - - std::shared_ptr renderData = - RenderableEntityItemProxy::Pointer(new RenderableEntityItemProxy(self)); - // render::PayloadPointer renderPayload = - std::shared_ptr renderPayload = - render::PayloadPointer(new RenderableEntityItemProxy::Payload(renderData)); - - pendingChanges.resetItem(_myItem, renderPayload); - - return true; -} - -void RenderablePolyVoxEntityItem::removeFromScene(EntityItemPointer self, - std::shared_ptr scene, - render::PendingChanges& pendingChanges) { - pendingChanges.removeItem(_myItem); -} - - - -void RenderablePolyVoxEntityItem::render(RenderArgs* args) { - PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render"); - assert(getType() == EntityTypes::PolyVox); - - if (_needsModelReload) { - getModel(); - } - - Transform transform(voxelToWorldMatrix()); - - auto mesh = _modelGeometry.getMesh(); - Q_ASSERT(args->_batch); - gpu::Batch& batch = *args->_batch; - DependencyManager::get()->bindSimpleProgram(batch, true); - batch.setModelTransform(transform); - batch.setInputFormat(mesh->getVertexFormat()); - batch.setInputBuffer(gpu::Stream::POSITION, mesh->getVertexBuffer()); - batch.setInputBuffer(gpu::Stream::NORMAL, - mesh->getVertexBuffer()._buffer, - sizeof(float) * 3, - mesh->getVertexBuffer()._stride); - batch.setIndexBuffer(gpu::UINT32, mesh->getIndexBuffer()._buffer, 0); - batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0); - - if (!_xTextureURL.isEmpty() && !_xTexture) { - _xTexture = DependencyManager::get()->getTexture(_xTextureURL); - } - if (!_yTextureURL.isEmpty() && !_yTexture) { - _yTexture = DependencyManager::get()->getTexture(_yTextureURL); - } - if (!_zTextureURL.isEmpty() && !_zTexture) { - _zTexture = DependencyManager::get()->getTexture(_zTextureURL); - } - - if (_xTexture) { - batch.setResourceTexture(0, _xTexture->getGPUTexture()); - } - - RenderableDebugableEntityItem::render(this, args); -} - class RaycastFunctor { public: diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index 40925cb765..d495900ce9 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -89,14 +89,6 @@ public: virtual void setVoxelInVolume(glm::vec3 position, uint8_t toValue); - virtual bool addToScene(EntityItemPointer self, - std::shared_ptr scene, - render::PendingChanges& pendingChanges); - virtual void removeFromScene(EntityItemPointer self, - std::shared_ptr scene, - render::PendingChanges& pendingChanges); - - virtual void setXTextureURL(QString xTextureURL); virtual void setYTextureURL(QString yTextureURL); virtual void setZTextureURL(QString zTextureURL); @@ -112,8 +104,6 @@ protected: virtual void updateVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle); private: - render::ItemID _myItem; - // The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions // may not match _voxelVolumeSize. From 56c0f9c814b32266cd9c599bc1a7d71f0035cbce Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 4 Aug 2015 17:37:15 -0700 Subject: [PATCH 5/5] work toward getting textures on polyvox entities --- .../src/RenderablePolyVoxEntityItem.cpp | 10 +++++++--- libraries/entities-renderer/src/polyvox.slf | 8 ++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 4f21fec4d3..748ca29770 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -706,8 +706,8 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) { gpu::Shader::BindingSet slotBindings; slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT)); - // slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), 0)); - // slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), 1)); + slotBindings.insert(gpu::Shader::Binding(std::string("xMap"), 0)); + slotBindings.insert(gpu::Shader::Binding(std::string("yMap"), 1)); // slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), 2)); // slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), 3)); // slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), 4)); @@ -739,7 +739,6 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) { sizeof(float) * 3, mesh->getVertexBuffer()._stride); batch.setIndexBuffer(gpu::UINT32, mesh->getIndexBuffer()._buffer, 0); - batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0); if (!_xTextureURL.isEmpty() && !_xTexture) { _xTexture = DependencyManager::get()->getTexture(_xTextureURL); @@ -756,6 +755,11 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) { if (_xTexture) { batch.setResourceTexture(0, _xTexture->getGPUTexture()); } + if (_yTexture) { + batch.setResourceTexture(1, _yTexture->getGPUTexture()); + } + + batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0); RenderableDebugableEntityItem::render(this, args); } diff --git a/libraries/entities-renderer/src/polyvox.slf b/libraries/entities-renderer/src/polyvox.slf index 28433a70ca..2d67149bf8 100644 --- a/libraries/entities-renderer/src/polyvox.slf +++ b/libraries/entities-renderer/src/polyvox.slf @@ -49,8 +49,8 @@ void main(void) { packDeferredFragment( normalize(interpolatedNormal.xyz), - evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), - getMaterialDiffuse(mat) * diffuse.rgb * color, - getMaterialSpecular(mat), - getMaterialShininess(mat)); + 0.0, + /*getMaterialDiffuse(mat)*/ /*diffuse.rgb * color*/ vec3(1.0, 1.0, 1.0), + /*getMaterialSpecular(mat)*/ vec3(0.02, 0.02, 0.02), + /*getMaterialShininess(mat)*/ 10.0); }