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