00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "channel.h"
00020
00021 #include "frameData.h"
00022 #include "initData.h"
00023 #include "node.h"
00024 #include "pipe.h"
00025 #include "window.h"
00026 #include "hlp.h"
00027 #include "framesOrderer.h"
00028 #include <eq/client/zoom.h>
00029
00030 using namespace eq::base;
00031 using namespace std;
00032
00033 namespace eVolve
00034 {
00035 Channel::Channel( eq::Window* parent )
00036 : eq::Channel( parent )
00037 , _bgColor( eq::Vector3f::ZERO )
00038 , _drawRange( eq::Range::ALL )
00039 {
00040 eq::FrameData* frameData = new eq::FrameData;
00041 frameData->setBuffers( eq::Frame::BUFFER_COLOR );
00042 _frame.setData( frameData );
00043 }
00044
00045 static void checkError( const std::string& msg )
00046 {
00047 const GLenum error = glGetError();
00048 if (error != GL_NO_ERROR)
00049 EQERROR << msg << " GL Error: " << error << endl;
00050 }
00051
00052
00053 bool Channel::configInit( const uint32_t initID )
00054 {
00055 if( !eq::Channel::configInit( initID ))
00056 return false;
00057 EQINFO << "Init channel initID " << initID << " ptr " << this << endl;
00058
00059
00060 setNearFar( 0.001f, 10.0f );
00061
00062 if( getenv( "EQ_TAINT_CHANNELS" ))
00063 {
00064 _bgColor = getUniqueColor();
00065 _bgColor /= 255.f;
00066 }
00067
00068 return true;
00069 }
00070
00071 void Channel::frameStart( const uint32_t frameID, const uint32_t frameNumber )
00072 {
00073 _drawRange = eq::Range::ALL;
00074 eq::Channel::frameStart( frameID, frameNumber );
00075 }
00076
00077 void Channel::frameClear( const uint32_t frameID )
00078 {
00079 applyBuffer();
00080 applyViewport();
00081
00082 if( getRange() == eq::Range::ALL )
00083 glClearColor( _bgColor.r(), _bgColor.g(), _bgColor.b(), 1.0f );
00084 else
00085 glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
00086
00087 glClear( GL_COLOR_BUFFER_BIT );
00088 }
00089
00090
00091 static void setLights( eq::Matrix4f& invRotationM )
00092 {
00093 GLfloat lightAmbient[] = {0.05f, 0.05f, 0.05f, 1.0f};
00094 GLfloat lightDiffuse[] = {0.9f , 0.9f , 0.9f , 1.0f};
00095 GLfloat lightSpecular[] = {0.8f , 0.8f , 0.8f , 1.0f};
00096 GLfloat lightPosition[] = {1.0f , 1.0f , 1.0f , 0.0f};
00097
00098 glLightfv( GL_LIGHT0, GL_AMBIENT, lightAmbient );
00099 glLightfv( GL_LIGHT0, GL_DIFFUSE, lightDiffuse );
00100 glLightfv( GL_LIGHT0, GL_SPECULAR, lightSpecular );
00101
00102
00103
00104
00105 glPushMatrix();
00106 glMultMatrixf( invRotationM.array );
00107 glLightfv( GL_LIGHT0, GL_POSITION, lightPosition );
00108 glPopMatrix();
00109 }
00110
00111
00112 void Channel::frameDraw( const uint32_t frameID )
00113 {
00114
00115 eq::Channel::frameDraw( frameID );
00116
00117 const FrameData::Data& frameData = _getFrameData();
00118 eq::Matrix4f invRotationM;
00119 frameData.rotation.inverse( invRotationM );
00120 setLights( invRotationM );
00121
00122 glTranslatef( frameData.translation.x(), frameData.translation.y(),
00123 frameData.translation.z() );
00124 glMultMatrixf( frameData.rotation.array );
00125
00126 Pipe* pipe = static_cast<Pipe*>( getPipe( ));
00127 Renderer* renderer = pipe->getRenderer();
00128 EQASSERT( renderer );
00129
00130 eq::Matrix4f modelviewM;
00131 eq::Matrix3f modelviewITM;
00132 _calcMVandITMV( modelviewM, modelviewITM );
00133
00134 const eq::Range& range = getRange();
00135 renderer->render( range, modelviewM, modelviewITM, invRotationM );
00136
00137 checkError( "error during rendering " );
00138
00139 _drawRange = range;
00140
00141 #ifndef NDEBUG
00142 outlineViewport();
00143 #endif
00144 }
00145
00146 const FrameData::Data& Channel::_getFrameData() const
00147 {
00148 const Pipe* pipe = static_cast< const Pipe* >( getPipe( ));
00149 return pipe->getFrameData();
00150 }
00151
00152 void Channel::applyFrustum() const
00153 {
00154 const FrameData::Data& frameData = _getFrameData();
00155
00156 if( frameData.ortho )
00157 eq::Channel::applyOrtho();
00158 else
00159 eq::Channel::applyFrustum();
00160 }
00161
00162
00163 void Channel::_calcMVandITMV(
00164 eq::Matrix4f& modelviewM,
00165 eq::Matrix3f& modelviewITM ) const
00166 {
00167 const FrameData::Data& frameData = _getFrameData();
00168 const Pipe* pipe = static_cast< const Pipe* >( getPipe( ));
00169 const Renderer* renderer = pipe->getRenderer();
00170
00171 if( renderer )
00172 {
00173 const VolumeScaling& volScaling = renderer->getVolumeScaling();
00174
00175 eq::Matrix4f scale( eq::Matrix4f::ZERO );
00176 scale.at(0,0) = volScaling.W;
00177 scale.at(1,1) = volScaling.H;
00178 scale.at(2,2) = volScaling.D;
00179 scale.at(3,3) = 1.f;
00180
00181 modelviewM = scale * frameData.rotation;
00182 }
00183 modelviewM.set_translation( frameData.translation );
00184
00185 modelviewM = getHeadTransform() * modelviewM;
00186
00187
00188 eq::Matrix4f modelviewIM;
00189 modelviewM.inverse( modelviewIM );
00190 eq::Matrix3f( modelviewIM ).transpose_to( modelviewITM );
00191 }
00192
00193
00194 static void _expandPVP( eq::PixelViewport& pvp,
00195 const vector< eq::Image* >& images,
00196 const eq::Vector2i& offset )
00197 {
00198 for( vector< eq::Image* >::const_iterator i = images.begin();
00199 i != images.end(); ++i )
00200 {
00201 const eq::PixelViewport imagePVP = (*i)->getPixelViewport() + offset;
00202 pvp.merge( imagePVP );
00203 }
00204 }
00205
00206
00207 void Channel::clearViewport( const eq::PixelViewport &pvp )
00208 {
00209
00210 glScissor( pvp.x, pvp.y, pvp.w, pvp.h );
00211 glClearColor( _bgColor.r(), _bgColor.g(), _bgColor.b(), 1.0f );
00212 glClear( GL_COLOR_BUFFER_BIT );
00213
00214
00215 const eq::PixelViewport& windowPVP = getWindow()->getPixelViewport();
00216 glScissor( 0, 0, windowPVP.w, windowPVP.h );
00217 }
00218
00219 void Channel::_orderFrames( eq::FrameVector& frames )
00220 {
00221 eq::Matrix4f modelviewM;
00222 eq::Matrix3f modelviewITM;
00223 const FrameData::Data& frameData = _getFrameData();
00224 const eq::Matrix4f& rotation = frameData.rotation;
00225
00226 if( !frameData.ortho )
00227 _calcMVandITMV( modelviewM, modelviewITM );
00228
00229 orderFrames( frames, modelviewM, modelviewITM, rotation, frameData.ortho );
00230 }
00231
00232
00233 void Channel::frameAssemble( const uint32_t frameID )
00234 {
00235 const bool composeOnly = (_drawRange == eq::Range::ALL);
00236
00237 _startAssemble();
00238
00239 const eq::FrameVector& frames = getInputFrames();
00240 eq::PixelViewport coveredPVP;
00241 eq::FrameVector dbFrames;
00242 eq::Zoom zoom( eq::Zoom::NONE );
00243
00244
00245 for( eq::FrameVector::const_iterator i = frames.begin();
00246 i != frames.end(); ++i )
00247 {
00248 eq::Frame* frame = *i;
00249 {
00250 eq::ChannelStatistics stat(eq::Statistic::CHANNEL_WAIT_FRAME, this);
00251 frame->waitReady( );
00252 }
00253 const eq::Range& curRange = frame->getRange();
00254 if( curRange == eq::Range::ALL )
00255 eq::Compositor::assembleFrame( frame, this );
00256 else
00257 {
00258 dbFrames.push_back( frame );
00259 zoom = frame->getZoom();
00260 _expandPVP( coveredPVP, frame->getImages(), frame->getOffset() );
00261 }
00262 }
00263 coveredPVP.intersect( getPixelViewport( ));
00264
00265 if( dbFrames.empty( ))
00266 {
00267 resetAssemblyState();
00268 return;
00269 }
00270
00271
00272 if( !composeOnly && coveredPVP.hasArea( ))
00273 {
00274 _frame.clear();
00275 _frame.setRange( _drawRange );
00276 dbFrames.push_back( &_frame );
00277 }
00278
00279 _orderFrames( dbFrames );
00280
00281
00282 if( !composeOnly )
00283 {
00284 if( _bgColor == eq::Vector3f::ZERO && dbFrames.front() == &_frame )
00285 dbFrames.erase( dbFrames.begin( ));
00286 else if( coveredPVP.hasArea())
00287 {
00288 eq::Window::ObjectManager* glObjects = getObjectManager();
00289
00290 _frame.setOffset( eq::Vector2i( 0, 0 ));
00291 _frame.setZoom( zoom );
00292 _frame.setPixelViewport( coveredPVP );
00293 _frame.startReadback( glObjects );
00294 clearViewport( coveredPVP );
00295 _frame.syncReadback();
00296
00297
00298 _frame.setOffset( eq::Vector2i( coveredPVP.x, coveredPVP.y ));
00299 }
00300 }
00301
00302
00303 eq::Compositor::assembleFramesSorted( dbFrames, this, true );
00304 resetAssemblyState();
00305
00306
00307 _drawRange = getRange();
00308 }
00309
00310 void Channel::_startAssemble()
00311 {
00312 applyBuffer();
00313 applyViewport();
00314 setupAssemblyState();
00315 }
00316
00317 void Channel::frameReadback( const uint32_t frameID )
00318 {
00319
00320 const eq::FrameVector& frames = getOutputFrames();
00321 for( eq::FrameVector::const_iterator i = frames.begin();
00322 i != frames.end(); ++i )
00323 {
00324 (*i)->disableBuffer( eq::Frame::BUFFER_DEPTH );
00325 }
00326
00327 eq::Channel::frameReadback( frameID );
00328 }
00329
00330 void Channel::frameViewFinish( const uint32_t frameID )
00331 {
00332
00333 const Window* window = static_cast<Window*>( getWindow( ));
00334 GLuint texture;
00335 eq::Vector2i size;
00336
00337 window->getLogoTexture( texture, size );
00338 if( !texture )
00339 return;
00340
00341 glMatrixMode( GL_PROJECTION );
00342 glLoadIdentity();
00343 applyScreenFrustum();
00344 glMatrixMode( GL_MODELVIEW );
00345 glLoadIdentity();
00346
00347 glDisable( GL_DEPTH_TEST );
00348 glDisable( GL_LIGHTING );
00349 glEnable( GL_BLEND );
00350 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
00351
00352 glEnable( GL_TEXTURE_RECTANGLE_ARB );
00353 glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture );
00354 glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
00355 GL_LINEAR );
00356 glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
00357 GL_LINEAR );
00358
00359 glColor3f( 1.0f, 1.0f, 1.0f );
00360 glBegin( GL_TRIANGLE_STRIP ); {
00361 glTexCoord2f( 0.0f, 0.0f );
00362 glVertex3f( 5.0f, 5.0f, 0.0f );
00363
00364 glTexCoord2f( size.x(), 0.0f );
00365 glVertex3f( size.x() + 5.0f, 5.0f, 0.0f );
00366
00367 glTexCoord2f( 0.0f, size.y() );
00368 glVertex3f( 5.0f, size.y() + 5.0f, 0.0f );
00369
00370 glTexCoord2f( size.x(), size.y() );
00371 glVertex3f( size.x() + 5.0f, size.y() + 5.0f, 0.0f );
00372 } glEnd();
00373
00374 glDisable( GL_TEXTURE_RECTANGLE_ARB );
00375 glDisable( GL_BLEND );
00376 }
00377
00378 }