From dc3c9b48eaa092f973f0c7b35ede707ee622b0ab Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 29 Sep 2015 18:28:20 -0700 Subject: [PATCH 1/9] MOving forward on the background beeing drawn last --- libraries/render-utils/src/Environment.cpp | 3 +- .../render-utils/src/FramebufferCache.cpp | 23 ++++ libraries/render-utils/src/FramebufferCache.h | 4 + .../render-utils/src/RenderDeferredTask.cpp | 107 +++++++++++++++++- .../render-utils/src/RenderDeferredTask.h | 17 +++ .../render-utils/src/drawOpaqueStencil.slf | 30 +++++ libraries/render/src/render/DrawTask.h | 1 + 7 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 libraries/render-utils/src/drawOpaqueStencil.slf diff --git a/libraries/render-utils/src/Environment.cpp b/libraries/render-utils/src/Environment.cpp index 7fbd89acc1..365fbdb16a 100644 --- a/libraries/render-utils/src/Environment.cpp +++ b/libraries/render-utils/src/Environment.cpp @@ -62,7 +62,8 @@ void Environment::setupAtmosphereProgram(const char* vertSource, const char* fra auto state = std::make_shared(); state->setCullMode(gpu::State::CULL_NONE); - state->setDepthTest(false); + // state->setDepthTest(false); + state->setDepthTest(true, false, gpu::LESS_EQUAL); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); diff --git a/libraries/render-utils/src/FramebufferCache.cpp b/libraries/render-utils/src/FramebufferCache.cpp index d6ebd001d2..eb154f77c9 100644 --- a/libraries/render-utils/src/FramebufferCache.cpp +++ b/libraries/render-utils/src/FramebufferCache.cpp @@ -35,7 +35,9 @@ void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) { _frameBufferSize = frameBufferSize; _primaryFramebufferFull.reset(); _primaryFramebufferDepthColor.reset(); + _primaryFramebufferDepthStencilColor.reset(); _primaryDepthTexture.reset(); + _primaryStencilTexture.reset(); _primaryColorTexture.reset(); _primaryNormalTexture.reset(); _primarySpecularTexture.reset(); @@ -47,6 +49,7 @@ void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) { void FramebufferCache::createPrimaryFramebuffer() { _primaryFramebufferFull = gpu::FramebufferPointer(gpu::Framebuffer::create()); _primaryFramebufferDepthColor = gpu::FramebufferPointer(gpu::Framebuffer::create()); + _primaryFramebufferDepthStencilColor = gpu::FramebufferPointer(gpu::Framebuffer::create()); auto colorFormat = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); auto width = _frameBufferSize.width(); @@ -63,12 +66,19 @@ void FramebufferCache::createPrimaryFramebuffer() { _primaryFramebufferDepthColor->setRenderBuffer(0, _primaryColorTexture); + _primaryFramebufferDepthStencilColor->setRenderBuffer(0, _primaryColorTexture); + auto depthFormat = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH); _primaryDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, width, height, defaultSampler)); + auto stencilFormat = gpu::Element(gpu::VEC2, gpu::UINT32, gpu::DEPTH_STENCIL); + _primaryStencilTexture = gpu::TexturePointer(gpu::Texture::create2D(stencilFormat, width, height, defaultSampler)); + _primaryFramebufferFull->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); _primaryFramebufferDepthColor->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); + + _primaryFramebufferDepthStencilColor->setDepthStencilBuffer(_primaryStencilTexture, stencilFormat); _selfieFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); auto tex = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width * 0.5, height * 0.5, defaultSampler)); @@ -89,6 +99,12 @@ gpu::FramebufferPointer FramebufferCache::getPrimaryFramebufferDepthColor() { return _primaryFramebufferDepthColor; } +gpu::FramebufferPointer FramebufferCache::getPrimaryFramebufferDepthStencilColor() { + if (!_primaryFramebufferDepthStencilColor) { + createPrimaryFramebuffer(); + } + return _primaryFramebufferDepthStencilColor; +} gpu::TexturePointer FramebufferCache::getPrimaryDepthTexture() { if (!_primaryDepthTexture) { @@ -97,6 +113,13 @@ gpu::TexturePointer FramebufferCache::getPrimaryDepthTexture() { return _primaryDepthTexture; } +gpu::TexturePointer FramebufferCache::getPrimaryStencilTexture() { + if (!_primaryStencilTexture) { + createPrimaryFramebuffer(); + } + return _primaryStencilTexture; +} + gpu::TexturePointer FramebufferCache::getPrimaryColorTexture() { if (!_primaryColorTexture) { createPrimaryFramebuffer(); diff --git a/libraries/render-utils/src/FramebufferCache.h b/libraries/render-utils/src/FramebufferCache.h index c2274a77e8..baca07af24 100644 --- a/libraries/render-utils/src/FramebufferCache.h +++ b/libraries/render-utils/src/FramebufferCache.h @@ -31,8 +31,10 @@ public: /// used for scene rendering. gpu::FramebufferPointer getPrimaryFramebuffer(); gpu::FramebufferPointer getPrimaryFramebufferDepthColor(); + gpu::FramebufferPointer getPrimaryFramebufferDepthStencilColor(); gpu::TexturePointer getPrimaryDepthTexture(); + gpu::TexturePointer getPrimaryStencilTexture(); gpu::TexturePointer getPrimaryColorTexture(); gpu::TexturePointer getPrimaryNormalTexture(); gpu::TexturePointer getPrimarySpecularTexture(); @@ -58,7 +60,9 @@ private: gpu::FramebufferPointer _primaryFramebufferFull; gpu::FramebufferPointer _primaryFramebufferDepthColor; + gpu::FramebufferPointer _primaryFramebufferDepthStencilColor; gpu::TexturePointer _primaryDepthTexture; + gpu::TexturePointer _primaryStencilTexture; gpu::TexturePointer _primaryColorTexture; gpu::TexturePointer _primaryNormalTexture; gpu::TexturePointer _primarySpecularTexture; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 65f77689c3..d21b6377be 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include "FramebufferCache.h" #include "DeferredLightingEffect.h" @@ -28,6 +29,8 @@ #include "overlay3D_vert.h" #include "overlay3D_frag.h" +#include "drawOpaqueStencil_frag.h" + using namespace render; void SetupDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { @@ -65,7 +68,7 @@ void ResolveDeferred::run(const SceneContextPointer& sceneContext, const RenderC RenderDeferredTask::RenderDeferredTask() : Task() { _jobs.push_back(Job(new SetupDeferred::JobModel("SetupFramebuffer"))); - _jobs.push_back(Job(new DrawBackground::JobModel("DrawBackground"))); + // _jobs.push_back(Job(new DrawBackground::JobModel("DrawBackground"))); _jobs.push_back(Job(new PrepareDeferred::JobModel("PrepareDeferred"))); _jobs.push_back(Job(new FetchItems::JobModel("FetchOpaque", @@ -79,7 +82,10 @@ RenderDeferredTask::RenderDeferredTask() : Task() { _jobs.push_back(Job(new DepthSortItems::JobModel("DepthSortOpaque", _jobs.back().getOutput()))); auto& renderedOpaques = _jobs.back().getOutput(); _jobs.push_back(Job(new DrawOpaqueDeferred::JobModel("DrawOpaqueDeferred", _jobs.back().getOutput()))); - + + _jobs.push_back(Job(new DrawStencilDeferred::JobModel("DrawOpaqueStencil"))); + _jobs.push_back(Job(new DrawBackgroundDeferred::JobModel("DrawBackgroundDeferred"))); + _jobs.push_back(Job(new DrawLight::JobModel("DrawLight"))); _jobs.push_back(Job(new RenderDeferred::JobModel("RenderDeferred"))); _jobs.push_back(Job(new ResolveDeferred::JobModel("ResolveDeferred"))); @@ -289,3 +295,100 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon args->_whiteTexture.reset(); } } + +gpu::PipelinePointer DrawStencilDeferred::_opaquePipeline; +const gpu::PipelinePointer& DrawStencilDeferred::getOpaquePipeline() { + if (!_opaquePipeline) { + auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); + auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(drawOpaqueStencil_frag))); + auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps)); + + auto state = std::make_shared(); + state->setDepthTest(true, true, gpu::LESS_EQUAL); + + _opaquePipeline.reset(gpu::Pipeline::create(program, state)); + } + return _opaquePipeline; +} + +void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + assert(renderContext->args); + assert(renderContext->args->_viewFrustum); + + // from the touched pixel generate the stencil buffer + RenderArgs* args = renderContext->args; + doInBatch(args->_context, [=](gpu::Batch& batch) { + args->_batch = &batch; + + auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferDepthStencilColor(); + auto primaryFboFull = DependencyManager::get()->getPrimaryFramebuffer(); + auto primaryDepth = DependencyManager::get()->getPrimaryDepthTexture(); + + batch.setFramebuffer(primaryFboColorDepthStencil); + + batch.enableStereo(false); + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); + + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); + + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + batch.setPipeline(getOpaquePipeline()); + batch.setResourceTexture(0, primaryDepth); + + batch.draw(gpu::TRIANGLE_STRIP, 4); + batch.setResourceTexture(0, nullptr); + + batch.setFramebuffer(primaryFboFull); + + }); + args->_batch = nullptr; +} + +void DrawBackgroundDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + assert(renderContext->args); + assert(renderContext->args->_viewFrustum); + + // render backgrounds + auto& scene = sceneContext->_scene; + auto& items = scene->getMasterBucket().at(ItemFilter::Builder::background()); + + + ItemIDsBounds inItems; + inItems.reserve(items.size()); + for (auto id : items) { + inItems.emplace_back(id); + } + RenderArgs* args = renderContext->args; + doInBatch(args->_context, [=](gpu::Batch& batch) { + args->_batch = &batch; + + // auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferDepthStencilColor(); + auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferDepthColor(); + auto primaryFboFull = DependencyManager::get()->getPrimaryFramebuffer(); + + batch.setFramebuffer(primaryFboColorDepthStencil); + + batch.enableSkybox(true); + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); + + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); + + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + + renderItems(sceneContext, renderContext, inItems); + + batch.setFramebuffer(primaryFboFull); + + }); + args->_batch = nullptr; +} \ No newline at end of file diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 8366a2665d..04483fc037 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -59,6 +59,23 @@ public: typedef render::Job::ModelI JobModel; }; +class DrawStencilDeferred { + static gpu::PipelinePointer _opaquePipeline; //lazy evaluation hence mutable +public: + static const gpu::PipelinePointer& getOpaquePipeline(); + + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); + + typedef render::Job::Model JobModel; +}; + +class DrawBackgroundDeferred { +public: + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); + + typedef render::Job::Model JobModel; +}; + class DrawOverlay3D { static gpu::PipelinePointer _opaquePipeline; //lazy evaluation hence mutable public: diff --git a/libraries/render-utils/src/drawOpaqueStencil.slf b/libraries/render-utils/src/drawOpaqueStencil.slf new file mode 100644 index 0000000000..0634d2d66a --- /dev/null +++ b/libraries/render-utils/src/drawOpaqueStencil.slf @@ -0,0 +1,30 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// drawOpaqueStencil.frag +// fragment shader +// +// Created by Sam Gateau on 9/29/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()$> + +in vec2 varTexCoord0; +out vec4 outFragColor; + +uniform sampler2D depthTexture; + +void main(void) { + + float depth = texture(depthTexture, varTexCoord0).r; + + outFragColor = vec4(vec3(depth), 1.0); +} diff --git a/libraries/render/src/render/DrawTask.h b/libraries/render/src/render/DrawTask.h index ec6656c0dc..b7a03b81e2 100755 --- a/libraries/render/src/render/DrawTask.h +++ b/libraries/render/src/render/DrawTask.h @@ -257,6 +257,7 @@ class DrawBackground { public: void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); + typedef Job::Model JobModel; }; From e78f1521abb9967886948243c5d3286aef70a5f6 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 30 Sep 2015 09:24:36 -0700 Subject: [PATCH 2/9] getting the stencil buffer in place --- libraries/gpu/src/gpu/Framebuffer.cpp | 8 ++- libraries/gpu/src/gpu/Framebuffer.h | 2 + libraries/gpu/src/gpu/GLBackendOutput.cpp | 13 ++++- libraries/gpu/src/gpu/GLBackendTexture.cpp | 49 +++++++++++++------ .../render-utils/src/RenderDeferredTask.cpp | 4 +- .../render-utils/src/drawOpaqueStencil.slf | 6 ++- 6 files changed, 63 insertions(+), 19 deletions(-) diff --git a/libraries/gpu/src/gpu/Framebuffer.cpp b/libraries/gpu/src/gpu/Framebuffer.cpp index 96bd3d3002..d570007b3e 100755 --- a/libraries/gpu/src/gpu/Framebuffer.cpp +++ b/libraries/gpu/src/gpu/Framebuffer.cpp @@ -247,7 +247,13 @@ bool Framebuffer::setDepthStencilBuffer(const TexturePointer& texture, const For _bufferMask = ( _bufferMask & ~BUFFER_DEPTHSTENCIL); if (texture) { - _bufferMask |= BUFFER_DEPTHSTENCIL; + if (format.getSemantic() == gpu::DEPTH) { + _bufferMask |= BUFFER_DEPTH; + } else if (format.getSemantic() == gpu::STENCIL) { + _bufferMask |= BUFFER_STENCIL; + } else if (format.getSemantic() == gpu::DEPTH_STENCIL) { + _bufferMask |= BUFFER_DEPTHSTENCIL; + } } return true; diff --git a/libraries/gpu/src/gpu/Framebuffer.h b/libraries/gpu/src/gpu/Framebuffer.h index 310255af9f..83ff8fbb23 100755 --- a/libraries/gpu/src/gpu/Framebuffer.h +++ b/libraries/gpu/src/gpu/Framebuffer.h @@ -116,6 +116,8 @@ public: bool isEmpty() const { return (_bufferMask == 0); } bool hasColor() const { return (getBufferMask() & BUFFER_COLORS); } bool hasDepthStencil() const { return (getBufferMask() & BUFFER_DEPTHSTENCIL); } + bool hasDepth() const { return (getBufferMask() & BUFFER_DEPTH); } + bool hasStencil() const { return (getBufferMask() & BUFFER_STENCIL); } bool validateTargetCompatibility(const Texture& texture, uint32 subresource = 0) const; diff --git a/libraries/gpu/src/gpu/GLBackendOutput.cpp b/libraries/gpu/src/gpu/GLBackendOutput.cpp index c3f61a67c3..70e4b18b0f 100755 --- a/libraries/gpu/src/gpu/GLBackendOutput.cpp +++ b/libraries/gpu/src/gpu/GLBackendOutput.cpp @@ -100,7 +100,18 @@ GLBackend::GLFramebuffer* GLBackend::syncGPUObject(const Framebuffer& framebuffe if (surface) { auto gltexture = GLBackend::syncGPUObject(*surface); if (gltexture) { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, gltexture->_texture, 0); + GLenum attachement = GL_DEPTH_STENCIL_ATTACHMENT; + if (!framebuffer.hasStencil()) { + attachement = GL_DEPTH_ATTACHMENT; + glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, gltexture->_texture, 0); + } else if (!framebuffer.hasDepth()) { + attachement = GL_STENCIL_ATTACHMENT; + glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, gltexture->_texture, 0); + } else { + attachement = GL_DEPTH_STENCIL_ATTACHMENT; + glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachement, GL_RENDERBUFFER, gltexture->_texture); + } + (void) CHECK_GL_ERROR(); } } } diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index dce5236868..044204934c 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -66,7 +66,9 @@ public: texel.internalFormat = GL_RG; break; case gpu::DEPTH_STENCIL: - texel.internalFormat = GL_DEPTH_STENCIL; + texel.type = GL_UNSIGNED_BYTE; + texel.format = GL_DEPTH_STENCIL; + texel.internalFormat = GL_DEPTH24_STENCIL8; break; default: qCDebug(gpulogging) << "Unknown combination of texel format"; @@ -197,7 +199,9 @@ public: texel.internalFormat = GL_RG; break; case gpu::DEPTH_STENCIL: - texel.internalFormat = GL_DEPTH_STENCIL; + texel.type = GL_UNSIGNED_BYTE; + texel.format = GL_DEPTH_STENCIL; + texel.internalFormat = GL_DEPTH24_STENCIL8; break; default: qCDebug(gpulogging) << "Unknown combination of texel format"; @@ -334,22 +338,37 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) { } GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(texture.getTexelFormat(), srcFormat); - - glTexImage2D(GL_TEXTURE_2D, 0, - texelFormat.internalFormat, texture.getWidth(), texture.getHeight(), 0, - texelFormat.format, texelFormat.type, bytes); - if (bytes && texture.isAutogenerateMips()) { - glGenerateMipmap(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - }/* else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - }*/ + auto semantic = texture.getTexelFormat().getSemantic(); + + if (semantic == gpu::DEPTH_STENCIL) { + glBindTexture(GL_TEXTURE_2D, 0); + glDeleteTextures(1, &object->_texture); + + glGenRenderbuffers(1, &object->_texture); + glBindRenderbuffer(GL_RENDERBUFFER, object->_texture); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, texture.getWidth(), texture.getHeight()); + // At this point the mip pixels have been loaded, we can notify + texture.notifyMipFaceGPULoaded(0, 0); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + + } else { + glTexImage2D(GL_TEXTURE_2D, 0, + texelFormat.internalFormat, texture.getWidth(), texture.getHeight(), 0, + texelFormat.format, texelFormat.type, bytes); + + if (bytes && texture.isAutogenerateMips()) { + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + }/* else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + }*/ - object->_target = GL_TEXTURE_2D; + object->_target = GL_TEXTURE_2D; - syncSampler(texture.getSampler(), texture.getType(), object); + syncSampler(texture.getSampler(), texture.getType(), object); + } // At this point the mip pixels have been loaded, we can notify texture.notifyMipFaceGPULoaded(0, 0); diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index d21b6377be..71bc41e6b6 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -232,7 +232,9 @@ const gpu::PipelinePointer& DrawOverlay3D::getOpaquePipeline() { auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps)); auto state = std::make_shared(); - state->setDepthTest(true, true, gpu::LESS_EQUAL); + state->setDepthTest(false); + // additive blending + state->setBlendFunction(true, gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::ONE); _opaquePipeline.reset(gpu::Pipeline::create(program, state)); } diff --git a/libraries/render-utils/src/drawOpaqueStencil.slf b/libraries/render-utils/src/drawOpaqueStencil.slf index 0634d2d66a..dae3e56c4d 100644 --- a/libraries/render-utils/src/drawOpaqueStencil.slf +++ b/libraries/render-utils/src/drawOpaqueStencil.slf @@ -26,5 +26,9 @@ void main(void) { float depth = texture(depthTexture, varTexCoord0).r; - outFragColor = vec4(vec3(depth), 1.0); + if (depth >= 0.9) { + outFragColor = vec4(1.0, 0.0, 0.0, 1.0); + } else { + discard; + } } From 75e858cd1314009181c21c0764996dbf266f9ccf Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 30 Sep 2015 15:54:03 -0700 Subject: [PATCH 3/9] Putting together the stencil buffer for opaque vs background and using it for the backgroud render items --- interface/src/Stars.cpp | 2 ++ libraries/gpu/src/gpu/GLBackendState.cpp | 5 +-- libraries/gpu/src/gpu/State.h | 6 ++-- libraries/model/src/model/Skybox.cpp | 1 + .../src/procedural/ProceduralSkybox.cpp | 3 +- libraries/render-utils/src/Environment.cpp | 3 +- .../render-utils/src/FramebufferCache.cpp | 14 ++++----- libraries/render-utils/src/FramebufferCache.h | 4 +-- .../render-utils/src/RenderDeferredTask.cpp | 31 ++++++++++--------- .../render-utils/src/drawOpaqueStencil.slf | 14 +++------ 10 files changed, 44 insertions(+), 39 deletions(-) diff --git a/interface/src/Stars.cpp b/interface/src/Stars.cpp index 4af1a26612..6145529b52 100644 --- a/interface/src/Stars.cpp +++ b/interface/src/Stars.cpp @@ -141,6 +141,7 @@ void Stars::render(RenderArgs* renderArgs, float alpha) { auto state = gpu::StatePointer(new gpu::State()); // enable decal blend state->setDepthTest(gpu::State::DepthTest(false)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _gridPipeline.reset(gpu::Pipeline::create(program, state)); } @@ -152,6 +153,7 @@ void Stars::render(RenderArgs* renderArgs, float alpha) { auto state = gpu::StatePointer(new gpu::State()); // enable decal blend state->setDepthTest(gpu::State::DepthTest(false)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setAntialiasedLineEnable(true); // line smoothing also smooth points state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _starsPipeline.reset(gpu::Pipeline::create(program, state)); diff --git a/libraries/gpu/src/gpu/GLBackendState.cpp b/libraries/gpu/src/gpu/GLBackendState.cpp index 9fdcbc0870..feba6e6853 100644 --- a/libraries/gpu/src/gpu/GLBackendState.cpp +++ b/libraries/gpu/src/gpu/GLBackendState.cpp @@ -655,11 +655,12 @@ void GLBackend::do_setStateStencil(State::StencilActivation activation, State::S GL_INCR, GL_DECR }; - glStencilFuncSeparate(GL_FRONT, STENCIL_OPS[frontTest.getFailOp()], STENCIL_OPS[frontTest.getPassOp()], STENCIL_OPS[frontTest.getDepthFailOp()]); + glStencilOpSeparate(GL_FRONT, STENCIL_OPS[frontTest.getFailOp()], STENCIL_OPS[frontTest.getPassOp()], STENCIL_OPS[frontTest.getDepthFailOp()]); glStencilFuncSeparate(GL_FRONT, GL_COMPARISON_FUNCTIONS[frontTest.getFunction()], frontTest.getReference(), frontTest.getReadMask()); - glStencilFuncSeparate(GL_BACK, STENCIL_OPS[backTest.getFailOp()], STENCIL_OPS[backTest.getPassOp()], STENCIL_OPS[backTest.getDepthFailOp()]); + glStencilOpSeparate(GL_BACK, STENCIL_OPS[backTest.getFailOp()], STENCIL_OPS[backTest.getPassOp()], STENCIL_OPS[backTest.getDepthFailOp()]); glStencilFuncSeparate(GL_BACK, GL_COMPARISON_FUNCTIONS[backTest.getFunction()], backTest.getReference(), backTest.getReadMask()); + } else { glDisable(GL_STENCIL_TEST); } diff --git a/libraries/gpu/src/gpu/State.h b/libraries/gpu/src/gpu/State.h index 5500f20e06..7740506bce 100755 --- a/libraries/gpu/src/gpu/State.h +++ b/libraries/gpu/src/gpu/State.h @@ -143,11 +143,11 @@ public: static const int PASS_OP_OFFSET = 12; uint16 _functionAndOperations; - uint8 _reference = 0; + int8 _reference = 0; uint8 _readMask = 0xff; public: - StencilTest(uint8 reference = 0, uint8 readMask =0xFF, ComparisonFunction func = ALWAYS, StencilOp failOp = STENCIL_OP_KEEP, StencilOp depthFailOp = STENCIL_OP_KEEP, StencilOp passOp = STENCIL_OP_KEEP) : + StencilTest(int8 reference = 0, uint8 readMask =0xFF, ComparisonFunction func = ALWAYS, StencilOp failOp = STENCIL_OP_KEEP, StencilOp depthFailOp = STENCIL_OP_KEEP, StencilOp passOp = STENCIL_OP_KEEP) : _functionAndOperations(func | (failOp << FAIL_OP_OFFSET) | (depthFailOp << DEPTH_FAIL_OP_OFFSET) | (passOp << PASS_OP_OFFSET)), _reference(reference), _readMask(readMask) {} @@ -157,7 +157,7 @@ public: StencilOp getDepthFailOp() const { return StencilOp((_functionAndOperations & DEPTH_FAIL_OP_MASK) >> DEPTH_FAIL_OP_OFFSET); } StencilOp getPassOp() const { return StencilOp((_functionAndOperations & PASS_OP_MASK) >> PASS_OP_OFFSET); } - uint8 getReference() const { return _reference; } + int8 getReference() const { return _reference; } uint8 getReadMask() const { return _readMask; } int32 getRaw() const { return *(reinterpret_cast(this)); } diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index e27a0d25ce..944d16a6dd 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -89,6 +89,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky } auto skyState = std::make_shared(); + skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState)); diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp index 8d34f0e7e5..f69e0575de 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp +++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp @@ -32,7 +32,8 @@ void ProceduralSkybox::setProcedural(const ProceduralPointer& procedural) { if (_procedural) { _procedural->_vertexSource = ProceduralSkybox_vert; _procedural->_fragmentSource = ProceduralSkybox_frag; - // No pipeline state customization + // Adjust the pipeline state for background using the stencil test + _procedural->_state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } } diff --git a/libraries/render-utils/src/Environment.cpp b/libraries/render-utils/src/Environment.cpp index 365fbdb16a..acb149a3cc 100644 --- a/libraries/render-utils/src/Environment.cpp +++ b/libraries/render-utils/src/Environment.cpp @@ -63,7 +63,8 @@ void Environment::setupAtmosphereProgram(const char* vertSource, const char* fra state->setCullMode(gpu::State::CULL_NONE); // state->setDepthTest(false); - state->setDepthTest(true, false, gpu::LESS_EQUAL); + // state->setDepthTest(true, false, gpu::LESS_EQUAL); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); diff --git a/libraries/render-utils/src/FramebufferCache.cpp b/libraries/render-utils/src/FramebufferCache.cpp index eb154f77c9..cd81a21f9a 100644 --- a/libraries/render-utils/src/FramebufferCache.cpp +++ b/libraries/render-utils/src/FramebufferCache.cpp @@ -35,7 +35,7 @@ void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) { _frameBufferSize = frameBufferSize; _primaryFramebufferFull.reset(); _primaryFramebufferDepthColor.reset(); - _primaryFramebufferDepthStencilColor.reset(); + _primaryFramebufferStencilColor.reset(); _primaryDepthTexture.reset(); _primaryStencilTexture.reset(); _primaryColorTexture.reset(); @@ -49,7 +49,7 @@ void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) { void FramebufferCache::createPrimaryFramebuffer() { _primaryFramebufferFull = gpu::FramebufferPointer(gpu::Framebuffer::create()); _primaryFramebufferDepthColor = gpu::FramebufferPointer(gpu::Framebuffer::create()); - _primaryFramebufferDepthStencilColor = gpu::FramebufferPointer(gpu::Framebuffer::create()); + _primaryFramebufferStencilColor = gpu::FramebufferPointer(gpu::Framebuffer::create()); auto colorFormat = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); auto width = _frameBufferSize.width(); @@ -66,7 +66,7 @@ void FramebufferCache::createPrimaryFramebuffer() { _primaryFramebufferDepthColor->setRenderBuffer(0, _primaryColorTexture); - _primaryFramebufferDepthStencilColor->setRenderBuffer(0, _primaryColorTexture); + _primaryFramebufferStencilColor->setRenderBuffer(0, _primaryColorTexture); auto depthFormat = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH); _primaryDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, width, height, defaultSampler)); @@ -78,7 +78,7 @@ void FramebufferCache::createPrimaryFramebuffer() { _primaryFramebufferDepthColor->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); - _primaryFramebufferDepthStencilColor->setDepthStencilBuffer(_primaryStencilTexture, stencilFormat); + _primaryFramebufferStencilColor->setDepthStencilBuffer(_primaryStencilTexture, stencilFormat); _selfieFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); auto tex = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width * 0.5, height * 0.5, defaultSampler)); @@ -99,11 +99,11 @@ gpu::FramebufferPointer FramebufferCache::getPrimaryFramebufferDepthColor() { return _primaryFramebufferDepthColor; } -gpu::FramebufferPointer FramebufferCache::getPrimaryFramebufferDepthStencilColor() { - if (!_primaryFramebufferDepthStencilColor) { +gpu::FramebufferPointer FramebufferCache::getPrimaryFramebufferStencilColor() { + if (!_primaryFramebufferStencilColor) { createPrimaryFramebuffer(); } - return _primaryFramebufferDepthStencilColor; + return _primaryFramebufferStencilColor; } gpu::TexturePointer FramebufferCache::getPrimaryDepthTexture() { diff --git a/libraries/render-utils/src/FramebufferCache.h b/libraries/render-utils/src/FramebufferCache.h index baca07af24..8951ceee80 100644 --- a/libraries/render-utils/src/FramebufferCache.h +++ b/libraries/render-utils/src/FramebufferCache.h @@ -31,7 +31,7 @@ public: /// used for scene rendering. gpu::FramebufferPointer getPrimaryFramebuffer(); gpu::FramebufferPointer getPrimaryFramebufferDepthColor(); - gpu::FramebufferPointer getPrimaryFramebufferDepthStencilColor(); + gpu::FramebufferPointer getPrimaryFramebufferStencilColor(); gpu::TexturePointer getPrimaryDepthTexture(); gpu::TexturePointer getPrimaryStencilTexture(); @@ -60,7 +60,7 @@ private: gpu::FramebufferPointer _primaryFramebufferFull; gpu::FramebufferPointer _primaryFramebufferDepthColor; - gpu::FramebufferPointer _primaryFramebufferDepthStencilColor; + gpu::FramebufferPointer _primaryFramebufferStencilColor; gpu::TexturePointer _primaryDepthTexture; gpu::TexturePointer _primaryStencilTexture; gpu::TexturePointer _primaryColorTexture; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 71bc41e6b6..e16544f5cd 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -301,12 +301,18 @@ 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::getDrawViewportQuadTransformTexcoordVS(); auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(drawOpaqueStencil_frag))); auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps)); + + + gpu::Shader::makeProgram((*program)); auto state = std::make_shared(); - state->setDepthTest(true, true, gpu::LESS_EQUAL); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); + // state->setStencilTest(false, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_INCR, gpu::State::STENCIL_OP_INCR, gpu::State::STENCIL_OP_INCR)); + state->setColorWriteMask(0); _opaquePipeline.reset(gpu::Pipeline::create(program, state)); } @@ -322,23 +328,20 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren doInBatch(args->_context, [=](gpu::Batch& batch) { args->_batch = &batch; - auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferDepthStencilColor(); + auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferStencilColor(); auto primaryFboFull = DependencyManager::get()->getPrimaryFramebuffer(); auto primaryDepth = DependencyManager::get()->getPrimaryDepthTexture(); + + batch.enableStereo(false); batch.setFramebuffer(primaryFboColorDepthStencil); - - batch.enableStereo(false); + batch.clearStencilFramebuffer(0, true); batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); - glm::mat4 projMat; - Transform viewMat; - args->_viewFrustum->evalProjectionMatrix(projMat); - args->_viewFrustum->evalViewTransform(viewMat); + Transform modelMat; + batch.setModelTransform(modelMat); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); batch.setPipeline(getOpaquePipeline()); batch.setResourceTexture(0, primaryDepth); @@ -369,13 +372,13 @@ void DrawBackgroundDeferred::run(const SceneContextPointer& sceneContext, const doInBatch(args->_context, [=](gpu::Batch& batch) { args->_batch = &batch; - // auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferDepthStencilColor(); - auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferDepthColor(); + auto primaryFboColorStencil = DependencyManager::get()->getPrimaryFramebufferStencilColor(); auto primaryFboFull = DependencyManager::get()->getPrimaryFramebuffer(); - batch.setFramebuffer(primaryFboColorDepthStencil); - batch.enableSkybox(true); + + batch.setFramebuffer(primaryFboColorStencil); + batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); diff --git a/libraries/render-utils/src/drawOpaqueStencil.slf b/libraries/render-utils/src/drawOpaqueStencil.slf index dae3e56c4d..883154c624 100644 --- a/libraries/render-utils/src/drawOpaqueStencil.slf +++ b/libraries/render-utils/src/drawOpaqueStencil.slf @@ -12,22 +12,18 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - -<@include gpu/Transform.slh@> - -<$declareStandardTransform()$> - in vec2 varTexCoord0; out vec4 outFragColor; uniform sampler2D depthTexture; void main(void) { + // outFragColor = vec4(varTexCoord0, 0.0, 1.0); - float depth = texture(depthTexture, varTexCoord0).r; - - if (depth >= 0.9) { - outFragColor = vec4(1.0, 0.0, 0.0, 1.0); + float depth = texture(depthTexture, varTexCoord0.xy).r; + outFragColor = vec4(1.0, 0.0, 0.0, 1.0); + if (depth < 1.0) { + outFragColor = vec4(0.0, 1.0, 0.0, 1.0); } else { discard; } From be9b244779a6b4e34156a22d43004f2fde06d18d Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 30 Sep 2015 17:21:52 -0700 Subject: [PATCH 4/9] Fix the skybox color issue with background rendering when no texture is there --- libraries/model/src/model/Skybox.cpp | 113 +++++++++++++++------------ libraries/model/src/model/Skybox.slf | 10 ++- 2 files changed, 69 insertions(+), 54 deletions(-) diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 944d16a6dd..4d49492c39 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -45,11 +45,18 @@ void Skybox::setCubemap(const gpu::TexturePointer& cubemap) { void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) { + const int VERTICES_SLOT = 0; + const int COLOR_SLOT = 1; + + // Create the static shared elements used to render the skybox static gpu::BufferPointer theBuffer; static gpu::Stream::FormatPointer theFormat; - - if (skybox.getCubemap()) { - if (!theBuffer) { + static gpu::BufferPointer theConstants; + static gpu::PipelinePointer thePipeline; + static int SKYBOX_CONSTANTS_SLOT = 0; // need to be defined by the compilation of the shader + static std::once_flag once; + std::call_once(once, [&] { + { const float CLIP = 1.0f; const glm::vec2 vertices[4] = { { -CLIP, -CLIP }, { CLIP, -CLIP }, { -CLIP, CLIP }, { CLIP, CLIP } }; theBuffer = std::make_shared(sizeof(vertices), (const gpu::Byte*) vertices); @@ -57,63 +64,65 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky theFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ)); } - glm::mat4 projMat; - viewFrustum.evalProjectionMatrix(projMat); + { + auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert))); + auto skyFS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(Skybox_frag))); + auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS)); - Transform viewTransform; - viewFrustum.evalViewTransform(viewTransform); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewTransform); - batch.setModelTransform(Transform()); // only for Mac - batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8); - batch.setInputFormat(theFormat); + gpu::Shader::BindingSet bindings; + bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0)); + if (!gpu::Shader::makeProgram(*skyShader, bindings)) { - if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) { - static gpu::BufferPointer theConstants; - static gpu::PipelinePointer thePipeline; - static int SKYBOX_CONSTANTS_SLOT = 0; // need to be defined by the compilation of the shader - if (!thePipeline) { - auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert))); - auto skyFS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(Skybox_frag))); - auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS)); - - gpu::Shader::BindingSet bindings; - bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0)); - if (!gpu::Shader::makeProgram(*skyShader, bindings)) { - - } - - SKYBOX_CONSTANTS_SLOT = skyShader->getBuffers().findLocation("skyboxBuffer"); - if (SKYBOX_CONSTANTS_SLOT == gpu::Shader::INVALID_LOCATION) { - SKYBOX_CONSTANTS_SLOT = skyShader->getUniforms().findLocation("skyboxBuffer"); - } - - auto skyState = std::make_shared(); - skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); - - thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState)); - - auto color = glm::vec4(1.0f); - theConstants = std::make_shared(sizeof(color), (const gpu::Byte*) &color); } - if (glm::all(glm::equal(skybox.getColor(), glm::vec3(0.0f)))) { - auto color = glm::vec4(1.0f); - theConstants->setSubData(0, sizeof(color), (const gpu::Byte*) &color); - } else { - theConstants->setSubData(0, sizeof(Color), (const gpu::Byte*) &skybox.getColor()); + SKYBOX_CONSTANTS_SLOT = skyShader->getBuffers().findLocation("skyboxBuffer"); + if (SKYBOX_CONSTANTS_SLOT == gpu::Shader::INVALID_LOCATION) { + SKYBOX_CONSTANTS_SLOT = skyShader->getUniforms().findLocation("skyboxBuffer"); } - batch.setPipeline(thePipeline); - batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, theConstants, 0, theConstants->getSize()); - batch.setResourceTexture(0, skybox.getCubemap()); - batch.draw(gpu::TRIANGLE_STRIP, 4); + auto skyState = std::make_shared(); + skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + + thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState)); + + auto color = glm::vec4(1.0f); + theConstants = std::make_shared(sizeof(color), (const gpu::Byte*) &color); } + }); - } else { - // skybox has no cubemap, just clear the color buffer - auto color = skybox.getColor(); - batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(color, 0.0f), 0.0f, 0, true); + // Render + glm::mat4 projMat; + viewFrustum.evalProjectionMatrix(projMat); + + Transform viewTransform; + viewFrustum.evalViewTransform(viewTransform); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewTransform); + batch.setModelTransform(Transform()); // only for Mac + batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8); + batch.setInputFormat(theFormat); + + gpu::TexturePointer skymap; + auto color = glm::vec4(skybox.getColor(), 0.0f); + if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) { + skymap = skybox.getCubemap(); + + if (glm::all(glm::equal(skybox.getColor(), glm::vec3(0.0f)))) { + color = glm::vec4(1.0f); + } else { + color.w = 1.0f; + } } + // Update the constant color. + theConstants->setSubData(0, sizeof(glm::vec4), (const gpu::Byte*) &color); + + batch.setPipeline(thePipeline); + batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, theConstants, 0, theConstants->getSize()); + batch.setResourceTexture(0, skymap); + + batch.draw(gpu::TRIANGLE_STRIP, 4); + + batch.setResourceTexture(0, nullptr); + } diff --git a/libraries/model/src/model/Skybox.slf b/libraries/model/src/model/Skybox.slf index 382801f52d..66abee8948 100755 --- a/libraries/model/src/model/Skybox.slf +++ b/libraries/model/src/model/Skybox.slf @@ -40,8 +40,14 @@ void main(void) { #else vec3 coord = normalize(_normal); - vec3 texel = texture(cubeMap, coord).rgb; - vec3 color = texel * _skybox._color.rgb; + + // Skybox color or blend with skymap + vec3 color = _skybox._color.rgb; + if (_skybox._color.a > 0.0) { + vec3 texel = texture(cubeMap, coord).rgb; + color *= texel; + } + vec3 pixel = pow(color, vec3(1.0/2.2)); // manual Gamma correction _fragColor = vec4(pixel, 0.0); From d3d47752327dd0a90fee77e30993d5c16bcb0193 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 30 Sep 2015 17:54:20 -0700 Subject: [PATCH 5/9] THe dataBuffer contining the properties of the skybox is now per instace and not static and shared so it's static from frames to frames --- libraries/model/src/model/Skybox.cpp | 55 ++++++++++--------- libraries/model/src/model/Skybox.h | 18 ++++-- .../src/procedural/ProceduralSkybox.cpp | 1 + 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 4d49492c39..7c22d7a062 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -21,6 +21,8 @@ using namespace model; Skybox::Skybox() { + Data data; + _dataBuffer = gpu::BufferView(std::make_shared(sizeof(Data), (const gpu::Byte*) &data)); /* // PLease create a default engineer skybox _cubemap.reset( gpu::Texture::createCube(gpu::Element::COLOR_RGBA_32, 1)); @@ -36,7 +38,7 @@ Skybox::Skybox() { } void Skybox::setColor(const Color& color) { - _color = color; + _dataBuffer.edit()._color = color; } void Skybox::setCubemap(const gpu::TexturePointer& cubemap) { @@ -44,16 +46,33 @@ void Skybox::setCubemap(const gpu::TexturePointer& cubemap) { } -void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) { - const int VERTICES_SLOT = 0; - const int COLOR_SLOT = 1; +void Skybox::updateDataBuffer() const { + auto blend = 0.0f; + if (getCubemap() && getCubemap()->isDefined()) { + blend = 1.0f; + } + if (blend != _dataBuffer.get()._blend) { + _dataBuffer.edit()._blend = blend; + } +} + + + +void Skybox::render(gpu::Batch& batch, const ViewFrustum& frustum) const { + updateDataBuffer(); + Skybox::render(batch, frustum, (*this)); +} + + +void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) { // Create the static shared elements used to render the skybox static gpu::BufferPointer theBuffer; static gpu::Stream::FormatPointer theFormat; static gpu::BufferPointer theConstants; static gpu::PipelinePointer thePipeline; - static int SKYBOX_CONSTANTS_SLOT = 0; // need to be defined by the compilation of the shader + const int SKYBOX_SKYMAP_SLOT = 0; + const int SKYBOX_CONSTANTS_SLOT = 0; static std::once_flag once; std::call_once(once, [&] { { @@ -70,23 +89,16 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS)); gpu::Shader::BindingSet bindings; - bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0)); + bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), SKYBOX_SKYMAP_SLOT)); + bindings.insert(gpu::Shader::Binding(std::string("skyboxBuffer"), SKYBOX_CONSTANTS_SLOT)); if (!gpu::Shader::makeProgram(*skyShader, bindings)) { } - SKYBOX_CONSTANTS_SLOT = skyShader->getBuffers().findLocation("skyboxBuffer"); - if (SKYBOX_CONSTANTS_SLOT == gpu::Shader::INVALID_LOCATION) { - SKYBOX_CONSTANTS_SLOT = skyShader->getUniforms().findLocation("skyboxBuffer"); - } - auto skyState = std::make_shared(); skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState)); - - auto color = glm::vec4(1.0f); - theConstants = std::make_shared(sizeof(color), (const gpu::Byte*) &color); } }); @@ -103,26 +115,17 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky batch.setInputFormat(theFormat); gpu::TexturePointer skymap; - auto color = glm::vec4(skybox.getColor(), 0.0f); if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) { skymap = skybox.getCubemap(); - - if (glm::all(glm::equal(skybox.getColor(), glm::vec3(0.0f)))) { - color = glm::vec4(1.0f); - } else { - color.w = 1.0f; - } } - // Update the constant color. - theConstants->setSubData(0, sizeof(glm::vec4), (const gpu::Byte*) &color); batch.setPipeline(thePipeline); - batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, theConstants, 0, theConstants->getSize()); - batch.setResourceTexture(0, skymap); + batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, skybox._dataBuffer); + batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, skymap); batch.draw(gpu::TRIANGLE_STRIP, 4); - batch.setResourceTexture(0, nullptr); + batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, nullptr); } diff --git a/libraries/model/src/model/Skybox.h b/libraries/model/src/model/Skybox.h index e9f95afa16..14ba9fa005 100755 --- a/libraries/model/src/model/Skybox.h +++ b/libraries/model/src/model/Skybox.h @@ -30,20 +30,28 @@ public: virtual ~Skybox() {}; void setColor(const Color& color); - const Color& getColor() const { return _color; } + const Color getColor() const { return _dataBuffer.get()._color; } void setCubemap(const gpu::TexturePointer& cubemap); const gpu::TexturePointer& getCubemap() const { return _cubemap; } - virtual void render(gpu::Batch& batch, const ViewFrustum& frustum) const { - render(batch, frustum, (*this)); - } + virtual void render(gpu::Batch& batch, const ViewFrustum& frustum) const; + static void render(gpu::Batch& batch, const ViewFrustum& frustum, const Skybox& skybox); protected: gpu::TexturePointer _cubemap; - Color _color{1.0f, 1.0f, 1.0f}; + + class Data { + public: + glm::vec3 _color{ 1.0f, 1.0f, 1.0f }; + float _blend = 1.0f; + }; + + mutable gpu::BufferView _dataBuffer; + + void updateDataBuffer() const; }; typedef std::shared_ptr< Skybox > SkyboxPointer; diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp index f69e0575de..1c7e7e457c 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp +++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp @@ -43,6 +43,7 @@ void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& frustum) con void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const ProceduralSkybox& skybox) { if (!(skybox._procedural)) { + skybox.updateDataBuffer(); Skybox::render(batch, viewFrustum, skybox); } From 69c40754390f7e70dcfcd16f79bf14f278e5286f Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 30 Sep 2015 18:08:01 -0700 Subject: [PATCH 6/9] Fix the behavior when skybox color is black and skymap is available --- libraries/model/src/model/Skybox.cpp | 4 ++++ libraries/model/src/model/Skybox.slf | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 7c22d7a062..21b40a54c8 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -50,6 +50,10 @@ void Skybox::updateDataBuffer() const { auto blend = 0.0f; if (getCubemap() && getCubemap()->isDefined()) { blend = 1.0f; + // If pitch black neutralize the color + if (glm::all(glm::equal(getColor(), glm::vec3(0.0f)))) { + blend = 2.0f; + } } if (blend != _dataBuffer.get()._blend) { diff --git a/libraries/model/src/model/Skybox.slf b/libraries/model/src/model/Skybox.slf index 66abee8948..a6283055d3 100755 --- a/libraries/model/src/model/Skybox.slf +++ b/libraries/model/src/model/Skybox.slf @@ -45,7 +45,9 @@ void main(void) { vec3 color = _skybox._color.rgb; if (_skybox._color.a > 0.0) { vec3 texel = texture(cubeMap, coord).rgb; - color *= texel; + if (_skybox._color.a < 2.0) { + color *= texel; + } } vec3 pixel = pow(color, vec3(1.0/2.2)); // manual Gamma correction From 0398f9429e9d7d21f181167664b52eb0799aecd7 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 30 Sep 2015 18:39:13 -0700 Subject: [PATCH 7/9] fix the coo/texel blender mode for the case when color is black and the stereo issue --- libraries/model/src/model/Skybox.cpp | 2 +- libraries/model/src/model/Skybox.slf | 2 ++ libraries/render-utils/src/RenderDeferredTask.cpp | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 21b40a54c8..e516fae583 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -129,7 +129,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky batch.draw(gpu::TRIANGLE_STRIP, 4); - batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, nullptr); + // batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, nullptr); } diff --git a/libraries/model/src/model/Skybox.slf b/libraries/model/src/model/Skybox.slf index a6283055d3..6246bbd9d3 100755 --- a/libraries/model/src/model/Skybox.slf +++ b/libraries/model/src/model/Skybox.slf @@ -47,6 +47,8 @@ void main(void) { vec3 texel = texture(cubeMap, coord).rgb; if (_skybox._color.a < 2.0) { color *= texel; + } else { + color = texel; } } diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index e16544f5cd..504070963d 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -335,9 +335,10 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren batch.enableStereo(false); batch.setFramebuffer(primaryFboColorDepthStencil); - batch.clearStencilFramebuffer(0, true); batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); + batch.clearStencilFramebuffer(0, true); + Transform modelMat; batch.setModelTransform(modelMat); From 3490e08521360bde1d0f0266f64ddacbab48a410 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 1 Oct 2015 18:42:09 -0700 Subject: [PATCH 8/9] Little improvments on the performance side to get the Stencil pass and the masking of the background under reasonable performances --- .../gpu/src/gpu/DrawUnitQuadTexcoord.slv | 28 +++++++++++++ libraries/gpu/src/gpu/GLBackend.cpp | 39 ++++++++++++------- libraries/gpu/src/gpu/GLBackendState.cpp | 23 +++++++---- libraries/gpu/src/gpu/GLBackendTransform.cpp | 30 ++++++++------ libraries/gpu/src/gpu/StandardShaderLib.cpp | 8 ++++ libraries/gpu/src/gpu/StandardShaderLib.h | 4 ++ .../render-utils/src/RenderDeferredTask.cpp | 21 ++++------ 7 files changed, 108 insertions(+), 45 deletions(-) create mode 100644 libraries/gpu/src/gpu/DrawUnitQuadTexcoord.slv diff --git a/libraries/gpu/src/gpu/DrawUnitQuadTexcoord.slv b/libraries/gpu/src/gpu/DrawUnitQuadTexcoord.slv new file mode 100644 index 0000000000..60ab0bd7dd --- /dev/null +++ b/libraries/gpu/src/gpu/DrawUnitQuadTexcoord.slv @@ -0,0 +1,28 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Draw the unit quad [-1,-1 -> 1,1] amd pass along the unit texcoords [0, 0 -> 1, 1]. Not transform used. +// Simply draw a Triangle_strip of 2 triangles, no input buffers or index buffer needed +// +// Created by Sam Gateau on 6/22/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 +// +out vec2 varTexCoord0; + +void main(void) { + const vec4 UNIT_QUAD[4] = vec4[4]( + vec4(-1.0, -1.0, 0.0, 1.0), + vec4(1.0, -1.0, 0.0, 1.0), + vec4(-1.0, 1.0, 0.0, 1.0), + vec4(1.0, 1.0, 0.0, 1.0) + ); + vec4 pos = UNIT_QUAD[gl_VertexID]; + + varTexCoord0 = (pos.xy + 1) * 0.5; + + gl_Position = pos; +} diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 250fc4aaac..b1e63a18bd 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -132,20 +132,26 @@ void GLBackend::renderPassTransfer(Batch& batch) { const size_t numCommands = batch.getCommands().size(); const Batch::Commands::value_type* command = batch.getCommands().data(); const Batch::CommandOffsets::value_type* offset = batch.getCommandOffsets().data(); - - for (auto& cached : batch._buffers._items) { - if (cached._data) { - syncGPUObject(*cached._data); + + { // Sync all the buffers + PROFILE_RANGE("syncGPUBuffer"); + + for (auto& cached : batch._buffers._items) { + if (cached._data) { + syncGPUObject(*cached._data); + } } } - // Reset the transform buffers - _transform._cameras.resize(0); - _transform._cameraOffsets.clear(); - _transform._objects.resize(0); - _transform._objectOffsets.clear(); - for (_commandIndex = 0; _commandIndex < numCommands; ++_commandIndex) { - switch (*command) { + { // Sync all the buffers + PROFILE_RANGE("syncCPUTransform"); + _transform._cameras.resize(0); + _transform._cameraOffsets.clear(); + _transform._objects.resize(0); + _transform._objectOffsets.clear(); + + for (_commandIndex = 0; _commandIndex < numCommands; ++_commandIndex) { + switch (*command) { case Batch::COMMAND_draw: case Batch::COMMAND_drawIndexed: case Batch::COMMAND_drawInstanced: @@ -164,11 +170,16 @@ void GLBackend::renderPassTransfer(Batch& batch) { default: break; + } + command++; + offset++; } - command++; - offset++; } - _transform.transfer(); + + { // Sync the transform buffers + PROFILE_RANGE("syncGPUTransform"); + _transform.transfer(); + } } void GLBackend::renderPassDraw(Batch& batch) { diff --git a/libraries/gpu/src/gpu/GLBackendState.cpp b/libraries/gpu/src/gpu/GLBackendState.cpp index feba6e6853..895d0a0027 100644 --- a/libraries/gpu/src/gpu/GLBackendState.cpp +++ b/libraries/gpu/src/gpu/GLBackendState.cpp @@ -642,8 +642,13 @@ void GLBackend::do_setStateStencil(State::StencilActivation activation, State::S if (activation.isEnabled()) { glEnable(GL_STENCIL_TEST); - glStencilMaskSeparate(GL_FRONT, activation.getWriteMaskFront()); - glStencilMaskSeparate(GL_BACK, activation.getWriteMaskBack()); + + if (activation.getWriteMaskFront() != activation.getWriteMaskBack()) { + glStencilMaskSeparate(GL_FRONT, activation.getWriteMaskFront()); + glStencilMaskSeparate(GL_BACK, activation.getWriteMaskBack()); + } else { + glStencilMask(activation.getWriteMaskFront()); + } static GLenum STENCIL_OPS[] = { GL_KEEP, @@ -655,12 +660,16 @@ void GLBackend::do_setStateStencil(State::StencilActivation activation, State::S GL_INCR, GL_DECR }; - glStencilOpSeparate(GL_FRONT, STENCIL_OPS[frontTest.getFailOp()], STENCIL_OPS[frontTest.getPassOp()], STENCIL_OPS[frontTest.getDepthFailOp()]); - glStencilFuncSeparate(GL_FRONT, GL_COMPARISON_FUNCTIONS[frontTest.getFunction()], frontTest.getReference(), frontTest.getReadMask()); - - glStencilOpSeparate(GL_BACK, STENCIL_OPS[backTest.getFailOp()], STENCIL_OPS[backTest.getPassOp()], STENCIL_OPS[backTest.getDepthFailOp()]); - glStencilFuncSeparate(GL_BACK, GL_COMPARISON_FUNCTIONS[backTest.getFunction()], backTest.getReference(), backTest.getReadMask()); + if (frontTest != backTest) { + glStencilOpSeparate(GL_FRONT, STENCIL_OPS[frontTest.getFailOp()], STENCIL_OPS[frontTest.getPassOp()], STENCIL_OPS[frontTest.getDepthFailOp()]); + glStencilFuncSeparate(GL_FRONT, GL_COMPARISON_FUNCTIONS[frontTest.getFunction()], frontTest.getReference(), frontTest.getReadMask()); + glStencilOpSeparate(GL_BACK, STENCIL_OPS[backTest.getFailOp()], STENCIL_OPS[backTest.getPassOp()], STENCIL_OPS[backTest.getDepthFailOp()]); + glStencilFuncSeparate(GL_BACK, GL_COMPARISON_FUNCTIONS[backTest.getFunction()], backTest.getReference(), backTest.getReadMask()); + } else { + glStencilOp(STENCIL_OPS[frontTest.getFailOp()], STENCIL_OPS[frontTest.getPassOp()], STENCIL_OPS[frontTest.getDepthFailOp()]); + glStencilFunc(GL_COMPARISON_FUNCTIONS[frontTest.getFunction()], frontTest.getReference(), frontTest.getReadMask()); + } } else { glDisable(GL_STENCIL_TEST); } diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 4a55155a86..5e16421c6a 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -130,19 +130,27 @@ void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const Stereo void GLBackend::TransformStageState::transfer() const { static QByteArray bufferData; - glBindBuffer(GL_UNIFORM_BUFFER, _cameraBuffer); - bufferData.resize(_cameraUboSize * _cameras.size()); - for (size_t i = 0; i < _cameras.size(); ++i) { - memcpy(bufferData.data() + (_cameraUboSize * i), &_cameras[i], sizeof(TransformCamera)); + if (!_cameras.empty()) { + glBindBuffer(GL_UNIFORM_BUFFER, _cameraBuffer); + bufferData.resize(_cameraUboSize * _cameras.size()); + for (size_t i = 0; i < _cameras.size(); ++i) { + memcpy(bufferData.data() + (_cameraUboSize * i), &_cameras[i], sizeof(TransformCamera)); + } + glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); } - glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); - glBindBuffer(GL_UNIFORM_BUFFER, _objectBuffer); - bufferData.resize(_objectUboSize * _objects.size()); - for (size_t i = 0; i < _objects.size(); ++i) { - memcpy(bufferData.data() + (_objectUboSize * i), &_objects[i], sizeof(TransformObject)); + + if (!_objects.empty()) { + glBindBuffer(GL_UNIFORM_BUFFER, _objectBuffer); + bufferData.resize(_objectUboSize * _objects.size()); + for (size_t i = 0; i < _objects.size(); ++i) { + memcpy(bufferData.data() + (_objectUboSize * i), &_objects[i], sizeof(TransformObject)); + } + glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); + } + + if (!_cameras.empty() || !_objects.empty()) { + glBindBuffer(GL_UNIFORM_BUFFER, 0); } - glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); - glBindBuffer(GL_UNIFORM_BUFFER, 0); CHECK_GL_ERROR(); } diff --git a/libraries/gpu/src/gpu/StandardShaderLib.cpp b/libraries/gpu/src/gpu/StandardShaderLib.cpp index 3f27a7fc35..864bff08c9 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.cpp +++ b/libraries/gpu/src/gpu/StandardShaderLib.cpp @@ -12,6 +12,7 @@ // #include "StandardShaderLib.h" +#include "DrawUnitQuadTexcoord_vert.h" #include "DrawTransformUnitQuad_vert.h" #include "DrawTexcoordRectTransformUnitQuad_vert.h" #include "DrawViewportQuadTransformTexcoord_vert.h" @@ -21,6 +22,7 @@ using namespace gpu; +ShaderPointer StandardShaderLib::_drawUnitQuadTexcoordVS; ShaderPointer StandardShaderLib::_drawTransformUnitQuadVS; ShaderPointer StandardShaderLib::_drawTexcoordRectTransformUnitQuadVS; ShaderPointer StandardShaderLib::_drawViewportQuadTransformTexcoordVS; @@ -55,6 +57,12 @@ ShaderPointer StandardShaderLib::getProgram(GetShader getVS, GetShader getPS) { } +ShaderPointer StandardShaderLib::getDrawUnitQuadTexcoordVS() { + if (!_drawUnitQuadTexcoordVS) { + _drawUnitQuadTexcoordVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(DrawUnitQuadTexcoord_vert))); + } + return _drawUnitQuadTexcoordVS; +} ShaderPointer StandardShaderLib::getDrawTransformUnitQuadVS() { if (!_drawTransformUnitQuadVS) { diff --git a/libraries/gpu/src/gpu/StandardShaderLib.h b/libraries/gpu/src/gpu/StandardShaderLib.h index 2d9c168473..12ea9045c2 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.h +++ b/libraries/gpu/src/gpu/StandardShaderLib.h @@ -23,6 +23,9 @@ namespace gpu { class StandardShaderLib { public: + // Shader draws the unit quad in the full viewport clipPos = ([(-1,-1),(1,1)]) and the unit texcoord = [(0,0),(1,1)]. + static ShaderPointer getDrawUnitQuadTexcoordVS(); + // Shader draw the unit quad objectPos = ([(-1,-1),(1,1)]) and transform it by the full model transform stack (Model, View, Proj). // A texcoord attribute is also generated texcoord = [(0,0),(1,1)] static ShaderPointer getDrawTransformUnitQuadVS(); @@ -44,6 +47,7 @@ public: protected: + static ShaderPointer _drawUnitQuadTexcoordVS; static ShaderPointer _drawTransformUnitQuadVS; static ShaderPointer _drawTexcoordRectTransformUnitQuadVS; static ShaderPointer _drawViewportQuadTransformTexcoordVS; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 504070963d..983c2d44ba 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -37,15 +37,19 @@ void SetupDeferred::run(const SceneContextPointer& sceneContext, const RenderCon RenderArgs* args = renderContext->args; gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { + auto primaryFboStencil = DependencyManager::get()->getPrimaryFramebufferStencilColor(); auto primaryFbo = DependencyManager::get()->getPrimaryFramebufferDepthColor(); batch.enableStereo(false); - batch.setFramebuffer(nullptr); - batch.setFramebuffer(primaryFbo); - batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); + batch.setFramebuffer(primaryFboStencil); + batch.clearFramebuffer( + gpu::Framebuffer::BUFFER_STENCIL, + vec4(vec3(0), 1), 1.0, 0.0, true); + + batch.setFramebuffer(primaryFbo); batch.clearFramebuffer( gpu::Framebuffer::BUFFER_COLOR0 | gpu::Framebuffer::BUFFER_DEPTH, @@ -68,7 +72,6 @@ void ResolveDeferred::run(const SceneContextPointer& sceneContext, const RenderC RenderDeferredTask::RenderDeferredTask() : Task() { _jobs.push_back(Job(new SetupDeferred::JobModel("SetupFramebuffer"))); - // _jobs.push_back(Job(new DrawBackground::JobModel("DrawBackground"))); _jobs.push_back(Job(new PrepareDeferred::JobModel("PrepareDeferred"))); _jobs.push_back(Job(new FetchItems::JobModel("FetchOpaque", @@ -302,7 +305,7 @@ gpu::PipelinePointer DrawStencilDeferred::_opaquePipeline; const gpu::PipelinePointer& DrawStencilDeferred::getOpaquePipeline() { if (!_opaquePipeline) { const gpu::int8 STENCIL_OPAQUE = 1; - auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); + auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(drawOpaqueStencil_frag))); auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps)); @@ -329,7 +332,6 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren args->_batch = &batch; auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferStencilColor(); - auto primaryFboFull = DependencyManager::get()->getPrimaryFramebuffer(); auto primaryDepth = DependencyManager::get()->getPrimaryDepthTexture(); batch.enableStereo(false); @@ -337,11 +339,6 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren batch.setFramebuffer(primaryFboColorDepthStencil); batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); - batch.clearStencilFramebuffer(0, true); - - - Transform modelMat; - batch.setModelTransform(modelMat); batch.setPipeline(getOpaquePipeline()); batch.setResourceTexture(0, primaryDepth); @@ -349,8 +346,6 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren batch.draw(gpu::TRIANGLE_STRIP, 4); batch.setResourceTexture(0, nullptr); - batch.setFramebuffer(primaryFboFull); - }); args->_batch = nullptr; } From 690620d74d7889f831a078f18c26f81b7958d935 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 1 Oct 2015 19:23:32 -0700 Subject: [PATCH 9/9] Cleaning code --- libraries/gpu/src/gpu/GLBackendTexture.cpp | 7 ++----- libraries/model/src/model/Skybox.cpp | 2 +- libraries/render-utils/src/Environment.cpp | 2 -- libraries/render-utils/src/RenderDeferredTask.cpp | 1 - libraries/render-utils/src/drawOpaqueStencil.slf | 10 ++-------- 5 files changed, 5 insertions(+), 17 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index 044204934c..ee5e1d3bc6 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -360,11 +360,8 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) { if (bytes && texture.isAutogenerateMips()) { glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - }/* else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - }*/ - + } + object->_target = GL_TEXTURE_2D; syncSampler(texture.getSampler(), texture.getType(), object); diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index e516fae583..21b40a54c8 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -129,7 +129,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky batch.draw(gpu::TRIANGLE_STRIP, 4); - // batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, nullptr); + batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, nullptr); } diff --git a/libraries/render-utils/src/Environment.cpp b/libraries/render-utils/src/Environment.cpp index acb149a3cc..b26d402fa3 100644 --- a/libraries/render-utils/src/Environment.cpp +++ b/libraries/render-utils/src/Environment.cpp @@ -62,8 +62,6 @@ void Environment::setupAtmosphereProgram(const char* vertSource, const char* fra auto state = std::make_shared(); state->setCullMode(gpu::State::CULL_NONE); - // state->setDepthTest(false); - // state->setDepthTest(true, false, gpu::LESS_EQUAL); state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 983c2d44ba..0f79dc8b8d 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -314,7 +314,6 @@ const gpu::PipelinePointer& DrawStencilDeferred::getOpaquePipeline() { auto state = std::make_shared(); state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); - // state->setStencilTest(false, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_INCR, gpu::State::STENCIL_OP_INCR, gpu::State::STENCIL_OP_INCR)); state->setColorWriteMask(0); _opaquePipeline.reset(gpu::Pipeline::create(program, state)); diff --git a/libraries/render-utils/src/drawOpaqueStencil.slf b/libraries/render-utils/src/drawOpaqueStencil.slf index 883154c624..14feda21e9 100644 --- a/libraries/render-utils/src/drawOpaqueStencil.slf +++ b/libraries/render-utils/src/drawOpaqueStencil.slf @@ -13,18 +13,12 @@ // in vec2 varTexCoord0; -out vec4 outFragColor; uniform sampler2D depthTexture; void main(void) { - // outFragColor = vec4(varTexCoord0, 0.0, 1.0); - - float depth = texture(depthTexture, varTexCoord0.xy).r; - outFragColor = vec4(1.0, 0.0, 0.0, 1.0); - if (depth < 1.0) { - outFragColor = vec4(0.0, 1.0, 0.0, 1.0); - } else { + float depth = texture(depthTexture, varTexCoord0.xy).r; + if (depth >= 1.0) { discard; } }