Render to texture first, rather than copying from the frame buffer. Copying

from the frame buffer requires it to have an alpha channel, which actually
does something on OS X (meaning we have to set it to 1.0).  We're going to
want to render to texture anyway for SSAO (or other effects).
This commit is contained in:
Andrzej Kapolka 2013-08-13 12:27:52 -07:00
parent c1f6794295
commit b05b43f027
5 changed files with 93 additions and 69 deletions

View file

@ -8,25 +8,25 @@
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
// the texture containing the color to blur
uniform sampler2D colorTexture;
// the texture containing the original color
uniform sampler2D originalTexture;
void main(void) {
float ds = dFdx(gl_TexCoord[0].s);
gl_FragColor = (texture2D(colorTexture, gl_TexCoord[0].st + vec2(ds * -15.5, 0.0)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(ds * -13.5, 0.0)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(ds * -11.5, 0.0)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(ds * -9.5, 0.0)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(ds * -7.5, 0.0)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(ds * -5.5, 0.0)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(ds * -3.5, 0.0)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(ds * -1.5, 0.0)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(ds * 1.5, 0.0)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(ds * 3.5, 0.0)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(ds * 5.5, 0.0)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(ds * 7.5, 0.0)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(ds * 9.5, 0.0)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(ds * 11.5, 0.0)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(ds * 13.5, 0.0)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(ds * 15.5, 0.0))) / 16.0;
gl_FragColor = (texture2D(originalTexture, gl_TexCoord[0].st + vec2(ds * -15.5, 0.0)) +
texture2D(originalTexture, gl_TexCoord[0].st + vec2(ds * -13.5, 0.0)) +
texture2D(originalTexture, gl_TexCoord[0].st + vec2(ds * -11.5, 0.0)) +
texture2D(originalTexture, gl_TexCoord[0].st + vec2(ds * -9.5, 0.0)) +
texture2D(originalTexture, gl_TexCoord[0].st + vec2(ds * -7.5, 0.0)) +
texture2D(originalTexture, gl_TexCoord[0].st + vec2(ds * -5.5, 0.0)) +
texture2D(originalTexture, gl_TexCoord[0].st + vec2(ds * -3.5, 0.0)) +
texture2D(originalTexture, gl_TexCoord[0].st + vec2(ds * -1.5, 0.0)) +
texture2D(originalTexture, gl_TexCoord[0].st + vec2(ds * 1.5, 0.0)) +
texture2D(originalTexture, gl_TexCoord[0].st + vec2(ds * 3.5, 0.0)) +
texture2D(originalTexture, gl_TexCoord[0].st + vec2(ds * 5.5, 0.0)) +
texture2D(originalTexture, gl_TexCoord[0].st + vec2(ds * 7.5, 0.0)) +
texture2D(originalTexture, gl_TexCoord[0].st + vec2(ds * 9.5, 0.0)) +
texture2D(originalTexture, gl_TexCoord[0].st + vec2(ds * 11.5, 0.0)) +
texture2D(originalTexture, gl_TexCoord[0].st + vec2(ds * 13.5, 0.0)) +
texture2D(originalTexture, gl_TexCoord[0].st + vec2(ds * 15.5, 0.0))) / 16.0;
}

View file

@ -8,25 +8,29 @@
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
// the texture containing the color to blur
uniform sampler2D colorTexture;
// the texture containing the original color
uniform sampler2D originalTexture;
// the texture containing the horizontally blurred color
uniform sampler2D horizontallyBlurredTexture;
void main(void) {
float dt = dFdy(gl_TexCoord[0].t);
gl_FragColor = (texture2D(colorTexture, gl_TexCoord[0].st + vec2(0.0, dt * -15.5)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(0.0, dt * -13.5)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(0.0, dt * -11.5)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(0.0, dt * -9.5)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(0.0, dt * -7.5)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(0.0, dt * -4.5)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(0.0, dt * -3.5)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(0.0, dt * -1.5)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(0.0, dt * 1.5)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(0.0, dt * 3.5)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(0.0, dt * 5.5)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(0.0, dt * 7.5)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(0.0, dt * 9.5)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(0.0, dt * 11.5)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(0.0, dt * 13.5)) +
texture2D(colorTexture, gl_TexCoord[0].st + vec2(0.0, dt * 15.5))) / 16.0;
vec4 blurred = (texture2D(horizontallyBlurredTexture, gl_TexCoord[0].st + vec2(0.0, dt * -15.5)) +
texture2D(horizontallyBlurredTexture, gl_TexCoord[0].st + vec2(0.0, dt * -13.5)) +
texture2D(horizontallyBlurredTexture, gl_TexCoord[0].st + vec2(0.0, dt * -11.5)) +
texture2D(horizontallyBlurredTexture, gl_TexCoord[0].st + vec2(0.0, dt * -9.5)) +
texture2D(horizontallyBlurredTexture, gl_TexCoord[0].st + vec2(0.0, dt * -7.5)) +
texture2D(horizontallyBlurredTexture, gl_TexCoord[0].st + vec2(0.0, dt * -4.5)) +
texture2D(horizontallyBlurredTexture, gl_TexCoord[0].st + vec2(0.0, dt * -3.5)) +
texture2D(horizontallyBlurredTexture, gl_TexCoord[0].st + vec2(0.0, dt * -1.5)) +
texture2D(horizontallyBlurredTexture, gl_TexCoord[0].st + vec2(0.0, dt * 1.5)) +
texture2D(horizontallyBlurredTexture, gl_TexCoord[0].st + vec2(0.0, dt * 3.5)) +
texture2D(horizontallyBlurredTexture, gl_TexCoord[0].st + vec2(0.0, dt * 5.5)) +
texture2D(horizontallyBlurredTexture, gl_TexCoord[0].st + vec2(0.0, dt * 7.5)) +
texture2D(horizontallyBlurredTexture, gl_TexCoord[0].st + vec2(0.0, dt * 9.5)) +
texture2D(horizontallyBlurredTexture, gl_TexCoord[0].st + vec2(0.0, dt * 11.5)) +
texture2D(horizontallyBlurredTexture, gl_TexCoord[0].st + vec2(0.0, dt * 13.5)) +
texture2D(horizontallyBlurredTexture, gl_TexCoord[0].st + vec2(0.0, dt * 15.5))) / 16.0;
gl_FragColor = blurred * blurred.a + texture2D(originalTexture, gl_TexCoord[0].st);
}

View file

@ -116,7 +116,7 @@ protected:
virtual void wheelEvent(QWheelEvent* event);
};
GLCanvas::GLCanvas() : QGLWidget(QGLFormat(QGL::AlphaChannel)) {
GLCanvas::GLCanvas() : QGLWidget(QGLFormat(QGL::NoDepthBuffer, QGL::NoStencilBuffer)) {
}
void GLCanvas::initializeGL() {
@ -418,8 +418,7 @@ void Application::paintGL() {
PerfStat("display");
glEnable(GL_LINE_SMOOTH);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
_myCamera.setTightness (100.0f);
_myCamera.setTargetPosition(_myAvatar.getUprightHeadPosition());

View file

@ -20,7 +20,7 @@ static ProgramObject* createBlurProgram(const QString& direction) {
program->link();
program->bind();
program->setUniformValue("colorTexture", 0);
program->setUniformValue("originalTexture", 0);
program->release();
return program;
@ -30,9 +30,16 @@ void GlowEffect::init() {
switchToResourcesParentIfRequired();
_horizontalBlurProgram = createBlurProgram("horizontal");
_verticalBlurProgram = createBlurProgram("vertical");
_verticalBlurProgram->bind();
_verticalBlurProgram->setUniformValue("horizontallyBlurredTexture", 1);
_verticalBlurProgram->release();
}
void GlowEffect::prepare() {
Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject()->bind();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_isEmpty = true;
}
@ -59,15 +66,10 @@ static void renderFullscreenQuad() {
}
void GlowEffect::render() {
if (_isEmpty) {
return; // nothing glowing
}
QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject();
primaryFBO->release();
glBindTexture(GL_TEXTURE_2D, primaryFBO->texture());
QSize size = primaryFBO->size();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size.width(), size.height());
glPushMatrix();
glLoadIdentity();
@ -76,33 +78,51 @@ void GlowEffect::render() {
glLoadIdentity();
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
// render the primary to the secondary with the horizontal blur
QOpenGLFramebufferObject* secondaryFBO = Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject();
secondaryFBO->bind();
_horizontalBlurProgram->bind();
renderFullscreenQuad();
_horizontalBlurProgram->release();
secondaryFBO->release();
// render the secondary to the screen with the vertical blur
glBindTexture(GL_TEXTURE_2D, secondaryFBO->texture());
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_CONSTANT_ALPHA, GL_ONE);
_verticalBlurProgram->bind();
renderFullscreenQuad();
_verticalBlurProgram->release();
if (_isEmpty) {
// copy the primary to the screen
if (QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()) {
QOpenGLFramebufferObject::blitFramebuffer(NULL, primaryFBO);
} else {
glEnable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glColor3f(1.0f, 1.0f, 1.0f);
renderFullscreenQuad();
glDisable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
}
} else {
// render the primary to the secondary with the horizontal blur
QOpenGLFramebufferObject* secondaryFBO =
Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject();
secondaryFBO->bind();
_horizontalBlurProgram->bind();
renderFullscreenQuad();
_horizontalBlurProgram->release();
secondaryFBO->release();
// render the secondary to the screen with the vertical blur
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, secondaryFBO->texture());
_verticalBlurProgram->bind();
renderFullscreenQuad();
_verticalBlurProgram->release();
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
}
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glBindTexture(GL_TEXTURE_2D, 0);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
}

View file

@ -57,7 +57,8 @@ GLuint TextureCache::getPermutationNormalTextureID() {
QOpenGLFramebufferObject* TextureCache::getPrimaryFramebufferObject() {
if (_primaryFramebufferObject == NULL) {
_primaryFramebufferObject = new QOpenGLFramebufferObject(Application::getInstance()->getGLWidget()->size());
_primaryFramebufferObject = new QOpenGLFramebufferObject(Application::getInstance()->getGLWidget()->size(),
QOpenGLFramebufferObject::Depth);
Application::getInstance()->getGLWidget()->installEventFilter(this);
}
return _primaryFramebufferObject;