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 ]; } ); }