00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef HAVE_CONFIG_H
00022 # include <simgear_config.h>
00023 #endif
00024
00025 #include <simgear/debug/logstream.hxx>
00026 #include "shader.h"
00027 #include <stdio.h>
00028 #include <stdarg.h>
00029
00030 #include <cstdlib>
00031 #include <cstring>
00032
00033 glVertexAttrib1dProc glVertexAttrib1dPtr = NULL;
00034 glVertexAttrib1dvProc glVertexAttrib1dvPtr = NULL;
00035 glVertexAttrib1fProc glVertexAttrib1fPtr = NULL;
00036 glVertexAttrib1fvProc glVertexAttrib1fvPtr = NULL;
00037 glVertexAttrib1sProc glVertexAttrib1sPtr = NULL;
00038 glVertexAttrib1svProc glVertexAttrib1svPtr = NULL;
00039 glVertexAttrib2dProc glVertexAttrib2dPtr = NULL;
00040 glVertexAttrib2dvProc glVertexAttrib2dvPtr = NULL;
00041 glVertexAttrib2fProc glVertexAttrib2fPtr = NULL;
00042 glVertexAttrib2fvProc glVertexAttrib2fvPtr = NULL;
00043 glVertexAttrib2sProc glVertexAttrib2sPtr = NULL;
00044 glVertexAttrib2svProc glVertexAttrib2svPtr = NULL;
00045 glVertexAttrib3dProc glVertexAttrib3dPtr = NULL;
00046 glVertexAttrib3dvProc glVertexAttrib3dvPtr = NULL;
00047 glVertexAttrib3fProc glVertexAttrib3fPtr = NULL;
00048 glVertexAttrib3fvProc glVertexAttrib3fvPtr = NULL;
00049 glVertexAttrib3sProc glVertexAttrib3sPtr = NULL;
00050 glVertexAttrib3svProc glVertexAttrib3svPtr = NULL;
00051 glVertexAttrib4NbvProc glVertexAttrib4NbvPtr = NULL;
00052 glVertexAttrib4NivProc glVertexAttrib4NivPtr = NULL;
00053 glVertexAttrib4NsvProc glVertexAttrib4NsvPtr = NULL;
00054 glVertexAttrib4NubProc glVertexAttrib4NubPtr = NULL;
00055 glVertexAttrib4NubvProc glVertexAttrib4NubvPtr = NULL;
00056 glVertexAttrib4NuivProc glVertexAttrib4NuivPtr = NULL;
00057 glVertexAttrib4NusvProc glVertexAttrib4NusvPtr = NULL;
00058 glVertexAttrib4bvProc glVertexAttrib4bvPtr = NULL;
00059 glVertexAttrib4dProc glVertexAttrib4dPtr = NULL;
00060 glVertexAttrib4dvProc glVertexAttrib4dvPtr = NULL;
00061 glVertexAttrib4fProc glVertexAttrib4fPtr = NULL;
00062 glVertexAttrib4fvProc glVertexAttrib4fvPtr = NULL;
00063 glVertexAttrib4ivProc glVertexAttrib4ivPtr = NULL;
00064 glVertexAttrib4sProc glVertexAttrib4sPtr = NULL;
00065 glVertexAttrib4svProc glVertexAttrib4svPtr = NULL;
00066 glVertexAttrib4ubvProc glVertexAttrib4ubvPtr = NULL;
00067 glVertexAttrib4uivProc glVertexAttrib4uivPtr = NULL;
00068 glVertexAttrib4usvProc glVertexAttrib4usvPtr = NULL;
00069 glVertexAttribPointerProc glVertexAttribPointerPtr = NULL;
00070 glEnableVertexAttribArrayProc glEnableVertexAttribArrayPtr = NULL;
00071 glDisableVertexAttribArrayProc glDisableVertexAttribArrayPtr = NULL;
00072 glProgramStringProc glProgramStringPtr = NULL;
00073 glBindProgramProc glBindProgramPtr = NULL;
00074 glDeleteProgramsProc glDeleteProgramsPtr = NULL;
00075 glGenProgramsProc glGenProgramsPtr = NULL;
00076 glProgramEnvParameter4dProc glProgramEnvParameter4dPtr = NULL;
00077 glProgramEnvParameter4dvProc glProgramEnvParameter4dvPtr = NULL;
00078 glProgramEnvParameter4fProc glProgramEnvParameter4fPtr = NULL;
00079 glProgramEnvParameter4fvProc glProgramEnvParameter4fvPtr = NULL;
00080 glProgramLocalParameter4dProc glProgramLocalParameter4dPtr = NULL;
00081 glProgramLocalParameter4dvProc glProgramLocalParameter4dvPtr = NULL;
00082 glProgramLocalParameter4fProc glProgramLocalParameter4fPtr = NULL;
00083 glProgramLocalParameter4fvProc glProgramLocalParameter4fvPtr = NULL;
00084 glGetProgramEnvParameterdvProc glGetProgramEnvParameterdvPtr = NULL;
00085 glGetProgramEnvParameterfvProc glGetProgramEnvParameterfvPtr = NULL;
00086 glGetProgramLocalParameterdvProc glGetProgramLocalParameterdvPtr = NULL;
00087 glGetProgramLocalParameterfvProc glGetProgramLocalParameterfvPtr = NULL;
00088 glGetProgramivProc glGetProgramivPtr = NULL;
00089 glGetProgramStringProc glGetProgramStringPtr = NULL;
00090 glGetVertexAttribdvProc glGetVertexAttribdvPtr = NULL;
00091 glGetVertexAttribfvProc glGetVertexAttribfvPtr = NULL;
00092 glGetVertexAttribivProc glGetVertexAttribivPtr = NULL;
00093 glGetVertexAttribPointervProc glGetVertexAttribPointervPtr = NULL;
00094 glIsProgramProc glIsProgramPtr = NULL;
00095
00096 glDeleteObjectProc glDeleteObjectPtr = NULL;
00097 glGetHandleProc glGetHandlePtr = NULL;
00098 glDetachObjectProc glDetachObjectPtr = NULL;
00099 glCreateShaderObjectProc glCreateShaderObjectPtr = NULL;
00100 glShaderSourceProc glShaderSourcePtr = NULL;
00101 glCompileShaderProc glCompileShaderPtr = NULL;
00102 glCreateProgramObjectProc glCreateProgramObjectPtr = NULL;
00103 glAttachObjectProc glAttachObjectPtr = NULL;
00104 glLinkProgramProc glLinkProgramPtr = NULL;
00105 glUseProgramObjectProc glUseProgramObjectPtr = NULL;
00106 glValidateProgramProc glValidateProgramPtr = NULL;
00107 glUniform1fProc glUniform1fPtr = NULL;
00108 glUniform2fProc glUniform2fPtr = NULL;
00109 glUniform3fProc glUniform3fPtr = NULL;
00110 glUniform4fProc glUniform4fPtr = NULL;
00111 glUniform1iProc glUniform1iPtr = NULL;
00112 glUniform2iProc glUniform2iPtr = NULL;
00113 glUniform3iProc glUniform3iPtr = NULL;
00114 glUniform4iProc glUniform4iPtr = NULL;
00115 glUniform1fvProc glUniform1fvPtr = NULL;
00116 glUniform2fvProc glUniform2fvPtr = NULL;
00117 glUniform3fvProc glUniform3fvPtr = NULL;
00118 glUniform4fvProc glUniform4fvPtr = NULL;
00119 glUniform1ivProc glUniform1ivPtr = NULL;
00120 glUniform2ivProc glUniform2ivPtr = NULL;
00121 glUniform3ivProc glUniform3ivPtr = NULL;
00122 glUniform4ivProc glUniform4ivPtr = NULL;
00123 glUniformMatrix2fvProc glUniformMatrix2fvPtr = NULL;
00124 glUniformMatrix3fvProc glUniformMatrix3fvPtr = NULL;
00125 glUniformMatrix4fvProc glUniformMatrix4fvPtr = NULL;
00126 glGetObjectParameterfvProc glGetObjectParameterfvPtr = NULL;
00127 glGetObjectParameterivProc glGetObjectParameterivPtr = NULL;
00128 glGetInfoLogProc glGetInfoLogPtr = NULL;
00129 glGetAttachedObjectsProc glGetAttachedObjectsPtr = NULL;
00130 glGetUniformLocationProc glGetUniformLocationPtr = NULL;
00131 glGetActiveUniformProc glGetActiveUniformPtr = NULL;
00132 glGetUniformfvProc glGetUniformfvPtr = NULL;
00133 glGetUniformivProc glGetUniformivPtr = NULL;
00134 glGetShaderSourceProc glGetShaderSourcePtr = NULL;
00135
00136 glBindAttribLocationProc glBindAttribLocationPtr = NULL;
00137 glGetActiveAttribProc glGetActiveAttribPtr = NULL;
00138 glGetAttribLocationProc glGetAttribLocationPtr = NULL;
00139
00140 glBindProgramNVProc glBindProgramNVPtr = NULL;
00141 glDeleteProgramsNVProc glDeleteProgramsNVPtr = NULL;
00142 glGenProgramsNVProc glGenProgramsNVPtr = NULL;
00143 glLoadProgramNVProc glLoadProgramNVPtr = NULL;
00144 glProgramParameter4fvNVProc glProgramParameter4fvNVPtr = NULL;
00145
00146 bool Shader::VP_supported = false;
00147 bool Shader::FP_supported = false;
00148 bool Shader::GLSL_supported = false;
00149 bool Shader::NVFP_supported = false;
00150 GLint Shader::nb_texture_unit = 0;
00151
00152 Shader::Shader(const char *name,const char *vertex,const char *fragment) {
00153
00154 program = 0;
00155 vertex_target = 0;
00156 vertex_id = 0;
00157 fragment_target = 0;
00158 fragment_id = 0;
00159
00160 char *data;
00161 FILE *file = fopen(name,"rb");
00162 if(!file) {
00163 SG_LOG(SG_GL, SG_ALERT, "Shader::Shader(): can't open '" << name << "' file\n");
00164 return;
00165 }
00166
00167 fseek(file,0,SEEK_END);
00168 int size = ftell(file);
00169 data = new char[size + 1];
00170 data[size] = '\0';
00171 fseek(file,0,SEEK_SET);
00172 fread(data,1,size,file);
00173 fclose(file);
00174
00175
00176 char *s = data;
00177 char *d = data;
00178 while(*s) {
00179 if(*s == '/' && *(s + 1) == '/') {
00180 while(*s && *s != '\n') s++;
00181 while(*s && *s == '\n') s++;
00182 *d++ = '\n';
00183 }
00184 else if(*s == '/' && *(s + 1) == '*') {
00185 while(*s && (*s != '*' || *(s + 1) != '/')) s++;
00186 s += 2;
00187 while(*s && *s == '\n') s++;
00188 *d++ = '\n';
00189 }
00190 else *d++ = *s++;
00191 }
00192 *d = '\0';
00193
00194
00195 char *vertex_src = NULL;
00196 char *fragment_src = NULL;
00197 s = data;
00198 while(*s) {
00199 if(*s == '<') {
00200 char *name = s;
00201 while(*s) {
00202 if(std::strchr("> \t\n\r",*s)) break;
00203 s++;
00204 }
00205 if(*s == '>') {
00206 *name++ = '\0';
00207 *s++ = '\0';
00208 while(*s && std::strchr(" \t\n\r",*s)) s++;
00209 if(vertex == NULL && !std::strcmp(name,"vertex")) vertex_src = s;
00210 if(vertex && !std::strcmp(name,vertex)) vertex_src = s;
00211 if(fragment == NULL && !std::strcmp(name,"fragment")) fragment_src = s;
00212 if(fragment && !std::strcmp(name,fragment)) fragment_src = s;
00213 }
00214 }
00215 s++;
00216 }
00217
00218 if(vertex_src) {
00219
00220
00221 if(VP_supported && !std::strncmp(vertex_src,"!!ARBvp1.0",10)) {
00222 vertex_target = GL_VERTEX_PROGRAM_ARB;
00223 glGenProgramsPtr(1,&vertex_id);
00224 glBindProgramPtr(GL_VERTEX_PROGRAM_ARB,vertex_id);
00225 glProgramStringPtr(GL_VERTEX_PROGRAM_ARB,GL_PROGRAM_FORMAT_ASCII_ARB,(GLsizei)std::strlen(vertex_src),vertex_src);
00226 GLint pos = -1;
00227 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB,&pos);
00228 if(pos != -1) {
00229 SG_LOG(SG_GL, SG_ALERT, "Shader::Shader(): vertex program error in " << name << " file\n" << get_error(vertex_src,pos));
00230 return;
00231 }
00232 char *var = std::strstr(vertex_src, "#var ");
00233 while( var ) {
00234 char *eol = std::strchr( var + 1, '#');
00235 char *c2, *c3, *c4;
00236 c2 = strchr( var + 6, ' ');
00237 if( c2 ) {
00238 c3 = strchr( c2 + 1, ':');
00239 if( c3 ) {
00240 c4 = strchr( c3 + 1, ':');
00241 if( c4 )
00242 c4 = strchr( c4 + 1, '[');
00243 if( c4 && c4 < eol) {
00244 char type[10], name[30];
00245 std::strncpy( type, var + 5, c2-var-5 );
00246 type[c2-var-5] = 0;
00247 std::strncpy( name, c2 + 1, c3-c2-2 );
00248 name[c3-c2-2] = 0;
00249 struct Parameter p;
00250 p.location = atoi( c4 + 1);
00251 p.length = 4;
00252 if( ! std::strcmp(type, "float3") )
00253 p.length = 3;
00254 else if( ! strcmp(type, "float") )
00255 p.length = 1;
00256 arb_parameters[ name ] = p;
00257 }
00258 }
00259 }
00260 var = strstr(var + 1, "#var ");
00261 }
00262 }
00263
00264 else {
00265
00266 program = glCreateProgramObjectPtr();
00267
00268 GLint length = (GLint)std::strlen(vertex_src);
00269 GLhandleARB vertex = glCreateShaderObjectPtr(GL_VERTEX_SHADER_ARB);
00270 glShaderSourcePtr(vertex,1,(const GLcharARB**)&vertex_src,&length);
00271 glCompileShaderPtr(vertex);
00272 glAttachObjectPtr(program,vertex);
00273 glDeleteObjectPtr(vertex);
00274
00275 glBindAttribLocationPtr(program,0,"s_attribute_0");
00276 glBindAttribLocationPtr(program,1,"s_attribute_1");
00277 glBindAttribLocationPtr(program,2,"s_attribute_2");
00278 glBindAttribLocationPtr(program,3,"s_attribute_3");
00279 glBindAttribLocationPtr(program,4,"s_attribute_4");
00280 glBindAttribLocationPtr(program,5,"s_attribute_5");
00281 glBindAttribLocationPtr(program,6,"s_attribute_6");
00282
00283 glBindAttribLocationPtr(program,0,"s_xyz");
00284 glBindAttribLocationPtr(program,1,"s_normal");
00285 glBindAttribLocationPtr(program,2,"s_tangent");
00286 glBindAttribLocationPtr(program,3,"s_binormal");
00287 glBindAttribLocationPtr(program,4,"s_texcoord");
00288 }
00289 }
00290
00291 if(fragment_src) {
00292
00293
00294 if(FP_supported && !std::strncmp(fragment_src,"!!ARBfp1.0",10)) {
00295 fragment_target = GL_FRAGMENT_PROGRAM_ARB;
00296 glGenProgramsPtr(1,&fragment_id);
00297 glBindProgramPtr(GL_FRAGMENT_PROGRAM_ARB,fragment_id);
00298 glProgramStringPtr(GL_FRAGMENT_PROGRAM_ARB,GL_PROGRAM_FORMAT_ASCII_ARB,(GLsizei)std::strlen(fragment_src),fragment_src);
00299 GLint pos = -1;
00300 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB,&pos);
00301 if(pos != -1) {
00302 SG_LOG(SG_GL, SG_ALERT, "Shader::Shader(): fragment program error in " << name << " file\n" << get_error(fragment_src,pos));
00303 return;
00304 }
00305 }
00306
00307
00308 else if(!strncmp(fragment_src,"!!FP1.0",7)) {
00309 fragment_target = GL_FRAGMENT_PROGRAM_NV;
00310 glGenProgramsNVPtr(1,&fragment_id);
00311 glBindProgramNVPtr(GL_FRAGMENT_PROGRAM_NV,fragment_id);
00312 glLoadProgramNVPtr(GL_FRAGMENT_PROGRAM_NV,fragment_id,(GLsizei)std::strlen(fragment_src),(GLubyte*)fragment_src);
00313 GLint pos = -1;
00314 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_NV,&pos);
00315 if(pos != -1) {
00316 SG_LOG(SG_GL, SG_ALERT, "Shader::Shader(): fragment program error in " << name << " file\n" << get_error(fragment_src,pos));
00317 return;
00318 }
00319 }
00320
00321
00322 else {
00323
00324 if(!program) program = glCreateProgramObjectPtr();
00325
00326 GLint length = (GLint)std::strlen(fragment_src);
00327 GLhandleARB fragment = glCreateShaderObjectPtr(GL_FRAGMENT_SHADER_ARB);
00328 glShaderSourcePtr(fragment,1,(const GLcharARB**)&fragment_src,&length);
00329 glCompileShaderPtr(fragment);
00330 glAttachObjectPtr(program,fragment);
00331 glDeleteObjectPtr(fragment);
00332 }
00333 }
00334
00335 if(program) {
00336
00337 glLinkProgramPtr(program);
00338 GLint linked;
00339 glGetObjectParameterivPtr(program,GL_OBJECT_LINK_STATUS_ARB,&linked);
00340 if(!linked) {
00341 SG_LOG(SG_GL, SG_ALERT, "Shader::Shader(): GLSL error in " << name << " file\n" << get_glsl_error());
00342 return;
00343 }
00344
00345 glUseProgramObjectPtr(program);
00346
00347 for(int i = 0; i < 8; i++) {
00348 char texture[32];
00349 sprintf(texture,"s_texture_%d",i);
00350 GLint location = glGetUniformLocationPtr(program,texture);
00351 if(location >= 0) glUniform1iPtr(location,i);
00352 }
00353
00354 glUseProgramObjectPtr(0);
00355
00356 glValidateProgramPtr(program);
00357 GLint validated;
00358 glGetObjectParameterivPtr(program,GL_OBJECT_VALIDATE_STATUS_ARB,&validated);
00359 if(!validated) {
00360 SG_LOG(SG_GL, SG_ALERT, "Shader::Shader(): GLSL error in " << name << " file\n" << get_glsl_error());
00361 return;
00362 }
00363 }
00364
00365 delete [] data;
00366 }
00367
00368 Shader::~Shader() {
00369 if(program) glDeleteObjectPtr(program);
00370 if(vertex_target == GL_VERTEX_PROGRAM_ARB) glDeleteProgramsPtr(1,&vertex_id);
00371 if(fragment_target == GL_FRAGMENT_PROGRAM_ARB) glDeleteProgramsPtr(1,&fragment_id);
00372 else if(fragment_target == GL_FRAGMENT_PROGRAM_NV) glDeleteProgramsNVPtr(1,&fragment_id);
00373 parameters.clear();
00374 }
00375
00376
00377
00378 const char *Shader::get_error(char *data,int pos) {
00379 char *s = data;
00380 while(*s && pos--) s++;
00381 while(s >= data && *s != '\n') s--;
00382 char *e = ++s;
00383 while(*e != '\0' && *e != '\n') e++;
00384 *e = '\0';
00385 return s;
00386 }
00387
00388
00389
00390
00391 const char *Shader::get_glsl_error() {
00392 GLint length;
00393 static char error[4096];
00394 glGetInfoLogPtr(program,sizeof(error),&length,error);
00395 return error;
00396 }
00397
00398
00399
00400 void Shader::getParameter(const char *name,Parameter *parameter) {
00401 if( program ) {
00402 char buf[1024];
00403 std::strcpy(buf,name);
00404 char *s = std::strchr(buf,':');
00405 if(s) {
00406 *s++ = '\0';
00407 parameter->length = std::atoi(s);
00408 } else {
00409 parameter->length = 4;
00410 }
00411 parameter->location = glGetUniformLocationPtr(program,buf);
00412 } else if( vertex_id ) {
00413 arb_parameter_list::iterator iParam = arb_parameters.find(name);
00414 if( iParam != arb_parameters.end() )
00415 parameter->location = iParam->second.location;
00416 else
00417 parameter->location = 90;
00418 parameter->length = 4;
00419 }
00420 }
00421
00422
00423
00424 void Shader::bindNames(const char *name,...) {
00425 Parameter parameter;
00426 getParameter(name,¶meter);
00427 parameters.push_back(parameter);
00428 va_list args;
00429 va_start(args,name);
00430 while(1) {
00431 const char *name = va_arg(args,const char*);
00432 if(name == NULL) break;
00433 getParameter(name,¶meter);
00434 parameters.push_back(parameter);
00435 }
00436 va_end(args);
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 void Shader::enable() {
00448 if(vertex_id) glEnable(vertex_target);
00449 if(fragment_id) glEnable(fragment_target);
00450 }
00451
00452
00453
00454 void Shader::disable() {
00455 if(program) glUseProgramObjectPtr(0);
00456 if(vertex_id) glDisable(vertex_target);
00457 if(fragment_id) glDisable(fragment_target);
00458 }
00459
00460
00461
00462 void Shader::bind() {
00463 if(program) glUseProgramObjectPtr(program);
00464 if(vertex_id) {
00465 if(vertex_target == GL_VERTEX_PROGRAM_ARB) glBindProgramPtr(vertex_target,vertex_id);
00466 }
00467 if(fragment_id) {
00468 if(fragment_target == GL_FRAGMENT_PROGRAM_ARB) glBindProgramPtr(fragment_target,fragment_id);
00469 else if(fragment_target == GL_FRAGMENT_PROGRAM_NV) glBindProgramNVPtr(fragment_target,fragment_id);
00470 }
00471 }
00472
00473
00474
00475 void Shader::bind(const float *v,...) {
00476 if(fragment_id) {
00477 if(fragment_target == GL_FRAGMENT_PROGRAM_ARB) glBindProgramPtr(fragment_target,fragment_id);
00478 else if(fragment_target == GL_FRAGMENT_PROGRAM_NV) glBindProgramNVPtr(fragment_target,fragment_id);
00479 } else {
00480 if(program == 0) {
00481 SG_LOG(SG_GL, SG_ALERT, "Shader::bind(): error GLSL shader isn't loaded\n");
00482 return;
00483 }
00484 glUseProgramObjectPtr(program);
00485 }
00486 const float *value = v;
00487 va_list args;
00488 va_start(args,v);
00489 for(int i = 0; i < (int)parameters.size(); i++) {
00490 if( vertex_target ) {
00491 glProgramLocalParameter4fvPtr( vertex_target, parameters[i].location, value);
00492 } else if( program ) {
00493 if(parameters[i].length == 1) glUniform1fvPtr(parameters[i].location,1,value);
00494 else if(parameters[i].length == 2) glUniform2fvPtr(parameters[i].location,1,value);
00495 else if(parameters[i].length == 3) glUniform3fvPtr(parameters[i].location,1,value);
00496 else if(parameters[i].length == 4) glUniform4fvPtr(parameters[i].location,1,value);
00497 else if(parameters[i].length == 9) glUniformMatrix3fvPtr(parameters[i].location,1,false,value);
00498 else if(parameters[i].length == 16) glUniformMatrix4fvPtr(parameters[i].location,1,false,value);
00499 }
00500 value = va_arg(args,const float*);
00501 if(!value) break;
00502 }
00503 va_end(args);
00504 }
00505
00506
00507
00508
00509
00510
00511
00512 void Shader::setLocalParameter(int location,const float *value) {
00513 if(vertex_target == 0) {
00514 SG_LOG(SG_GL, SG_ALERT, "Shader::setLocalParameter(): error vertex program isn't loaded\n");
00515 return;
00516 }
00517 glProgramLocalParameter4fvPtr(vertex_target,location,value);
00518 }
00519
00520 void Shader::setEnvParameter(int location,const float *value) {
00521 if(vertex_target == 0) {
00522 SG_LOG(SG_GL, SG_ALERT, "Shader::setEnvParameter(): error vertex program isn't loaded\n");
00523 return;
00524 }
00525 glProgramEnvParameter4fvPtr(vertex_target,location,value);
00526 }
00527
00528
00529
00530 void Shader::setParameter(const char *name,const float *value) {
00531 Parameter parameter;
00532 getParameter(name,¶meter);
00533 if( vertex_target ) {
00534 glProgramLocalParameter4fvPtr( vertex_target, parameter.location, value);
00535 return;
00536 }
00537 if(program == 0) {
00538 SG_LOG(SG_GL, SG_ALERT, "Shader::setLocalParameter(): error GLSL shader isn't loaded\n");
00539 return;
00540 }
00541 if(parameter.length == 1) glUniform1fvPtr(parameter.location,1,value);
00542 else if(parameter.length == 2) glUniform2fvPtr(parameter.location,1,value);
00543 else if(parameter.length == 3) glUniform3fvPtr(parameter.location,1,value);
00544 else if(parameter.length == 4) glUniform4fvPtr(parameter.location,1,value);
00545 else if(parameter.length == 9) glUniformMatrix3fvPtr(parameter.location,1,false,value);
00546 else if(parameter.length == 16) glUniformMatrix4fvPtr(parameter.location,1,false,value);
00547 }
00548
00549
00550
00551 void Shader::setParameters(const float *v,...) {
00552 const float *value = v;
00553 va_list args;
00554 va_start(args,v);
00555 for(int i = 0; i < (int)parameters.size(); i++) {
00556 if( vertex_target ) {
00557 glProgramLocalParameter4fvPtr( vertex_target, parameters[i].location, value);
00558 } else if( program ) {
00559 if(parameters[i].length == 1) glUniform1fvPtr(parameters[i].location,1,value);
00560 else if(parameters[i].length == 2) glUniform2fvPtr(parameters[i].location,1,value);
00561 else if(parameters[i].length == 3) glUniform3fvPtr(parameters[i].location,1,value);
00562 else if(parameters[i].length == 4) glUniform4fvPtr(parameters[i].location,1,value);
00563 else if(parameters[i].length == 9) glUniformMatrix3fvPtr(parameters[i].location,1,false,value);
00564 else if(parameters[i].length == 16) glUniformMatrix4fvPtr(parameters[i].location,1,false,value);
00565 }
00566 value = va_arg(args,const float*);
00567 if(!value) break;
00568 }
00569 va_end(args);
00570 }
00571
00572 #ifndef CONCAT
00573 #define CONCAT(a,b) a##b
00574 #endif
00575 #define mystringify(a) CONCAT(ST,R)(a)
00576 #define STR(x) #x
00577 #define LOAD_EXT(fn) CONCAT(fn,Ptr) = (CONCAT(fn,Proc)) SGLookupFunction( mystringify(CONCAT(fn,ARB)) )
00578
00579 void Shader::Init(void) {
00580 if( SGIsOpenGLExtensionSupported("GL_ARB_multitexture") )
00581 glGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB, &nb_texture_unit );
00582 VP_supported = SGIsOpenGLExtensionSupported("GL_ARB_vertex_program");
00583 FP_supported = SGIsOpenGLExtensionSupported("GL_ARB_fragment_program");
00584
00585 GLSL_supported = SGIsOpenGLExtensionSupported("GL_ARB_shading_language_100") &&
00586 SGIsOpenGLExtensionSupported("GL_ARB_fragment_shader") &&
00587 SGIsOpenGLExtensionSupported("GL_ARB_vertex_shader") &&
00588 SGIsOpenGLExtensionSupported("GL_ARB_shader_objects");
00589 NVFP_supported = SGIsOpenGLExtensionSupported("GL_NV_fragment_program");
00590
00591 if( VP_supported || FP_supported ) {
00592
00593 LOAD_EXT(glVertexAttrib1d);
00594 LOAD_EXT( glVertexAttrib1dv );
00595 LOAD_EXT( glVertexAttrib1f );
00596 LOAD_EXT( glVertexAttrib1fv );
00597 LOAD_EXT( glVertexAttrib1s );
00598 LOAD_EXT( glVertexAttrib1sv );
00599 LOAD_EXT( glVertexAttrib2d );
00600 LOAD_EXT( glVertexAttrib2dv );
00601 LOAD_EXT( glVertexAttrib2f );
00602 LOAD_EXT( glVertexAttrib2fv );
00603 LOAD_EXT( glVertexAttrib2s );
00604 LOAD_EXT( glVertexAttrib2sv );
00605 LOAD_EXT( glVertexAttrib3d );
00606 LOAD_EXT( glVertexAttrib3dv );
00607 LOAD_EXT( glVertexAttrib3f );
00608 LOAD_EXT( glVertexAttrib3fv );
00609 LOAD_EXT( glVertexAttrib3s );
00610 LOAD_EXT( glVertexAttrib3sv );
00611 LOAD_EXT( glVertexAttrib4Nbv );
00612 LOAD_EXT( glVertexAttrib4Niv );
00613 LOAD_EXT( glVertexAttrib4Nsv );
00614 LOAD_EXT( glVertexAttrib4Nub );
00615 LOAD_EXT( glVertexAttrib4Nubv );
00616 LOAD_EXT( glVertexAttrib4Nuiv );
00617 LOAD_EXT( glVertexAttrib4Nusv );
00618 LOAD_EXT( glVertexAttrib4bv );
00619 LOAD_EXT( glVertexAttrib4d );
00620 LOAD_EXT( glVertexAttrib4dv );
00621 LOAD_EXT( glVertexAttrib4f );
00622 LOAD_EXT( glVertexAttrib4fv );
00623 LOAD_EXT( glVertexAttrib4iv );
00624 LOAD_EXT( glVertexAttrib4s );
00625 LOAD_EXT( glVertexAttrib4sv );
00626 LOAD_EXT( glVertexAttrib4ubv );
00627 LOAD_EXT( glVertexAttrib4uiv );
00628 LOAD_EXT( glVertexAttrib4usv );
00629 LOAD_EXT( glVertexAttribPointer );
00630 LOAD_EXT( glEnableVertexAttribArray );
00631 LOAD_EXT( glDisableVertexAttribArray );
00632 LOAD_EXT( glProgramString );
00633 LOAD_EXT( glBindProgram );
00634 LOAD_EXT( glDeletePrograms );
00635 LOAD_EXT( glGenPrograms );
00636 LOAD_EXT( glProgramEnvParameter4d );
00637 LOAD_EXT( glProgramEnvParameter4dv );
00638 LOAD_EXT( glProgramEnvParameter4f );
00639 LOAD_EXT( glProgramEnvParameter4fv );
00640 LOAD_EXT( glProgramLocalParameter4d );
00641 LOAD_EXT( glProgramLocalParameter4dv );
00642 LOAD_EXT( glProgramLocalParameter4f );
00643 LOAD_EXT( glProgramLocalParameter4fv );
00644 LOAD_EXT( glGetProgramEnvParameterdv );
00645 LOAD_EXT( glGetProgramEnvParameterfv );
00646 LOAD_EXT( glGetProgramLocalParameterdv );
00647 LOAD_EXT( glGetProgramLocalParameterfv );
00648 LOAD_EXT( glGetProgramiv );
00649 LOAD_EXT( glGetProgramString );
00650 LOAD_EXT( glGetVertexAttribdv );
00651 LOAD_EXT( glGetVertexAttribfv );
00652 LOAD_EXT( glGetVertexAttribiv );
00653 LOAD_EXT( glGetVertexAttribPointerv );
00654 LOAD_EXT( glIsProgram );
00655 }
00656 if( GLSL_supported ) {
00657 LOAD_EXT( glDeleteObject );
00658 LOAD_EXT( glGetHandle );
00659 LOAD_EXT( glDetachObject );
00660 LOAD_EXT( glCreateShaderObject );
00661 LOAD_EXT( glShaderSource );
00662 LOAD_EXT( glCompileShader );
00663 LOAD_EXT( glCreateProgramObject );
00664 LOAD_EXT( glAttachObject );
00665 LOAD_EXT( glLinkProgram );
00666 LOAD_EXT( glUseProgramObject );
00667 LOAD_EXT( glValidateProgram );
00668 LOAD_EXT( glUniform1f );
00669 LOAD_EXT( glUniform2f );
00670 LOAD_EXT( glUniform3f );
00671 LOAD_EXT( glUniform4f );
00672 LOAD_EXT( glUniform1i );
00673 LOAD_EXT( glUniform2i );
00674 LOAD_EXT( glUniform3i );
00675 LOAD_EXT( glUniform4i );
00676 LOAD_EXT( glUniform1fv );
00677 LOAD_EXT( glUniform2fv );
00678 LOAD_EXT( glUniform3fv );
00679 LOAD_EXT( glUniform4fv );
00680 LOAD_EXT( glUniform1iv );
00681 LOAD_EXT( glUniform2iv );
00682 LOAD_EXT( glUniform3iv );
00683 LOAD_EXT( glUniform4iv );
00684 LOAD_EXT( glUniformMatrix2fv );
00685 LOAD_EXT( glUniformMatrix3fv );
00686 LOAD_EXT( glUniformMatrix4fv );
00687 LOAD_EXT( glGetObjectParameterfv );
00688 LOAD_EXT( glGetObjectParameteriv );
00689 LOAD_EXT( glGetInfoLog );
00690 LOAD_EXT( glGetAttachedObjects );
00691 LOAD_EXT( glGetUniformLocation );
00692 LOAD_EXT( glGetActiveUniform );
00693 LOAD_EXT( glGetUniformfv );
00694 LOAD_EXT( glGetUniformiv );
00695 LOAD_EXT( glGetShaderSource );
00696
00697 LOAD_EXT( glBindAttribLocation );
00698 LOAD_EXT( glGetActiveAttrib );
00699 LOAD_EXT( glGetAttribLocation );
00700
00701 }
00702 if( NVFP_supported ) {
00703 glBindProgramNVPtr = (glBindProgramNVProc) SGLookupFunction( "glBindProgramNV" );
00704 glDeleteProgramsNVPtr = (glDeleteProgramsNVProc) SGLookupFunction( "glDeleteProgramsNV" );
00705 glGenProgramsNVPtr = (glGenProgramsNVProc) SGLookupFunction( "glGenProgramsNV" );
00706 glLoadProgramNVPtr = (glLoadProgramNVProc) SGLookupFunction( "glLoadProgramNV" );
00707 glProgramParameter4fvNVPtr = (glProgramParameter4fvNVProc) SGLookupFunction( "glProgramParameter4fvNV" );
00708 }
00709 }