mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-05 23:27:42 +02:00
Replace ShapePipelineLib abstract with ShapePlumber instanced class
This commit is contained in:
parent
5332873273
commit
4ff2b85e1a
10 changed files with 339 additions and 338 deletions
|
@ -1,204 +0,0 @@
|
|||
//
|
||||
// DeferredPipelineLib.cpp
|
||||
// render-utils/src
|
||||
//
|
||||
// Created by Zach Pomerantz on 1/4/2015.
|
||||
// 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 "DeferredPipelineLib.h"
|
||||
|
||||
#include <model-networking/TextureCache.h>
|
||||
|
||||
#include <PerfStat.h>
|
||||
|
||||
#include "DeferredLightingEffect.h"
|
||||
|
||||
#include "model_vert.h"
|
||||
#include "model_shadow_vert.h"
|
||||
#include "model_normal_map_vert.h"
|
||||
#include "model_lightmap_vert.h"
|
||||
#include "model_lightmap_normal_map_vert.h"
|
||||
#include "skin_model_vert.h"
|
||||
#include "skin_model_shadow_vert.h"
|
||||
#include "skin_model_normal_map_vert.h"
|
||||
|
||||
#include "model_frag.h"
|
||||
#include "model_shadow_frag.h"
|
||||
#include "model_normal_map_frag.h"
|
||||
#include "model_normal_specular_map_frag.h"
|
||||
#include "model_specular_map_frag.h"
|
||||
#include "model_lightmap_frag.h"
|
||||
#include "model_lightmap_normal_map_frag.h"
|
||||
#include "model_lightmap_normal_specular_map_frag.h"
|
||||
#include "model_lightmap_specular_map_frag.h"
|
||||
#include "model_translucent_frag.h"
|
||||
|
||||
DeferredPipelineLib::DeferredPipelineLib() {
|
||||
if (!_isInitPipeline) {
|
||||
initPipeline();
|
||||
}
|
||||
}
|
||||
|
||||
const DeferredPipelineLib::PipelinePointer DeferredPipelineLib::pickPipeline(RenderArgs* args, const Key& key) const {
|
||||
PerformanceTimer perfTimer("DeferredPipelineLib::pickPipeline");
|
||||
|
||||
auto pipeline = _pickPipeline(args, key);
|
||||
if (!pipeline) {
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
if ((pipeline->locations->normalFittingMapUnit > -1)) {
|
||||
args->_batch->setResourceTexture(pipeline->locations->normalFittingMapUnit,
|
||||
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
||||
}
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
bool DeferredPipelineLib::_isInitPipeline { false };
|
||||
|
||||
void DeferredPipelineLib::initPipeline() {
|
||||
assert(_pipelineLib.empty());
|
||||
|
||||
// Vertex shaders
|
||||
auto modelVertex = gpu::Shader::createVertex(std::string(model_vert));
|
||||
auto modelNormalMapVertex = gpu::Shader::createVertex(std::string(model_normal_map_vert));
|
||||
auto modelLightmapVertex = gpu::Shader::createVertex(std::string(model_lightmap_vert));
|
||||
auto modelLightmapNormalMapVertex = gpu::Shader::createVertex(std::string(model_lightmap_normal_map_vert));
|
||||
auto modelShadowVertex = gpu::Shader::createVertex(std::string(model_shadow_vert));
|
||||
auto skinModelVertex = gpu::Shader::createVertex(std::string(skin_model_vert));
|
||||
auto skinModelNormalMapVertex = gpu::Shader::createVertex(std::string(skin_model_normal_map_vert));
|
||||
auto skinModelShadowVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_vert));
|
||||
|
||||
// Pixel shaders
|
||||
auto modelPixel = gpu::Shader::createPixel(std::string(model_frag));
|
||||
auto modelNormalMapPixel = gpu::Shader::createPixel(std::string(model_normal_map_frag));
|
||||
auto modelSpecularMapPixel = gpu::Shader::createPixel(std::string(model_specular_map_frag));
|
||||
auto modelNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(model_normal_specular_map_frag));
|
||||
auto modelTranslucentPixel = gpu::Shader::createPixel(std::string(model_translucent_frag));
|
||||
auto modelShadowPixel = gpu::Shader::createPixel(std::string(model_shadow_frag));
|
||||
auto modelLightmapPixel = gpu::Shader::createPixel(std::string(model_lightmap_frag));
|
||||
auto modelLightmapNormalMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_map_frag));
|
||||
auto modelLightmapSpecularMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_specular_map_frag));
|
||||
auto modelLightmapNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_specular_map_frag));
|
||||
|
||||
// Fill the pipelineLib
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder(),
|
||||
modelVertex, modelPixel);
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withTangents(),
|
||||
modelNormalMapVertex, modelNormalMapPixel);
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withSpecular(),
|
||||
modelVertex, modelSpecularMapPixel);
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withTangents().withSpecular(),
|
||||
modelNormalMapVertex, modelNormalSpecularMapPixel);
|
||||
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withTranslucent(),
|
||||
modelVertex, modelTranslucentPixel);
|
||||
// FIXME Ignore lightmap for translucents meshpart
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withTranslucent().withLightmap(),
|
||||
modelVertex, modelTranslucentPixel);
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withTangents().withTranslucent(),
|
||||
modelNormalMapVertex, modelTranslucentPixel);
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withSpecular().withTranslucent(),
|
||||
modelVertex, modelTranslucentPixel);
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withTangents().withSpecular().withTranslucent(),
|
||||
modelNormalMapVertex, modelTranslucentPixel);
|
||||
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withLightmap(),
|
||||
modelLightmapVertex, modelLightmapPixel);
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withLightmap().withTangents(),
|
||||
modelLightmapNormalMapVertex, modelLightmapNormalMapPixel);
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withLightmap().withSpecular(),
|
||||
modelLightmapVertex, modelLightmapSpecularMapPixel);
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withLightmap().withTangents().withSpecular(),
|
||||
modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel);
|
||||
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withSkinned(),
|
||||
skinModelVertex, modelPixel);
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withSkinned().withTangents(),
|
||||
skinModelNormalMapVertex, modelNormalMapPixel);
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withSkinned().withSpecular(),
|
||||
skinModelVertex, modelSpecularMapPixel);
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withSkinned().withTangents().withSpecular(),
|
||||
skinModelNormalMapVertex, modelNormalSpecularMapPixel);
|
||||
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withSkinned().withTranslucent(),
|
||||
skinModelVertex, modelTranslucentPixel);
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withSkinned().withTangents().withTranslucent(),
|
||||
skinModelNormalMapVertex, modelTranslucentPixel);
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withSkinned().withSpecular().withTranslucent(),
|
||||
skinModelVertex, modelTranslucentPixel);
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withSkinned().withTangents().withSpecular().withTranslucent(),
|
||||
skinModelNormalMapVertex, modelTranslucentPixel);
|
||||
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withDepthOnly().withShadow(),
|
||||
modelShadowVertex, modelShadowPixel);
|
||||
|
||||
|
||||
_pipelineLib.addPipeline(
|
||||
Key::Builder().withSkinned().withDepthOnly().withShadow(),
|
||||
skinModelShadowVertex, modelShadowPixel);
|
||||
|
||||
_isInitPipeline = true;
|
||||
}
|
||||
|
||||
model::MaterialPointer DeferredPipelineLib::_collisionHullMaterial;
|
||||
|
||||
model::MaterialPointer DeferredPipelineLib::getCollisionHullMaterial() {
|
||||
if (!_collisionHullMaterial) {
|
||||
_collisionHullMaterial = std::make_shared<model::Material>();
|
||||
_collisionHullMaterial->setDiffuse(glm::vec3(1.0f, 0.5f, 0.0f));
|
||||
_collisionHullMaterial->setMetallic(0.02f);
|
||||
_collisionHullMaterial->setGloss(1.0f);
|
||||
}
|
||||
|
||||
return _collisionHullMaterial;
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
//
|
||||
// DeferredPipelineLib.h
|
||||
// render-utils/src
|
||||
//
|
||||
// Created by Zach Pomerantz on 1/4/2015.
|
||||
// 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
|
||||
//
|
||||
|
||||
#ifndef hifi_render_utils_DeferredPipelineLib_h
|
||||
#define hifi_render_utils_DeferredPipelineLib_h
|
||||
|
||||
#include <render/ShapePipeline.h>
|
||||
#include <model/Material.h>
|
||||
|
||||
class DeferredPipelineLib : public render::ShapePipelineLib {
|
||||
public:
|
||||
DeferredPipelineLib();
|
||||
const PipelinePointer pickPipeline(RenderArgs* args, const Key& key) const override;
|
||||
|
||||
static model::MaterialPointer getCollisionHullMaterial();
|
||||
|
||||
protected:
|
||||
static bool _isInitPipeline;
|
||||
static void initPipeline();
|
||||
|
||||
static model::MaterialPointer _collisionHullMaterial;
|
||||
};
|
||||
|
||||
#endif // hifi_render_utils_DeferredPipelineLib_h
|
|
@ -22,7 +22,6 @@
|
|||
#include <ViewFrustum.h>
|
||||
|
||||
#include "AbstractViewStateInterface.h"
|
||||
#include "DeferredPipelineLib.h"
|
||||
#include "MeshPartPayload.h"
|
||||
#include "Model.h"
|
||||
|
||||
|
@ -36,6 +35,8 @@ static int vec3VectorTypeId = qRegisterMetaType<QVector<glm::vec3> >();
|
|||
float Model::FAKE_DIMENSION_PLACEHOLDER = -1.0f;
|
||||
#define HTTP_INVALID_COM "http://invalid.com"
|
||||
|
||||
model::MaterialPointer Model::_collisionHullMaterial;
|
||||
|
||||
Model::Model(RigPointer rig, QObject* parent) :
|
||||
QObject(parent),
|
||||
_translation(0.0f),
|
||||
|
@ -1194,8 +1195,13 @@ void Model::segregateMeshGroups() {
|
|||
int totalParts = mesh.parts.size();
|
||||
for (int partIndex = 0; partIndex < totalParts; partIndex++) {
|
||||
if (showingCollisionHull) {
|
||||
_renderItemsSet << std::make_shared<MeshPartPayload>(networkMesh._mesh, partIndex, DeferredPipelineLib::getCollisionHullMaterial(), transform, offset);
|
||||
|
||||
if (!_collisionHullMaterial) {
|
||||
_collisionHullMaterial = std::make_shared<model::Material>();
|
||||
_collisionHullMaterial->setDiffuse(glm::vec3(1.0f, 0.5f, 0.0f));
|
||||
_collisionHullMaterial->setMetallic(0.02f);
|
||||
_collisionHullMaterial->setGloss(1.0f);
|
||||
}
|
||||
_renderItemsSet << std::make_shared<MeshPartPayload>(networkMesh._mesh, partIndex, _collisionHullMaterial, transform, offset);
|
||||
} else {
|
||||
_renderItemsSet << std::make_shared<ModelMeshPartPayload>(this, i, partIndex, shapeID, transform, offset);
|
||||
}
|
||||
|
|
|
@ -347,6 +347,7 @@ protected:
|
|||
void recalculateMeshBoxes(bool pickAgainstTriangles = false);
|
||||
|
||||
void segregateMeshGroups(); // used to calculate our list of translucent vs opaque meshes
|
||||
static model::MaterialPointer _collisionHullMaterial;
|
||||
|
||||
bool _meshGroupsKnown;
|
||||
bool _isWireframe;
|
||||
|
|
|
@ -28,6 +28,26 @@
|
|||
#include "AmbientOcclusionEffect.h"
|
||||
#include "AntialiasingEffect.h"
|
||||
|
||||
#include "model_vert.h"
|
||||
#include "model_shadow_vert.h"
|
||||
#include "model_normal_map_vert.h"
|
||||
#include "model_lightmap_vert.h"
|
||||
#include "model_lightmap_normal_map_vert.h"
|
||||
#include "skin_model_vert.h"
|
||||
#include "skin_model_shadow_vert.h"
|
||||
#include "skin_model_normal_map_vert.h"
|
||||
|
||||
#include "model_frag.h"
|
||||
#include "model_shadow_frag.h"
|
||||
#include "model_normal_map_frag.h"
|
||||
#include "model_normal_specular_map_frag.h"
|
||||
#include "model_specular_map_frag.h"
|
||||
#include "model_lightmap_frag.h"
|
||||
#include "model_lightmap_normal_map_frag.h"
|
||||
#include "model_lightmap_normal_specular_map_frag.h"
|
||||
#include "model_lightmap_specular_map_frag.h"
|
||||
#include "model_translucent_frag.h"
|
||||
|
||||
#include "overlay3D_vert.h"
|
||||
#include "overlay3D_frag.h"
|
||||
|
||||
|
@ -35,6 +55,7 @@
|
|||
|
||||
using namespace render;
|
||||
|
||||
void initDeferredPipelines(render::ShapePlumber& plumber);
|
||||
|
||||
void PrepareDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
DependencyManager::get<DeferredLightingEffect>()->prepare(renderContext->getArgs());
|
||||
|
@ -50,6 +71,15 @@ void ToneMappingDeferred::run(const SceneContextPointer& sceneContext, const Ren
|
|||
}
|
||||
|
||||
RenderDeferredTask::RenderDeferredTask() : Task() {
|
||||
// Prepare the ShapePipelines
|
||||
ShapePlumberPointer shapePlumber = std::make_shared<ShapePlumber>([](gpu::Batch& batch, ShapePipelinePointer pipeline) {
|
||||
if ((pipeline->locations->normalFittingMapUnit > -1)) {
|
||||
batch.setResourceTexture(pipeline->locations->normalFittingMapUnit,
|
||||
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
||||
}
|
||||
});
|
||||
initDeferredPipelines(*shapePlumber);
|
||||
|
||||
// CPU only, create the list of renderedOpaques items
|
||||
_jobs.push_back(Job(new FetchItems::JobModel("FetchOpaque",
|
||||
FetchItems([](const RenderContextPointer& context, int count) {
|
||||
|
@ -75,7 +105,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
|
|||
_jobs.push_back(Job(new PrepareDeferred::JobModel("PrepareDeferred")));
|
||||
|
||||
// Render opaque objects in DeferredBuffer
|
||||
_jobs.push_back(Job(new DrawOpaqueDeferred::JobModel("DrawOpaqueDeferred", renderedOpaques)));
|
||||
_jobs.push_back(Job(new DrawOpaqueDeferred::JobModel("DrawOpaqueDeferred", renderedOpaques, DrawOpaqueDeferred(shapePlumber))));
|
||||
|
||||
// Once opaque is all rendered create stencil background
|
||||
_jobs.push_back(Job(new DrawStencilDeferred::JobModel("DrawOpaqueStencil")));
|
||||
|
@ -100,7 +130,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
|
|||
_antialiasingJobIndex = (int)_jobs.size() - 1;
|
||||
|
||||
// Render transparent objects forward in LigthingBuffer
|
||||
_jobs.push_back(Job(new DrawTransparentDeferred::JobModel("TransparentDeferred", renderedTransparents)));
|
||||
_jobs.push_back(Job(new DrawTransparentDeferred::JobModel("TransparentDeferred", renderedTransparents, DrawTransparentDeferred(shapePlumber))));
|
||||
|
||||
// Lighting Buffer ready for tone mapping
|
||||
_jobs.push_back(Job(new ToneMappingDeferred::JobModel("ToneMapping")));
|
||||
|
@ -121,7 +151,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
|
|||
_drawStatusJobIndex = (int)_jobs.size() - 1;
|
||||
}
|
||||
|
||||
_jobs.push_back(Job(new DrawOverlay3D::JobModel("DrawOverlay3D")));
|
||||
_jobs.push_back(Job(new DrawOverlay3D::JobModel("DrawOverlay3D", DrawOverlay3D(shapePlumber))));
|
||||
|
||||
_jobs.push_back(Job(new HitEffect::JobModel("HitEffect")));
|
||||
_jobs.back().setEnabled(false);
|
||||
|
@ -193,7 +223,7 @@ void DrawOpaqueDeferred::run(const SceneContextPointer& sceneContext, const Rend
|
|||
batch.setProjectionTransform(projMat);
|
||||
batch.setViewTransform(viewMat);
|
||||
|
||||
renderShapes(sceneContext, renderContext, _deferredPipelineLib, inItems, opaque.maxDrawn);
|
||||
renderShapes(sceneContext, renderContext, _shapePlumber, inItems, opaque.maxDrawn);
|
||||
args->_batch = nullptr;
|
||||
});
|
||||
}
|
||||
|
@ -219,11 +249,12 @@ void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const
|
|||
batch.setProjectionTransform(projMat);
|
||||
batch.setViewTransform(viewMat);
|
||||
|
||||
renderShapes(sceneContext, renderContext, _deferredPipelineLib, inItems, transparent.maxDrawn);
|
||||
renderShapes(sceneContext, renderContext, _shapePlumber, inItems, transparent.maxDrawn);
|
||||
args->_batch = nullptr;
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: Move this to the shapePlumber
|
||||
gpu::PipelinePointer DrawOverlay3D::_opaquePipeline;
|
||||
const gpu::PipelinePointer& DrawOverlay3D::getOpaquePipeline() {
|
||||
if (!_opaquePipeline) {
|
||||
|
@ -292,7 +323,7 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon
|
|||
|
||||
batch.setPipeline(getOpaquePipeline());
|
||||
batch.setResourceTexture(0, args->_whiteTexture);
|
||||
renderShapes(sceneContext, renderContext, _deferredPipelineLib, inItems, renderContext->getItemsConfig().overlay3D.maxDrawn);
|
||||
renderShapes(sceneContext, renderContext, _shapePlumber, inItems, renderContext->getItemsConfig().overlay3D.maxDrawn);
|
||||
});
|
||||
args->_batch = nullptr;
|
||||
args->_whiteTexture.reset();
|
||||
|
@ -485,3 +516,129 @@ int RenderDeferredTask::getToneMappingToneCurve() const {
|
|||
}
|
||||
}
|
||||
|
||||
void initDeferredPipelines(render::ShapePlumber& plumber) {
|
||||
using Key = render::ShapeKey;
|
||||
|
||||
// Vertex shaders
|
||||
auto modelVertex = gpu::Shader::createVertex(std::string(model_vert));
|
||||
auto modelNormalMapVertex = gpu::Shader::createVertex(std::string(model_normal_map_vert));
|
||||
auto modelLightmapVertex = gpu::Shader::createVertex(std::string(model_lightmap_vert));
|
||||
auto modelLightmapNormalMapVertex = gpu::Shader::createVertex(std::string(model_lightmap_normal_map_vert));
|
||||
auto modelShadowVertex = gpu::Shader::createVertex(std::string(model_shadow_vert));
|
||||
auto skinModelVertex = gpu::Shader::createVertex(std::string(skin_model_vert));
|
||||
auto skinModelNormalMapVertex = gpu::Shader::createVertex(std::string(skin_model_normal_map_vert));
|
||||
auto skinModelShadowVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_vert));
|
||||
|
||||
// Pixel shaders
|
||||
auto modelPixel = gpu::Shader::createPixel(std::string(model_frag));
|
||||
auto modelNormalMapPixel = gpu::Shader::createPixel(std::string(model_normal_map_frag));
|
||||
auto modelSpecularMapPixel = gpu::Shader::createPixel(std::string(model_specular_map_frag));
|
||||
auto modelNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(model_normal_specular_map_frag));
|
||||
auto modelTranslucentPixel = gpu::Shader::createPixel(std::string(model_translucent_frag));
|
||||
auto modelShadowPixel = gpu::Shader::createPixel(std::string(model_shadow_frag));
|
||||
auto modelLightmapPixel = gpu::Shader::createPixel(std::string(model_lightmap_frag));
|
||||
auto modelLightmapNormalMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_map_frag));
|
||||
auto modelLightmapSpecularMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_specular_map_frag));
|
||||
auto modelLightmapNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(model_lightmap_normal_specular_map_frag));
|
||||
|
||||
// Fill the pipelineLib
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder(),
|
||||
modelVertex, modelPixel);
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withTangents(),
|
||||
modelNormalMapVertex, modelNormalMapPixel);
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withSpecular(),
|
||||
modelVertex, modelSpecularMapPixel);
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withTangents().withSpecular(),
|
||||
modelNormalMapVertex, modelNormalSpecularMapPixel);
|
||||
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withTranslucent(),
|
||||
modelVertex, modelTranslucentPixel);
|
||||
// FIXME Ignore lightmap for translucents meshpart
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withTranslucent().withLightmap(),
|
||||
modelVertex, modelTranslucentPixel);
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withTangents().withTranslucent(),
|
||||
modelNormalMapVertex, modelTranslucentPixel);
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withSpecular().withTranslucent(),
|
||||
modelVertex, modelTranslucentPixel);
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withTangents().withSpecular().withTranslucent(),
|
||||
modelNormalMapVertex, modelTranslucentPixel);
|
||||
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withLightmap(),
|
||||
modelLightmapVertex, modelLightmapPixel);
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withLightmap().withTangents(),
|
||||
modelLightmapNormalMapVertex, modelLightmapNormalMapPixel);
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withLightmap().withSpecular(),
|
||||
modelLightmapVertex, modelLightmapSpecularMapPixel);
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withLightmap().withTangents().withSpecular(),
|
||||
modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel);
|
||||
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withSkinned(),
|
||||
skinModelVertex, modelPixel);
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withSkinned().withTangents(),
|
||||
skinModelNormalMapVertex, modelNormalMapPixel);
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withSkinned().withSpecular(),
|
||||
skinModelVertex, modelSpecularMapPixel);
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withSkinned().withTangents().withSpecular(),
|
||||
skinModelNormalMapVertex, modelNormalSpecularMapPixel);
|
||||
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withSkinned().withTranslucent(),
|
||||
skinModelVertex, modelTranslucentPixel);
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withSkinned().withTangents().withTranslucent(),
|
||||
skinModelNormalMapVertex, modelTranslucentPixel);
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withSkinned().withSpecular().withTranslucent(),
|
||||
skinModelVertex, modelTranslucentPixel);
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withSkinned().withTangents().withSpecular().withTranslucent(),
|
||||
skinModelNormalMapVertex, modelTranslucentPixel);
|
||||
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withDepthOnly(),
|
||||
modelShadowVertex, modelShadowPixel);
|
||||
|
||||
|
||||
plumber.addPipeline(
|
||||
Key::Builder().withSkinned().withDepthOnly(),
|
||||
skinModelShadowVertex, modelShadowPixel);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
#define hifi_RenderDeferredTask_h
|
||||
|
||||
#include "render/DrawTask.h"
|
||||
#include "render/ShapePipeline.h"
|
||||
|
||||
#include "gpu/Pipeline.h"
|
||||
|
||||
#include "DeferredPipelineLib.h"
|
||||
#include "ToneMappingEffect.h"
|
||||
|
||||
class SetupDeferred {
|
||||
|
@ -52,22 +52,24 @@ public:
|
|||
|
||||
class DrawOpaqueDeferred {
|
||||
public:
|
||||
DrawOpaqueDeferred(render::ShapePlumberPointer shapePlumber) : _shapePlumber{ shapePlumber } {}
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const render::ItemIDsBounds& inItems);
|
||||
|
||||
typedef render::Job::ModelI<DrawOpaqueDeferred, render::ItemIDsBounds> JobModel;
|
||||
|
||||
protected:
|
||||
DeferredPipelineLib _deferredPipelineLib;
|
||||
render::ShapePlumberPointer _shapePlumber;
|
||||
};
|
||||
|
||||
class DrawTransparentDeferred {
|
||||
public:
|
||||
DrawTransparentDeferred(render::ShapePlumberPointer shapePlumber) : _shapePlumber{ shapePlumber } {}
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const render::ItemIDsBounds& inItems);
|
||||
|
||||
typedef render::Job::ModelI<DrawTransparentDeferred, render::ItemIDsBounds> JobModel;
|
||||
|
||||
protected:
|
||||
DeferredPipelineLib _deferredPipelineLib;
|
||||
render::ShapePlumberPointer _shapePlumber;
|
||||
};
|
||||
|
||||
class DrawStencilDeferred {
|
||||
|
@ -91,6 +93,7 @@ public:
|
|||
|
||||
class DrawOverlay3D {
|
||||
public:
|
||||
DrawOverlay3D(render::ShapePlumberPointer shapePlumber) : _shapePlumber{ shapePlumber } {}
|
||||
static const gpu::PipelinePointer& getOpaquePipeline();
|
||||
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
|
@ -99,7 +102,7 @@ public:
|
|||
|
||||
protected:
|
||||
static gpu::PipelinePointer _opaquePipeline; //lazy evaluation hence mutable
|
||||
DeferredPipelineLib _deferredPipelineLib;
|
||||
render::ShapePlumberPointer _shapePlumber;
|
||||
};
|
||||
|
||||
class Blit {
|
||||
|
|
|
@ -195,11 +195,11 @@ void render::renderLights(const SceneContextPointer& sceneContext, const RenderC
|
|||
}
|
||||
}
|
||||
|
||||
void renderShape(RenderArgs* args, const ShapePipelineLib& shapeContext, const Item& item) {
|
||||
void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, const Item& item) {
|
||||
assert(item.getKey().isShape());
|
||||
const auto& key = item.getShapeKey();
|
||||
if (key.isValid() && !key.hasOwnPipeline()) {
|
||||
args->_pipeline = shapeContext.pickPipeline(args, key);
|
||||
args->_pipeline = shapeContext->pickPipeline(args, key);
|
||||
if (args->_pipeline) {
|
||||
item.render(args);
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ void renderShape(RenderArgs* args, const ShapePipelineLib& shapeContext, const I
|
|||
}
|
||||
|
||||
void render::renderShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext,
|
||||
const ShapePipelineLib& shapeContext, const ItemIDsBounds& inItems, int maxDrawnItems) {
|
||||
const ShapePlumberPointer& shapeContext, const ItemIDsBounds& inItems, int maxDrawnItems) {
|
||||
auto& scene = sceneContext->_scene;
|
||||
RenderArgs* args = renderContext->getArgs();
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ public:
|
|||
Model() {}
|
||||
Model(const std::string& name): Concept(name) {}
|
||||
Model(Data data): _data(data) {}
|
||||
Model(Data data, const std::string& name): Concept(name), _data(data) {}
|
||||
Model(const std::string& name, Data data): Concept(name), _data(data) {}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||
if (isEnabled()) {
|
||||
|
@ -222,7 +222,7 @@ typedef std::vector<Job> Jobs;
|
|||
void cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outITems);
|
||||
void depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemIDsBounds& inItems, ItemIDsBounds& outITems);
|
||||
void renderLights(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems);
|
||||
void renderShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ShapePipelineLib& shapeContext, const ItemIDsBounds& inItems, int maxDrawnItems = -1);
|
||||
void renderShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ShapePlumberPointer& shapeContext, const ItemIDsBounds& inItems, int maxDrawnItems = -1);
|
||||
|
||||
|
||||
class FetchItems {
|
||||
|
|
|
@ -9,41 +9,67 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "DependencyManager.h"
|
||||
|
||||
#include "ShapePipeline.h"
|
||||
|
||||
#include <PerfStat.h>
|
||||
|
||||
using namespace render;
|
||||
|
||||
ShapePipelineLib::PipelineLib ShapePipelineLib::_pipelineLib;
|
||||
|
||||
void ShapePipelineLib::addPipeline(Key key, gpu::ShaderPointer& vertexShader, gpu::ShaderPointer& pixelShader) {
|
||||
_pipelineLib.addPipeline(key, vertexShader, pixelShader);
|
||||
ShapeKey::Filter::Builder::Builder() {
|
||||
_mask.set(OWN_PIPELINE);
|
||||
_mask.set(INVALID);
|
||||
}
|
||||
|
||||
const ShapePipelineLib::PipelinePointer ShapePipelineLib::_pickPipeline(RenderArgs* args, const Key& key) {
|
||||
assert(!_pipelineLib.empty());
|
||||
assert(args);
|
||||
assert(args->_batch);
|
||||
void defaultStateSetter(ShapeKey key, gpu::State& state) {
|
||||
// Cull backface
|
||||
state.setCullMode(gpu::State::CULL_BACK);
|
||||
|
||||
PerformanceTimer perfTimer("ShapePipelineLib::getPipeline");
|
||||
// Z test depends on transparency
|
||||
state.setDepthTest(true, !key.isTranslucent(), gpu::LESS_EQUAL);
|
||||
|
||||
const auto& pipelineIterator = _pipelineLib.find(key);
|
||||
if (pipelineIterator == _pipelineLib.end()) {
|
||||
qDebug() << "Couldn't find a pipeline from ShapeKey ?" << key;
|
||||
return PipelinePointer(nullptr);
|
||||
// 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);
|
||||
}
|
||||
|
||||
PipelinePointer shapePipeline(pipelineIterator->second);
|
||||
auto& batch = args->_batch;
|
||||
|
||||
// Setup the one pipeline (to rule them all)
|
||||
batch->setPipeline(shapePipeline->pipeline);
|
||||
|
||||
return shapePipeline;
|
||||
}
|
||||
|
||||
void ShapePipelineLib::PipelineLib::addPipeline(Key key, gpu::ShaderPointer& vertexShader, gpu::ShaderPointer& pixelShader) {
|
||||
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) {
|
||||
addPipelineHelper(filter, key, ++bit, program, locations);
|
||||
if (filter._mask[bit]) {
|
||||
key._flags.flip(bit);
|
||||
addPipelineHelper(filter, key, ++bit, program, locations);
|
||||
}
|
||||
} else {
|
||||
auto state = std::make_shared<gpu::State>();
|
||||
_stateSetter(key, *state);
|
||||
|
||||
// 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, std::make_shared<Pipeline>(pipeline, locations)));
|
||||
}
|
||||
}
|
||||
|
||||
void ShapePlumber::addPipeline(const Key& key, gpu::ShaderPointer& vertexShader, gpu::ShaderPointer& pixelShader) {
|
||||
addPipeline(Filter{key}, vertexShader, pixelShader);
|
||||
}
|
||||
|
||||
void ShapePlumber::addPipeline(const Filter& filter, gpu::ShaderPointer& vertexShader, gpu::ShaderPointer& pixelShader) {
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("skinClusterBuffer"), Slot::SKINNING_GPU));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), Slot::MATERIAL_GPU));
|
||||
|
@ -69,37 +95,29 @@ void ShapePipelineLib::PipelineLib::addPipeline(Key key, gpu::ShaderPointer& ver
|
|||
locations->materialBufferUnit = program->getBuffers().findLocation("materialBuffer");
|
||||
locations->lightBufferUnit = program->getBuffers().findLocation("lightBuffer");
|
||||
|
||||
auto state = std::make_shared<gpu::State>();
|
||||
|
||||
// Backface on shadow
|
||||
if (key.isShadow()) {
|
||||
state->setCullMode(gpu::State::CULL_FRONT);
|
||||
state->setDepthBias(1.0f);
|
||||
state->setDepthBiasSlopeScale(4.0f);
|
||||
} else {
|
||||
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(),
|
||||
gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, // For transparent only, this keep the highlight intensity
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
|
||||
// Add the brand new pipeline and cache its location in the lib
|
||||
auto pipeline = gpu::Pipeline::create(program, state);
|
||||
insert(value_type(key, std::make_shared<Pipeline>(pipeline, locations)));
|
||||
|
||||
// Add a wireframe version
|
||||
if (!key.isWireFrame()) {
|
||||
ShapeKey wireframeKey(ShapeKey::Builder(key).withWireframe());
|
||||
|
||||
auto wireframeState = std::make_shared<gpu::State>(state->getValues());
|
||||
wireframeState->setFillMode(gpu::State::FILL_LINE);
|
||||
|
||||
auto wireframePipeline = gpu::Pipeline::create(program, wireframeState);
|
||||
insert(value_type(wireframeKey, std::make_shared<Pipeline>(wireframePipeline, locations)));
|
||||
}
|
||||
ShapeKey key{filter._flags};
|
||||
addPipelineHelper(filter, key, 0, program, locations);
|
||||
}
|
||||
|
||||
const ShapePipelinePointer ShapePlumber::pickPipeline(RenderArgs* args, const Key& key) const {
|
||||
assert(!_pipelineMap.empty());
|
||||
assert(args);
|
||||
assert(args->_batch);
|
||||
|
||||
PerformanceTimer perfTimer("ShapePlumber::pickPipeline");
|
||||
|
||||
const auto& pipelineIterator = _pipelineMap.find(key);
|
||||
if (pipelineIterator == _pipelineMap.end()) {
|
||||
qDebug() << "Couldn't find a pipeline from ShapeKey ?" << key;
|
||||
return PipelinePointer(nullptr);
|
||||
}
|
||||
|
||||
PipelinePointer shapePipeline(pipelineIterator->second);
|
||||
auto& batch = args->_batch;
|
||||
_batchSetter(*batch, shapePipeline);
|
||||
|
||||
// Setup the one pipeline (to rule them all)
|
||||
batch->setPipeline(shapePipeline->pipeline);
|
||||
|
||||
return shapePipeline;
|
||||
}
|
||||
|
|
|
@ -28,29 +28,26 @@ public:
|
|||
SKINNED,
|
||||
STEREO,
|
||||
DEPTH_ONLY,
|
||||
SHADOW,
|
||||
WIREFRAME,
|
||||
|
||||
OWN_PIPELINE,
|
||||
INVALID,
|
||||
|
||||
NUM_FLAGS, // Not a valid flag
|
||||
NUM_FLAGS, // Not a valid flag
|
||||
};
|
||||
using Flags = std::bitset<NUM_FLAGS>;
|
||||
|
||||
Flags _flags;
|
||||
|
||||
ShapeKey() : _flags{ 0 } {}
|
||||
ShapeKey(const Flags& flags) : _flags(flags) {}
|
||||
ShapeKey() : _flags{0} {}
|
||||
ShapeKey(const Flags& flags) : _flags{flags} {}
|
||||
|
||||
class Builder {
|
||||
friend class ShapeKey;
|
||||
Flags _flags{ 0 };
|
||||
public:
|
||||
Builder() {}
|
||||
Builder(ShapeKey key) : _flags{ key._flags } {}
|
||||
Builder(ShapeKey key) : _flags{key._flags} {}
|
||||
|
||||
ShapeKey build() const { return ShapeKey(_flags); }
|
||||
ShapeKey build() const { return ShapeKey{_flags}; }
|
||||
|
||||
Builder& withTranslucent() { _flags.set(TRANSLUCENT); return (*this); }
|
||||
Builder& withLightmap() { _flags.set(LIGHTMAP); return (*this); }
|
||||
|
@ -60,15 +57,70 @@ public:
|
|||
Builder& withSkinned() { _flags.set(SKINNED); return (*this); }
|
||||
Builder& withStereo() { _flags.set(STEREO); return (*this); }
|
||||
Builder& withDepthOnly() { _flags.set(DEPTH_ONLY); return (*this); }
|
||||
Builder& withShadow() { _flags.set(SHADOW); return (*this); }
|
||||
Builder& withWireframe() { _flags.set(WIREFRAME); return (*this); }
|
||||
|
||||
Builder& withOwnPipeline() { _flags.set(OWN_PIPELINE); return (*this); }
|
||||
Builder& invalidate() { _flags.set(INVALID); return (*this); }
|
||||
|
||||
static const ShapeKey ownPipeline() { return Builder().withOwnPipeline(); }
|
||||
static const ShapeKey invalid() { return Builder().invalidate(); }
|
||||
|
||||
protected:
|
||||
friend class ShapeKey;
|
||||
Flags _flags{0};
|
||||
};
|
||||
ShapeKey(const Builder& builder) : ShapeKey{builder._flags} {}
|
||||
|
||||
class Filter {
|
||||
public:
|
||||
Filter(Flags flags, Flags mask) : _flags{flags}, _mask{mask} {}
|
||||
Filter(const ShapeKey& key) : _flags{ key._flags } { _mask.set(); }
|
||||
|
||||
// Build a standard filter (will always exclude OWN_PIPELINE, INVALID)
|
||||
class Builder {
|
||||
public:
|
||||
Builder();
|
||||
|
||||
Filter build() const { return Filter(_flags, _mask); }
|
||||
|
||||
Builder& withOpaque() { _flags.reset(TRANSLUCENT); _mask.set(TRANSLUCENT); return (*this); }
|
||||
Builder& withTranslucent() { _flags.set(TRANSLUCENT); _mask.set(TRANSLUCENT); return (*this); }
|
||||
|
||||
Builder& withLightmap() { _flags.reset(LIGHTMAP); _mask.set(LIGHTMAP); return (*this); }
|
||||
Builder& withoutLightmap() { _flags.set(LIGHTMAP); _mask.set(LIGHTMAP); return (*this); }
|
||||
|
||||
Builder& withTangents() { _flags.reset(TANGENTS); _mask.set(TANGENTS); return (*this); }
|
||||
Builder& withoutTangents() { _flags.set(TANGENTS); _mask.set(TANGENTS); return (*this); }
|
||||
|
||||
Builder& withSpecular() { _flags.reset(SPECULAR); _mask.set(SPECULAR); return (*this); }
|
||||
Builder& withoutSpecular() { _flags.set(SPECULAR); _mask.set(SPECULAR); return (*this); }
|
||||
|
||||
Builder& withEmissive() { _flags.reset(EMISSIVE); _mask.set(EMISSIVE); return (*this); }
|
||||
Builder& withoutEmissive() { _flags.set(EMISSIVE); _mask.set(EMISSIVE); return (*this); }
|
||||
|
||||
Builder& withSkinned() { _flags.reset(SKINNED); _mask.set(SKINNED); return (*this); }
|
||||
Builder& withoutSkinned() { _flags.set(SKINNED); _mask.set(SKINNED); return (*this); }
|
||||
|
||||
Builder& withStereo() { _flags.reset(STEREO); _mask.set(STEREO); return (*this); }
|
||||
Builder& withoutStereo() { _flags.set(STEREO); _mask.set(STEREO); return (*this); }
|
||||
|
||||
Builder& withDepthOnly() { _flags.reset(DEPTH_ONLY); _mask.set(DEPTH_ONLY); return (*this); }
|
||||
Builder& withoutDepthOnly() { _flags.set(DEPTH_ONLY); _mask.set(DEPTH_ONLY); return (*this); }
|
||||
|
||||
Builder& withWireframe() { _flags.reset(WIREFRAME); _mask.set(WIREFRAME); return (*this); }
|
||||
Builder& withoutWireframe() { _flags.set(WIREFRAME); _mask.set(WIREFRAME); return (*this); }
|
||||
|
||||
protected:
|
||||
friend class Filter;
|
||||
Flags _flags{0};
|
||||
Flags _mask{0};
|
||||
};
|
||||
Filter(const Filter::Builder& builder) : Filter(builder._flags, builder._mask) {}
|
||||
protected:
|
||||
friend class ShapePlumber;
|
||||
Flags _flags{0};
|
||||
Flags _mask{0};
|
||||
};
|
||||
ShapeKey(const Builder& builder) : ShapeKey(builder._flags) {}
|
||||
|
||||
bool hasLightmap() const { return _flags[LIGHTMAP]; }
|
||||
bool hasTangents() const { return _flags[TANGENTS]; }
|
||||
|
@ -78,7 +130,6 @@ public:
|
|||
bool isSkinned() const { return _flags[SKINNED]; }
|
||||
bool isStereo() const { return _flags[STEREO]; }
|
||||
bool isDepthOnly() const { return _flags[DEPTH_ONLY]; }
|
||||
bool isShadow() const { return _flags[SHADOW]; }
|
||||
bool isWireFrame() const { return _flags[WIREFRAME]; }
|
||||
|
||||
bool hasOwnPipeline() const { return _flags[OWN_PIPELINE]; }
|
||||
|
@ -113,7 +164,6 @@ inline QDebug operator<<(QDebug debug, const ShapeKey& renderKey) {
|
|||
<< "isSkinned:" << renderKey.isSkinned()
|
||||
<< "isStereo:" << renderKey.isStereo()
|
||||
<< "isDepthOnly:" << renderKey.isDepthOnly()
|
||||
<< "isShadow:" << renderKey.isShadow()
|
||||
<< "isWireFrame:" << renderKey.isWireFrame()
|
||||
<< "]";
|
||||
}
|
||||
|
@ -124,6 +174,7 @@ inline QDebug operator<<(QDebug debug, const ShapeKey& renderKey) {
|
|||
}
|
||||
|
||||
// Rendering abstraction over gpu::Pipeline and map locations
|
||||
// Meta-information (pipeline and locations) to render a shape
|
||||
class ShapePipeline {
|
||||
public:
|
||||
class Slot {
|
||||
|
@ -162,32 +213,33 @@ public:
|
|||
};
|
||||
using ShapePipelinePointer = std::shared_ptr<ShapePipeline>;
|
||||
|
||||
// Meta-information (pipeline and locations) to render a shape
|
||||
class ShapePipelineLib {
|
||||
class ShapePlumber {
|
||||
public:
|
||||
using Key = ShapeKey;
|
||||
using Filter = Key::Filter;
|
||||
using Pipeline = ShapePipeline;
|
||||
using PipelinePointer = ShapePipelinePointer;
|
||||
using Slot = ShapePipeline::Slot;
|
||||
using Locations = ShapePipeline::Locations;
|
||||
using PipelineMap = std::unordered_map<ShapeKey, PipelinePointer, ShapeKey::Hash, ShapeKey::KeyEqual>;
|
||||
using Slot = Pipeline::Slot;
|
||||
using Locations = Pipeline::Locations;
|
||||
using LocationsPointer = Pipeline::LocationsPointer;
|
||||
using StateSetter = std::function<void(Key, gpu::State&)>;
|
||||
using BatchSetter = std::function<void(gpu::Batch&, PipelinePointer)>;
|
||||
|
||||
virtual ~ShapePipelineLib() = default;
|
||||
ShapePlumber();
|
||||
explicit ShapePlumber(BatchSetter batchSetter);
|
||||
|
||||
static void addPipeline(Key key, gpu::ShaderPointer& vertexShader, gpu::ShaderPointer& pixelShader);
|
||||
virtual const PipelinePointer pickPipeline(RenderArgs* args, const Key& key) const {
|
||||
return ShapePipelineLib::_pickPipeline(args, key);
|
||||
}
|
||||
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;
|
||||
|
||||
protected:
|
||||
using PipelineMap = std::unordered_map<ShapeKey, PipelinePointer, ShapeKey::Hash, ShapeKey::KeyEqual>;
|
||||
class PipelineLib : public PipelineMap {
|
||||
public:
|
||||
void addPipeline(Key key, gpu::ShaderPointer& vertexShader, gpu::ShaderPointer& pixelShader);
|
||||
};
|
||||
|
||||
static PipelineLib _pipelineLib;
|
||||
static const PipelinePointer _pickPipeline(RenderArgs* args, const Key& key);
|
||||
void addPipelineHelper(const Filter& filter, Key key, int bit, gpu::ShaderPointer pipeline, LocationsPointer locations);
|
||||
PipelineMap _pipelineMap;
|
||||
StateSetter _stateSetter;
|
||||
BatchSetter _batchSetter;
|
||||
};
|
||||
using ShapePlumberPointer = std::shared_ptr<ShapePlumber>;
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue