267 lines · 9.6 KB · C++
RawDownload
////  FramebufferCache.cpp//  interface/src/renderer////  Created by Andrzej Kapolka on 8/6/13.//  Copyright 2013 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 "FramebufferCache.h" #include <mutex> #include <glm/glm.hpp> #include <QMap>#include <QQueue>#include <gpu/Batch.h>#include "RenderUtilsLogging.h" static QQueue<gpu::FramebufferPointer> _cachedFramebuffers; FramebufferCache::FramebufferCache() {} FramebufferCache::~FramebufferCache() {    _cachedFramebuffers.clear();} void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) {    //If the size changed, we need to delete our FBOs    if (_frameBufferSize != frameBufferSize) {        _frameBufferSize = frameBufferSize;        _primaryFramebuffer.reset();        _primaryDepthTexture.reset();        _primaryColorTexture.reset();        _deferredFramebuffer.reset();        _deferredFramebufferDepthColor.reset();        _deferredColorTexture.reset();        _deferredNormalTexture.reset();        _deferredSpecularTexture.reset();        _selfieFramebuffer.reset();        _cachedFramebuffers.clear();        _lightingTexture.reset();        _lightingFramebuffer.reset();        _depthPyramidFramebuffer.reset();        _depthPyramidTexture.reset();        _occlusionFramebuffer.reset();        _occlusionTexture.reset();        _occlusionBlurredFramebuffer.reset();        _occlusionBlurredTexture.reset();    }} void FramebufferCache::createPrimaryFramebuffer() {    _primaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());    _deferredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());    _deferredFramebufferDepthColor = gpu::FramebufferPointer(gpu::Framebuffer::create());     auto colorFormat = gpu::Element::COLOR_RGBA_32;    auto width = _frameBufferSize.width();    auto height = _frameBufferSize.height();     auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);    _primaryColorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));     _primaryFramebuffer->setRenderBuffer(0, _primaryColorTexture);     _deferredColorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));    _deferredNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));    _deferredSpecularTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));     _deferredFramebuffer->setRenderBuffer(0, _deferredColorTexture);    _deferredFramebuffer->setRenderBuffer(1, _deferredNormalTexture);    _deferredFramebuffer->setRenderBuffer(2, _deferredSpecularTexture);     _deferredFramebufferDepthColor->setRenderBuffer(0, _deferredColorTexture);   //  auto depthFormat = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH);    auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format    _primaryDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, width, height, defaultSampler));     _primaryFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);     _deferredFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);     _deferredFramebufferDepthColor->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);      _selfieFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());    auto tex = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width * 0.5, height * 0.5, defaultSampler));    _selfieFramebuffer->setRenderBuffer(0, tex);     auto smoothSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR);     // FIXME: Decide on the proper one, let s stick to R11G11B10 for now    //_lightingTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, defaultSampler));    _lightingTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::R11G11B10), width, height, defaultSampler));    //_lightingTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::HALF, gpu::RGBA), width, height, defaultSampler));    _lightingFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());    _lightingFramebuffer->setRenderBuffer(0, _lightingTexture);    _lightingFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);      // For AO:    _depthPyramidTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RGB), width, height, smoothSampler));    _depthPyramidFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());    _depthPyramidFramebuffer->setRenderBuffer(0, _depthPyramidTexture);    _depthPyramidFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);            _occlusionTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGB), width, height, defaultSampler));    _occlusionFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());    _occlusionFramebuffer->setRenderBuffer(0, _occlusionTexture);    _occlusionFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);            _occlusionBlurredTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGB), width, height, defaultSampler));    _occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());    _occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture);    _occlusionBlurredFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); } gpu::FramebufferPointer FramebufferCache::getPrimaryFramebuffer() {    if (!_primaryFramebuffer) {        createPrimaryFramebuffer();    }    return _primaryFramebuffer;} gpu::TexturePointer FramebufferCache::getPrimaryDepthTexture() {    if (!_primaryDepthTexture) {        createPrimaryFramebuffer();    }    return _primaryDepthTexture;} gpu::TexturePointer FramebufferCache::getPrimaryColorTexture() {    if (!_primaryColorTexture) {        createPrimaryFramebuffer();    }    return _primaryColorTexture;} gpu::FramebufferPointer FramebufferCache::getDeferredFramebuffer() {    if (!_deferredFramebuffer) {        createPrimaryFramebuffer();    }    return _deferredFramebuffer;} gpu::FramebufferPointer FramebufferCache::getDeferredFramebufferDepthColor() {    if (!_deferredFramebufferDepthColor) {        createPrimaryFramebuffer();    }    return _deferredFramebufferDepthColor;} gpu::TexturePointer FramebufferCache::getDeferredColorTexture() {    if (!_deferredColorTexture) {        createPrimaryFramebuffer();    }    return _deferredColorTexture;} gpu::TexturePointer FramebufferCache::getDeferredNormalTexture() {    if (!_deferredNormalTexture) {        createPrimaryFramebuffer();    }    return _deferredNormalTexture;} gpu::TexturePointer FramebufferCache::getDeferredSpecularTexture() {    if (!_deferredSpecularTexture) {        createPrimaryFramebuffer();    }    return _deferredSpecularTexture;} gpu::FramebufferPointer FramebufferCache::getLightingFramebuffer() {    if (!_lightingFramebuffer) {        createPrimaryFramebuffer();    }    return _lightingFramebuffer;} gpu::TexturePointer FramebufferCache::getLightingTexture() {    if (!_lightingTexture) {        createPrimaryFramebuffer();    }    return _lightingTexture;} gpu::FramebufferPointer FramebufferCache::getFramebuffer() {    if (_cachedFramebuffers.isEmpty()) {        _cachedFramebuffers.push_back(gpu::FramebufferPointer(gpu::Framebuffer::create(gpu::Element::COLOR_RGBA_32, _frameBufferSize.width(), _frameBufferSize.height())));    }    gpu::FramebufferPointer result = _cachedFramebuffers.front();    _cachedFramebuffers.pop_front();    return result;} void FramebufferCache::releaseFramebuffer(const gpu::FramebufferPointer& framebuffer) {    if (QSize(framebuffer->getSize().x, framebuffer->getSize().y) == _frameBufferSize) {        _cachedFramebuffers.push_back(framebuffer);    }} gpu::FramebufferPointer FramebufferCache::getShadowFramebuffer() {    if (!_shadowFramebuffer) {        const int SHADOW_MAP_SIZE = 2048;        _shadowFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::createShadowmap(SHADOW_MAP_SIZE));    }    return _shadowFramebuffer;} gpu::FramebufferPointer FramebufferCache::getSelfieFramebuffer() {    if (!_selfieFramebuffer) {        createPrimaryFramebuffer();    }    return _selfieFramebuffer;} gpu::FramebufferPointer FramebufferCache::getDepthPyramidFramebuffer() {    if (!_depthPyramidFramebuffer) {        createPrimaryFramebuffer();    }    return _depthPyramidFramebuffer;} gpu::TexturePointer FramebufferCache::getDepthPyramidTexture() {    if (!_depthPyramidTexture) {        createPrimaryFramebuffer();    }    return _depthPyramidTexture;} gpu::FramebufferPointer FramebufferCache::getOcclusionFramebuffer() {    if (!_occlusionFramebuffer) {        createPrimaryFramebuffer();    }    return _occlusionFramebuffer;} gpu::TexturePointer FramebufferCache::getOcclusionTexture() {    if (!_occlusionTexture) {        createPrimaryFramebuffer();    }    return _occlusionTexture;} gpu::FramebufferPointer FramebufferCache::getOcclusionBlurredFramebuffer() {    if (!_occlusionBlurredFramebuffer) {        createPrimaryFramebuffer();    }    return _occlusionBlurredFramebuffer;} gpu::TexturePointer FramebufferCache::getOcclusionBlurredTexture() {    if (!_occlusionBlurredTexture) {        createPrimaryFramebuffer();    }    return _occlusionBlurredTexture;}