shader.cpp
上传用户:qccn516
上传日期:2013-05-02
资源大小:3382k
文件大小:19k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /* Shader
  2.  *
  3.  * Copyright (C) 2003-2004, Alexander Zaprjagaev <frustum@frustum.org>
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  */
  19. #include "engine.h"
  20. #include "light.h"
  21. #include "parser.h"
  22. #include "shader.h"
  23. /*
  24.  */
  25. Shader *Shader::old_shader;
  26. vec4 Shader::parameters[NUM_PARAMETERS];
  27. Texture *Shader::old_textures[NUM_TEXTURES];
  28. /*
  29.  */
  30. Shader::Shader(const char *name) {
  31. load(name);
  32. }
  33. Shader::~Shader() {
  34. if(vertex_target == GL_VERTEX_PROGRAM_ARB) {
  35. if(vertex_id) glDeleteProgramsARB(1,&vertex_id);
  36. }
  37. if(fragment_target == GL_FRAGMENT_PROGRAM_ARB) {
  38. if(fragment_id) glDeleteProgramsARB(1,&fragment_id);
  39. } else if(fragment_target == GL_FRAGMENT_PROGRAM_NV) {
  40. if(fragment_id) glDeleteProgramsNV(1,&fragment_id);
  41. } else if(fragment_target == GL_COMBINE) {
  42. glDeleteLists(fragment_id,1);
  43. }
  44. }
  45. /*****************************************************************************/
  46. /*                                                                           */
  47. /* load shader                                                               */
  48. /*                                                                           */
  49. /*****************************************************************************/
  50. /*
  51.  */
  52. void Shader::load(const char *name) {
  53. Parser *parser = new Parser(name);
  54. // matrixes
  55. num_matrixes = 0;
  56. for(int i = 0; i < NUM_MATRIXES; i++) {
  57. char buf[1024];
  58. sprintf(buf,"matrix%d",i);
  59. if(parser->get(buf)) {
  60. matrixes[num_matrixes].num = i;
  61. getMatrix(parser->get(buf),&matrixes[num_matrixes]);
  62. num_matrixes++;
  63. }
  64. }
  65. // vertex program local parameters
  66. num_vertex_parameters = 0;
  67. for(int i = 0; i < NUM_LOCAL_PARAMETERS; i++) {
  68. char buf[1024];
  69. sprintf(buf,"vertex_local%d",i);
  70. if(parser->get(buf)) {
  71. vertex_parameters[num_vertex_parameters].num = i;
  72. getLocalParameter(parser->get(buf),&vertex_parameters[num_vertex_parameters]);
  73. num_vertex_parameters++;
  74. }
  75. }
  76. // fragement program local parameters
  77. num_fragment_parameters = 0;
  78. for(int i = 0; i < NUM_LOCAL_PARAMETERS; i++) {
  79. char buf[1024];
  80. sprintf(buf,"fragment_local%d",i);
  81. if(parser->get(buf)) {
  82. fragment_parameters[num_fragment_parameters].num = i;
  83. getLocalParameter(parser->get(buf),&fragment_parameters[num_fragment_parameters]);
  84. num_fragment_parameters++;
  85. }
  86. }
  87. char *data;
  88. // vertex program
  89. vertex_target = 0;
  90. vertex_id = 0;
  91. if((data = parser->get("vertex"))) {
  92. int error = -1;
  93. if(!strncmp(data,"!!ARBvp1.0",10)) {
  94. vertex_target = GL_VERTEX_PROGRAM_ARB;
  95. glGenProgramsARB(1,&vertex_id);
  96. glBindProgramARB(vertex_target,vertex_id);
  97. glProgramStringARB(vertex_target,GL_PROGRAM_FORMAT_ASCII_ARB,strlen(data),data);
  98. glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB,&error);
  99. } else {
  100. char *s = data;
  101. while(*s != '' && *s != 'n') s++;
  102. *s = '';
  103. fprintf(stderr,"Shader::Shader(): unknown vertex program header "%s" in "%s" filen",data,name);
  104. }
  105. if(error != -1) {
  106. int line = 0;
  107. char *s = data;
  108. while(error-- && *s) if(*s++ == 'n') line++;
  109. while(s >= data && *s != 'n') s--;
  110. char *e = ++s;
  111. while(*e != '' && *e != 'n') e++;
  112. *e = '';
  113. fprintf(stderr,"Shader::Shader(): vertex program error in "%s" file at line %d:n"%s"n",name,line,s);
  114. }
  115. }
  116. // fragment program
  117. fragment_target = 0;
  118. fragment_id = 0;
  119. if((data = parser->get("fragment"))) {
  120. int error = -1;
  121. if(!strncmp(data,"!!ARBfp1.0",10)) {
  122. fragment_target = GL_FRAGMENT_PROGRAM_ARB;
  123. glGenProgramsARB(1,&fragment_id);
  124. glBindProgramARB(fragment_target,fragment_id);
  125. glProgramStringARB(fragment_target,GL_PROGRAM_FORMAT_ASCII_ARB,strlen(data),data);
  126. glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB,&error);
  127. } else if(!strncmp(data,"!!FP1.0",7)) {
  128. fragment_target = GL_FRAGMENT_PROGRAM_NV;
  129. glGenProgramsNV(1,&fragment_id);
  130. glBindProgramNV(fragment_target,fragment_id);
  131. glLoadProgramNV(fragment_target,fragment_id,strlen(data),(GLubyte*)data);
  132. glGetIntegerv(GL_PROGRAM_ERROR_POSITION_NV,&error);
  133. } else if(!strncmp(data,"!!ARBtec1.0",11)) { // arb texture env combine
  134. fragment_target = GL_COMBINE;
  135. fragment_id = compileARBtec(data);
  136. } else {
  137. char *s = data;
  138. while(*s != '' && *s != 'n') s++;
  139. *s = '';
  140. fprintf(stderr,"Shader::Shader(): unknown fragment program header "%s" in "%s" filen",data,name);
  141. }
  142. if(error != -1) {
  143. int line = 0;
  144. char *s = data;
  145. while(error-- && *s) if(*s++ == 'n') line++;
  146. while(s >= data && *s != 'n') s--;
  147. char *e = ++s;
  148. while(*e != '' && *e != 'n') e++;
  149. *e = '';
  150. fprintf(stderr,"Shader::Shader(): fragment program error in "%s" file at line %d:n"%s"n",name,line,s);
  151. }
  152. }
  153. delete parser;
  154. }
  155. /*
  156.  */
  157. GLuint Shader::compileARBtec(const char *src) {
  158. const char *s = src;
  159. GLuint list = glGenLists(1);
  160. glNewList(list,GL_COMPILE);
  161. if(strncmp("!!ARBtec1.0",s,11)) {
  162. fprintf(stderr,"Shader::compileARBtec(): unknown headern");
  163. glEndList();
  164. return list;
  165. }
  166. s += 11;
  167. int unit = -1;
  168. while(*s) {
  169. if(*s == '#') while(*s && *s != 'n') s++;
  170. else if(strchr(" tnr",*s)) s++;
  171. else if(!strncmp("END",s,3)) break;
  172. else {
  173. int sources = 0;
  174. if(unit > 0) glActiveTexture(GL_TEXTURE0 + unit);
  175. while(*s) {
  176. if(strchr(" t",*s)) s++;
  177. else if(!strncmp("nop",s,3) && (s += 3)) {
  178. if(++unit > 0) glActiveTexture(GL_TEXTURE0 + unit);
  179. glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
  180. }
  181. else if(!strncmp("replace",s,7) && (s += 7)) {
  182. if(++unit > 0) glActiveTexture(GL_TEXTURE0 + unit);
  183. glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
  184. glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_REPLACE);
  185. }
  186. else if(!strncmp("modulate",s,8) && (s += 8)) {
  187. if(++unit > 0) glActiveTexture(GL_TEXTURE0 + unit);
  188. glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
  189. glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_MODULATE);
  190. }
  191. else if(!strncmp("add",s,3) && (s += 3)) {
  192. if(++unit > 0) glActiveTexture(GL_TEXTURE0 + unit);
  193. glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
  194. glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_ADD);
  195. }
  196. else if(!strncmp("add_signed",s,10) && (s += 10)) {
  197. if(++unit > 0) glActiveTexture(GL_TEXTURE0 + unit);
  198. glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
  199. glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_ADD_SIGNED);
  200. }
  201. else if(!strncmp("sub",s,3) && (s += 3)) {
  202. if(++unit > 0) glActiveTexture(GL_TEXTURE0 + unit);
  203. glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
  204. glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_SUBTRACT);
  205. }
  206. else if(!strncmp("dot3",s,4) && (s += 4)) {
  207. if(++unit > 0) glActiveTexture(GL_TEXTURE0 + unit);
  208. glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
  209. glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_DOT3_RGB);
  210. }
  211. else if(!strncmp("primary",s,7) && (s += 7)) glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB + sources++,GL_PRIMARY_COLOR);
  212. else if(!strncmp("texture0",s,8) && (s += 8)) glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB + sources++,GL_TEXTURE0);
  213. else if(!strncmp("texture1",s,8) && (s += 8)) glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB + sources++,GL_TEXTURE1);
  214. else if(!strncmp("texture2",s,8) && (s += 8)) glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB + sources++,GL_TEXTURE2);
  215. else if(!strncmp("texture3",s,8) && (s += 8)) glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB + sources++,GL_TEXTURE3);
  216. else if(!strncmp("texture",s,7) && (s += 7)) glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB + sources++,GL_TEXTURE0 + unit);
  217. else if(!strncmp("previous",s,8) && (s += 8)) glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB + sources++,GL_PREVIOUS);
  218. else if(!strncmp("scale2",s,6) && (s += 6)) glTexEnvi(GL_TEXTURE_ENV,GL_RGB_SCALE,2);
  219. else if(!strncmp("scale4",s,6) && (s += 6)) glTexEnvi(GL_TEXTURE_ENV,GL_RGB_SCALE,4);
  220. else if(*s == 'n' && s++) break;
  221. else {
  222. printf("%sn",s);
  223. char buf[1024];
  224. char *d = buf;
  225. while(*s && !strchr(" tnr",*s)) *d++ = *s++;
  226. *d = '';
  227. fprintf(stderr,"Shader::compileARBtec(): unknown token "%s"n",buf);
  228. glEndList();
  229. return list;
  230. }
  231. }
  232. for(int i = 0; i < sources; i++) glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB + i,GL_SRC_COLOR);
  233. }
  234. }
  235. if(unit > 1) glActiveTexture(GL_TEXTURE0);
  236. glEndList();
  237. return list;
  238. }
  239. /*
  240.  */
  241. void Shader::getMatrix(const char *name,Matrix *m) {
  242. if(!strcmp(name,"projection")) m->type = PROJECTION;
  243. else if(!strcmp(name,"modelview")) m->type = MODELVIEW;
  244. else if(!strcmp(name,"imodelview")) m->type = IMODELVIEW;
  245. else if(!strcmp(name,"transform")) m->type = TRANSFORM;
  246. else if(!strcmp(name,"itransform")) m->type = ITRANSFORM;
  247. else if(!strcmp(name,"light_transform")) m->type = LIGHT_TRANSFORM;
  248. else fprintf(stderr,"Shader::getMatrix(): unknown matrix "%s"n",name);
  249. }
  250. void Shader::getLocalParameter(const char *name,Shader::LocalParameter *p) {
  251. if(!strcmp(name,"time")) p->type = TIME;
  252. else if(!strcmp(name,"sin")) p->type = SIN;
  253. else if(!strcmp(name,"cos")) p->type = COS;
  254. else if(!strcmp(name,"camera")) p->type = CAMERA;
  255. else if(!strcmp(name,"icamera")) p->type = ICAMERA;
  256. else if(!strcmp(name,"light")) p->type = LIGHT;
  257. else if(!strcmp(name,"ilight")) p->type = ILIGHT;
  258. else if(!strcmp(name,"light_color")) p->type = LIGHT_COLOR;
  259. else if(!strcmp(name,"fog_color")) p->type = FOG_COLOR;
  260. else if(!strcmp(name,"viewport")) p->type = VIEWPORT;
  261. else if(!strncmp(name,"parameter",9)) {
  262. p->type = PARAMETER;
  263. sscanf(name + 9,"%d",&p->parameter);
  264. if(p->parameter >= NUM_PARAMETERS) {
  265. fprintf(stderr,"Shader::getLocalParameter(): number of parameters is bign");
  266. p->parameter = 0;
  267. }
  268. }
  269. else fprintf(stderr,"Shader::getLocalParameter(): unknown parameter "%s"n",name);
  270. }
  271. /*
  272.  */
  273. void Shader::setParameter(int num,const vec4 &parameter) {
  274. parameters[num] = parameter;
  275. }
  276. /*****************************************************************************/
  277. /*                                                                           */
  278. /* enable/disable/bind                                                       */
  279. /*                                                                           */
  280. /*****************************************************************************/
  281. /*
  282.  */
  283. void Shader::enable() {
  284. if(old_shader == this) return;
  285. if(old_shader) {
  286. if(old_shader->vertex_target != vertex_target) {
  287. if(old_shader->vertex_target) glDisable(old_shader->vertex_target);
  288. if(vertex_target) glEnable(vertex_target);
  289. }
  290. if(old_shader->fragment_target != fragment_target) {
  291. if(old_shader->fragment_target == GL_FRAGMENT_PROGRAM_ARB) glDisable(old_shader->fragment_target);
  292. else if(old_shader->fragment_target == GL_FRAGMENT_PROGRAM_NV) glDisable(old_shader->fragment_target);
  293. else if(old_shader->fragment_target == GL_COMBINE) {
  294. glActiveTexture(GL_TEXTURE0);
  295. glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
  296. glActiveTexture(GL_TEXTURE1);
  297. glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
  298. glActiveTexture(GL_TEXTURE2);
  299. glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
  300. glActiveTexture(GL_TEXTURE3);
  301. glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
  302. glActiveTexture(GL_TEXTURE0);
  303. }
  304. if(fragment_target == GL_FRAGMENT_PROGRAM_ARB) glEnable(fragment_target);
  305. else if(fragment_target == GL_FRAGMENT_PROGRAM_NV) glEnable(fragment_target);
  306. }
  307. } else {
  308. if(vertex_target) glEnable(vertex_target);
  309. if(fragment_target == GL_FRAGMENT_PROGRAM_ARB) glEnable(fragment_target);
  310. else if(fragment_target == GL_FRAGMENT_PROGRAM_NV) glEnable(fragment_target);
  311. }
  312. }
  313. /*
  314.  */
  315. void Shader::disable() {
  316. if(vertex_target) glDisable(vertex_target);
  317. if(fragment_target == GL_FRAGMENT_PROGRAM_ARB) glDisable(fragment_target);
  318. else if(fragment_target == GL_FRAGMENT_PROGRAM_NV) glDisable(fragment_target);
  319. else if(fragment_target == GL_COMBINE) {
  320. glActiveTexture(GL_TEXTURE0);
  321. glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
  322. glActiveTexture(GL_TEXTURE1);
  323. glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
  324. glActiveTexture(GL_TEXTURE2);
  325. glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
  326. glActiveTexture(GL_TEXTURE3);
  327. glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
  328. }
  329. for(int i = 0; i < NUM_TEXTURES; i++) {
  330. if(old_textures[i]) {
  331. glActiveTexture(GL_TEXTURE0 + i);
  332. old_textures[i]->disable();
  333. }
  334. old_textures[i] = NULL;
  335. }
  336. glActiveTexture(GL_TEXTURE0);
  337. old_shader = NULL;
  338. }
  339. /*
  340.  */
  341. void Shader::bind() {
  342. if(old_shader != this) {
  343. if(vertex_target == GL_VERTEX_PROGRAM_ARB) glBindProgramARB(vertex_target,vertex_id);
  344. if(fragment_target == GL_FRAGMENT_PROGRAM_ARB) glBindProgramARB(fragment_target,fragment_id);
  345. else if(fragment_target == GL_FRAGMENT_PROGRAM_NV) glBindProgramNV(fragment_target,fragment_id);
  346. else if(fragment_target == GL_COMBINE) glCallList(fragment_id);
  347. old_shader = this;
  348. }
  349. for(int i = 0; i < num_matrixes; i++) {
  350. glMatrixMode(GL_MATRIX0_ARB + matrixes[i].num);
  351. if(matrixes[i].type == PROJECTION) glLoadMatrixf(Engine::projection);
  352. else if(matrixes[i].type == MODELVIEW) glLoadMatrixf(Engine::modelview);
  353. else if(matrixes[i].type == IMODELVIEW) glLoadMatrixf(Engine::imodelview);
  354. else if(matrixes[i].type == TRANSFORM) glLoadMatrixf(Engine::transform);
  355. else if(matrixes[i].type == ITRANSFORM) glLoadMatrixf(Engine::itransform);
  356. else if(matrixes[i].type == LIGHT_TRANSFORM && Engine::current_light) glLoadMatrixf(Engine::current_light->transform);
  357. }
  358. if(num_matrixes) glMatrixMode(GL_MODELVIEW);
  359. for(int i = 0; i < num_vertex_parameters; i++) {
  360. if(vertex_parameters[i].type == TIME) glProgramLocalParameter4fvARB(vertex_target,vertex_parameters[i].num,vec4(Engine::time,Engine::time / 2.0f,Engine::time / 3.0f,Engine::time / 5.0f));
  361. else if(vertex_parameters[i].type == SIN) glProgramLocalParameter4fvARB(vertex_target,vertex_parameters[i].num,vec4(sin(Engine::time),sin(Engine::time / 2.0f),sin(Engine::time / 3.0f),sin(Engine::time / 5.0f)));
  362. else if(vertex_parameters[i].type == COS) glProgramLocalParameter4fvARB(vertex_target,vertex_parameters[i].num,vec4(cos(Engine::time),cos(Engine::time / 2.0f),cos(Engine::time / 3.0f),cos(Engine::time / 5.0f)));
  363. else if(vertex_parameters[i].type == CAMERA) glProgramLocalParameter4fvARB(vertex_target,vertex_parameters[i].num,vec4(Engine::camera,1));
  364. else if(vertex_parameters[i].type == ICAMERA) glProgramLocalParameter4fvARB(vertex_target,vertex_parameters[i].num,vec4(Engine::itransform * Engine::camera,1));
  365. else if(vertex_parameters[i].type == LIGHT) glProgramLocalParameter4fvARB(vertex_target,vertex_parameters[i].num,Engine::light);
  366. else if(vertex_parameters[i].type == ILIGHT) glProgramLocalParameter4fvARB(vertex_target,vertex_parameters[i].num,vec4(Engine::itransform * vec3(Engine::light),Engine::light.w));
  367. else if(vertex_parameters[i].type == LIGHT_COLOR) glProgramLocalParameter4fvARB(vertex_target,vertex_parameters[i].num,Engine::light_color);
  368. else if(vertex_parameters[i].type == FOG_COLOR) glProgramLocalParameter4fvARB(vertex_target,vertex_parameters[i].num,Engine::fog_color);
  369. else if(vertex_parameters[i].type == VIEWPORT) glProgramLocalParameter4fvARB(vertex_target,vertex_parameters[i].num,vec4(Engine::viewport[0],Engine::viewport[1],Engine::viewport[2],Engine::viewport[3]));
  370. else if(vertex_parameters[i].type == PARAMETER) glProgramLocalParameter4fvARB(vertex_target,vertex_parameters[i].num,parameters[vertex_parameters[i].parameter]);
  371. }
  372. for(int i = 0; i < num_fragment_parameters; i++) {
  373. if(vertex_parameters[i].type == TIME) glProgramLocalParameter4fvARB(fragment_target,fragment_parameters[i].num,vec4(Engine::time,Engine::time / 2.0f,Engine::time / 3.0f,Engine::time / 5.0f));
  374. else if(vertex_parameters[i].type == SIN) glProgramLocalParameter4fvARB(fragment_target,fragment_parameters[i].num,vec4(sin(Engine::time),sin(Engine::time / 2.0f),sin(Engine::time / 3.0f),sin(Engine::time / 5.0f)));
  375. else if(vertex_parameters[i].type == COS) glProgramLocalParameter4fvARB(fragment_target,fragment_parameters[i].num,vec4(cos(Engine::time),cos(Engine::time / 2.0f),cos(Engine::time / 3.0f),cos(Engine::time / 5.0f)));
  376. else if(fragment_parameters[i].type == CAMERA) glProgramLocalParameter4fvARB(fragment_target,fragment_parameters[i].num,vec4(Engine::camera,1));
  377. else if(fragment_parameters[i].type == ICAMERA) glProgramLocalParameter4fvARB(fragment_target,fragment_parameters[i].num,vec4(Engine::itransform * Engine::camera,1));
  378. else if(fragment_parameters[i].type == LIGHT) glProgramLocalParameter4fvARB(fragment_target,fragment_parameters[i].num,Engine::light);
  379. else if(fragment_parameters[i].type == ILIGHT) glProgramLocalParameter4fvARB(fragment_target,fragment_parameters[i].num,vec4(Engine::itransform * vec3(Engine::light),Engine::light.w));
  380. else if(fragment_parameters[i].type == LIGHT_COLOR) glProgramLocalParameter4fvARB(fragment_target,fragment_parameters[i].num,Engine::light_color);
  381. else if(fragment_parameters[i].type == FOG_COLOR) glProgramLocalParameter4fvARB(fragment_target,fragment_parameters[i].num,Engine::fog_color);
  382. else if(fragment_parameters[i].type == VIEWPORT) glProgramLocalParameter4fvARB(fragment_target,fragment_parameters[i].num,vec4(Engine::viewport[0],Engine::viewport[1],Engine::viewport[2],Engine::viewport[3]));
  383. else if(fragment_parameters[i].type == PARAMETER) glProgramLocalParameter4fvARB(fragment_target,fragment_parameters[i].num,parameters[fragment_parameters[i].parameter]);
  384. }
  385. }
  386. /*****************************************************************************/
  387. /*                                                                           */
  388. /* bind texture                                                              */
  389. /*                                                                           */
  390. /*****************************************************************************/
  391. /*
  392.  */
  393. void Shader::bindTexture(int unit,Texture *texture) {
  394. if(old_textures[unit] == texture) return;
  395. glActiveTexture(GL_TEXTURE0 + unit);
  396. if(texture) {
  397. if(old_textures[unit] == NULL) texture->enable();
  398. else if(texture->target != old_textures[unit]->target) {
  399. old_textures[unit]->disable();
  400. texture->enable();
  401. }
  402. texture->bind();
  403. } else {
  404. if(old_textures[unit]) old_textures[unit]->disable();
  405. }
  406. old_textures[unit] = texture;
  407. }