Merge pull request #875 from ey6es/master

Fix for diffuse glow with SSAO, made diffuse glow the default, improved performance, added debug statements.
This commit is contained in:
ZappoMan 2013-08-20 18:04:10 -07:00
commit c320a87d5a
4 changed files with 54 additions and 18 deletions

View file

@ -14,15 +14,14 @@ uniform sampler2D originalTexture;
// the texture containing the diffused color
uniform sampler2D diffusedTexture;
// the scale of diffusion
uniform vec2 diffusionScale;
void main(void) {
float ds = dFdx(gl_TexCoord[0].s);
float dt = dFdy(gl_TexCoord[0].t);
gl_FragColor = (texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(-ds, -dt)) +
texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(0.0, -dt)) +
texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(ds, -dt)) +
texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(ds, 0.0)) +
texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(ds, dt)) +
texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(0.0, dt)) +
texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(-ds, dt)) +
texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(-ds, 0.0))) / 8.5 + texture2D(originalTexture, gl_TexCoord[0].st) * 0.1;
vec2 minExtents = gl_TexCoord[0].st + diffusionScale * vec2(-1.5, -1.5);
vec2 maxExtents = gl_TexCoord[0].st + diffusionScale * vec2(1.5, 1.5);
gl_FragColor = (texture2D(diffusedTexture, minExtents) +
texture2D(diffusedTexture, vec2(maxExtents.s, minExtents.t)) +
texture2D(diffusedTexture, vec2(minExtents.s, maxExtents.t)) +
texture2D(diffusedTexture, maxExtents)) * 0.235 + texture2D(originalTexture, gl_TexCoord[0].st) * 0.1;
}

View file

@ -97,9 +97,9 @@ void AmbientOcclusionEffect::render() {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, _rotationTextureID);
// render with the occlusion shader to the secondary buffer
QOpenGLFramebufferObject* secondaryFBO = Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject();
secondaryFBO->bind();
// render with the occlusion shader to the secondary/tertiary buffer
QOpenGLFramebufferObject* freeFBO = Application::getInstance()->getGlowEffect()->getFreeFramebufferObject();
freeFBO->bind();
float left, right, bottom, top, nearVal, farVal;
glm::vec4 nearClipPlane, farClipPlane;
@ -119,7 +119,7 @@ void AmbientOcclusionEffect::render() {
_occlusionProgram->release();
secondaryFBO->release();
freeFBO->release();
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
@ -130,7 +130,7 @@ void AmbientOcclusionEffect::render() {
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE);
glBindTexture(GL_TEXTURE_2D, secondaryFBO->texture());
glBindTexture(GL_TEXTURE_2D, freeFBO->texture());
_blurProgram->bind();
_blurProgram->setUniformValue(_blurScaleLocation, 1.0f / size.width(), 1.0f / size.height());

View file

@ -15,7 +15,13 @@
#include "ProgramObject.h"
#include "RenderUtil.h"
GlowEffect::GlowEffect() : _renderMode(BLUR_ADD_MODE) {
GlowEffect::GlowEffect() : _renderMode(DIFFUSE_ADD_MODE), _isOddFrame(false) {
}
QOpenGLFramebufferObject* GlowEffect::getFreeFramebufferObject() const {
return (_renderMode == DIFFUSE_ADD_MODE && !_isOddFrame) ?
Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject() :
Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject();
}
static ProgramObject* createProgram(const QString& name) {
@ -51,6 +57,8 @@ void GlowEffect::init() {
_diffuseProgram->bind();
_diffuseProgram->setUniformValue("diffusedTexture", 1);
_diffuseProgram->release();
_diffusionScaleLocation = _diffuseProgram->uniformLocation("diffusionScale");
}
void GlowEffect::prepare() {
@ -58,6 +66,7 @@ void GlowEffect::prepare() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_isEmpty = true;
_isOddFrame = !_isOddFrame;
}
void GlowEffect::begin(float intensity) {
@ -109,7 +118,7 @@ void GlowEffect::render() {
Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject();
QOpenGLFramebufferObject* newDiffusedFBO =
Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject();
if ((_isOddFrame = !_isOddFrame)) {
if (_isOddFrame) {
qSwap(oldDiffusedFBO, newDiffusedFBO);
}
newDiffusedFBO->bind();
@ -118,7 +127,11 @@ void GlowEffect::render() {
glBindTexture(GL_TEXTURE_2D, oldDiffusedFBO->texture());
_diffuseProgram->bind();
QSize size = Application::getInstance()->getGLWidget()->size();
_diffuseProgram->setUniformValue(_diffusionScaleLocation, 1.0f / size.width(), 1.0f / size.height());
renderFullscreenQuad();
_diffuseProgram->release();
newDiffusedFBO->release();
@ -204,5 +217,22 @@ void GlowEffect::render() {
}
void GlowEffect::cycleRenderMode() {
_renderMode = (RenderMode)((_renderMode + 1) % RENDER_MODE_COUNT);
switch(_renderMode = (RenderMode)((_renderMode + 1) % RENDER_MODE_COUNT)) {
case ADD_MODE:
qDebug() << "Glow mode: Add\n";
break;
case BLUR_ADD_MODE:
qDebug() << "Glow mode: Blur/add\n";
break;
case BLUR_PERSIST_ADD_MODE:
qDebug() << "Glow mode: Blur/persist/add\n";
break;
default:
case DIFFUSE_ADD_MODE:
qDebug() << "Glow mode: Diffuse/add\n";
break;
}
}

View file

@ -11,6 +11,8 @@
#include <QObject>
class QOpenGLFramebufferObject;
class ProgramObject;
/// A generic full screen glow effect.
@ -21,6 +23,10 @@ public:
GlowEffect();
/// 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;
void init();
/// Prepares the glow effect for rendering the current frame. To be called before rendering the scene.
@ -51,6 +57,7 @@ private:
ProgramObject* _verticalBlurProgram;
ProgramObject* _addSeparateProgram;
ProgramObject* _diffuseProgram;
int _diffusionScaleLocation;
bool _isEmpty; ///< set when nothing in the scene is currently glowing
bool _isOddFrame; ///< controls the alternation between texture targets in diffuse add mode