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
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
00024 glGetObjectParameterivARB(iProgramID, GL_OBJECT_ATTACHED_OBJECTS_ARB, &count);
00025
00026
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
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;
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
00236 vertexShader = glCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
00237
00238 glShaderSourceARB( vertexShader, 1, &sShaderCode, NULL );
00239
00240 glCompileShaderARB( vertexShader );
00241
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
00272 geometryShader = glCreateShaderObjectARB( GL_GEOMETRY_SHADER_EXT );
00273
00274 glShaderSourceARB( geometryShader, 1, &sShaderCode, NULL );
00275
00276 glCompileShaderARB( geometryShader );
00277
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
00304 iProgramID = glCreateProgramObjectARB();
00305
00306 if( vertexShader )
00307 glAttachObjectARB( iProgramID, vertexShader );
00308 if( fragmentShader )
00309 glAttachObjectARB( iProgramID, fragmentShader );
00310 if( geometryShader )
00311 glAttachObjectARB( iProgramID, geometryShader );
00312
00313 glLinkProgramARB( iProgramID );
00314
00315
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
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
00569 #ifdef _WIN32
00570 if (glDrawBuffersARB)
00571 #endif
00572 glDrawBuffersARB( iTextures, buffers );
00573 glViewport( 0, 0, mWidth, mHeight );
00574
00575
00576 switch( (GLenum)glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) )
00577 {
00578 case GL_FRAMEBUFFER_COMPLETE_EXT: break;
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
00674 char cCh = fgetc( f );
00675
00676
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
00686 if( cCh == '\r' )
00687 fgetc( f );
00688
00689 line[iPlace] = '\0';
00690
00691 return iPlace;
00692 }
00693
00694
00695
00696
00697
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
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
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857