Exemplo n.º 1
0
void ShaderToyApp::draw()
{
    // Bind textures.
    if( mChannel0 ) mChannel0->bind( 0 );
    if( mChannel1 ) mChannel1->bind( 1 );
    if( mChannel2 ) mChannel2->bind( 2 );
    if( mChannel3 ) mChannel3->bind( 3 );

    // Render the current shader to a frame buffer.
    if( mShaderCurrent && mBufferCurrent ) {
        gl::ScopedFramebuffer fbo( mBufferCurrent );

        // Bind shader.
        gl::ScopedGlslProg shader( mShaderCurrent );
        setUniforms();

        // Clear buffer and draw full screen quad (flipped).
        gl::clear();
        gl::drawSolidRect( Rectf( 0, (float)getWindowHeight(), (float)getWindowWidth(), 0 ) );
    }

    // Render the next shader to a frame buffer.
    if( mShaderNext && mBufferNext ) {
        gl::ScopedFramebuffer fbo( mBufferNext );

        // Bind shader.
        gl::ScopedGlslProg shader( mShaderNext );
        setUniforms();

        // Clear buffer and draw full screen quad (flipped).
        gl::clear();
        gl::drawSolidRect( Rectf( 0, (float)getWindowHeight(), (float)getWindowWidth(), 0 ) );
    }

    // Perform a cross-fade between the two shaders.
    double time = getElapsedSeconds() - mTransitionTime;
    double fade = math<double>::clamp( time / mTransitionDuration, 0.0, 1.0 );

    if( fade <= 0.0 ) {
        // Transition has not yet started. Keep drawing current buffer.
        gl::draw( mBufferCurrent->getColorTexture(), getWindowBounds() );
    }
    else if( fade < 1.0 ) {
        // Transition is in progress.
        // Use a transition shader to avoid having to draw one buffer on top of another.
        gl::ScopedTextureBind tex0( mBufferCurrent->getColorTexture(), 0 );
        gl::ScopedTextureBind tex1( mBufferNext->getColorTexture(), 1 );

        gl::ScopedGlslProg shader( mShaderTransition );
        mShaderTransition->uniform( "iSrc", 0 );
        mShaderTransition->uniform( "iDst", 1 );
        mShaderTransition->uniform( "iFade", (float)fade );

        gl::drawSolidRect( getWindowBounds() );
    }
    else if( mShaderNext ) {
        // Transition is done. Swap shaders.
        gl::draw( mBufferNext->getColorTexture(), getWindowBounds() );

        mShaderCurrent = mShaderNext;
        mShaderNext.reset();

        mPathCurrent = mPathNext;
        mPathNext.clear();

        getWindow()->setTitle( std::string( "ShaderToyApp - Showing " ) + mPathCurrent.filename().string() );
    }
    else {
        // No transition in progress.
        gl::draw( mBufferCurrent->getColorTexture(), getWindowBounds() );
    }
}