Пример #1
0
void Channel::frameAssemble( const eq::uint128_t& frameID )
{
    const bool composeOnly = (_drawRange == eq::Range::ALL);
    eq::FrameData* data = _frame.getData();

    _startAssemble();

    const eq::Frames& frames = getInputFrames();
    eq::PixelViewport  coveredPVP;
    eq::Frames    dbFrames;
    eq::Zoom           zoom( eq::Zoom::NONE );

    // Make sure all frames are ready and gather some information on them
    for( eq::Frames::const_iterator i = frames.begin();
         i != frames.end(); ++i )
    {
        eq::Frame* frame = *i;
        {
            eq::ChannelStatistics stat( eq::Statistic::CHANNEL_FRAME_WAIT_READY,
                                        this );
            frame->waitReady( );
        }
        const eq::Range& range = frame->getRange();
        if( range == eq::Range::ALL ) // 2D frame, assemble directly
            eq::Compositor::assembleFrame( frame, this );
        else
        {
            dbFrames.push_back( frame );
            zoom = frame->getZoom();
            _expandPVP( coveredPVP, frame->getImages(), frame->getOffset() );
        }
    }
    coveredPVP.intersect( getPixelViewport( ));

    if( dbFrames.empty( ))
    {
        resetAssemblyState();
        return;
    }

    // calculate correct frames sequence
    if( !composeOnly && coveredPVP.hasArea( ))
    {
        _frame.clear();
        data->setRange( _drawRange );
        dbFrames.push_back( &_frame );
    }

    _orderFrames( dbFrames );

    // check if current frame is in proper position, read back if not
    if( !composeOnly )
    {
        if( _bgColor == eq::Vector3f::ZERO && dbFrames.front() == &_frame )
            dbFrames.erase( dbFrames.begin( ));
        else if( coveredPVP.hasArea())
        {
            eq::Window::ObjectManager* glObjects = getObjectManager();

            _frame.setOffset( eq::Vector2i( 0, 0 ));
            _frame.setZoom( zoom );
            data->setPixelViewport( coveredPVP );
            _frame.readback( glObjects, getDrawableConfig( ));
            clearViewport( coveredPVP );

            // offset for assembly
            _frame.setOffset( eq::Vector2i( coveredPVP.x, coveredPVP.y ));
        }
    }

    // blend DB frames in order
    try
    {
        eq::Compositor::assembleFramesSorted( dbFrames, this, 0, 
                                              true /*blendAlpha*/ );
    }
    catch( eq::Exception e )
    {
        EQWARN << e << std::endl;
    }

    resetAssemblyState();

    // Update range
    _drawRange = getRange();
}
Пример #2
0
void Channel::frameAssemble( const eq::uint128_t&, const eq::Frames& frames )
{
    _startAssemble();

    eq::PixelViewport  coveredPVP;
    eq::ImageOps       dbImages;
    eq::Zoom           zoom( eq::Zoom::NONE );

    // Make sure all frames are ready and gather some information on them
    for( eq::Frame* frame : frames )
    {
        {
            eq::ChannelStatistics stat( eq::Statistic::CHANNEL_FRAME_WAIT_READY,
                                        this );
            frame->waitReady( );
        }
        for( eq::Image* image : frame->getImages( ))
        {
            eq::ImageOp op( frame, image );
            op.offset = frame->getOffset();
            const eq::Range& range = image->getContext().range;
            if( range == eq::Range::ALL ) // 2D frame, assemble directly
                eq::Compositor::assembleImage( op, this );
            else
            {
                dbImages.emplace_back( op );
                zoom = frame->getZoom();
                coveredPVP.merge( image->getPixelViewport() + frame->getOffset());
            }
        }
    }
    if( dbImages.empty( ))
    {
        resetAssemblyState();
        return;
    }

    // calculate correct image sequence
    const bool dbCompose = _image.getContext().range != eq::Range::ALL;
    coveredPVP.intersect( getPixelViewport( ));
    if( dbCompose && coveredPVP.hasArea( ))
    {
        eq::ImageOp op;
        op.image = &_image;
        op.buffers = eq::Frame::BUFFER_COLOR;
        op.zoom = zoom;
        op.offset = eq::Vector2i( coveredPVP.x, coveredPVP.y );
        dbImages.emplace_back( op );
    }

    _orderImages( dbImages );

    // check if current image is in proper position, read back if not
    if( dbCompose )
    {
        if( _bgColor == eq::Vector3f() && dbImages.front().image == &_image)
            dbImages.erase( dbImages.begin( ));
        else if( coveredPVP.hasArea())
        {
            eq::util::ObjectManager& glObjects = getObjectManager();
            eq::PixelViewport pvp = getRegion();
            pvp.intersect( coveredPVP );

            // Update range
            eq::Range range( 1.f, 0.f );
            for( const eq::ImageOp& op : dbImages )
            {
                const eq::Range& r = op.image->getContext().range;
                range.start = std::min( range.start, r.start );
                range.end = std::max( range.end, r.end );
            }
            eq::RenderContext context = _image.getContext();
            context.range = range;

            if( _image.startReadback( eq::Frame::BUFFER_COLOR, pvp, context,
                                      zoom, glObjects ))
            {
                _image.finishReadback( glewGetContext( ));
            }
            clearViewport( coveredPVP );
        }
    }

    glEnable( GL_BLEND );
    LBASSERT( GLEW_EXT_blend_func_separate );
    glBlendFuncSeparate( GL_ONE, GL_SRC_ALPHA, GL_ZERO, GL_SRC_ALPHA );

    eq::Compositor::blendImages( dbImages, this, 0 );
    resetAssemblyState();
}