Ejemplo n.º 1
0
QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) {
    QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject();
    primaryFBO->release();
    glBindTexture(GL_TEXTURE_2D, primaryFBO->texture());

    glPushMatrix();
    glLoadIdentity();
    
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    
    glDisable(GL_BLEND);
    glDisable(GL_DEPTH_TEST);
    glDepthMask(GL_FALSE);
    
    QOpenGLFramebufferObject* destFBO = toTexture ?
        Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject() : NULL;
    if (_isEmpty && _renderMode != DIFFUSE_ADD_MODE) {
        // copy the primary to the screen
        if (QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()) {
            QOpenGLFramebufferObject::blitFramebuffer(destFBO, primaryFBO);
                
        } else {
            maybeBind(destFBO);
            glEnable(GL_TEXTURE_2D);
            glDisable(GL_LIGHTING);
            glColor3f(1.0f, 1.0f, 1.0f);
            renderFullscreenQuad();    
            glDisable(GL_TEXTURE_2D);
            glEnable(GL_LIGHTING);
            maybeRelease(destFBO);
        }
    } else if (_renderMode == ADD_MODE) {
        maybeBind(destFBO);
        _addProgram->bind();
        renderFullscreenQuad();
        _addProgram->release();
        maybeRelease(destFBO);
    
    } else if (_renderMode == DIFFUSE_ADD_MODE) {
        // diffuse into the secondary/tertiary (alternating between frames)
        QOpenGLFramebufferObject* oldDiffusedFBO =
            Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject();
        QOpenGLFramebufferObject* newDiffusedFBO =
            Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject();
        if (_isOddFrame) {
            qSwap(oldDiffusedFBO, newDiffusedFBO);
        }
        newDiffusedFBO->bind();
        
        if (_isFirstFrame) {
            glClear(GL_COLOR_BUFFER_BIT);    
            
        } else {
            glActiveTexture(GL_TEXTURE1);
            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();
        
        // add diffused texture to the primary
        glBindTexture(GL_TEXTURE_2D, newDiffusedFBO->texture());
        
        if (toTexture) {
            destFBO = oldDiffusedFBO;
        }
        maybeBind(destFBO);
        _addSeparateProgram->bind();      
        renderFullscreenQuad();
        _addSeparateProgram->release();
        maybeRelease(destFBO);
        
        glBindTexture(GL_TEXTURE_2D, 0);
        glActiveTexture(GL_TEXTURE0);
        
    } else { // _renderMode == BLUR_ADD_MODE || _renderMode == BLUR_PERSIST_ADD_MODE
        // 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();
        
        if (_renderMode == BLUR_ADD_MODE) {
            // render the secondary to the screen with the vertical blur
            glActiveTexture(GL_TEXTURE1);
            glBindTexture(GL_TEXTURE_2D, secondaryFBO->texture());
            
            if (toTexture) {
                destFBO = Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject();
            }
            maybeBind(destFBO);
            _verticalBlurAddProgram->bind();      
            renderFullscreenQuad();
            _verticalBlurAddProgram->release();
            maybeRelease(destFBO);
            
        } else { // _renderMode == BLUR_PERSIST_ADD_MODE
            // render the secondary to the tertiary with vertical blur and persistence
            QOpenGLFramebufferObject* tertiaryFBO =
                Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject();
            tertiaryFBO->bind();
            
            glEnable(GL_BLEND);
            glBlendFunc(GL_ONE_MINUS_CONSTANT_ALPHA, GL_CONSTANT_ALPHA);
            const float PERSISTENCE_SMOOTHING = 0.9f;
            glBlendColor(0.0f, 0.0f, 0.0f, _isFirstFrame ? 0.0f : PERSISTENCE_SMOOTHING);
            
            glBindTexture(GL_TEXTURE_2D, secondaryFBO->texture());
            
            _verticalBlurProgram->bind();      
            renderFullscreenQuad();
            _verticalBlurProgram->release();
        
            glBlendColor(0.0f, 0.0f, 0.0f, 0.0f);
            glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
            glDisable(GL_BLEND);
        
            // now add the tertiary to the primary buffer
            tertiaryFBO->release();
            
            glBindTexture(GL_TEXTURE_2D, primaryFBO->texture());
            
            glActiveTexture(GL_TEXTURE1);
            glBindTexture(GL_TEXTURE_2D, tertiaryFBO->texture());
            
            maybeBind(destFBO);
            _addSeparateProgram->bind();      
            renderFullscreenQuad();
            _addSeparateProgram->release();
            maybeRelease(destFBO);
        }
        
        glBindTexture(GL_TEXTURE_2D, 0);
        glActiveTexture(GL_TEXTURE0);
    }
    
    glPopMatrix();
    
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
       
    glEnable(GL_BLEND);
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glBindTexture(GL_TEXTURE_2D, 0);
    
    _isFirstFrame = false;
    
    return destFBO;
}
Ejemplo n.º 2
0
QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) {
    PerformanceTimer perfTimer("glowEffect");

    TextureCache* textureCache = DependencyManager::get<TextureCache>();
    QOpenGLFramebufferObject* primaryFBO = textureCache->getPrimaryFramebufferObject();
    primaryFBO->release();
    glBindTexture(GL_TEXTURE_2D, primaryFBO->texture());

    glPushMatrix();
    glLoadIdentity();
    
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    
    glDisable(GL_BLEND);
    glDisable(GL_DEPTH_TEST);
    glDepthMask(GL_FALSE);

    QOpenGLFramebufferObject* destFBO = toTexture ?
        textureCache->getSecondaryFramebufferObject() : NULL;
    if (!Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect) || _isEmpty) {
        // copy the primary to the screen
        if (destFBO && QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()) {
            QOpenGLFramebufferObject::blitFramebuffer(destFBO, primaryFBO);          
        } else {
            maybeBind(destFBO);
            if (!destFBO) {
                glViewport(0, 0, Application::getInstance()->getGLWidget()->getDeviceWidth(),
                    Application::getInstance()->getGLWidget()->getDeviceHeight());
            }
            glEnable(GL_TEXTURE_2D);
            glDisable(GL_LIGHTING);
            glColor3f(1.0f, 1.0f, 1.0f);
            renderFullscreenQuad();
            glDisable(GL_TEXTURE_2D);
            glEnable(GL_LIGHTING);
            maybeRelease(destFBO);
        }
    } else {
        // diffuse into the secondary/tertiary (alternating between frames)
        QOpenGLFramebufferObject* oldDiffusedFBO =
            textureCache->getSecondaryFramebufferObject();
        QOpenGLFramebufferObject* newDiffusedFBO =
            textureCache->getTertiaryFramebufferObject();
        if (_isOddFrame) {
            qSwap(oldDiffusedFBO, newDiffusedFBO);
        }
        newDiffusedFBO->bind();
        
        if (_isFirstFrame) {
            glClear(GL_COLOR_BUFFER_BIT);    
            
        } else {
            glActiveTexture(GL_TEXTURE1);
            glBindTexture(GL_TEXTURE_2D, oldDiffusedFBO->texture());
            
            _diffuseProgram->bind();
            QSize size = primaryFBO->size();
            _diffuseProgram->setUniformValue(_diffusionScaleLocation, 1.0f / size.width(), 1.0f / size.height());
        
            renderFullscreenQuad();
        
            _diffuseProgram->release();
        }
        
        newDiffusedFBO->release();
        
        // add diffused texture to the primary
        glBindTexture(GL_TEXTURE_2D, newDiffusedFBO->texture());
        
        if (toTexture) {
            destFBO = oldDiffusedFBO;
        }
        maybeBind(destFBO);
        if (!destFBO) {
            glViewport(0, 0,
                Application::getInstance()->getGLWidget()->getDeviceWidth(),
                Application::getInstance()->getGLWidget()->getDeviceHeight());
        }
        _addSeparateProgram->bind();      
        renderFullscreenQuad();
        _addSeparateProgram->release();
        maybeRelease(destFBO);
        
        glBindTexture(GL_TEXTURE_2D, 0);
        glActiveTexture(GL_TEXTURE0);
        
    }
    
    glPopMatrix();
    
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
       
    glEnable(GL_BLEND);
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glBindTexture(GL_TEXTURE_2D, 0);
    
    _isFirstFrame = false;
    
    return destFBO;
}