From c34c5f60758039f4aaddb4aa4396d79dea09cd88 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 14 Apr 2015 08:47:52 -0700 Subject: [PATCH] adding the Fremabuffer to be used for shadows and main rendering --- interface/src/Application.cpp | 21 ++- libraries/gpu/src/gpu/Format.h | 3 +- libraries/gpu/src/gpu/Framebuffer.cpp | 8 ++ libraries/gpu/src/gpu/Framebuffer.h | 18 ++- libraries/gpu/src/gpu/GLBackendOutput.cpp | 5 +- libraries/gpu/src/gpu/GLBackendTexture.cpp | 34 +++++ .../src/DeferredLightingEffect.cpp | 23 +++- libraries/render-utils/src/GlowEffect.cpp | 23 +++- libraries/render-utils/src/Model.cpp | 125 ++++-------------- libraries/render-utils/src/TextureCache.cpp | 124 ++++++++++++++++- libraries/render-utils/src/TextureCache.h | 31 ++++- 11 files changed, 276 insertions(+), 139 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 82447257fb..3fe03476a3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -798,7 +798,8 @@ void Application::paintGL() { DependencyManager::get()->prepare(); // Viewport is assigned to the size of the framebuffer - QSize size = DependencyManager::get()->getPrimaryFramebufferObject()->size(); + // QSize size = DependencyManager::get()->getPrimaryFramebufferObject()->size(); + QSize size = DependencyManager::get()->getFrameBufferSize(); glViewport(0, 0, size.width(), size.height()); glMatrixMode(GL_MODELVIEW); @@ -2636,8 +2637,12 @@ void Application::updateShadowMap() { activeRenderingThread = QThread::currentThread(); PerformanceTimer perfTimer("shadowMap"); - QOpenGLFramebufferObject* fbo = DependencyManager::get()->getShadowFramebufferObject(); - fbo->bind(); +// QOpenGLFramebufferObject* fbo = DependencyManager::get()->getShadowFramebufferObject(); +// fbo->bind(); + auto shadowFramebuffer = DependencyManager::get()->getShadowFramebuffer(); + GLuint shadowFBO = gpu::GLBackend::getFramebufferID(shadowFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, shadowFBO); + glEnable(GL_DEPTH_TEST); glClear(GL_DEPTH_BUFFER_BIT); @@ -2653,16 +2658,18 @@ void Application::updateShadowMap() { loadViewFrustum(_myCamera, _viewFrustum); int matrixCount = 1; - int targetSize = fbo->width(); + //int targetSize = fbo->width(); + int sourceSize = shadowFramebuffer->getWidth(); + int targetSize = shadowFramebuffer->getWidth(); float targetScale = 1.0f; if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) { matrixCount = CASCADED_SHADOW_MATRIX_COUNT; - targetSize = fbo->width() / 2; + targetSize = sourceSize / 2; targetScale = 0.5f; } for (int i = 0; i < matrixCount; i++) { const glm::vec2& coord = MAP_COORDS[i]; - glViewport(coord.s * fbo->width(), coord.t * fbo->height(), targetSize, targetSize); + glViewport(coord.s * sourceSize, coord.t * sourceSize, targetSize, targetSize); // if simple shadow then since the resolution is twice as much as with cascaded, cover 2 regions with the map, not just one int regionIncrement = (matrixCount == 1 ? 2 : 1); @@ -2785,7 +2792,7 @@ void Application::updateShadowMap() { glMatrixMode(GL_MODELVIEW); } - fbo->release(); + // fbo->release(); glViewport(0, 0, _glWidget->getDeviceWidth(), _glWidget->getDeviceHeight()); activeRenderingThread = nullptr; diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h index aee6f3bdf4..d3330fd147 100644 --- a/libraries/gpu/src/gpu/Format.h +++ b/libraries/gpu/src/gpu/Format.h @@ -119,7 +119,8 @@ enum Semantic { INDEX, //used by index buffer of a mesh PART, // used by part buffer of a mesh - DEPTH, // Depth buffer + DEPTH, // Depth only buffer + STENCIL, // Stencil only buffer DEPTH_STENCIL, // Depth Stencil buffer SRGB, diff --git a/libraries/gpu/src/gpu/Framebuffer.cpp b/libraries/gpu/src/gpu/Framebuffer.cpp index cb33a930ca..f671dba28e 100755 --- a/libraries/gpu/src/gpu/Framebuffer.cpp +++ b/libraries/gpu/src/gpu/Framebuffer.cpp @@ -41,6 +41,14 @@ Framebuffer* Framebuffer::create( const Format& colorBufferFormat, const Format& return framebuffer; } +Framebuffer* Framebuffer::createShadowmap(uint16 width) { + auto framebuffer = Framebuffer::create(); + auto depthTexture = TexturePointer(Texture::create2D(Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH), width, width)); + + framebuffer->setDepthStencilBuffer(depthTexture, Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH)); + + return framebuffer; +} bool Framebuffer::isSwapchain() const { return _swapchain != 0; diff --git a/libraries/gpu/src/gpu/Framebuffer.h b/libraries/gpu/src/gpu/Framebuffer.h index 9253cd021e..8028d1b478 100755 --- a/libraries/gpu/src/gpu/Framebuffer.h +++ b/libraries/gpu/src/gpu/Framebuffer.h @@ -116,6 +116,7 @@ public: static Framebuffer* create(const SwapchainPointer& swapchain); static Framebuffer* create(); static Framebuffer* create(const Format& colorBufferFormat, const Format& depthStencilBufferFormat, uint16 width, uint16 height, uint16 samples ); + static Framebuffer* createShadowmap(uint16 width); bool isSwapchain() const; SwapchainPointer getSwapchain() const { return _swapchain; } @@ -136,6 +137,7 @@ public: uint32 getDepthStencilBufferSubresource() const; Format getDepthStencilBufferFormat() const; + // Properties uint32 getBufferMask() const { return _bufferMask; } bool isEmpty() const { return (_bufferMask == 0); } @@ -157,26 +159,22 @@ public: static uint32 getMaxNumRenderBuffers() { return MAX_NUM_RENDER_BUFFERS; } // Get viewport covering the ful Canvas - Viewport getViewport() const { return Viewport(getWidth(), getHeight(), 0, 0); } - - bool isDefined() const { return _isDefined; } + Viewport getViewport() const { return Viewport(getWidth(), getHeight(), 0, 0); } protected: - uint16 _width; - uint16 _height; - uint16 _numSamples; + uint16 _width = 0; + uint16 _height = 0; + uint16 _numSamples = 0; - uint32 _bufferMask; + uint32 _bufferMask = 0; - uint32 _frameCount; + uint32 _frameCount = 0; SwapchainPointer _swapchain; TextureViews _renderBuffers; TextureView _depthStencilBuffer; - bool _isDefined = false; - void updateSize(const TexturePointer& texture); // Non exposed diff --git a/libraries/gpu/src/gpu/GLBackendOutput.cpp b/libraries/gpu/src/gpu/GLBackendOutput.cpp index 877ecce950..9b3fb5fe34 100755 --- a/libraries/gpu/src/gpu/GLBackendOutput.cpp +++ b/libraries/gpu/src/gpu/GLBackendOutput.cpp @@ -28,7 +28,7 @@ GLBackend::GLFramebuffer* GLBackend::syncGPUObject(const Framebuffer& framebuffe bool needUpdate = false; if (object) { return object; - } else if (!framebuffer.isDefined()) { + } else if (framebuffer.isEmpty()) { // NO framebuffer definition yet so let's avoid thinking return nullptr; } @@ -39,7 +39,7 @@ GLBackend::GLFramebuffer* GLBackend::syncGPUObject(const Framebuffer& framebuffe glGenFramebuffers(1, &fbo); CHECK_GL_ERROR(); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); unsigned int nbColorBuffers = 0; GLenum colorBuffers[16]; @@ -82,7 +82,6 @@ GLBackend::GLFramebuffer* GLBackend::syncGPUObject(const Framebuffer& framebuffe if (surface) { auto gltexture = GLBackend::syncGPUObject(*surface); if (gltexture) { - if (surface) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, gltexture->_texture, 0); } } diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index 2bbb3d633f..da6d993171 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -144,7 +144,38 @@ public: texel.internalFormat = GL_RED; break; case gpu::DEPTH: + texel.format = GL_DEPTH_COMPONENT; // It's depth component to load it texel.internalFormat = GL_DEPTH_COMPONENT; + switch (dstFormat.getType()) { + case gpu::UINT32: + case gpu::INT32: + case gpu::NUINT32: + case gpu::NINT32: { + texel.internalFormat = GL_DEPTH_COMPONENT32; + break; + } + case gpu::NFLOAT: + case gpu::FLOAT: { + texel.internalFormat = GL_DEPTH_COMPONENT32F; + break; + } + case gpu::UINT16: + case gpu::INT16: + case gpu::NUINT16: + case gpu::NINT16: + case gpu::HALF: + case gpu::NHALF: { + texel.internalFormat = GL_DEPTH_COMPONENT16; + break; + } + case gpu::UINT8: + case gpu::INT8: + case gpu::NUINT8: + case gpu::NINT8: { + texel.internalFormat = GL_DEPTH_COMPONENT24; + break; + } + } break; default: qCDebug(gpulogging) << "Unknown combination of texel format"; @@ -306,6 +337,9 @@ 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); } // At this point the mip piels have been loaded, we can notify diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index a4f45802a4..c5a09a4f0f 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -183,15 +183,17 @@ void DeferredLightingEffect::render() { auto textureCache = DependencyManager::get(); - QOpenGLFramebufferObject* primaryFBO = textureCache->getPrimaryFramebufferObject(); - primaryFBO->release(); + // QOpenGLFramebufferObject* primaryFBO = textureCache->getPrimaryFramebufferObject(); + // primaryFBO->release(); + QSize framebufferSize = textureCache->getFrameBufferSize(); QOpenGLFramebufferObject* freeFBO = DependencyManager::get()->getFreeFramebufferObject(); freeFBO->bind(); glClear(GL_COLOR_BUFFER_BIT); // glEnable(GL_FRAMEBUFFER_SRGB); - glBindTexture(GL_TEXTURE_2D, primaryFBO->texture()); + // glBindTexture(GL_TEXTURE_2D, primaryFBO->texture()); + glBindTexture(GL_TEXTURE_2D, textureCache->getPrimaryColorTextureID()); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textureCache->getPrimaryNormalTextureID()); @@ -209,11 +211,17 @@ void DeferredLightingEffect::render() { const int VIEWPORT_Y_INDEX = 1; const int VIEWPORT_WIDTH_INDEX = 2; const int VIEWPORT_HEIGHT_INDEX = 3; - float sMin = viewport[VIEWPORT_X_INDEX] / (float)primaryFBO->width(); + /* float sMin = viewport[VIEWPORT_X_INDEX] / (float)primaryFBO->width(); float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)primaryFBO->width(); float tMin = viewport[VIEWPORT_Y_INDEX] / (float)primaryFBO->height(); float tHeight = viewport[VIEWPORT_HEIGHT_INDEX] / (float)primaryFBO->height(); - + */ + float sMin = viewport[VIEWPORT_X_INDEX] / (float)framebufferSize.width(); + float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)framebufferSize.width(); + float tMin = viewport[VIEWPORT_Y_INDEX] / (float)framebufferSize.height(); + float tHeight = viewport[VIEWPORT_HEIGHT_INDEX] / (float)framebufferSize.height(); + + // Fetch the ViewMatrix; glm::mat4 invViewMat; _viewState->getViewTransform().getMatrix(invViewMat); @@ -437,7 +445,10 @@ void DeferredLightingEffect::render() { glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); glColorMask(true, true, true, false); - primaryFBO->bind(); + auto primaryFBO = gpu::GLBackend::getFramebufferID(textureCache->getPrimaryOpaqueFramebuffer()); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, primaryFBO); + + //primaryFBO->bind(); glBindTexture(GL_TEXTURE_2D, freeFBO->texture()); glEnable(GL_TEXTURE_2D); diff --git a/libraries/render-utils/src/GlowEffect.cpp b/libraries/render-utils/src/GlowEffect.cpp index 2ba1d7df13..2399cfa1a7 100644 --- a/libraries/render-utils/src/GlowEffect.cpp +++ b/libraries/render-utils/src/GlowEffect.cpp @@ -24,6 +24,7 @@ #include "TextureCache.h" #include "RenderUtilsLogging.h" +#include "gpu/GLBackend.h" GlowEffect::GlowEffect() : _initialized(false), @@ -105,7 +106,11 @@ int GlowEffect::getDeviceHeight() const { void GlowEffect::prepare() { - DependencyManager::get()->getPrimaryFramebufferObject()->bind(); + //DependencyManager::get()->getPrimaryFramebufferObject()->bind(); + auto primaryFBO = DependencyManager::get()->getPrimaryOpaqueFramebuffer(); + GLuint fbo = gpu::GLBackend::getFramebufferID(primaryFBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); _isEmpty = true; @@ -140,9 +145,11 @@ QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) { PerformanceTimer perfTimer("glowEffect"); auto textureCache = DependencyManager::get(); - QOpenGLFramebufferObject* primaryFBO = textureCache->getPrimaryFramebufferObject(); - primaryFBO->release(); - glBindTexture(GL_TEXTURE_2D, primaryFBO->texture()); + // QOpenGLFramebufferObject* primaryFBO = textureCache->getPrimaryFramebufferObject(); + // primaryFBO->release(); + auto primaryFBO = gpu::GLBackend::getFramebufferID(textureCache->getPrimaryOpaqueFramebuffer()); + glBindTexture(GL_TEXTURE_2D, textureCache->getPrimaryColorTextureID()); + auto framebufferSize = textureCache->getFrameBufferSize(); glPushMatrix(); glLoadIdentity(); @@ -160,7 +167,10 @@ QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) { if (!_enabled || _isEmpty) { // copy the primary to the screen if (destFBO && QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()) { - QOpenGLFramebufferObject::blitFramebuffer(destFBO, primaryFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER, primaryFBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, destFBO->handle()); + glBlitFramebuffer(0, 0, framebufferSize.width(), framebufferSize.height(), 0, 0, framebufferSize.width(), framebufferSize.height(), GL_COLOR_BUFFER_BIT, GL_NEAREST); + // QOpenGLFramebufferObject::blitFramebuffer(destFBO, primaryFBO); } else { maybeBind(destFBO); if (!destFBO) { @@ -192,7 +202,8 @@ QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) { glBindTexture(GL_TEXTURE_2D, oldDiffusedFBO->texture()); _diffuseProgram->bind(); - QSize size = primaryFBO->size(); + //QSize size = primaryFBO->size(); + QSize size = framebufferSize; _diffuseProgram->setUniformValue(_diffusionScaleLocation, 1.0f / size.width(), 1.0f / size.height()); renderFullscreenQuad(); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index b98123803f..bddbc2a0ff 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -673,8 +673,6 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) { return false; } - // auto glowEffectIntensity = DependencyManager::get()->getIntensity(); - // Let's introduce a gpu::Batch to capture all the calls to the graphics api _renderBatch.clear(); gpu::Batch& batch = _renderBatch; @@ -703,35 +701,12 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) { batch.setViewTransform(_transforms[0]); - // GLBATCH(glDisable)(GL_COLOR_MATERIAL); - - // taking care of by the state? - /* if (mode == RenderArgs::DIFFUSE_RENDER_MODE || mode == RenderArgs::NORMAL_RENDER_MODE) { - GLBATCH(glDisable)(GL_CULL_FACE); - } else { - GLBATCH(glEnable)(GL_CULL_FACE); - if (mode == RenderArgs::SHADOW_RENDER_MODE) { - GLBATCH(glCullFace)(GL_FRONT); - } - } - */ - - // render opaque meshes with alpha testing - -// GLBATCH(glDisable)(GL_BLEND); -// GLBATCH(glEnable)(GL_ALPHA_TEST); - - /* if (mode == RenderArgs::SHADOW_RENDER_MODE) { - GLBATCH(glAlphaFunc)(GL_EQUAL, 0.0f); - } - */ - /*DependencyManager::get()->setPrimaryDrawBuffers( mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::DIFFUSE_RENDER_MODE, mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::NORMAL_RENDER_MODE, mode == RenderArgs::DEFAULT_RENDER_MODE); */ - { + /*if (mode != RenderArgs::SHADOW_RENDER_MODE)*/ { GLenum buffers[3]; int bufferCount = 0; @@ -748,6 +723,7 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) { buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; } GLBATCH(glDrawBuffers)(bufferCount, buffers); + // batch.setFramebuffer(DependencyManager::get()->getPrimaryOpaqueFramebuffer()); } const float DEFAULT_ALPHA_THRESHOLD = 0.5f; @@ -790,12 +766,6 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) { translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, false, args, true); translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, true, args, true); - // GLBATCH(glDisable)(GL_ALPHA_TEST); - /* GLBATCH(glEnable)(GL_BLEND); - GLBATCH(glDepthMask)(false); - GLBATCH(glDepthFunc)(GL_LEQUAL); - */ - //DependencyManager::get()->setPrimaryDrawBuffers(true); { GLenum buffers[1]; int bufferCount = 0; @@ -805,6 +775,8 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) { // if (mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::DIFFUSE_RENDER_MODE) { if (mode != RenderArgs::SHADOW_RENDER_MODE) { + // batch.setFramebuffer(DependencyManager::get()->getPrimaryTransparentFramebuffer()); + const float MOSTLY_TRANSPARENT_THRESHOLD = 0.0f; translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, false, args, true); translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, true, args, true); @@ -814,6 +786,8 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) { translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, true, args, true); translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, false, args, true); translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, true, args, true); + + // batch.setFramebuffer(DependencyManager::get()->getPrimaryOpaqueFramebuffer()); } GLBATCH(glDepthMask)(true); @@ -1758,14 +1732,6 @@ void Model::setupBatchTransform(gpu::Batch& batch, RenderArgs* args) { void Model::endScene(RenderMode mode, RenderArgs* args) { PROFILE_RANGE(__FUNCTION__); - // auto glowEffectIntensity = DependencyManager::get()->getIntensity(); - - - #if defined(ANDROID) - #else - glPushMatrix(); - #endif - RenderArgs::RenderSide renderSide = RenderArgs::MONO; if (args) { renderSide = args->_renderSide; @@ -1792,34 +1758,15 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { _sceneRenderBatch.clear(); gpu::Batch& batch = _sceneRenderBatch; - // GLBATCH(glDisable)(GL_COLOR_MATERIAL); - - /* if (mode == RenderArgs::DIFFUSE_RENDER_MODE || mode == RenderArgs::NORMAL_RENDER_MODE) { - GLBATCH(glDisable)(GL_CULL_FACE); - } else { - GLBATCH(glEnable)(GL_CULL_FACE); - if (mode == RenderArgs::SHADOW_RENDER_MODE) { - GLBATCH(glCullFace)(GL_FRONT); - } - }*/ - - // render opaque meshes with alpha testing - - // GLBATCH(glDisable)(GL_BLEND); - // GLBATCH(glEnable)(GL_ALPHA_TEST); - - /* if (mode == RenderArgs::SHADOW_RENDER_MODE) { - GLBATCH(glAlphaFunc)(GL_EQUAL, 0.0f); - } -*/ - /*DependencyManager::get()->setPrimaryDrawBuffers( mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::DIFFUSE_RENDER_MODE, mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::NORMAL_RENDER_MODE, mode == RenderArgs::DEFAULT_RENDER_MODE); */ - { + + /* if (mode != RenderArgs::SHADOW_RENDER_MODE) */{ GLenum buffers[3]; + int bufferCount = 0; // if (mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::DIFFUSE_RENDER_MODE) { if (mode != RenderArgs::SHADOW_RENDER_MODE) { @@ -1834,6 +1781,8 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; } GLBATCH(glDrawBuffers)(bufferCount, buffers); + + // batch.setFramebuffer(DependencyManager::get()->getPrimaryOpaqueFramebuffer()); } const float DEFAULT_ALPHA_THRESHOLD = 0.5f; @@ -1856,7 +1805,6 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, false, args); // render translucent meshes afterwards - //DependencyManager::get()->setPrimaryDrawBuffers(false, true, true); { GLenum buffers[2]; int bufferCount = 0; @@ -1876,21 +1824,19 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, false, args); translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, true, args); - // GLBATCH(glDisable)(GL_ALPHA_TEST); - /* GLBATCH(glEnable)(GL_BLEND); - GLBATCH(glDepthMask)(false); - GLBATCH(glDepthFunc)(GL_LEQUAL); - */ - //DependencyManager::get()->setPrimaryDrawBuffers(true); + { GLenum buffers[1]; int bufferCount = 0; buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; GLBATCH(glDrawBuffers)(bufferCount, buffers); + // batch.setFramebuffer(DependencyManager::get()->getPrimaryTransparentFramebuffer()); } // if (mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::DIFFUSE_RENDER_MODE) { if (mode != RenderArgs::SHADOW_RENDER_MODE) { + // batch.setFramebuffer(DependencyManager::get()->getPrimaryTransparentFramebuffer()); + const float MOSTLY_TRANSPARENT_THRESHOLD = 0.0f; translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, false, args); translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, true, args); @@ -1900,6 +1846,8 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, true, args); translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, false, args); translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, true, args); + + // batch.setFramebuffer(DependencyManager::get()->getPrimaryOpaqueFramebuffer()); } GLBATCH(glDepthMask)(true); @@ -1938,10 +1886,10 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { // Back to no program GLBATCH(glUseProgram)(0); - if (args) { - args->_translucentMeshPartsRendered = translucentParts; - args->_opaqueMeshPartsRendered = opaqueMeshPartsRendered; - } + if (args) { + args->_translucentMeshPartsRendered = translucentParts; + args->_opaqueMeshPartsRendered = opaqueMeshPartsRendered; + } } @@ -1951,12 +1899,6 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { backend.render(_sceneRenderBatch); } - - #if defined(ANDROID) - #else - glPopMatrix(); - #endif - // restore all the default material settings _viewState->setupWorldLight(); @@ -2334,17 +2276,15 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f RenderKey key(mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned); auto pipeline = _renderPipelineLib.find(key.getRaw()); if (pipeline == _renderPipelineLib.end()) { - qDebug() << "No good, couldn;t find a pipeline from the key ?" << key.getRaw(); + qDebug() << "No good, couldn't find a pipeline from the key ?" << key.getRaw(); return; } gpu::ShaderPointer program = (*pipeline).second._pipeline->getProgram(); locations = (*pipeline).second._locations.get(); - //GLuint glprogram = gpu::GLBackend::getShaderID(program); - //GLBATCH(glUseProgram)(glprogram); - // dare! + // Setup the One pipeline batch.setPipeline((*pipeline).second._pipeline); if ((locations->alphaThreshold > -1) && (mode != RenderArgs::SHADOW_RENDER_MODE)) { @@ -2354,9 +2294,6 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f if ((locations->glowIntensity > -1) && (mode != RenderArgs::SHADOW_RENDER_MODE)) { GLBATCH(glUniform1f)(locations->glowIntensity, DependencyManager::get()->getIntensity()); } - // if (!(translucent && alphaThreshold == 0.0f) && (mode != RenderArgs::SHADOW_RENDER_MODE)) { - // GLBATCH(glAlphaFunc)(GL_EQUAL, DependencyManager::get()->getIntensity()); - // } } int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, @@ -2383,10 +2320,7 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool } } } - // if we selected a program, then unselect it - if (!pickProgramsNeeded) { - // GLBATCH(glUseProgram)(0); - } + return meshPartsRendered; } @@ -2415,8 +2349,6 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl args, locations); meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, args, locations, forceRenderSomeMeshes); - // GLBATCH(glUseProgram)(0); - return meshPartsRendered; } @@ -2427,7 +2359,7 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod PROFILE_RANGE(__FUNCTION__); auto textureCache = DependencyManager::get(); - // auto glowEffect = DependencyManager::get(); + QString lastMaterialID; int meshPartsRendered = 0; updateVisibleJointStates(); @@ -2531,13 +2463,6 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod qCDebug(renderutils) << "NEW part.materialID:" << part.materialID; } -/* if (locations->glowIntensity >= 0) { - GLBATCH(glUniform1f)(locations->glowIntensity, glowEffect->getIntensity()); - } - if (!(translucent && alphaThreshold == 0.0f)) { - GLBATCH(glAlphaFunc)(GL_EQUAL, glowEffect->getIntensity()); - } -*/ if (locations->materialBufferUnit >= 0) { batch.setUniformBuffer(locations->materialBufferUnit, material->getSchemaBuffer()); } diff --git a/libraries/render-utils/src/TextureCache.cpp b/libraries/render-utils/src/TextureCache.cpp index 9b2a458231..28da6977f2 100644 --- a/libraries/render-utils/src/TextureCache.cpp +++ b/libraries/render-utils/src/TextureCache.cpp @@ -72,6 +72,15 @@ void TextureCache::setFrameBufferSize(QSize frameBufferSize) { if (_frameBufferSize != frameBufferSize) { _frameBufferSize = frameBufferSize; + if (_primaryOpaqueFramebuffer) { + _primaryOpaqueFramebuffer.reset(); + _primaryTransparentFramebuffer.reset(); + _primaryDepthTexture.reset(); + _primaryColorTexture.reset(); + _primaryNormalTexture.reset(); + _primarySpecularTexture.reset(); + } + if (_primaryFramebufferObject) { delete _primaryFramebufferObject; _primaryFramebufferObject = NULL; @@ -243,20 +252,95 @@ QOpenGLFramebufferObject* TextureCache::getPrimaryFramebufferObject() { return _primaryFramebufferObject; } +void TextureCache::createPrimaryFramebuffer() { + _primaryOpaqueFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); + _primaryTransparentFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); + + auto colorFormat = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); + auto width = _frameBufferSize.width(); + auto height = _frameBufferSize.height(); + _primaryColorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height)); + _primaryNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height)); + _primarySpecularTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height)); + + _primaryOpaqueFramebuffer->setRenderBuffer(0, _primaryColorTexture); + _primaryOpaqueFramebuffer->setRenderBuffer(1, _primaryNormalTexture); + _primaryOpaqueFramebuffer->setRenderBuffer(2, _primarySpecularTexture); + + _primaryTransparentFramebuffer->setRenderBuffer(0, _primaryColorTexture); + + auto depthFormat = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH); + _primaryDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, width, height)); + + _primaryOpaqueFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); + + _primaryTransparentFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); +} + +gpu::FramebufferPointer TextureCache::getPrimaryOpaqueFramebuffer() { + if (!_primaryOpaqueFramebuffer) { + createPrimaryFramebuffer(); + } + return _primaryOpaqueFramebuffer; +} + +gpu::FramebufferPointer TextureCache::getPrimaryTransparentFramebuffer() { + if (!_primaryTransparentFramebuffer) { + createPrimaryFramebuffer(); + } + return _primaryTransparentFramebuffer; +} + +gpu::TexturePointer TextureCache::getPrimaryDepthTexture() { + if (!_primaryDepthTexture) { + createPrimaryFramebuffer(); + } + return _primaryDepthTexture; +} + +gpu::TexturePointer TextureCache::getPrimaryColorTexture() { + if (!_primaryColorTexture) { + createPrimaryFramebuffer(); + } + return _primaryColorTexture; +} + +gpu::TexturePointer TextureCache::getPrimaryNormalTexture() { + if (!_primaryNormalTexture) { + createPrimaryFramebuffer(); + } + return _primaryNormalTexture; +} + +gpu::TexturePointer TextureCache::getPrimarySpecularTexture() { + if (!_primarySpecularTexture) { + createPrimaryFramebuffer(); + } + return _primarySpecularTexture; +} + GLuint TextureCache::getPrimaryDepthTextureID() { // ensure that the primary framebuffer object is initialized before returning the depth texture id - getPrimaryFramebufferObject(); + //getPrimaryFramebufferObject(); + + _primaryDepthTextureID = gpu::GLBackend::getTextureID(_primaryDepthTexture); return _primaryDepthTextureID; } +GLuint TextureCache::getPrimaryColorTextureID() { + return gpu::GLBackend::getTextureID(_primaryColorTexture); +} + GLuint TextureCache::getPrimaryNormalTextureID() { // ensure that the primary framebuffer object is initialized before returning the normal texture id - getPrimaryFramebufferObject(); + //getPrimaryFramebufferObject(); + _primaryNormalTextureID = gpu::GLBackend::getTextureID(_primaryNormalTexture); return _primaryNormalTextureID; } GLuint TextureCache::getPrimarySpecularTextureID() { - getPrimaryFramebufferObject(); + //getPrimaryFramebufferObject(); + _primarySpecularTextureID = gpu::GLBackend::getTextureID(_primarySpecularTexture); return _primarySpecularTextureID; } @@ -289,6 +373,36 @@ QOpenGLFramebufferObject* TextureCache::getTertiaryFramebufferObject() { return _tertiaryFramebufferObject; } + +gpu::FramebufferPointer TextureCache::getShadowFramebuffer() { + if (!_shadowFramebuffer) { + const int SHADOW_MAP_SIZE = 2048; + _shadowFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::createShadowmap(SHADOW_MAP_SIZE)); + + _shadowTexture = _shadowFramebuffer->getDepthStencilBuffer(); + /* + glGenTextures(1, &_shadowDepthTextureID); + glBindTexture(GL_TEXTURE_2D, _shadowDepthTextureID); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, SHADOW_MAP_SIZE, SHADOW_MAP_SIZE, + 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + const float DISTANT_BORDER[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, DISTANT_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + glBindTexture(GL_TEXTURE_2D, 0); + + _shadowFramebufferObject->bind(); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _shadowDepthTextureID, 0); + _shadowFramebufferObject->release(); + */ + } + return _shadowFramebuffer; +} + QOpenGLFramebufferObject* TextureCache::getShadowFramebufferObject() { if (!_shadowFramebufferObject) { const int SHADOW_MAP_SIZE = 2048; @@ -318,7 +432,9 @@ QOpenGLFramebufferObject* TextureCache::getShadowFramebufferObject() { GLuint TextureCache::getShadowDepthTextureID() { // ensure that the shadow framebuffer object is initialized before returning the depth texture id - getShadowFramebufferObject(); + //getShadowFramebufferObject(); + _shadowDepthTextureID = gpu::GLBackend::getTextureID(_shadowTexture); + return _shadowDepthTextureID; } diff --git a/libraries/render-utils/src/TextureCache.h b/libraries/render-utils/src/TextureCache.h index 3ea46a4421..0d0cfc40aa 100644 --- a/libraries/render-utils/src/TextureCache.h +++ b/libraries/render-utils/src/TextureCache.h @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -62,9 +63,18 @@ public: /// used for scene rendering. QOpenGLFramebufferObject* getPrimaryFramebufferObject(); + gpu::FramebufferPointer getPrimaryOpaqueFramebuffer(); + gpu::FramebufferPointer getPrimaryTransparentFramebuffer(); + + gpu::TexturePointer getPrimaryDepthTexture(); + gpu::TexturePointer getPrimaryColorTexture(); + gpu::TexturePointer getPrimaryNormalTexture(); + gpu::TexturePointer getPrimarySpecularTexture(); + /// Returns the ID of the primary framebuffer object's depth texture. This contains the Z buffer used in rendering. GLuint getPrimaryDepthTextureID(); - + GLuint getPrimaryColorTextureID(); + /// Returns the ID of the primary framebuffer object's normal texture. GLuint getPrimaryNormalTextureID(); @@ -78,6 +88,7 @@ public: /// screen effects. QOpenGLFramebufferObject* getSecondaryFramebufferObject(); + /// Returns a pointer to the tertiary framebuffer object, used as an additional render target when performing full /// screen effects. QOpenGLFramebufferObject* getTertiaryFramebufferObject(); @@ -85,6 +96,9 @@ public: /// Returns a pointer to the framebuffer object used to render shadow maps. QOpenGLFramebufferObject* getShadowFramebufferObject(); + gpu::FramebufferPointer getShadowFramebuffer(); + + /// Returns the ID of the shadow framebuffer object's depth texture. GLuint getShadowDepthTextureID(); @@ -105,9 +119,18 @@ private: gpu::TexturePointer _permutationNormalTexture; gpu::TexturePointer _whiteTexture; gpu::TexturePointer _blueTexture; + QHash > _dilatableNetworkTextures; - + + gpu::TexturePointer _primaryDepthTexture; + gpu::TexturePointer _primaryColorTexture; + gpu::TexturePointer _primaryNormalTexture; + gpu::TexturePointer _primarySpecularTexture; + gpu::FramebufferPointer _primaryOpaqueFramebuffer; + gpu::FramebufferPointer _primaryTransparentFramebuffer; + void createPrimaryFramebuffer(); + GLuint _primaryDepthTextureID; GLuint _primaryNormalTextureID; GLuint _primarySpecularTextureID; @@ -115,9 +138,13 @@ private: QOpenGLFramebufferObject* _secondaryFramebufferObject; QOpenGLFramebufferObject* _tertiaryFramebufferObject; + QOpenGLFramebufferObject* _shadowFramebufferObject; GLuint _shadowDepthTextureID; + gpu::FramebufferPointer _shadowFramebuffer; + gpu::TexturePointer _shadowTexture; + QSize _frameBufferSize; QGLWidget* _associatedWidget; };