36 #include "configEvent.h"
40 #include "vertexBufferState.h"
43 static GLfloat lightPosition[] = {0.0f, 0.0f, 1.0f, 0.0f};
44 static GLfloat lightAmbient[] = {0.1f, 0.1f, 0.1f, 1.0f};
45 static GLfloat lightDiffuse[] = {0.8f, 0.8f, 0.8f, 1.0f};
46 static GLfloat lightSpecular[] = {0.8f, 0.8f, 0.8f, 1.0f};
49 static GLfloat materialAmbient[] = {0.2f, 0.2f, 0.2f, 1.0f};
50 static GLfloat materialDiffuse[] = {0.8f, 0.8f, 0.8f, 1.0f};
51 static GLfloat materialSpecular[] = {0.5f, 0.5f, 0.5f, 1.0f};
52 static GLint materialShininess = 64;
55 # define M_SQRT3_2 0.86603f
62 : eq::Channel( parent )
81 for(
size_t i = 0; i < eq::NUM_EYES; ++i )
83 delete _accum[ i ].buffer;
84 _accum[ i ].buffer = 0;
98 const FrameData& frameData = _getFrameData();
99 const int32_t eyeIndex = lunchbox::getIndexOfLastBit(
getEye() );
100 if( _isDone() && !_accum[ eyeIndex ].transfer )
107 if( view && frameData.getCurrentViewID() == view->getID( ))
108 glClearColor( 1.f, 1.f, 1.f, 0.f );
110 else if( getenv(
"EQ_TAINT_CHANNELS" ))
113 glClearColor( color.r()/255.f, color.g()/255.f, color.b()/255.f, 0.f );
117 glClearColor( 0.f, 0.f, 0.f, 0.0f );
119 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
124 if( stopRendering( ))
133 const Model* oldModel = _model;
134 const Model* model = _getModel();
136 if( oldModel != model )
137 state.setFrustumCulling(
false );
140 _updateNearFar( model->getBoundingSphere( ));
144 glLightfv( GL_LIGHT0, GL_POSITION, lightPosition );
145 glLightfv( GL_LIGHT0, GL_AMBIENT, lightAmbient );
146 glLightfv( GL_LIGHT0, GL_DIFFUSE, lightDiffuse );
147 glLightfv( GL_LIGHT0, GL_SPECULAR, lightSpecular );
149 glMaterialfv( GL_FRONT, GL_AMBIENT, materialAmbient );
150 glMaterialfv( GL_FRONT, GL_DIFFUSE, materialDiffuse );
151 glMaterialfv( GL_FRONT, GL_SPECULAR, materialSpecular );
152 glMateriali( GL_FRONT, GL_SHININESS, materialShininess );
154 const FrameData& frameData = _getFrameData();
155 glPolygonMode( GL_FRONT_AND_BACK,
156 frameData.useWireframe() ? GL_LINE : GL_FILL );
158 const eq::Vector3f& position = frameData.getCameraPosition();
160 glMultMatrixf( frameData.getCameraRotation().array );
161 glTranslatef( position.x(), position.y(), position.z() );
162 glMultMatrixf( frameData.getModelRotation().array );
167 glColor3ub( color.r(), color.g(), color.b() );
170 glColor3f( .75f, .75f, .75f );
176 glNormal3f( 0.f, -1.f, 0.f );
177 glBegin( GL_TRIANGLE_STRIP );
178 glVertex3f( .25f, 0.f, .25f );
179 glVertex3f( -.25f, 0.f, .25f );
180 glVertex3f( .25f, 0.f, -.25f );
181 glVertex3f( -.25f, 0.f, -.25f );
185 state.setFrustumCulling(
true );
186 Accum& accum = _accum[ lunchbox::getIndexOfLastBit(
getEye()) ];
187 accum.stepsDone = LB_MAX( accum.stepsDone,
189 accum.transfer =
true;
194 if( stopRendering( ))
200 Accum& accum = _accum[ lunchbox::getIndexOfLastBit(
getEye()) ];
204 accum.transfer =
true;
206 if( accum.buffer && !accum.buffer->usesFBO( ))
208 LBWARN <<
"Current viewport different from view viewport, "
209 <<
"idle anti-aliasing not implemented." << std::endl;
218 accum.transfer =
true;
221 for( eq::Frames::const_iterator i = frames.begin(); i != frames.end(); ++i )
224 const eq::SubPixel& curSubPixel = frame->
getSubPixel();
226 if( curSubPixel != eq::SubPixel::ALL )
227 accum.transfer =
false;
229 accum.stepsDone = LB_MAX( accum.stepsDone, frame->
getSubPixel().size *
241 catch(
const co::Exception& e )
243 LBWARN << e.what() << std::endl;
251 if( stopRendering() || _isDone( ))
254 const FrameData& frameData = _getFrameData();
262 if( frameData.isIdle( ))
267 if( frameData.useCompression( ))
277 const uint32_t frameNumber )
279 if( stopRendering( ))
282 for(
size_t i = 0; i < eq::NUM_EYES; ++i )
283 _accum[ i ].stepsDone = 0;
290 if( stopRendering( ))
299 const uint32_t frameNumber )
301 if( stopRendering( ))
304 for(
size_t i = 0; i < eq::NUM_EYES; ++i )
306 Accum& accum = _accum[ i ];
309 if( int32_t( accum.stepsDone ) > accum.step )
312 accum.step -= accum.stepsDone;
321 if( stopRendering( ))
326 const FrameData& frameData = _getFrameData();
327 Accum& accum = _accum[ lunchbox::getIndexOfLastBit(
getEye()) ];
332 const bool isResized = accum.buffer->resize( pvp );
337 accum.buffer->clear();
338 accum.step = view->getIdleSteps();
341 else if( frameData.isIdle( ))
345 if( !_isDone() && accum.transfer )
346 accum.buffer->accum();
347 accum.buffer->display();
357 if( frameData.useStatistics())
361 if( frameData.isIdle( ))
363 for(
size_t i = 0; i < eq::NUM_EYES; ++i )
364 steps = LB_MAX( steps, _accum[i].step );
369 steps = view ? view->getIdleSteps() : 0;
375 config->
sendEvent( IDLE_AA_LEFT ) << steps;
382 const FrameData& frameData = _getFrameData();
383 return frameData.useOrtho();
386 const FrameData& Channel::_getFrameData()
const
389 return pipe->getFrameData();
392 bool Channel::_isDone()
const
394 const FrameData& frameData = _getFrameData();
395 if( !frameData.isIdle( ))
399 const Accum& accum = _accum[ lunchbox::getIndexOfLastBit(
getEye()) ];
400 return int32_t( subpixel.index ) >= accum.step;
403 void Channel::_initJitter()
408 const FrameData& frameData = _getFrameData();
409 if( frameData.isIdle( ))
412 const View* view =
static_cast< const View*
>(
getView( ));
416 const int32_t idleSteps = view->getIdleSteps();
421 Accum& accum = _accum[ lunchbox::getIndexOfLastBit(
getEye()) ];
423 accum.buffer->clear();
424 accum.step = idleSteps;
427 bool Channel::_initAccum()
433 const eq::Eye eye =
getEye();
434 Accum& accum = _accum[ lunchbox::getIndexOfLastBit( eye ) ];
439 if( accum.step == -1 )
445 for(
size_t i = 0; i < eq::NUM_EYES; ++i )
447 if( _accum[ i ].buffer )
449 LBWARN <<
"glAccum-based accumulation does not support "
450 <<
"stereo, disabling idle anti-aliasing."
452 for(
size_t j = 0; j < eq::NUM_EYES; ++j )
454 delete _accum[ j ].buffer;
455 _accum[ j ].buffer = 0;
456 _accum[ j ].step = -1;
459 view->setIdleSteps( 0 );
468 LBASSERT( pvp.isValid( ));
470 if( !accum.buffer->init( pvp,
getWindow()->getColorFormat( )) ||
471 accum.buffer->getMaxSteps() < 256 )
473 LBWARN <<
"Accumulation buffer initialization failed, "
474 <<
"idle AA not available." << std::endl;
482 LBVERB <<
"Initialized "
483 << (accum.buffer->usesFBO() ?
"FBO accum" :
"glAccum")
487 view->setIdleSteps( accum.buffer ? 256 : 0 );
491 bool Channel::stopRendering()
const
498 const FrameData& frameData = _getFrameData();
499 const Accum& accum = _accum[ lunchbox::getIndexOfLastBit(
getEye()) ];
501 if( !frameData.isIdle() || accum.step <= 0 )
505 if( !view || view->getIdleSteps() != 256 )
506 return eq::Vector2f::ZERO;
508 const eq::Vector2i jitterStep = _getJitterStep();
509 if( jitterStep == eq::Vector2i::ZERO )
510 return eq::Vector2f::ZERO;
513 const float pvp_w = float( pvp.w );
514 const float pvp_h = float( pvp.h );
515 const float frustum_w = float((
getFrustum().get_width( )));
516 const float frustum_h = float((
getFrustum().get_height( )));
518 const float pixel_w = frustum_w / pvp_w;
519 const float pixel_h = frustum_h / pvp_h;
521 const float sampleSize = 16.f;
522 const float subpixel_w = pixel_w / sampleSize;
523 const float subpixel_h = pixel_h / sampleSize;
527 const eq::Pixel& pixel =
getPixel();
529 const float i = ( rng.get<
float >() * subpixel_w +
530 float( jitterStep.x( )) * subpixel_w ) / float( pixel.w );
531 const float j = ( rng.get<
float >() * subpixel_h +
532 float( jitterStep.y( )) * subpixel_h ) / float( pixel.h );
534 return eq::Vector2f( i, j );
537 static const uint32_t _primes[100] = {
538 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829,
539 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
540 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
541 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109,
542 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
543 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291,
544 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
545 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451 };
547 eq::Vector2i Channel::_getJitterStep()
const
550 const uint32_t channelID = subPixel.index;
551 const View* view =
static_cast< const View*
>(
getView( ));
553 return eq::Vector2i::ZERO;
555 const uint32_t totalSteps = uint32_t( view->getIdleSteps( ));
556 if( totalSteps != 256 )
557 return eq::Vector2i::ZERO;
559 const Accum& accum = _accum[ lunchbox::getIndexOfLastBit(
getEye()) ];
561 const uint32_t index = ( accum.step * _primes[ channelID % 100 ] )%subset +
562 ( channelID * subset );
563 const uint32_t sampleSize = 16;
564 const int dx = index % sampleSize;
565 const int dy = index / sampleSize;
567 return eq::Vector2i( dx, dy );
570 const Model* Channel::_getModel()
572 Config* config =
static_cast< Config*
>(
getConfig( ));
573 const View* view =
static_cast< const View*
>(
getView( ));
574 const FrameData& frameData = _getFrameData();
575 LBASSERT( !view || dynamic_cast< const View* >(
getView( )));
577 eq::uint128_t
id = view ? view->getModelID() : frameData.getModelID();
579 id = frameData.getModelID();
582 _model = config->getModel(
id );
589 void Channel::_drawModel(
const Model* scene )
591 Window* window =
static_cast< Window*
>(
getWindow( ));
592 VertexBufferState& state = window->getState();
593 const FrameData& frameData = _getFrameData();
595 if( frameData.getColorMode() ==
COLOR_MODEL && scene->hasColors( ))
596 state.setColors(
true );
598 state.setColors(
false );
599 state.setChannel(
this );
602 const eq::Matrix4f& rotation = frameData.getCameraRotation();
603 const eq::Matrix4f& modelRotation = frameData.getModelRotation();
604 eq::Matrix4f position = eq::Matrix4f::IDENTITY;
605 position.set_translation( frameData.getCameraPosition());
608 const eq::Matrix4f projection =
useOrtho() ? frustum.compute_ortho_matrix():
609 frustum.compute_matrix();
611 const eq::Matrix4f model = rotation * position * modelRotation;
613 state.setProjectionModelViewMatrix( projection * view * model );
617 const GLuint program = state.getProgram( pipe );
618 if( program != VertexBufferState::INVALID )
619 glUseProgram( program );
621 scene->cullDraw( state );
623 state.setChannel( 0 );
624 if( program != VertexBufferState::INVALID )
627 const InitData& initData =
628 static_cast<Config*
>(
getConfig( ))->getInitData();
629 if( initData.useROI( ))
635 #ifndef NDEBUG // region border
637 const eq::PixelViewport& region =
getRegion();
639 glMatrixMode( GL_PROJECTION );
641 glOrtho( 0.f, pvp.w, 0.f, pvp.h, -1.f, 1.f );
642 glMatrixMode( GL_MODELVIEW );
649 glColor3ub( color.r(), color.g(), color.b() );
651 else if( currentView &&
652 frameData.getCurrentViewID() == currentView->getID( ))
654 glColor3f( 0.f, 0.f, 0.f );
657 glColor3f( 1.f, 1.f, 1.f );
658 glNormal3f( 0.f, 0.f, 1.f );
660 const eq::Vector4f rect(
float( region.x ) + .5f,
float( region.y ) + .5f,
661 float( region.getXEnd( )) - .5f,
662 float( region.getYEnd( )) - .5f );
663 glBegin( GL_LINE_LOOP ); {
664 glVertex3f( rect[0], rect[1], -.99f );
665 glVertex3f( rect[2], rect[1], -.99f );
666 glVertex3f( rect[2], rect[3], -.99f );
667 glVertex3f( rect[0], rect[3], -.99f );
672 void Channel::_drawOverlay()
675 const Window* window =
static_cast<Window*
>(
getWindow( ));
680 glMatrixMode( GL_PROJECTION );
683 glMatrixMode( GL_MODELVIEW );
686 glDisable( GL_DEPTH_TEST );
687 glDisable( GL_LIGHTING );
688 glColor3f( 1.0f, 1.0f, 1.0f );
689 glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
692 glEnable( GL_BLEND );
693 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
694 const GLenum target = texture->
getTarget();
697 glTexParameteri( target, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
698 glTexParameteri( target, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
700 const float tWidth = float( texture->
getWidth( ) );
701 const float tHeight = float( texture->
getHeight( ) );
703 const float width = target == GL_TEXTURE_2D ? 1.0f : tWidth;
704 const float height = target == GL_TEXTURE_2D ? 1.0f : tHeight;
706 glBegin( GL_QUADS ); {
707 glTexCoord2f( 0, 0 );
708 glVertex3f( 5.0f, 5.0f, 0.0f );
710 glTexCoord2f( width, 0 );
711 glVertex3f( tWidth + 5.0f, 5.0f, 0.0f );
713 glTexCoord2f( width, height );
714 glVertex3f( tWidth + 5.0f, tHeight + 5.0f, 0.0f );
716 glTexCoord2f( 0, height );
717 glVertex3f( 5.0f, tHeight + 5.0f, 0.0f );
722 glDisable( GL_BLEND );
723 glEnable( GL_LIGHTING );
724 glEnable( GL_DEPTH_TEST );
727 void Channel::_drawHelp()
729 const FrameData& frameData = _getFrameData();
730 std::string message = frameData.getMessage();
732 if( !frameData.showHelp() && message.empty( ))
740 glEnable( GL_COLOR_LOGIC_OP );
741 glDisable( GL_LIGHTING );
742 glDisable( GL_DEPTH_TEST );
744 glColor3f( 1.f, 1.f, 1.f );
748 const float height = pvp.h / vp.h;
750 if( !message.empty( ))
754 const float width = pvp.w / vp.w;
755 const float xOffset = vp.x * width;
757 const float yOffset = vp.y * height;
758 const float yPos = 0.618f * height;
759 float y = yPos - yOffset;
761 for(
size_t pos = message.find(
'\n' ); pos != std::string::npos;
762 pos = message.find(
'\n' ))
764 glRasterPos3f( 10.f - xOffset, y, 0.99f );
765 font->
draw( message.substr( 0, pos ));
766 message = message.substr( pos + 1 );
770 glRasterPos3f( 10.f - xOffset, y, 0.99f );
771 font->
draw( message );
774 glMatrixMode( GL_PROJECTION );
777 glMatrixMode( GL_MODELVIEW );
779 if( frameData.showHelp( ))
782 std::string help = EqPly::getHelp();
783 float y = height - 16.f;
785 for(
size_t pos = help.find(
'\n' ); pos != std::string::npos;
786 pos = help.find(
'\n' ))
788 glRasterPos3f( 10.f, y, 0.99f );
790 font->
draw( help.substr( 0, pos ));
791 help = help.substr( pos + 1 );
795 glRasterPos3f( 10.f, y, 0.99f );
802 void Channel::_updateNearFar(
const mesh::BoundingSphere& boundingSphere )
805 const FrameData& frameData = _getFrameData();
807 const eq::Matrix4f& rotation = frameData.getCameraRotation();
810 eq::Matrix4f modelInv;
811 compute_inverse( headTransform, modelInv );
813 const eq::Vector3f zero = modelInv * eq::Vector3f::ZERO;
814 eq::Vector3f front = modelInv * eq::Vector3f( 0.0f, 0.0f, -1.0f );
818 front *= boundingSphere.w();
820 const eq::Vector3f center =
821 frameData.getCameraPosition().get_sub_vector< 3 >() -
822 boundingSphere.get_sub_vector< 3 >();
823 const eq::Vector3f nearPoint = headTransform * ( center - front );
824 const eq::Vector3f farPoint = headTransform * ( center + front );
828 LBASSERTINFO( fabs( farPoint.z() - nearPoint.z() ) >
829 std::numeric_limits< float >::epsilon(),
830 nearPoint <<
" == " << farPoint );
837 const float width = fabs( frustum.right() - frustum.left() );
838 const float height = fabs( frustum.top() - frustum.bottom() );
839 const float size = LB_MIN( width, height );
840 const float minNear = frustum.near_plane() / size * .001f;
842 const float zNear = LB_MAX( minNear, -nearPoint.z() );
843 const float zFar = LB_MAX( zNear * 2.f, -farPoint.z() );
A configuration is a visualization session driven by an application.
virtual void setupAssemblyState()
Setup the OpenGL state for a readback or assemble operation.
virtual void frameClear(const uint128_t &frameID)
Clear the frame buffer.
virtual void applyViewport() const
Apply the OpenGL viewport for the current rendering task.
virtual void frameStart(const uint128_t &frameID, const uint32_t frameNumber)
Start rendering a frame.
virtual void drawStatistics()
Draw a statistics overlay.
A View is a 2D area of a Layout.
virtual void frameAssemble(const uint128_t &frameID)
Assemble all input frames.
A Window represents an on-screen or off-screen drawable.
virtual Vector2f getJitter() const
const GLEWContext * glewGetContext() const
Get the GLEW context for this channel.
const Viewport & getViewport() const
const Frames & getInputFrames()
void applyScreenFrustum() const
Apply an orthographic frustum for pixel-based 2D operations.
virtual void resetRegions()
Reset the declared regions of interest.
A wrapper around AGL, WGL and GLX bitmap fonts.
virtual void frameFinish(const uint128_t &frameID, const uint32_t frameNumber)
Finish rendering a frame.
const Frames & getOutputFrames()
virtual void applyBuffer()
Apply the current rendering buffer, including the color mask.
void draw(const std::string &text) const
Draw text on the current raster position.
const SubPixel & getSubPixel() const
int32_t getHeight() const
uint32_t size
Total number of contributors.
virtual bool configExit()
Exit this channel.
A Pipe represents a graphics card (GPU) on a Node.
uint32_t getPeriod() const
PixelViewport getRegion() const
View * getView()
Get the channel's current View.
A window represent an OpenGL drawable and context.
bool usesFBO() const
Test if the accumulation uses the FBO implementation.
Render using the colors defined in the ply file.
void sendEvent(ConfigEvent &event)
Send an (old) event to the application node.
void bind() const
Bind the texture.
virtual bool configExit()
Exit this channel.
static uint32_t assembleFrames(const Frames &frames, Channel *channel, util::Accum *accum)
Assemble all frames in an arbitrary order using the fastest implemented algorithm on the given channe...
const Matrix4f & getHeadTransform() const
Return the view matrix.
const Range & getRange() const
virtual bool useOrtho() const
Select perspective or orthographic rendering.
The representation of one GPU.
const Vector3ub & getUniqueColor() const
void useCompressor(const Frame::Buffer buffer, const uint32_t name)
Sets a compressor for compression for following transmissions.
View * getNativeView()
Get the channel's native view.
const SubPixel & getSubPixel() const
A holder for a frame data and related parameters.
std::vector< Frame * > Frames
A vector of pointers to eq::Frame.
virtual bool configInit(const uint128_t &initID)
Initialize this channel.
virtual void declareRegion(const eq::PixelViewport ®ion)
Declare a region covered by the current draw or assemble operation.
EQFABRIC_INL void setNearFar(const float nearPlane, const float farPlane)
Set the near and far planes for this channel.
A C++ class to abstract an accumulation buffer.
Frames::const_iterator FramesCIter
A const_iterator over a eq::Frame vector.
uint32_t getPeriod() const
virtual void frameDraw(const uint128_t &frameID)
Draw the scene.
A wrapper around OpenGL textures.
virtual void frameViewFinish(const uint128_t &frameID)
Finish updating a destination channel.
const PixelViewport & getPixelViewport() const
void setAlphaUsage(const bool useAlpha)
Set alpha usage for newly allocated images.
virtual void frameStart(const eq::uint128_t &frameID, const uint32_t frameNumber)
Start rendering a frame.
const std::string & getName() const
virtual void frameViewStart(const uint128_t &frameID)
Start updating a destination channel.
uint32_t getCurrentFrame() const
Return the current frame number.
const Frustumf & getFrustum() const
virtual void frameReadback(const uint128_t &frameID)
Read back the rendered frame buffer into the output frames.
virtual void frameDraw(const eq::uint128_t &frameID)
Draw the scene.
const Pixel & getPixel() const
Use a unique color to demonstrate decomposition.
unsigned getTarget() const
void setQuality(const Frame::Buffer buffer, const float quality)
Set the minimum quality after compression.
virtual void resetAssemblyState()
Reset the OpenGL state after an assembly operation.