mirror of
https://github.com/overte-org/overte.git
synced 2025-08-18 13:53:19 +02:00
Change payload interface to return ShapeKey, not MaterialKey
This commit is contained in:
parent
16bb861046
commit
59a354ea8c
5 changed files with 173 additions and 122 deletions
|
@ -14,30 +14,36 @@
|
|||
#include <PerfStat.h>
|
||||
|
||||
#include "DeferredLightingEffect.h"
|
||||
|
||||
#include "Model.h"
|
||||
|
||||
namespace render {
|
||||
template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload) {
|
||||
if (payload) {
|
||||
return payload->getKey();
|
||||
}
|
||||
// Return opaque for lack of a better idea
|
||||
return ItemKey::Builder::opaqueShape();
|
||||
}
|
||||
using namespace render;
|
||||
|
||||
template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload) {
|
||||
if (payload) {
|
||||
return payload->getBound();
|
||||
}
|
||||
return render::Item::Bound();
|
||||
}
|
||||
template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args) {
|
||||
return payload->render(args);
|
||||
namespace render {
|
||||
template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload) {
|
||||
if (payload) {
|
||||
return payload->getKey();
|
||||
}
|
||||
return ItemKey::Builder::opaqueShape(); // for lack of a better idea
|
||||
}
|
||||
|
||||
using namespace render;
|
||||
template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload) {
|
||||
if (payload) {
|
||||
return payload->getBound();
|
||||
}
|
||||
return Item::Bound();
|
||||
}
|
||||
|
||||
template <> const ShapeKey shapeGetShapeKey(const MeshPartPayload::Pointer& payload) {
|
||||
if (payload) {
|
||||
return payload->getShapeKey();
|
||||
}
|
||||
return ShapeKey::Builder::invalid();
|
||||
}
|
||||
|
||||
template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args) {
|
||||
return payload->render(args);
|
||||
}
|
||||
}
|
||||
|
||||
MeshPartPayload::MeshPartPayload(model::MeshPointer mesh, int partIndex, model::MaterialPointer material, const Transform& transform, const Transform& offsetTransform) {
|
||||
|
||||
|
@ -69,7 +75,7 @@ void MeshPartPayload::updateMaterial(model::MaterialPointer drawMaterial) {
|
|||
_drawMaterial = drawMaterial;
|
||||
}
|
||||
|
||||
render::ItemKey MeshPartPayload::getKey() const {
|
||||
ItemKey MeshPartPayload::getKey() const {
|
||||
ItemKey::Builder builder;
|
||||
builder.withTypeShape();
|
||||
|
||||
|
@ -83,10 +89,29 @@ render::ItemKey MeshPartPayload::getKey() const {
|
|||
return builder.build();
|
||||
}
|
||||
|
||||
render::Item::Bound MeshPartPayload::getBound() const {
|
||||
Item::Bound MeshPartPayload::getBound() const {
|
||||
return _worldBound;
|
||||
}
|
||||
|
||||
ShapeKey MeshPartPayload::getShapeKey() const {
|
||||
model::MaterialKey drawMaterialKey;
|
||||
if (_drawMaterial) {
|
||||
drawMaterialKey = _drawMaterial->getKey();
|
||||
}
|
||||
|
||||
bool isTranslucent = drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap();
|
||||
bool hasTangents = drawMaterialKey.isNormalMap();
|
||||
bool hasSpecular = drawMaterialKey.isGlossMap();
|
||||
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
||||
|
||||
ShapeKey::Builder builder;
|
||||
if (isTranslucent) { builder.withTranslucent(); }
|
||||
if (hasTangents) { builder.withTangents(); }
|
||||
if (hasSpecular) { builder.withSpecular(); }
|
||||
if (hasLightmap) { builder.withLightmap(); }
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
void MeshPartPayload::drawCall(gpu::Batch& batch) const {
|
||||
batch.drawIndexed(gpu::TRIANGLES, _drawPart._numIndices, _drawPart._startIndex);
|
||||
}
|
||||
|
@ -195,27 +220,13 @@ void MeshPartPayload::bindTransform(gpu::Batch& batch, const ModelRender::Locati
|
|||
void MeshPartPayload::render(RenderArgs* args) const {
|
||||
PerformanceTimer perfTimer("MeshPartPayload::render");
|
||||
|
||||
|
||||
gpu::Batch& batch = *(args->_batch);
|
||||
auto mode = args->_renderMode;
|
||||
|
||||
model::MaterialKey drawMaterialKey;
|
||||
if (_drawMaterial) {
|
||||
drawMaterialKey = _drawMaterial->getKey();
|
||||
}
|
||||
bool translucentMesh = drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap();
|
||||
|
||||
bool hasTangents = drawMaterialKey.isNormalMap();
|
||||
bool hasSpecular = drawMaterialKey.isGlossMap();
|
||||
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
||||
bool isSkinned = false;
|
||||
bool wireframe = false;
|
||||
if (wireframe) {
|
||||
translucentMesh = hasTangents = hasSpecular = hasLightmap = isSkinned = false;
|
||||
}
|
||||
ShapeKey key = getShapeKey();
|
||||
|
||||
ModelRender::Locations* locations = nullptr;
|
||||
ModelRender::pickPrograms(batch, mode, translucentMesh, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe,
|
||||
ModelRender::pickPrograms(batch, mode, key.isTranslucent(), key.hasLightmap(), key.hasTangents(), key.hasSpecular(), key.isSkinned(), key.isWireFrame(),
|
||||
args, locations);
|
||||
|
||||
|
||||
|
@ -230,7 +241,7 @@ void MeshPartPayload::render(RenderArgs* args) const {
|
|||
|
||||
|
||||
// TODO: We should be able to do that just in the renderTransparentJob
|
||||
if (translucentMesh && locations->lightBufferUnit >= 0) {
|
||||
if (key.isTranslucent() && locations->lightBufferUnit >= 0) {
|
||||
PerformanceTimer perfTimer("DLE->setupTransparent()");
|
||||
|
||||
DependencyManager::get<DeferredLightingEffect>()->setupTransparent(args, locations->lightBufferUnit);
|
||||
|
@ -251,29 +262,32 @@ void MeshPartPayload::render(RenderArgs* args) const {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace render {
|
||||
template <> const ItemKey payloadGetKey(const ModelMeshPartPayload::Pointer& payload) {
|
||||
if (payload) {
|
||||
return payload->getKey();
|
||||
}
|
||||
// Return opaque for lack of a better idea
|
||||
return ItemKey::Builder::opaqueShape();
|
||||
}
|
||||
|
||||
template <> const Item::Bound payloadGetBound(const ModelMeshPartPayload::Pointer& payload) {
|
||||
if (payload) {
|
||||
return payload->getBound();
|
||||
}
|
||||
return render::Item::Bound();
|
||||
}
|
||||
template <> void payloadRender(const ModelMeshPartPayload::Pointer& payload, RenderArgs* args) {
|
||||
return payload->render(args);
|
||||
template <> const ItemKey payloadGetKey(const ModelMeshPartPayload::Pointer& payload) {
|
||||
if (payload) {
|
||||
return payload->getKey();
|
||||
}
|
||||
return ItemKey::Builder::opaqueShape(); // for lack of a better idea
|
||||
}
|
||||
|
||||
using namespace render;
|
||||
template <> const Item::Bound payloadGetBound(const ModelMeshPartPayload::Pointer& payload) {
|
||||
if (payload) {
|
||||
return payload->getBound();
|
||||
}
|
||||
return Item::Bound();
|
||||
}
|
||||
|
||||
template <> const ShapeKey shapeGetShapeKey(const ModelMeshPartPayload::Pointer& payload) {
|
||||
if (payload) {
|
||||
return payload->getShapeKey();
|
||||
}
|
||||
return ShapeKey::Builder::invalid();
|
||||
}
|
||||
|
||||
template <> void payloadRender(const ModelMeshPartPayload::Pointer& payload, RenderArgs* args) {
|
||||
return payload->render(args);
|
||||
}
|
||||
}
|
||||
|
||||
ModelMeshPartPayload::ModelMeshPartPayload(Model* model, int _meshIndex, int partIndex, int shapeIndex, const Transform& transform, const Transform& offsetTransform) :
|
||||
_model(model),
|
||||
|
@ -310,7 +324,7 @@ void ModelMeshPartPayload::notifyLocationChanged() {
|
|||
_model->_needsUpdateClusterMatrices = true;
|
||||
}
|
||||
|
||||
render::ItemKey ModelMeshPartPayload::getKey() const {
|
||||
ItemKey ModelMeshPartPayload::getKey() const {
|
||||
ItemKey::Builder builder;
|
||||
builder.withTypeShape();
|
||||
|
||||
|
@ -332,12 +346,70 @@ render::ItemKey ModelMeshPartPayload::getKey() const {
|
|||
return builder.build();
|
||||
}
|
||||
|
||||
render::Item::Bound ModelMeshPartPayload::getBound() const {
|
||||
Item::Bound ModelMeshPartPayload::getBound() const {
|
||||
// NOTE: we can't cache this bounds because we need to handle the case of a moving
|
||||
// entity or mesh part.
|
||||
return _model->getPartBounds(_meshIndex, _partIndex, _transform.getTranslation(), _transform.getRotation());
|
||||
}
|
||||
|
||||
ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
||||
const FBXGeometry& geometry = _model->_geometry->getFBXGeometry();
|
||||
const std::vector<std::unique_ptr<NetworkMesh>>& networkMeshes = _model->_geometry->getMeshes();
|
||||
|
||||
// guard against partially loaded meshes
|
||||
if (_meshIndex >= (int)networkMeshes.size() || _meshIndex >= (int)geometry.meshes.size() || _meshIndex >= (int)_model->_meshStates.size()) {
|
||||
return ShapeKey::Builder::invalid();
|
||||
}
|
||||
|
||||
// Back to model to update the cluster matrices right now
|
||||
_model->updateClusterMatrices(_transform.getTranslation(), _transform.getRotation());
|
||||
|
||||
const FBXMesh& mesh = geometry.meshes.at(_meshIndex);
|
||||
|
||||
// if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown
|
||||
// to false to rebuild out mesh groups.
|
||||
if (_meshIndex < 0 || _meshIndex >= (int)networkMeshes.size() || _meshIndex > geometry.meshes.size()) {
|
||||
_model->_meshGroupsKnown = false; // regenerate these lists next time around.
|
||||
_model->_readyWhenAdded = false; // in case any of our users are using scenes
|
||||
_model->invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid
|
||||
return ShapeKey::Builder::invalid();
|
||||
}
|
||||
|
||||
|
||||
int vertexCount = mesh.vertices.size();
|
||||
if (vertexCount == 0) {
|
||||
// sanity check
|
||||
return ShapeKey::Builder::invalid();
|
||||
}
|
||||
|
||||
|
||||
model::MaterialKey drawMaterialKey;
|
||||
if (_drawMaterial) {
|
||||
drawMaterialKey = _drawMaterial->getKey();
|
||||
}
|
||||
|
||||
bool isTranslucent = drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap();
|
||||
bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty();
|
||||
bool hasSpecular = drawMaterialKey.isGlossMap();
|
||||
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
||||
|
||||
bool isSkinned = _isSkinned;
|
||||
bool wireframe = _model->isWireframe();
|
||||
|
||||
if (wireframe) {
|
||||
isTranslucent = hasTangents = hasSpecular = hasLightmap = isSkinned = false;
|
||||
}
|
||||
|
||||
ShapeKey::Builder builder;
|
||||
if (isTranslucent) { builder.withTranslucent(); }
|
||||
if (hasTangents) { builder.withTangents(); }
|
||||
if (hasSpecular) { builder.withSpecular(); }
|
||||
if (hasLightmap) { builder.withLightmap(); }
|
||||
if (isSkinned) { builder.withSkinned(); }
|
||||
if (wireframe) { builder.withWireframe(); }
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
void ModelMeshPartPayload::bindMesh(gpu::Batch& batch) const {
|
||||
if (!_isBlendShaped) {
|
||||
batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0);
|
||||
|
@ -387,6 +459,7 @@ void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, const ModelRender::L
|
|||
|
||||
void ModelMeshPartPayload::render(RenderArgs* args) const {
|
||||
PerformanceTimer perfTimer("ModelMeshPartPayload::render");
|
||||
|
||||
if (!_model->_readyWhenAdded || !_model->_isVisible) {
|
||||
return; // bail asap
|
||||
}
|
||||
|
@ -394,47 +467,11 @@ void ModelMeshPartPayload::render(RenderArgs* args) const {
|
|||
gpu::Batch& batch = *(args->_batch);
|
||||
auto mode = args->_renderMode;
|
||||
|
||||
const FBXGeometry& geometry = _model->_geometry->getFBXGeometry();
|
||||
const std::vector<std::unique_ptr<NetworkMesh>>& networkMeshes = _model->_geometry->getMeshes();
|
||||
|
||||
// guard against partially loaded meshes
|
||||
if (_meshIndex >= (int)networkMeshes.size() || _meshIndex >= (int)geometry.meshes.size() || _meshIndex >= (int)_model->_meshStates.size() ) {
|
||||
ShapeKey key = getShapeKey();
|
||||
if (!key.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Back to model to update the cluster matrices right now
|
||||
_model->updateClusterMatrices(_transform.getTranslation(), _transform.getRotation());
|
||||
|
||||
const FBXMesh& mesh = geometry.meshes.at(_meshIndex);
|
||||
|
||||
// if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown
|
||||
// to false to rebuild out mesh groups.
|
||||
if (_meshIndex < 0 || _meshIndex >= (int)networkMeshes.size() || _meshIndex > geometry.meshes.size()) {
|
||||
_model->_meshGroupsKnown = false; // regenerate these lists next time around.
|
||||
_model->_readyWhenAdded = false; // in case any of our users are using scenes
|
||||
_model->invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid
|
||||
return; // FIXME!
|
||||
}
|
||||
|
||||
|
||||
int vertexCount = mesh.vertices.size();
|
||||
if (vertexCount == 0) {
|
||||
// sanity check
|
||||
return; // FIXME!
|
||||
}
|
||||
|
||||
model::MaterialKey drawMaterialKey;
|
||||
if (_drawMaterial) {
|
||||
drawMaterialKey = _drawMaterial->getKey();
|
||||
}
|
||||
bool translucentMesh = drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap();
|
||||
|
||||
bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty();
|
||||
bool hasSpecular = drawMaterialKey.isGlossMap();
|
||||
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
||||
bool isSkinned = _isSkinned;
|
||||
bool wireframe = _model->isWireframe();
|
||||
|
||||
// render the part bounding box
|
||||
#ifdef DEBUG_BOUNDING_PARTS
|
||||
{
|
||||
|
@ -458,12 +495,8 @@ void ModelMeshPartPayload::render(RenderArgs* args) const {
|
|||
}
|
||||
#endif //def DEBUG_BOUNDING_PARTS
|
||||
|
||||
if (wireframe) {
|
||||
translucentMesh = hasTangents = hasSpecular = hasLightmap = isSkinned = false;
|
||||
}
|
||||
|
||||
ModelRender::Locations* locations = nullptr;
|
||||
ModelRender::pickPrograms(batch, mode, translucentMesh, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe,
|
||||
ModelRender::pickPrograms(batch, mode, key.isTranslucent(), key.hasLightmap(), key.hasTangents(), key.hasSpecular(), key.isSkinned(), key.isWireFrame(),
|
||||
args, locations);
|
||||
|
||||
if (!locations) { // the pipeline could not be found
|
||||
|
@ -481,7 +514,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) const {
|
|||
|
||||
|
||||
// TODO: We should be able to do that just in the renderTransparentJob
|
||||
if (translucentMesh && locations->lightBufferUnit >= 0) {
|
||||
if (key.isTranslucent() && locations->lightBufferUnit >= 0) {
|
||||
PerformanceTimer perfTimer("DLE->setupTransparent()");
|
||||
|
||||
DependencyManager::get<DeferredLightingEffect>()->setupTransparent(args, locations->lightBufferUnit);
|
||||
|
|
|
@ -40,6 +40,7 @@ public:
|
|||
// Render Item interface
|
||||
virtual render::ItemKey getKey() const;
|
||||
virtual render::Item::Bound getBound() const;
|
||||
virtual render::ShapeKey getShapeKey() const; // shape interface
|
||||
virtual void render(RenderArgs* args) const;
|
||||
|
||||
// ModelMeshPartPayload functions to perform render
|
||||
|
@ -67,10 +68,10 @@ public:
|
|||
namespace render {
|
||||
template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload);
|
||||
template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload);
|
||||
template <> const ShapeKey shapeGetShapeKey(const MeshPartPayload::Pointer& payload);
|
||||
template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args);
|
||||
}
|
||||
|
||||
|
||||
class ModelMeshPartPayload : public MeshPartPayload {
|
||||
public:
|
||||
ModelMeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex, const Transform& transform, const Transform& offsetTransform);
|
||||
|
@ -83,8 +84,9 @@ public:
|
|||
// Render Item interface
|
||||
render::ItemKey getKey() const override;
|
||||
render::Item::Bound getBound() const override;
|
||||
render::ShapeKey getShapeKey() const override; // shape interface
|
||||
void render(RenderArgs* args) const override;
|
||||
|
||||
|
||||
// ModelMeshPartPayload functions to perform render
|
||||
void bindMesh(gpu::Batch& batch) const override;
|
||||
void bindTransform(gpu::Batch& batch, const ModelRender::Locations* locations) const override;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <RenderArgs.h>
|
||||
|
||||
#include "model/Material.h"
|
||||
#include "Shape.h"
|
||||
|
||||
namespace render {
|
||||
|
||||
|
@ -264,7 +265,7 @@ public:
|
|||
|
||||
virtual void render(RenderArgs* args) = 0;
|
||||
|
||||
virtual const model::MaterialKey getMaterialKey() const = 0;
|
||||
virtual const ShapeKey getShapeKey() const = 0;
|
||||
|
||||
~PayloadInterface() {}
|
||||
|
||||
|
@ -304,7 +305,7 @@ public:
|
|||
void render(RenderArgs* args) { _payload->render(args); }
|
||||
|
||||
// Shape Type Interface
|
||||
const model::MaterialKey getMaterialKey() const { return _payload->getMaterialKey(); }
|
||||
const ShapeKey getShapeKey() const { return _payload->getShapeKey(); }
|
||||
|
||||
// Access the status
|
||||
const StatusPointer& getStatus() const { return _payload->getStatus(); }
|
||||
|
@ -346,7 +347,7 @@ template <class T> int payloadGetLayer(const std::shared_ptr<T>& payloadData) {
|
|||
template <class T> void payloadRender(const std::shared_ptr<T>& payloadData, RenderArgs* args) { }
|
||||
|
||||
// Shape type interface
|
||||
template <class T> const model::MaterialKey shapeGetMaterialKey(const std::shared_ptr<T>& payloadData) { return model::MaterialKey(); }
|
||||
template <class T> const ShapeKey shapeGetShapeKey(const std::shared_ptr<T>& payloadData) { return ShapeKey::Builder::invalid(); }
|
||||
|
||||
template <class T> class Payload : public Item::PayloadInterface {
|
||||
public:
|
||||
|
@ -364,7 +365,7 @@ public:
|
|||
virtual void render(RenderArgs* args) { payloadRender<T>(_data, args); }
|
||||
|
||||
// Shape Type interface
|
||||
virtual const model::MaterialKey getMaterialKey() const { return shapeGetMaterialKey<T>(_data); }
|
||||
virtual const ShapeKey getShapeKey() const { return shapeGetShapeKey<T>(_data); }
|
||||
|
||||
protected:
|
||||
DataPointer _data;
|
||||
|
|
|
@ -31,6 +31,8 @@ public:
|
|||
SHADOW,
|
||||
WIREFRAME,
|
||||
|
||||
INVALID,
|
||||
|
||||
NUM_FLAGS, // Not a valid flag
|
||||
};
|
||||
using Flags = std::bitset<NUM_FLAGS>;
|
||||
|
@ -59,6 +61,9 @@ public:
|
|||
Builder& withDepthOnly() { _flags.set(DEPTH_ONLY); return (*this); }
|
||||
Builder& withShadow() { _flags.set(SHADOW); return (*this); }
|
||||
Builder& withWireframe() { _flags.set(WIREFRAME); return (*this); }
|
||||
Builder& invalidate() { _flags.set(INVALID); return (*this); }
|
||||
|
||||
static const ShapeKey& invalid() { return Builder().invalidate(); }
|
||||
};
|
||||
ShapeKey(const Builder& builder) : ShapeKey(builder._flags) {}
|
||||
|
||||
|
@ -72,6 +77,7 @@ public:
|
|||
bool isDepthOnly() const { return _flags[DEPTH_ONLY]; }
|
||||
bool isShadow() const { return _flags[SHADOW]; }
|
||||
bool isWireFrame() const { return _flags[WIREFRAME]; }
|
||||
bool isValid() const { return !_flags[INVALID]; }
|
||||
|
||||
// Hasher for use in unordered_maps
|
||||
class Hash {
|
||||
|
@ -104,11 +110,9 @@ inline QDebug operator<<(QDebug debug, const ShapeKey& renderKey) {
|
|||
return debug;
|
||||
}
|
||||
|
||||
// Meta-information (pipeline and locations) to render a shape
|
||||
class Shape {
|
||||
// Rendering abstraction over gpu::Pipeline and map locations
|
||||
class ShapePipeline {
|
||||
public:
|
||||
using Key = ShapeKey;
|
||||
|
||||
class Slots {
|
||||
public:
|
||||
static const int SKINNING_GPU = 2;
|
||||
|
@ -135,16 +139,21 @@ public:
|
|||
int lightBufferUnit;
|
||||
};
|
||||
|
||||
// Rendering abstraction over gpu::Pipeline and map locations
|
||||
class Pipeline {
|
||||
public:
|
||||
gpu::PipelinePointer pipeline;
|
||||
std::shared_ptr<Locations> locations;
|
||||
gpu::PipelinePointer pipeline;
|
||||
std::shared_ptr<Locations> locations;
|
||||
|
||||
Pipeline() : Pipeline(nullptr, nullptr) {}
|
||||
Pipeline(gpu::PipelinePointer pipeline, std::shared_ptr<Locations> locations) :
|
||||
pipeline(pipeline), locations(locations) {}
|
||||
};
|
||||
ShapePipeline() : ShapePipeline(nullptr, nullptr) {}
|
||||
ShapePipeline(gpu::PipelinePointer pipeline, std::shared_ptr<Locations> locations) :
|
||||
pipeline(pipeline), locations(locations) {}
|
||||
};
|
||||
|
||||
// Meta-information (pipeline and locations) to render a shape
|
||||
class Shape {
|
||||
public:
|
||||
using Key = ShapeKey;
|
||||
using Pipeline = ShapePipeline;
|
||||
using Slots = ShapePipeline::Slots;
|
||||
using Locations = ShapePipeline::Locations;
|
||||
|
||||
using PipelineMap = std::unordered_map<ShapeKey, Pipeline, ShapeKey::Hash, ShapeKey::KeyEqual>;
|
||||
class PipelineLib : public PipelineMap {
|
||||
|
@ -166,4 +175,4 @@ protected:
|
|||
|
||||
}
|
||||
|
||||
#endif // hifi_render_Shape_h
|
||||
#endif // hifi_render_Shape_h
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
class AABox;
|
||||
class OctreeRenderer;
|
||||
class ViewFrustum;
|
||||
|
||||
namespace gpu {
|
||||
class Batch;
|
||||
class Context;
|
||||
|
@ -27,6 +28,10 @@ class Texture;
|
|||
class Framebuffer;
|
||||
}
|
||||
|
||||
namespace render {
|
||||
class ShapePipeline;
|
||||
}
|
||||
|
||||
class RenderDetails {
|
||||
public:
|
||||
enum Type {
|
||||
|
@ -103,6 +108,7 @@ public:
|
|||
|
||||
std::shared_ptr<gpu::Context> _context = nullptr;
|
||||
std::shared_ptr<gpu::Framebuffer> _blitFramebuffer = nullptr;
|
||||
std::shared_ptr<render::ShapePipeline> _pipeline = nullptr;
|
||||
OctreeRenderer* _renderer = nullptr;
|
||||
ViewFrustum* _viewFrustum = nullptr;
|
||||
glm::ivec4 _viewport{ 0, 0, 1, 1 };
|
||||
|
|
Loading…
Reference in a new issue