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