1 ////////////////////////////////////////////////////////////////////// 2 // 3 // Pixie 4 // 5 // Copyright � 1999 - 2003, Okan Arikan 6 // 7 // Contact: okan@cs.utexas.edu 8 // 9 // This library is free software; you can redistribute it and/or 10 // modify it under the terms of the GNU Lesser General Public 11 // License as published by the Free Software Foundation; either 12 // version 2.1 of the License, or (at your option) any later version. 13 // 14 // This library is distributed in the hope that it will be useful, 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 // Lesser General Public License for more details. 18 // 19 // You should have received a copy of the GNU Lesser General Public 20 // License along with this library; if not, write to the Free Software 21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 // 23 /////////////////////////////////////////////////////////////////////// 24 /////////////////////////////////////////////////////////////////////// 25 // 26 // File : shaderFunctions.h 27 // Classes : - 28 // Description : Shader language specific buint in functions 29 // 30 //////////////////////////////////////////////////////////////////////// 31 32 33 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 34 // debug "o=v" 35 #define DEBUGVEXPR debugFunction((float *) res); 36 37 38 DEFFUNC(DebugFloat ,"debug" ,"o=f", FUN1EXPR_PRE, DEBUGVEXPR, FUN1EXPR_UPDATE(1), NULL_EXPR, 0) 39 DEFLINKFUNC(DebugP ,"debug" ,"o=p", 0) 40 DEFLINKFUNC(DebugC ,"debug" ,"o=c", 0) 41 DEFLINKFUNC(DebugN ,"debug" ,"o=n", 0) 42 DEFFUNC(DebugVector ,"debug" ,"o=v", FUN1EXPR_PRE, DEBUGVEXPR, FUN1EXPR_UPDATE(3), NULL_EXPR, 0) 43 44 45 46 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 47 // faceforward "v=vv" 48 #define FACEFORWARDEXPR_PRE const float *Ng = varying[VARIABLE_NG]; \ 49 FUN3EXPR_PRE 50 51 #define FACEFORWARDEXPR if (dotvv(op1,Ng) > 0) { \ 52 if (dotvv(op2,Ng) > 0) \ 53 mulvf(res,op1,-1); \ 54 else \ 55 movvv(res,op1); \ 56 } else { \ 57 if (dotvv(op2,Ng) > 0) \ 58 movvv(res,op1); \ 59 else \ 60 mulvf(res,op1,-1); \ 61 } 62 63 64 #define FACEFORWARDEXPR_UPDATE FUN3EXPR_UPDATE(3,3,3); \ 65 Ng += 3; 66 67 DEFFUNC(FaceForward ,"faceforward" ,"v=vv" ,FACEFORWARDEXPR_PRE,FACEFORWARDEXPR,FACEFORWARDEXPR_UPDATE,NULL_EXPR,PARAMETER_NG) 68 69 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 70 // faceforward "v=vvv" 71 #define FACEFORWARD2EXPR if (dotvv(op1,op3) > 0) { \ 72 if (dotvv(op2,op3) > 0) \ 73 mulvf(res,op1,-1); \ 74 else \ 75 movvv(res,op1); \ 76 } else { \ 77 if (dotvv(op2,op3) > 0) \ 78 movvv(res,op1); \ 79 else \ 80 mulvf(res,op1,-1); \ 81 } 82 83 84 DEFFUNC(FaceForward3 ,"faceforward" ,"v=vvv",FUN4EXPR_PRE,FACEFORWARD2EXPR,FUN4EXPR_UPDATE(3,3,3,3),NULL_EXPR,0) 85 86 87 88 89 // The following macros are used to evaluate u and v derivatives using central differencing 90 91 92 93 94 95 96 97 98 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 99 // du "f=f" 100 #ifndef INIT_SHADING 101 #define DUFEXPR_PRE FUN2EXPR_PRE \ 102 duFloat(res,op); 103 #else 104 #undef DUFEXPR_PRE 105 #define DUFEXPR_PRE 106 #endif 107 108 DEFFUNC(Duf ,"Du" ,"f=f" ,DUFEXPR_PRE,NULL_EXPR,NULL_EXPR,NULL_EXPR,PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 109 110 #undef DUVEXPR_PRE 111 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 112 // du "v=v" 113 #ifndef INIT_SHADING 114 #define DUVEXPR_PRE FUN2EXPR_PRE \ 115 duVector(res,op); 116 117 #else 118 #undef DUVEXPR_PRE 119 #define DUVEXPR_PRE 120 #endif 121 122 DEFLINKFUNC(Duv1 ,"Du" ,"v=c", PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 123 DEFLINKFUNC(Duv2 ,"Du" ,"v=p", PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 124 DEFLINKFUNC(Duv3 ,"Du" ,"v=n", PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 125 DEFFUNC(Duv ,"Du" ,"v=v" ,DUVEXPR_PRE,NULL_EXPR,NULL_EXPR,NULL_EXPR,PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 126 127 #undef DUVEXPR_PRE 128 129 130 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 131 // dv "f=f" 132 #ifndef INIT_SHADING 133 #define DVFEXPR_PRE FUN2EXPR_PRE \ 134 dvFloat(res,op); 135 #else 136 #undef DVFEXPR_PRE 137 #define DVFEXPR_PRE 138 #endif 139 140 DEFFUNC(Dvf ,"Dv" ,"f=f" ,DVFEXPR_PRE,NULL_EXPR,NULL_EXPR,NULL_EXPR,PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 141 142 #undef DVFEXPR_PRE 143 144 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 145 // dv "v=v" 146 #ifndef INIT_SHADING 147 #define DVVEXPR_PRE FUN2EXPR_PRE \ 148 dvVector(res,op); 149 #else 150 #undef DVVEXPR_PRE 151 #define DVVEXPR_PRE 152 #endif 153 154 155 DEFLINKFUNC(Dvv1 ,"Dv" ,"v=c", PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 156 DEFLINKFUNC(Dvv2 ,"Dv" ,"v=p", PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 157 DEFLINKFUNC(Dvv3 ,"Dv" ,"v=n", PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 158 DEFFUNC(Dvv ,"Dv" ,"v=v" ,DVVEXPR_PRE,NULL_EXPR,NULL_EXPR,NULL_EXPR,PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 159 160 #undef DVVEXPR_PRE 161 162 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 163 // deriv "f=ff" 164 #ifndef INIT_SHADING 165 #define DERIVFEXPR_PRE FUN3EXPR_PRE \ 166 float *duTop = (float *) ralloc(numVertices*sizeof(float)*4,threadMemory); \ 167 float *duBottom = duTop + numVertices; \ 168 float *dvTop = duBottom + numVertices; \ 169 float *dvBottom = dvTop + numVertices; \ 170 duFloat(duTop, op1); \ 171 duFloat(duBottom, op2); \ 172 dvFloat(dvTop, op1); \ 173 dvFloat(dvBottom, op2); 174 175 #define DERIVFEXPR if (duBottom[0] != 0) { \ 176 res[0] = duTop[0] / duBottom[0]; \ 177 } else { \ 178 res[0] = 0; \ 179 } \ 180 \ 181 if (dvBottom[0] != 0) { \ 182 res[0] += dvTop[0] / dvBottom[0]; \ 183 } 184 185 186 187 #define DERIVFEXPR_UPDATE ++res; \ 188 ++duTop; \ 189 ++duBottom; \ 190 ++dvTop; \ 191 ++dvBottom; 192 193 #else 194 195 #define DERIVFEXPR_PRE 196 #define DERIVFEXPR 197 #define DERIVFEXPR_UPDATE 198 199 #endif 200 201 DEFFUNC(Derivf ,"Deriv" ,"f=ff" ,DERIVFEXPR_PRE,DERIVFEXPR,DERIVFEXPR_UPDATE,NULL_EXPR,PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 202 203 #undef DERIVFEXPR_PRE 204 #undef DERIVFEXPR 205 #undef DERIVFEXPR_UPDATE 206 207 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 208 // deriv "v=vf" 209 #ifndef INIT_SHADING 210 #define DERIVVEXPR_PRE FUN3EXPR_PRE \ 211 float *duTop = (float *) ralloc(numVertices*sizeof(float)*8,threadMemory); \ 212 float *duBottom = duTop + numVertices*3; \ 213 float *dvTop = duBottom + numVertices; \ 214 float *dvBottom = dvTop + numVertices*3; \ 215 duVector(duTop, op1); \ 216 duFloat(duBottom, op2); \ 217 dvVector(dvTop, op1); \ 218 dvFloat(dvBottom, op2); 219 220 #define DERIVVEXPR if (duBottom[0] != 0) { \ 221 res[0] = (float) ((double)duTop[0] / (double)duBottom[0]); \ 222 res[1] = (float) ((double)duTop[1] / (double)duBottom[0]); \ 223 res[2] = (float) ((double)duTop[2] / (double)duBottom[0]); \ 224 } else { \ 225 res[0] = 0; \ 226 res[1] = 0; \ 227 res[2] = 0; \ 228 } \ 229 \ 230 if (dvBottom[0] != 0) { \ 231 res[0] += (float) ((double)dvTop[0] / (double)dvBottom[0]); \ 232 res[1] += (float) ((double)dvTop[1] / (double)dvBottom[0]); \ 233 res[2] += (float) ((double)dvTop[2] / (double)dvBottom[0]); \ 234 } 235 236 237 #define DERIVVEXPR_UPDATE res += 3; \ 238 duTop += 3; \ 239 dvTop += 3; \ 240 ++duBottom; \ 241 ++dvBottom; 242 243 #else 244 #define DERIVVEXPR_PRE 245 #define DERIVVEXPR 246 #define DERIVVEXPR_UPDATE 247 #endif 248 249 DEFLINKFUNC(Derivv1 ,"Deriv" ,"v=cf", PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 250 DEFLINKFUNC(Derivv2 ,"Deriv" ,"v=pf", PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 251 DEFLINKFUNC(Derivv3 ,"Deriv" ,"v=nf", PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 252 DEFFUNC(Derivv ,"Deriv" ,"v=vf" , DERIVVEXPR_PRE,DERIVVEXPR,DERIVVEXPR_UPDATE,NULL_EXPR,PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 253 254 #undef DERIVVEXPR_PRE 255 #undef DERIVVEXPR 256 #undef DERIVVEXPR_UPDATE 257 258 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 259 // area "f=p" 260 #ifndef INIT_SHADING 261 #define AREAEXPR_PRE FUN2EXPR_PRE \ 262 float *du = varying[VARIABLE_DU]; \ 263 float *dv = varying[VARIABLE_DV]; \ 264 float *dPdu = (float *) ralloc(numVertices*6*sizeof(float),threadMemory); \ 265 float *dPdv = dPdu + numVertices*3; \ 266 vector tmp; \ 267 duVector(dPdu,op); \ 268 dvVector(dPdv,op); 269 270 271 #define AREAEXPR mulvf(dPdu,du[0]); \ 272 mulvf(dPdv,dv[0]); \ 273 crossvv(tmp,dPdu,dPdv); \ 274 *res = lengthv(tmp); \ 275 assert(*res >= 0); 276 277 #define AREAEXPR_UPDATE ++res; \ 278 dPdu += 3; \ 279 dPdv += 3; \ 280 ++du; \ 281 ++dv; 282 #else 283 #define AREAEXPR_PRE 284 #define AREAEXPR 285 #define AREAEXPR_UPDATE 286 #endif 287 288 // Totally ignore the measure argument for area 289 DEFFUNC(Area ,"area" ,"f=p", AREAEXPR_PRE,AREAEXPR,AREAEXPR_UPDATE,NULL_EXPR,PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 290 291 #undef AREAEXPR_PRE 292 #undef AREAEXPR 293 #undef AREAEXPR_UPDATE 294 295 296 297 298 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 299 // area "f=pS" 300 #ifndef INIT_SHADING 301 #define AREAEXPR_PRE FUN2EXPR_PRE \ 302 float *du; \ 303 float *dv; \ 304 float *dPdu; \ 305 float *dPdv; \ 306 vector tmp; \ 307 const char **measure; \ 308 int dicingMeasure; \ 309 operand(2,measure,const char **); \ 310 if (strcmp(*measure,"shading") == 0) { \ 311 du = varying[VARIABLE_DU]; \ 312 dv = varying[VARIABLE_DV]; \ 313 dPdu = (float *) ralloc(numVertices*6*sizeof(float),threadMemory); \ 314 dPdv = dPdu + numVertices*3; \ 315 duVector(dPdu,op); \ 316 dvVector(dPdv,op); \ 317 dicingMeasure = FALSE; \ 318 } else if (strcmp(*measure,"dicing") == 0) { \ 319 du = rayDiff(op); \ 320 dicingMeasure = TRUE; \ 321 } else { \ 322 error(CODE_BADTOKEN,"Unrecognized area measure: \"%s\". Assuming \"dicing\"\n",*measure); \ 323 du = rayDiff(op); \ 324 dicingMeasure = TRUE; \ 325 } 326 327 328 #define AREAEXPR if (dicingMeasure) { \ 329 assert(*du >= 0); \ 330 *res = (*du)*(*du); \ 331 } else { \ 332 mulvf(dPdu,du[0]); \ 333 mulvf(dPdv,dv[0]); \ 334 crossvv(tmp,dPdu,dPdv); \ 335 *res = lengthv(tmp); \ 336 } 337 338 #define AREAEXPR_UPDATE ++res; \ 339 ++du; \ 340 if (dicingMeasure == FALSE) { \ 341 dPdu += 3; \ 342 dPdv += 3; \ 343 ++dv; \ 344 } 345 #else 346 #define AREAEXPR_PRE 347 #define AREAEXPR 348 #define AREAEXPR_UPDATE 349 #endif 350 351 // Totally ignore the measure argument for area 352 DEFFUNC(AreaS ,"area" ,"f=pS", AREAEXPR_PRE,AREAEXPR,AREAEXPR_UPDATE,NULL_EXPR,PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 353 354 #undef AREAEXPR_PRE 355 #undef AREAEXPR 356 #undef AREAEXPR_UPDATE 357 358 359 360 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 361 // calculatenormal "p=p" 362 #ifndef INIT_SHADING 363 364 #define CALCULATENORMALEXPR_PRE FUN2EXPR_PRE \ 365 float *dPdu = (float *) ralloc(numVertices*6*sizeof(float),threadMemory); \ 366 float *dPdv = dPdu + numVertices*3; \ 367 const float mult = ((currentShadingState->currentObject->attributes->flags & ATTRIBUTES_FLAGS_INSIDE) ? (float) -1 : (float) 1); \ 368 duVector(dPdu,op); \ 369 dvVector(dPdv,op); 370 371 #define CALCULATENORMALEXPR crossvv(res,dPdu,dPdv); \ 372 mulvf(res,mult); 373 374 #define CALCULATENORMALEXPR_UPDATE res += 3; \ 375 dPdu += 3; \ 376 dPdv += 3; 377 #else 378 #define CALCULATENORMALEXPR_PRE 379 #define CALCULATENORMALEXPR 380 #define CALCULATENORMALEXPR_UPDATE 381 #endif 382 383 DEFFUNC(CalculateNormal ,"calculatenormal" ,"p=p" ,CALCULATENORMALEXPR_PRE,CALCULATENORMALEXPR,CALCULATENORMALEXPR_UPDATE,NULL_EXPR,PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 384 385 #undef CALCULATENORMALEXPR_PRE 386 #undef CALCULATENORMALEXPR 387 #undef CALCULATENORMALEXPR_UPDATE 388 389 390 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 391 // noise "f=f" 392 #define NOISE1D1EXPR *res = FUNCTION(*op); 393 #define NOISE1D2EXPR *res = FUNCTION(*op1,*op2); 394 #define NOISE1D3EXPR *res = FUNCTION(op); 395 #define NOISE1D4EXPR *res = FUNCTION(op1,*op2); 396 397 #define NOISE3D1EXPR FUNCTION(res,*op); 398 #define NOISE3D2EXPR FUNCTION(res,*op1,*op2); 399 #define NOISE3D3EXPR FUNCTION(res,op); 400 #define NOISE3D4EXPR FUNCTION(res,op1,*op2); 401 402 #define FUNCTION noiseFloat 403 DEFFUNC(Noise1D1 ,"noise" ,"f=f" ,FUN2EXPR_PRE,NOISE1D1EXPR,FUN2EXPR_UPDATE(1,1),NULL_EXPR,0) 404 DEFFUNC(Noise1D2 ,"noise" ,"f=ff" ,FUN3EXPR_PRE,NOISE1D2EXPR,FUN3EXPR_UPDATE(1,1,1),NULL_EXPR,0) 405 DEFFUNC(Noise1D3 ,"noise" ,"f=p" ,FUN2EXPR_PRE,NOISE1D3EXPR,FUN2EXPR_UPDATE(1,3),NULL_EXPR,0) 406 DEFFUNC(Noise1D4 ,"noise" ,"f=pf" ,FUN3EXPR_PRE,NOISE1D4EXPR,FUN3EXPR_UPDATE(1,3,1),NULL_EXPR,0) 407 #undef FUNCTION 408 409 #define FUNCTION noiseVector 410 DEFLINKFUNC(Noise1Dv1 ,"noise" ,"c=f", 0) 411 DEFLINKFUNC(Noise1Dv2 ,"noise" ,"p=f", 0) 412 DEFLINKFUNC(Noise1Dv3 ,"noise" ,"n=f", 0) 413 DEFFUNC(Noise3D1 ,"noise" ,"v=f" ,FUN2EXPR_PRE,NOISE3D1EXPR,FUN2EXPR_UPDATE(3,1),NULL_EXPR,0) 414 DEFLINKFUNC(Noise2Dv1 ,"noise" ,"c=ff", 0) 415 DEFLINKFUNC(Noise2Dv2 ,"noise" ,"p=ff", 0) 416 DEFLINKFUNC(Noise2Dv3 ,"noise" ,"n=ff", 0) 417 DEFFUNC(Noise3D2 ,"noise" ,"v=ff" ,FUN3EXPR_PRE,NOISE3D2EXPR,FUN3EXPR_UPDATE(3,1,1),NULL_EXPR,0) 418 DEFLINKFUNC(Noise3Dv1 ,"noise" ,"c=p", 0) 419 DEFLINKFUNC(Noise3Dv2 ,"noise" ,"p=p", 0) 420 DEFLINKFUNC(Noise3Dv3 ,"noise" ,"n=p", 0) 421 DEFFUNC(Noise3D3 ,"noise" ,"v=p" ,FUN2EXPR_PRE,NOISE3D3EXPR,FUN2EXPR_UPDATE(3,3),NULL_EXPR,0) 422 DEFLINKFUNC(Noise4Dv1 ,"noise" ,"c=pf", 0) 423 DEFLINKFUNC(Noise4Dv2 ,"noise" ,"p=pf", 0) 424 DEFLINKFUNC(Noise4Dv3 ,"noise" ,"n=pf", 0) 425 DEFFUNC(Noise3D4 ,"noise" ,"v=pf" ,FUN3EXPR_PRE,NOISE3D4EXPR,FUN3EXPR_UPDATE(3,3,1),NULL_EXPR,0) 426 #undef FUNCTION 427 428 #define FUNCTION cellNoiseFloat 429 DEFFUNC(CellNoise1D1 ,"cellnoise" ,"f=f" ,FUN2EXPR_PRE,NOISE1D1EXPR,FUN2EXPR_UPDATE(1,1),NULL_EXPR,0) 430 DEFFUNC(CellNoise1D2 ,"cellnoise" ,"f=ff" ,FUN3EXPR_PRE,NOISE1D2EXPR,FUN3EXPR_UPDATE(1,1,1),NULL_EXPR,0) 431 DEFFUNC(CellNoise1D3 ,"cellnoise" ,"f=p" ,FUN2EXPR_PRE,NOISE1D3EXPR,FUN2EXPR_UPDATE(1,3),NULL_EXPR,0) 432 DEFFUNC(CellNoise1D4 ,"cellnoise" ,"f=pf" ,FUN3EXPR_PRE,NOISE1D4EXPR,FUN3EXPR_UPDATE(1,3,1),NULL_EXPR,0) 433 #undef FUNCTION 434 435 #define FUNCTION cellNoiseVector 436 DEFLINKFUNC(CellNoise1Dv1 ,"cellnoise" ,"c=f", 0) 437 DEFLINKFUNC(CellNoise1Dv2 ,"cellnoise" ,"p=f", 0) 438 DEFLINKFUNC(CellNoise1Dv3 ,"cellnoise" ,"n=f", 0) 439 DEFFUNC(CellNoise3D1 ,"cellnoise" ,"v=f" ,FUN2EXPR_PRE,NOISE3D1EXPR,FUN2EXPR_UPDATE(3,1),NULL_EXPR,0) 440 DEFLINKFUNC(CellNoise2Dv1 ,"cellnoise" ,"c=ff", 0) 441 DEFLINKFUNC(CellNoise2Dv2 ,"cellnoise" ,"p=ff", 0) 442 DEFLINKFUNC(CellNoise2Dv3 ,"cellnoise" ,"n=ff", 0) 443 DEFFUNC(CellNoise3D2 ,"cellnoise" ,"v=ff" ,FUN3EXPR_PRE,NOISE3D2EXPR,FUN3EXPR_UPDATE(3,1,1),NULL_EXPR,0) 444 DEFLINKFUNC(CellNoise3Dv1 ,"cellnoise" ,"c=p", 0) 445 DEFLINKFUNC(CellNoise3Dv2 ,"cellnoise" ,"p=p", 0) 446 DEFLINKFUNC(CellNoise3Dv3 ,"cellnoise" ,"n=p", 0) 447 DEFFUNC(CellNoise3D3 ,"cellnoise" ,"v=p" ,FUN2EXPR_PRE,NOISE3D3EXPR,FUN2EXPR_UPDATE(3,3),NULL_EXPR,0) 448 DEFLINKFUNC(CellNoise4Dv1 ,"cellnoise" ,"c=pf", 0) 449 DEFLINKFUNC(CellNoise4Dv2 ,"cellnoise" ,"p=pf", 0) 450 DEFLINKFUNC(CellNoise4Dv3 ,"cellnoise" ,"n=pf", 0) 451 DEFFUNC(CellNoise3D4 ,"cellnoise" ,"v=pf" ,FUN3EXPR_PRE,NOISE3D4EXPR,FUN3EXPR_UPDATE(3,3,1),NULL_EXPR,0) 452 #undef FUNCTION 453 454 455 #define PNOISE1D1EXPR *res = FUNCTION(*op1,*op2); 456 #define PNOISE1D2EXPR *res = FUNCTION(*op1,*op2,*op3,*op4); 457 #define PNOISE1D3EXPR *res = FUNCTION(op1,op2); 458 #define PNOISE1D4EXPR *res = FUNCTION(op1,*op2,op3,*op4); 459 460 #define PNOISE3D1EXPR FUNCTION(res,*op1,*op2); 461 #define PNOISE3D2EXPR FUNCTION(res,*op1,*op2,*op3,*op4); 462 #define PNOISE3D3EXPR FUNCTION(res,op1,op2); 463 #define PNOISE3D4EXPR FUNCTION(res,op1,*op2,op3,*op4); 464 465 #define FUNCTION pnoiseFloat 466 DEFFUNC(PNoise1D1 ,"pnoise" ,"f=ff" ,FUN3EXPR_PRE,PNOISE1D1EXPR,FUN3EXPR_UPDATE(1,1,1),NULL_EXPR,0) 467 DEFFUNC(PNoise1D2 ,"pnoise" ,"f=ffff" ,FUN5EXPR_PRE,PNOISE1D2EXPR,FUN5EXPR_UPDATE(1,1,1,1,1),NULL_EXPR,0) 468 DEFFUNC(PNoise1D3 ,"pnoise" ,"f=pp" ,FUN3EXPR_PRE,PNOISE1D3EXPR,FUN3EXPR_UPDATE(1,3,3),NULL_EXPR,0) 469 DEFFUNC(PNoise1D4 ,"pnoise" ,"f=pfpf" ,FUN5EXPR_PRE,PNOISE1D4EXPR,FUN5EXPR_UPDATE(1,3,1,3,1),NULL_EXPR,0) 470 #undef FUNCTION 471 472 #define FUNCTION pnoiseVector 473 DEFLINKFUNC(PNoise1Dv1 ,"pnoise" ,"c=ff", 0) 474 DEFLINKFUNC(PNoise1Dv2 ,"pnoise" ,"p=ff", 0) 475 DEFLINKFUNC(PNoise1Dv3 ,"pnoise" ,"n=ff", 0) 476 DEFFUNC(PNoise3D1 ,"pnoise" ,"v=ff" , FUN3EXPR_PRE,PNOISE3D1EXPR,FUN3EXPR_UPDATE(3,1,1),NULL_EXPR,0) 477 DEFLINKFUNC(PNoise2Dv1 ,"pnoise" ,"c=ffff", 0) 478 DEFLINKFUNC(PNoise2Dv2 ,"pnoise" ,"p=ffff", 0) 479 DEFLINKFUNC(PNoise2Dv3 ,"pnoise" ,"n=ffff", 0) 480 DEFFUNC(PNoise3D2 ,"pnoise" ,"v=ffff", FUN5EXPR_PRE,PNOISE3D2EXPR,FUN5EXPR_UPDATE(3,1,1,1,1),NULL_EXPR,0) 481 DEFLINKFUNC(PNoise3Dv1 ,"pnoise" ,"c=pp", 0) 482 DEFLINKFUNC(PNoise3Dv2 ,"pnoise" ,"p=pp", 0) 483 DEFLINKFUNC(PNoise3Dv3 ,"pnoise" ,"n=pp", 0) 484 DEFFUNC(PNoise3D3 ,"pnoise" ,"v=pp" , FUN3EXPR_PRE,PNOISE3D3EXPR,FUN3EXPR_UPDATE(3,3,3),NULL_EXPR,0) 485 DEFLINKFUNC(PNoise4Dv1 ,"pnoise" ,"c=pfpf", 0) 486 DEFLINKFUNC(PNoise4Dv2 ,"pnoise" ,"p=pfpf", 0) 487 DEFLINKFUNC(PNoise4Dv3 ,"pnoise" ,"n=pfpf", 0) 488 DEFFUNC(PNoise3D4 ,"pnoise" ,"v=pfpf", FUN5EXPR_PRE,PNOISE3D4EXPR,FUN5EXPR_UPDATE(3,3,1,3,1),NULL_EXPR,0) 489 #undef FUNCTION 490 491 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 492 // ctransform "c=Sc" 493 #define CTRANSFORMEXPR_PRE const float *from,*to; \ 494 float *res; \ 495 const char **op1; \ 496 const float *op2; \ 497 operand(0,res,float *); \ 498 operand(1,op1,const char **); \ 499 operand(2,op2,const float *); \ 500 ECoordinateSystem cSystem; \ 501 findCoordinateSystem(*op1,from,to,cSystem); 502 503 #define CTRANSFORMEXPR convertColorTo(res,op2,cSystem); 504 505 DEFFUNC(CTransform ,"ctransform" ,"c=Sc" ,CTRANSFORMEXPR_PRE,CTRANSFORMEXPR,FUN3EXPR_UPDATE(3,0,3),NULL_EXPR,0) 506 507 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 508 // ctransform "c=SSc" 509 #define CTRANSFORMSEXPR_PRE const float *from,*to; \ 510 vector vtmp; \ 511 ECoordinateSystem cSystemFrom,cSystemTo; \ 512 float *res; \ 513 const char **op1; \ 514 const char **op2; \ 515 const float *op3; \ 516 operand(0,res,float *); \ 517 operand(1,op1,const char **); \ 518 operand(2,op2,const char **); \ 519 operand(3,op3,const float *); \ 520 findCoordinateSystem(*op1,from,to,cSystemFrom); \ 521 findCoordinateSystem(*op2,from,to,cSystemTo); 522 523 #define CTRANSFORMSEXPR convertColorFrom(vtmp,op3,cSystemFrom); \ 524 convertColorTo(res,vtmp,cSystemTo); 525 526 527 DEFFUNC(CTransforms ,"ctransform" ,"c=SSc" ,CTRANSFORMSEXPR_PRE,CTRANSFORMSEXPR,FUN4EXPR_UPDATE(3,0,0,3),NULL_EXPR,0) 528 529 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 530 // transform "p=Sp 531 #define TRANSFORM1EXPR_PRE ECoordinateSystem cSystem; \ 532 const float *from,*to; \ 533 float *res; \ 534 const char **op1; \ 535 const float *op2; \ 536 operand(0,res,float *); \ 537 operand(1,op1,const char **); \ 538 operand(2,op2,const float *); \ 539 findCoordinateSystem(*op1,from,to,cSystem); 540 541 542 #define TRANSFORM1EXPR mulmp(res,to,op2); 543 544 545 #define TRANSFORM1EXPR_UPDATE FUN3EXPR_UPDATE(3,0,3); 546 547 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 548 // transform "p=SSp" 549 #define TRANSFORM2EXPR_PRE ECoordinateSystem cSystemFrom,cSystemTo; \ 550 const float *from1,*to1,*from2,*to2; \ 551 vector vtmp; \ 552 float *res; \ 553 const char **op1; \ 554 const char **op2; \ 555 const float *op3; \ 556 operand(0,res,float *); \ 557 operand(1,op1,const char **); \ 558 operand(2,op2,const char **); \ 559 operand(3,op3,const float *); \ 560 findCoordinateSystem(*op1,from1,to1,cSystemFrom); \ 561 findCoordinateSystem(*op2,from2,to2,cSystemTo); 562 563 #define TRANSFORM2EXPR mulmp(vtmp,from1,op3); \ 564 mulmp(res,to2,vtmp); 565 566 #define TRANSFORM2EXPR_UPDATE FUN4EXPR_UPDATE(3,0,0,3); 567 568 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 569 // transform "p=mp" 570 #define TRANSFORM3EXPR mulmp(res,op1,op2); 571 572 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 573 // transform "p=Smp" 574 #define TRANSFORM4EXPR_PRE ECoordinateSystem cSystem; \ 575 const float *from,*to; \ 576 vector vtmp; \ 577 float *res; \ 578 const char **op1; \ 579 const float *op2; \ 580 const float *op3; \ 581 operand(0,res,float *); \ 582 operand(1,op1,const char **); \ 583 operand(2,op2,const float *); \ 584 operand(3,op3,const float *); \ 585 findCoordinateSystem(*op1,from,to,cSystem); 586 587 #define TRANSFORM4EXPR mulmp(vtmp,from,op3); \ 588 mulmp(res,op2,vtmp); 589 590 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 591 // vtransform "p=Sp 592 #define VTRANSFORM1EXPR_PRE ECoordinateSystem cSystem; \ 593 const float *from,*to; \ 594 float *res; \ 595 const char **op1; \ 596 const float *op2; \ 597 operand(0,res,float *); \ 598 operand(1,op1,const char **); \ 599 operand(2,op2,const float *); \ 600 findCoordinateSystem(*op1,from,to,cSystem); 601 602 #define VTRANSFORM1EXPR mulmv(res,to,op2); 603 604 605 #define VTRANSFORM1EXPR_UPDATE FUN3EXPR_UPDATE(3,0,3); 606 607 608 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 609 // ntransform "p=Sp 610 #define NTRANSFORM1EXPR_PRE ECoordinateSystem cSystem; \ 611 const float *from,*to; \ 612 float *res; \ 613 const char **op1; \ 614 const float *op2; \ 615 operand(0,res,float *); \ 616 operand(1,op1,const char **); \ 617 operand(2,op2,const float *); \ 618 findCoordinateSystem(*op1,from,to,cSystem); \ 619 620 #define NTRANSFORM1EXPR mulmn(res,from,op2); 621 622 #define NTRANSFORM1EXPR_UPDATE FUN3EXPR_UPDATE(3,0,3); \ 623 624 625 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 626 // vtransform "p=SSp" 627 #define VTRANSFORM2EXPR_PRE ECoordinateSystem cSystemFrom,cSystemTo; \ 628 const float *from1,*to1,*from2,*to2; \ 629 vector vtmp; \ 630 float *res; \ 631 const char **op1; \ 632 const char **op2; \ 633 const float *op3; \ 634 operand(0,res,float *); \ 635 operand(1,op1,const char **); \ 636 operand(2,op2,const char **); \ 637 operand(3,op3,const float *); \ 638 findCoordinateSystem(*op1,from1,to1,cSystemFrom); \ 639 findCoordinateSystem(*op2,from2,to2,cSystemTo); 640 641 #define VTRANSFORM2EXPR mulmv(vtmp,from1,op3); \ 642 mulmv(res,to2,vtmp); 643 644 #define VTRANSFORM2EXPR_UPDATE FUN4EXPR_UPDATE(3,0,0,3); 645 646 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 647 // ntransform "p=SSp" 648 #define NTRANSFORM2EXPR_PRE ECoordinateSystem cSystemFrom,cSystemTo; \ 649 const float *from1,*to1,*from2,*to2; \ 650 vector vtmp; \ 651 float *res; \ 652 const char **op1; \ 653 const char **op2; \ 654 const float *op3; \ 655 operand(0,res,float *); \ 656 operand(1,op1,const char **); \ 657 operand(2,op2,const char **); \ 658 operand(3,op3,const float *); \ 659 findCoordinateSystem(*op1,from1,to1,cSystemFrom); \ 660 findCoordinateSystem(*op2,from2,to2,cSystemTo); 661 662 #define NTRANSFORM2EXPR mulmn(vtmp,to1,op3); \ 663 mulmn(res,from2,vtmp); 664 665 #define NTRANSFORM2EXPR_UPDATE FUN4EXPR_UPDATE(3,0,0,3); 666 667 668 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 669 // vtransform "p=mp" 670 #define VTRANSFORM3EXPR mulmv(res,op1,op2); 671 672 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 673 // ntransform "p=mp" 674 #define NTRANSFORM3EXPR matrix mtmp; \ 675 invertm(mtmp,op1); \ 676 mulmn(res,mtmp,op2); 677 678 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 679 // vtransform "p=Smp" 680 #define VTRANSFORM4EXPR_PRE ECoordinateSystem cSystem; \ 681 const float *from,*to; \ 682 vector vtmp; \ 683 float *res; \ 684 const char **op1; \ 685 const float *op2; \ 686 const float *op3; \ 687 operand(0,res,float *); \ 688 operand(1,op1,const char **); \ 689 operand(2,op2,const float *); \ 690 operand(3,op3,const float *); \ 691 findCoordinateSystem(*op1,from,to,cSystem); 692 693 #define VTRANSFORM4EXPR mulmv(vtmp,from,op3); \ 694 mulmv(res,op2,vtmp); 695 696 #define VTRANSFORM4EXPR_UPDATE FUN4EXPR_UPDATE(3,0,16,3); 697 698 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 699 // ntransform "p=Smp" 700 #define NTRANSFORM4EXPR_PRE ECoordinateSystem cSystem; \ 701 const float *from,*to; \ 702 matrix mtmp; \ 703 vector vtmp; \ 704 float *res; \ 705 const char **op1; \ 706 const float *op2; \ 707 const float *op3; \ 708 operand(0,res,float *); \ 709 operand(1,op1,const char **); \ 710 operand(2,op2,const float *); \ 711 operand(3,op3,const float *); \ 712 findCoordinateSystem(*op1,from,to,cSystem); 713 714 #define NTRANSFORM4EXPR invertm(mtmp,op2); \ 715 mulmn(vtmp,to,op3); \ 716 mulmn(res,mtmp,vtmp); 717 718 #define NTRANSFORM4EXPR_UPDATE FUN4EXPR_UPDATE(3,0,16,3); 719 720 721 DEFFUNC(Transform1 ,"transform" ,"p=Sp" ,TRANSFORM1EXPR_PRE,TRANSFORM1EXPR,TRANSFORM1EXPR_UPDATE,NULL_EXPR,0) 722 DEFFUNC(Transform2 ,"transform" ,"p=SSp" ,TRANSFORM2EXPR_PRE,TRANSFORM2EXPR,TRANSFORM2EXPR_UPDATE,NULL_EXPR,0) 723 DEFFUNC(Transform3 ,"transform" ,"p=mp" ,FUN3EXPR_PRE,TRANSFORM3EXPR,FUN3EXPR_UPDATE(3,16,3),NULL_EXPR,0) 724 DEFFUNC(Transform4 ,"transform" ,"p=Smp" ,TRANSFORM4EXPR_PRE,TRANSFORM4EXPR,FUN4EXPR_UPDATE(3,1,16,3),NULL_EXPR,0) 725 DEFFUNC(VTransform1 ,"vtransform" ,"v=Sv" ,VTRANSFORM1EXPR_PRE,VTRANSFORM1EXPR,VTRANSFORM1EXPR_UPDATE,NULL_EXPR,0) 726 DEFFUNC(VTransform2 ,"vtransform" ,"v=SSv" ,VTRANSFORM2EXPR_PRE,VTRANSFORM2EXPR,VTRANSFORM2EXPR_UPDATE,NULL_EXPR,0) 727 DEFFUNC(VTransform3 ,"vtransform" ,"v=mv" ,FUN3EXPR_PRE,VTRANSFORM3EXPR,FUN3EXPR_UPDATE(3,16,3),NULL_EXPR,0) 728 DEFFUNC(VTransform4 ,"vtransform" ,"v=Smv" ,VTRANSFORM4EXPR_PRE,VTRANSFORM4EXPR,VTRANSFORM4EXPR_UPDATE,NULL_EXPR,0) 729 DEFFUNC(NTransform1 ,"ntransform" ,"n=Sn" ,NTRANSFORM1EXPR_PRE,NTRANSFORM1EXPR,NTRANSFORM1EXPR_UPDATE,NULL_EXPR,0) 730 DEFFUNC(NTransform2 ,"ntransform" ,"n=SSn" ,NTRANSFORM2EXPR_PRE,NTRANSFORM2EXPR,NTRANSFORM2EXPR_UPDATE,NULL_EXPR,0) 731 DEFFUNC(NTransform3 ,"ntransform" ,"n=mn" ,FUN3EXPR_PRE,NTRANSFORM3EXPR,FUN3EXPR_UPDATE(3,16,3),NULL_EXPR,0) 732 DEFFUNC(NTransform4 ,"ntransform" ,"n=Smn" ,NTRANSFORM4EXPR_PRE,NTRANSFORM4EXPR,NTRANSFORM4EXPR_UPDATE,NULL_EXPR,0) 733 734 735 736 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 737 // depth "f=p" 738 #define DEPTHEXPR *res = (op[2] - CRenderer::clipMin) / (CRenderer::clipMax - CRenderer::clipMin); 739 740 DEFFUNC(Depth ,"depth" ,"f=p" ,FUN2EXPR_PRE,DEPTHEXPR,FUN2EXPR_UPDATE(1,3),NULL_EXPR,0) 741 742 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 743 // clearlighting "o=" 744 #define CLEARLIGHTINGEXPR_PRE clearLighting(); 745 746 DEFFUNC(Clearlighting ,"clearlighting" ,"o=" ,CLEARLIGHTINGEXPR_PRE,NULL_EXPR,NULL_EXPR,NULL_EXPR,0) 747 748 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 749 // ambient "c=" 750 #define AMBIENTEXPR_PRE const float *Clsave; \ 751 float *res; \ 752 operand(0,res,float *); \ 753 runAmbientLights(); \ 754 Clsave = (*alights)->savedState[1]; 755 756 #define AMBIENTEXPR movvv(res,Clsave); 757 758 #define AMBIENTEXPR_UPDATE res += 3; \ 759 Clsave += 3; 760 761 DEFFUNC(Ambient ,"ambient" ,"c=" ,AMBIENTEXPR_PRE,AMBIENTEXPR,AMBIENTEXPR_UPDATE,NULL_EXPR,0) 762 763 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 764 // diffuse "c=n" 765 #define DIFFUSEEXPR_PRE float *costheta = (float *) ralloc(numVertices*sizeof(float),threadMemory); \ 766 float *res; \ 767 const float *op; \ 768 vector Ltmp; \ 769 for (int i=0;i<numVertices;++i) costheta[i] = 0; \ 770 operand(0,res,float *); \ 771 operand(1,op,const float *); \ 772 const float *P = varying[VARIABLE_P]; \ 773 const float *N = op; \ 774 \ 775 runLights(P,N,costheta); \ 776 /* initialize output appropriately */ \ 777 float *R = res; \ 778 tags = tagStart; \ 779 for (int i=0;i<numVertices;++i) { \ 780 if (*tags == 0) initv(R,0,0,0); \ 781 R += 3; \ 782 ++tags; \ 783 } \ 784 /* loop the lighting contributions */ \ 785 *currentLight = *lights; \ 786 while (*currentLight) { \ 787 int ndStep; \ 788 float _nd = 0; \ 789 const float *nd; \ 790 enterFastLightingConditional(); \ 791 CShaderInstance *_inst = (*currentLight)->instance; \ 792 if (_inst ->flags & SHADERFLAGS_NONDIFFUSE) { \ 793 CLightShaderData *lightData = (CLightShaderData*) _inst->data; \ 794 nd = (*currentLight)->savedState[2+lightData->nonDiffuseIndex]; \ 795 ndStep = lightData->nonDiffuseStep; \ 796 } else { \ 797 nd = &_nd; \ 798 ndStep = 0; \ 799 } \ 800 const float *L = (*currentLight)->savedState[0]; \ 801 const float *Cl = (*currentLight)->savedState[1]; \ 802 R = res; \ 803 N = op; \ 804 tags = tagStart; 805 806 807 #define DIFFUSEEXPR normalizev(Ltmp,L); \ 808 const float coefficient = (1.0f-nd[0])*dotvv(N,Ltmp); \ 809 if (coefficient > 0) { \ 810 R[COMP_R] += coefficient * Cl[COMP_R]; \ 811 R[COMP_G] += coefficient * Cl[COMP_G]; \ 812 R[COMP_B] += coefficient * Cl[COMP_B]; \ 813 } 814 815 #define DIFFUSEEXPR_UPDATE R += 3; \ 816 N += 3; \ 817 Cl += 3; \ 818 L += 3; \ 819 nd += ndStep; 820 821 #define DIFFUSEEXPR_POST exitFastLightingConditional(); \ 822 *currentLight=(*currentLight)->next; \ 823 } 824 825 DEFLIGHTFUNC(Diffuse ,"diffuse" ,"c=n" ,DIFFUSEEXPR_PRE, DIFFUSEEXPR, DIFFUSEEXPR_UPDATE, DIFFUSEEXPR_POST, PARAMETER_P) 826 827 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 828 // diffuse "c=pnf" 829 #define DIFFUSE2EXPR_PRE const float *P,*N; \ 830 float *costheta = (float *) ralloc(numVertices*sizeof(float),threadMemory); \ 831 const float *cosangle; \ 832 const float *op3; \ 833 vector Ltmp; \ 834 float *res; \ 835 const float *op2; \ 836 operand(0,res,float *); \ 837 operand(1,P,const float *); \ 838 operand(2,op2,const float *); \ 839 operand(3,op3,const float *); \ 840 for (int i=0;i<numVertices;++i) costheta[i] = (float) cos(op3[i]); \ 841 N = op2; \ 842 runLights(P,N,costheta); \ 843 /* initialize output appropriately */ \ 844 float *R = res; \ 845 tags = tagStart; \ 846 for (int i=0;i<numVertices;++i) { \ 847 if (*tags==0) initv(R,0,0,0); \ 848 R += 3; \ 849 ++tags; \ 850 } \ 851 /* loop the lighting contributions */ \ 852 *currentLight = *lights; \ 853 while (*currentLight) { \ 854 int ndStep; \ 855 float _nd = 0; \ 856 const float *nd; \ 857 enterFastLightingConditional(); \ 858 CShaderInstance *_inst = (*currentLight)->instance; \ 859 if (_inst ->flags & SHADERFLAGS_NONDIFFUSE) { \ 860 CLightShaderData *lightData = (CLightShaderData*) _inst->data; \ 861 nd = (*currentLight)->savedState[2+lightData->nonDiffuseIndex]; \ 862 ndStep = lightData->nonDiffuseStep; \ 863 } else { \ 864 nd = &_nd; \ 865 ndStep = 0; \ 866 } \ 867 const float *L = (*currentLight)->savedState[0]; \ 868 const float *Cl = (*currentLight)->savedState[1]; \ 869 R = res; \ 870 N = op2; \ 871 cosangle = costheta; \ 872 tags = tagStart; 873 874 #define DIFFUSE2EXPR normalizev(Ltmp,L); \ 875 const float coefficient = (1.0f-nd[0])*dotvv(N,Ltmp); \ 876 if (coefficient > *cosangle) { \ 877 R[COMP_R] += coefficient * Cl[COMP_R]; \ 878 R[COMP_G] += coefficient * Cl[COMP_G]; \ 879 R[COMP_B] += coefficient * Cl[COMP_B]; \ 880 } 881 882 #define DIFFUSE2EXPR_UPDATE R += 3; \ 883 N += 3; \ 884 cosangle += 1; \ 885 Cl += 3; \ 886 L += 3; \ 887 nd += ndStep; 888 889 890 #define DIFFUSE2EXPR_POST exitFastLightingConditional(); \ 891 *currentLight=(*currentLight)->next; \ 892 } 893 894 895 DEFLIGHTFUNC(Diffuse2 ,"diffuse" ,"c=pnf" ,DIFFUSE2EXPR_PRE, DIFFUSE2EXPR, DIFFUSE2EXPR_UPDATE, DIFFUSE2EXPR_POST, 0) 896 897 898 899 900 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 901 // specular "c=nvf" 902 #define SPECULAREXPR_PRE float *costheta = (float *) ralloc(numVertices*sizeof(float),threadMemory); \ 903 float *powers = (float *) ralloc(numVertices*sizeof(float),threadMemory); \ 904 const float *op1,*op2,*op3; \ 905 float *res; \ 906 vector Ltmp,halfway; \ 907 operand(0,res,float *); \ 908 operand(1,op1,const float *); \ 909 operand(2,op2,const float *); \ 910 operand(3,op3,const float *); \ 911 for (int i=0;i<numVertices;++i) costheta[i] = 0; \ 912 const float *P = varying[VARIABLE_P]; \ 913 const float *N = op1; \ 914 runLights(P,N,costheta); \ 915 /* initialize output appropriately */ \ 916 float *R = res; \ 917 float *power = powers; \ 918 tags = tagStart; \ 919 for (int i=0;i<numVertices;++i) { \ 920 if (*tags==0) { \ 921 initv(R,0,0,0); \ 922 *power = 10.0f / *op3; \ 923 } \ 924 R += 3; \ 925 op3 += 1; \ 926 power += 1; \ 927 ++tags; \ 928 } \ 929 /* loop the lighting contributions */ \ 930 *currentLight = *lights; \ 931 while (*currentLight) { \ 932 float _ns = 0; \ 933 int nsStep; \ 934 const float *ns; \ 935 enterFastLightingConditional(); \ 936 CShaderInstance *_inst = (*currentLight)->instance; \ 937 if (_inst ->flags & SHADERFLAGS_NONSPECULAR) { \ 938 CLightShaderData *lightData = (CLightShaderData*) _inst->data; \ 939 ns = (*currentLight)->savedState[2+lightData->nonSpecularIndex]; \ 940 nsStep = lightData->nonSpecularStep; \ 941 } else { \ 942 ns = &_ns; \ 943 nsStep = 0; \ 944 } \ 945 const float *L = (*currentLight)->savedState[0]; \ 946 const float *Cl = (*currentLight)->savedState[1]; \ 947 const float *V = op2; \ 948 R = res; \ 949 N = op1; \ 950 power = powers; \ 951 tags = tagStart; 952 953 #define SPECULAREXPR normalizev(Ltmp,L); \ 954 addvv(halfway,V,Ltmp); \ 955 normalizev(halfway); \ 956 const float tmp = ((1.0f-ns[0])*dotvv(N,halfway)); \ 957 if (tmp > 0) { \ 958 const float coefficient = (float) pow(tmp,*power); \ 959 R[COMP_R] += coefficient * Cl[COMP_R]; \ 960 R[COMP_G] += coefficient * Cl[COMP_G]; \ 961 R[COMP_B] += coefficient * Cl[COMP_B]; \ 962 } 963 964 #define SPECULAREXPR_UPDATE R += 3; \ 965 N += 3; \ 966 V += 3; \ 967 power += 1; \ 968 Cl += 3; \ 969 L += 3; \ 970 ns += nsStep; 971 972 #define SPECULAREXPR_POST exitFastLightingConditional(); \ 973 *currentLight=(*currentLight)->next; \ 974 } 975 976 DEFLIGHTFUNC(Specular ,"specular" ,"c=nvf" ,SPECULAREXPR_PRE, SPECULAREXPR, SPECULAREXPR_UPDATE, SPECULAREXPR_POST, PARAMETER_P) 977 978 979 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 980 // phong "c=nvf" 981 #define PHONGEXPR_PRE float *costheta = (float *) ralloc(numVertices*sizeof(float),threadMemory); \ 982 float *refDirs = (float *) ralloc(3*numVertices*sizeof(float),threadMemory); \ 983 const float *op1,*op2,*op3; \ 984 float *res; \ 985 vector Ltmp; \ 986 operand(0,res,float *); \ 987 operand(1,op1,const float *); \ 988 operand(2,op2,const float *); \ 989 operand(3,op3,const float *); \ 990 for (int i=0;i<numVertices;++i) costheta[i] = 0; \ 991 const float *P = varying[VARIABLE_P]; \ 992 const float *N = op1; \ 993 runLights(P,N,costheta); \ 994 /* initialize output appropriately */ \ 995 float *R = res; \ 996 const float *V = op2; \ 997 float *refDir = refDirs; \ 998 N = op1; \ 999 tags = tagStart; \ 1000 for (int i=0;i<numVertices;++i) { \ 1001 if (*tags==0) { \ 1002 initv(R,0,0,0); \ 1003 mulvf(refDir,N,2*dotvv(N,V)); \ 1004 subvv(refDir,V); \ 1005 } \ 1006 R += 3; \ 1007 N += 3; \ 1008 V += 3; \ 1009 refDir += 3; \ 1010 ++tags; \ 1011 } \ 1012 /* loop the lighting contributions */ \ 1013 *currentLight = *lights; \ 1014 while (*currentLight) { \ 1015 int nsStep; \ 1016 const float *ns; \ 1017 float _ns = 0; \ 1018 enterFastLightingConditional(); \ 1019 CShaderInstance *_inst = (*currentLight)->instance; \ 1020 if (_inst ->flags & SHADERFLAGS_NONSPECULAR) { \ 1021 CLightShaderData *lightData = (CLightShaderData*) _inst->data; \ 1022 ns = (*currentLight)->savedState[2+lightData->nonSpecularIndex]; \ 1023 nsStep = lightData->nonSpecularStep; \ 1024 } else { \ 1025 ns = &_ns; \ 1026 nsStep = 0; \ 1027 } \ 1028 const float *L = (*currentLight)->savedState[0]; \ 1029 const float *Cl = (*currentLight)->savedState[1]; \ 1030 const float *size = op3; \ 1031 R = res; \ 1032 refDir = refDirs; \ 1033 tags = tagStart; 1034 1035 #define PHONGEXPR normalizev(Ltmp,L); \ 1036 const float coefficient = (1.0f-ns[0]) * (float) pow(max(0,dotvv(refDir,Ltmp)),*size); \ 1037 if (coefficient > 0) { \ 1038 R[COMP_R] += coefficient * Cl[COMP_R]; \ 1039 R[COMP_G] += coefficient * Cl[COMP_G]; \ 1040 R[COMP_B] += coefficient * Cl[COMP_B]; \ 1041 } 1042 1043 #define PHONGEXPR_UPDATE R += 3; \ 1044 size += 1; \ 1045 refDir += 3; \ 1046 Cl += 3; \ 1047 L += 3; \ 1048 ns += nsStep; 1049 1050 #define PHONGEXPR_POST exitFastLightingConditional(); \ 1051 *currentLight=(*currentLight)->next; \ 1052 } 1053 1054 DEFLIGHTFUNC(Phong ,"phong" ,"c=nvf" ,PHONGEXPR_PRE, PHONGEXPR, PHONGEXPR_UPDATE, PHONGEXPR_POST, PARAMETER_P) 1055 1056 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1057 // specularBRDF "c=vnvf" 1058 #define SPECULARBRDFEXPR_PRE float *res; \ 1059 const float *op1,*op2,*op3,*op4; \ 1060 vector halfway; \ 1061 operand(0,res,float *); \ 1062 operand(1,op1,const float *); \ 1063 operand(2,op2,const float *); \ 1064 operand(3,op3,const float *); \ 1065 operand(4,op4,const float *); 1066 1067 #define SPECULARBRDFEXPR addvv(halfway,op3,op1); \ 1068 normalizev(halfway); \ 1069 res[0] = (float) pow(max(0,dotvv(op2,halfway)),(10.0f)/(*op4)); \ 1070 res[1] = res[0]; \ 1071 res[2] = res[1]; \ 1072 1073 #define SPECULARBRDFEXPR_UPDATE res += 3; \ 1074 op1 += 3; \ 1075 op2 += 3; \ 1076 op3 += 3; \ 1077 op4 += 1; 1078 1079 1080 1081 DEFFUNC(SpecularBRDF ,"specularbrdf" ,"c=vnvf" ,SPECULARBRDFEXPR_PRE,SPECULARBRDFEXPR,SPECULARBRDFEXPR_UPDATE,NULL_EXPR,0) 1082 1083 1084 1085 1086 1087 #ifndef INIT_SHADING 1088 1089 1090 //////////////////// 1091 // FIXME: Not 64 bit compatible 1092 #define PARAMETEREXPR_PRE(accessor) \ 1093 float *res; \ 1094 const char **op1; \ 1095 float *op2; \ 1096 int op2Step; \ 1097 operand(0,res,float *); \ 1098 operand(1,op1,const char **); \ 1099 operand(2,op2,float *); \ 1100 op2Step = operandVaryingStep(2); \ 1101 \ 1102 int globalIndex = -1; \ 1103 CVariable *cVar = NULL; \ 1104 float found = (float) FUNCTION(op2,*op1,&cVar,&globalIndex); \ 1105 const float *src = op2; \ 1106 int srcStep = op2Step; \ 1107 \ 1108 if (found != 0) { \ 1109 srcStep = 0; \ 1110 if (cVar != NULL) { \ 1111 if (cVar->storage == STORAGE_PARAMETER || cVar->storage == STORAGE_MUTABLEPARAMETER) { \ 1112 src = currentShadingState->locals[accessor][cVar->entry]; \ 1113 } else { \ 1114 src = varying[cVar->entry]; \ 1115 } \ 1116 srcStep = cVar->numFloats; \ 1117 if ((cVar->container == CONTAINER_UNIFORM) || (cVar->container == CONTAINER_CONSTANT)) { \ 1118 srcStep = 0; \ 1119 } else if (op2Step == 0) { \ 1120 /* guard against varying->uniform assignment : nullify copy */ \ 1121 srcStep = 0; \ 1122 src = op2; \ 1123 found = 0; \ 1124 } \ 1125 } \ 1126 } 1127 1128 #define LIGHTPARAMETEREXPR_PRE float *res; \ 1129 const char **op1; \ 1130 float *op2; \ 1131 int op2Step; \ 1132 operand(0,res,float *); \ 1133 operand(1,op1,const char **); \ 1134 operand(2,op2,float *); \ 1135 op2Step = operandVaryingStep(2); \ 1136 \ 1137 int globalIndex = -1; \ 1138 CVariable *cVar = NULL; \ 1139 float found = (float) (*currentLight)->instance->getParameter(*op1,op2,&cVar,&globalIndex);\ 1140 const float *src = op2; \ 1141 int srcStep = op2Step; \ 1142 \ 1143 if (found != 0) { \ 1144 srcStep = 0; \ 1145 if (cVar != NULL) { \ 1146 src = (*currentLight)->savedState[2+globalIndex]; \ 1147 srcStep = cVar->numFloats; \ 1148 if ((cVar->container == CONTAINER_UNIFORM) || (cVar->container == CONTAINER_CONSTANT)) { \ 1149 srcStep = 0; \ 1150 } else if (op2Step == 0) { \ 1151 /* guard against varying->uniform assignment : nullify copy */ \ 1152 srcStep = 0; \ 1153 src = op2; \ 1154 found = 0; \ 1155 } \ 1156 } \ 1157 } 1158 1159 #define PARAMETEREXPRF *res = found; \ 1160 *op2 = *src; 1161 1162 #define PARAMETEREXPRS *res = found; \ 1163 *op2 = *src; 1164 1165 #define PARAMETEREXPRV *res = found; \ 1166 op2[0] = src[0]; \ 1167 op2[1] = src[1]; \ 1168 op2[2] = src[2]; 1169 1170 #define PARAMETEREXPRM *res = found; \ 1171 op2[0] = src[0]; \ 1172 op2[1] = src[1]; \ 1173 op2[2] = src[2]; \ 1174 op2[3] = src[3]; \ 1175 op2[4] = src[4]; \ 1176 op2[5] = src[5]; \ 1177 op2[6] = src[6]; \ 1178 op2[7] = src[7]; \ 1179 op2[8] = src[8]; \ 1180 op2[9] = src[9]; \ 1181 op2[10] = src[10]; \ 1182 op2[11] = src[11]; \ 1183 op2[12] = src[12]; \ 1184 op2[13] = src[13]; \ 1185 op2[14] = src[14]; \ 1186 op2[15] = src[15]; 1187 1188 1189 #define PARAMETEREXPR_UPDATE(__r,__o2) \ 1190 res += __r; \ 1191 op2 += __o2; \ 1192 src += srcStep; 1193 1194 #else 1195 #undef PARAMETEREXPR_PRE 1196 #undef LIGHTPARAMETEREXPR_PRE 1197 #undef PARAMETEREXPRF 1198 #undef PARAMETEREXPRS 1199 #undef PARAMETEREXPRV 1200 #undef PARAMETEREXPRM 1201 #undef PARAMETEREXPR_UPDATE 1202 #define PARAMETEREXPR_PRE(a) 1203 #define LIGHTPARAMETEREXPR_PRE 1204 #define PARAMETEREXPRF 1205 #define PARAMETEREXPRS 1206 #define PARAMETEREXPRV 1207 #define PARAMETEREXPRM 1208 #define PARAMETEREXPR_UPDATE 1209 #endif 1210 1211 #define FUNCTION displacementParameter 1212 DEFLINKFUNC(Displacement2 ,"displacement" ,"f=SC", PARAMETER_MESSAGEPASSING) 1213 DEFLINKFUNC(Displacement3 ,"displacement" ,"f=SN", PARAMETER_MESSAGEPASSING) 1214 DEFLINKFUNC(Displacement4 ,"displacement" ,"f=SP", PARAMETER_MESSAGEPASSING) 1215 DEFFUNC(DisplacementV ,"displacement" ,"f=SV" ,PARAMETEREXPR_PRE(ACCESSOR_DISPLACEMENT),PARAMETEREXPRV,PARAMETEREXPR_UPDATE(1,3),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1216 DEFFUNC(Displacement ,"displacement" ,"f=SF" ,PARAMETEREXPR_PRE(ACCESSOR_DISPLACEMENT),PARAMETEREXPRF,PARAMETEREXPR_UPDATE(1,1),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1217 DEFFUNC(DisplacementS ,"displacement" ,"f=SS" ,PARAMETEREXPR_PRE(ACCESSOR_DISPLACEMENT),PARAMETEREXPRS,PARAMETEREXPR_UPDATE(1,1),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1218 DEFFUNC(DisplacementM ,"displacement" ,"f=SM" ,PARAMETEREXPR_PRE(ACCESSOR_DISPLACEMENT),PARAMETEREXPRM,PARAMETEREXPR_UPDATE(1,16),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1219 #undef FUNCTION 1220 1221 #define FUNCTION surfaceParameter 1222 DEFLINKFUNC(Surface2 ,"surface" ,"f=SC", PARAMETER_MESSAGEPASSING) 1223 DEFLINKFUNC(Surface3 ,"surface" ,"f=SN", PARAMETER_MESSAGEPASSING) 1224 DEFLINKFUNC(Surface4 ,"surface" ,"f=SP", PARAMETER_MESSAGEPASSING) 1225 DEFFUNC(SurfaceV ,"surface" ,"f=SV" ,PARAMETEREXPR_PRE(ACCESSOR_SURFACE),PARAMETEREXPRV,PARAMETEREXPR_UPDATE(1,3),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1226 DEFFUNC(Surface ,"surface" ,"f=SF" ,PARAMETEREXPR_PRE(ACCESSOR_SURFACE),PARAMETEREXPRF,PARAMETEREXPR_UPDATE(1,1),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1227 DEFFUNC(SurfaceS ,"surface" ,"f=SS" ,PARAMETEREXPR_PRE(ACCESSOR_SURFACE),PARAMETEREXPRS,PARAMETEREXPR_UPDATE(1,1),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1228 DEFFUNC(SurfaceM ,"surface" ,"f=SM" ,PARAMETEREXPR_PRE(ACCESSOR_SURFACE),PARAMETEREXPRM,PARAMETEREXPR_UPDATE(1,16),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1229 #undef FUNCTION 1230 1231 DEFLINKFUNC(Lightsource2 ,"lightsource" ,"f=SC", PARAMETER_MESSAGEPASSING) 1232 DEFLINKFUNC(Lightsource3 ,"lightsource" ,"f=SN", PARAMETER_MESSAGEPASSING) 1233 DEFLINKFUNC(Lightsource4 ,"lightsource" ,"f=SP", PARAMETER_MESSAGEPASSING) 1234 DEFFUNC(LightsourceV ,"lightsource" ,"f=SV" ,LIGHTPARAMETEREXPR_PRE,PARAMETEREXPRV,PARAMETEREXPR_UPDATE(1,3),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1235 DEFFUNC(Lightsource ,"lightsource" ,"f=SF" ,LIGHTPARAMETEREXPR_PRE,PARAMETEREXPRF,PARAMETEREXPR_UPDATE(1,1),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1236 DEFFUNC(LightsourceS ,"lightsource" ,"f=SS" ,LIGHTPARAMETEREXPR_PRE,PARAMETEREXPRS,PARAMETEREXPR_UPDATE(1,1),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1237 DEFFUNC(LightsourceM ,"lightsource" ,"f=SM" ,LIGHTPARAMETEREXPR_PRE,PARAMETEREXPRM,PARAMETEREXPR_UPDATE(1,16),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1238 1239 #define FUNCTION atmosphereParameter 1240 DEFLINKFUNC(Atmosphere2 ,"atmosphere" ,"f=SC", PARAMETER_MESSAGEPASSING) 1241 DEFLINKFUNC(Atmosphere3 ,"atmosphere" ,"f=SN", PARAMETER_MESSAGEPASSING) 1242 DEFLINKFUNC(Atmosphere4 ,"atmosphere" ,"f=SP", PARAMETER_MESSAGEPASSING) 1243 DEFFUNC(AtmosphereV ,"atmosphere" ,"f=SV" ,PARAMETEREXPR_PRE(ACCESSOR_ATMOSPHERE),PARAMETEREXPRV,PARAMETEREXPR_UPDATE(1,3),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1244 DEFFUNC(Atmosphere ,"atmosphere" ,"f=SF" ,PARAMETEREXPR_PRE(ACCESSOR_ATMOSPHERE),PARAMETEREXPRF,PARAMETEREXPR_UPDATE(1,1),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1245 DEFFUNC(AtmosphereS ,"atmosphere" ,"f=SS" ,PARAMETEREXPR_PRE(ACCESSOR_ATMOSPHERE),PARAMETEREXPRS,PARAMETEREXPR_UPDATE(1,1),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1246 DEFFUNC(AtmosphereM ,"atmosphere" ,"f=SM" ,PARAMETEREXPR_PRE(ACCESSOR_ATMOSPHERE),PARAMETEREXPRM,PARAMETEREXPR_UPDATE(1,16),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1247 #undef FUNCTION 1248 1249 /* note that whilst we provide accessors for incident and opposite, they will never be used */ 1250 1251 #define FUNCTION incidentParameter 1252 DEFLINKFUNC(Incident2 ,"incident" ,"f=SC", PARAMETER_MESSAGEPASSING) 1253 DEFLINKFUNC(Incident3 ,"incident" ,"f=SN", PARAMETER_MESSAGEPASSING) 1254 DEFLINKFUNC(Incident4 ,"incident" ,"f=SP", PARAMETER_MESSAGEPASSING) 1255 DEFFUNC(IncidentV ,"incident" ,"f=SV" ,PARAMETEREXPR_PRE(ACCESSOR_EXTERIOR),PARAMETEREXPRV,PARAMETEREXPR_UPDATE(1,3),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1256 DEFFUNC(Incident ,"incident" ,"f=SF" ,PARAMETEREXPR_PRE(ACCESSOR_EXTERIOR),PARAMETEREXPRF,PARAMETEREXPR_UPDATE(1,1),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1257 DEFFUNC(IncidentS ,"incident" ,"f=SS" ,PARAMETEREXPR_PRE(ACCESSOR_EXTERIOR),PARAMETEREXPRS,PARAMETEREXPR_UPDATE(1,1),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1258 DEFFUNC(IncidentM ,"incident" ,"f=SM" ,PARAMETEREXPR_PRE(ACCESSOR_EXTERIOR),PARAMETEREXPRM,PARAMETEREXPR_UPDATE(1,16),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1259 #undef FUNCTION 1260 1261 #define FUNCTION oppositeParameter 1262 DEFLINKFUNC(Opposite2 ,"opposite" ,"f=SC", PARAMETER_MESSAGEPASSING) 1263 DEFLINKFUNC(Opposite3 ,"opposite" ,"f=SN", PARAMETER_MESSAGEPASSING) 1264 DEFLINKFUNC(Opposite4 ,"opposite" ,"f=SP", PARAMETER_MESSAGEPASSING) 1265 DEFFUNC(OppositeV ,"opposite" ,"f=SV" ,PARAMETEREXPR_PRE(ACCESSOR_INTERIOR),PARAMETEREXPRV(ACCESSOR_INTERIOR),PARAMETEREXPR_UPDATE(1,3),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1266 DEFFUNC(Opposite ,"opposite" ,"f=SF" ,PARAMETEREXPR_PRE(ACCESSOR_INTERIOR),PARAMETEREXPRF(ACCESSOR_INTERIOR),PARAMETEREXPR_UPDATE(1,1),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1267 DEFFUNC(OppositeS ,"opposite" ,"f=SS" ,PARAMETEREXPR_PRE(ACCESSOR_INTERIOR),PARAMETEREXPRS(ACCESSOR_INTERIOR),PARAMETEREXPR_UPDATE(1,1),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1268 DEFFUNC(OppositeM ,"opposite" ,"f=SM" ,PARAMETEREXPR_PRE(ACCESSOR_INTERIOR),PARAMETEREXPRM(ACCESSOR_INTERIOR),PARAMETEREXPR_UPDATE(1,16),NULL_EXPR,PARAMETER_MESSAGEPASSING) 1269 #undef FUNCTION 1270 1271 /* note the accessor for the remaining functions is not used */ 1272 1273 #define FUNCTION attributes 1274 DEFLINKFUNC(Attributes2 ,"attribute" ,"f=SC", 0) 1275 DEFLINKFUNC(Attributes3 ,"attribute" ,"f=SN", 0) 1276 DEFLINKFUNC(Attributes4 ,"attribute" ,"f=SP", 0) 1277 DEFFUNC(AttributesV ,"attribute" ,"f=SV" ,PARAMETEREXPR_PRE(0),PARAMETEREXPRV,PARAMETEREXPR_UPDATE(1,3),NULL_EXPR,0) 1278 DEFFUNC(Attributes ,"attribute" ,"f=SF" ,PARAMETEREXPR_PRE(0),PARAMETEREXPRF,PARAMETEREXPR_UPDATE(1,1),NULL_EXPR,0) 1279 DEFFUNC(AttributesS ,"attribute" ,"f=SS" ,PARAMETEREXPR_PRE(0),PARAMETEREXPRS,PARAMETEREXPR_UPDATE(1,1),NULL_EXPR,0) 1280 DEFFUNC(AttributesM ,"attribute" ,"f=SM" ,PARAMETEREXPR_PRE(0),PARAMETEREXPRM,PARAMETEREXPR_UPDATE(1,16),NULL_EXPR,0) 1281 #undef FUNCTION 1282 1283 #define FUNCTION options 1284 DEFLINKFUNC(Options2 ,"option" ,"f=SC", 0) 1285 DEFLINKFUNC(Options3 ,"option" ,"f=SN", 0) 1286 DEFLINKFUNC(Options4 ,"option" ,"f=SP", 0) 1287 DEFFUNC(OptionsV ,"option" ,"f=SV" ,PARAMETEREXPR_PRE(0),PARAMETEREXPRV,PARAMETEREXPR_UPDATE(1,3),NULL_EXPR,0) 1288 DEFFUNC(Options ,"option" ,"f=SF" ,PARAMETEREXPR_PRE(0),PARAMETEREXPRF,PARAMETEREXPR_UPDATE(1,1),NULL_EXPR,0) 1289 DEFFUNC(OptionsS ,"option" ,"f=SS" ,PARAMETEREXPR_PRE(0),PARAMETEREXPRS,PARAMETEREXPR_UPDATE(1,1),NULL_EXPR,0) 1290 DEFFUNC(OptionsM ,"option" ,"f=SM" ,PARAMETEREXPR_PRE(0),PARAMETEREXPRM,PARAMETEREXPR_UPDATE(1,16),NULL_EXPR,0) 1291 #undef FUNCTION 1292 1293 #define FUNCTION rendererInfo 1294 DEFLINKFUNC(Rendererinfo2 ,"rendererinfo" ,"f=SC", 0) 1295 DEFLINKFUNC(Rendererinfo3 ,"rendererinfo" ,"f=SN", 0) 1296 DEFLINKFUNC(Rendererinfo4 ,"rendererinfo" ,"f=SP", 0) 1297 DEFFUNC(RendererinfoV ,"rendererinfo" ,"f=SV" ,PARAMETEREXPR_PRE(0),PARAMETEREXPRV,PARAMETEREXPR_UPDATE(1,3),NULL_EXPR,0) 1298 DEFFUNC(Rendererinfo ,"rendererinfo" ,"f=SF" ,PARAMETEREXPR_PRE(0),PARAMETEREXPRF,PARAMETEREXPR_UPDATE(1,1),NULL_EXPR,0) 1299 DEFFUNC(RendererinfoS ,"rendererinfo" ,"f=SS" ,PARAMETEREXPR_PRE(0),PARAMETEREXPRS,PARAMETEREXPR_UPDATE(1,1),NULL_EXPR,0) 1300 DEFFUNC(RendererinfoM ,"rendererinfo" ,"f=SM" ,PARAMETEREXPR_PRE(0),PARAMETEREXPRM,PARAMETEREXPR_UPDATE(1,16),NULL_EXPR,0) 1301 #undef FUNCTION 1302 1303 1304 1305 1306 #ifndef INIT_SHADING 1307 1308 #define TEXTUREINFO_PRE(_t) plBegin(CMapInfoLookup,4); \ 1309 float *res; \ 1310 const char **op1; \ 1311 const char **op2; \ 1312 _t op3; \ 1313 float found; \ 1314 float out[16*2]; \ 1315 const char *outS; \ 1316 _t src = (_t) out; \ 1317 int op3sz; \ 1318 \ 1319 operand(0,res,float *); \ 1320 operand(1,op1,const char **); \ 1321 operand(2,op2,const char **); \ 1322 operandSize(3,op3,op3sz,_t); \ 1323 \ 1324 CTextureInfoBase *textureInfo; \ 1325 if ((textureInfo = lookup->map) == NULL) { \ 1326 osLock(CRenderer::shaderMutex); \ 1327 lookup->map = textureInfo = CRenderer::getTextureInfo(*op1);\ 1328 osUnlock(CRenderer::shaderMutex); \ 1329 } \ 1330 \ 1331 if (textureInfo == NULL) { \ 1332 found = 0; \ 1333 src = op3; /* prevent writing result */ \ 1334 } else { \ 1335 \ 1336 for (int i=0;i<16*2;++i) out[i] = 0; \ 1337 \ 1338 found = 1; \ 1339 \ 1340 if (strcmp(*op2,"resolution") == 0) { \ 1341 textureInfo->getResolution(out); \ 1342 } else if (strcmp(*op2,"type") == 0) { \ 1343 outS = textureInfo->getTextureType(); \ 1344 src = (_t) &outS; \ 1345 } else if (strcmp(*op2,"channels") == 0) { \ 1346 out[0] = (float) textureInfo->getNumChannels(); \ 1347 } else if (strcmp(*op2,"viewingmatrix") == 0) { \ 1348 found = (float) textureInfo->getViewMatrix(out); \ 1349 } else if (strcmp(*op2,"projectionmatrix") == 0) { \ 1350 found = (float) textureInfo->getProjectionMatrix(out);\ 1351 } else if (strcmp(*op2,"exists") == 0) { \ 1352 src = op3; /* prevent writing result */ \ 1353 } else { \ 1354 found = 0; \ 1355 src = op3; /* prevent writing result */ \ 1356 } \ 1357 } 1358 1359 #define TEXTUREINFOF *res = found; \ 1360 *op3 = src[0]; \ 1361 if (op3sz > 1) op3[1] = src[1]; 1362 1363 #define TEXTUREINFOS *res = found; \ 1364 *op3 = src[0]; 1365 1366 #define TEXTUREINFOV *res = found; \ 1367 op3[0] = src[0]; \ 1368 op3[1] = src[1]; \ 1369 op3[2] = src[2]; 1370 1371 #define TEXTUREINFOM *res = found; \ 1372 op3[0] = src[0]; \ 1373 op3[1] = src[1]; \ 1374 op3[2] = src[2]; \ 1375 op3[3] = src[3]; \ 1376 op3[4] = src[4]; \ 1377 op3[5] = src[5]; \ 1378 op3[6] = src[6]; \ 1379 op3[7] = src[7]; \ 1380 op3[8] = src[8]; \ 1381 op3[9] = src[9]; \ 1382 op3[10] = src[10]; \ 1383 op3[11] = src[11]; \ 1384 op3[12] = src[12]; \ 1385 op3[13] = src[13]; \ 1386 op3[14] = src[14]; \ 1387 op3[15] = src[15]; 1388 1389 1390 #define TEXTUREINFO_UPDATE(__r,__o2) FUN4EXPR_UPDATE(__r,0,0,__o2) 1391 1392 #define TEXTUREINFO_POST plEnd(); 1393 1394 1395 #else 1396 1397 #undef TEXTUREINFO_PRE 1398 #undef TEXTUREINFOF 1399 #undef TEXTUREINFOS 1400 #undef TEXTUREINFOV 1401 #undef TEXTUREINFOM 1402 #undef TEXTUREINFO_UPDATE 1403 #undef TEXTUREINFO_POST 1404 1405 #define TEXTUREINFO_PRE(__t) 1406 #define TEXTUREINFOF 1407 #define TEXTUREINFOS 1408 #define TEXTUREINFOV 1409 #define TEXTUREINFOM 1410 #define TEXTUREINFO_UPDATE 1411 #define TEXTUREINFO_POST 1412 #endif 1413 1414 DEFLINKFUNC(Textureinfo2 ,"textureinfo" ,"f=SSC!", 0) 1415 DEFLINKFUNC(Textureinfo3 ,"textureinfo" ,"f=SSN!", 0) 1416 DEFLINKFUNC(Textureinfo4 ,"textureinfo" ,"f=SSP!", 0) 1417 DEFFUNC(TextureinfoV ,"textureinfo" ,"f=SSV!" ,TEXTUREINFO_PRE(float *),TEXTUREINFOV,TEXTUREINFO_UPDATE(1,3),TEXTUREINFO_POST,0) 1418 DEFFUNC(Textureinfo ,"textureinfo" ,"f=SSF!" ,TEXTUREINFO_PRE(float *),TEXTUREINFOF,TEXTUREINFO_UPDATE(1,op3sz),TEXTUREINFO_POST,0) 1419 DEFFUNC(TextureinfoS ,"textureinfo" ,"f=SSS!" ,TEXTUREINFO_PRE(char **),TEXTUREINFOS,TEXTUREINFO_UPDATE(1,1),TEXTUREINFO_POST,0) 1420 DEFFUNC(TextureinfoM ,"textureinfo" ,"f=SSM!" ,TEXTUREINFO_PRE(float *),TEXTUREINFOM,TEXTUREINFO_UPDATE(1,16),TEXTUREINFO_POST,0) 1421 1422 1423 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1424 // shadername "s=" 1425 #define SHADERNAMEEXPR_PRE char **res; \ 1426 operand(0,res,char **); 1427 1428 #define SHADERNAMEEXPR *res = (char *) currentShader->name; 1429 1430 DEFFUNC(ShaderName ,"shadername" ,"s=" ,SHADERNAMEEXPR_PRE,SHADERNAMEEXPR,FUN1EXPR_UPDATE(1),NULL_EXPR,0) 1431 1432 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1433 // shadername "s=s" 1434 #ifndef INIT_SHADING 1435 #define SHADERNAMESEXPR_PRE char **res,**op; \ 1436 operand(0,res,char **); \ 1437 operand(1,op,char **); 1438 1439 #define SHADERNAMESEXPR *res = (char *) shaderName(*op); 1440 #else 1441 #undef SHADERNAMESEXPR_PRE 1442 #undef SHADERNAMESEXPR 1443 #define SHADERNAMESEXPR_PRE 1444 #define SHADERNAMESEXPR 1445 #endif 1446 1447 DEFFUNC(ShaderNames ,"shadername" ,"s=s" ,SHADERNAMESEXPR_PRE,SHADERNAMESEXPR,FUN2EXPR_UPDATE(1,1),NULL_EXPR,0) 1448 1449 1450 1451 1452 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1453 // 1454 // Texture - Environment - Shadow mapping macros 1455 // 1456 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1457 1458 1459 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1460 // texture "f=SFff" 1461 #ifndef INIT_SHADING 1462 #define TEXTUREFEXPR_PRE float *res; \ 1463 const float *s,*t; \ 1464 const float *op2; \ 1465 /* Begin the parameter list */ \ 1466 plBegin(CTextureLookup,5); \ 1467 /* Fetch the parameters as usual */ \ 1468 operand(0,res,float *); \ 1469 operand(2,op2,const float *); \ 1470 operand(3,s,const float *); \ 1471 operand(4,t,const float *); \ 1472 /* Get the texture */ \ 1473 CTexture *tex; \ 1474 if ((tex = lookup->map) == NULL) { \ 1475 const char **op1; \ 1476 operand(1,op1,const char **); \ 1477 osLock(CRenderer::shaderMutex); \ 1478 lookup->map = tex = CRenderer::getTexture(*op1); \ 1479 osUnlock(CRenderer::shaderMutex); \ 1480 } \ 1481 int i; \ 1482 float *dsdu = (float *) ralloc(numVertices*4*sizeof(float),threadMemory); \ 1483 float *dsdv = dsdu + numVertices; \ 1484 float *dtdu = dsdv + numVertices; \ 1485 float *dtdv = dtdu + numVertices; \ 1486 float cs[4],ct[4]; \ 1487 const float swidth = (scratch->textureParams.width == 0 ? scratch->textureParams.swidth : scratch->textureParams.width); \ 1488 const float twidth = (scratch->textureParams.width == 0 ? scratch->textureParams.twidth : scratch->textureParams.width); \ 1489 const float *du = varying[VARIABLE_DU]; \ 1490 const float *dv = varying[VARIABLE_DV]; \ 1491 \ 1492 scratch->textureParams.filter = lookup->filter; \ 1493 \ 1494 duFloat(dsdu,s); \ 1495 duFloat(dtdu,t); \ 1496 dvFloat(dsdv,s); \ 1497 dvFloat(dtdv,t); \ 1498 \ 1499 i = 0; 1500 1501 #define TEXTUREFEXPR plReady(); \ 1502 cs[0] = s[i]; \ 1503 cs[1] = s[i] + dsdu[i]*du[i]*swidth; \ 1504 cs[2] = s[i] + dsdv[i]*dv[i]*swidth; \ 1505 cs[3] = s[i] + (dsdu[i]*du[i] + dsdv[i]*dv[i])*swidth; \ 1506 ct[0] = t[i]; \ 1507 ct[1] = t[i] + dtdu[i]*du[i]*twidth; \ 1508 ct[2] = t[i] + dtdv[i]*dv[i]*twidth; \ 1509 ct[3] = t[i] + (dtdu[i]*du[i] + dtdv[i]*dv[i])*twidth; \ 1510 vector tmp; \ 1511 tex->lookup4(tmp,cs,ct,this); \ 1512 res[i] = tmp[int(*op2)&3]; 1513 1514 #define TEXTUREFEXPR_UPDATE ++i; plStep(); 1515 1516 #define TEXTUREFEXPR_POST plEnd(); 1517 #else 1518 #define TEXTUREFEXPR_PRE 1519 #define TEXTUREFEXPR 1520 #define TEXTUREFEXPR_UPDATE 1521 #define TEXTUREFEXPR_POST 1522 #endif 1523 1524 DEFFUNC(TextureFloat ,"texture" ,"f=SFff!" ,TEXTUREFEXPR_PRE,TEXTUREFEXPR,TEXTUREFEXPR_UPDATE,TEXTUREFEXPR_POST,PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 1525 1526 1527 1528 1529 1530 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1531 // texture "c=SFff" 1532 #ifndef INIT_SHADING 1533 1534 #define TEXTURECEXPR plReady(); \ 1535 cs[0] = s[i]; \ 1536 cs[1] = s[i] + dsdu[i]*du[i]*swidth; \ 1537 cs[2] = s[i] + dsdv[i]*dv[i]*swidth; \ 1538 cs[3] = s[i] + (dsdu[i]*du[i] + dsdv[i]*dv[i])*swidth; \ 1539 ct[0] = t[i]; \ 1540 ct[1] = t[i] + dtdu[i]*du[i]*twidth; \ 1541 ct[2] = t[i] + dtdv[i]*dv[i]*twidth; \ 1542 ct[3] = t[i] + (dtdu[i]*du[i] + dtdv[i]*dv[i])*twidth; \ 1543 tex->lookup4(res,cs,ct,this); 1544 1545 #define TEXTURECEXPR_UPDATE ++i; res += 3; plStep(); 1546 1547 #define TEXTURECEXPR_POST plEnd(); 1548 1549 #else 1550 #define TEXTURECEXPR_PRE 1551 #define TEXTURECEXPR 1552 #define TEXTURECEXPR_UPDATE 1553 #define TEXTURECEXPR_POST 1554 #endif 1555 1556 DEFFUNC(TextureColor ,"texture" ,"c=SFff!" ,TEXTUREFEXPR_PRE,TEXTURECEXPR,TEXTURECEXPR_UPDATE,TEXTURECEXPR_POST,PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 1557 1558 #undef TEXTURECEXPR_PRE 1559 #undef TEXTURECEXPR 1560 #undef TEXTURECEXPR_UPDATE 1561 #undef TEXTURECEXPR_POST 1562 #undef TEXTUREFEXPR_PRE 1563 #undef TEXTUREFEXPR 1564 #undef TEXTUREFEXPR_UPDATE 1565 #undef TEXTUREFEXPR_POST 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1585 // texture "f=SFffffffff" 1586 #ifndef INIT_SHADING 1587 #define TEXTUREFFULLEXPR_PRE /* Begin the parameter list */ \ 1588 plBegin(CTextureLookup,11); \ 1589 /* Fetch the parameters as usual */ \ 1590 float *res; \ 1591 const float *op2,*op3,*op4,*op5,*op6,*op7,*op8,*op9,*op10; \ 1592 float cs[4],ct[4]; \ 1593 operand(0,res,float *); \ 1594 operand(2,op2,const float *); \ 1595 operand(3,op3,const float *); \ 1596 operand(4,op4,const float *); \ 1597 operand(5,op5,const float *); \ 1598 operand(6,op6,const float *); \ 1599 operand(7,op7,const float *); \ 1600 operand(8,op8,const float *); \ 1601 operand(9,op9,const float *); \ 1602 operand(10,op10,const float *); \ 1603 /* Get the texture */ \ 1604 CTexture *tex; \ 1605 if ((tex = lookup->map) == NULL) { \ 1606 const char **op1; \ 1607 operand(1,op1,const char **); \ 1608 osLock(CRenderer::shaderMutex); \ 1609 lookup->map = tex = CRenderer::getTexture(*op1); \ 1610 osUnlock(CRenderer::shaderMutex); \ 1611 } \ 1612 scratch->textureParams.filter = lookup->filter; 1613 1614 1615 #define TEXTUREFFULLEXPR plReady(); \ 1616 cs[0] = *op3; \ 1617 cs[1] = *op5; \ 1618 cs[2] = *op7; \ 1619 cs[3] = *op9; \ 1620 ct[0] = *op4; \ 1621 ct[1] = *op6; \ 1622 ct[2] = *op8; \ 1623 ct[3] = *op10; \ 1624 vector tmp; \ 1625 tex->lookup4(tmp,cs,ct,this); \ 1626 *res = tmp[0]; 1627 1628 #define TEXTUREFFULLEXPR_UPDATE ++res; \ 1629 ++op3; \ 1630 ++op4; \ 1631 ++op5; \ 1632 ++op6; \ 1633 ++op7; \ 1634 ++op8; \ 1635 ++op9; \ 1636 ++op10; \ 1637 plStep(); 1638 1639 1640 #define TEXTUREFFULLEXPR_POST plEnd(); 1641 1642 #else 1643 #define TEXTUREFFULLEXPR_PRE 1644 #define TEXTUREFFULLEXPR 1645 #define TEXTUREFFULLEXPR_UPDATE 1646 #define TEXTUREFFULLEXPR_POST 1647 #endif 1648 1649 DEFFUNC(TextureFloatFull ,"texture" ,"f=SFffffffff!" ,TEXTUREFFULLEXPR_PRE,TEXTUREFFULLEXPR,TEXTUREFFULLEXPR_UPDATE,TEXTUREFFULLEXPR_POST,0) 1650 1651 1652 1653 1654 1655 1656 1657 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1658 // texture "c=SFffffffff" 1659 #ifndef INIT_SHADING 1660 #define TEXTURECFULLEXPR plReady(); \ 1661 cs[0] = *op3; \ 1662 cs[1] = *op5; \ 1663 cs[2] = *op7; \ 1664 cs[3] = *op9; \ 1665 ct[0] = *op4; \ 1666 ct[1] = *op6; \ 1667 ct[2] = *op8; \ 1668 ct[3] = *op10; \ 1669 tex->lookup4(res,cs,ct,this); 1670 1671 #define TEXTURECFULLEXPR_UPDATE res += 3; \ 1672 ++op3; \ 1673 ++op4; \ 1674 ++op5; \ 1675 ++op6; \ 1676 ++op7; \ 1677 ++op8; \ 1678 ++op9; \ 1679 ++op10; \ 1680 plStep(); 1681 1682 1683 #define TEXTURECFULLEXPR_POST plEnd(); 1684 1685 #else 1686 #define TEXTURECFULLEXPR_PRE 1687 #define TEXTURECFULLEXPR 1688 #define TEXTURECFULLEXPR_UPDATE 1689 #define TEXTURECFULLEXPR_POST 1690 #endif 1691 1692 DEFFUNC(TextureColorFull ,"texture" ,"c=SFffffffff!" ,TEXTUREFFULLEXPR_PRE,TEXTURECFULLEXPR,TEXTURECFULLEXPR_UPDATE,TEXTURECFULLEXPR_POST,0) 1693 1694 #undef TEXTURECFULLEXPR_PRE 1695 #undef TEXTURECFULLEXPR 1696 #undef TEXTURECFULLEXPR_UPDATE 1697 #undef TEXTURECFULLEXPR_POST 1698 #undef TEXTUREFFULLEXPR_PRE 1699 #undef TEXTUREFFULLEXPR 1700 #undef TEXTUREFFULLEXPR_UPDATE 1701 #undef TEXTUREFFULLEXPR_POST 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1719 // 1720 // Environment / Shadow mapping macros 1721 // 1722 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1723 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1724 // environment "f=SFv" 1725 #ifndef INIT_SHADING 1726 #define ENVIRONMENTEXPR_PRE(__name) \ 1727 /* Begin the parameter list */ \ 1728 plBegin(CEnvironmentLookup,4); \ 1729 float *res; \ 1730 const char **op1; \ 1731 const float *op2; \ 1732 /* Fetch the parameters as usual */ \ 1733 operand(0,res,float *); \ 1734 operand(1,op1,const char **); \ 1735 operand(2,op2,const float *); \ 1736 /* Get the texture */ \ 1737 CEnvironment *tex = NULL; \ 1738 if ((strcmp(*op1,"raytrace") != 0) && (strcmp(*op1,__name) != 0)) { \ 1739 if ((tex = lookup->map) == NULL) { \ 1740 osLock(CRenderer::shaderMutex); \ 1741 lookup->map = tex = CRenderer::getEnvironment(*op1); \ 1742 osUnlock(CRenderer::shaderMutex); \ 1743 } \ 1744 } \ 1745 CTraceLocation *rays; \ 1746 int numRays; \ 1747 const float *P,*N; \ 1748 float *dPdu,*dPdv; \ 1749 if (tex == NULL) { \ 1750 rays = (CTraceLocation *) ralloc(currentShadingState->numVertices*sizeof(CTraceLocation),threadMemory); \ 1751 P = varying[VARIABLE_P]; \ 1752 N = varying[VARIABLE_N]; \ 1753 dPdu = varying[VARIABLE_DPDU]; \ 1754 dPdv = varying[VARIABLE_DPDV]; \ 1755 numRays = 0; \ 1756 } \ 1757 \ 1758 const float *D; \ 1759 float *dDdu = (float *) ralloc(numVertices*6*sizeof(float),threadMemory); \ 1760 float *dDdv = dDdu + numVertices*3; \ 1761 const float *du = varying[VARIABLE_DU]; \ 1762 const float *dv = varying[VARIABLE_DV]; \ 1763 const float *time = varying[VARIABLE_TIME]; \ 1764 const float swidth = (scratch->textureParams.width == 0 ? scratch->textureParams.swidth : scratch->textureParams.width); \ 1765 const float twidth = (scratch->textureParams.width == 0 ? scratch->textureParams.twidth : scratch->textureParams.width); \ 1766 operand(3,D,const float *); \ 1767 \ 1768 scratch->textureParams.filter = lookup->filter; \ 1769 \ 1770 duVector(dDdu,D); \ 1771 dvVector(dDdv,D); 1772 1773 #define ENVIRONMENTEXPR(__float) \ 1774 plReady(); \ 1775 if (tex == NULL) { \ 1776 rays->res = res; \ 1777 movvv(rays->D,D); \ 1778 mulvf(rays->dDdu,dDdu,(*du)*swidth); \ 1779 mulvf(rays->dDdv,dDdv,(*dv)*twidth); \ 1780 movvv(rays->P,P); \ 1781 mulvf(rays->dPdu,dPdu,(*du)*swidth); \ 1782 mulvf(rays->dPdv,dPdv,(*dv)*twidth); \ 1783 rays->coneAngle = max(scratch->traceParams.coneAngle,scratch->textureParams.blur); \ 1784 rays->numSamples = (int) scratch->traceParams.samples; \ 1785 rays->bias = scratch->traceParams.bias; \ 1786 rays->sampleBase = scratch->traceParams.sampleBase; \ 1787 rays->maxDist = scratch->traceParams.maxDist; \ 1788 rays->time = *time; \ 1789 ++rays; \ 1790 ++numRays; \ 1791 } else { \ 1792 vector D0,D1,D2,D3; \ 1793 mulvf(dDdu,(*du)*swidth*0.5f); \ 1794 mulvf(dDdv,(*dv)*twidth*0.5f); \ 1795 subvv(D0,D,dDdu); subvv(D0,dDdv); \ 1796 addvv(D1,D,dDdu); subvv(D1,dDdv); \ 1797 subvv(D2,D,dDdu); addvv(D2,dDdv); \ 1798 addvv(D3,D,dDdu); addvv(D3,dDdv); \ 1799 if (__float) { \ 1800 vector color; \ 1801 tex->lookup(color,D0,D1,D2,D3,this); \ 1802 *res = color[0]; \ 1803 } else { \ 1804 tex->lookup(res,D0,D1,D2,D3,this); \ 1805 } \ 1806 } 1807 1808 #define ENVIRONMENTEXPR_UPDATE(__n) \ 1809 res += __n; \ 1810 D += 3; \ 1811 dDdu += 3; \ 1812 dDdv += 3; \ 1813 ++du; \ 1814 ++dv; \ 1815 ++time; \ 1816 if (tex == NULL) { \ 1817 P += 3; \ 1818 N += 3; \ 1819 dPdu += 3; \ 1820 dPdv += 3; \ 1821 } \ 1822 plStep(); 1823 1824 1825 1826 #define ENVIRONMENTEXPR_POST(__float) \ 1827 if ((tex == NULL) && (numRays > 0)) { \ 1828 rays -= numRays; \ 1829 traceReflection(numRays,rays,FALSE); \ 1830 if (__float) { \ 1831 for (int i=numRays;i>0;--i,++rays) { \ 1832 *(rays->res) = (rays->C[0] + rays->C[1] + rays->C[2]) / 3.0f; \ 1833 } \ 1834 } else { \ 1835 for (int i=numRays;i>0;--i,++rays) movvv(rays->res,rays->C); \ 1836 } \ 1837 } \ 1838 plEnd(); 1839 1840 #else 1841 #define ENVIRONMENTEXPR_PRE 1842 #define ENVIRONMENTEXPR 1843 #define ENVIRONMENTEXPR_UPDATE 1844 #define ENVIRONMENTEXPR_POST(__float) 1845 #endif 1846 1847 DEFSHORTFUNC(EnvironmentFloat ,"environment" ,"f=SFv!" ,ENVIRONMENTEXPR_PRE("reflection"),ENVIRONMENTEXPR(TRUE),ENVIRONMENTEXPR_UPDATE(1),ENVIRONMENTEXPR_POST(TRUE),PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_TIME | PARAMETER_DERIVATIVE) 1848 DEFSHORTFUNC(EnvironmentColor ,"environment" ,"c=SFv!" ,ENVIRONMENTEXPR_PRE("reflection"),ENVIRONMENTEXPR(FALSE),ENVIRONMENTEXPR_UPDATE(3),ENVIRONMENTEXPR_POST(FALSE),PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_TIME | PARAMETER_DERIVATIVE) 1849 1850 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1851 // shadow "f=Sfv" 1852 #ifndef INIT_SHADING 1853 1854 1855 // Note: we are swapping dDdu and dDdv with dPdu and dPdv here, because 1856 // the ENVIRONMENT_PRE macro always calculates the dD differentials. 1857 // It is also very impartant that we supply dPdu and dPdv so the ray differentials 1858 // are correct or otherwise we waste time overtesselating 1859 1860 #define SHADOWEXPR_PRE ENVIRONMENTEXPR_PRE("shadow"); \ 1861 const float *L = varying[VARIABLE_L]; \ 1862 if (tex == NULL) { \ 1863 float *tmp = (float*) ralloc(currentShadingState->numVertices*sizeof(float)*9,threadMemory); \ 1864 dPdu = tmp + currentShadingState->numVertices*3; \ 1865 dPdv = dPdu + currentShadingState->numVertices*3; \ 1866 for(int v=0;v<currentShadingState->numVertices*3;v+=3) { \ 1867 subvv(tmp+v,D+v,L+v); \ 1868 } \ 1869 duVector(dPdu,tmp); \ 1870 dvVector(dPdv,tmp); \ 1871 } 1872 1873 1874 #define SHADOWEXPR(__float) plReady(); \ 1875 if (tex == NULL) { \ 1876 rays->res = res; \ 1877 movvv(rays->P,D); \ 1878 mulvf(rays->dPdu,dDdu,(*du)*swidth); \ 1879 mulvf(rays->dPdv,dDdv,(*dv)*twidth); \ 1880 subvv(rays->D,D,L); \ 1881 mulvf(rays->dDdu,dPdu,(*du)*swidth); \ 1882 mulvf(rays->dDdv,dPdv,(*dv)*twidth); \ 1883 rays->coneAngle = max(scratch->traceParams.coneAngle,scratch->textureParams.blur); \ 1884 rays->sampleBase = scratch->traceParams.sampleBase; \ 1885 rays->numSamples = (int) scratch->traceParams.samples; \ 1886 rays->bias = scratch->traceParams.bias; \ 1887 rays->maxDist = scratch->traceParams.maxDist; \ 1888 rays->time = *time; \ 1889 ++rays; \ 1890 ++numRays; \ 1891 } else { \ 1892 vector D0,D1,D2,D3; \ 1893 mulvf(dDdu,(*du)*swidth*0.5f); \ 1894 mulvf(dDdv,(*dv)*twidth*0.5f); \ 1895 subvv(D0,D,dDdu); subvv(D0,dDdv); \ 1896 addvv(D1,D,dDdu); subvv(D1,dDdv); \ 1897 subvv(D2,D,dDdu); addvv(D2,dDdv); \ 1898 addvv(D3,D,dDdu); addvv(D3,dDdv); \ 1899 if (__float) { \ 1900 vector color; \ 1901 tex->lookup(color,D0,D1,D2,D3,this); \ 1902 *res = (color[0] + color[1] + color[2])/3.0f; \ 1903 } else { \ 1904 tex->lookup(res,D0,D1,D2,D3,this); \ 1905 } \ 1906 } 1907 1908 #define SHADOWEXPR_UPDATE(__n) res +=__n; \ 1909 D += 3; \ 1910 dDdu += 3; \ 1911 dDdv += 3; \ 1912 ++du; \ 1913 ++dv; \ 1914 ++time; \ 1915 L += 3; \ 1916 if (tex == NULL) { \ 1917 dPdu += 3; \ 1918 dPdv += 3; \ 1919 } \ 1920 plStep(); 1921 1922 1923 #define SHADOWEXPR_POST(__float) \ 1924 if ((tex == NULL) && (numRays > 0)) { \ 1925 rays -= numRays; \ 1926 traceTransmission(numRays,rays,FALSE); \ 1927 if (__float) { \ 1928 for (int i=numRays;i>0;--i,++rays) { \ 1929 *(rays->res) = 1 - (rays->C[0] + rays->C[1] + rays->C[2]) / 3.0f; \ 1930 } \ 1931 } else { \ 1932 for (int i=numRays;i>0;--i,++rays) { \ 1933 res = rays->res; \ 1934 res[0] = 1 - rays->C[0]; \ 1935 res[1] = 1 - rays->C[1]; \ 1936 res[2] = 1 - rays->C[2]; \ 1937 } \ 1938 } \ 1939 } \ 1940 plEnd(); 1941 1942 #else 1943 #define SHADOWEXPR_PRE 1944 #define SHADOWEXPR 1945 #define SHADOWEXPR_UPDATE 1946 #define SHADOWEXPR_POST(__float) 1947 #endif 1948 1949 DEFSHORTFUNC(ShadowFloat ,"shadow" ,"f=SFp!" ,SHADOWEXPR_PRE,SHADOWEXPR(TRUE),SHADOWEXPR_UPDATE(1),SHADOWEXPR_POST(TRUE),PARAMETER_DU | PARAMETER_DV | PARAMETER_TIME | PARAMETER_DERIVATIVE) 1950 DEFSHORTFUNC(ShadowColor ,"shadow" ,"c=SFp!" ,SHADOWEXPR_PRE,SHADOWEXPR(FALSE),SHADOWEXPR_UPDATE(3),SHADOWEXPR_POST(FALSE),PARAMETER_DU | PARAMETER_DV | PARAMETER_TIME | PARAMETER_DERIVATIVE) 1951 1952 #undef ENVIRONMENTEXPR_PRE 1953 #undef ENVIRONMENTEXPR 1954 #undef ENVIRONMENTEXPR_UPDATE 1955 #undef ENVIRONMENTEXPR_POST 1956 1957 #undef SHADOWEXPR_PRE 1958 #undef SHADOWEXPR 1959 #undef SHADOWEXPR_UPDATE 1960 #undef SHADOWEXPR_POST 1961 1962 1963 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1964 // filterstep "f=ff!" 1965 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1966 #ifndef INIT_SHADING 1967 #define FILTERSTEP2EXPR_PRE FUN3EXPR_PRE \ 1968 plBegin(CFilterLookup,3); \ 1969 float *dsdu = (float *) ralloc(numVertices*2*sizeof(float),threadMemory); \ 1970 float *dsdv = dsdu + numVertices; \ 1971 float *fwidth = dsdu; \ 1972 const float *du = varying[VARIABLE_DU]; \ 1973 const float *dv = varying[VARIABLE_DV]; \ 1974 const float *s = op2; \ 1975 \ 1976 duFloat(dsdu,s); \ 1977 dvFloat(dsdv,s); \ 1978 for (int i=0;i<numVertices;++i) { \ 1979 dsdu[i] = fabs(dsdu[i]*du[i]); \ 1980 dsdv[i] = fabs(dsdv[i]*dv[i]); \ 1981 fwidth[i] = scratch->textureParams.width*max(dsdu[i] + dsdv[i],C_EPSILON); \ 1982 } 1983 1984 #define FILTERSTEP2EXPR plReady(); \ 1985 *res = lookup->filter(*op2,*op1,fwidth[0]); 1986 1987 1988 #define FILTERSTEP2EXPR_UPDATE plStep(); \ 1989 FUN3EXPR_UPDATE(1,1,1) \ 1990 ++fwidth; 1991 1992 #else 1993 #define FILTERSTEP2EXPR_PRE 1994 #define FILTERSTEP2EXPR 1995 #define FILTERSTEP2EXPR_UPDATE 1996 #endif 1997 1998 DEFFUNC(FilterStep2 ,"filterstep" ,"f=ff!" ,FILTERSTEP2EXPR_PRE,FILTERSTEP2EXPR,FUN3EXPR_UPDATE(1,1,1),NULL_EXPR,PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 1999 2000 2001 #undef FILTERSTEP2EXPR_PRE 2002 #undef FILTERSTEP2EXPR 2003 #undef FILTERSTEP2EXPR_UPDATE 2004 2005 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2006 // filterstep "f=fff!" 2007 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2008 #ifndef INIT_SHADING 2009 #define FILTERSTEP3EXPR_PRE FUN4EXPR_PRE \ 2010 plBegin(CFilterLookup,4); 2011 2012 #define FILTERSTEP3EXPR plReady(); \ 2013 *res = lookup->filter(0.5f*(*op2+*op3),*op1,*op3-*op2); 2014 2015 2016 #define FILTERSTEP3EXPR_UPDATE plStep(); FUN4EXPR_UPDATE(1,1,1,1) 2017 #else 2018 #define FILTERSTEP3EXPR_PRE 2019 #define FILTERSTEP3EXPR 2020 #define FILTERSTEP3EXPR_UPDATE 2021 #endif 2022 2023 DEFFUNC(FilterStep3 ,"filterstep" ,"f=fff!" ,FILTERSTEP3EXPR_PRE,FILTERSTEP3EXPR,FUN4EXPR_UPDATE(1,1,1,1),NULL_EXPR,0) 2024 2025 2026 #undef FILTERSTEP3EXPR_PRE 2027 #undef FILTERSTEP3EXPR 2028 #undef FILTERSTEP3EXPR_UPDATE 2029 2030 2031 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2032 // bake3d "f=SSpn!" 2033 #ifndef INIT_SHADING 2034 #define BAKE3DEXPR_PRE plBegin(CTexture3dLookup,5); \ 2035 CTexture3d *tex; \ 2036 if ((tex = lookup->map) == NULL) { \ 2037 const float *from,*to; \ 2038 findCoordinateSystem(scratch->texture3dParams.coordsys,from,to); \ 2039 const char **op1,**op2; \ 2040 operand(1,op1,const char **); \ 2041 operand(2,op2,const char **); \ 2042 osLock(CRenderer::shaderMutex); \ 2043 lookup->map = tex = CRenderer::getTexture3d(*op1,TRUE,*op2,from,to); \ 2044 osUnlock(CRenderer::shaderMutex); \ 2045 tex->resolve(lookup->numChannels,lookup->channelName,lookup->channelEntry,lookup->channelSize); \ 2046 } \ 2047 float *res; \ 2048 const float *op3,*op4; \ 2049 operand(0,res,float *); \ 2050 operand(3,op3,const float *); \ 2051 operand(4,op4,const float *); \ 2052 int curU=0,curV=0; \ 2053 const int uVerts = currentShadingState->numUvertices; \ 2054 const int vVerts = currentShadingState->numVvertices; \ 2055 const int doInterp = ((scratch->texture3dParams.interpolate == 1.0f) && currentShadingState->numVertices == currentShadingState->numRealVertices); \ 2056 float *dest = (float *) ralloc(tex->dataSize*sizeof(float),threadMemory); \ 2057 const float **channelValues = (const float **) ralloc(lookup->numChannels*sizeof(const float *),threadMemory); \ 2058 float *dPdu = (float *) ralloc(numVertices*6*sizeof(float),threadMemory); \ 2059 float *dPdv = dPdu + numVertices*3; \ 2060 duVector(dPdu,op3); \ 2061 dvVector(dPdv,op3); \ 2062 const float *du = varying[VARIABLE_DU]; \ 2063 const float *dv = varying[VARIABLE_DV]; \ 2064 \ 2065 for (int channel=0;channel<lookup->numChannels;++channel) { \ 2066 operand(lookup->channelIndex[channel],channelValues[channel],const float *);\ 2067 } \ 2068 \ 2069 vector P; \ 2070 float radius; 2071 2072 #define BAKE3DEXPR plReady(); \ 2073 mulvf(dPdu,*du); \ 2074 mulvf(dPdv,*dv); \ 2075 if (scratch->texture3dParams.radius > 0) { \ 2076 radius = scratch->texture3dParams.radius*scratch->texture3dParams.radiusScale; \ 2077 } else { \ 2078 radius = (lengthv(dPdu) + lengthv(dPdv))*0.5f*scratch->texture3dParams.radiusScale; \ 2079 } \ 2080 \ 2081 texture3Dflatten(dest,lookup->numChannels,channelValues,lookup->channelEntry,lookup->channelSize); \ 2082 if (doInterp == FALSE) { \ 2083 movvv(P,op3); \ 2084 tex->store(dest,P,op4,radius); \ 2085 } else if ((curU < uVerts-1) && (curV < vVerts-1)) { \ 2086 /* skip the end - do not double-bake seams */ \ 2087 P[0] = (dPdu[0] + dPdv[0])*0.5f + op3[0]; \ 2088 P[1] = (dPdu[1] + dPdv[1])*0.5f + op3[1]; \ 2089 P[2] = (dPdu[2] + dPdv[2])*0.5f + op3[2]; \ 2090 tex->store(dest,P,op4,radius); \ 2091 } \ 2092 *res = 1; 2093 2094 #define BAKE3DEXPR_UPDATE ++res; \ 2095 op3 += 3; \ 2096 op4 += 3; \ 2097 dPdu += 3; \ 2098 dPdv += 3; \ 2099 ++du; ++dv; \ 2100 ++curU; \ 2101 plStep(); \ 2102 if (curU == uVerts) { curV++; curU = 0; } \ 2103 for (int channel=0;channel<lookup->numChannels;++channel) { \ 2104 channelValues[channel] += lookup->channelSize[channel]; \ 2105 } 2106 2107 #define BAKE3DEXPR_POST plEnd(); 2108 2109 #else 2110 #define BAKE3DEXPR_PRE 2111 #define BAKE3DEXPR 2112 #define BAKE3DEXPR_UPDATE 2113 #define BAKE3DEXPR_POST 2114 #endif 2115 2116 DEFSHORTFUNC(Bake3d ,"bake3d" ,"f=SSpn!" ,BAKE3DEXPR_PRE,BAKE3DEXPR,BAKE3DEXPR_UPDATE,BAKE3DEXPR_POST,PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 2117 2118 #undef BAKE3DEXPR_PRE 2119 #undef BAKE3DEXPR 2120 #undef BAKE3DEXPR_UPDATE 2121 #undef BAKE3DEXPR_POST 2122 2123 2124 2125 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2126 // texture3d "f=Spn!" 2127 #ifndef INIT_SHADING 2128 #define TEXTURE3DEXPR_PRE plBegin(CTexture3dLookup,4); \ 2129 CTexture3d *tex; \ 2130 if ((tex = lookup->map) == NULL) { \ 2131 const float *from,*to; \ 2132 findCoordinateSystem(scratch->texture3dParams.coordsys,from,to); \ 2133 const char **op1; \ 2134 operand(1,op1,const char **); \ 2135 osLock(CRenderer::shaderMutex); \ 2136 lookup->map = tex = CRenderer::getTexture3d(*op1,FALSE,NULL,from,to); \ 2137 osUnlock(CRenderer::shaderMutex); \ 2138 tex->resolve(lookup->numChannels,lookup->channelName,lookup->channelEntry,lookup->channelSize); \ 2139 } \ 2140 float *res; \ 2141 const float *op2,*op3; \ 2142 operand(0,res,float *); \ 2143 operand(2,op2,const float *); \ 2144 operand(3,op3,const float *); \ 2145 float *dest = (float *) ralloc(tex->dataSize*sizeof(float),threadMemory); \ 2146 float **channelValues = (float **) ralloc(lookup->numChannels*sizeof(float*),threadMemory); \ 2147 float *dPdu = (float *) ralloc(numVertices*6*sizeof(float),threadMemory); \ 2148 float *dPdv = dPdu + numVertices*3; \ 2149 duVector(dPdu,op2); \ 2150 dvVector(dPdv,op2); \ 2151 const float *du = varying[VARIABLE_DU]; \ 2152 const float *dv = varying[VARIABLE_DV]; \ 2153 \ 2154 for (int channel=0;channel<lookup->numChannels;++channel) { \ 2155 operand(lookup->channelIndex[channel],channelValues[channel],float *); \ 2156 } 2157 2158 #define TEXTURE3DEXPR plReady(); \ 2159 float radius; \ 2160 mulvf(dPdu,*du); \ 2161 mulvf(dPdv,*dv); \ 2162 if (scratch->texture3dParams.radius > 0) { \ 2163 radius = scratch->texture3dParams.radius*scratch->texture3dParams.radiusScale; \ 2164 } else { \ 2165 radius = (lengthv(dPdu) + lengthv(dPdv))*0.5f*scratch->texture3dParams.radiusScale; \ 2166 } \ 2167 tex->lookup(dest,op2,op3,radius); \ 2168 texture3Dunpack(dest,lookup->numChannels,channelValues,lookup->channelEntry,lookup->channelSize); \ 2169 *res = 1; 2170 2171 #define TEXTURE3DEXPR_UPDATE ++res; \ 2172 op2 += 3; \ 2173 op3 += 3; \ 2174 dPdu += 3; \ 2175 dPdv += 3; \ 2176 ++du; ++dv; \ 2177 plStep(); \ 2178 for (int channel=0;channel<lookup->numChannels;++channel) { \ 2179 channelValues[channel] += lookup->channelSize[channel]; \ 2180 } 2181 2182 #define TEXTURE3DEXPR_POST plEnd(); 2183 #else 2184 #define TEXTURE3DEXPR_PRE 2185 #define TEXTURE3DEXPR 2186 #define TEXTURE3DEXPR_UPDATE 2187 #define TEXTURE3DEXPR_POST 2188 #endif 2189 2190 DEFFUNC(Texture3d ,"texture3d" ,"f=Spn!" ,TEXTURE3DEXPR_PRE,TEXTURE3DEXPR,TEXTURE3DEXPR_UPDATE,TEXTURE3DEXPR_POST,PARAMETER_DPDU | PARAMETER_DPDV | PARAMETER_DU | PARAMETER_DV | PARAMETER_DERIVATIVE) 2191 2192 #undef TEXTURE3DEXPR_PRE 2193 #undef TEXTURE3DEXPR 2194 #undef TEXTURE3DEXPR_UPDATE 2195 #undef TEXTURE3DEXPR_POST 2196 2197 2198 /////////////////////////////////////////////////// 2199 // 2200 // FIXME : missing functions : 2201 // bump 2202 2203 2204 #include "giFunctions.h" 2205 2206