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_GL_CALL( applyBuffer( ));
00116 EQ_GL_CALL( applyViewport( ));
00117
00118 EQ_GL_CALL( glMatrixMode( GL_PROJECTION ));
00119 EQ_GL_CALL( glLoadIdentity( ));
00120 EQ_GL_CALL( applyFrustum( ));
00121
00122 EQ_GL_CALL( glMatrixMode( GL_MODELVIEW ));
00123 EQ_GL_CALL( glLoadIdentity( ));
00124
00125
00126
00127 const FrameData& frameData = _getFrameData();
00128 const eq::Matrix4f& rotation = frameData.getRotation();
00129 const eq::Vector3f& translation = frameData.getTranslation();
00130
00131 eq::Matrix4f invRotationM;
00132 rotation.inverse( invRotationM );
00133 setLights( invRotationM );
00134
00135 EQ_GL_CALL( applyHeadTransform( ));
00136
00137 glTranslatef( translation.x(), translation.y(), translation.z() );
00138 glMultMatrixf( rotation.array );
00139
00140 Pipe* pipe = static_cast<Pipe*>( getPipe( ));
00141 Renderer* renderer = pipe->getRenderer();
00142 EQASSERT( renderer );
00143
00144 eq::Matrix4f modelviewM;
00145 eq::Matrix3f modelviewITM;
00146 _calcMVandITMV( modelviewM, modelviewITM );
00147
00148 const eq::Range& range = getRange();
00149 renderer->render( range, modelviewM, modelviewITM, invRotationM );
00150
00151 checkError( "error during rendering " );
00152
00153 _drawRange = range;
00154
00155 #ifndef NDEBUG
00156 outlineViewport();
00157 #endif
00158 }
00159
00160 const FrameData& Channel::_getFrameData() const
00161 {
00162 const Pipe* pipe = static_cast< const Pipe* >( getPipe( ));
00163 return pipe->getFrameData();
00164 }
00165
00166 void Channel::applyFrustum() const
00167 {
00168 const FrameData& frameData = _getFrameData();
00169
00170 if( frameData.useOrtho( ))
00171 eq::Channel::applyOrtho();
00172 else
00173 eq::Channel::applyFrustum();
00174 }
00175
00176
00177 void Channel::_calcMVandITMV(
00178 eq::Matrix4f& modelviewM,
00179 eq::Matrix3f& modelviewITM ) const
00180 {
00181 const FrameData& frameData = _getFrameData();
00182 const Pipe* pipe = static_cast< const Pipe* >( getPipe( ));
00183 const Renderer* renderer = pipe->getRenderer();
00184
00185 if( renderer )
00186 {
00187 const VolumeScaling& volScaling = renderer->getVolumeScaling();
00188
00189 eq::Matrix4f scale( eq::Matrix4f::ZERO );
00190 scale.at(0,0) = volScaling.W;
00191 scale.at(1,1) = volScaling.H;
00192 scale.at(2,2) = volScaling.D;
00193 scale.at(3,3) = 1.f;
00194
00195 modelviewM = scale * frameData.getRotation();
00196 }
00197 modelviewM.set_translation( frameData.getTranslation( ));
00198
00199 modelviewM = getHeadTransform() * modelviewM;
00200
00201
00202 eq::Matrix4f modelviewIM;
00203 modelviewM.inverse( modelviewIM );
00204 eq::Matrix3f( modelviewIM ).transpose_to( modelviewITM );
00205 }
00206
00207
00208 static void _expandPVP( eq::PixelViewport& pvp,
00209 const vector< eq::Image* >& images,
00210 const eq::Vector2i& offset )
00211 {
00212 for( vector< eq::Image* >::const_iterator i = images.begin();
00213 i != images.end(); ++i )
00214 {
00215 const eq::PixelViewport imagePVP = (*i)->getPixelViewport() + offset;
00216 pvp.merge( imagePVP );
00217 }
00218 }
00219
00220
00221 void Channel::clearViewport( const eq::PixelViewport &pvp )
00222 {
00223
00224 glScissor( pvp.x, pvp.y, pvp.w, pvp.h );
00225 glClearColor( _bgColor.r(), _bgColor.g(), _bgColor.b(), 1.0f );
00226 glClear( GL_COLOR_BUFFER_BIT );
00227
00228
00229 const eq::PixelViewport& windowPVP = getWindow()->getPixelViewport();
00230 glScissor( 0, 0, windowPVP.w, windowPVP.h );
00231 }
00232
00233 void Channel::_orderFrames( eq::FrameVector& frames )
00234 {
00235 eq::Matrix4f modelviewM;
00236 eq::Matrix3f modelviewITM;
00237 const FrameData& frameData = _getFrameData();
00238 const eq::Matrix4f& rotation = frameData.getRotation();
00239
00240 if( !frameData.useOrtho( ))
00241 _calcMVandITMV( modelviewM, modelviewITM );
00242
00243 orderFrames( frames, modelviewM, modelviewITM, rotation, frameData.useOrtho( ));
00244 }
00245
00246
00247 void Channel::frameAssemble( const uint32_t frameID )
00248 {
00249 const bool composeOnly = (_drawRange == eq::Range::ALL);
00250
00251 _startAssemble();
00252
00253 const eq::FrameVector& frames = getInputFrames();
00254 eq::PixelViewport coveredPVP;
00255 eq::FrameVector dbFrames;
00256 eq::Zoom zoom( eq::Zoom::NONE );
00257
00258
00259 for( eq::FrameVector::const_iterator i = frames.begin();
00260 i != frames.end(); ++i )
00261 {
00262 eq::Frame* frame = *i;
00263 {
00264 eq::ChannelStatistics stat(eq::Statistic::CHANNEL_WAIT_FRAME, this);
00265 frame->waitReady( );
00266 }
00267 const eq::Range& curRange = frame->getRange();
00268 if( curRange == eq::Range::ALL )
00269 eq::Compositor::assembleFrame( frame, this );
00270 else
00271 {
00272 dbFrames.push_back( frame );
00273 zoom = frame->getZoom();
00274 _expandPVP( coveredPVP, frame->getImages(), frame->getOffset() );
00275 }
00276 }
00277 coveredPVP.intersect( getPixelViewport( ));
00278
00279 if( dbFrames.empty( ))
00280 {
00281 resetAssemblyState();
00282 return;
00283 }
00284
00285
00286 if( !composeOnly && coveredPVP.hasArea( ))
00287 {
00288 _frame.clear();
00289 _frame.setRange( _drawRange );
00290 dbFrames.push_back( &_frame );
00291 }
00292
00293 _orderFrames( dbFrames );
00294
00295
00296 if( !composeOnly )
00297 {
00298 if( _bgColor == eq::Vector3f::ZERO && dbFrames.front() == &_frame )
00299 dbFrames.erase( dbFrames.begin( ));
00300 else if( coveredPVP.hasArea())
00301 {
00302 eq::Window::ObjectManager* glObjects = getObjectManager();
00303
00304 _frame.setOffset( eq::Vector2i( 0, 0 ));
00305 _frame.setZoom( zoom );
00306 _frame.setPixelViewport( coveredPVP );
00307 _frame.startReadback( glObjects );
00308 clearViewport( coveredPVP );
00309 _frame.syncReadback();
00310
00311
00312 _frame.setOffset( eq::Vector2i( coveredPVP.x, coveredPVP.y ));
00313 }
00314 }
00315
00316
00317 eq::Compositor::assembleFramesSorted( dbFrames, this, 0, true );
00318 resetAssemblyState();
00319
00320
00321 _drawRange = getRange();
00322 }
00323
00324 void Channel::_startAssemble()
00325 {
00326 applyBuffer();
00327 applyViewport();
00328 setupAssemblyState();
00329 }
00330
00331 void Channel::frameReadback( const uint32_t frameID )
00332 {
00333
00334 const eq::FrameVector& frames = getOutputFrames();
00335 for( eq::FrameVector::const_iterator i = frames.begin();
00336 i != frames.end(); ++i )
00337 {
00338 (*i)->disableBuffer( eq::Frame::BUFFER_DEPTH );
00339 }
00340
00341 eq::Channel::frameReadback( frameID );
00342 }
00343
00344 void Channel::frameViewFinish( const uint32_t frameID )
00345 {
00346 _drawHelp();
00347 _drawLogo();
00348 }
00349
00350 void Channel::_drawLogo( )
00351 {
00352
00353 const Window* window = static_cast<Window*>( getWindow( ));
00354 GLuint texture;
00355 eq::Vector2i size;
00356
00357 window->getLogoTexture( texture, size );
00358 if( !texture )
00359 return;
00360
00361 glMatrixMode( GL_PROJECTION );
00362 glLoadIdentity();
00363 applyScreenFrustum();
00364 glMatrixMode( GL_MODELVIEW );
00365 glLoadIdentity();
00366
00367 glDisable( GL_DEPTH_TEST );
00368 glDisable( GL_LIGHTING );
00369 glEnable( GL_BLEND );
00370 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
00371
00372 glEnable( GL_TEXTURE_RECTANGLE_ARB );
00373 glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture );
00374 glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
00375 GL_LINEAR );
00376 glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
00377 GL_LINEAR );
00378
00379 glColor3f( 1.0f, 1.0f, 1.0f );
00380 glBegin( GL_TRIANGLE_STRIP ); {
00381 glTexCoord2f( 0.0f, 0.0f );
00382 glVertex3f( 5.0f, 5.0f, 0.0f );
00383
00384 glTexCoord2f( size.x(), 0.0f );
00385 glVertex3f( size.x() + 5.0f, 5.0f, 0.0f );
00386
00387 glTexCoord2f( 0.0f, size.y() );
00388 glVertex3f( 5.0f, size.y() + 5.0f, 0.0f );
00389
00390 glTexCoord2f( size.x(), size.y() );
00391 glVertex3f( size.x() + 5.0f, size.y() + 5.0f, 0.0f );
00392 } glEnd();
00393
00394 glDisable( GL_TEXTURE_RECTANGLE_ARB );
00395 glDisable( GL_BLEND );
00396 }
00397
00398 void Channel::_drawHelp()
00399 {
00400 const FrameData& frameData = _getFrameData();
00401 std::string message = frameData.getMessage();
00402
00403 if( !frameData.showHelp() && message.empty( ))
00404 return;
00405
00406 EQ_GL_CALL( applyBuffer( ));
00407 EQ_GL_CALL( applyViewport( ));
00408 EQ_GL_CALL( setupAssemblyState( ));
00409
00410 glDisable( GL_LIGHTING );
00411 glDisable( GL_DEPTH_TEST );
00412
00413 glColor3f( 1.f, 1.f, 1.f );
00414
00415 if( frameData.showHelp( ))
00416 {
00417 const eq::Window::Font* font = getWindow()->getSmallFont();
00418 std::string help = EVolve::getHelp();
00419 float y = 340.f;
00420
00421 for( size_t pos = help.find( '\n' ); pos != std::string::npos;
00422 pos = help.find( '\n' ))
00423 {
00424 glRasterPos3f( 10.f, y, 0.99f );
00425
00426 font->draw( help.substr( 0, pos ));
00427 help = help.substr( pos + 1 );
00428 y -= 16.f;
00429 }
00430
00431 glRasterPos3f( 10.f, y, 0.99f );
00432 font->draw( help );
00433 }
00434
00435 if( !message.empty( ))
00436 {
00437 const eq::Window::Font* font = getWindow()->getMediumFont();
00438
00439 const eq::Viewport& vp = getViewport();
00440 const eq::PixelViewport& pvp = getPixelViewport();
00441
00442 const float width = pvp.w / vp.w;
00443 const float xOffset = vp.x * width;
00444
00445 const float height = pvp.h / vp.h;
00446 const float yOffset = vp.y * height;
00447 const float yMiddle = 0.5f * height;
00448 float y = yMiddle - yOffset;
00449
00450 for( size_t pos = message.find( '\n' ); pos != std::string::npos;
00451 pos = message.find( '\n' ))
00452 {
00453 glRasterPos3f( 10.f - xOffset, y, 0.99f );
00454
00455 font->draw( message.substr( 0, pos ));
00456 message = message.substr( pos + 1 );
00457 y -= 22.f;
00458 }
00459
00460 glRasterPos3f( 10.f - xOffset, y, 0.99f );
00461 font->draw( message );
00462 }
00463
00464 EQ_GL_CALL( resetAssemblyState( ));
00465 }
00466
00467
00468 }