First draft of custom pipeline on geometry cache

This commit is contained in:
Olivier Prat 2017-07-13 17:09:49 +02:00
parent c583de4d96
commit 1b8696fdda
7 changed files with 139 additions and 48 deletions

View file

@ -130,3 +130,42 @@ void makeEntityItemStatusGetters(EntityItemPointer entity, render::Item::Status:
(unsigned char)RenderItemStatusIcon::CLIENT_ONLY);
});
}
bool SimplerRenderableEntitySupport::addToScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) {
_myItem = scene->allocateID();
auto renderData = std::make_shared<RenderableEntityItemProxy>(self, _myItem);
auto renderPayload = std::make_shared<RenderableEntityItemProxy::Payload>(renderData);
render::Item::Status::Getters statusGetters;
makeEntityItemStatusGetters(self, statusGetters);
renderPayload->addStatusGetters(statusGetters);
transaction.resetItem(_myItem, renderPayload);
return true;
}
void SimplerRenderableEntitySupport::removeFromScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) {
transaction.removeItem(_myItem);
render::Item::clearID(_myItem);
}
void SimplerRenderableEntitySupport::notifyChanged() {
if (!render::Item::isValidID(_myItem)) {
return;
}
render::Transaction transaction;
render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene();
if (scene) {
transaction.updateItem<RenderableEntityItemProxy>(_myItem, [](RenderableEntityItemProxy& data) {
});
scene->enqueueTransaction(transaction);
}
else {
qCWarning(entitiesrenderer) << "SimpleRenderableEntityItem::notifyChanged(), Unexpected null scene, possibly during application shutdown";
}
}

View file

@ -70,44 +70,13 @@ namespace render {
// Mixin class for implementing basic single item rendering
class SimplerRenderableEntitySupport : public RenderableEntityInterface {
public:
bool addToScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override {
_myItem = scene->allocateID();
auto renderData = std::make_shared<RenderableEntityItemProxy>(self, _myItem);
auto renderPayload = std::make_shared<RenderableEntityItemProxy::Payload>(renderData);
bool addToScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override;
void removeFromScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override;
void notifyChanged();
render::Item::Status::Getters statusGetters;
makeEntityItemStatusGetters(self, statusGetters);
renderPayload->addStatusGetters(statusGetters);
protected:
transaction.resetItem(_myItem, renderPayload);
return true;
}
void removeFromScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override {
transaction.removeItem(_myItem);
render::Item::clearID(_myItem);
}
void notifyChanged() {
if (!render::Item::isValidID(_myItem)) {
return;
}
render::Transaction transaction;
render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene();
if (scene) {
transaction.updateItem<RenderableEntityItemProxy>(_myItem, [](RenderableEntityItemProxy& data) {
});
scene->enqueueTransaction(transaction);
} else {
qCWarning(entitiesrenderer) << "SimpleRenderableEntityItem::notifyChanged(), Unexpected null scene, possibly during application shutdown";
}
}
private:
render::ItemID _myItem { render::Item::INVALID_ITEM_ID };
};

View file

@ -82,6 +82,27 @@ bool RenderableShapeEntityItem::isTransparent() {
}
}
namespace render {
template <> const ShapeKey shapeGetShapeKey(const ShapePayload::Pointer& payload) {
return ShapeKey::Builder().withCustom(GeometryCache::CUSTOM_PIPELINE_NUMBER).build();
}
}
bool RenderableShapeEntityItem::addToScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) {
_myItem = scene->allocateID();
auto renderData = std::make_shared<ShapePayload>(self, _myItem);
auto renderPayload = std::make_shared<ShapePayload::Payload>(renderData);
render::Item::Status::Getters statusGetters;
makeEntityItemStatusGetters(self, statusGetters);
renderPayload->addStatusGetters(statusGetters);
transaction.resetItem(_myItem, renderPayload);
return true;
}
void RenderableShapeEntityItem::render(RenderArgs* args) {
PerformanceTimer perfTimer("RenderableShapeEntityItem::render");
//Q_ASSERT(getType() == EntityTypes::Shape);

View file

@ -14,6 +14,19 @@
#include "RenderableEntityItem.h"
class ShapePayload : public RenderableEntityItemProxy {
public:
ShapePayload(const EntityItemPointer& entity, render::ItemID metaID)
: RenderableEntityItemProxy(entity, metaID) {}
typedef render::Payload<ShapePayload> Payload;
typedef Payload::DataPointer Pointer;
};
namespace render {
template <> const ShapeKey shapeGetShapeKey(const ShapePayload::Pointer& payload);
}
class RenderableShapeEntityItem : public ShapeEntityItem, private SimplerRenderableEntitySupport {
using Pointer = std::shared_ptr<RenderableShapeEntityItem>;
static Pointer baseFactory(const EntityItemID& entityID, const EntityItemProperties& properties);
@ -23,6 +36,7 @@ public:
static EntityItemPointer sphereFactory(const EntityItemID& entityID, const EntityItemProperties& properties);
RenderableShapeEntityItem(const EntityItemID& entityItemID) : ShapeEntityItem(entityItemID) {}
bool addToScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override;
void render(RenderArgs* args) override;
void setUserData(const QString& value) override;

View file

@ -450,14 +450,50 @@ gpu::Stream::FormatPointer& getInstancedSolidStreamFormat() {
return INSTANCED_SOLID_STREAM_FORMAT;
}
QHash<SimpleProgramKey, gpu::PipelinePointer> GeometryCache::_simplePrograms;
gpu::ShaderPointer GeometryCache::_simpleShader;
gpu::ShaderPointer GeometryCache::_unlitShader;
gpu::ShaderPointer GeometryCache::_simpleFadeShader;
gpu::ShaderPointer GeometryCache::_unlitFadeShader;
render::ShapePipelinePointer GeometryCache::_simpleOpaquePipeline;
render::ShapePipelinePointer GeometryCache::_simpleTransparentPipeline;
render::ShapePipelinePointer GeometryCache::_simpleOpaqueFadePipeline;
render::ShapePipelinePointer GeometryCache::_simpleTransparentFadePipeline;
render::ShapePipelinePointer GeometryCache::_simpleWirePipeline;
uint8_t GeometryCache::CUSTOM_PIPELINE_NUMBER = 0;
render::ShapePipelinePointer GeometryCache::shapePipelineFactory(const render::ShapePlumber& plumber, const render::ShapeKey& key) {
initializeShapePipelines();
if (key.isWireframe()) {
return _simpleWirePipeline;
}
if (key.isFaded()) {
if (key.isTranslucent()) {
return _simpleTransparentFadePipeline;
}
else {
return _simpleOpaqueFadePipeline;
}
}
else {
if (key.isTranslucent()) {
return _simpleTransparentPipeline;
}
else {
return _simpleOpaquePipeline;
}
}
}
GeometryCache::GeometryCache() :
_nextID(0) {
// Let's register its special shapePipeline factory:
registerShapePipeline();
buildShapes();
}
@ -504,11 +540,13 @@ void setupBatchInstance(gpu::Batch& batch, gpu::BufferPointer colorBuffer) {
}
void GeometryCache::initializeShapePipelines() {
GeometryCache::_simpleOpaquePipeline = getShapePipeline(false, false, true, false);
GeometryCache::_simpleTransparentPipeline = getShapePipeline(false, true, true, false);
GeometryCache::_simpleOpaqueFadePipeline = getShapePipeline(false, false, true, false, false, true);
GeometryCache::_simpleTransparentFadePipeline = getShapePipeline(false, true, true, false, false, true);
GeometryCache::_simpleWirePipeline = getShapePipeline(false, false, true, true);
if (!_simpleOpaquePipeline) {
_simpleOpaquePipeline = getShapePipeline(false, false, true, false);
_simpleTransparentPipeline = getShapePipeline(false, true, true, false);
_simpleOpaqueFadePipeline = getShapePipeline(false, false, true, false, false, true);
_simpleTransparentFadePipeline = getShapePipeline(false, true, true, false, false, true);
_simpleWirePipeline = getShapePipeline(false, false, true, true);
}
}
render::ShapePipelinePointer GeometryCache::getShapePipeline(bool textured, bool transparent, bool culled,

View file

@ -147,6 +147,14 @@ public:
NUM_SHAPES,
};
static uint8_t CUSTOM_PIPELINE_NUMBER;
static render::ShapePipelinePointer shapePipelineFactory(const render::ShapePlumber& plumber, const render::ShapeKey& key);
static void registerShapePipeline() {
if (!CUSTOM_PIPELINE_NUMBER) {
CUSTOM_PIPELINE_NUMBER = render::ShapePipeline::registerCustomShapePipelineFactory(shapePipelineFactory);
}
}
int allocateID() { return _nextID++; }
void releaseID(int id);
static const int UNKNOWN_ID;
@ -155,7 +163,7 @@ public:
void bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool transparent = false, bool culled = true,
bool unlit = false, bool depthBias = false);
// Get the pipeline to render static geometry
gpu::PipelinePointer getSimplePipeline(bool textured = false, bool transparent = false, bool culled = true,
static gpu::PipelinePointer getSimplePipeline(bool textured = false, bool transparent = false, bool culled = true,
bool unlit = false, bool depthBias = false, bool fading = false);
void bindOpaqueWebBrowserProgram(gpu::Batch& batch, bool isAA);
@ -164,9 +172,9 @@ public:
void bindTransparentWebBrowserProgram(gpu::Batch& batch, bool isAA);
gpu::PipelinePointer getTransparentWebBrowserProgram(bool isAA);
void initializeShapePipelines();
static void initializeShapePipelines();
render::ShapePipelinePointer getShapePipeline(bool textured = false, bool transparent = false, bool culled = true,
static render::ShapePipelinePointer getShapePipeline(bool textured = false, bool transparent = false, bool culled = true,
bool unlit = false, bool depthBias = false, bool fading = false);
render::ShapePipelinePointer getOpaqueShapePipeline() { assert(_simpleOpaquePipeline != nullptr); return _simpleOpaquePipeline; }
@ -426,10 +434,10 @@ private:
QHash<int, Vec2FloatPairPair> _lastRegisteredGridBuffer;
QHash<int, GridBuffer> _registeredGridBuffers;
gpu::ShaderPointer _simpleShader;
gpu::ShaderPointer _unlitShader;
gpu::ShaderPointer _simpleFadeShader;
gpu::ShaderPointer _unlitFadeShader;
static gpu::ShaderPointer _simpleShader;
static gpu::ShaderPointer _unlitShader;
static gpu::ShaderPointer _simpleFadeShader;
static gpu::ShaderPointer _unlitFadeShader;
static render::ShapePipelinePointer _simpleOpaquePipeline;
static render::ShapePipelinePointer _simpleTransparentPipeline;
static render::ShapePipelinePointer _simpleOpaqueFadePipeline;
@ -438,7 +446,8 @@ private:
static render::ShapePipelinePointer _simpleTransparentOverlayPipeline;
static render::ShapePipelinePointer _simpleWirePipeline;
gpu::PipelinePointer _glowLinePipeline;
QHash<SimpleProgramKey, gpu::PipelinePointer> _simplePrograms;
static QHash<SimpleProgramKey, gpu::PipelinePointer> _simplePrograms;
gpu::ShaderPointer _simpleOpaqueWebBrowserShader;
gpu::PipelinePointer _simpleOpaqueWebBrowserPipeline;

View file

@ -71,6 +71,7 @@ public:
Flags _flags{ 0 };
public:
Builder() {}
Builder(const ItemKey& key) : _flags{ key._flags } {}
ItemKey build() const { return ItemKey(_flags); }