mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 03:13:09 +02:00
Refine addPipeline signature to be more explicit
This commit is contained in:
parent
801dde7950
commit
db91b12203
3 changed files with 94 additions and 82 deletions
|
@ -74,12 +74,7 @@ void ToneMappingDeferred::run(const SceneContextPointer& sceneContext, const Ren
|
||||||
|
|
||||||
RenderDeferredTask::RenderDeferredTask() : Task() {
|
RenderDeferredTask::RenderDeferredTask() : Task() {
|
||||||
// Prepare the ShapePipelines
|
// Prepare the ShapePipelines
|
||||||
ShapePlumberPointer shapePlumber = std::make_shared<ShapePlumber>([](gpu::Batch& batch, ShapePipelinePointer pipeline) {
|
ShapePlumberPointer shapePlumber;
|
||||||
if ((pipeline->locations->normalFittingMapUnit > -1)) {
|
|
||||||
batch.setResourceTexture(pipeline->locations->normalFittingMapUnit,
|
|
||||||
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
initDeferredPipelines(*shapePlumber);
|
initDeferredPipelines(*shapePlumber);
|
||||||
|
|
||||||
// CPU only, create the list of renderedOpaques items
|
// CPU only, create the list of renderedOpaques items
|
||||||
|
@ -513,8 +508,45 @@ int RenderDeferredTask::getToneMappingToneCurve() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pipelineBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {
|
||||||
|
if (pipeline.locations->normalFittingMapUnit > -1) {
|
||||||
|
batch.setResourceTexture(pipeline.locations->normalFittingMapUnit,
|
||||||
|
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void initDeferredPipelines(render::ShapePlumber& plumber) {
|
void initDeferredPipelines(render::ShapePlumber& plumber) {
|
||||||
using Key = render::ShapeKey;
|
using Key = render::ShapeKey;
|
||||||
|
using ShaderPointer = gpu::ShaderPointer;
|
||||||
|
|
||||||
|
auto addPipeline = [&plumber](const Key& key, const ShaderPointer& vertexShader, const ShaderPointer& pixelShader) {
|
||||||
|
auto state = std::make_shared<gpu::State>();
|
||||||
|
|
||||||
|
// Cull backface
|
||||||
|
state->setCullMode(gpu::State::CULL_BACK);
|
||||||
|
|
||||||
|
// Z test depends on transparency
|
||||||
|
state->setDepthTest(true, !key.isTranslucent(), gpu::LESS_EQUAL);
|
||||||
|
|
||||||
|
// Blend if transparent
|
||||||
|
state->setBlendFunction(key.isTranslucent(),
|
||||||
|
// For transparency, keep the highlight intensity
|
||||||
|
gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||||
|
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||||
|
|
||||||
|
ShaderPointer program = gpu::Shader::createProgram(vertexShader, pixelShader);
|
||||||
|
plumber.addPipeline(key, program, state, &pipelineBatchSetter);
|
||||||
|
|
||||||
|
// Add a wireframe version
|
||||||
|
if (!key.isWireFrame()) {
|
||||||
|
auto wireFrameKey = Key::Builder(key).withWireframe();
|
||||||
|
auto wireFrameState = std::make_shared<gpu::State>(state->getValues());
|
||||||
|
|
||||||
|
wireFrameState->setFillMode(gpu::State::FILL_LINE);
|
||||||
|
|
||||||
|
plumber.addPipeline(wireFrameKey, program, wireFrameState, &pipelineBatchSetter);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Vertex shaders
|
// Vertex shaders
|
||||||
auto modelVertex = gpu::Shader::createVertex(std::string(model_vert));
|
auto modelVertex = gpu::Shader::createVertex(std::string(model_vert));
|
||||||
|
@ -539,102 +571,101 @@ void initDeferredPipelines(render::ShapePlumber& plumber) {
|
||||||
auto modelLightmapNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_specular_map_frag));
|
auto modelLightmapNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_specular_map_frag));
|
||||||
|
|
||||||
// Fill the pipelineLib
|
// Fill the pipelineLib
|
||||||
|
addPipeline(
|
||||||
plumber.addPipeline(
|
|
||||||
Key::Builder(),
|
Key::Builder(),
|
||||||
modelVertex, modelPixel);
|
modelVertex, modelPixel);
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withTangents(),
|
Key::Builder().withTangents(),
|
||||||
modelNormalMapVertex, modelNormalMapPixel);
|
modelNormalMapVertex, modelNormalMapPixel);
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withSpecular(),
|
Key::Builder().withSpecular(),
|
||||||
modelVertex, modelSpecularMapPixel);
|
modelVertex, modelSpecularMapPixel);
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withTangents().withSpecular(),
|
Key::Builder().withTangents().withSpecular(),
|
||||||
modelNormalMapVertex, modelNormalSpecularMapPixel);
|
modelNormalMapVertex, modelNormalSpecularMapPixel);
|
||||||
|
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withTranslucent(),
|
Key::Builder().withTranslucent(),
|
||||||
modelVertex, modelTranslucentPixel);
|
modelVertex, modelTranslucentPixel);
|
||||||
// FIXME Ignore lightmap for translucents meshpart
|
// FIXME Ignore lightmap for translucents meshpart
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withTranslucent().withLightmap(),
|
Key::Builder().withTranslucent().withLightmap(),
|
||||||
modelVertex, modelTranslucentPixel);
|
modelVertex, modelTranslucentPixel);
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withTangents().withTranslucent(),
|
Key::Builder().withTangents().withTranslucent(),
|
||||||
modelNormalMapVertex, modelTranslucentPixel);
|
modelNormalMapVertex, modelTranslucentPixel);
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withSpecular().withTranslucent(),
|
Key::Builder().withSpecular().withTranslucent(),
|
||||||
modelVertex, modelTranslucentPixel);
|
modelVertex, modelTranslucentPixel);
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withTangents().withSpecular().withTranslucent(),
|
Key::Builder().withTangents().withSpecular().withTranslucent(),
|
||||||
modelNormalMapVertex, modelTranslucentPixel);
|
modelNormalMapVertex, modelTranslucentPixel);
|
||||||
|
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withLightmap(),
|
Key::Builder().withLightmap(),
|
||||||
modelLightmapVertex, modelLightmapPixel);
|
modelLightmapVertex, modelLightmapPixel);
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withLightmap().withTangents(),
|
Key::Builder().withLightmap().withTangents(),
|
||||||
modelLightmapNormalMapVertex, modelLightmapNormalMapPixel);
|
modelLightmapNormalMapVertex, modelLightmapNormalMapPixel);
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withLightmap().withSpecular(),
|
Key::Builder().withLightmap().withSpecular(),
|
||||||
modelLightmapVertex, modelLightmapSpecularMapPixel);
|
modelLightmapVertex, modelLightmapSpecularMapPixel);
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withLightmap().withTangents().withSpecular(),
|
Key::Builder().withLightmap().withTangents().withSpecular(),
|
||||||
modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel);
|
modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel);
|
||||||
|
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withSkinned(),
|
Key::Builder().withSkinned(),
|
||||||
skinModelVertex, modelPixel);
|
skinModelVertex, modelPixel);
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withSkinned().withTangents(),
|
Key::Builder().withSkinned().withTangents(),
|
||||||
skinModelNormalMapVertex, modelNormalMapPixel);
|
skinModelNormalMapVertex, modelNormalMapPixel);
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withSkinned().withSpecular(),
|
Key::Builder().withSkinned().withSpecular(),
|
||||||
skinModelVertex, modelSpecularMapPixel);
|
skinModelVertex, modelSpecularMapPixel);
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withSkinned().withTangents().withSpecular(),
|
Key::Builder().withSkinned().withTangents().withSpecular(),
|
||||||
skinModelNormalMapVertex, modelNormalSpecularMapPixel);
|
skinModelNormalMapVertex, modelNormalSpecularMapPixel);
|
||||||
|
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withSkinned().withTranslucent(),
|
Key::Builder().withSkinned().withTranslucent(),
|
||||||
skinModelVertex, modelTranslucentPixel);
|
skinModelVertex, modelTranslucentPixel);
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withSkinned().withTangents().withTranslucent(),
|
Key::Builder().withSkinned().withTangents().withTranslucent(),
|
||||||
skinModelNormalMapVertex, modelTranslucentPixel);
|
skinModelNormalMapVertex, modelTranslucentPixel);
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withSkinned().withSpecular().withTranslucent(),
|
Key::Builder().withSkinned().withSpecular().withTranslucent(),
|
||||||
skinModelVertex, modelTranslucentPixel);
|
skinModelVertex, modelTranslucentPixel);
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withSkinned().withTangents().withSpecular().withTranslucent(),
|
Key::Builder().withSkinned().withTangents().withSpecular().withTranslucent(),
|
||||||
skinModelNormalMapVertex, modelTranslucentPixel);
|
skinModelNormalMapVertex, modelTranslucentPixel);
|
||||||
|
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withDepthOnly(),
|
Key::Builder().withDepthOnly(),
|
||||||
modelShadowVertex, modelShadowPixel);
|
modelShadowVertex, modelShadowPixel);
|
||||||
|
|
||||||
|
|
||||||
plumber.addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withSkinned().withDepthOnly(),
|
Key::Builder().withSkinned().withDepthOnly(),
|
||||||
skinModelShadowVertex, modelShadowPixel);
|
skinModelShadowVertex, modelShadowPixel);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,54 +22,29 @@ ShapeKey::Filter::Builder::Builder() {
|
||||||
_mask.set(INVALID);
|
_mask.set(INVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void defaultStateSetter(ShapeKey key, gpu::State& state) {
|
void ShapePlumber::addPipelineHelper(const Filter& filter, ShapeKey key, int bit, const PipelinePointer& pipeline) {
|
||||||
// Cull backface
|
// Iterate over all keys
|
||||||
state.setCullMode(gpu::State::CULL_BACK);
|
|
||||||
|
|
||||||
// Z test depends on transparency
|
|
||||||
state.setDepthTest(true, !key.isTranslucent(), gpu::LESS_EQUAL);
|
|
||||||
|
|
||||||
// Blend if transparent
|
|
||||||
state.setBlendFunction(key.isTranslucent(),
|
|
||||||
// For transparency, keep the highlight intensity
|
|
||||||
gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
|
||||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
|
||||||
|
|
||||||
// Add a wireframe version
|
|
||||||
if (!key.isWireFrame()) {
|
|
||||||
state.setFillMode(gpu::State::FILL_LINE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void defaultBatchSetter(gpu::Batch& batch, ShapePipelinePointer pipeline) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ShapePlumber::ShapePlumber() : _stateSetter{ defaultStateSetter }, _batchSetter{ defaultBatchSetter } {}
|
|
||||||
ShapePlumber::ShapePlumber(BatchSetter batchSetter) : _stateSetter{ defaultStateSetter }, _batchSetter{ batchSetter } {}
|
|
||||||
|
|
||||||
void ShapePlumber::addPipelineHelper(const Filter& filter, ShapeKey key, int bit, gpu::ShaderPointer program, LocationsPointer locations) {
|
|
||||||
// Iterate over all keys, toggling only bits set as significant in filter._mask
|
|
||||||
if (bit < (int)ShapeKey::FlagBit::NUM_FLAGS) {
|
if (bit < (int)ShapeKey::FlagBit::NUM_FLAGS) {
|
||||||
addPipelineHelper(filter, key, ++bit, program, locations);
|
++bit;
|
||||||
|
addPipelineHelper(filter, key, bit, pipeline);
|
||||||
if (filter._mask[bit]) {
|
if (filter._mask[bit]) {
|
||||||
|
// Toggle bits set as significant in filter._mask
|
||||||
key._flags.flip(bit);
|
key._flags.flip(bit);
|
||||||
addPipelineHelper(filter, key, ++bit, program, locations);
|
addPipelineHelper(filter, key, bit, pipeline);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto state = std::make_shared<gpu::State>();
|
|
||||||
_stateSetter(key, *state);
|
|
||||||
|
|
||||||
// Add the brand new pipeline and cache its location in the lib
|
// Add the brand new pipeline and cache its location in the lib
|
||||||
auto pipeline = gpu::Pipeline::create(program, state);
|
_pipelineMap.insert(PipelineMap::value_type(key, pipeline));
|
||||||
_pipelineMap.insert(PipelineMap::value_type(key, std::make_shared<Pipeline>(pipeline, locations)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShapePlumber::addPipeline(const Key& key, gpu::ShaderPointer& vertexShader, gpu::ShaderPointer& pixelShader) {
|
void ShapePlumber::addPipeline(const Key& key, const gpu::ShaderPointer& program, const gpu::StatePointer& state,
|
||||||
addPipeline(Filter{key}, vertexShader, pixelShader);
|
BatchSetter batchSetter) {
|
||||||
|
addPipeline(Filter{key}, program, state, batchSetter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShapePlumber::addPipeline(const Filter& filter, gpu::ShaderPointer& vertexShader, gpu::ShaderPointer& pixelShader) {
|
void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& program, const gpu::StatePointer& state,
|
||||||
|
BatchSetter batchSetter) {
|
||||||
gpu::Shader::BindingSet slotBindings;
|
gpu::Shader::BindingSet slotBindings;
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("skinClusterBuffer"), Slot::SKINNING_GPU));
|
slotBindings.insert(gpu::Shader::Binding(std::string("skinClusterBuffer"), Slot::SKINNING_GPU));
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), Slot::MATERIAL_GPU));
|
slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), Slot::MATERIAL_GPU));
|
||||||
|
@ -80,7 +55,6 @@ void ShapePlumber::addPipeline(const Filter& filter, gpu::ShaderPointer& vertexS
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), Slot::LIGHT_BUFFER));
|
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), Slot::LIGHT_BUFFER));
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), Slot::NORMAL_FITTING_MAP));
|
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), Slot::NORMAL_FITTING_MAP));
|
||||||
|
|
||||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vertexShader, pixelShader);
|
|
||||||
gpu::Shader::makeProgram(*program, slotBindings);
|
gpu::Shader::makeProgram(*program, slotBindings);
|
||||||
|
|
||||||
auto locations = std::make_shared<Locations>();
|
auto locations = std::make_shared<Locations>();
|
||||||
|
@ -96,7 +70,9 @@ void ShapePlumber::addPipeline(const Filter& filter, gpu::ShaderPointer& vertexS
|
||||||
locations->lightBufferUnit = program->getBuffers().findLocation("lightBuffer");
|
locations->lightBufferUnit = program->getBuffers().findLocation("lightBuffer");
|
||||||
|
|
||||||
ShapeKey key{filter._flags};
|
ShapeKey key{filter._flags};
|
||||||
addPipelineHelper(filter, key, 0, program, locations);
|
auto gpuPipeline = gpu::Pipeline::create(program, state);
|
||||||
|
auto shapePipeline = std::make_shared<Pipeline>(gpuPipeline, locations, batchSetter);
|
||||||
|
addPipelineHelper(filter, key, 0, shapePipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ShapePipelinePointer ShapePlumber::pickPipeline(RenderArgs* args, const Key& key) const {
|
const ShapePipelinePointer ShapePlumber::pickPipeline(RenderArgs* args, const Key& key) const {
|
||||||
|
@ -114,7 +90,9 @@ const ShapePipelinePointer ShapePlumber::pickPipeline(RenderArgs* args, const Ke
|
||||||
|
|
||||||
PipelinePointer shapePipeline(pipelineIterator->second);
|
PipelinePointer shapePipeline(pipelineIterator->second);
|
||||||
auto& batch = args->_batch;
|
auto& batch = args->_batch;
|
||||||
_batchSetter(*batch, shapePipeline);
|
|
||||||
|
// Run the pipeline's BatchSetter on the passed in batch
|
||||||
|
shapePipeline->batchSetter(*shapePipeline, *batch);
|
||||||
|
|
||||||
// Setup the one pipeline (to rule them all)
|
// Setup the one pipeline (to rule them all)
|
||||||
batch->setPipeline(shapePipeline->pipeline);
|
batch->setPipeline(shapePipeline->pipeline);
|
||||||
|
|
|
@ -204,12 +204,18 @@ public:
|
||||||
};
|
};
|
||||||
using LocationsPointer = std::shared_ptr<Locations>;
|
using LocationsPointer = std::shared_ptr<Locations>;
|
||||||
|
|
||||||
|
using BatchSetter = std::function<void(const ShapePipeline&, gpu::Batch&)>;
|
||||||
|
|
||||||
|
ShapePipeline(gpu::PipelinePointer pipeline, LocationsPointer locations, BatchSetter batchSetter) :
|
||||||
|
pipeline(pipeline), locations(locations), batchSetter(batchSetter) {}
|
||||||
|
|
||||||
gpu::PipelinePointer pipeline;
|
gpu::PipelinePointer pipeline;
|
||||||
std::shared_ptr<Locations> locations;
|
std::shared_ptr<Locations> locations;
|
||||||
|
|
||||||
ShapePipeline() : ShapePipeline(nullptr, nullptr) {}
|
protected:
|
||||||
ShapePipeline(gpu::PipelinePointer pipeline, std::shared_ptr<Locations> locations) :
|
friend class ShapePlumber;
|
||||||
pipeline(pipeline), locations(locations) {}
|
|
||||||
|
BatchSetter batchSetter;
|
||||||
};
|
};
|
||||||
using ShapePipelinePointer = std::shared_ptr<ShapePipeline>;
|
using ShapePipelinePointer = std::shared_ptr<ShapePipeline>;
|
||||||
|
|
||||||
|
@ -223,21 +229,18 @@ public:
|
||||||
using Slot = Pipeline::Slot;
|
using Slot = Pipeline::Slot;
|
||||||
using Locations = Pipeline::Locations;
|
using Locations = Pipeline::Locations;
|
||||||
using LocationsPointer = Pipeline::LocationsPointer;
|
using LocationsPointer = Pipeline::LocationsPointer;
|
||||||
using StateSetter = std::function<void(Key, gpu::State&)>;
|
using BatchSetter = Pipeline::BatchSetter;
|
||||||
using BatchSetter = std::function<void(gpu::Batch&, PipelinePointer)>;
|
|
||||||
|
|
||||||
ShapePlumber();
|
void addPipeline(const Key& key, const gpu::ShaderPointer& program, const gpu::StatePointer& state,
|
||||||
explicit ShapePlumber(BatchSetter batchSetter);
|
BatchSetter batchSetter = nullptr);
|
||||||
|
void addPipeline(const Filter& filter, const gpu::ShaderPointer& program, const gpu::StatePointer& state,
|
||||||
|
BatchSetter batchSetter = nullptr);
|
||||||
|
|
||||||
void addPipeline(const Key& key, gpu::ShaderPointer& vertexShader, gpu::ShaderPointer& pixelShader);
|
|
||||||
void addPipeline(const Filter& filter, gpu::ShaderPointer& vertexShader, gpu::ShaderPointer& pixelShader);
|
|
||||||
const PipelinePointer pickPipeline(RenderArgs* args, const Key& key) const;
|
const PipelinePointer pickPipeline(RenderArgs* args, const Key& key) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void addPipelineHelper(const Filter& filter, Key key, int bit, gpu::ShaderPointer pipeline, LocationsPointer locations);
|
void addPipelineHelper(const Filter& filter, Key key, int bit, const PipelinePointer& pipeline);
|
||||||
PipelineMap _pipelineMap;
|
PipelineMap _pipelineMap;
|
||||||
StateSetter _stateSetter;
|
|
||||||
BatchSetter _batchSetter;
|
|
||||||
};
|
};
|
||||||
using ShapePlumberPointer = std::shared_ptr<ShapePlumber>;
|
using ShapePlumberPointer = std::shared_ptr<ShapePlumber>;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue