00001
00002 #ifndef RT_GLES1
00003
00004 #include "RenderTools.h"
00005 #include "Program.h"
00006 #include "Sampler.h"
00007 #include "Error.h"
00008 #include "Property.h"
00009
00010 #include <string>
00011 #include <ctype.h>
00012
00013 using namespace std;
00014
00015 namespace RenderTools {
00016
00017 ProgramPtr Program::s_current = ProgramPtr();
00018
00024 Program::Program( void ):
00025 AbstractPropertyContainer( ),
00026 m_vertexShader( "" ),
00027 m_fragmentShader( "" ),
00028 m_programID( 0 ),
00029 m_vertexID( 0 ),
00030 m_fragmentID( 0 ),
00031 m_unit( 0 ){
00032
00033 }
00034
00035 PropertyPtr Program::create( const XMLNodePtr & xml ){
00036 ProgramPtr p( new Program() );
00037 p->setName( xml );
00038 p->createProperties();
00039 p->setProperties( xml, false );
00040 return( dynamic_pointer_cast< AbstractProperty, Program >( p ) );
00041 }
00042
00043 void Program::createProperties( void ){
00044 AbstractPropertyContainer::createProperties();
00045 createProperty( this, "uniforms", & m_uniforms );
00046 createProperty( this, "vertexShader", & m_vertexShader, SHADER | FILENAME );
00047 createProperty( this, "fragmentShader", & m_fragmentShader, SHADER | FILENAME );
00048 }
00049
00050 const string Program::getTypeName( bool ofComponent ) const {
00051 return( "Program" );
00052 }
00053
00054 void Program::onInitialize( void ){
00056 unbind();
00057
00058 m_uniforms->removeProperties();
00059
00060 string vertexCodeStr;
00061 string fragmentCodeStr;
00062
00063 if( m_vertexShader != "" ){
00064
00065 vertexCodeStr = readCode( m_vertexShader );
00066 }
00067 if( m_fragmentShader != "" ){
00068
00069 fragmentCodeStr = readCode( m_fragmentShader );
00070 }
00071
00072
00073 if( m_vertexID ){
00074 glDeleteShader( m_vertexID );
00075 }
00076 if( m_fragmentID ){
00077 glDeleteShader( m_fragmentID );
00078 }
00079 if( m_programID ){
00080 glDeleteProgram( m_programID );
00081 }
00082
00083 m_programID = glCreateProgram();
00084
00085 if( m_vertexShader != "" ){
00086 m_vertexID = glCreateShader( GL_VERTEX_SHADER );
00087 }
00088 if( m_fragmentShader != "" ){
00089 m_fragmentID = glCreateShader( GL_FRAGMENT_SHADER );
00090 }
00091
00092 GLint status;
00093 char *codeptr;
00094
00095 if( m_vertexShader != "" ){
00096
00097 codeptr = ( char * )vertexCodeStr.c_str();
00098 glShaderSource( m_vertexID, 1, ( const char ** )&codeptr, NULL );
00099 glCompileShader( m_vertexID );
00100 glGetShaderiv( m_vertexID, GL_COMPILE_STATUS, &status );
00101 if( status == GL_FALSE ){
00102 printProgramInfo( m_programID );
00103 printShaderInfo( m_fragmentID );
00104 printShaderInfo( m_vertexID );
00105 printInfoLog();
00106 Error::error( Error::SHADER_COMPILE_FAILED, __FILE__, __LINE__, m_vertexShader );
00107 }
00108
00109 glAttachShader( m_programID, m_vertexID );
00110 }
00111
00112 if( m_fragmentShader != "" ){
00113
00114 codeptr = ( char * )fragmentCodeStr.c_str();
00115 glShaderSource( m_fragmentID, 1, ( const char ** )&codeptr, NULL );
00116 glCompileShader( m_fragmentID );
00117 glGetShaderiv( m_fragmentID, GL_COMPILE_STATUS, &status );
00118 if( status == GL_FALSE ){
00119 printProgramInfo( m_programID );
00120 printShaderInfo( m_fragmentID );
00121 printShaderInfo( m_vertexID );
00122 printInfoLog();
00123 Error::error( Error::SHADER_COMPILE_FAILED, __FILE__, __LINE__, m_fragmentShader );
00124 }
00125 glAttachShader( m_programID, m_fragmentID );
00126 }
00127
00128
00129 glLinkProgram( m_programID );
00130 glGetProgramiv( m_programID, GL_LINK_STATUS, &status );
00131 if( status == GL_FALSE ){
00132 printProgramInfo( m_programID );
00133 printShaderInfo( m_fragmentID );
00134 printShaderInfo( m_vertexID );
00135 printInfoLog();
00136 Error::error( Error::SHADER_LINK_FAILED, __FILE__, __LINE__, m_vertexShader + " or " + m_fragmentShader );
00137 }
00138
00139
00140 extractUniforms( m_vertexShader );
00141 extractUniforms( m_fragmentShader );
00142
00143
00144 Error::assertNoErrors( __FILE__, __LINE__, m_vertexShader + " or " + m_fragmentShader );
00145
00146 }
00150 void Program::extractUniforms( string shader ){
00151
00152 string codestr = readCode( shader );
00153
00154 int codelen = codestr.size() + 1;
00155
00156 char * strptr = ( char * )calloc( codelen, 1 );
00157
00158 memcpy( strptr, ( char * )codestr.c_str(), codestr.size() );
00159
00160 char * cptr = strptr;
00161
00162 while( ( cptr = strstr( cptr, "//" ) ) ){
00163 while( *cptr != '\n' ){
00164
00165 if( cptr - strptr > codelen ){
00166 Error::error( Error::FILE_READ_FAILED, __FILE__, __LINE__, "while reading uniform" );
00167 }
00168 *cptr++ = ' ';
00169 }
00170 }
00171
00172 cptr = strptr;
00173
00174 while( ( cptr = strstr( cptr, "/*" ) ) ){
00175 while( strncmp( cptr , "*/", 2 ) ){
00176
00177 if( cptr - strptr > codelen ){
00178 Error::error( Error::FILE_READ_FAILED, __FILE__, __LINE__, "while reading uniform" );
00179 }
00180
00181 *cptr++ = ' ';
00182 }
00183 }
00184
00185 cptr = strptr;
00186
00187 while( ( cptr = strstr( cptr, "uniform" ) ) ){
00188
00189 cptr += strlen( "uniform" );
00190
00191 while( *cptr == ' ' || *cptr == '\t' )cptr++;
00192
00193 char *type = cptr;
00194
00195
00196 while( *cptr != ' ' && *cptr != '\t' )cptr++;
00197
00198 while( *cptr == ' ' || *cptr == '\t' )cptr++;
00199
00200 if( cptr - strptr > codelen ){
00201 Error::error( Error::FILE_READ_FAILED, __FILE__, __LINE__, "while reading uniform" );
00202 }
00203
00204
00205 string name;
00206 int arraySize = 1;
00207
00208 while( *cptr != ' ' && *cptr != '\t' && *cptr != ';' ){
00209 if( *cptr == '[' ){
00210 arraySize = atoi( ++cptr );
00211 break;
00212 }
00213 else{
00214 name += *cptr;
00215 cptr++;
00216 }
00217 if( cptr - strptr > codelen ){
00218 Error::error( Error::FILE_READ_FAILED, __FILE__, __LINE__, "while reading uniform" );
00219 }
00220 }
00221
00222
00223 bool found = false;
00224 char * ref = cptr;
00225 while( ( ref = strstr( ref, name.c_str() ) ) ){
00226 if( ! isalpha( *( ref - 1 ) ) && ! isalpha( *( ref + name.size() ) ) ){
00227 found = true;
00228 break;
00229 }
00230 ref += name.size();
00231 }
00232 if( ! found )continue;
00233
00234 if( strncmp( type, "bool", strlen( "bool" ) ) == 0 ){
00235 vector< GLint > * v = new vector< GLint >();
00236 v->resize( arraySize );
00237 createProperty( m_uniforms.get(), name, v );
00238 }
00239 else if( strncmp( type, "int", strlen( "int" ) ) == 0 ){
00240 vector< GLint > * v = new vector< GLint >();
00241 v->resize( arraySize );
00242 createProperty( m_uniforms.get(), name, v );
00243 }
00244 else if( strncmp( type, "float", strlen( "float" ) ) == 0 ){
00245 vector< GLfloat > * v = new vector< GLfloat >();
00246 v->resize( arraySize );
00247 createProperty( m_uniforms.get(), name, v );
00248 }
00249 else if( strncmp( type, "vec2", strlen( "vec2" ) ) == 0 ){
00250 vector< GLfloat > * v = new vector< GLfloat >();
00251 v->resize( arraySize );
00252 createProperty( m_uniforms.get(), name, v );
00253 }
00254 else if( strncmp( type, "vec3", strlen( "vec3" ) ) == 0 ){
00255 vector< GLfloat > * v = new vector< GLfloat >();
00256 v->resize( arraySize );
00257 createProperty( m_uniforms.get(), name, v );
00258 }
00259 else if( strncmp( type, "vec4", strlen( "vec4" ) ) == 0 ){
00260 vector< GLfloat > * v = new vector< GLfloat >();
00261 v->resize( arraySize );
00262 createProperty( m_uniforms.get(), name, v );
00263 }
00264 else if( strncmp( type, "mat4", strlen( "mat4" ) ) == 0 ){
00265 vector< GLfloat > * v = new vector< GLfloat >();
00266 v->resize( arraySize );
00267 createProperty( m_uniforms.get(), name, v );
00268 }
00269 else if( strncmp( type, "sampler2D", strlen( "sampler2D" ) ) == 0 ){
00270 createProperty( m_uniforms.get(), name, name.c_str() );
00271 }
00272 else{
00273 continue;
00274 }
00275 }
00276
00277 free( strptr );
00278 }
00279
00280 GLuint Program::getProgramID( void ) const {
00281 return( m_programID );
00282 }
00283
00284 GLuint Program::getVertexID( void ) const {
00285 return( m_vertexID );
00286 }
00287
00288 GLuint Program::getFragmentID( void ) const {
00289 return( m_fragmentID );
00290 }
00291
00292 const PropertyContainerPtr Program::getUniforms( void ) const {
00293 return( m_uniforms );
00294 }
00295
00296 const PropertyPtr Program::findUniform( const string name ) const {
00297 for( unsigned int i = 0; i < m_uniforms->size(); i++ ){
00298 if( m_uniforms->getItem( i )->getName() == name ){
00299 return( m_uniforms->getProperty( i ) );
00300 }
00301 }
00302 return( PropertyPtr() );
00303 }
00304
00305 #ifdef RT_CG
00306
00309 void Program::_checkCG( char *file, int line ){
00310 CGerror error;
00311 const char *str = cgGetLastErrorString( &error );
00312 if( error != CG_NO_ERROR ){
00313 if( m_contextCG ){
00314 cerr << cgGetLastListing( m_contextCG );
00315 }
00316 Error::error( Error::PROGRAM_VALIDATION_FAILED, file, line, string( str ) );
00317 }
00318 }
00319 #endif
00320
00326 string Program::readCode( string filename ){
00327
00328 string cppname = findFile( filename );
00329 if( cppname != "" ){
00330 FILE *fp = fopen( cppname.c_str(), "rb" );
00331 if( fp ){
00332
00333 fseek( fp, 0, SEEK_END );
00334 int len = ftell( fp );
00335 fseek( fp, 0, SEEK_SET );
00336
00337 char *code = (char *)calloc( len + 1, 1 );
00338 if( ! code ){
00339 Error::error( Error::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__ );
00340 }
00341 if( fread( code, 1, len, fp ) != len ){
00342 Error::error( Error::FILE_READ_FAILED, __FILE__, __LINE__ );
00343 }
00345 fflush( fp );
00346 fclose( fp );
00347
00348
00349 string retstr = string( code );
00350
00351 free( code );
00352
00353
00354 vector<string>includes;
00355
00356
00357 char *include = (char *)retstr.c_str();
00358 while( ( include = strstr( include, "#include" ) ) ){
00359 string incName;
00360
00361 while( *include != '\"' ){
00362 *include++ = ' ';
00363 }
00364
00365 *include++ = ' ';
00366
00367 while( *include != '\"' ){
00368 incName.push_back( *include );
00369 *include++ = ' ';
00370 }
00371
00372 while( *include != '\n' )*include++ = ' ';
00373
00374 includes.push_back( incName );
00375 }
00376
00377 for( int i = (int)includes.size() - 1; i >= 0; i-- ){
00378
00379 FILE *inc = fopen( findFile( includes[ i ] ).c_str(), "rb" );
00380 if( inc ){
00381
00382 fclose( inc );
00383 retstr = readCode( includes[ i ] ) + retstr;
00384 }
00385 else{
00386
00387 Error::error( Error::FILE_READ_FAILED, __FILE__, __LINE__, includes[ i ] );
00388 }
00389 }
00390
00391
00392 return( retstr );
00393 }
00394 }
00395
00396 return( filename );
00397 }
00398
00402 void Program::printShaderInfo( GLuint shader ){
00403 GLint param;
00404 glGetShaderiv( shader, GL_SHADER_TYPE, ¶m );
00405 if( param == GL_VERTEX_SHADER ){
00406 cout << "begin shader info (" << m_vertexShader << ":" << shader << "):\n" ;
00407 }
00408 else{
00409 cout << "begin shader info (" << m_fragmentShader << ":" << shader << "):\n" ;
00410 }
00411 cout << "GL_SHADER_TYPE: " << ( param == GL_VERTEX_SHADER ? "GL_VERTEX_SHADER" : "GL_FRAGMENT_SHADER" ) << endl;
00412 glGetShaderiv( shader, GL_DELETE_STATUS, ¶m );
00413 cout << "GL_DELETE_STATUS: " << ( param == GL_TRUE ? "GL_TRUE" : "GL_FALSE" ) << endl;
00414 glGetShaderiv( shader, GL_COMPILE_STATUS, ¶m );
00415 cout << "GL_COMPILE_STATUS: " << ( param == GL_TRUE ? "GL_TRUE" : "GL_FALSE" ) << endl;
00416 glGetShaderiv( shader, GL_INFO_LOG_LENGTH, ¶m );
00417 cout << "GL_INFO_LOG_LENGTH: " << param << endl;
00418 glGetShaderiv( shader, GL_SHADER_SOURCE_LENGTH, ¶m );
00419 cout << "GL_SHADER_SOURCE_LENGTH: " << param << endl;
00420 cout << "end shader info (" << shader << "):\n" ;
00421 }
00422
00426 void Program::printProgramInfo( GLuint program ){
00427 cout << "begin program info (" << program << "):\n" ;
00428 GLint param;
00429 glGetProgramiv( program, GL_DELETE_STATUS, ¶m );
00430 cout << "GL_DELETE_STATUS: " << ( param == GL_TRUE ? "GL_TRUE" : "GL_FALSE" ) << endl;
00431 glGetProgramiv( program, GL_LINK_STATUS, ¶m );
00432 cout << "GL_LINK_STATUS: " << ( param == GL_TRUE ? "GL_TRUE" : "GL_FALSE" ) << endl;
00433 glGetProgramiv( program, GL_VALIDATE_STATUS, ¶m );
00434 cout << "GL_VALIDATE_STATUS: " << ( param == GL_TRUE ? "GL_TRUE" : "GL_FALSE" ) << endl;
00435 glGetProgramiv( program, GL_INFO_LOG_LENGTH, ¶m );
00436 cout << "GL_INFO_LOG_LENGTH: " << param << endl;
00437 glGetProgramiv( program, GL_ATTACHED_SHADERS, ¶m );
00438 cout << "GL_ATTACHED_SHADERS: " << param << endl;
00439 glGetProgramiv( program, GL_ACTIVE_ATTRIBUTES, ¶m );
00440 cout << "GL_ACTIVE_ATTRIBUTES: " << param << endl;
00441 glGetProgramiv( program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, ¶m );
00442 cout << "GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: " << param << endl;
00443 glGetProgramiv( program, GL_ACTIVE_UNIFORMS, ¶m );
00444 cout << "GL_ACTIVE_UNIFORMS: " << param << endl;
00445 glGetProgramiv( program, GL_ACTIVE_UNIFORM_MAX_LENGTH, ¶m );
00446 cout << "GL_ACTIVE_UNIFORM_MAX_LENGTH: " << param << endl;
00447 cout << "end program info (" << program << "):\n" ;
00448 }
00449
00454 void Program::printInfoLog(){
00455 int len;
00456 char text[2048];
00457 glGetProgramInfoLog( m_programID, 2048, &len, text );
00458 if( len ){
00459 cout << "ProgramLog:\n***" << text << "***" << len << endl;
00460 }
00461 else{
00462 cout << "ProgramLog is empty\n";
00463 }
00464 glGetShaderInfoLog( m_vertexID, 2048, &len, text );
00465 if( len ){
00466 cout << "VertexShaderLog:\n***" << text << "***" << len << endl;
00467 }
00468 else{
00469 cout << "VertexShaderLog is empty\n";
00470 }
00471 glGetShaderInfoLog( m_fragmentID, 2048, &len, text );
00472 if( len ){
00473 cout << "FragmentShaderLog:\n***" << text << "***" << len << endl;
00474 }
00475 else{
00476 cout << "FragmentShaderLog is empty\n";
00477 }
00478 }
00479
00483 Program::~Program( void ){
00484 if( RenderTools::isGLInitialized() ){
00485 glDeleteShader( m_vertexID );
00486 glDeleteShader( m_fragmentID );
00487 glDeleteProgram( m_programID );
00488 }
00489 }
00490
00491 bool Program::bind( const string name, const string value ){
00492 PropertyPtr p = m_uniforms->findProperty( name );
00493 if( p ){
00494 p->setValue( value );
00495 return( bind( p ) );
00496 }
00497 else{
00498 Error::error( Error::ITEM_NOT_IN_GROUP, __FILE__, __LINE__ );
00499 return( false );
00500 }
00501 }
00502
00503 bool Program::bind( const PropertyPtr uniform ){
00504 GLint location = glGetUniformLocation( m_programID, uniform->getName().c_str() );
00505
00506 if( location != -1 ){
00507
00508 if( uniform->getTypeName() == "Sampler" ){
00509
00510 SamplerPtr sampler = * ( ( SamplerPtr * )( getPointer( 0 ) ) );
00511 sampler->onBind( m_unit );
00512 glUniform1i( location, m_unit );
00513
00514 m_unit++;
00515 }
00516 else if( uniform->isInteger() ){
00517 GLint * buffer = ( GLint * )malloc( uniform->getNumVectorElements() * sizeof( GLint ) );
00518 for( unsigned int i = 0; i < uniform->getNumVectorElements(); i++ ){
00519 GLint value;
00520 stringstream( uniform->getValue( i ) ) >> value;
00521 memcpy( buffer + i, & value, sizeof( GLint ) );
00522 }
00523 glUniform1iv( location, uniform->getNumVectorElements(), ( GLint * )buffer );
00524 }
00525 else if( uniform->isReal() ){
00526 GLfloat * buffer = ( GLfloat * )malloc( uniform->getNumVectorElements() * sizeof( GLfloat ) );
00527 for( unsigned int i = 0; i < uniform->getNumVectorElements(); i++ ){
00528 GLfloat value;
00529 stringstream( uniform->getValue( i ) ) >> value;
00530 memcpy( buffer + i, & value, sizeof( GLfloat ) );
00531 }
00532 glUniform1fv( location, uniform->getNumVectorElements(), ( GLfloat * )buffer );
00533 delete buffer;
00534 }
00535 else if( uniform->getTypeName() == "Vec2" ){
00536 GLfloat * buffer = ( GLfloat * )malloc( uniform->getNumVectorElements() * 2 * sizeof( GLfloat ) );
00537 for( unsigned int i = 0; i < uniform->getNumVectorElements(); i++ ){
00538 Vec2 value;
00539 stringstream( uniform->getValue( i ) ) >> value;
00540 memcpy( buffer + i, * value, 2 * sizeof( GLfloat ) );
00541 }
00542 glUniform2fv( location, uniform->getNumVectorElements(), buffer );
00543 delete buffer;
00544 }
00545 else if( uniform->getTypeName() == "Vec3" ){
00546 GLfloat * buffer = ( GLfloat * )malloc( uniform->getNumVectorElements() * 3 * sizeof( GLfloat ) );
00547 for( unsigned int i = 0; i < uniform->getNumVectorElements(); i++ ){
00548 Vec3 value;
00549 stringstream( uniform->getValue( i ) ) >> value;
00550 memcpy( buffer + i, * value, 3 * sizeof( GLfloat ) );
00551 }
00552 glUniform3fv( location, uniform->getNumVectorElements(), buffer );
00553 delete buffer;
00554 }
00555 else if( uniform->getTypeName() == "Vec4" || uniform->getTypeName() == "Quat" ){
00556 GLfloat * buffer = ( GLfloat * )malloc( uniform->getNumVectorElements() * 4 * sizeof( GLfloat ) );
00557 for( unsigned int i = 0; i < uniform->getNumVectorElements(); i++ ){
00558 Vec4 value;
00559 stringstream( uniform->getValue( i ) ) >> value;
00560 memcpy( buffer + i, * value, 4 * sizeof( GLfloat ) );
00561 }
00562 glUniform4fv( location, uniform->getNumVectorElements(), buffer );
00563 delete buffer;
00564 }
00565 else if( uniform->getTypeName() == "Mat3" ){
00566 GLfloat * buffer = ( GLfloat * )malloc( uniform->getNumVectorElements() * 9 * sizeof( GLfloat ) );
00567 for( unsigned int i = 0; i < uniform->getNumVectorElements(); i++ ){
00568 Mat3 value;
00569 stringstream( uniform->getValue( i ) ) >> value;
00570 memcpy( buffer + i, * value, 9 * sizeof( GLfloat ) );
00571 }
00572 glUniformMatrix3fv( location, uniform->getNumVectorElements(), GL_FALSE, buffer );
00573 delete buffer;
00574 }
00575 else if( uniform->getTypeName() == "Mat4" ){
00576 GLfloat * buffer = ( GLfloat * )malloc( uniform->getNumVectorElements() * 16 * sizeof( GLfloat ) );
00577 for( unsigned int i = 0; i < uniform->getNumVectorElements(); i++ ){
00578 Mat4 value;
00579 stringstream( uniform->getValue( i ) ) >> value;
00580 memcpy( buffer + i, * value, 16 * sizeof( GLfloat ) );
00581 }
00582 glUniformMatrix4fv( location, uniform->getNumVectorElements(), GL_FALSE, buffer );
00583 delete buffer;
00584 }
00585 else{
00586 Error::warning( Error::WRONG_TYPE, __FILE__, __LINE__, "uniform type not recognized");
00587 return( false );
00588 }
00589 Error::assertNoErrors( __FILE__, __LINE__ );
00590 return( true );
00591 }
00592 else{
00593 Error::warning( Error::UNIFORM_NOT_IN_PROGRAM, __FILE__, __LINE__, uniform->getName().c_str() );
00594 return( false );
00595 }
00596 }
00597
00598
00609 unsigned int Program::bind( void ){
00610 s_current = getSharedPtrProgram();
00611
00612 GLint status;
00613
00614 #ifdef DEBUG
00615 glValidateProgram( m_programID );
00616 glGetProgramiv( m_programID, GL_VALIDATE_STATUS, & status );
00617 if( status == GL_FALSE ){
00618 printProgramInfo( m_programID );
00619 printShaderInfo( m_fragmentID );
00620 printShaderInfo( m_vertexID );
00621 printInfoLog();
00622 Error::error( Error::PROGRAM_VALIDATION_FAILED, __FILE__, __LINE__ );
00623 }
00624 #endif
00625 if( glIsProgram( m_programID ) ){
00626 if( glGetInteger( GL_CURRENT_PROGRAM ) != m_programID ){
00627 glUseProgram( m_programID );
00628 }
00629 }
00630 else{
00631 glGetProgramiv( m_programID, GL_DELETE_STATUS, & status );
00632 printf( "GL_DELETE_STATUS: %d\n", status );
00633 glGetProgramiv( m_programID, GL_LINK_STATUS, & status );
00634 printf( "GL_LINK_STATUS: %d\n", status );
00635 glGetProgramiv( m_programID, GL_VALIDATE_STATUS, & status );
00636 printf( "GL_VALIDATE_STATUS: %d\n", status );
00637 glGetProgramiv( m_programID, GL_INFO_LOG_LENGTH, & status );
00638 printf( "GL_INFO_LOG_LENGTH: %d\n", status );
00639 glGetProgramiv( m_programID, GL_ATTACHED_SHADERS, & status );
00640 printf( "GL_ATTACHED_SHADERS: %d\n", status );
00641 glGetProgramiv( m_programID, GL_ACTIVE_ATTRIBUTES, & status );
00642 printf( "GL_ACTIVE_ATTRIBUTES: %d\n", status );
00643 glGetProgramiv( m_programID, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, & status );
00644 printf( "GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: %d\n", status );
00645 glGetProgramiv( m_programID, GL_ACTIVE_UNIFORMS, & status );
00646 printf( "GL_ACTIVE_UNIFORMS: %d\n", status );
00647 glGetProgramiv( m_programID, GL_ACTIVE_UNIFORM_MAX_LENGTH, & status );
00648 printf( "GL_ACTIVE_UNIFORM_MAX_LENGTH: %d\n", status );
00649 Error::error( Error::PROGRAM_DOES_NOT_EXIST, __FILE__, __LINE__ );
00650 return( 0 );
00651 }
00652
00653 unsigned int i = 0, unit = 0;
00654 for( ; i < m_uniforms->size(); i++ ){
00655 bind( m_uniforms->getProperty( i ) );
00656 }
00657 Error::assertNoErrors( __FILE__, __LINE__ );
00658 return( 0 );
00659 }
00660
00661 void Program::unbind( void ){
00662 glUseProgram(0);
00663 s_current = ProgramPtr();
00664 }
00665
00666 ProgramPtr Program::getSharedPtrProgram( void ){
00667 return( dynamic_pointer_cast< Program, AbstractProperty >( getSharedPtr< AbstractProperty >() ) );
00668 }
00669
00670 const ProgramPtr Program::getSharedPtrProgram( void ) const {
00671 return( dynamic_pointer_cast< Program, AbstractProperty >( getSharedPtr< AbstractProperty >() ) );
00672 }
00673
00674 };
00675
00676 #else
00677 int andABogusSymbolToKeepTheCompilerHappy = 0;
00678 #endif
00679