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