CPPGPGPU Library - Reference (Doxygen)

Main Page | General Use | Reference | Examples Info | Get/Download CPPGPGPU | SF.net Page

OGLParts.cpp

Go to the documentation of this file.
00001 #include "OGLParts.h"
00002 #include <sys/types.h>
00003 #include <sys/stat.h>
00004 #include <string>
00005 using namespace std;
00006 
00007 GLuint imTypes[6] = { GL_LUMINANCE8, GL_RGB, GL_RGBA, GL_RGBA16F_ARB, GL_RGBA32F_ARB, 0 };
00008 
00009 //For things that require GL_RGBA when dealing with floating point data; usually when dealing with verticies or host data.
00010 GLuint imXTypes[6] ={ GL_LUMINANCE, GL_RGB, GL_RGBA, GL_RGBA, GL_RGBA, 0 };
00011 GLuint byTypes[6] = { GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE, GL_FLOAT, GL_FLOAT, 0 };
00012 
00013 int OpenPPM( const char * sPPMName, unsigned char ** buffer, int * width, int * height );
00014 
00015 void DestroyShaderProgram( GLhandleARB iProgramID )
00016 {
00017     GLhandleARB *objects = NULL;
00018     GLint i, count = -1;
00019 
00020     if( !iProgramID )
00021         return;
00022 
00023     //If we can't destroy the object, then don't try.
00024     glGetObjectParameterivARB(iProgramID, GL_OBJECT_ATTACHED_OBJECTS_ARB, &count);
00025 
00026     //Iterate through all children.
00027     if (count > 0)
00028     {
00029         objects = (GLhandleARB *)malloc(count*sizeof(GLhandleARB));
00030         glGetAttachedObjectsARB(iProgramID, count, NULL, objects);
00031     }
00032     else
00033         return;
00034 
00035     for ( i = 0; i < count; ++i)
00036     {
00037         glDetachObjectARB(iProgramID, objects[i]);
00038     }
00039 
00040     glDeleteObjectARB(iProgramID);
00041     free( objects );
00042     return;
00043 }
00044 
00045 Shader::Shader()
00046 {
00047     iProgramID = (GLhandleARB)NULL; 
00048     vertexShader = (GLhandleARB)NULL;
00049     fragmentShader = (GLhandleARB)NULL;
00050     geometryShader = (GLhandleARB)NULL;
00051     iTimeCode[0] = 0;
00052     iTimeCode[1] = 0;
00053     iTimeCode[2] = 0;
00054     bIsGLSLAsm = 0;
00055 //  sOldFilename = ""; 
00056 }
00057 
00058 Shader::~Shader()
00059 {
00060     DestroyShaderProgram( iProgramID );
00061 }
00062 
00063 void Shader::CheckForNewer( const char * sShaderName )
00064 {
00065     unsigned long iCurTimes[3];
00066     GetTimeCodes( iCurTimes, sShaderName );
00067     if( iCurTimes[0] != iTimeCode[0] || iCurTimes[1] != iTimeCode[1] || iCurTimes[2] != iTimeCode[2] )
00068     {
00069         DestroyShaderProgram( iProgramID );
00070         LoadShader( sShaderName );
00071     }
00072 }
00073 
00074 void Shader::GetTimeCodes( unsigned long * iOut, const char * sShaderName  )
00075 {
00076     struct stat sb;
00077     stat( (string(sShaderName)+".vert").c_str(), &sb );
00078     iOut[0] = sb.st_mtime;
00079     stat( (string(sShaderName)+".frag").c_str(), &sb );
00080     iOut[1] = sb.st_mtime;
00081     stat( (string(sShaderName)+".geom").c_str(), &sb );
00082     iOut[2] = sb.st_mtime;
00083 }
00084 
00085 bool Shader::LoadShader( const char * sShaderName )
00086 {
00087     GetTimeCodes( iTimeCode, sShaderName );
00088     string s1 = sShaderName, s2 = sShaderName, s3 = sShaderName;
00089     FILE * f1;
00090     FILE * f2;
00091     FILE * f3; //geometry
00092     char * Buffer;
00093     int i;
00094 
00095     s1 += ".frag";
00096     s2 += ".vert";
00097     s3 += ".geom";
00098     f1 = fopen( (char*)s1.c_str(), "rb" );
00099     f2 = fopen( (char*)s2.c_str(), "rb" );
00100     f3 = fopen( (char*)s3.c_str(), "rb" );
00101     if( f1 == 0 || f2 == 0 )
00102     {
00103         if( !f1 )
00104             printf( "Could not open %s.\n", (char*)s1.c_str() );
00105         if( !f2 )
00106             printf( "Could not open %s.\n", (char*)s2.c_str() );
00107         return false;
00108     }
00109     if( f1 )
00110     {
00111         fseek( f1, 0, SEEK_END );
00112         i = ftell( f1 );
00113         fseek( f1, 0, SEEK_SET );
00114         Buffer = (char*)malloc( i+1 );
00115         fread( Buffer, 1, i, f1 );
00116         fclose( f1 );
00117         printf( "Compiling: %s\n", s1.c_str() );
00118         Buffer[i] = '\0';
00119         if( !LoadShaderFrag( Buffer ) )
00120         {
00121             free( Buffer );
00122             if( f2 )
00123                 fclose( f2 );
00124             if( f3 )
00125                 fclose( f3 );
00126             printf( "Reporting failed shaderload. Not linking.\n" );
00127             return false;
00128         }
00129         free( Buffer );
00130     }
00131     if( f2 )
00132     {
00133         fseek( f2, 0, SEEK_END );
00134         i = ftell( f2 );
00135         fseek( f2, 0, SEEK_SET );
00136         Buffer = (char*)malloc( i+1 );
00137         fread( Buffer, 1, i, f2 );
00138         fclose( f2 );
00139         Buffer[i] = '\0';
00140         printf( "Compiling: %s\n", s2.c_str() );
00141         if( !LoadShaderVert( Buffer ) )
00142         {
00143             if( f3 )
00144                 fclose( f3 );
00145             free( Buffer );
00146             printf( "Reporting failed shaderload. Not linking.\n" );
00147             return false;
00148         }
00149         free( Buffer );
00150     }
00151     if( f3 )
00152     {
00153         fseek( f3, 0, SEEK_END );
00154         i = ftell( f3 );
00155         fseek( f3, 0, SEEK_SET );
00156         Buffer = (char*)malloc( i+1 );
00157         fread( Buffer, 1, i, f3 );
00158         fclose( f3 );
00159         Buffer[i] = '\0';
00160         printf( "Compiling: %s\n", s3.c_str() );
00161         if( !LoadShaderGeom( Buffer ) )
00162         {
00163             free( Buffer );
00164             printf( "Reporting failed shaderload. Not linking.\n" );
00165             return false;
00166         }
00167         free( Buffer );
00168     }
00169     return LinkShaders();
00170 }
00171 
00172 bool Shader::LoadShaderFrag( const char * sShaderCode )
00173 {
00174     if( strlen( sShaderCode ) < 5 )
00175         return false;
00176 
00177     if( strncmp( sShaderCode, "!!ARB", 5 ) == 0 )
00178     {
00179         glGenProgramsARB( 1, &fragmentProgram );
00180         glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, fragmentProgram );
00181         glProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(sShaderCode), (GLubyte*)sShaderCode );
00182         if (glGetError() != GL_NO_ERROR)
00183         {
00184             puts( "ERROR Compiling ASM Fragment Shader Error follows:" );
00185             puts( (char*)glGetString(GL_PROGRAM_ERROR_STRING_ARB) );
00186             return false;
00187         }
00188         bIsGLSLAsm = 1;
00189     }
00190     else
00191     {
00192         GLint bFragCompiled;
00193         GLint stringLength;
00194         fragmentShader = glCreateShaderObjectARB( GL_FRAGMENT_SHADER_ARB );
00195         glShaderSourceARB( fragmentShader, 1, &sShaderCode, NULL );
00196         glCompileShaderARB( fragmentShader );
00197     
00198         glGetObjectParameterivARB( fragmentShader, GL_OBJECT_COMPILE_STATUS_ARB, &bFragCompiled );
00199         glGetObjectParameterivARB( fragmentShader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &stringLength );
00200         if ( stringLength > 1 )
00201         {
00202             char * tmpstr = (char*)malloc( stringLength + 1 );
00203             glGetInfoLogARB( fragmentShader, stringLength, NULL, tmpstr );
00204             puts( "ERROR Compiling Fragment Shader Error follows:" );
00205             puts( tmpstr );
00206             free( tmpstr );
00207             return false;
00208         }
00209     }
00210     return true;
00211 }
00212 
00213 bool Shader::LoadShaderVert( const char * sShaderCode )
00214 {
00215     if( strlen( sShaderCode ) < 5 )
00216         return false;
00217 
00218     if( strncmp( sShaderCode, "!!ARB", 5 ) == 0 )
00219     {
00220         glGenProgramsARB( 1, &vertexProgram );
00221         glBindProgramARB( GL_VERTEX_PROGRAM_ARB, vertexProgram );
00222         glProgramStringARB( GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(sShaderCode), (GLubyte*)sShaderCode );
00223         if (glGetError() != GL_NO_ERROR)
00224         {
00225             puts( "ERROR Compiling ASM Fragment Shader Error follows:" );
00226             puts( (char*)glGetString(GL_PROGRAM_ERROR_STRING_ARB) );
00227             return false;
00228         }
00229         bIsGLSLAsm = 1;
00230     }
00231     else
00232     {
00233         GLint bVertCompiled;
00234         GLint stringLength;
00235         //Create a new vertex shader
00236         vertexShader = glCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
00237         //Bind the shader to the text, setting that to be its source.
00238         glShaderSourceARB( vertexShader, 1, &sShaderCode, NULL );
00239         //Compile the shader
00240         glCompileShaderARB( vertexShader );
00241         //Did the shader compile?  Were there any errors?
00242         glGetObjectParameterivARB( vertexShader, GL_OBJECT_COMPILE_STATUS_ARB, &bVertCompiled );
00243         glGetObjectParameterivARB( vertexShader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &stringLength );
00244         if( stringLength > 1 )
00245         {
00246             char * tmpstr = (char*)malloc( stringLength + 1 );
00247             glGetInfoLogARB( vertexShader, stringLength, NULL, tmpstr );
00248             puts( "ERROR Compiling Vertex Shader Error follows:" );
00249             puts( tmpstr );
00250             free( tmpstr );
00251             return false;
00252         }
00253     }
00254     return true;
00255 }
00256 
00257 bool Shader::LoadShaderGeom( const char * sShaderCode )
00258 {
00259     if( strlen( sShaderCode ) < 5 )
00260         return false;
00261 
00262     if( strncmp( sShaderCode, "!!ARB", 5 ) == 0 )
00263     {
00264         puts( "ERROR: ASM geometry shaders are not supported." );
00265         return false;
00266     }
00267     else
00268     {
00269         GLint bGeomCompiled;
00270         GLint stringLength;
00271         //Create a new geometry shader
00272         geometryShader = glCreateShaderObjectARB( GL_GEOMETRY_SHADER_EXT );
00273         //Bind the shader to the text, setting that to be its source.
00274         glShaderSourceARB( geometryShader, 1, &sShaderCode, NULL );
00275         //Compile the shader
00276         glCompileShaderARB( geometryShader );
00277         //Did the shader compile?  Were there any errors?
00278         glGetObjectParameterivARB( geometryShader, GL_OBJECT_COMPILE_STATUS_ARB, &bGeomCompiled );
00279         glGetObjectParameterivARB( geometryShader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &stringLength );
00280         if( stringLength > 1 || bGeomCompiled == 0 )
00281         {
00282             char * tmpstr = (char*)malloc( stringLength + 1 );
00283             glGetInfoLogARB( geometryShader, stringLength, NULL, tmpstr );
00284             puts( "ERROR Compiling Geometry Shader Error follows:" );
00285             puts( tmpstr );
00286             free( tmpstr );
00287             return false;
00288         }
00289     }
00290     return true;
00291 }
00292 
00293 bool Shader::LinkShaders()
00294 {
00295     if( bIsGLSLAsm )
00296     {
00297         return true;
00298     }
00299     else
00300     {
00301         GLint bLinked;
00302         GLint stringLength;
00303         //Create the actual shader prgoram
00304         iProgramID = glCreateProgramObjectARB();
00305         //Attach the fragment/vertex shader to it.
00306         if( vertexShader )
00307             glAttachObjectARB( iProgramID, vertexShader );
00308         if( fragmentShader )
00309             glAttachObjectARB( iProgramID, fragmentShader );
00310         if( geometryShader )
00311             glAttachObjectARB( iProgramID, geometryShader );
00312         //Attempt to link the shader
00313         glLinkProgramARB( iProgramID );
00314 
00315         //If we're using a geometry shader, we have to do a little extra.
00316         if( geometryShader )
00317         {
00318             glProgramParameteriEXT( iProgramID, GL_GEOMETRY_INPUT_TYPE_EXT, GL_TRIANGLES );
00319             glProgramParameteriEXT( iProgramID, GL_GEOMETRY_OUTPUT_TYPE_EXT, GL_TRIANGLE_STRIP );
00320 
00321             int ierror, i;
00322             GLint imaxvert;
00323             glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT,&imaxvert);
00324             if( (ierror = glGetError()) != 0 )
00325             {
00326                 puts( "ERROR: You cannot load a geometry shader when there are still errors left in OpenGL." );
00327                 puts( "Please track down the error remaining by using glGetError() to cordon off your code." );
00328                 printf( "The last error received was: %d\n", ierror );
00329             }
00330             for( i = 1; i < imaxvert; i++ )
00331             {
00332                 glProgramParameteriEXT(iProgramID,GL_GEOMETRY_VERTICES_OUT_EXT,imaxvert/i);
00333                 if( glGetError() == 0 )
00334                     break;
00335             }
00336             printf( "Geometry Shader loaded with a total of %d max verticies.  Because there are %d max vertices, and %d preceived components per vert.\n", imaxvert/i, imaxvert, i );
00337         }
00338 
00339 
00340         //See if there were any errors.
00341         glGetObjectParameterivARB( iProgramID, GL_OBJECT_LINK_STATUS_ARB, &bLinked );
00342         glGetObjectParameterivARB( iProgramID, GL_OBJECT_INFO_LOG_LENGTH_ARB, &stringLength );
00343 
00344         if ( stringLength > 1 || bLinked == 0 )
00345         {
00346             char * tmpstr = (char*)malloc( stringLength + 1 );
00347             glGetInfoLogARB( iProgramID, stringLength, NULL, tmpstr );
00348             puts( "ERROR linking shaders. Error follows:" );
00349             puts( tmpstr );
00350             free( tmpstr );
00351             return false;
00352         }
00353         return true;
00354     }
00355 }
00356 
00357 bool Shader::ActivateShader( vector< string > &vsAllSamplerLocs, vector< string > &vsUniformFloats, vector < float > & vfUniformFloats )
00358 {
00359     unsigned i;
00360 
00361     if( bIsGLSLAsm )
00362     {
00363         glEnable( GL_VERTEX_PROGRAM_ARB );
00364         glBindProgramARB( GL_VERTEX_PROGRAM_ARB, vertexProgram);
00365         glEnable( GL_FRAGMENT_PROGRAM_ARB );
00366         glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, fragmentProgram);
00367 
00368         for( i = 0; i < vfUniformFloats.size(); ++i )
00369         {
00370             glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, i, vfUniformFloats[i],0,0,0 );
00371             glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, i, vfUniformFloats[i],0,0,0 );
00372         }
00373     }
00374     else
00375     {
00376         glUseProgramObjectARB( iProgramID );
00377     
00378         for( i = 0; i < vsAllSamplerLocs.size(); ++i )
00379         {
00380             int iTexPosID = glGetUniformLocationARB( iProgramID, vsAllSamplerLocs[i].c_str() );
00381             if( iTexPosID > -1 )
00382                 glUniform1iARB( iTexPosID, i );
00383         }
00384     
00385         for( i = 0; i < vsUniformFloats.size(); ++i )
00386         {
00387             int iTexPosID = glGetUniformLocationARB( iProgramID, vsUniformFloats[i].c_str() );
00388             if( iTexPosID > -1 )
00389                 glUniform1fARB( iTexPosID, vfUniformFloats[i] );
00390         }   
00391     }
00392     return true;
00393 }
00394 
00395 bool Shader::ActivateShader( vector< string > &vsAllSamplerLocs)
00396 {
00397     unsigned i;
00398 
00399     glUseProgramObjectARB( iProgramID );
00400 
00401     for( i = 0; i < vsAllSamplerLocs.size(); ++i )
00402     {
00403         int iTexPosID = glGetUniformLocationARB( iProgramID, vsAllSamplerLocs[i].c_str() );
00404         if( iTexPosID > -1 )
00405             glUniform1iARB( iTexPosID, i );
00406     }
00407 
00408     return true;
00409 }
00410 
00411 bool Shader::DeactivateShader()
00412 {
00413     glUseProgramObjectARB( 0 );
00414     return true;
00415 }
00416 
00417 Texture::~Texture()
00418 {
00419     if( (int)iTexture == -1 )
00420         return;
00421     glDeleteTextures( 1, &iTexture );
00422 }
00423 
00424 bool Texture::StripFromScreen( int x, int y, int width, int height )
00425 {
00426     glActiveTextureARB( GL_TEXTURE0_ARB );
00427     glBindTexture( GL_TEXTURE_2D, iTexture );
00428     glEnable( GL_TEXTURE_2D );
00429 
00430     glCopyTexImage2D( GL_TEXTURE_2D, 0, imXTypes[mtt], x, y, width, height, 0);
00431 
00432     glDisable( GL_TEXTURE_2D );
00433         glBindTexture( GL_TEXTURE_2D, 0 );
00434     return true;
00435 }
00436 
00437 bool Texture::MakeDynamicTexture( int iWidth, int iHeight, TextureType tt )
00438 {
00439     mtt = tt;
00440     mWidth = iWidth;
00441     mHeight = iHeight;
00442 
00443     if( (int)iTexture == -1 )
00444         glGenTextures( 1, &iTexture );
00445     if( (int)iTexture == -1 )
00446         return false;
00447 
00448     glBindTexture( GL_TEXTURE_2D, iTexture );
00449     glCopyTexImage2D( GL_TEXTURE_2D, 0, imTypes[tt], 0, 0, iWidth, iHeight, 0 );
00450     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
00451     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00452     glBindTexture( GL_TEXTURE_2D, 0 );
00453     return true;
00454 }
00455 
00456 bool Texture::LoadTextureFile( const char * sFileName )
00457 {
00458     unsigned char * Buffer;
00459     if( (int)iTexture == -1 )
00460         glGenTextures( 1, &iTexture );
00461     if( (int)iTexture == -1 )
00462     {
00463         puts( "Texture failed to generate" );
00464         return false;
00465     }
00466     if( !OpenPPM( sFileName, &Buffer, &mWidth, &mHeight ) )
00467     {
00468         puts( "PPM Failed to open" );
00469         return false;
00470     }
00471     mtt = TTRGB;
00472 
00473     glBindTexture( GL_TEXTURE_2D, iTexture );
00474     glTexImage2D( GL_TEXTURE_2D, 0, imTypes[mtt], mWidth, mHeight, 0, imTypes[mtt], byTypes[mtt], Buffer );
00475     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00476     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00477     glBindTexture( GL_TEXTURE_2D, 0 );
00478     free( Buffer );
00479     return true;
00480 }
00481 
00482 bool Texture::LoadTexture( char * sRawData, int iWidth, int iHeight, TextureType tt )
00483 {
00484     if( (int)iTexture == -1 )
00485         glGenTextures( 1, &iTexture );
00486     if( (int)iTexture == -1 )
00487         return false;
00488 
00489     mtt = tt;
00490     mWidth = iWidth;
00491     mHeight = iHeight;
00492 
00493     glBindTexture( GL_TEXTURE_2D, iTexture );
00494     glTexImage2D( GL_TEXTURE_2D, 0, imTypes[mtt], mWidth, mHeight, 0, imXTypes[mtt], byTypes[mtt], sRawData );
00495     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
00496     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00497     glBindTexture( GL_TEXTURE_2D, 0 );
00498     return true;
00499 }
00500 
00501 void Texture::ChangeFilter( bool bNearest )
00502 {
00503     glBindTexture( GL_TEXTURE_2D, iTexture );
00504     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (bNearest)?GL_NEAREST:GL_LINEAR );
00505     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (bNearest)?GL_NEAREST:GL_LINEAR );
00506     glBindTexture( GL_TEXTURE_2D, 0 );
00507 }
00508 
00509 bool Texture::ActivateTexture( int iPlace )
00510 {
00511     glActiveTextureARB( GL_TEXTURE0_ARB + iPlace );
00512     glBindTexture( GL_TEXTURE_2D, iTexture );
00513     glEnable( GL_TEXTURE_2D );
00514     return true;
00515 }
00516 
00517 bool Texture::DeactivateTexture( int iPlace )
00518 {
00519     glActiveTextureARB( GL_TEXTURE0_ARB + iPlace );
00520     glDisable( GL_TEXTURE_2D );
00521     return true;
00522 }
00523 
00524 RFBuffer::RFBuffer()
00525 {
00526     mWidth = 0; mHeight = 0; mtt = TTGRAYSCALE;
00527     iRenderbuffer = 0;
00528     iOutputBuffer = 0;
00529 }
00530 
00531 RFBuffer::~RFBuffer()
00532 {
00533     if( iRenderbuffer != 0 )
00534     {
00535         glDeleteRenderbuffersEXT( 1, &iRenderbuffer );
00536         glDeleteFramebuffersEXT( 1, &iOutputBuffer );
00537     }
00538 }
00539 
00540 bool RFBuffer::Setup( bool bUseDepthBuffer )
00541 {
00542     m_bUseDepthBuffer = bUseDepthBuffer;
00543     if( m_bUseDepthBuffer )
00544         glGenRenderbuffersEXT( 1, &iRenderbuffer );
00545     glGenFramebuffersEXT( 1, &iOutputBuffer );
00546     return true;
00547 }
00548 
00549 bool RFBuffer::ConfigureAndStart( int iWidth, int iHeight, int iTextures, Texture * TexturesToAttach, bool bClear )
00550 {
00551     const GLenum buffers[8] = {   GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT,
00552             GL_COLOR_ATTACHMENT3_EXT, GL_COLOR_ATTACHMENT4_EXT, GL_COLOR_ATTACHMENT5_EXT,
00553             GL_COLOR_ATTACHMENT6_EXT, GL_COLOR_ATTACHMENT7_EXT };
00554     mWidth = iWidth; mHeight = iHeight;
00555     if( m_bUseDepthBuffer )
00556     {
00557         glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, iRenderbuffer );
00558         glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, mWidth, mHeight );
00559     }
00560     glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, iOutputBuffer );
00561     for( int i = 0; i < iTextures; i++ )
00562         glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + i, 
00563             GL_TEXTURE_2D, TexturesToAttach[i].GetTexHandle(), 0 );
00564     if( m_bUseDepthBuffer  )
00565         glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, 
00566             GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, iRenderbuffer );
00567 
00568     //Added by Peter Bessman to verify nonexecution of the following code.
00569     #ifdef _WIN32
00570     if (glDrawBuffersARB)
00571     #endif
00572         glDrawBuffersARB( iTextures, buffers );
00573     glViewport( 0, 0, mWidth, mHeight );
00574 
00575     //Check to see if there were any errors with the framebuffer
00576     switch( (GLenum)glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) )
00577     {
00578         case GL_FRAMEBUFFER_COMPLETE_EXT: break;  //GOOD!
00579         case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
00580             printf("OpenGL Framebuffer error: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\n");
00581             return false;
00582         case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
00583             printf("OpenGL Framebuffer error: GL_FRAMEBUFFER_UNSUPPORTED_EXT\n");
00584             return false;
00585         case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
00586             printf("OpenGL Framebuffer error: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\n");
00587             return false;
00588         case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
00589             printf("OpenGL Framebuffer error: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\n");
00590             return false;
00591         case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
00592             printf("OpenGL Framebuffer error: GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\n");
00593             return false;
00594         case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
00595             printf("OpenGL Framebuffer error: GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\n");
00596             return false;
00597         case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
00598             printf("OpenGL Framebuffer error: GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\n");
00599             return false;
00600         default:
00601             printf("UNKNWON error with OpenGL Framebuffer\n");
00602             return false;
00603     }
00604 
00605     if( bClear )
00606         glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00607     return true;
00608 }
00609 
00610 bool RFBuffer::End( int iRegVPX, int iRegVPY )
00611 {
00612     for( unsigned i = 0; i < 8; i++ )
00613     {
00614         glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + i, 
00615             GL_TEXTURE_2D, 0, 0 );
00616 
00617         glActiveTextureARB( GL_TEXTURE0_ARB + i );
00618         glDisable( GL_TEXTURE_2D );
00619     }
00620     glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
00621     glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, 0 );
00622     glViewport( 0, 0, iRegVPX, iRegVPY );
00623     return true;
00624 }
00625 
00626 VertexData::~VertexData()
00627 {
00628     if( iVertexData == 0 )
00629         return;
00630     glDeleteBuffersARB( 1, &iVertexData );
00631 }
00632 
00633 void VertexData::Init( float * Verts, int iNumVerts, int iStride )
00634 {
00635     mStride = iStride;
00636     glGenBuffersARB( 1, &iVertexData );
00637     glBindBufferARB( GL_ARRAY_BUFFER_ARB, iVertexData  );
00638     if( !Verts )
00639         glBufferDataARB( GL_ARRAY_BUFFER_ARB, iNumVerts * iStride * sizeof( float ), 0, GL_STREAM_COPY );
00640     else
00641         UpdateData( Verts, iNumVerts, iStride );
00642 }
00643 
00644 void VertexData::UpdateData( float * Verts, int iNumVerts, int iStride )
00645 {
00646     mStride = iStride;
00647     glBindBufferARB( GL_ARRAY_BUFFER_ARB, iVertexData  );
00648     glBufferDataARB( GL_ARRAY_BUFFER_ARB, iNumVerts * iStride * sizeof( float ), Verts, GL_STATIC_DRAW_ARB );
00649     glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
00650 }
00651 
00652 void VertexData::StripFromFrameBuffer( int iWidth, int iHeight, TextureType tt )
00653 {
00654     glBindBufferARB( GL_PIXEL_PACK_BUFFER_ARB, iVertexData );
00655 
00656     glReadPixels( 0, 0, iWidth, iHeight, imXTypes[tt], byTypes[tt], 0 );
00657     glBindBufferARB( GL_PIXEL_PACK_BUFFER_ARB, 0 );
00658 }
00659 
00660 IndexData::~IndexData()
00661 {   
00662 }
00663 
00664 void IndexData::Init( int * Indices, int iNumIndices )
00665 {
00666     mIndexData = (GLuint*)Indices; mIndexCount = iNumIndices;
00667 }
00668 
00669 int FileReadLine( FILE * f, char * line, int iBufferSize )
00670 {
00671         int iPlace = 0;
00672 
00673         //Read the first character.
00674         char cCh = fgetc( f );
00675 
00676         //If we have a newline, or a windows-type newline, quit.
00677         while( cCh != '\n' && cCh != '\r' && !feof( f ))
00678         {
00679                 line[iPlace] = cCh;
00680                 iPlace++;
00681                 if( iPlace >= iBufferSize )
00682                         return 0;
00683                 cCh = fgetc( f );
00684         }
00685         //If it's a windows-type newline (\r\n) then, throw away the true \n.
00686         if( cCh == '\r' )
00687                 fgetc( f );
00688 
00689         line[iPlace] = '\0';
00690 
00691         return iPlace;
00692 }
00693 
00694 
00695 //
00696 //NOTE: I have no IDEA at ALL if this is being parsed right, I just exported some PPM's from GIMP
00697 //      and this thing seems to load them all ok. (DO NOT TRUST THIS CODE TO BE RELIABLE)
00698 //
00699 int OpenPPM( const char * sPPMName, unsigned char ** buffer, int * width, int * height )
00700 {
00701         unsigned char Magic[2];
00702         char line[512];
00703         int maxval;
00704         int totalsize;
00705 
00706         *width = 0;
00707         *height = 0;
00708 
00709         FILE * f = fopen( sPPMName, "rb" );
00710         if( !f )
00711         {
00712                 printf( "Could not open specified ppm, %s.\n", sPPMName );
00713                 return 0;
00714         }
00715 
00716         fread( &Magic[0], 2, 1, f );
00717         if( Magic[0] != 'P' || Magic[1] != '6' )
00718         {
00719                 fclose( f );
00720                 printf( "The PPM: %s does not contain the P6 magic word.\n", sPPMName );
00721                 return 0;
00722         }
00723 
00724         FileReadLine( f, line, 512 );
00725 
00726         //No idea if this part is right, I'd expect it to be wrong.  It just happens to work with gimp.
00727         while( FileReadLine( f, line, 512 ) && !feof( f ))
00728                 if( sscanf( line, "%d %d", width, height ) == 2 )
00729                         break;
00730 
00731         while( FileReadLine( f, line, 512 ) && !feof( f ))
00732                 if( sscanf( line, "%d", &maxval ) == 1 )
00733                         break;
00734 
00735         if( *width <= 0 || *width >= 8192 || *height <=0 || *height >= 8192 )
00736         {
00737                 fclose( f );
00738                 printf( "Invalid image size set for PPM: %s.  (Or PPM Read Failed.)\n", sPPMName );
00739                 return 0;
00740         }
00741 
00742         if( maxval != 255 )
00743         {
00744                 fclose( f );
00745                 printf( "Unsupported color-byte type for PPM: %s\n", sPPMName );
00746                 return 0;
00747         }
00748 
00749         totalsize = 3 * (*height) * (*width);
00750         *buffer = (unsigned char*)malloc( totalsize );
00751         fread( *buffer, totalsize, 1, f );
00752         fclose( f );
00753         return totalsize;
00754 }
00755 
00756 void DrawSquare()
00757 {
00758     glBegin( GL_QUADS );
00759     glTexCoord2f( 0.0f, 0.0f );
00760     glVertex3f( -1.0f, -1.0f, 0.0f );
00761     glTexCoord2f( 0.0f, 1.0f );
00762     glVertex3f( -1.0f, 1.0f, 0.0f );
00763     glTexCoord2f( 1.0f, 1.0f );
00764     glVertex3f( 1.0f, 1.0f, 0.0f );
00765     glTexCoord2f( 1.0f, 0.0f );
00766     glVertex3f( 1.0f, -1.0f, 0.0f );
00767     glEnd();
00768 }
00769 
00770 
00771 void DrawGeometry( VertexData ** vd, string * vsVertexNames, int iNumVertexDatas, IndexData * id, Shader * sShader )
00772 {
00773     int i;
00774     glBindBufferARB( GL_ARRAY_BUFFER_ARB, vd[0]->iVertexData );
00775     glVertexPointer( vd[0]->mStride, GL_FLOAT, 0, 0 );
00776 
00777     if( sShader )
00778         for( i = 1; i < iNumVertexDatas; ++i )
00779         {
00780             int iTexPosID = glGetAttribLocationARB( sShader->GetProgramID(), vsVertexNames[i].c_str() );
00781             glBindBufferARB( GL_ARRAY_BUFFER_ARB, vd[i]->iVertexData );
00782             glEnableVertexAttribArrayARB( iTexPosID );
00783             glVertexAttribPointerARB( iTexPosID, vd[i]->mStride, GL_FLOAT, 0, 0, 0 );
00784         }
00785 
00786 
00787     glEnableClientState( GL_VERTEX_ARRAY );
00788     glDrawElements( GL_POINTS, id->mIndexCount, GL_UNSIGNED_INT, id->mIndexData );
00789     glDisableClientState( GL_VERTEX_ARRAY );
00790 }
00791 
00792 void DrawGeometrySolid( VertexData ** vd, string * vsVertexNames, int iNumVertexDatas, IndexData * id, Shader * sShader, int facecount )
00793 {
00794     int i;
00795     glBindBufferARB( GL_ARRAY_BUFFER_ARB, vd[0]->iVertexData );
00796     glVertexPointer( vd[0]->mStride, GL_FLOAT, 0, 0 );
00797 
00798     if( sShader )
00799         for( i = 1; i < iNumVertexDatas; ++i )
00800         {
00801             int iTexPosID = glGetAttribLocationARB( sShader->GetProgramID(), vsVertexNames[i].c_str() );
00802             glBindBufferARB( GL_ARRAY_BUFFER_ARB, vd[i]->iVertexData );
00803             glEnableVertexAttribArrayARB( iTexPosID );
00804             glVertexAttribPointerARB( iTexPosID, vd[i]->mStride, GL_FLOAT, 0, 0, 0 );
00805         }
00806 
00807 
00808     glEnableClientState( GL_VERTEX_ARRAY );
00809     glDrawElements( GL_TRIANGLES, facecount, GL_UNSIGNED_INT, id->mIndexData );
00810     glDisableClientState( GL_VERTEX_ARRAY );
00811 }
00812 
00813 void SetupForDataRun()
00814 {
00815     glDisable( GL_LIGHTING );
00816     glMatrixMode(GL_PROJECTION);
00817     glPushMatrix();
00818     glLoadIdentity();
00819     glMatrixMode(GL_MODELVIEW);
00820     glPushMatrix();
00821     glLoadIdentity();
00822 }
00823 
00824 void PopFromDataRun()
00825 {
00826     glMatrixMode( GL_PROJECTION );
00827     glPopMatrix();
00828     glMatrixMode( GL_MODELVIEW );
00829     glPopMatrix();
00830 }
00831 
00832 void StripDataFromBuffer( int ix, int iy, int iwidth, int iheight, TextureType tt, char * buffer )
00833 {
00834     glReadPixels( ix, iy, iwidth, iheight, imXTypes[tt], byTypes[tt], buffer );
00835 }
00836 
00837 /*
00838 Copyright (c) 2005, 2006, 2007 Charles Lohr, David Chapman, Joshua Allen
00839 
00840 Permission is hereby granted, free of charge, to any person obtaining a copy
00841 of this software and associated documentation files (the "Software"), to deal
00842 in the Software without restriction, including without limitation the rights
00843 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00844 copies of the Software, and to permit persons to whom the Software is
00845 furnished to do so, subject to the following conditions:
00846 
00847 The above copyright notice and this permission notice shall be included in
00848 all copies or substantial portions of the Software.
00849 
00850 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00851 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00852 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00853 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00854 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00855 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00856 THE SOFTWARE.
00857 */

© 2005-2007 Charles Lohr, Joshua Allen, David Chapman, Andrew Lohr. All material including documentation under the MIT/X11 license.