SCEShaders.c
00001 /*------------------------------------------------------------------------------ 00002 SCEngine - A 3D real time rendering engine written in the C language 00003 Copyright (C) 2006-2009 Antony Martin <martin(dot)antony(at)yahoo(dot)fr> 00004 00005 This program is free software: you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation, either version 3 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 -----------------------------------------------------------------------------*/ 00018 00019 /* created: 06/03/2006 00020 updated: 26/09/2008 */ 00021 00022 #include <ctype.h> 00023 00024 #include <SCE/SCEMinimal.h> 00025 00026 #include <SCE/utils/SCEString.h> 00027 #include <SCE/utils/SCEMedia.h> 00028 #include <SCE/utils/SCEResources.h> 00029 00030 #include <SCE/interface/SCEShaders.h> 00031 00032 00033 typedef void (*SCE_FShaderDelete)(SCE_SShader*); 00034 #ifdef SCE_USE_CG 00035 static void SCE_Shader_DeleteCG (SCE_SShader*); 00036 #endif 00037 static void SCE_Shader_DeleteGLSL (SCE_SShader*); 00038 00039 typedef int (*SCE_FShaderBuild)(SCE_SShader*); 00040 #ifdef SCE_USE_CG 00041 static int SCE_Shader_BuildCG (SCE_SShader*); 00042 #endif 00043 static int SCE_Shader_BuildGLSL (SCE_SShader*); 00044 00045 /*******/ 00046 typedef int (*SCE_FShaderGetIndex)(SCE_SShader*, int, const char*); 00047 #ifdef SCE_USE_CG 00048 static int SCE_Shader_GetIndexCG (SCE_SShader*, int, const char*); 00049 #endif 00050 static int SCE_Shader_GetIndexGLSL (SCE_SShader*, int, const char*); 00051 00052 typedef int (*SCE_FShaderGetAttribIndex)(SCE_SShader*, const char*); 00053 #ifdef SCE_USE_CG 00054 static int SCE_Shader_GetAttribIndexCG (SCE_SShader*, const char*); 00055 #endif 00056 static int SCE_Shader_GetAttribIndexGLSL (SCE_SShader*, const char*); 00057 00058 /*******/ 00059 typedef void (*SCE_FShaderParam)(int, const char*, int); 00060 #ifdef SCE_USE_CG 00061 static void SCE_Shader_ParamCG (int, const char*, int); 00062 #endif 00063 static void SCE_Shader_ParamGLSL (int, const char*, int); 00064 00065 typedef void (*SCE_FShaderParamf)(int, const char*, float); 00066 #ifdef SCE_USE_CG 00067 static void SCE_Shader_ParamfCG (int, const char*, float); 00068 #endif 00069 static void SCE_Shader_ParamfGLSL (int, const char*, float); 00070 00071 typedef void (*SCE_FShaderParamfv)(int, const char*, size_t, float*); 00072 #ifdef SCE_USE_CG 00073 static void SCE_Shader_Param1fvCG (int, const char*, size_t, float*); 00074 static void SCE_Shader_Param2fvCG (int, const char*, size_t, float*); 00075 static void SCE_Shader_Param3fvCG (int, const char*, size_t, float*); 00076 static void SCE_Shader_Param4fvCG (int, const char*, size_t, float*); 00077 #endif 00078 static void SCE_Shader_Param1fvGLSL (int, const char*, size_t, float*); 00079 static void SCE_Shader_Param2fvGLSL (int, const char*, size_t, float*); 00080 static void SCE_Shader_Param3fvGLSL (int, const char*, size_t, float*); 00081 static void SCE_Shader_Param4fvGLSL (int, const char*, size_t, float*); 00082 00083 /*******/ 00084 typedef void (*SCE_FShaderSetParam)(int, int); 00085 #ifdef SCE_USE_CG 00086 static void SCE_Shader_SetParamCG (int, int); 00087 #endif 00088 static void SCE_Shader_SetParamGLSL (int, int); 00089 00090 typedef void (*SCE_FShaderSetParamf)(int, float); 00091 #ifdef SCE_USE_CG 00092 static void SCE_Shader_SetParamfCG (int, float); 00093 #endif 00094 static void SCE_Shader_SetParamfGLSL (int, float); 00095 00096 /* already defined in SCEShaders.h */ 00097 /*typedef void (*SCE_FShaderSetParamfv)(int, size_t, float*);*/ 00098 #ifdef SCE_USE_CG 00099 static void SCE_Shader_SetParam1fvCG (int, size_t, float*); 00100 static void SCE_Shader_SetParam2fvCG (int, size_t, float*); 00101 static void SCE_Shader_SetParam3fvCG (int, size_t, float*); 00102 static void SCE_Shader_SetParam4fvCG (int, size_t, float*); 00103 #endif 00104 static void SCE_Shader_SetParam1fvGLSL (int, size_t, float*); 00105 static void SCE_Shader_SetParam2fvGLSL (int, size_t, float*); 00106 static void SCE_Shader_SetParam3fvGLSL (int, size_t, float*); 00107 static void SCE_Shader_SetParam4fvGLSL (int, size_t, float*); 00108 /*******/ 00109 00110 /* already defined in SCEShaders.h */ 00111 /*typedef void (*SCE_FShaderSetMatrix)(int, SCE_TMatrix4);*/ 00112 #ifdef SCE_USE_CG 00113 static void SCE_Shader_SetMatrix3CG (int, SCE_TMatrix4); 00114 static void SCE_Shader_SetMatrix4CG (int, SCE_TMatrix4); 00115 #endif 00116 static void SCE_Shader_SetMatrix3GLSL (int, SCE_TMatrix4); 00117 static void SCE_Shader_SetMatrix4GLSL (int, SCE_TMatrix4); 00118 /*******/ 00119 00120 typedef void (*SCE_FShaderUse)(SCE_SShader*); 00121 #ifdef SCE_USE_CG 00122 static void SCE_Shader_UseCG (SCE_SShader*); 00123 #endif 00124 static void SCE_Shader_UseGLSL (SCE_SShader*); 00125 00126 00127 static const SCE_FShaderDelete Delete[2] = 00128 { 00129 #ifdef SCE_USE_CG 00130 SCE_Shader_DeleteCG, 00131 #else 00132 NULL, 00133 #endif 00134 SCE_Shader_DeleteGLSL 00135 }; 00136 00137 /*******/ 00138 static const SCE_FShaderBuild Build[2] = 00139 { 00140 #ifdef SCE_USE_CG 00141 SCE_Shader_BuildCG, 00142 #else 00143 NULL, 00144 #endif 00145 SCE_Shader_BuildGLSL 00146 }; 00147 00148 /*******/ 00149 static const SCE_FShaderGetIndex GetIndex[2] = 00150 { 00151 #ifdef SCE_USE_CG 00152 SCE_Shader_GetIndexCG, 00153 #else 00154 NULL, 00155 #endif 00156 SCE_Shader_GetIndexGLSL 00157 }; 00158 00159 static const SCE_FShaderGetAttribIndex GetAttribIndex[2] = 00160 { 00161 #ifdef SCE_USE_CG 00162 SCE_Shader_GetAttribIndexCG, 00163 #else 00164 NULL, 00165 #endif 00166 SCE_Shader_GetAttribIndexGLSL 00167 }; 00168 00169 /*******/ 00170 static const SCE_FShaderParam Param[2] = 00171 { 00172 #ifdef SCE_USE_CG 00173 SCE_Shader_ParamCG, 00174 #else 00175 NULL, 00176 #endif 00177 SCE_Shader_ParamGLSL 00178 }; 00179 00180 static const SCE_FShaderParamf Paramf[2] = 00181 { 00182 #ifdef SCE_USE_CG 00183 SCE_Shader_ParamfCG, 00184 #else 00185 NULL, 00186 #endif 00187 SCE_Shader_ParamfGLSL 00188 }; 00189 00190 00191 static const SCE_FShaderParamfv Param1fv[2] = 00192 { 00193 #ifdef SCE_USE_CG 00194 SCE_Shader_Param1fvCG, 00195 #else 00196 NULL, 00197 #endif 00198 SCE_Shader_Param1fvGLSL 00199 }; 00200 static const SCE_FShaderParamfv Param2fv[2] = 00201 { 00202 #ifdef SCE_USE_CG 00203 SCE_Shader_Param2fvCG, 00204 #else 00205 NULL, 00206 #endif 00207 SCE_Shader_Param2fvGLSL 00208 }; 00209 static const SCE_FShaderParamfv Param3fv[2] = 00210 { 00211 #ifdef SCE_USE_CG 00212 SCE_Shader_Param3fvCG, 00213 #else 00214 NULL, 00215 #endif 00216 SCE_Shader_Param3fvGLSL 00217 }; 00218 static const SCE_FShaderParamfv Param4fv[2] = 00219 { 00220 #ifdef SCE_USE_CG 00221 SCE_Shader_Param4fvCG, 00222 #else 00223 NULL, 00224 #endif 00225 SCE_Shader_Param4fvGLSL 00226 }; 00227 00228 00229 /*******/ 00230 static const SCE_FShaderSetParam SetParam[2] = 00231 { 00232 #ifdef SCE_USE_CG 00233 SCE_Shader_SetParamCG, 00234 #else 00235 NULL, 00236 #endif 00237 SCE_Shader_SetParamGLSL 00238 }; 00239 00240 00241 static const SCE_FShaderSetParamf SetParamf[2] =\ 00242 { 00243 #ifdef SCE_USE_CG 00244 SCE_Shader_SetParamfCG, 00245 #else 00246 NULL, 00247 #endif 00248 SCE_Shader_SetParamfGLSL 00249 }; 00250 00251 00252 static const SCE_FShaderSetParamfv SetParam1fv[2] = 00253 { 00254 #ifdef SCE_USE_CG 00255 SCE_Shader_SetParam1fvCG, 00256 #else 00257 NULL, 00258 #endif 00259 SCE_Shader_SetParam1fvGLSL 00260 }; 00261 static const SCE_FShaderSetParamfv SetParam2fv[2] = 00262 { 00263 #ifdef SCE_USE_CG 00264 SCE_Shader_SetParam2fvCG, 00265 #else 00266 NULL, 00267 #endif 00268 SCE_Shader_SetParam2fvGLSL 00269 }; 00270 static const SCE_FShaderSetParamfv SetParam3fv[2] = 00271 { 00272 #ifdef SCE_USE_CG 00273 SCE_Shader_SetParam3fvCG, 00274 #else 00275 NULL, 00276 #endif 00277 SCE_Shader_SetParam3fvGLSL 00278 }; 00279 static const SCE_FShaderSetParamfv SetParam4fv[2] = 00280 { 00281 #ifdef SCE_USE_CG 00282 SCE_Shader_SetParam4fvCG, 00283 #else 00284 NULL, 00285 #endif 00286 SCE_Shader_SetParam4fvGLSL 00287 }; 00288 00289 00290 static const SCE_FShaderSetMatrix SetMatrix3[2] = 00291 { 00292 #ifdef SCE_USE_CG 00293 SCE_Shader_SetMatrix3CG, 00294 #else 00295 NULL, 00296 #endif 00297 SCE_Shader_SetMatrix3GLSL 00298 }; 00299 00300 static const SCE_FShaderSetMatrix SetMatrix4[2] = 00301 { 00302 #ifdef SCE_USE_CG 00303 SCE_Shader_SetMatrix4CG, 00304 #else 00305 NULL, 00306 #endif 00307 SCE_Shader_SetMatrix4GLSL 00308 }; 00309 00310 00311 /*******/ 00312 static const SCE_FShaderUse Use[2] = 00313 { 00314 #ifdef SCE_USE_CG 00315 SCE_Shader_UseCG, 00316 #else 00317 NULL, 00318 #endif 00319 SCE_Shader_UseGLSL 00320 }; 00321 00322 00323 /* identifiant de type du media manager */ 00324 static int shader_mediatypeid = 0; 00325 00326 static int sce_shd_enabled = SCE_FALSE; 00327 00328 static SCE_SShader *used = NULL; 00329 00330 00331 /* revise le 19/10/2007 */ 00332 int SCE_Init_Shader (void) 00333 { 00334 static int is_init = SCE_FALSE; 00335 00336 SCE_btstart (); 00337 if (!is_init) 00338 { 00339 shader_mediatypeid = SCE_Media_GenTypeID (); 00340 SCE_Media_RegisterLoader (shader_mediatypeid, 0, 00341 ".glsl .vert .frag" 00342 #ifdef SCE_USE_CG 00343 " .cg .vcg .pcg .fcg .cgvs .cgps" 00344 #endif 00345 ,SCE_Shader_LoadSourceFromFile); 00346 00347 is_init = SCE_TRUE; 00348 sce_shd_enabled = SCE_TRUE; 00349 } 00350 00351 SCE_btend (); 00352 return SCE_OK; 00353 } 00354 00355 /* revise le 18/10/2007 */ 00356 void SCE_Quit_Shader (void) 00357 { 00358 sce_shd_enabled = SCE_FALSE; 00359 used = NULL; 00360 } 00361 00362 int SCE_Shader_MediaTypeID (void) 00363 { 00364 return shader_mediatypeid; 00365 } 00366 00367 00368 static void SCE_Shader_InitParam (SCE_SShaderParam *sp) 00369 { 00370 sp->param = NULL; 00371 sp->index = 0; /* TODO: constante nulle pour les indices 00372 de parametres non-definie... */ 00373 sp->setfv = NULL; 00374 } 00375 static void SCE_Shader_DeleteParam (void *p) 00376 { 00377 SCE_free (p); 00378 } 00379 00380 void SCE_Shader_Init (SCE_SShader *shader) 00381 { 00382 shader->p_glsl = NULL; 00383 shader->v = shader->p = NULL; 00384 00385 shader->type = SCE_UNKNOWN_SHADER; 00386 shader->ready = SCE_FALSE; 00387 shader->res[0] = shader->res[1] = NULL; 00388 shader->vs_source = shader->ps_source = NULL; 00389 shader->vs_addsrc = shader->ps_addsrc = NULL; 00390 00391 shader->params_i = shader->params_f = shader->params_m = NULL; 00392 } 00393 00394 SCE_SShader* SCE_Shader_Create (int type) 00395 { 00396 SCE_SShader *shader = NULL; 00397 00398 SCE_btstart (); 00399 shader = SCE_malloc (sizeof *shader); 00400 if (!shader) 00401 Logger_LogSrc (); 00402 else 00403 { 00404 #define SCE_SHDASSERT(c)if(c){\ 00405 SCE_Shader_Delete (shader);\ 00406 Logger_LogSrc ();\ 00407 SCE_btend ();\ 00408 return NULL;\ 00409 } 00410 SCE_Shader_Init (shader); 00411 shader->type = type; 00412 SCE_SHDASSERT (!(shader->params_i = 00413 SCE_List_Create (SCE_Shader_DeleteParam))) 00414 SCE_SHDASSERT (!(shader->params_f = 00415 SCE_List_Create (SCE_Shader_DeleteParam))) 00416 SCE_SHDASSERT (!(shader->params_m = 00417 SCE_List_Create (SCE_Shader_DeleteParam))) 00418 #undef SCE_SHDASSERT 00419 } 00420 SCE_btend (); 00421 return shader; 00422 } 00423 00424 00425 #ifdef SCE_USE_CG 00426 static void SCE_Shader_DeleteCG (SCE_SShader *shader) 00427 { 00428 SCE_btstart (); 00429 SCE_CDeleteShaderCG (shader->v); 00430 SCE_CDeleteShaderCG (shader->p); 00431 SCE_btend (); 00432 } 00433 #endif 00434 static void SCE_Shader_DeleteGLSL (SCE_SShader *shader) 00435 { 00436 SCE_btstart (); 00437 SCE_CDeleteProgram (shader->p_glsl); 00438 SCE_CDeleteShaderGLSL (shader->v); 00439 SCE_CDeleteShaderGLSL (shader->p); 00440 SCE_btend (); 00441 } 00442 /* revise le 19/10/2007 */ 00443 void SCE_Shader_Delete (SCE_SShader *shader) 00444 { 00445 SCE_btstart (); 00446 if (shader) 00447 { 00448 Delete[shader->type] (shader); 00449 00450 SCE_free (shader->vs_addsrc); 00451 SCE_free (shader->ps_addsrc); 00452 00453 if (SCE_Resource_Free (shader->res[0])) 00454 { 00455 SCE_free (shader->res[0][0]); 00456 SCE_free (shader->res[0][1]); 00457 SCE_free (shader->res[0]); 00458 } 00459 if (SCE_Resource_Free (shader->res[1])) 00460 { 00461 SCE_free (shader->res[1][0]); 00462 SCE_free (shader->res[1][1]); 00463 SCE_free (shader->res[1]); 00464 } 00465 00466 SCE_List_Delete (shader->params_m); 00467 SCE_List_Delete (shader->params_f); 00468 SCE_List_Delete (shader->params_i); 00469 SCE_free (shader); 00470 } 00471 SCE_btend (); 00472 } 00473 00474 int SCE_Shader_GetLanguage (SCE_SShader *shader) 00475 { 00476 return shader->type; 00477 } 00478 00479 int SCE_Shader_GetType (SCE_SShader *shader) 00480 { 00481 if ((shader->ps_source != NULL || shader->ps_addsrc != NULL) && 00482 (shader->vs_source != NULL || shader->vs_addsrc != NULL) ) 00483 return SCE_UNKNOWN_SHADER; 00484 else if (shader->ps_source != NULL || shader->ps_addsrc != NULL) 00485 return SCE_PIXEL_SHADER; 00486 else 00487 return SCE_VERTEX_SHADER; 00488 } 00489 00490 00491 /* retourne le type d'un shader d'apres son extension */ 00492 static void SCE_Shader_SearchTypes (const char *ext, int *type) 00493 { 00494 SCE_btstart (); 00495 #define SCE_SHADER_FOR(str, val, val2)\ 00496 if (SCE_String_Cmp (str, ext, 0))\ 00497 {\ 00498 type[0] = val;\ 00499 type[1] = val2;\ 00500 }\ 00501 else 00502 00503 /* NOTE: c'est bien statique tout ça... il faudrait rajouter une 00504 fonctionnalite de stockage d'extensions */ 00505 SCE_SHADER_FOR (".glsl", SCE_GLSL_SHADER, SCE_UNKNOWN_SHADER) 00506 SCE_SHADER_FOR (".vert", SCE_GLSL_SHADER, SCE_VERTEX_SHADER) 00507 SCE_SHADER_FOR (".frag", SCE_GLSL_SHADER, SCE_PIXEL_SHADER) 00508 00509 #ifdef SCE_USE_CG 00510 SCE_SHADER_FOR (".cg", SCE_CG_SHADER, SCE_UNKNOWN_SHADER) 00511 SCE_SHADER_FOR (".vcg", SCE_CG_SHADER, SCE_VERTEX_SHADER) 00512 SCE_SHADER_FOR (".pcg", SCE_CG_SHADER, SCE_PIXEL_SHADER) 00513 SCE_SHADER_FOR (".fcg", SCE_CG_SHADER, SCE_PIXEL_SHADER) 00514 SCE_SHADER_FOR (".cgvs", SCE_CG_SHADER, SCE_VERTEX_SHADER) 00515 SCE_SHADER_FOR (".cgps", SCE_CG_SHADER, SCE_PIXEL_SHADER) 00516 #endif 00517 { 00518 Logger_Log (SCE_INVALID_ARG); 00519 Logger_LogMsg ("'%s' is not a valid shader source extension", ext); 00520 type[0] = type[1] = SCE_UNKNOWN_SHADER; 00521 } 00522 #undef SCE_SHADER_FOR 00523 SCE_btend (); 00524 } 00525 00526 00527 /* NOTE: a deplacer */ 00528 /* positionne le curseur de fp sur la prochaine occurrence a str 00529 retourne 1 si la fonction a trouve une occurrence */ 00530 static int SCE_Shader_SetPosFile (FILE *fp, const char *str, int at_end) 00531 { 00532 size_t i = 0; 00533 long cur = 0, curo = 0; 00534 char buf[256] = {0}; 00535 size_t lenstr = 0; 00536 00537 SCE_btstart (); 00538 lenstr = strlen (str); 00539 curo = ftell (fp); 00540 00541 while (1) 00542 { 00543 fseek (fp, curo+cur, SEEK_SET); 00544 cur++; 00545 00546 for (i=0; i<lenstr; i++) 00547 { 00548 buf[i] = fgetc (fp); 00549 if (buf[i] == EOF) /* fin du fichier */ 00550 { 00551 fseek (fp, curo, SEEK_SET); 00552 SCE_btend (); 00553 return 0; 00554 } 00555 } 00556 00557 if (SCE_String_Cmp (str, buf, 0)) 00558 { 00559 if (!at_end) 00560 fseek (fp, -lenstr, SEEK_CUR); 00561 SCE_btend (); 00562 return 1; 00563 } 00564 } 00565 00566 fseek (fp, curo, SEEK_SET); 00567 00568 SCE_btend (); 00569 return 0; 00570 } 00571 00572 /* charge du texte a partir d'un fichier, jusqu'a end */ 00573 static char* SCE_Shader_LoadSource (FILE *fp, long end) 00574 { 00575 char *src = NULL; 00576 long len = ftell (fp); 00577 long curpos; 00578 00579 SCE_btstart (); 00580 if (end == EOF) 00581 { 00582 /* on calcul la distance qu'il y a jusqu'a la fin du fichier */ 00583 curpos = len; 00584 fseek (fp, 0, SEEK_END); 00585 len = ftell (fp) - len; 00586 fseek (fp, curpos, SEEK_SET); 00587 } 00588 else 00589 len = end - len; 00590 00591 /* dans le cas ou la zone serait vide, aucun code de shader du type prefixe 00592 n'est present a cet endroit, mais pas la peine d'en faire un fromage */ 00593 if (len <= 0) 00594 { 00595 SCE_btend (); 00596 return NULL; 00597 } 00598 00599 src = SCE_malloc (len+1); 00600 if (!src) 00601 { 00602 Logger_LogSrc (); 00603 SCE_btend (); 00604 return NULL; 00605 } 00606 src[len] = '\0'; 00607 00608 fread (src, 1, len, fp); 00609 00610 SCE_btend (); 00611 return src; 00612 } 00613 00614 static void* SCE_Shader_LoadSources (FILE *fp, const char *fname) 00615 { 00616 char **srcs = NULL; 00617 long vpos, ppos, vend, pend; 00618 int type[2]; 00619 00620 SCE_btstart (); 00621 srcs = SCE_malloc (2 * sizeof *srcs); 00622 if (!srcs) 00623 { 00624 Logger_LogSrc (); 00625 SCE_btend (); 00626 return NULL; 00627 } 00628 srcs[0] = srcs[1] = NULL; 00629 00630 /* recherche du type du shader */ 00631 SCE_Shader_SearchTypes (SCE_String_GetExt ((char*)fname), type); 00632 if (type[1] == SCE_UNKNOWN_SHADER) 00633 { 00634 /* le fichier contient le code du vertex et du pixel shader */ 00635 /* recuperation de la position du code du vertex shader */ 00636 SCE_Shader_SetPosFile (fp, "[vertex shader]", SCE_FALSE); 00637 vpos = ftell (fp); 00638 vend = vpos + 15; /* 16 = strlen("[vertex shader]"); */ 00639 rewind (fp); 00640 00641 /* recuperation de la position du code du pixel shader */ 00642 SCE_Shader_SetPosFile (fp, "[pixel shader]", SCE_FALSE); 00643 ppos = ftell (fp); 00644 pend = ppos + 14; /* 15 = strlen("[pixel shader]"); */ 00645 00646 /* lecture du code du vertex shader */ 00647 fseek (fp, vend, SEEK_SET); 00648 srcs[0] = SCE_Shader_LoadSource (fp, (vpos > ppos) ? EOF : ppos); 00649 00650 /* lecture du code du pixel shader */ 00651 fseek (fp, pend, SEEK_SET); 00652 srcs[1] = SCE_Shader_LoadSource (fp, (ppos > vpos) ? EOF : vpos); 00653 } 00654 else 00655 { 00656 /* le fichier contient le code de type[1] */ 00657 srcs[0] = SCE_Shader_LoadSource (fp, EOF); 00658 00659 if (type[1] == SCE_PIXEL_SHADER) 00660 { 00661 srcs[1] = srcs[0]; 00662 srcs[0] = NULL; 00663 } 00664 } 00665 SCE_btend (); 00666 return srcs; 00667 } 00668 00669 /* TODO: w00t */ 00670 #define SCE_SHADER_INCLUDE "#include" 00671 00672 void* SCE_Shader_LoadSourceFromFile (FILE *fp, const char *fname, void *uusd) 00673 { 00674 int i, j; 00675 char buf[BUFSIZ] = {0}; 00676 char *ptr = NULL; 00677 char **srcs = SCE_Shader_LoadSources (fp, fname); 00678 SCE_btstart (); 00679 if (!srcs) 00680 { 00681 Logger_LogSrc (); 00682 SCE_btend (); 00683 return NULL; 00684 } 00685 00686 for (j=0; j<2; j++) 00687 if (srcs[j] && (ptr = strstr (srcs[j], SCE_SHADER_INCLUDE))) 00688 { 00689 size_t len, diff = ptr - srcs[j]; 00690 char *tsrc = NULL; 00691 char **isrcs = NULL; 00692 /* include trouve dans le vertex shader */ 00693 /* lecture du nom du fichier (forme #include <filename>) */ 00694 memset (buf, '\0', BUFSIZ); 00695 i = 0; 00696 while (*ptr++ != '<'); 00697 while (*ptr != '>') 00698 buf[i++] = *ptr++; 00699 /* lecture des fichiers inclus de maniere recursive */ 00700 isrcs = SCE_Resource_Load (buf, NULL, NULL); /* type non force */ 00701 if (!isrcs) 00702 { 00703 Logger_LogSrc (); 00704 SCE_btend (); 00705 return NULL; 00706 } 00707 /* si le fichier contient des donnees du meme type */ 00708 if (isrcs[j]) 00709 { 00710 len = strlen (srcs[j]) + strlen (isrcs[j]) + 1; 00711 tsrc = SCE_malloc (len); 00712 memset (tsrc, '\0', len); 00713 strncpy (tsrc, srcs[j], diff); 00714 strcat (tsrc, isrcs[j]); 00715 strcat (tsrc, ptr); 00716 SCE_free (srcs[j]); 00717 srcs[j] = tsrc; 00718 } 00719 } 00720 SCE_btend (); 00721 return srcs; 00722 } 00723 00724 SCE_SShader* SCE_Shader_CreateFromFile (const char *vname, const char *pname) 00725 { 00726 SCE_SShader *shader = NULL; 00727 char **srcs1 = NULL, **srcs2 = NULL; 00728 char *vsource = NULL, *psource = NULL; 00729 int type[2]; 00730 int ttemp = SCE_UNKNOWN_SHADER; 00731 00732 SCE_btstart (); 00733 if (vname) 00734 { 00735 SCE_Shader_SearchTypes (SCE_String_GetExt ((char*)vname), type); 00736 00737 srcs1 = SCE_Resource_Load (vname, NULL, NULL); 00738 if (!srcs1) 00739 { 00740 Logger_LogSrc (); 00741 SCE_btend (); 00742 return NULL; 00743 } 00744 00745 /* on vient de charger un fichier contenant les deux codes */ 00746 if (srcs1[0] && srcs1[1]) 00747 pname = NULL; 00748 00749 vsource = srcs1[0]; 00750 psource = srcs1[1]; 00751 ttemp = type[0]; 00752 } 00753 00754 if (pname) 00755 { 00756 SCE_Shader_SearchTypes (SCE_String_GetExt ((char*)pname), type); 00757 00758 srcs2 = SCE_Resource_Load (pname, NULL, NULL); 00759 if (!srcs2) 00760 { 00761 Logger_LogSrc (); 00762 SCE_btend (); 00763 return NULL; 00764 } 00765 00766 /* on vient de charger un fichier contenant les deux codes */ 00767 if (srcs2[0] && srcs2[1]) 00768 vsource = srcs2[0]; 00769 00770 psource = srcs2[1]; 00771 00772 if (ttemp != type[0] && vname) 00773 { 00774 /* le type du pixel shader differe de celui du vertex shader */ 00775 00776 if (SCE_Resource_Free (srcs1)) 00777 { 00778 SCE_free (vsource); 00779 SCE_free (psource); 00780 SCE_free (srcs1); 00781 } 00782 00783 Logger_Log (SCE_INVALID_ARG); 00784 Logger_LogMsg ("you can't load a %s vertex shader with" 00785 " a %s pixel shader", 00786 (ttemp == SCE_GLSL_SHADER) ? "GLSL" : "Cg", 00787 (type[0] == SCE_GLSL_SHADER) ? "GLSL" : "Cg"); 00788 SCE_btend (); 00789 return NULL; 00790 } 00791 } 00792 00793 /* creation du shader */ 00794 shader = SCE_Shader_Create (type[0]); 00795 if (!shader) 00796 { 00797 if (SCE_Resource_Free (srcs1)) 00798 { 00799 SCE_free (vsource); 00800 SCE_free (psource); 00801 SCE_free (srcs1); 00802 } 00803 Logger_LogSrc (); 00804 SCE_btend (); 00805 return NULL; 00806 } 00807 00808 shader->res[0] = srcs1; 00809 shader->res[1] = srcs2; 00810 shader->vs_source = vsource; 00811 shader->ps_source = psource; 00812 00813 SCE_btend (); 00814 return shader; 00815 } 00816 00817 00818 #define SCE_SHADER_BUILDFUNC(bign, add)\ 00819 static int SCE_Shader_Build##bign (SCE_SShader *shader)\ 00820 {\ 00821 SCE_btstart ();\ 00822 if (shader->vs_source)\ 00823 {\ 00824 shader->v = SCE_CCreateShader##bign (SCE_VERTEX_SHADER);\ 00825 if (!shader->v)\ 00826 {\ 00827 Logger_LogSrc ();\ 00828 SCE_btend ();\ 00829 return SCE_ERROR;\ 00830 }\ 00831 SCE_CSetShader##bign##Source (shader->v, shader->vs_source);\ 00832 if (SCE_CBuildShader##bign (shader->v) < 0)\ 00833 {\ 00834 SCE_CDeleteShader##bign (shader->v);\ 00835 Logger_LogSrc ();\ 00836 SCE_btend ();\ 00837 return SCE_ERROR;\ 00838 }\ 00839 }\ 00840 \ 00841 if (shader->ps_source)\ 00842 {\ 00843 shader->p = SCE_CCreateShader##bign (SCE_PIXEL_SHADER);\ 00844 if (!shader->p)\ 00845 {\ 00846 Logger_LogSrc ();\ 00847 SCE_btend ();\ 00848 return SCE_ERROR;\ 00849 }\ 00850 SCE_CSetShader##bign##Source (shader->p, shader->ps_source);\ 00851 if (SCE_CBuildShader##bign (shader->p) < 0)\ 00852 {\ 00853 SCE_CDeleteShader##bign (shader->p);\ 00854 Logger_LogSrc ();\ 00855 SCE_btend ();\ 00856 return SCE_ERROR;\ 00857 }\ 00858 }\ 00859 add\ 00860 SCE_btend ();\ 00861 return SCE_OK;\ 00862 } 00863 00864 #ifdef SCE_USE_CG 00865 SCE_SHADER_BUILDFUNC (CG, ) 00866 #endif 00867 SCE_SHADER_BUILDFUNC 00868 (GLSL, 00869 shader->p_glsl = SCE_CCreateProgram (); 00870 if (!shader->p_glsl) 00871 { 00872 SCE_CDeleteShaderGLSL (shader->v); 00873 SCE_CDeleteShaderGLSL (shader->p); 00874 Logger_LogSrc (); 00875 SCE_btend (); 00876 return SCE_ERROR; 00877 } 00878 if (shader->v) 00879 SCE_CSetProgramShader (shader->p_glsl, shader->v, 1); 00880 if (shader->p) 00881 SCE_CSetProgramShader (shader->p_glsl, shader->p, 1); 00882 if (SCE_CBuildProgram (shader->p_glsl) < 0) 00883 { 00884 SCE_CDeleteProgram (shader->p_glsl); 00885 SCE_CDeleteShaderGLSL (shader->v); 00886 SCE_CDeleteShaderGLSL (shader->p); 00887 Logger_LogSrc (); 00888 SCE_btend (); 00889 return SCE_ERROR; 00890 } 00891 ) 00892 00893 int SCE_Shader_Build (SCE_SShader *shader) 00894 { 00895 SCE_btstart (); 00896 #ifdef SCE_DEBUG 00897 /* si le shader ne contient aucun code source */ 00898 if (!shader->vs_source && !shader->ps_source && 00899 !shader->vs_addsrc && !shader->ps_addsrc) 00900 { 00901 Logger_Log (SCE_INVALID_OPERATION); 00902 Logger_LogMsg ("this shader don't have a source code!"); 00903 SCE_btend (); 00904 return SCE_ERROR; 00905 } 00906 #endif 00907 00908 if (shader->vs_source || shader->vs_addsrc) 00909 { 00910 shader->vs_source = SCE_String_CatDup (shader->vs_addsrc, shader->vs_source); 00911 if (!shader->vs_source) 00912 { 00913 Logger_LogSrc (); 00914 SCE_btend (); 00915 return SCE_ERROR; 00916 } 00917 } 00918 if (shader->ps_source || shader->ps_addsrc) 00919 { 00920 shader->ps_source = SCE_String_CatDup (shader->ps_addsrc, shader->ps_source); 00921 if (!shader->ps_source) 00922 { 00923 Logger_LogSrc (); 00924 SCE_btend (); 00925 return SCE_ERROR; 00926 } 00927 } 00928 00929 if (Build[shader->type] (shader) < 0) 00930 { 00931 Logger_LogSrc (); 00932 SCE_btend (); 00933 return SCE_ERROR; 00934 } 00935 00936 shader->ready = SCE_TRUE; 00937 SCE_btend (); 00938 return SCE_OK; 00939 } 00940 00941 00942 /* revise le 19/10/2007 */ 00943 int SCE_Shader_AddSource (SCE_SShader *shader, int type, char *src) 00944 { 00945 /* taille de la reallocation */ 00946 size_t realen; 00947 int first_alloc = 1; 00948 char *addsrc = NULL; 00949 00950 SCE_btstart (); 00951 if (!src) 00952 { 00953 SCE_btend (); 00954 return SCE_OK; 00955 } 00956 00957 #ifdef SCE_DEBUG 00958 if (type != SCE_PIXEL_SHADER && type != SCE_VERTEX_SHADER && 00959 type != SCE_UNKNOWN_SHADER) 00960 { 00961 Logger_Log (SCE_INVALID_ARG); 00962 SCE_btend (); 00963 return SCE_ERROR; 00964 } 00965 #endif 00966 00967 addsrc = 00968 (type == SCE_PIXEL_SHADER) ? shader->ps_addsrc : shader->vs_addsrc; 00969 00970 /* + 2 car, 1: retour chariot. 2: caractere de fin de chaine */ 00971 realen = strlen(src) + 2; 00972 00973 if (addsrc) 00974 { 00975 first_alloc = 0; 00976 realen += strlen (addsrc); 00977 } 00978 00979 addsrc = SCE_realloc (addsrc, realen); 00980 if (!addsrc) 00981 { 00982 Logger_LogSrc (); 00983 SCE_btend (); 00984 return SCE_ERROR; 00985 } 00986 /* s'il s'agit de la premiere allocation, on initialise le contenu */ 00987 if (first_alloc) 00988 memset (addsrc, '\0', realen); 00989 00990 strcat (addsrc, src); 00991 00992 /* affectation */ 00993 if (type == SCE_PIXEL_SHADER) 00994 shader->ps_addsrc = addsrc; 00995 else 00996 shader->vs_addsrc = addsrc; 00997 00998 SCE_btend (); 00999 return SCE_OK; 01000 } 01001 01002 01003 #ifdef SCE_USE_CG 01004 static int SCE_Shader_GetIndexCG (SCE_SShader *s, int t, const char *n) 01005 { 01006 if (t == SCE_PIXEL_SHADER) 01007 return (int)SCE_CGetShaderCGIndex (s->p, n); 01008 else 01009 return (int)SCE_CGetShaderCGIndex (s->v, n); 01010 } 01011 #endif 01012 static int SCE_Shader_GetIndexGLSL (SCE_SShader *s, int t, const char *n) 01013 { 01014 (void)t; 01015 return SCE_CGetProgramIndex (s->p_glsl, n); 01016 } 01017 01018 int SCE_Shader_GetIndex (SCE_SShader *shader, int type, const char *name) 01019 { 01020 #ifdef SCE_DEBUG 01021 if (!shader || !name) 01022 { 01023 Logger_Log (SCE_INVALID_ARG); 01024 return SCE_SHADER_BAD_INDEX; 01025 } 01026 if (!shader->ready) 01027 { 01028 Logger_Log (SCE_INVALID_OPERATION); 01029 Logger_LogMsg ("you can't use a non-built shader"); 01030 return SCE_SHADER_BAD_INDEX; 01031 } 01032 #endif 01033 01034 return GetIndex[shader->type] (shader, type, name); 01035 } 01036 01037 01038 #ifdef SCE_USE_CG 01039 static int SCE_Shader_GetAttribIndexCG (SCE_SShader *s, const char *n) 01040 { 01041 return 0; /* TODO: undefined... */ 01042 } 01043 #endif 01044 static int SCE_Shader_GetAttribIndexGLSL (SCE_SShader *s, const char *n) 01045 { 01046 return SCE_CGetProgramAttribIndex (s->p_glsl, n); 01047 } 01048 01049 int SCE_Shader_GetAttribIndex (SCE_SShader *shader, const char *name) 01050 { 01051 return GetAttribIndex[shader->type] (shader, name); 01052 } 01053 01054 01055 #ifdef SCE_USE_CG 01056 static void SCE_Shader_ParamCG (int t, const char *n, int v) 01057 { 01058 SCE_CSetShaderCGParam ((CGparameter)SCE_Shader_GetIndexCG (used, t, n), v); 01059 } 01060 #endif 01061 static void SCE_Shader_ParamGLSL (int t, const char *n, int v) 01062 { 01063 SCE_CSetProgramParam (SCE_CGetProgramIndex (used->p_glsl, n), v); 01064 } 01065 void SCE_Shader_Param (int type, const char *name, int val) 01066 { 01067 Param[used->type] (type, name, val); 01068 } 01069 01070 01071 #ifdef SCE_USE_CG 01072 static void SCE_Shader_ParamfCG (int t, const char *n, float v) 01073 { 01074 SCE_CSetShaderCGParamf ((CGparameter)SCE_Shader_GetIndexCG (used, t, n), v); 01075 } 01076 #endif 01077 static void SCE_Shader_ParamfGLSL (int t, const char *n, float v) 01078 { 01079 SCE_CSetProgramParamf (SCE_CGetProgramIndex (used->p_glsl, n), v); 01080 } 01081 void SCE_Shader_Paramf (int type, const char *name, float val) 01082 { 01083 Paramf[used->type] (type, name, val); 01084 } 01085 01086 01087 #define SCE_CG_PARAM_FUNC(n)\ 01088 static void SCE_Shader_Param##n##fvCG (int t, const char *na, size_t s, float *v)\ 01089 {\ 01090 SCE_CSetShaderCGParam##n##fv ((CGparameter)SCE_Shader_GetIndexCG\ 01091 (used, t, na), s, v);\ 01092 } 01093 #define SCE_GLSL_PARAM_FUNC(n)\ 01094 static void SCE_Shader_Param##n##fvGLSL (int t, const char *na,\ 01095 size_t s, float *v)\ 01096 {\ 01097 SCE_CSetProgramParam##n##fv (SCE_CGetProgramIndex (used->p_glsl, na), s, v);\ 01098 }\ 01099 void SCE_Shader_Param##n##fv (int type, const char *name, size_t size, float *val)\ 01100 {\ 01101 Param##n##fv[used->type] (type, name, size, val);\ 01102 } 01103 #ifdef SCE_USE_CG 01104 SCE_CG_PARAM_FUNC(1) 01105 SCE_CG_PARAM_FUNC(2) 01106 SCE_CG_PARAM_FUNC(3) 01107 SCE_CG_PARAM_FUNC(4) 01108 #endif 01109 SCE_GLSL_PARAM_FUNC(1) 01110 SCE_GLSL_PARAM_FUNC(2) 01111 SCE_GLSL_PARAM_FUNC(3) 01112 SCE_GLSL_PARAM_FUNC(4) 01113 #undef SCE_GLSL_PARAM_FUNC 01114 #undef SCE_CG_PARAM_FUNC 01115 01116 01117 #ifdef SCE_USE_CG 01118 static void SCE_Shader_SetParamCG (int i, int v) 01119 { 01120 SCE_CSetShaderCGParam ((CGparameter)i, v); 01121 } 01122 #endif 01123 static void SCE_Shader_SetParamGLSL (int i, int v) 01124 { 01125 SCE_CSetProgramParam (i, v); 01126 } 01127 void SCE_Shader_SetParam (int index, int val) 01128 { 01129 SetParam[used->type] (index, val); 01130 } 01131 01132 01133 #ifdef SCE_USE_CG 01134 static void SCE_Shader_SetParamfCG (int i, float v) 01135 { 01136 SCE_CSetShaderCGParamf ((CGparameter)i, v); 01137 } 01138 #endif 01139 static void SCE_Shader_SetParamfGLSL (int i, float v) 01140 { 01141 SCE_CSetProgramParamf (i, v); 01142 } 01143 void SCE_Shader_SetParamf (int index, float val) 01144 { 01145 SetParamf[used->type] (index, val); 01146 } 01147 01148 01149 #define SCE_CG_SETPARAM_FUNC(n)\ 01150 static void SCE_Shader_SetParam##n##fvCG (int i, size_t s, float *v)\ 01151 {\ 01152 SCE_CSetShaderCGParam##n##fv ((CGparameter)i, s, v);\ 01153 } 01154 #define SCE_GLSL_SETPARAM_FUNC(n)\ 01155 static void SCE_Shader_SetParam##n##fvGLSL (int i, size_t s, float *v)\ 01156 {\ 01157 SCE_CSetProgramParam##n##fv (i, s, v);\ 01158 }\ 01159 void SCE_Shader_SetParam##n##fv (int index, size_t size, float *val)\ 01160 {\ 01161 SetParam##n##fv[used->type] (index, size, val);\ 01162 } 01163 #ifdef SCE_USE_CG 01164 SCE_CG_SETPARAM_FUNC(1) 01165 SCE_CG_SETPARAM_FUNC(2) 01166 SCE_CG_SETPARAM_FUNC(3) 01167 SCE_CG_SETPARAM_FUNC(4) 01168 #endif 01169 SCE_GLSL_SETPARAM_FUNC(1) 01170 SCE_GLSL_SETPARAM_FUNC(2) 01171 SCE_GLSL_SETPARAM_FUNC(3) 01172 SCE_GLSL_SETPARAM_FUNC(4) 01173 #undef SCE_GLSL_SETPARAM_FUNC 01174 #undef SCE_CG_SETPARAM_FUNC 01175 01176 #ifdef SCE_USE_CG 01177 static void SCE_Shader_SetMatrix3CG (int i, SCE_TMatrix4 m) 01178 { 01179 /* TODO: where are Cg API's funcs to manage 3x3 matrices ? */ 01180 /* kick warnings */ 01181 i = 0; m = NULL; 01182 } 01183 #endif 01184 static void SCE_Shader_SetMatrix3GLSL (int i, SCE_TMatrix4 m) 01185 { 01186 SCE_CSetProgramMatrix3 (i, 1, m); /* count forced */ 01187 } 01188 void SCE_Shader_SetMatrix3 (int index, SCE_TMatrix4 m) 01189 { 01190 SetMatrix3[used->type] (index, m); 01191 } 01192 01193 #ifdef SCE_USE_CG 01194 static void SCE_Shader_SetMatrix4CG (int i, SCE_TMatrix4 m) 01195 { 01196 SCE_CSetShaderCGMatrix ((CGparameter)i, m); 01197 } 01198 #endif 01199 static void SCE_Shader_SetMatrix4GLSL (int i, SCE_TMatrix4 m) 01200 { 01201 SCE_CSetProgramMatrix4 (i, 1, m); /* count forced */ 01202 } 01203 void SCE_Shader_SetMatrix4 (int index, SCE_TMatrix4 m) 01204 { 01205 SetMatrix4[used->type] (index, m); 01206 } 01207 01219 int SCE_Shader_AddParamv (SCE_SShader *shader, int type, const char *n, void *p) 01220 { 01221 SCE_SShaderParam *param = NULL; 01222 SCE_btstart (); 01223 if (!(param = SCE_malloc (sizeof *param))) 01224 { 01225 Logger_LogSrc (); 01226 SCE_btend (); 01227 return SCE_ERROR; 01228 } 01229 if (SCE_List_AppendNewl (shader->params_i, param) < 0) 01230 { 01231 SCE_free (param); 01232 Logger_LogSrc (); 01233 SCE_btend (); 01234 return SCE_ERROR; 01235 } 01236 SCE_Shader_InitParam (param); 01237 param->param = p; 01238 /* necessite que le shader ait deja ete construit */ 01239 param->index = SCE_Shader_GetIndex (shader, type, n); 01240 SCE_btend (); 01241 return SCE_OK; 01242 } 01258 int SCE_Shader_AddParamfv (SCE_SShader *shader, int type, const char *n, 01259 int num, int size, void *p) 01260 { 01261 SCE_SShaderParam *param = NULL; 01262 SCE_btstart (); 01263 if (!(param = SCE_malloc (sizeof *param))) 01264 { 01265 Logger_LogSrc (); 01266 SCE_btend (); 01267 return SCE_ERROR; 01268 } 01269 if (SCE_List_AppendNewl (shader->params_f, param) < 0) 01270 { 01271 SCE_free (param); 01272 Logger_LogSrc (); 01273 SCE_btend (); 01274 return SCE_ERROR; 01275 } 01276 SCE_Shader_InitParam (param); 01277 param->param = p; 01278 switch (num) 01279 { 01280 #define SCE_SHDCASE(n) case n: param->setfv = SCE_Shader_SetParam##n##fv; break; 01281 SCE_SHDCASE (1) 01282 SCE_SHDCASE (2) 01283 SCE_SHDCASE (3) 01284 SCE_SHDCASE (4) 01285 #undef SCE_SHDCASE 01286 } 01287 param->size = size; 01288 /* necessite que le shader ait deja ete construit */ 01289 param->index = SCE_Shader_GetIndex (shader, type, n); 01290 /* NOTE: et la on ne verifie pas index... ? bof ca fait chier */ 01291 SCE_btend (); 01292 return SCE_OK; 01293 } 01294 /* ajoute le 23/09/2008 */ 01306 int SCE_Shader_AddMatrix (SCE_SShader *shader, int type, const char *n, 01307 int size, void *p) 01308 { 01309 SCE_SShaderParam *param = NULL; 01310 SCE_btstart (); 01311 if (!(param = SCE_malloc (sizeof *param))) 01312 { 01313 Logger_LogSrc (); 01314 SCE_btend (); 01315 return SCE_ERROR; 01316 } 01317 if (SCE_List_AppendNewl (shader->params_m, param) < 0) 01318 { 01319 SCE_free (param); 01320 Logger_LogSrc (); 01321 SCE_btend (); 01322 return SCE_ERROR; 01323 } 01324 SCE_Shader_InitParam (param); 01325 param->param = p; 01326 /* necessite que le shader ait deja ete construit */ 01327 param->index = SCE_Shader_GetIndex (shader, type, n); 01328 if (size == 3) 01329 param->setm = SCE_Shader_SetMatrix3; 01330 else 01331 param->setm = SCE_Shader_SetMatrix4; 01332 SCE_btend (); 01333 return SCE_OK; 01334 } 01335 01336 01337 /* ajoute le 14/06/2007 */ 01338 void SCE_Shader_Active (int enabled) 01339 { 01340 sce_shd_enabled = enabled; 01341 } 01342 /* ajoute le 14/06/2007 */ 01343 void SCE_Shader_Enable (void) 01344 { 01345 sce_shd_enabled = SCE_TRUE; 01346 } 01347 /* ajoute le 14/06/2007 */ 01348 void SCE_Shader_Disable (void) 01349 { 01350 sce_shd_enabled = SCE_FALSE; 01351 } 01352 01353 /* ajoute le 05/05/2008 */ 01354 /* revise le 23/09/2008 */ 01355 static void SCE_Shader_SetParams (SCE_SShader *shader) 01356 { 01357 SCE_SListIterator *i = NULL; 01358 SCE_SShaderParam *p = NULL; 01359 SCE_List_ForEach (i, shader->params_i) 01360 { 01361 p = SCE_List_GetData (i); 01362 SCE_Shader_SetParam (p->index, *((int*)p->param)); 01363 } 01364 SCE_List_ForEach (i, shader->params_f) 01365 { 01366 p = SCE_List_GetData (i); 01367 p->setfv (p->index, p->size, p->param); 01368 } 01369 SCE_List_ForEach (i, shader->params_m) 01370 { 01371 p = SCE_List_GetData (i); 01372 p->setm (p->index, p->param); 01373 } 01374 } 01375 01376 #ifdef SCE_USE_CG 01377 static void SCE_Shader_UseCG (SCE_SShader *shader) 01378 { 01379 if (!sce_shd_enabled) 01380 return; 01381 else if (shader) 01382 { 01383 if (shader->v) 01384 SCE_CUseShaderCG (shader->v); 01385 if (shader->p) 01386 SCE_CUseShaderCG (shader->p); 01387 } 01388 else 01389 SCE_CUseShaderCG (NULL); 01390 } 01391 #endif 01392 /* revise le 12/01/2008 */ 01393 static void SCE_Shader_UseGLSL (SCE_SShader *shader) 01394 { 01395 if (!sce_shd_enabled) 01396 return; 01397 else if (shader) 01398 SCE_CUseProgram (shader->p_glsl); 01399 else 01400 SCE_CUseProgram (NULL); 01401 } 01402 /* revise le 28/11/2008 */ 01403 void SCE_Shader_Use (SCE_SShader *shader) 01404 { 01405 static void *pixelshader = NULL; 01406 static int vs_binded = SCE_FALSE; 01407 01408 if (!shader) 01409 { 01410 if (used) 01411 { 01412 Use[used->type] (NULL); 01413 Use[used->type] (NULL); 01414 used = NULL; 01415 } 01416 01417 pixelshader = NULL; 01418 vs_binded = SCE_FALSE; 01419 } 01420 else if (shader != used) 01421 { 01422 if (used && used->type != shader->type) 01423 { 01424 Use[used->type] (NULL); /* pixel shader */ 01425 Use[used->type] (NULL); /* vertex shader */ 01426 vs_binded = SCE_FALSE; 01427 pixelshader = NULL; 01428 } 01429 01430 if (shader->type == SCE_GLSL_SHADER) 01431 Use[shader->type] (shader); 01432 else 01433 { 01434 /* analyse du type du shader */ 01435 if (!shader->v) 01436 { 01437 /* aucun vertex shader n'est present, on verifie s'il y en 01438 a deja un d'actif, si oui, on active le pixel shader 01439 du shader envoye, sinon, on retient l'adresse du pixel shader 01440 pour une activation ulterieur */ 01441 if (vs_binded) 01442 Use[shader->type] (shader); 01443 else 01444 pixelshader = shader->p; 01445 } 01446 else 01447 { 01448 void *tmp = shader->p; 01449 01450 if (pixelshader && !tmp) 01451 { 01452 shader->p = pixelshader; 01453 pixelshader = NULL; 01454 } 01455 01456 /* un vertex shader est present, on l'active */ 01457 Use[shader->type] (shader); 01458 /* on remet son pixel shader au shader */ 01459 shader->p = tmp; 01460 /* un vertex shader est binde */ 01461 vs_binded = SCE_TRUE; 01462 } 01463 } 01464 /* prendre soin d'affecter used avant d'appeler SetParams() */ 01465 used = shader; 01466 /* envoie des parametres automatiques */ 01467 SCE_Shader_SetParams (shader); 01468 } 01469 }
Generated on Sat Feb 14 02:57:19 2009 for SCEngine 0.0.9 by Doxygen 1.5.6