Esempio n. 1
0
void FrameRenderer::render( Camera& cam, Node& root, const Viewport& vp ) const
{
    /* Start time measurement.
     */
    Stopwatch stopwatch;

    /* Check for errors.
     */
    REPORT_GL_ERROR;

    /* Reshape render stages' buffers.
     */
    for( std::size_t rsIdx = 0; rsIdx < stages(); ++rsIdx )
    {
        RenderStage& rs = stageAt( rsIdx );
        
        /* Ensure buffers are properly sized.
         */
        if( pimpl->reshaped || !rs.isInitialized() )
        {
            /* This 'const_cast' is okay, because 'RenderStage' objects are clearly
             * stated to be components of a 'FrameRenderer', thus "it runs in the
             * family" as long as an immutable 'RenderStage' reference not induces a
             * mutable 'FrameRenderer' reference.
             */
            FrameRenderer& fr = const_cast< FrameRenderer& >( *this );
            rs.reshape( fr, pimpl->viewport->width(), pimpl->viewport->height() );
        }

        /* Notify stages of beginning frame.
         */
        rs.prepareFrame( root );
    }
    
    /* Mark that all buffer sizes have been established.
     */
    pimpl->reshaped = false;

    /* Clear buffers.
     */
    glClearColor
        ( pimpl->backgroundColor[ 0 ]
        , pimpl->backgroundColor[ 1 ]
        , pimpl->backgroundColor[ 2 ]
        , pimpl->backgroundColor[ 3 ] );
    
    /* Render frame.
     */
    RenderTask task( *this, cam.projection(), cam.viewTransform() );
    task.render( vp, GLContext::COLOR_BUFFER_BIT | GLContext::DEPTH_BUFFER_BIT );

    /* Check for errors.
     */
    REPORT_GL_ERROR;
    
    /* Stop and evaluate time measurement.
     */
    const double time = stopwatch.result();
    const double fps  = 1 / time;
    pimpl->fpsData.push( fps );
    pimpl->fpsStatistics = math::Statistics< double >( pimpl->fpsData.size(),
        [&]( std::size_t idx )->double
        {
            return pimpl->fpsData[ idx ];
        }
    );
}