Code Search for Developers
 
 
  

channel.cpp from Equalizer - Multipipe Rendering at Krugle


Show channel.cpp syntax highlighted


/* Copyright (c) 2006-2007, Stefan Eilemann <eile@equalizergraphics.com> 
   All rights reserved. */

#include "channel.h"

#include "frameData.h"
#include "initData.h"
#include "node.h"
#include "pipe.h"
#include "window.h"
#include "shader.h"
#include "hlp.h"


//Only for gluErrorString()
#ifdef __APPLE__
#include <GLUT/glut.h>
#else // linux & Win
#include <GL/glu.h>
#endif


//#define DYNAMIC_NEAR_FAR 
#ifndef M_SQRT3
#  define M_SQRT3    1.7321f   /* sqrt(3) */
#endif
#ifndef M_SQRT3_2
#  define M_SQRT3_2  0.86603f  /* sqrt(3)/2 */
#endif

namespace eqVol
{

using namespace eqBase;
using namespace std;

#define COMPOSE_MODE_NEW


Channel::Channel()
: eq::Channel()
, _model(NULL)
,_vertexID(0)
{
}

	
void checkError( std::string msg ) 
{
	GLenum error = glGetError();
	if (error != GL_NO_ERROR)
        EQERROR << msg << " GL Error: " << gluErrorString(error) << endl;
}


struct quad 
{
	GLfloat x;
	GLfloat y;
	GLfloat z;
};
	
void createVertexArray( uint32_t numberOfSlices, GLuint &vertexID )
{
	vector<quad> pVertex;
	pVertex.resize( 4*numberOfSlices );
	
	//draw the slices
	for( uint32_t ii=0; ii<numberOfSlices; ii++ )
    {
		pVertex[4*ii+3].x =  1.8;
		pVertex[4*ii+3].y = -1.8;
		pVertex[4*ii+3].z =  (3.6*ii)/(numberOfSlices-1)-1.8;
		
		pVertex[4*ii+2].x =  1.8;
		pVertex[4*ii+2].y =  1.8;
		pVertex[4*ii+2].z =  (3.6*ii)/(numberOfSlices-1)-1.8;
		
		pVertex[4*ii+1].x = -1.8;
		pVertex[4*ii+1].y =  1.8;
		pVertex[4*ii+1].z =  (3.6*ii)/(numberOfSlices-1)-1.8;
		
		
		pVertex[4*ii  ].x = -1.8;
		pVertex[4*ii  ].y = -1.8;
		pVertex[4*ii  ].z =  (3.6*ii)/(numberOfSlices-1)-1.8;
	}

	glGenBuffers( 1, &vertexID );
	glBindBuffer( GL_ARRAY_BUFFER, vertexID );
	glBufferData( GL_ARRAY_BUFFER, 3*4*numberOfSlices*sizeof(GLfloat), &pVertex[0], GL_STATIC_DRAW );
	glBindBuffer( GL_ARRAY_BUFFER, 0 );
	
	checkError( "creating vertex array" );
}
	
bool Channel::configInit( const uint32_t initID )
{
    EQINFO << "Init channel initID " << initID << " ptr " << this << endl;

//chose projection type
	_perspective = true;
	
	if( _model )
		delete _model;
		
    Node* node  = (Node*)getNode();
	_model = new Model( node->getInitData().getDataFilename() );


	glDisable(GL_LIGHTING);
	glDisable(GL_DEPTH_TEST);
	
#ifndef DYNAMIC_NEAR_FAR
    setNearFar( 0.0001f, 10.0f );
#endif
    return true;
}


void Channel::applyFrustum() const
{
	const vmml::Frustumf& frustum = _curFrData.frustum;

	if( _perspective )
	{
	    glFrustum( frustum.left, frustum.right, frustum.bottom, frustum.top,
	             frustum.nearPlane, frustum.farPlane ); 
	}else
	{
	    glOrtho( frustum.left, frustum.right, frustum.bottom, frustum.top,
	             frustum.nearPlane, frustum.farPlane ); 
	}

   	EQVERB << "Apply " << frustum << endl;
}

void Channel::frameClear( const uint32_t frameID )
{
    applyBuffer();
    applyViewport();

#ifdef COMPOSE_MODE_NEW
	glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
#else
	glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
#endif

    glClear( GL_COLOR_BUFFER_BIT );
}


void createHexagonsList( int num, GLuint &listId )
{
    if( listId != 0 )
        glDeleteLists( listId, 1 );
     
    listId = glGenLists(1);
    
    glNewList( listId, GL_COMPILE );    
    
	for( int s = 0; s < num; ++s )
	{
		glBegin( GL_POLYGON );
		for( int i = 0; i < 6; ++i )
			glVertex2i( i, num-1-s );
		glEnd();
	}

    glEndList();
}

//#define TEXTURE_ROTATION

void Channel::frameDraw( const uint32_t frameID )
{
    const Pipe*      pipe      = static_cast<Pipe*>( getPipe( ));
    const FrameData& frameData = pipe->getFrameData();

	_curFrData.needInverse = frameData.data.rotation.ml[10] < 0; //check if z coordinate of vector (0,0,1) after rotation is < 0
	_curFrData.lastRange   = getRange();						 //save range for compositing

   	if( _model )
		_model->createTextures( _tex3D, _preintName, _curFrData.lastRange ); 


    vmml::FrustumCullerf culler;
    _initFrustum( culler ); 

    applyBuffer();
    applyViewport();
            
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();

    applyFrustum();


   	if( _model )
    {
		uint32_t numberOfSlices = _model->getResolution() * 2;
		if( _prvNumberOfSlices != numberOfSlices )
		{
#ifndef TEXTURE_ROTATION 
            createHexagonsList( numberOfSlices, _vertexID );
#else		
			createVertexArray(  numberOfSlices, _vertexID );
#endif
			_prvNumberOfSlices = numberOfSlices;
		}

		GLfloat lightAmbient[]  = {0.2f, 0.2f, 0.2f, 1.0f};
		GLfloat lightDiffuse[]  = {0.8f, 0.8f, 0.8f, 1.0f};
		GLfloat lightSpecular[] = {0.8f, 0.8f, 0.8f, 1.0f};
		GLfloat lightPosition[] = {0.0f, 0.0f, 1.0f, 0.0f}; 

		//set light parameters
		glLightfv( GL_LIGHT0, GL_AMBIENT,  lightAmbient  );
		glLightfv( GL_LIGHT0, GL_DIFFUSE,  lightDiffuse  );
		glLightfv( GL_LIGHT0, GL_SPECULAR, lightSpecular );
		glLightfv( GL_LIGHT0, GL_POSITION, lightPosition );

#ifdef TEXTURE_ROTATION 
		// Rotate 3D texture
		glActiveTexture( GL_TEXTURE0 );
		glMatrixMode( GL_TEXTURE );
		glLoadIdentity();
		glMultMatrixf( frameData.data.rotation.ml );
#endif


/////////////////////////////////////////////////////////////////////////////		

		// Matrix World
		glMatrixMode( GL_MODELVIEW );
		glLoadIdentity();
    	applyHeadTransform();

		glTranslatef(  frameData.data.translation.x,
		               frameData.data.translation.y,
		               frameData.data.translation.z );
#ifndef TEXTURE_ROTATION 
		glMultMatrixf( frameData.data.rotation.ml );
#endif
		glScalef( _model->volScales.W, _model->volScales.H, _model->volScales.D );

/*		glPushMatrix(); //Rotate lights
		{
			glLoadIdentity();
			vmml::Matrix4f r = frameData.data.rotation; 
			r.ml[1] = -r.ml[1]; 
			r.ml[2] = -r.ml[2];
			r.ml[4] = -r.ml[4]; 
			r.ml[6] = -r.ml[6];
			r.ml[8] = -r.ml[8]; 
			r.ml[9] = -r.ml[9];
			
			vmml::Matrix4f ri; r.getInverse(r);
			glMultMatrixf( ri.ml );
			glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
		}
		glPopMatrix();
*/
		checkError("");

			
		vmml::Matrix4d pMatrix      = _curFrData.modelviewM;
		vmml::Matrix4d matModelView = _curFrData.modelviewIM;

		vmml::Vector4d camPosition = matModelView * vmml::Vector4f( 0.0, 0.0, 0.0, 1.0 );
		camPosition[3] = 1.0;

		vmml::Vector4d viewVec( -pMatrix.ml[2], -pMatrix.ml[6], -pMatrix.ml[10], 0.0 );

		double m_dScaleFactorX = 1.0;
		double m_dScaleFactorY = 1.0;
		double m_dScaleFactorZ = 1.0;
		double m_dSliceDist    = 3.6/numberOfSlices;

		vmml::Vector4d scaledViewVec( viewVec.x*m_dScaleFactorX, viewVec.y*m_dScaleFactorY, viewVec.z*m_dScaleFactorZ, 0.0 ) ;

		double zRs = -1+2*_curFrData.lastRange.start;
		double zRe = -1+2*_curFrData.lastRange.end;

		vmml::Vector4d m_pVertices[8];
		m_pVertices[0] = vmml::Vector4f(-1.0,-1.0,zRs, 1.0);
		m_pVertices[1] = vmml::Vector4f( 1.0,-1.0,zRs, 1.0);
		m_pVertices[2] = vmml::Vector4f(-1.0, 1.0,zRs, 1.0);
		m_pVertices[3] = vmml::Vector4f( 1.0, 1.0,zRs, 1.0);

		m_pVertices[4] = vmml::Vector4f(-1.0,-1.0,zRe, 1.0);
		m_pVertices[5] = vmml::Vector4f( 1.0,-1.0,zRe, 1.0);
		m_pVertices[6] = vmml::Vector4f(-1.0, 1.0,zRe, 1.0);
		m_pVertices[7] = vmml::Vector4f( 1.0, 1.0,zRe, 1.0);
		

		float dMaxDist = scaledViewVec.dot( m_pVertices[0] );
		int nMaxIdx = 0;
		for( int i = 1; i < 8; i++ )
		{
			float dist = scaledViewVec.dot( m_pVertices[i] );
			if ( dist > dMaxDist)
			{
				dMaxDist = dist;
				nMaxIdx = i;
			}
		}

		//rendering

		// Enable shader
		
#ifdef CG_SHADERS
		eqCgShaders shaders = pipe->getShaders();
		shaders.cgVertex->use();
		shaders.cgFragment->use();

		CGprogram m_vProg = shaders.cgVertex->get_program();
		CGprogram m_fProg = shaders.cgFragment->get_program();
#else
		GLhandleARB shader = pipe->getShader();
		glUseProgramObjectARB( shader );
#endif


#ifndef TEXTURE_ROTATION 
		const float sequence[64] = {
			0, 1, 4, 2, 3, 5, 6, 7,      
			1, 0, 3, 5, 4, 2, 7, 6, 
			2, 0, 6, 3, 1, 4, 7, 5, 
			3, 1, 2, 7, 5, 0, 6, 4, 
			4, 0, 5, 6, 2, 1, 7, 3, 
			5, 1, 7, 4, 0, 3, 6, 2, 
			6, 2, 4, 7, 3, 0, 5, 1, 
			7, 3, 6, 5, 1, 2, 4, 0 };

		const float e1[24] = {
			0, 1, 4, 4,
			1, 0, 1, 4,
			0, 2, 5, 5,
			2, 0, 2, 5,
			0, 3, 6, 6, 
			3, 0, 3, 6 };
			
		const float e2[24] = {
			1, 4, 7, 7,
			5, 1, 4, 7,
			2, 5, 7, 7,
			6, 2, 5, 7,
			3, 6, 7, 7,
			4, 3, 6, 7 };
	
		float vertices[24];
		for(int i = 0; i < 8; ++i)
		{
			vertices[3*i]   = static_cast<double>( m_dScaleFactorX * m_pVertices[i][0] );
			vertices[3*i+1] = static_cast<double>( m_dScaleFactorY * m_pVertices[i][1] );
			vertices[3*i+2] = static_cast<double>( m_dScaleFactorZ * m_pVertices[i][2] );
		}
			
#ifdef CG_SHADERS
		cgGLSetParameterArray3f( cgGetNamedParameter( m_vProg, "vecVertices" ), 0,  8, vertices );
		cgGLSetParameterArray1f( cgGetNamedParameter( m_vProg, "sequence"    ), 0, 64, sequence );
		cgGLSetParameterArray1f( cgGetNamedParameter( m_vProg, "v1"          ), 0, 24, e1       );
		cgGLSetParameterArray1f( cgGetNamedParameter( m_vProg, "v2"          ), 0, 24, e2       );

		cgGLSetParameter3dv(     cgGetNamedParameter( m_vProg, "vecView"     ), viewVec.xyzw   );
		cgGLSetParameter1f(      cgGetNamedParameter( m_vProg, "frontIndex"  ), float(nMaxIdx) );

		cgGLSetParameter1d(      cgGetNamedParameter( m_vProg, "dPlaneIncr"  ), m_dSliceDist   );  
#else
		glUniform3fvARB( glGetUniformLocationARB( shader, "vecVertices"),  8, vertices );
		glUniform1ivARB( glGetUniformLocationARB( shader, "sequence"   ), 64, sequence );
		glUniform1ivARB( glGetUniformLocationARB( shader, "v1"         ), 24, e1       );
		glUniform1ivARB( glGetUniformLocationARB( shader, "v2"         ), 24, e2       );

		glUniform3fARB(  glGetUniformLocationARB( shader, "vecView"    ), viewVec.x, viewVec.y, viewVec.z );
		const GLint frontInd = static_cast<GLint>(nMaxIdx);
		glUniform1iARB(  glGetUniformLocationARB( shader, "frontIndex" ), frontInd     );
		glUniform1fARB(  glGetUniformLocationARB( shader, "dPlaneIncr" ), m_dSliceDist );
#endif //CG_SHADERS			

		const int nSequence[8][8] = {
			{7,3,5,6,1,2,4,0},
			{6,2,4,7,0,3,5,1},
			{5,1,4,7,0,3,6,2},
			{4,0,5,6,1,2,7,3},
			{3,1,2,7,0,5,6,4},
			{2,0,3,6,1,4,7,5},
			{1,0,3,5,2,4,7,6},
			{0,1,2,4,3,5,6,7},
		};
	
		int nMinIdx = 0;
		double dMinDist = (camPosition - m_pVertices[0]).length();

		double dDist;
		for(int v = 1; v < 8; v++) {
			dDist = (camPosition - m_pVertices[v]).length();
			if (dDist < dMinDist) {
				dMinDist = dDist;
				nMinIdx = v;
			}
		}

		double dStartDist   = viewVec.dot( m_pVertices[nSequence[nMaxIdx][0]] );
//		double dEndDist     = viewVec.dot( m_pVertices[nMaxIdx]               );
		double dS           = ceil( dStartDist/m_dSliceDist);
		dStartDist          = dS * m_dSliceDist;

//		int nNumSlices = int((dEndDist-dStartDist)/m_dSliceDist)+1; 

#ifdef CG_SHADERS
		cgGLSetParameter1d(cgGetNamedParameter(  m_vProg, "dPlaneStart" ), dStartDist ); 

 		cgGLSetParameter1d(cgGetNamedParameter(  m_vProg, "W"  ), _model->TD.W  ); 
		cgGLSetParameter1d(cgGetNamedParameter(  m_vProg, "H"  ), _model->TD.H  ); 
		cgGLSetParameter1d(cgGetNamedParameter(  m_vProg, "D"  ), _model->TD.D  ); 
		cgGLSetParameter1d(cgGetNamedParameter(  m_vProg, "Do" ), _model->TD.Do ); 
		cgGLSetParameter1d(cgGetNamedParameter(  m_vProg, "Db" ), _model->TD.Db ); 
		
		
#else
		glUniform1fARB( glGetUniformLocationARB(  shader, "dPlaneStart" ), dStartDist );
#endif
#endif //TEXTURE_ROTATION 


		// Fill volume data
		{
			glActiveTexture( GL_TEXTURE1 );
			glBindTexture( GL_TEXTURE_2D, _preintName ); //preintegrated values
#ifdef CG_SHADERS
			cgGLSetTextureParameter(    cgGetNamedParameter( m_fProg,"preInt" ), _preintName    );
			cgGLEnableTextureParameter( cgGetNamedParameter( m_fProg,"preInt" )                 );
#else
			glUniform1iARB( glGetUniformLocationARB( shader, "preInt"        ), 1              ); //f-shader
#endif

			glActiveTexture( GL_TEXTURE0 ); // Activate last because it has to be the active texture
			glBindTexture( GL_TEXTURE_3D, _tex3D ); //gx, gy, gz, val
			glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
#ifdef CG_SHADERS
			cgGLSetTextureParameter(    cgGetNamedParameter( m_fProg, "volume" ), _tex3D        );
			cgGLEnableTextureParameter( cgGetNamedParameter( m_fProg, "volume" )                );

			cgGLSetParameter1f(  cgGetNamedParameter( m_vProg, "sliceDistance" ), m_dSliceDist  );
			cgGLSetParameter1f(  cgGetNamedParameter( m_fProg, "shininess"     ), 20.0f         );
#else
			glUniform1iARB( glGetUniformLocationARB(  shader,  "volume"        ), 0             ); //f-shader

			glUniform1fARB( glGetUniformLocationARB(  shader,  "sliceDistance" ), m_dSliceDist  ); //v-shader
			glUniform1fARB( glGetUniformLocationARB(  shader,  "shininess"     ), 20.0f         ); //f-shader
#endif
		}

			//Render slices
		glEnable(GL_BLEND);
#ifdef COMPOSE_MODE_NEW
		glBlendFuncSeparateEXT( GL_ONE, GL_SRC_ALPHA, GL_ZERO, GL_SRC_ALPHA );
#else
		glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
#endif

#ifndef TEXTURE_ROTATION 
		cgGLSetParameter1f(  cgGetNamedParameter( m_fProg, "lines" ), 0.0f );

		glCallList( _vertexID );

#else		
		// Draw slices from vertex array
		glEnableClientState( GL_VERTEX_ARRAY );
		glBindBuffer( GL_ARRAY_BUFFER, _vertexID );
		glVertexPointer( 3, GL_FLOAT, 0, 0 );
		glDrawArrays( GL_QUADS, 0, 4*numberOfSlices );
		glDisableClientState( GL_VERTEX_ARRAY );	
		glBindBuffer( GL_ARRAY_BUFFER, 0 );
#endif

		glDisable(GL_BLEND);

		checkError( "error during rendering " );			

		//Disable shader
#ifdef CG_SHADERS
		shaders.cgVertex->unbind_and_disable();
		shaders.cgFragment->unbind_and_disable();
#else
		glUseProgramObjectARB( NULL );
#endif
	
/**/		
     }
    else
    {
        glColor3f( 1.f, 1.f, 0.f );
        glNormal3f( 0.f, -1.f, 0.f );
        glBegin( GL_TRIANGLE_STRIP );
        glVertex3f(  .25f, 0.f,  .25f );
        glVertex3f(  .25f, 0.f, -.25f );
        glVertex3f( -.25f, 0.f,  .25f );
        glVertex3f( -.25f, 0.f, -.25f );
        glEnd();
    }
//    _drawLogo();
}

bool cmpRangesDec(const Range& r1, const Range& r2)
{
	return r1.start < r2.start;
}

bool cmpRangesInc(const Range& r1, const Range& r2)
{
	return r1.start > r2.start;
}

void Channel::arrangeFrames( vector<Range>& ranges )
{
	ranges.push_back( _curFrData.lastRange );

	if( _perspective )
	{//perspective projection
		vmml::Vector3d norm = _curFrData.modelviewITM * vmml::Vector3d( 0.0, 0.0, 1.0 );
		norm.normalize();
		
		sort( ranges.begin(), ranges.end(), cmpRangesDec );

		vector<double> dotVals;  	        // cos of angle between normal and vectors from center 
		dotVals.reserve( ranges.size()+1 ); // of projection to the middle of slices' boundaries
	
		for( uint i=0; i<ranges.size(); i++ )
		{
			double px = -1.0 + ranges[i].start*2.0;

			vmml::Vector4d pS = _curFrData.modelviewM * vmml::Vector4d( 0.0, 0.0, px , 1.0 );
			dotVals.push_back( norm.dot( pS.getNormalizedVector3() ) );
		}

		vmml::Vector4d pS = _curFrData.modelviewM * vmml::Vector4d( 0.0, 0.0, 1.0, 1.0 );
		dotVals.push_back( norm.dot( pS.getNormalizedVector3() ) );
	
		//check if any slices need to be rendered in rederse orded
		int minPos = -1;
		for( uint i=0; i<dotVals.size()-1; i++ )
			if( dotVals[i] < 0 && dotVals[i+1] < 0 )
				minPos = static_cast<int>(i);
	
		if( minPos >= 0 )
		{
			uint          rangesNum = ranges.size();
			vector<Range> rangesTmp = ranges;

			//Copy slices that should be rendered first
			memcpy( &ranges[0], &rangesTmp[minPos+1], (rangesNum-minPos-1)*sizeof(Range) );
		
			//Copy sliced that shouls be rendered last in reversed order
			for( int i=0; i<=minPos; i++ )
				ranges[ rangesNum-i-1 ] = rangesTmp[i];
		}
	}else
	{//parallel projection
		sort( ranges.begin(), ranges.end(), _curFrData.needInverse ? cmpRangesDec : cmpRangesInc );
	}
}


void IntersectViewports( PixelViewport &pvp, const vector<Image*>& vecImages, const vmml::Vector2i& offset )
{
	if( vecImages.size() < 1 )
	{
		pvp.invalidate();
		return;
	}
	
	PixelViewport overalPVP = vecImages[0]->getPixelViewport() + offset;

	for( uint i=1; i<vecImages.size(); i++ )
		overalPVP += vecImages[i]->getPixelViewport() + offset;

	pvp ^= overalPVP;	
}

void Channel::_clearPixelViewPorts( const vector<Image*> &vecImages, const vmml::Vector2i& offset )
{
	for( uint i=0; i<vecImages.size(); i++ )
		clearViewport( vecImages[i]->getPixelViewport() + offset );
}

#define SOLID_BG

void Channel::clearViewport( const PixelViewport &pvp )
{
   	glViewport( pvp.x, pvp.y, pvp.w, pvp.h );
	glScissor(  pvp.x, pvp.y, pvp.w, pvp.h );

#ifndef NDEBUG
    if( getenv( "EQ_TAINT_CHANNELS" ))
    {
        const vmml::Vector3ub color = getUniqueColor();
        glClearColor( color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, 1.0f );
    }
#else 
#ifdef SOLID_BG
	glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
#endif //SOLID_BG
#endif //NDEBUG

    glClear( GL_COLOR_BUFFER_BIT );

	applyViewport();
}
	

void Channel::frameAssemble( const uint32_t frameID )
{
    applyBuffer();
    applyViewport();
    setupAssemblyState();

    Pipe*                 pipe    = static_cast<eqVol::Pipe*>( getPipe() );
    const vector<Frame*>& frames  = getInputFrames();
    Monitor<uint32_t>     monitor;

    for( vector<Frame*>::const_iterator i = frames.begin();
         i != frames.end(); ++i )
    {
        Frame* frame = *i;
        frame->addListener( monitor );
    }

    uint32_t       nUsedFrames  = 0;
    vector<Frame*> unusedFrames = frames;

    while( !unusedFrames.empty() )
    {
        StatEvent event( StatEvent::CHANNEL_WAIT_FRAME, this, 
                         pipe->getFrameTime( ));

        monitor.waitGE( ++nUsedFrames );
        if( getIAttribute( IATTR_HINT_STATISTICS ))
            pipe->addStatEvent( event );

		uint32_t nFr = frames.size();
        for( vector<Frame*>::iterator i = unusedFrames.begin();
             i != unusedFrames.end(); ++i )
        {
            Frame* frame = *i;
            if( frame->isReady( ))
				nFr--;
        }

		if( nFr == 0 ) //All frames is ready
		{
			//fill ranges - it should be supplied by server actualy 
			eq::PixelViewport curPVP = getPixelViewport();
			
			vector<Range> ranges;
			for( uint k=0; k<unusedFrames.size(); k++ )
			{
				Range curRange = unusedFrames[k]->getRange();
				
				if( !curRange.isFull() ) // Add only DB related slices, screen decomposition should be composed as is
				{
					ranges.push_back( curRange );
					IntersectViewports( curPVP, unusedFrames[k]->getImages(), unusedFrames[k]->getOffset() ); 
				}
			}
			
			//calculate correct frames sequence
			arrangeFrames( ranges );

			//check if current frame in proper position, redback if not
#ifndef NDEBUG
			if( _curFrData.lastRange == ranges.back() && !getenv( "EQ_TAINT_CHANNELS" ) )
				ranges.pop_back();
			else
#else
#ifndef SOLID_BG
			if( _curFrData.lastRange == ranges.back() )
				ranges.pop_back();
			else
#endif //SOLID_BG
#endif //NDEBUG
				if( curPVP.hasArea() )
				{
					_curFrameImage.setFormat(        Frame::BUFFER_COLOR, GL_RGBA          );
	        		_curFrameImage.setType(          Frame::BUFFER_COLOR, GL_UNSIGNED_BYTE );

					_curFrameImage.setPixelViewport(                      curPVP           );
					_curFrameImage.startReadback(    Frame::BUFFER_COLOR, curPVP           );
				
					//clear part of a screen
					clearViewport( curPVP );
				}

			while( !unusedFrames.empty() )
			{
		        for( vector<Frame*>::iterator i = unusedFrames.begin(); i != unusedFrames.end(); ++i )
		        {
					bool foundMatchedFrame = false;

		            Frame* frame = *i;
					Range curRange = frame->getRange();
					
					if( curRange.isFull() ) //2D screen element, asseble as is
					{
						_clearPixelViewPorts( frame->getImages(), frame->getOffset() );
	            		frame->startAssemble();
						unusedFrames.erase( i );
						foundMatchedFrame = true;
					}
					else
					{
						if( ranges.empty() ) // no ranges to put but some not full-ranges frames -> error
						{
							EQERROR << "uncounted frame" << endl;
							unusedFrames.erase( i );
							break;
						}else
							if( ranges.back() == curRange ) // current frame has proper range
							{
			            		frame->startAssemble();
								unusedFrames.erase( i );
								ranges.pop_back();
								foundMatchedFrame = true;
							}
					}

					if( ranges.back() == _curFrData.lastRange ) // current range equals to range of original frame
					{
						if( curPVP.hasArea() )
							_curFrameImage.startAssemble( Frame::BUFFER_COLOR, vmml::Vector2i( curPVP.x, curPVP.y ) );

						ranges.pop_back();
						foundMatchedFrame = true;
					}
					
					if( foundMatchedFrame )
						break;
	        	}			
			}
		}
    }

    for( vector<Frame*>::const_iterator i = frames.begin(); i != frames.end();
         ++i )
    {
        Frame* frame = *i;
        frame->syncAssemble();
        frame->removeListener( monitor );
    }

    resetAssemblyState();
}

void Channel::setupAssemblyState()
{
	eq::Channel::setupAssemblyState();

	glEnable( GL_BLEND );
	
#ifdef COMPOSE_MODE_NEW
	glBlendFunc( GL_ONE, GL_SRC_ALPHA );
#else
	glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
#endif

//	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}


void Channel::frameReadback( const uint32_t frameID )
{
    applyBuffer();
    applyViewport();
    setupAssemblyState();

    const vector<Frame*>& frames = getOutputFrames();

    for( vector<Frame*>::const_iterator iter = frames.begin(); iter != frames.end(); ++iter )
	{
		//Drop depth buffer flag if present
		(*iter)->disableBuffer( Frame::BUFFER_DEPTH );
		
        (*iter)->startReadback();
	}

    resetAssemblyState();
}


void Channel::_drawLogo()
{
    const Window*  window      = static_cast<Window*>( getWindow( ));
    GLuint         texture;
    vmml::Vector2i size;

    window->getLogoTexture( texture, size );
    if( !texture )
        return;
    
    const eq::PixelViewport pvp    = getPixelViewport();
    const vmml::Vector2i    offset = getPixelOffset();

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    glOrtho( offset.x, offset.x + pvp.w, offset.y, offset.y + pvp.h, 0., 1. );

	glMatrixMode(GL_TEXTURE);
	glLoadIdentity();

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    glDisable( GL_DEPTH_TEST );
    glDisable( GL_LIGHTING );
    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

    glEnable( GL_TEXTURE_RECTANGLE_ARB );
    glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture );
    glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
                     GL_LINEAR );
    glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, 
                     GL_LINEAR );

    glColor3f( 1.0f, 1.0f, 1.0f );
    glBegin( GL_TRIANGLE_STRIP ); {
        glTexCoord2f( 0.0f, 0.0f );
        glVertex3f( 0.0f, 0.0f, 0.0f );
        
        glTexCoord2f( size.x, 0.0f );
        glVertex3f( size.x, 0.0f, 0.0f );
        
        glTexCoord2f( 0.0f, size.y );
        glVertex3f( 0.0f, size.y, 0.0f );
        
        glTexCoord2f( size.x, size.y );
        glVertex3f( size.x, size.y, 0.0f );
    } glEnd();

    glDisable( GL_TEXTURE_RECTANGLE_ARB );
    glDisable( GL_BLEND );
    glEnable( GL_LIGHTING );
    glEnable( GL_DEPTH_TEST );
}

void Channel::_initFrustum( vmml::FrustumCullerf& culler )
{
	const Pipe*      pipe      = static_cast<Pipe*>( getPipe( ));
    const FrameData& frameData = pipe->getFrameData();

    vmml::Matrix4f view( frameData.data.rotation );
    
    if( _model )
    {
        vmml::Matrix4f scale( 
            _model->volScales.W, 0, 0, 0, 
            0, _model->volScales.H, 0, 0,
            0, 0, _model->volScales.D, 0,
            0, 0,                   0, 1 );
            
        view = scale * view;
    }
    
    view.setTranslation( frameData.data.translation );
    
    const vmml::Frustumf&  frustum       = getFrustum();
    const vmml::Matrix4f&  headTransform = getHeadTransform();
    const vmml::Matrix4f   modelView     = headTransform * view;

#ifdef DYNAMIC_NEAR_FAR
    vmml::Matrix4f modelInv;
    headTransform.getInverse( modelInv );

    const vmml::Vector3f zero  = modelInv * vmml::Vector3f( 0.0f, 0.0f,  0.0f );
    vmml::Vector3f       front = modelInv * vmml::Vector3f( 0.0f, 0.0f, -1.0f );
    front -= zero;
    front.normalise();
    EQINFO << getName()  << " front " << front << endl;
    front.scale( M_SQRT3_2 ); // bounding sphere size of unit-sized cube

    const vmml::Vector3f center( frameData.data.translation );
    const vmml::Vector3f near  = headTransform * ( center - front );
    const vmml::Vector3f far   = headTransform * ( center + front );
    const float          zNear = MAX( 0.0001f, -near.z );
    const float          zFar  = MAX( 0.0002f, -far.z );

    EQINFO << getName() << " center:    " << headTransform * center << endl;
    EQINFO << getName() << " near, far: " << near  << " " << far << endl;
    EQINFO << getName() << " near, far: " << zNear << " " << zFar << endl;
    setNearFar( zNear, zFar );
#endif

   	vmml::Matrix4f projection;
	if( _perspective )
	{
		projection         = frustum.computeMatrix();
		_curFrData.frustum = frustum; 

	}else
	{
	    vmml::Frustumf  f = frustum;
		double zc = ( 1.0 + f.farPlane/f.nearPlane ) / 3.0;
		f.left   *= zc;
		f.right  *= zc;
		f.top    *= zc;
		f.bottom *= zc;

	    projection         = f.computeOrthoMatrix();
		_curFrData.frustum = f; 
	}

	_curFrData.modelviewM.set( modelView.ml );
//	_curFrData.projectionM = projection;

	//calculate inverse transposed matrix
	_curFrData.modelviewM.getInverse( _curFrData.modelviewIM );
//	_curFrData.modelviewITM = (_curFrData.modelviewIM.getTransposed()).getMainSubmatrix();
	_curFrData.modelviewITM = _curFrData.modelviewIM.getTransposed();
	

    culler.setup( projection * modelView );
}
}




See more files for this project here

Equalizer - Multipipe Rendering

Equalizer is a programming interface and resource management system for scalable graphics applications for clusters and shared memory systems. It is build upon a scalable programming interface solving the problems common to any multipipe application.

Project homepage: http://sourceforge.net/projects/equalizer
Programming language(s): C,C++
License: lgpl21

  eqVol.app/
    Contents/
      MacOS/
  Bucky32x32x32_d.raw
  Bucky32x32x32_d.raw.vhf
  Makefile
  channel.cpp
  channel.h
  config.cpp
  config.h
  eqVol.cpp
  eqVol.h
  frame.h
  frameData.h
  fshader.cg
  fshader.oglsl
  fshader_.oglsl
  hlp.h
  image.h
  initData.cpp
  initData.h
  localInitData.cpp
  localInitData.h
  logo.rgb
  main.cpp
  node.cpp
  node.h
  pipe.cpp
  pipe.h
  rawConverter.cpp
  rawConverter.h
  rawVolModel.cpp
  rawVolModel.h
  shader.cpp
  shader.h
  tracker.cpp
  tracker.h
  vshader.cg
  vshader.lst
  vshader.oglsl
  vshader_.oglsl
  window.cpp
  window.h