Removing almost all the QFramebufferObject (instead in overlay layer) in favor of gpu::Framebuffer, eveyrthing seems to work properly

This commit is contained in:
Sam Gateau 2015-04-14 18:27:24 -07:00
parent 87030236cb
commit fec52f6b10
13 changed files with 133 additions and 288 deletions

View file

@ -35,7 +35,6 @@
#include <QMouseEvent>
#include <QNetworkReply>
#include <QNetworkDiskCache>
#include <QOpenGLFramebufferObject>
#include <QObject>
#include <QWheelEvent>
#include <QScreen>
@ -798,7 +797,6 @@ void Application::paintGL() {
DependencyManager::get<GlowEffect>()->prepare();
// Viewport is assigned to the size of the framebuffer
// QSize size = DependencyManager::get<TextureCache>()->getPrimaryFramebufferObject()->size();
QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
glViewport(0, 0, size.width(), size.height());
@ -2637,11 +2635,8 @@ void Application::updateShadowMap() {
activeRenderingThread = QThread::currentThread();
PerformanceTimer perfTimer("shadowMap");
// QOpenGLFramebufferObject* fbo = DependencyManager::get<TextureCache>()->getShadowFramebufferObject();
// fbo->bind();
auto shadowFramebuffer = DependencyManager::get<TextureCache>()->getShadowFramebuffer();
GLuint shadowFBO = gpu::GLBackend::getFramebufferID(shadowFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, shadowFBO);
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(shadowFramebuffer));
glEnable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT);
@ -2838,7 +2833,8 @@ PickRay Application::computePickRay(float x, float y) {
}
QImage Application::renderAvatarBillboard() {
DependencyManager::get<TextureCache>()->getPrimaryFramebufferObject()->bind();
auto primaryFramebuffer = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFramebuffer));
// the "glow" here causes an alpha of one
Glower glower;
@ -2851,7 +2847,7 @@ QImage Application::renderAvatarBillboard() {
QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32);
glReadPixels(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE, GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
DependencyManager::get<TextureCache>()->getPrimaryFramebufferObject()->release();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return image;
}

View file

@ -17,7 +17,6 @@
#include <QDesktopWidget>
#include <QGuiApplication>
#include <QOpenGLFramebufferObject>
#include <QScreen>
#include <QOpenGLTimerQuery>
@ -35,6 +34,8 @@
#include "InterfaceLogging.h"
#include "Application.h"
#include <gpu\GLBackend.h>
template <typename Function>
void for_each_eye(Function function) {
for (ovrEyeType eye = ovrEyeType::ovrEye_Left;
@ -521,7 +522,8 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect)) {
DependencyManager::get<GlowEffect>()->prepare();
} else {
DependencyManager::get<TextureCache>()->getPrimaryFramebufferObject()->bind();
auto primaryFBO = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFBO));
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
@ -612,15 +614,15 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p
glPopMatrix();
QOpenGLFramebufferObject * finalFbo = nullptr;
gpu::FramebufferPointer finalFbo;
//Bind the output texture from the glow shader. If glow effect is disabled, we just grab the texture
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect)) {
//Full texture viewport for glow effect
glViewport(0, 0, _renderTargetSize.w, _renderTargetSize.h);
finalFbo = DependencyManager::get<GlowEffect>()->render(true);
} else {
finalFbo = DependencyManager::get<TextureCache>()->getPrimaryFramebufferObject();
finalFbo->release();
finalFbo = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
glMatrixMode(GL_PROJECTION);
@ -644,7 +646,7 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p
//Left over from when OR was not connected.
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, finalFbo->texture());
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(finalFbo->getRenderBuffer(0)));
//Renders the distorted mesh onto the screen
renderDistortionMesh(eyeRenderPose);

View file

@ -11,8 +11,6 @@
#include "InterfaceConfig.h"
#include <QOpenGLFramebufferObject>
#include <glm/glm.hpp>
#include <GlowEffect.h>

View file

@ -173,6 +173,8 @@ public:
return getRaw() != right.getRaw();
}
static const Element COLOR_RGBA_32;
protected:
uint8 _semantic;
uint8 _dimension : 4;

View file

@ -29,7 +29,18 @@ Framebuffer* Framebuffer::create() {
return framebuffer;
}
Framebuffer* Framebuffer::create( const Format& colorBufferFormat, const Format& depthStencilBufferFormat, uint16 width, uint16 height, uint16 numSamples) {
Framebuffer* Framebuffer::create( const Format& colorBufferFormat, uint16 width, uint16 height) {
auto framebuffer = Framebuffer::create();
auto colorTexture = TexturePointer(Texture::create2D(colorBufferFormat, width, height, Sampler(Sampler::FILTER_MIN_MAG_POINT)));
framebuffer->setRenderBuffer(0, colorTexture);
return framebuffer;
}
Framebuffer* Framebuffer::create( const Format& colorBufferFormat, const Format& depthStencilBufferFormat, uint16 width, uint16 height) {
auto framebuffer = Framebuffer::create();
auto colorTexture = TexturePointer(Texture::create2D(colorBufferFormat, width, height, Sampler(Sampler::FILTER_MIN_MAG_POINT)));

View file

@ -115,7 +115,8 @@ 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* create(const Format& colorBufferFormat, uint16 width, uint16 height);
static Framebuffer* create(const Format& colorBufferFormat, const Format& depthStencilBufferFormat, uint16 width, uint16 height);
static Framebuffer* createShadowmap(uint16 width);
bool isSwapchain() const;

View file

@ -16,6 +16,8 @@
using namespace gpu;
const Element Element::COLOR_RGBA_32 = Element(VEC4, UINT8, RGBA);
Resource::Size Resource::Sysmem::allocateMemory(Byte** dataAllocated, Size size) {
if ( !dataAllocated ) {
qWarning() << "Buffer::Sysmem::allocateMemory() : Must have a valid dataAllocated pointer.";

View file

@ -12,7 +12,7 @@
// include this before QOpenGLFramebufferObject, which includes an earlier version of OpenGL
#include <gpu/GPUConfig.h>
#include <QOpenGLFramebufferObject>
#include <gpu/GLBackend.h>
#include <glm/gtc/random.hpp>
@ -107,8 +107,8 @@ void AmbientOcclusionEffect::render() {
glBindTexture(GL_TEXTURE_2D, _rotationTextureID);
// render with the occlusion shader to the secondary/tertiary buffer
QOpenGLFramebufferObject* freeFBO = DependencyManager::get<GlowEffect>()->getFreeFramebufferObject();
freeFBO->bind();
auto freeFramebuffer = DependencyManager::get<GlowEffect>()->getFreeFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(freeFramebuffer));
float left, right, bottom, top, nearVal, farVal;
glm::vec4 nearClipPlane, farClipPlane;
@ -118,9 +118,10 @@ void AmbientOcclusionEffect::render() {
glGetIntegerv(GL_VIEWPORT, viewport);
const int VIEWPORT_X_INDEX = 0;
const int VIEWPORT_WIDTH_INDEX = 2;
QOpenGLFramebufferObject* primaryFBO = DependencyManager::get<TextureCache>()->getPrimaryFramebufferObject();
float sMin = viewport[VIEWPORT_X_INDEX] / (float)primaryFBO->width();
float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)primaryFBO->width();
auto framebufferSize = DependencyManager::get<TextureCache>()->getFrameBufferSize();
float sMin = viewport[VIEWPORT_X_INDEX] / (float)framebufferSize.width();
float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)framebufferSize.width();
_occlusionProgram->bind();
_occlusionProgram->setUniformValue(_nearLocation, nearVal);
@ -128,7 +129,7 @@ void AmbientOcclusionEffect::render() {
_occlusionProgram->setUniformValue(_leftBottomLocation, left, bottom);
_occlusionProgram->setUniformValue(_rightTopLocation, right, top);
_occlusionProgram->setUniformValue(_noiseScaleLocation, viewport[VIEWPORT_WIDTH_INDEX] / (float)ROTATION_WIDTH,
primaryFBO->height() / (float)ROTATION_HEIGHT);
framebufferSize.height() / (float)ROTATION_HEIGHT);
_occlusionProgram->setUniformValue(_texCoordOffsetLocation, sMin, 0.0f);
_occlusionProgram->setUniformValue(_texCoordScaleLocation, sWidth, 1.0f);
@ -136,22 +137,24 @@ void AmbientOcclusionEffect::render() {
_occlusionProgram->release();
freeFBO->release();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
// now render secondary to primary with 4x4 blur
DependencyManager::get<TextureCache>()->getPrimaryFramebufferObject()->bind();
auto primaryFramebuffer = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFramebuffer));
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE);
glBindTexture(GL_TEXTURE_2D, freeFBO->texture());
auto freeFramebufferTexture = freeFramebuffer->getRenderBuffer(0);
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(freeFramebufferTexture));
_blurProgram->bind();
_blurProgram->setUniformValue(_blurScaleLocation, 1.0f / primaryFBO->width(), 1.0f / primaryFBO->height());
_blurProgram->setUniformValue(_blurScaleLocation, 1.0f / framebufferSize.width(), 1.0f / framebufferSize.height());
renderFullscreenQuad(sMin, sMin + sWidth);

View file

@ -12,7 +12,6 @@
// include this before QOpenGLFramebufferObject, which includes an earlier version of OpenGL
#include <gpu/GPUConfig.h>
#include <QOpenGLFramebufferObject>
#include <GLMHelpers.h>
#include <PathUtils.h>
@ -183,12 +182,13 @@ void DeferredLightingEffect::render() {
auto textureCache = DependencyManager::get<TextureCache>();
// QOpenGLFramebufferObject* primaryFBO = textureCache->getPrimaryFramebufferObject();
// primaryFBO->release();
glBindFramebuffer(GL_FRAMEBUFFER, 0 );
QSize framebufferSize = textureCache->getFrameBufferSize();
QOpenGLFramebufferObject* freeFBO = DependencyManager::get<GlowEffect>()->getFreeFramebufferObject();
freeFBO->bind();
auto freeFBO = DependencyManager::get<GlowEffect>()->getFreeFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(freeFBO));
glClear(GL_COLOR_BUFFER_BIT);
// glEnable(GL_FRAMEBUFFER_SRGB);
@ -211,11 +211,7 @@ 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 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();
@ -436,7 +432,9 @@ void DeferredLightingEffect::render() {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
freeFBO->release();
//freeFBO->release();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// glDisable(GL_FRAMEBUFFER_SRGB);
glDisable(GL_CULL_FACE);
@ -445,12 +443,12 @@ void DeferredLightingEffect::render() {
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
glColorMask(true, true, true, false);
auto primaryFBO = gpu::GLBackend::getFramebufferID(textureCache->getPrimaryOpaqueFramebuffer());
auto primaryFBO = gpu::GLBackend::getFramebufferID(textureCache->getPrimaryFramebuffer());
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, primaryFBO);
//primaryFBO->bind();
glBindTexture(GL_TEXTURE_2D, freeFBO->texture());
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(freeFBO->getRenderBuffer(0)));
glEnable(GL_TEXTURE_2D);
glPushMatrix();

View file

@ -46,10 +46,10 @@ GlowEffect::~GlowEffect() {
}
}
QOpenGLFramebufferObject* GlowEffect::getFreeFramebufferObject() const {
gpu::FramebufferPointer GlowEffect::getFreeFramebuffer() const {
return (_isOddFrame ?
DependencyManager::get<TextureCache>()->getSecondaryFramebufferObject():
DependencyManager::get<TextureCache>()->getTertiaryFramebufferObject());
DependencyManager::get<TextureCache>()->getSecondaryFramebuffer():
DependencyManager::get<TextureCache>()->getTertiaryFramebuffer());
}
static ProgramObject* createProgram(const QString& name) {
@ -106,8 +106,7 @@ int GlowEffect::getDeviceHeight() const {
void GlowEffect::prepare() {
//DependencyManager::get<TextureCache>()->getPrimaryFramebufferObject()->bind();
auto primaryFBO = DependencyManager::get<TextureCache>()->getPrimaryOpaqueFramebuffer();
auto primaryFBO = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
GLuint fbo = gpu::GLBackend::getFramebufferID(primaryFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
@ -129,25 +128,26 @@ void GlowEffect::end() {
glBlendColor(0.0f, 0.0f, 0.0f, _intensity = _intensityStack.pop());
}
static void maybeBind(QOpenGLFramebufferObject* fbo) {
static void maybeBind(const gpu::FramebufferPointer& fbo) {
if (fbo) {
fbo->bind();
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(fbo));
}
}
static void maybeRelease(QOpenGLFramebufferObject* fbo) {
static void maybeRelease(const gpu::FramebufferPointer& fbo) {
if (fbo) {
fbo->release();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
}
QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) {
gpu::FramebufferPointer GlowEffect::render(bool toTexture) {
PerformanceTimer perfTimer("glowEffect");
auto textureCache = DependencyManager::get<TextureCache>();
// QOpenGLFramebufferObject* primaryFBO = textureCache->getPrimaryFramebufferObject();
// primaryFBO->release();
auto primaryFBO = gpu::GLBackend::getFramebufferID(textureCache->getPrimaryOpaqueFramebuffer());
auto primaryFBO = gpu::GLBackend::getFramebufferID(textureCache->getPrimaryFramebuffer());
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, textureCache->getPrimaryColorTextureID());
auto framebufferSize = textureCache->getFrameBufferSize();
@ -162,15 +162,14 @@ QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) {
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
QOpenGLFramebufferObject* destFBO = toTexture ?
textureCache->getSecondaryFramebufferObject() : NULL;
gpu::FramebufferPointer destFBO = toTexture ?
textureCache->getSecondaryFramebuffer() : nullptr;
if (!_enabled || _isEmpty) {
// copy the primary to the screen
if (destFBO && QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()) {
glBindFramebuffer(GL_READ_FRAMEBUFFER, primaryFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, destFBO->handle());
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(destFBO));
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) {
@ -185,36 +184,35 @@ QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) {
}
} else {
// diffuse into the secondary/tertiary (alternating between frames)
QOpenGLFramebufferObject* oldDiffusedFBO =
textureCache->getSecondaryFramebufferObject();
QOpenGLFramebufferObject* newDiffusedFBO =
textureCache->getTertiaryFramebufferObject();
auto oldDiffusedFBO =
textureCache->getSecondaryFramebuffer();
auto newDiffusedFBO =
textureCache->getTertiaryFramebuffer();
if (_isOddFrame) {
qSwap(oldDiffusedFBO, newDiffusedFBO);
}
newDiffusedFBO->bind();
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(newDiffusedFBO));
if (_isFirstFrame) {
glClear(GL_COLOR_BUFFER_BIT);
} else {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, oldDiffusedFBO->texture());
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(oldDiffusedFBO->getRenderBuffer(0)));
_diffuseProgram->bind();
//QSize size = primaryFBO->size();
QSize size = framebufferSize;
_diffuseProgram->setUniformValue(_diffusionScaleLocation, 1.0f / size.width(), 1.0f / size.height());
_diffuseProgram->setUniformValue(_diffusionScaleLocation, 1.0f / framebufferSize.width(), 1.0f / framebufferSize.height());
renderFullscreenQuad();
_diffuseProgram->release();
}
newDiffusedFBO->release();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// add diffused texture to the primary
glBindTexture(GL_TEXTURE_2D, newDiffusedFBO->texture());
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(newDiffusedFBO->getRenderBuffer(0)));
if (toTexture) {
destFBO = oldDiffusedFBO;

View file

@ -13,6 +13,7 @@
#define hifi_GlowEffect_h
#include <gpu/GPUConfig.h>
#include <gpu/Framebuffer.h>
#include <QObject>
#include <QGLWidget>
@ -20,8 +21,6 @@
#include <DependencyManager.h>
class QOpenGLFramebufferObject;
class ProgramObject;
/// A generic full screen glow effect.
@ -33,7 +32,7 @@ public:
/// Returns a pointer to the framebuffer object that the glow effect is *not* using for persistent state
/// (either the secondary or the tertiary).
QOpenGLFramebufferObject* getFreeFramebufferObject() const;
gpu::FramebufferPointer getFreeFramebuffer() const;
void init(QGLWidget* widget, bool enabled);
@ -53,7 +52,7 @@ public:
/// Renders the glow effect. To be called after rendering the scene.
/// \param toTexture whether to render to a texture, rather than to the frame buffer
/// \return the framebuffer object to which we rendered, or NULL if to the frame buffer
QOpenGLFramebufferObject* render(bool toTexture = false);
gpu::FramebufferPointer render(bool toTexture = false);
public slots:
void toggleGlowEffect(bool enabled);

View file

@ -32,13 +32,6 @@ TextureCache::TextureCache() :
_permutationNormalTexture(0),
_whiteTexture(0),
_blueTexture(0),
_primaryDepthTextureID(0),
_primaryNormalTextureID(0),
_primarySpecularTextureID(0),
_primaryFramebufferObject(NULL),
_secondaryFramebufferObject(NULL),
_tertiaryFramebufferObject(NULL),
_shadowFramebufferObject(NULL),
_frameBufferSize(100, 100),
_associatedWidget(NULL)
{
@ -47,24 +40,6 @@ TextureCache::TextureCache() :
}
TextureCache::~TextureCache() {
if (_primaryFramebufferObject) {
glDeleteTextures(1, &_primaryDepthTextureID);
glDeleteTextures(1, &_primaryNormalTextureID);
glDeleteTextures(1, &_primarySpecularTextureID);
}
if (_primaryFramebufferObject) {
delete _primaryFramebufferObject;
}
if (_secondaryFramebufferObject) {
delete _secondaryFramebufferObject;
}
if (_tertiaryFramebufferObject) {
delete _tertiaryFramebufferObject;
}
}
void TextureCache::setFrameBufferSize(QSize frameBufferSize) {
@ -72,35 +47,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();
}
_primaryFramebuffer.reset();
_primaryDepthTexture.reset();
_primaryColorTexture.reset();
_primaryNormalTexture.reset();
_primarySpecularTexture.reset();
if (_primaryFramebufferObject) {
delete _primaryFramebufferObject;
_primaryFramebufferObject = NULL;
glDeleteTextures(1, &_primaryDepthTextureID);
_primaryDepthTextureID = 0;
glDeleteTextures(1, &_primaryNormalTextureID);
_primaryNormalTextureID = 0;
glDeleteTextures(1, &_primarySpecularTextureID);
_primarySpecularTextureID = 0;
}
_secondaryFramebuffer.reset();
if (_secondaryFramebufferObject) {
delete _secondaryFramebufferObject;
_secondaryFramebufferObject = NULL;
}
if (_tertiaryFramebufferObject) {
delete _tertiaryFramebufferObject;
_tertiaryFramebufferObject = NULL;
}
_tertiaryFramebuffer.reset();
}
}
@ -215,46 +170,8 @@ NetworkTexturePointer TextureCache::getTexture(const QUrl& url, TextureType type
return texture;
}
QOpenGLFramebufferObject* TextureCache::getPrimaryFramebufferObject() {
if (!_primaryFramebufferObject) {
_primaryFramebufferObject = createFramebufferObject();
glGenTextures(1, &_primaryDepthTextureID);
glBindTexture(GL_TEXTURE_2D, _primaryDepthTextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, _frameBufferSize.width(), _frameBufferSize.height(),
0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glGenTextures(1, &_primaryNormalTextureID);
glBindTexture(GL_TEXTURE_2D, _primaryNormalTextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _frameBufferSize.width(), _frameBufferSize.height(),
0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
glGenTextures(1, &_primarySpecularTextureID);
glBindTexture(GL_TEXTURE_2D, _primarySpecularTextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _frameBufferSize.width(), _frameBufferSize.height(),
0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
_primaryFramebufferObject->bind();
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _primaryDepthTextureID, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, _primaryNormalTextureID, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, _primarySpecularTextureID, 0);
_primaryFramebufferObject->release();
}
return _primaryFramebufferObject;
}
void TextureCache::createPrimaryFramebuffer() {
_primaryOpaqueFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
_primaryTransparentFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
_primaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
auto colorFormat = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
auto width = _frameBufferSize.width();
@ -265,32 +182,22 @@ void TextureCache::createPrimaryFramebuffer() {
_primaryNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_primarySpecularTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_primaryOpaqueFramebuffer->setRenderBuffer(0, _primaryColorTexture);
_primaryOpaqueFramebuffer->setRenderBuffer(1, _primaryNormalTexture);
_primaryOpaqueFramebuffer->setRenderBuffer(2, _primarySpecularTexture);
_primaryFramebuffer->setRenderBuffer(0, _primaryColorTexture);
_primaryFramebuffer->setRenderBuffer(1, _primaryNormalTexture);
_primaryFramebuffer->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, defaultSampler));
_primaryOpaqueFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
_primaryTransparentFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
_primaryFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
}
gpu::FramebufferPointer TextureCache::getPrimaryOpaqueFramebuffer() {
if (!_primaryOpaqueFramebuffer) {
gpu::FramebufferPointer TextureCache::getPrimaryFramebuffer() {
if (!_primaryFramebuffer) {
createPrimaryFramebuffer();
}
return _primaryOpaqueFramebuffer;
}
gpu::FramebufferPointer TextureCache::getPrimaryTransparentFramebuffer() {
if (!_primaryTransparentFramebuffer) {
createPrimaryFramebuffer();
}
return _primaryTransparentFramebuffer;
return _primaryFramebuffer;
}
gpu::TexturePointer TextureCache::getPrimaryDepthTexture() {
@ -322,28 +229,19 @@ gpu::TexturePointer TextureCache::getPrimarySpecularTexture() {
}
GLuint TextureCache::getPrimaryDepthTextureID() {
// ensure that the primary framebuffer object is initialized before returning the depth texture id
//getPrimaryFramebufferObject();
_primaryDepthTextureID = gpu::GLBackend::getTextureID(_primaryDepthTexture);
return _primaryDepthTextureID;
return gpu::GLBackend::getTextureID(getPrimaryDepthTexture());
}
GLuint TextureCache::getPrimaryColorTextureID() {
return gpu::GLBackend::getTextureID(_primaryColorTexture);
return gpu::GLBackend::getTextureID(getPrimaryColorTexture());
}
GLuint TextureCache::getPrimaryNormalTextureID() {
// ensure that the primary framebuffer object is initialized before returning the normal texture id
//getPrimaryFramebufferObject();
_primaryNormalTextureID = gpu::GLBackend::getTextureID(_primaryNormalTexture);
return _primaryNormalTextureID;
return gpu::GLBackend::getTextureID(getPrimaryNormalTexture());
}
GLuint TextureCache::getPrimarySpecularTextureID() {
//getPrimaryFramebufferObject();
_primarySpecularTextureID = gpu::GLBackend::getTextureID(_primarySpecularTexture);
return _primarySpecularTextureID;
return gpu::GLBackend::getTextureID(getPrimarySpecularTexture());
}
void TextureCache::setPrimaryDrawBuffers(bool color, bool normal, bool specular) {
@ -361,18 +259,18 @@ void TextureCache::setPrimaryDrawBuffers(bool color, bool normal, bool specular)
glDrawBuffers(bufferCount, buffers);
}
QOpenGLFramebufferObject* TextureCache::getSecondaryFramebufferObject() {
if (!_secondaryFramebufferObject) {
_secondaryFramebufferObject = createFramebufferObject();
gpu::FramebufferPointer TextureCache::getSecondaryFramebuffer() {
if (!_secondaryFramebuffer) {
_secondaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create(gpu::Element::COLOR_RGBA_32, _frameBufferSize.width(), _frameBufferSize.height()));
}
return _secondaryFramebufferObject;
return _secondaryFramebuffer;
}
QOpenGLFramebufferObject* TextureCache::getTertiaryFramebufferObject() {
if (!_tertiaryFramebufferObject) {
_tertiaryFramebufferObject = createFramebufferObject();
gpu::FramebufferPointer TextureCache::getTertiaryFramebuffer() {
if (!_tertiaryFramebuffer) {
_tertiaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create(gpu::Element::COLOR_RGBA_32, _frameBufferSize.width(), _frameBufferSize.height()));
}
return _tertiaryFramebufferObject;
return _tertiaryFramebuffer;
}
@ -386,58 +284,25 @@ gpu::FramebufferPointer TextureCache::getShadowFramebuffer() {
return _shadowFramebuffer;
}
QOpenGLFramebufferObject* TextureCache::getShadowFramebufferObject() {
if (!_shadowFramebufferObject) {
const int SHADOW_MAP_SIZE = 2048;
_shadowFramebufferObject = new QOpenGLFramebufferObject(SHADOW_MAP_SIZE, SHADOW_MAP_SIZE,
QOpenGLFramebufferObject::NoAttachment, GL_TEXTURE_2D, GL_RGB);
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 _shadowFramebufferObject;
}
GLuint TextureCache::getShadowDepthTextureID() {
// ensure that the shadow framebuffer object is initialized before returning the depth texture id
//getShadowFramebufferObject();
_shadowDepthTextureID = gpu::GLBackend::getTextureID(_shadowTexture);
return _shadowDepthTextureID;
getShadowFramebuffer();
return gpu::GLBackend::getTextureID(_shadowTexture);
}
bool TextureCache::eventFilter(QObject* watched, QEvent* event) {
if (event->type() == QEvent::Resize) {
QSize size = static_cast<QResizeEvent*>(event)->size();
if (_primaryFramebufferObject && _primaryFramebufferObject->size() != size) {
delete _primaryFramebufferObject;
_primaryFramebufferObject = NULL;
glDeleteTextures(1, &_primaryDepthTextureID);
glDeleteTextures(1, &_primaryNormalTextureID);
glDeleteTextures(1, &_primarySpecularTextureID);
}
if (_secondaryFramebufferObject && _secondaryFramebufferObject->size() != size) {
delete _secondaryFramebufferObject;
_secondaryFramebufferObject = NULL;
}
if (_tertiaryFramebufferObject && _tertiaryFramebufferObject->size() != size) {
delete _tertiaryFramebufferObject;
_tertiaryFramebufferObject = NULL;
if (_frameBufferSize != size) {
_primaryFramebuffer.reset();
_primaryColorTexture.reset();
_primaryDepthTexture.reset();
_primaryNormalTexture.reset();
_primarySpecularTexture.reset();
_secondaryFramebuffer.reset();
_tertiaryFramebuffer.reset();
}
}
return false;
@ -458,17 +323,6 @@ void TextureCache::associateWithWidget(QGLWidget* widget) {
_associatedWidget->installEventFilter(this);
}
QOpenGLFramebufferObject* TextureCache::createFramebufferObject() {
QOpenGLFramebufferObject* fbo = new QOpenGLFramebufferObject(_frameBufferSize);
glBindTexture(GL_TEXTURE_2D, fbo->texture());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
return fbo;
}
Texture::Texture() {
}

View file

@ -23,8 +23,6 @@
#include <DependencyManager.h>
#include <ResourceCache.h>
class QOpenGLFramebufferObject;
class NetworkTexture;
typedef QSharedPointer<NetworkTexture> NetworkTexturePointer;
@ -61,10 +59,7 @@ public:
/// Returns a pointer to the primary framebuffer object. This render target includes a depth component, and is
/// used for scene rendering.
QOpenGLFramebufferObject* getPrimaryFramebufferObject();
gpu::FramebufferPointer getPrimaryOpaqueFramebuffer();
gpu::FramebufferPointer getPrimaryTransparentFramebuffer();
gpu::FramebufferPointer getPrimaryFramebuffer();
gpu::TexturePointer getPrimaryDepthTexture();
gpu::TexturePointer getPrimaryColorTexture();
@ -86,16 +81,13 @@ public:
/// Returns a pointer to the secondary framebuffer object, used as an additional render target when performing full
/// screen effects.
QOpenGLFramebufferObject* getSecondaryFramebufferObject();
gpu::FramebufferPointer getSecondaryFramebuffer();
/// Returns a pointer to the tertiary framebuffer object, used as an additional render target when performing full
/// screen effects.
QOpenGLFramebufferObject* getTertiaryFramebufferObject();
/// Returns a pointer to the framebuffer object used to render shadow maps.
QOpenGLFramebufferObject* getShadowFramebufferObject();
gpu::FramebufferPointer getTertiaryFramebuffer();
/// Returns the framebuffer object used to render shadow maps;
gpu::FramebufferPointer getShadowFramebuffer();
@ -113,8 +105,6 @@ private:
TextureCache();
virtual ~TextureCache();
friend class DilatableNetworkTexture;
QOpenGLFramebufferObject* createFramebufferObject();
gpu::TexturePointer _permutationNormalTexture;
gpu::TexturePointer _whiteTexture;
@ -127,20 +117,11 @@ private:
gpu::TexturePointer _primaryColorTexture;
gpu::TexturePointer _primaryNormalTexture;
gpu::TexturePointer _primarySpecularTexture;
gpu::FramebufferPointer _primaryOpaqueFramebuffer;
gpu::FramebufferPointer _primaryTransparentFramebuffer;
gpu::FramebufferPointer _primaryFramebuffer;
void createPrimaryFramebuffer();
GLuint _primaryDepthTextureID;
GLuint _primaryNormalTextureID;
GLuint _primarySpecularTextureID;
QOpenGLFramebufferObject* _primaryFramebufferObject;
QOpenGLFramebufferObject* _secondaryFramebufferObject;
QOpenGLFramebufferObject* _tertiaryFramebufferObject;
QOpenGLFramebufferObject* _shadowFramebufferObject;
GLuint _shadowDepthTextureID;
gpu::FramebufferPointer _secondaryFramebuffer;
gpu::FramebufferPointer _tertiaryFramebuffer;
gpu::FramebufferPointer _shadowFramebuffer;
gpu::TexturePointer _shadowTexture;