Breaking framebuffer ops out of texture cache

This commit is contained in:
Brad Davis 2015-07-20 17:26:26 -07:00
parent 94d57a2e43
commit c3a2b72c13
10 changed files with 236 additions and 236 deletions

View file

@ -59,6 +59,7 @@
#include <DependencyManager.h>
#include <EntityScriptingInterface.h>
#include <ErrorDialog.h>
#include <FramebufferCache.h>
#include <gpu/Batch.h>
#include <gpu/Context.h>
#include <gpu/GLBackend.h>
@ -85,6 +86,7 @@
#include <SettingHandle.h>
#include <SimpleAverage.h>
#include <SoundCache.h>
#include <TextureCache.h>
#include <Tooltip.h>
#include <UserActivityLogger.h>
#include <UUID.h>
@ -263,6 +265,8 @@ bool setupEssentials(int& argc, char** argv) {
auto audioScope = DependencyManager::set<AudioScope>();
auto deferredLightingEffect = DependencyManager::set<DeferredLightingEffect>();
auto textureCache = DependencyManager::set<TextureCache>();
auto framebufferCache = DependencyManager::set<FramebufferCache>();
auto animationCache = DependencyManager::set<AnimationCache>();
auto ddeFaceTracker = DependencyManager::set<DdeFaceTracker>();
auto modelBlender = DependencyManager::set<ModelBlender>();
@ -730,6 +734,7 @@ Application::~Application() {
DependencyManager::destroy<OffscreenUi>();
DependencyManager::destroy<AvatarManager>();
DependencyManager::destroy<AnimationCache>();
DependencyManager::destroy<FramebufferCache>();
DependencyManager::destroy<TextureCache>();
DependencyManager::destroy<GeometryCache>();
DependencyManager::destroy<ScriptCache>();
@ -889,6 +894,8 @@ void Application::paintGL() {
PerformanceWarning warn(showWarnings, "Application::paintGL()");
resizeGL();
glEnable(GL_LINE_SMOOTH);
{
PerformanceTimer perfTimer("renderOverlay");
@ -899,7 +906,6 @@ void Application::paintGL() {
_applicationOverlay.renderOverlay(&renderArgs);
}
glEnable(GL_LINE_SMOOTH);
if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, _myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN);
@ -976,7 +982,7 @@ void Application::paintGL() {
{
gpu::Batch batch;
auto primaryFbo = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
batch.setFramebuffer(primaryFbo);
// clear the normal and specular buffers
batch.clearFramebuffer(
@ -987,7 +993,7 @@ void Application::paintGL() {
vec4(vec3(0), 1), 1.0, 0.0);
// Viewport is assigned to the size of the framebuffer
QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize();
renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height());
batch.setViewportTransform(renderArgs._viewport);
renderArgs._context->render(batch);
@ -1003,7 +1009,7 @@ void Application::paintGL() {
{
auto geometryCache = DependencyManager::get<GeometryCache>();
auto primaryFbo = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
gpu::Batch batch;
batch.blit(primaryFbo, glm::ivec4(0, 0, _renderResolution.x, _renderResolution.y),
nullptr, glm::ivec4(0, 0, _glWidget->getDeviceSize().width(), _glWidget->getDeviceSize().height()));
@ -1077,7 +1083,7 @@ void Application::resizeGL() {
if (_renderResolution != toGlm(renderSize)) {
_renderResolution = toGlm(renderSize);
DependencyManager::get<TextureCache>()->setFrameBufferSize(renderSize);
DependencyManager::get<FramebufferCache>()->setFrameBufferSize(renderSize);
updateProjectionMatrix();
}
@ -2997,7 +3003,7 @@ PickRay Application::computePickRay(float x, float y) const {
}
QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) {
auto primaryFramebuffer = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
auto primaryFramebuffer = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFramebuffer));
// clear the alpha channel so the background is transparent
@ -3475,11 +3481,11 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi
// set the bounds of rear mirror view
gpu::Vec4i viewport;
if (billboard) {
QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize();
viewport = gpu::Vec4i(region.x(), size.height() - region.y() - region.height(), region.width(), region.height());
} else {
// if not rendering the billboard, the region is in device independent coordinates; must convert to device
QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize();
float ratio = (float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale();
int x = region.x() * ratio, y = region.y() * ratio, width = region.width() * ratio, height = region.height() * ratio;
viewport = gpu::Vec4i(x, size.height() - y - height, width, height);

View file

@ -34,7 +34,6 @@
#include <ScriptEngine.h>
#include <ShapeManager.h>
#include <StDev.h>
#include <TextureCache.h>
#include <udt/PacketHeaders.h>
#include <ViewFrustum.h>

View file

@ -30,6 +30,7 @@
#include <PathUtils.h>
#include <SharedUtil.h>
#include <UserActivityLogger.h>
#include <FramebufferCache.h>
#include <OVR_CAPI_GL.h>
@ -644,7 +645,7 @@ void OculusManager::display(QGLWidget * glCanvas, RenderArgs* renderArgs, const
return;
}
auto primaryFBO = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
auto primaryFBO = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFBO));
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -704,7 +705,7 @@ void OculusManager::display(QGLWidget * glCanvas, RenderArgs* renderArgs, const
_activeEye = ovrEye_Count;
gpu::FramebufferPointer finalFbo;
finalFbo = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
finalFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// restore our normal viewport

View file

@ -1,19 +1,21 @@
//
// Framebuffer.h
// libraries/gpu/src/gpu
//
// Created by Sam Gateau on 4/12/2015.
// Copyright 2014 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
//
#ifndef hifi_gpu_Framebuffer_h
#define hifi_gpu_Framebuffer_h
#include "Texture.h"
//
// Framebuffer.h
// libraries/gpu/src/gpu
//
// Created by Sam Gateau on 4/12/2015.
// Copyright 2014 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
//
#ifndef hifi_gpu_Framebuffer_h
#define hifi_gpu_Framebuffer_h
#include "Texture.h"
#include <memory>
class QImage;
namespace gpu {
typedef Element Format;
@ -130,7 +132,9 @@ public:
void resize( uint16 width, uint16 height, uint16 samples = 1 );
static const uint32 MAX_NUM_RENDER_BUFFERS = 8;
static uint32 getMaxNumRenderBuffers() { return MAX_NUM_RENDER_BUFFERS; }
static uint32 getMaxNumRenderBuffers() { return MAX_NUM_RENDER_BUFFERS; }
void getImage(QImage* result) const;
protected:
SwapchainPointer _swapchain;
@ -151,10 +155,10 @@ protected:
// Non exposed
Framebuffer(const Framebuffer& framebuffer) {}
Framebuffer() {}
// This shouldn't be used by anything else than the Backend class with the proper casting.
mutable GPUObject* _gpuObject = NULL;
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
// This shouldn't be used by anything else than the Backend class with the proper casting.
mutable GPUObject* _gpuObject = NULL;
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
GPUObject* getGPUObject() const { return _gpuObject; }
friend class Backend;
};
@ -162,4 +166,4 @@ typedef std::shared_ptr<Framebuffer> FramebufferPointer;
}
#endif
#endif

View file

@ -10,7 +10,7 @@
//
#include "Texture.h"
#include <math.h>
#include <glm/gtc/constants.hpp>
#include <QDebug>

View file

@ -23,6 +23,7 @@
#include "GeometryCache.h"
#include "RenderUtil.h"
#include "TextureCache.h"
#include "FramebufferCache.h"
#include "simple_vert.h"
@ -215,8 +216,6 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu
}
void DeferredLightingEffect::prepare(RenderArgs* args) {
auto textureCache = DependencyManager::get<TextureCache>();
gpu::Batch batch;
// clear the normal and specular buffers
@ -232,25 +231,23 @@ void DeferredLightingEffect::render(RenderArgs* args) {
gpu::Batch batch;
// perform deferred lighting, rendering to free fbo
auto textureCache = DependencyManager::get<TextureCache>();
auto framebufferCache = DependencyManager::get<FramebufferCache>();
QSize framebufferSize = textureCache->getFrameBufferSize();
QSize framebufferSize = framebufferCache->getFrameBufferSize();
// binding the first framebuffer
auto freeFBO = DependencyManager::get<TextureCache>()->getSecondaryFramebuffer();
auto freeFBO = framebufferCache->getSecondaryFramebuffer();
batch.setFramebuffer(freeFBO);
batch.setViewportTransform(args->_viewport);
batch.clearColorFramebuffer(freeFBO->getBufferMask(), glm::vec4(0.0f, 0.0f, 0.0f, 0.0f));
batch.setResourceTexture(0, textureCache->getPrimaryColorTexture());
batch.setResourceTexture(1, textureCache->getPrimaryNormalTexture());
batch.setResourceTexture(2, textureCache->getPrimarySpecularTexture());
batch.setResourceTexture(3, textureCache->getPrimaryDepthTexture());
auto primaryFramebuffer = framebufferCache->getPrimaryFramebuffer();
for (int i = 0; i < 3; ++i) {
batch.setResourceTexture(i, primaryFramebuffer->getRenderBuffer(i));
}
batch.setResourceTexture(3, primaryFramebuffer->getDepthStencilBuffer());
float sMin = args->_viewport.x / (float)framebufferSize.width();
float sWidth = args->_viewport.z / (float)framebufferSize.width();
@ -267,7 +264,7 @@ void DeferredLightingEffect::render(RenderArgs* args) {
const LightLocations* locations = &_directionalLightLocations;
bool shadowsEnabled = _viewState->getShadowsEnabled();
if (shadowsEnabled) {
batch.setResourceTexture(4, textureCache->getShadowFramebuffer()->getDepthStencilBuffer());
batch.setResourceTexture(4, framebufferCache->getShadowFramebuffer()->getDepthStencilBuffer());
program = _directionalLightShadowMap;
locations = &_directionalLightShadowMapLocations;
@ -294,7 +291,7 @@ void DeferredLightingEffect::render(RenderArgs* args) {
}
batch.setPipeline(program);
}
batch._glUniform1f(locations->shadowScale, 1.0f / textureCache->getShadowFramebuffer()->getWidth());
batch._glUniform1f(locations->shadowScale, 1.0f / framebufferCache->getShadowFramebuffer()->getWidth());
} else {
if (useSkyboxCubemap) {
@ -537,12 +534,12 @@ void DeferredLightingEffect::render(RenderArgs* args) {
void DeferredLightingEffect::copyBack(RenderArgs* args) {
gpu::Batch batch;
auto textureCache = DependencyManager::get<TextureCache>();
QSize framebufferSize = textureCache->getFrameBufferSize();
auto framebufferCache = DependencyManager::get<FramebufferCache>();
QSize framebufferSize = framebufferCache->getFrameBufferSize();
auto freeFBO = DependencyManager::get<TextureCache>()->getSecondaryFramebuffer();
auto freeFBO = framebufferCache->getSecondaryFramebuffer();
batch.setFramebuffer(textureCache->getPrimaryFramebuffer());
batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer());
batch.setPipeline(_blitLightBuffer);
batch.setResourceTexture(0, freeFBO->getRenderBuffer(0));
@ -564,7 +561,6 @@ void DeferredLightingEffect::copyBack(RenderArgs* args) {
batch.draw(gpu::TRIANGLE_STRIP, 4);
args->_context->syncCache();
args->_context->render(batch);
}

View file

@ -0,0 +1,112 @@
//
// 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 <gpu/GPUConfig.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();
}
}
void FramebufferCache::createPrimaryFramebuffer() {
_primaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
static auto colorFormat = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
static auto depthFormat = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH);
auto width = _frameBufferSize.width();
auto height = _frameBufferSize.height();
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
auto colorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
auto normalTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
auto specularTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_primaryFramebuffer->setRenderBuffer(0, colorTexture);
_primaryFramebuffer->setRenderBuffer(1, normalTexture);
_primaryFramebuffer->setRenderBuffer(2, specularTexture);
auto depthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, width, height, defaultSampler));
_primaryFramebuffer->setDepthStencilBuffer(depthTexture, depthFormat);
}
gpu::FramebufferPointer FramebufferCache::getPrimaryFramebuffer() {
if (!_primaryFramebuffer) {
createPrimaryFramebuffer();
}
return _primaryFramebuffer;
}
void FramebufferCache::setPrimaryDrawBuffers(gpu::Batch& batch, bool color, bool normal, bool specular) {
GLenum buffers[3];
int bufferCount = 0;
if (color) {
buffers[bufferCount++] = GL_COLOR_ATTACHMENT0;
}
if (normal) {
buffers[bufferCount++] = GL_COLOR_ATTACHMENT1;
}
if (specular) {
buffers[bufferCount++] = GL_COLOR_ATTACHMENT2;
}
batch._glDrawBuffers(bufferCount, buffers);
}
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) {
_cachedFramebuffers.push_back(framebuffer);
}
gpu::FramebufferPointer FramebufferCache::getSecondaryFramebuffer() {
static auto _secondaryFramebuffer = getFramebuffer();
return _secondaryFramebuffer;
}
gpu::FramebufferPointer FramebufferCache::getShadowFramebuffer() {
if (!_shadowFramebuffer) {
const int SHADOW_MAP_SIZE = 2048;
_shadowFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::createShadowmap(SHADOW_MAP_SIZE));
}
return _shadowFramebuffer;
}

View file

@ -0,0 +1,59 @@
//
// Created by Bradley Austin Davis on 2015/07/20
// 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
//
#ifndef hifi_FramebufferCache_h
#define hifi_FramebufferCache_h
#include <QSize>
#include <gpu/Framebuffer.h>
#include <DependencyManager.h>
namespace gpu {
class Batch;
}
/// Stores cached textures, including render-to-texture targets.
class FramebufferCache : public Dependency {
SINGLETON_DEPENDENCY
public:
/// Sets the desired texture resolution for the framebuffer objects.
void setFrameBufferSize(QSize frameBufferSize);
const QSize& getFrameBufferSize() const { return _frameBufferSize; }
/// Returns a pointer to the primary framebuffer object. This render target includes a depth component, and is
/// used for scene rendering.
gpu::FramebufferPointer getPrimaryFramebuffer();
gpu::FramebufferPointer getSecondaryFramebuffer();
/// Returns the framebuffer object used to render shadow maps;
gpu::FramebufferPointer getShadowFramebuffer();
/// Enables or disables draw buffers on the primary framebuffer. Note: the primary framebuffer must be bound.
void setPrimaryDrawBuffers(gpu::Batch& batch, bool color, bool normal = false, bool specular = false);
/// Returns a free framebuffer with a single color attachment for temp or intra-frame operations
gpu::FramebufferPointer getFramebuffer();
// TODO add sync functionality to the release, so we don't reuse a framebuffer being read from
/// Releases a free framebuffer back for reuse
void releaseFramebuffer(const gpu::FramebufferPointer& framebuffer);
private:
FramebufferCache();
virtual ~FramebufferCache();
void createPrimaryFramebuffer();
gpu::FramebufferPointer _primaryFramebuffer;
gpu::FramebufferPointer _shadowFramebuffer;
QSize _frameBufferSize{ 100, 100 };
};
#endif // hifi_FramebufferCache_h

View file

@ -9,6 +9,13 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "TextureCache.h"
#include <mutex>
#include <glm/glm.hpp>
#include <glm/gtc/random.hpp>
#include <gpu/Batch.h>
#include <gpu/GLBackend.h>
#include <gpu/GPUConfig.h>
@ -19,21 +26,10 @@
#include <QThreadPool>
#include <qimagereader.h>
#include <glm/glm.hpp>
#include <glm/gtc/random.hpp>
#include "RenderUtilsLogging.h"
#include "TextureCache.h"
#include <mutex>
TextureCache::TextureCache() :
_permutationNormalTexture(0),
_whiteTexture(0),
_blueTexture(0),
_frameBufferSize(100, 100)
{
TextureCache::TextureCache() {
const qint64 TEXTURE_DEFAULT_UNUSED_MAX_SIZE = DEFAULT_UNUSED_MAX_SIZE;
setUnusedResourceCacheSize(TEXTURE_DEFAULT_UNUSED_MAX_SIZE);
}
@ -41,23 +37,6 @@ TextureCache::TextureCache() :
TextureCache::~TextureCache() {
}
void TextureCache::setFrameBufferSize(QSize frameBufferSize) {
//If the size changed, we need to delete our FBOs
if (_frameBufferSize != frameBufferSize) {
_frameBufferSize = frameBufferSize;
_primaryFramebuffer.reset();
_primaryDepthTexture.reset();
_primaryColorTexture.reset();
_primaryNormalTexture.reset();
_primarySpecularTexture.reset();
_secondaryFramebuffer.reset();
_tertiaryFramebuffer.reset();
}
}
// use fixed table of permutations. Could also make ordered list programmatically
// and then shuffle algorithm. For testing, this ensures consistent behavior in each run.
// this list taken from Ken Perlin's Improved Noise reference implementation (orig. in Java) at
@ -175,113 +154,6 @@ NetworkTexturePointer TextureCache::getTexture(const QUrl& url, TextureType type
return texture;
}
void TextureCache::createPrimaryFramebuffer() {
_primaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
auto colorFormat = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
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));
_primaryNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_primarySpecularTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_primaryFramebuffer->setRenderBuffer(0, _primaryColorTexture);
_primaryFramebuffer->setRenderBuffer(1, _primaryNormalTexture);
_primaryFramebuffer->setRenderBuffer(2, _primarySpecularTexture);
auto depthFormat = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH);
_primaryDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, width, height, defaultSampler));
_primaryFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
}
gpu::FramebufferPointer TextureCache::getPrimaryFramebuffer() {
if (!_primaryFramebuffer) {
createPrimaryFramebuffer();
}
return _primaryFramebuffer;
}
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() {
return gpu::GLBackend::getTextureID(getPrimaryDepthTexture());
}
void TextureCache::setPrimaryDrawBuffers(bool color, bool normal, bool specular) {
gpu::Batch batch;
setPrimaryDrawBuffers(batch, color, normal, specular);
gpu::GLBackend::renderBatch(batch);
}
void TextureCache::setPrimaryDrawBuffers(gpu::Batch& batch, bool color, bool normal, bool specular) {
GLenum buffers[3];
int bufferCount = 0;
if (color) {
buffers[bufferCount++] = GL_COLOR_ATTACHMENT0;
}
if (normal) {
buffers[bufferCount++] = GL_COLOR_ATTACHMENT1;
}
if (specular) {
buffers[bufferCount++] = GL_COLOR_ATTACHMENT2;
}
batch._glDrawBuffers(bufferCount, buffers);
}
gpu::FramebufferPointer TextureCache::getSecondaryFramebuffer() {
if (!_secondaryFramebuffer) {
_secondaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create(gpu::Element::COLOR_RGBA_32, _frameBufferSize.width(), _frameBufferSize.height()));
}
return _secondaryFramebuffer;
}
gpu::FramebufferPointer TextureCache::getTertiaryFramebuffer() {
if (!_tertiaryFramebuffer) {
_tertiaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create(gpu::Element::COLOR_RGBA_32, _frameBufferSize.width(), _frameBufferSize.height()));
}
return _tertiaryFramebuffer;
}
gpu::FramebufferPointer TextureCache::getShadowFramebuffer() {
if (!_shadowFramebuffer) {
const int SHADOW_MAP_SIZE = 2048;
_shadowFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::createShadowmap(SHADOW_MAP_SIZE));
_shadowTexture = _shadowFramebuffer->getDepthStencilBuffer();
}
return _shadowFramebuffer;
}
/// Returns a texture version of an image file
gpu::TexturePointer TextureCache::getImageTexture(const QString& path) {
QImage image = QImage(path).mirrored(false, true);

View file

@ -13,8 +13,6 @@
#define hifi_TextureCache_h
#include <gpu/Texture.h>
#include <gpu/Framebuffer.h>
#include <model/Light.h>
#include <QImage>
@ -39,10 +37,6 @@ class TextureCache : public ResourceCache, public Dependency {
SINGLETON_DEPENDENCY
public:
/// Sets the desired texture resolution for the framebuffer objects.
void setFrameBufferSize(QSize frameBufferSize);
const QSize& getFrameBufferSize() const { return _frameBufferSize; }
/// Returns the ID of the permutation/normal texture used for Perlin noise shader programs. This texture
/// has two lines: the first, a set of random numbers in [0, 255] to be used as permutation offsets, and
/// the second, a set of random unit vectors to be used as noise gradients.
@ -67,33 +61,6 @@ public:
NetworkTexturePointer getTexture(const QUrl& url, TextureType type = DEFAULT_TEXTURE, bool dilatable = false,
const QByteArray& content = QByteArray());
/// Returns a pointer to the primary framebuffer object. This render target includes a depth component, and is
/// used for scene rendering.
gpu::FramebufferPointer getPrimaryFramebuffer();
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.
uint32_t getPrimaryDepthTextureID();
/// Enables or disables draw buffers on the primary framebuffer. Note: the primary framebuffer must be bound.
void setPrimaryDrawBuffers(bool color, bool normal = false, bool specular = false);
void setPrimaryDrawBuffers(gpu::Batch& batch, bool color, bool normal = false, bool specular = false);
/// Returns a pointer to the secondary framebuffer object, used as an additional render target when performing full
/// screen effects.
gpu::FramebufferPointer getSecondaryFramebuffer();
/// Returns a pointer to the tertiary framebuffer object, used as an additional render target when performing full
/// screen effects.
gpu::FramebufferPointer getTertiaryFramebuffer();
/// Returns the framebuffer object used to render shadow maps;
gpu::FramebufferPointer getShadowFramebuffer();
protected:
virtual QSharedPointer<Resource> createResource(const QUrl& url,
@ -110,23 +77,7 @@ private:
gpu::TexturePointer _blueTexture;
gpu::TexturePointer _blackTexture;
QHash<QUrl, QWeakPointer<NetworkTexture> > _dilatableNetworkTextures;
gpu::TexturePointer _primaryDepthTexture;
gpu::TexturePointer _primaryColorTexture;
gpu::TexturePointer _primaryNormalTexture;
gpu::TexturePointer _primarySpecularTexture;
gpu::FramebufferPointer _primaryFramebuffer;
void createPrimaryFramebuffer();
gpu::FramebufferPointer _secondaryFramebuffer;
gpu::FramebufferPointer _tertiaryFramebuffer;
gpu::FramebufferPointer _shadowFramebuffer;
gpu::TexturePointer _shadowTexture;
QSize _frameBufferSize;
};
/// A simple object wrapper for an OpenGL texture.