From 671f27e5bc3950cc75884a5b8b0e6b6221011cb5 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 28 Jan 2016 12:05:59 -0800 Subject: [PATCH 1/4] Move DrawStencil to use ShapePlumber --- .../render-utils/src/RenderDeferredTask.cpp | 33 ++++++++----------- .../render-utils/src/RenderDeferredTask.h | 4 +-- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index d76d0a77de..9ae76bfe02 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -256,25 +256,19 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon } } -gpu::PipelinePointer DrawStencilDeferred::_opaquePipeline; -const gpu::PipelinePointer& DrawStencilDeferred::getOpaquePipeline() { - if (!_opaquePipeline) { - const gpu::int8 STENCIL_OPAQUE = 1; - auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); - auto ps = gpu::Shader::createPixel(std::string(drawOpaqueStencil_frag)); - auto program = gpu::Shader::createProgram(vs, ps); - +DrawStencilDeferred::DrawStencilDeferred() : _shapePlumber{ std::make_shared() } { + const gpu::int8 STENCIL_OPAQUE = 1; + auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); + auto ps = gpu::Shader::createPixel(std::string(drawOpaqueStencil_frag)); + auto program = gpu::Shader::createProgram(vs, ps); + gpu::Shader::makeProgram((*program)); - gpu::Shader::makeProgram((*program)); + auto state = std::make_shared(); + state->setDepthTest(true, false, gpu::LESS_EQUAL); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_REPLACE)); + state->setColorWriteMask(0); - auto state = std::make_shared(); - state->setDepthTest(true, false, gpu::LESS_EQUAL); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_REPLACE)); - state->setColorWriteMask(0); - - _opaquePipeline = gpu::Pipeline::create(program, state); - } - return _opaquePipeline; + _shapePlumber->addPipeline(ShapeKey::Filter::Builder(), program, state); } void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { @@ -294,11 +288,12 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); - batch.setPipeline(getOpaquePipeline()); + // We only need to fetch this once + static const auto& pipeline = _shapePlumber->pickPipeline(args, ShapeKey()); + batch.setPipeline(pipeline->pipeline); batch.draw(gpu::TRIANGLE_STRIP, 4); batch.setResourceTexture(0, nullptr); - }); args->_batch = nullptr; } diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 8d773a9b21..2ebb2e4e12 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -68,14 +68,14 @@ protected: class DrawStencilDeferred { public: - static const gpu::PipelinePointer& getOpaquePipeline(); + DrawStencilDeferred(); void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); using JobModel = render::Job::Model; protected: - static gpu::PipelinePointer _opaquePipeline; //lazy evaluation hence mutable + render::ShapePlumberPointer _shapePlumber; }; class DrawBackgroundDeferred { From df894d364a032fcc31837838e802621c96a7dbb6 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 28 Jan 2016 12:25:31 -0800 Subject: [PATCH 2/4] Move DrawOverlay3D to use ShapePlumber --- .../render-utils/src/RenderDeferredTask.cpp | 39 ++++++++++--------- .../render-utils/src/RenderDeferredTask.h | 5 +-- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 9ae76bfe02..15a37998ca 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -128,7 +128,7 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) { addJob("DrawStatus", opaques, DrawStatus(statusIconMap)); } - addJob("DrawOverlay3D", shapePlumber); + addJob("DrawOverlay3D"); addJob("HitEffect"); @@ -180,22 +180,26 @@ void DrawDeferred::run(const SceneContextPointer& sceneContext, const RenderCont }); } -// TODO: Move this to the shapePlumber -gpu::PipelinePointer DrawOverlay3D::_opaquePipeline; -const gpu::PipelinePointer& DrawOverlay3D::getOpaquePipeline() { - if (!_opaquePipeline) { - auto vs = gpu::Shader::createVertex(std::string(overlay3D_vert)); - auto ps = gpu::Shader::createPixel(std::string(overlay3D_frag)); - auto program = gpu::Shader::createProgram(vs, ps); - - auto state = std::make_shared(); - state->setDepthTest(false); - // additive blending - state->setBlendFunction(true, gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::ONE); +DrawOverlay3D::DrawOverlay3D() : _shapePlumber{ std::make_shared() } { + auto vs = gpu::Shader::createVertex(std::string(overlay3D_vert)); + auto ps = gpu::Shader::createPixel(std::string(overlay3D_frag)); + auto program = gpu::Shader::createProgram(vs, ps); - _opaquePipeline = gpu::Pipeline::create(program, state); - } - return _opaquePipeline; + auto opaqueState = std::make_shared(); + opaqueState->setDepthTest(false); + opaqueState->setBlendFunction(true, + // Additive blending + gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + + auto transparentState = std::make_shared(); + transparentState->setDepthTest(false); + transparentState->setBlendFunction(true, + // 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); + + _shapePlumber->addPipeline(ShapeKey::Filter::Builder().withOpaque(), program, opaqueState); + _shapePlumber->addPipeline(ShapeKey::Filter::Builder().withTranslucent(), program, transparentState); } void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { @@ -246,9 +250,8 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon batch.setViewTransform(viewMat); batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); - - batch.setPipeline(getOpaquePipeline()); batch.setResourceTexture(0, args->_whiteTexture); + renderShapes(sceneContext, renderContext, _shapePlumber, inItems, _maxDrawn); }); args->_batch = nullptr; diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 2ebb2e4e12..894a91cdc3 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -106,15 +106,12 @@ public: using Config = DrawOverlay3DConfig; using JobModel = render::Job::Model; - DrawOverlay3D(render::ShapePlumberPointer shapePlumber) : _shapePlumber{ shapePlumber } {} + DrawOverlay3D(); void configure(const Config& config) { _maxDrawn = config.maxDrawn; } void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); - static const gpu::PipelinePointer& getOpaquePipeline(); - protected: - static gpu::PipelinePointer _opaquePipeline; //lazy evaluation hence mutable render::ShapePlumberPointer _shapePlumber; int _maxDrawn; // initialized by Config }; From 5d49eacf83c3e4e850acffd38c6a8292293f786d Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 28 Jan 2016 15:51:56 -0800 Subject: [PATCH 3/4] Move pipeline init to separate file --- .../render-utils/src/RenderDeferredTask.cpp | 228 +---------------- .../render-utils/src/RenderPipelines.cpp | 234 ++++++++++++++++++ 2 files changed, 240 insertions(+), 222 deletions(-) create mode 100644 libraries/render-utils/src/RenderPipelines.cpp diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 15a37998ca..8a47280526 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -4,7 +4,7 @@ // render-utils/src/ // // Created by Sam Gateau on 5/29/15. -// Copyright 20154 High Fidelity, Inc. +// Copyright 2016 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 @@ -15,7 +15,6 @@ #include #include #include -#include #include "DebugDeferredBuffer.h" #include "DeferredLightingEffect.h" @@ -31,34 +30,11 @@ #include "RenderDeferredTask.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" - -#include "drawOpaqueStencil_frag.h" - using namespace render; -void initDeferredPipelines(render::ShapePlumber& plumber); +extern void initOverlay3DPipelines(render::ShapePlumber& plumber); +extern void initStencilPipelines(render::ShapePlumber& plumber); +extern void initDeferredPipelines(render::ShapePlumber& plumber); void PrepareDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { DependencyManager::get()->prepare(renderContext->args); @@ -181,25 +157,7 @@ void DrawDeferred::run(const SceneContextPointer& sceneContext, const RenderCont } DrawOverlay3D::DrawOverlay3D() : _shapePlumber{ std::make_shared() } { - auto vs = gpu::Shader::createVertex(std::string(overlay3D_vert)); - auto ps = gpu::Shader::createPixel(std::string(overlay3D_frag)); - auto program = gpu::Shader::createProgram(vs, ps); - - auto opaqueState = std::make_shared(); - opaqueState->setDepthTest(false); - opaqueState->setBlendFunction(true, - // Additive blending - gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::ONE); - - auto transparentState = std::make_shared(); - transparentState->setDepthTest(false); - transparentState->setBlendFunction(true, - // 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); - - _shapePlumber->addPipeline(ShapeKey::Filter::Builder().withOpaque(), program, opaqueState); - _shapePlumber->addPipeline(ShapeKey::Filter::Builder().withTranslucent(), program, transparentState); + initOverlay3DPipelines(*_shapePlumber); } void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { @@ -260,18 +218,7 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon } DrawStencilDeferred::DrawStencilDeferred() : _shapePlumber{ std::make_shared() } { - const gpu::int8 STENCIL_OPAQUE = 1; - auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); - auto ps = gpu::Shader::createPixel(std::string(drawOpaqueStencil_frag)); - auto program = gpu::Shader::createProgram(vs, ps); - gpu::Shader::makeProgram((*program)); - - auto state = std::make_shared(); - state->setDepthTest(true, false, gpu::LESS_EQUAL); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_REPLACE)); - state->setColorWriteMask(0); - - _shapePlumber->addPipeline(ShapeKey::Filter::Builder(), program, state); + initStencilPipelines(*_shapePlumber); } void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { @@ -411,166 +358,3 @@ void Blit::run(const SceneContextPointer& sceneContext, const RenderContextPoint } }); } - -void pipelineBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) { - if (pipeline.locations->normalFittingMapUnit > -1) { - batch.setResourceTexture(pipeline.locations->normalFittingMapUnit, - DependencyManager::get()->getNormalFittingTexture()); - } -} - -void initDeferredPipelines(render::ShapePlumber& plumber) { - 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(); - - // 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(state->getValues()); - - wireFrameState->setFillMode(gpu::State::FILL_LINE); - - plumber.addPipeline(wireFrameKey, program, wireFrameState, &pipelineBatchSetter); - } - }; - - // 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 - addPipeline( - Key::Builder(), - modelVertex, modelPixel); - - addPipeline( - Key::Builder().withTangents(), - modelNormalMapVertex, modelNormalMapPixel); - - addPipeline( - Key::Builder().withSpecular(), - modelVertex, modelSpecularMapPixel); - - addPipeline( - Key::Builder().withTangents().withSpecular(), - modelNormalMapVertex, modelNormalSpecularMapPixel); - - - addPipeline( - Key::Builder().withTranslucent(), - modelVertex, modelTranslucentPixel); - // FIXME Ignore lightmap for translucents meshpart - addPipeline( - Key::Builder().withTranslucent().withLightmap(), - modelVertex, modelTranslucentPixel); - - addPipeline( - Key::Builder().withTangents().withTranslucent(), - modelNormalMapVertex, modelTranslucentPixel); - - addPipeline( - Key::Builder().withSpecular().withTranslucent(), - modelVertex, modelTranslucentPixel); - - addPipeline( - Key::Builder().withTangents().withSpecular().withTranslucent(), - modelNormalMapVertex, modelTranslucentPixel); - - - addPipeline( - Key::Builder().withLightmap(), - modelLightmapVertex, modelLightmapPixel); - - addPipeline( - Key::Builder().withLightmap().withTangents(), - modelLightmapNormalMapVertex, modelLightmapNormalMapPixel); - - addPipeline( - Key::Builder().withLightmap().withSpecular(), - modelLightmapVertex, modelLightmapSpecularMapPixel); - - addPipeline( - Key::Builder().withLightmap().withTangents().withSpecular(), - modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel); - - - addPipeline( - Key::Builder().withSkinned(), - skinModelVertex, modelPixel); - - addPipeline( - Key::Builder().withSkinned().withTangents(), - skinModelNormalMapVertex, modelNormalMapPixel); - - addPipeline( - Key::Builder().withSkinned().withSpecular(), - skinModelVertex, modelSpecularMapPixel); - - addPipeline( - Key::Builder().withSkinned().withTangents().withSpecular(), - skinModelNormalMapVertex, modelNormalSpecularMapPixel); - - - addPipeline( - Key::Builder().withSkinned().withTranslucent(), - skinModelVertex, modelTranslucentPixel); - - addPipeline( - Key::Builder().withSkinned().withTangents().withTranslucent(), - skinModelNormalMapVertex, modelTranslucentPixel); - - addPipeline( - Key::Builder().withSkinned().withSpecular().withTranslucent(), - skinModelVertex, modelTranslucentPixel); - - addPipeline( - Key::Builder().withSkinned().withTangents().withSpecular().withTranslucent(), - skinModelNormalMapVertex, modelTranslucentPixel); - - - addPipeline( - Key::Builder().withDepthOnly(), - modelShadowVertex, modelShadowPixel); - - - addPipeline( - Key::Builder().withSkinned().withDepthOnly(), - skinModelShadowVertex, modelShadowPixel); -} - diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp new file mode 100644 index 0000000000..a7e9081d9a --- /dev/null +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -0,0 +1,234 @@ + +// +// RenderPipelines.cpp +// render-utils/src/ +// +// Created by Zach Pomerantz on 1/28/2016. +// Copyright 2016 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 +#include + +#include "TextureCache.h" +#include "render/DrawTask.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" + +#include "drawOpaqueStencil_frag.h" + +using namespace render; + +void initOverlay3DPipelines(ShapePlumber& plumber) { + auto vs = gpu::Shader::createVertex(std::string(overlay3D_vert)); + auto ps = gpu::Shader::createPixel(std::string(overlay3D_frag)); + auto program = gpu::Shader::createProgram(vs, ps); + + auto opaqueState = std::make_shared(); + opaqueState->setDepthTest(false); + opaqueState->setBlendFunction(false); + + plumber.addPipeline(ShapeKey::Filter::Builder().withOpaque(), program, opaqueState); +} + +void initStencilPipelines(ShapePlumber& plumber) { + const gpu::int8 STENCIL_OPAQUE = 1; + auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); + auto ps = gpu::Shader::createPixel(std::string(drawOpaqueStencil_frag)); + auto program = gpu::Shader::createProgram(vs, ps); + gpu::Shader::makeProgram((*program)); + + auto state = std::make_shared(); + state->setDepthTest(true, false, gpu::LESS_EQUAL); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_REPLACE)); + state->setColorWriteMask(0); + + plumber.addPipeline(ShapeKey::Filter::Builder(), program, state); +} + +void pipelineBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) { + if (pipeline.locations->normalFittingMapUnit > -1) { + batch.setResourceTexture(pipeline.locations->normalFittingMapUnit, + DependencyManager::get()->getNormalFittingTexture()); + } +} + +void initDeferredPipelines(render::ShapePlumber& plumber) { + 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(); + + // 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(state->getValues()); + + wireFrameState->setFillMode(gpu::State::FILL_LINE); + + plumber.addPipeline(wireFrameKey, program, wireFrameState, &pipelineBatchSetter); + } + }; + + // 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 + addPipeline( + Key::Builder(), + modelVertex, modelPixel); + + addPipeline( + Key::Builder().withTangents(), + modelNormalMapVertex, modelNormalMapPixel); + + addPipeline( + Key::Builder().withSpecular(), + modelVertex, modelSpecularMapPixel); + + addPipeline( + Key::Builder().withTangents().withSpecular(), + modelNormalMapVertex, modelNormalSpecularMapPixel); + + + addPipeline( + Key::Builder().withTranslucent(), + modelVertex, modelTranslucentPixel); + // FIXME Ignore lightmap for translucents meshpart + addPipeline( + Key::Builder().withTranslucent().withLightmap(), + modelVertex, modelTranslucentPixel); + + addPipeline( + Key::Builder().withTangents().withTranslucent(), + modelNormalMapVertex, modelTranslucentPixel); + + addPipeline( + Key::Builder().withSpecular().withTranslucent(), + modelVertex, modelTranslucentPixel); + + addPipeline( + Key::Builder().withTangents().withSpecular().withTranslucent(), + modelNormalMapVertex, modelTranslucentPixel); + + + addPipeline( + Key::Builder().withLightmap(), + modelLightmapVertex, modelLightmapPixel); + + addPipeline( + Key::Builder().withLightmap().withTangents(), + modelLightmapNormalMapVertex, modelLightmapNormalMapPixel); + + addPipeline( + Key::Builder().withLightmap().withSpecular(), + modelLightmapVertex, modelLightmapSpecularMapPixel); + + addPipeline( + Key::Builder().withLightmap().withTangents().withSpecular(), + modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel); + + + addPipeline( + Key::Builder().withSkinned(), + skinModelVertex, modelPixel); + + addPipeline( + Key::Builder().withSkinned().withTangents(), + skinModelNormalMapVertex, modelNormalMapPixel); + + addPipeline( + Key::Builder().withSkinned().withSpecular(), + skinModelVertex, modelSpecularMapPixel); + + addPipeline( + Key::Builder().withSkinned().withTangents().withSpecular(), + skinModelNormalMapVertex, modelNormalSpecularMapPixel); + + + addPipeline( + Key::Builder().withSkinned().withTranslucent(), + skinModelVertex, modelTranslucentPixel); + + addPipeline( + Key::Builder().withSkinned().withTangents().withTranslucent(), + skinModelNormalMapVertex, modelTranslucentPixel); + + addPipeline( + Key::Builder().withSkinned().withSpecular().withTranslucent(), + skinModelVertex, modelTranslucentPixel); + + addPipeline( + Key::Builder().withSkinned().withTangents().withSpecular().withTranslucent(), + skinModelNormalMapVertex, modelTranslucentPixel); + + + addPipeline( + Key::Builder().withDepthOnly(), + modelShadowVertex, modelShadowPixel); + + + addPipeline( + Key::Builder().withSkinned().withDepthOnly(), + skinModelShadowVertex, modelShadowPixel); +} + From aa10af2851f25284dd1ed4c8ee0ceed4f517add1 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 2 Feb 2016 17:10:21 -0800 Subject: [PATCH 4/4] Revert "Move DrawStencil to use ShapePlumber" This reverts commit 671f27e5bc3950cc75884a5b8b0e6b6221011cb5. --- .../render-utils/src/RenderDeferredTask.cpp | 15 ++++++---- .../render-utils/src/RenderDeferredTask.h | 9 +++--- .../render-utils/src/RenderPipelines.cpp | 28 +++++++++---------- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 8a47280526..e21b8ce799 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -32,8 +32,8 @@ using namespace render; +extern void initStencilPipeline(gpu::PipelinePointer& pipeline); extern void initOverlay3DPipelines(render::ShapePlumber& plumber); -extern void initStencilPipelines(render::ShapePlumber& plumber); extern void initDeferredPipelines(render::ShapePlumber& plumber); void PrepareDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { @@ -217,8 +217,12 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon } } -DrawStencilDeferred::DrawStencilDeferred() : _shapePlumber{ std::make_shared() } { - initStencilPipelines(*_shapePlumber); +gpu::PipelinePointer DrawStencilDeferred::_opaquePipeline; +const gpu::PipelinePointer& DrawStencilDeferred::getOpaquePipeline() { + if (!_opaquePipeline) { + initStencilPipeline(_opaquePipeline); + } + return _opaquePipeline; } void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { @@ -238,12 +242,11 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); - // We only need to fetch this once - static const auto& pipeline = _shapePlumber->pickPipeline(args, ShapeKey()); + batch.setPipeline(getOpaquePipeline()); - batch.setPipeline(pipeline->pipeline); batch.draw(gpu::TRIANGLE_STRIP, 4); batch.setResourceTexture(0, nullptr); + }); args->_batch = nullptr; } diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 894a91cdc3..0be2e0e808 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -68,14 +68,13 @@ protected: class DrawStencilDeferred { public: - DrawStencilDeferred(); - - void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); - using JobModel = render::Job::Model; + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); + static const gpu::PipelinePointer& getOpaquePipeline(); + protected: - render::ShapePlumberPointer _shapePlumber; + static gpu::PipelinePointer _opaquePipeline; //lazy evaluation hence mutable }; class DrawBackgroundDeferred { diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index a7e9081d9a..d2e880aea3 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -43,19 +43,7 @@ using namespace render; -void initOverlay3DPipelines(ShapePlumber& plumber) { - auto vs = gpu::Shader::createVertex(std::string(overlay3D_vert)); - auto ps = gpu::Shader::createPixel(std::string(overlay3D_frag)); - auto program = gpu::Shader::createProgram(vs, ps); - - auto opaqueState = std::make_shared(); - opaqueState->setDepthTest(false); - opaqueState->setBlendFunction(false); - - plumber.addPipeline(ShapeKey::Filter::Builder().withOpaque(), program, opaqueState); -} - -void initStencilPipelines(ShapePlumber& plumber) { +void initStencilPipeline(gpu::PipelinePointer& pipeline) { const gpu::int8 STENCIL_OPAQUE = 1; auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); auto ps = gpu::Shader::createPixel(std::string(drawOpaqueStencil_frag)); @@ -67,7 +55,19 @@ void initStencilPipelines(ShapePlumber& plumber) { state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_REPLACE)); state->setColorWriteMask(0); - plumber.addPipeline(ShapeKey::Filter::Builder(), program, state); + pipeline = gpu::Pipeline::create(program, state); +} + +void initOverlay3DPipelines(ShapePlumber& plumber) { + auto vs = gpu::Shader::createVertex(std::string(overlay3D_vert)); + auto ps = gpu::Shader::createPixel(std::string(overlay3D_frag)); + auto program = gpu::Shader::createProgram(vs, ps); + + auto opaqueState = std::make_shared(); + opaqueState->setDepthTest(false); + opaqueState->setBlendFunction(false); + + plumber.addPipeline(ShapeKey::Filter::Builder().withOpaque(), program, opaqueState); } void pipelineBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {