From 5c547037f26ab6d51c2c55c9c484fddfd6a85a7e Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 17 Jun 2015 15:54:20 +0200 Subject: [PATCH] Migrating the overaly 3d rendering in their own job and their own shader --- .../src/ui/overlays/BillboardOverlay.cpp | 2 + interface/src/ui/overlays/Cube3DOverlay.cpp | 3 +- .../render-utils/src/RenderDeferredTask.cpp | 73 ++++++++++++++++++- .../render-utils/src/RenderDeferredTask.h | 11 +++ libraries/render-utils/src/overlay3D.slf | 28 +++++++ libraries/render-utils/src/overlay3D.slv | 40 ++++++++++ libraries/shared/src/RenderArgs.h | 5 ++ 7 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 libraries/render-utils/src/overlay3D.slf create mode 100644 libraries/render-utils/src/overlay3D.slv diff --git a/interface/src/ui/overlays/BillboardOverlay.cpp b/interface/src/ui/overlays/BillboardOverlay.cpp index ed0ddd8dc7..e7b043f44f 100644 --- a/interface/src/ui/overlays/BillboardOverlay.cpp +++ b/interface/src/ui/overlays/BillboardOverlay.cpp @@ -99,6 +99,8 @@ void BillboardOverlay::render(RenderArgs* args) { DependencyManager::get()->renderQuad(*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha)); + + batch->setUniformTexture(0, args->_whiteTexture); // restore default white color after me } else { glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.5f); diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 73406c07a0..d048b1a05a 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -69,8 +69,9 @@ void Cube3DOverlay::render(RenderArgs* args) { transform.setScale(dimensions); batch->setModelTransform(transform); + DependencyManager::get()->renderSolidCube(*batch, 1.0f, cubeColor); - DependencyManager::get()->renderSolidCube(*batch, 1.0f, cubeColor); + //DependencyManager::get()->renderSolidCube(*batch, 1.0f, cubeColor); } else { if (getIsDashedLine()) { diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index d9dda279e0..ce3c6769ca 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -15,9 +15,12 @@ #include "DeferredLightingEffect.h" #include "ViewFrustum.h" #include "RenderArgs.h" +#include "TextureCache.h" #include +#include "overlay3D_vert.h" +#include "overlay3D_frag.h" using namespace render; @@ -50,7 +53,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() { _jobs.push_back(Job(RenderDeferred())); _jobs.push_back(Job(ResolveDeferred())); _jobs.push_back(Job(DrawTransparentDeferred())); - _jobs.push_back(Job(DrawPostLayered())); + _jobs.push_back(Job(DrawOverlay3D())); _jobs.push_back(Job(ResetGLState())); } @@ -225,10 +228,76 @@ template <> void render::jobRun(const DrawTransparentDeferred& job, const SceneC renderItems(sceneContext, renderContext, renderedItems, renderContext->_maxDrawnTransparentItems); + // Before rendering the batch make sure we re in sync with gl state + args->_context->syncCache(); args->_context->render((*args->_batch)); args->_batch = nullptr; // reset blend function to standard... - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); + // glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); } } + +const gpu::PipelinePointer& DrawOverlay3D::getOpaquePipeline() const { + if (!_opaquePipeline) { + auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(overlay3D_vert))); + auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(overlay3D_frag))); + + auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps)); + + auto state = gpu::StatePointer(new gpu::State()); + state->setDepthTest(true, true, gpu::LESS_EQUAL); + + _opaquePipeline.reset(gpu::Pipeline::create(program, state)); + } + return _opaquePipeline; +} + +template <> void render::jobRun(const DrawOverlay3D& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("DrawOverlay3D"); + assert(renderContext->args); + assert(renderContext->args->_viewFrustum); + + // render backgrounds + auto& scene = sceneContext->_scene; + auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape().withLayered()); + + + ItemIDsBounds inItems; + inItems.reserve(items.size()); + for (auto id : items) { + auto& item = scene->getItem(id); + if (item.getKey().isVisible() && (item.getLayer() == 1)) { + inItems.emplace_back(id); + } + } + + RenderArgs* args = renderContext->args; + gpu::Batch batch; + args->_batch = &batch; + args->_whiteTexture = DependencyManager::get()->getWhiteTexture(); + + + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); + if (args->_renderMode == RenderArgs::MIRROR_RENDER_MODE) { + viewMat.postScale(glm::vec3(-1.0f, 1.0f, 1.0f)); + } + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + batch.setPipeline(job.getOpaquePipeline()); + batch.setUniformTexture(0, args->_whiteTexture); + + if (!inItems.empty()) { + batch.clearFramebuffer(gpu::Framebuffer::BUFFER_DEPTH, glm::vec4(), 1.f, 0); + renderItems(sceneContext, renderContext, inItems); + } + + // Before rendering the batch make sure we re in sync with gl state + args->_context->syncCache(); + args->_context->render((*args->_batch)); + args->_batch = nullptr; + args->_whiteTexture.reset(); +} diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index e2cac53c0d..3b0ffdfc9b 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -14,6 +14,8 @@ #include "render/DrawTask.h" +#include "gpu/Pipeline.h" + class PrepareDeferred { public: }; @@ -50,6 +52,15 @@ namespace render { template <> void jobRun(const DrawTransparentDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); } +class DrawOverlay3D { + mutable gpu::PipelinePointer _opaquePipeline; //lazy evaluation hence mutable +public: + const gpu::PipelinePointer& getOpaquePipeline() const; +}; +namespace render { +template <> void jobRun(const DrawOverlay3D& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); +} + class RenderDeferredTask : public render::Task { public: diff --git a/libraries/render-utils/src/overlay3D.slf b/libraries/render-utils/src/overlay3D.slf new file mode 100644 index 0000000000..8686066dd8 --- /dev/null +++ b/libraries/render-utils/src/overlay3D.slf @@ -0,0 +1,28 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// model.frag +// fragment shader +// +// Created by Sam Gateau on 6/16/15. +// 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 +// + +uniform sampler2D diffuseMap; + +varying vec2 varTexcoord; + +varying vec3 varEyeNormal; + +varying vec4 varColor; + + +void main(void) { + vec4 diffuse = texture2D(diffuseMap, varTexcoord.st); + + + gl_FragColor = vec4(varColor * diffuse); +} diff --git a/libraries/render-utils/src/overlay3D.slv b/libraries/render-utils/src/overlay3D.slv new file mode 100644 index 0000000000..b272b2bfd0 --- /dev/null +++ b/libraries/render-utils/src/overlay3D.slv @@ -0,0 +1,40 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// overlay3D.slv +// +// Created by Sam Gateau on 6/16/15. +// 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 gpu/Transform.slh@> + +<$declareStandardTransform()$> + +attribute vec2 attribTexcoord; + +varying vec2 varTexcoord; + +// interpolated eye position +varying vec4 varEyePosition; + +// the interpolated normal +varying vec3 varEyeNormal; + +varying vec4 varColor; + +void main(void) { + varTexcoord = attribTexcoord; + + // pass along the color + varColor = gl_Color; + + // standard transform + TransformCamera cam = getTransformCamera(); + TransformObject obj = getTransformObject(); + <$transformModelToEyeAndClipPos(cam, obj, gl_Vertex, varEyePosition, gl_Position)$> + <$transformModelToEyeDir(cam, obj, gl_Normal, varEyeNormal.xyz)$> +} diff --git a/libraries/shared/src/RenderArgs.h b/libraries/shared/src/RenderArgs.h index 84b3a202b4..9673623b13 100644 --- a/libraries/shared/src/RenderArgs.h +++ b/libraries/shared/src/RenderArgs.h @@ -13,6 +13,8 @@ #define hifi_RenderArgs_h #include +#include + class AABox; class OctreeRenderer; @@ -20,6 +22,7 @@ class ViewFrustum; namespace gpu { class Batch; class Context; +class Texture; } class RenderDetails { @@ -109,6 +112,8 @@ public: gpu::Batch* _batch = nullptr; ShoudRenderFunctor _shouldRender; + std::shared_ptr _whiteTexture; + RenderDetails _details; float _alphaThreshold = 0.5f;