light.cpp revision 69ca17a12444ef619952b783ddaac121a0d438e5
1/* libs/opengles/light.cpp 2** 3** Copyright 2006, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18#include <stdio.h> 19#include "context.h" 20#include "fp.h" 21#include "light.h" 22#include "state.h" 23#include "matrix.h" 24 25 26#if defined(__arm__) && defined(__thumb__) 27#warning "light.cpp should not be compiled in thumb on ARM." 28#endif 29 30namespace android { 31 32// ---------------------------------------------------------------------------- 33 34static void invalidate_lighting(ogles_context_t* c); 35static void lightVertexValidate(ogles_context_t* c, vertex_t* v); 36static void lightVertexNop(ogles_context_t* c, vertex_t* v); 37static void lightVertex(ogles_context_t* c, vertex_t* v); 38static void lightVertexMaterial(ogles_context_t* c, vertex_t* v); 39 40static inline void vscale3(GLfixed* d, const GLfixed* m, GLfixed s); 41 42static __attribute__((noinline)) 43void vnorm3(GLfixed* d, const GLfixed* a); 44 45static inline void vsa3(GLfixed* d, 46 const GLfixed* m, GLfixed s, const GLfixed* a); 47static inline void vss3(GLfixed* d, 48 const GLfixed* m, GLfixed s, const GLfixed* a); 49static inline void vmla3(GLfixed* d, 50 const GLfixed* m0, const GLfixed* m1, const GLfixed* a); 51static inline void vmul3(GLfixed* d, 52 const GLfixed* m0, const GLfixed* m1); 53 54static GLfixed fog_linear(ogles_context_t* c, GLfixed z); 55static GLfixed fog_exp(ogles_context_t* c, GLfixed z); 56static GLfixed fog_exp2(ogles_context_t* c, GLfixed z); 57 58 59// ---------------------------------------------------------------------------- 60 61static void init_white(vec4_t& c) { 62 c.r = c.g = c.b = c.a = 0x10000; 63} 64 65void ogles_init_light(ogles_context_t* c) 66{ 67 for (unsigned int i=0 ; i<OGLES_MAX_LIGHTS ; i++) { 68 c->lighting.lights[i].ambient.a = 0x10000; 69 c->lighting.lights[i].position.z = 0x10000; 70 c->lighting.lights[i].spotDir.z = -0x10000; 71 c->lighting.lights[i].spotCutoff = gglIntToFixed(180); 72 c->lighting.lights[i].attenuation[0] = 0x10000; 73 } 74 init_white(c->lighting.lights[0].diffuse); 75 init_white(c->lighting.lights[0].specular); 76 77 c->lighting.front.ambient.r = 78 c->lighting.front.ambient.g = 79 c->lighting.front.ambient.b = gglFloatToFixed(0.2f); 80 c->lighting.front.ambient.a = 0x10000; 81 c->lighting.front.diffuse.r = 82 c->lighting.front.diffuse.g = 83 c->lighting.front.diffuse.b = gglFloatToFixed(0.8f); 84 c->lighting.front.diffuse.a = 0x10000; 85 c->lighting.front.specular.a = 0x10000; 86 c->lighting.front.emission.a = 0x10000; 87 88 c->lighting.lightModel.ambient.r = 89 c->lighting.lightModel.ambient.g = 90 c->lighting.lightModel.ambient.b = gglFloatToFixed(0.2f); 91 c->lighting.lightModel.ambient.a = 0x10000; 92 93 c->lighting.colorMaterial.face = GL_FRONT_AND_BACK; 94 c->lighting.colorMaterial.mode = GL_AMBIENT_AND_DIFFUSE; 95 96 c->fog.mode = GL_EXP; 97 c->fog.fog = fog_exp; 98 c->fog.density = 0x10000; 99 c->fog.end = 0x10000; 100 c->fog.invEndMinusStart = 0x10000; 101 102 invalidate_lighting(c); 103 104 c->rasterizer.procs.shadeModel(c, GL_SMOOTH); 105 c->lighting.shadeModel = GL_SMOOTH; 106} 107 108void ogles_uninit_light(ogles_context_t* c) 109{ 110} 111 112static inline int32_t clampF(GLfixed f) CONST; 113int32_t clampF(GLfixed f) { 114 f = (f & ~(f>>31)); 115 if (f >= 0x10000) 116 f = 0x10000; 117 return f; 118} 119 120static GLfixed fog_linear(ogles_context_t* c, GLfixed z) { 121 return clampF(gglMulx((c->fog.end - ((z<0)?-z:z)), c->fog.invEndMinusStart)); 122} 123 124static GLfixed fog_exp(ogles_context_t* c, GLfixed z) { 125 const float e = fixedToFloat(gglMulx(c->fog.density, ((z<0)?-z:z))); 126 return clampF(gglFloatToFixed(fastexpf(-e))); 127} 128 129static GLfixed fog_exp2(ogles_context_t* c, GLfixed z) { 130 const float e = fixedToFloat(gglMulx(c->fog.density, z)); 131 return clampF(gglFloatToFixed(fastexpf(-e*e))); 132} 133 134// ---------------------------------------------------------------------------- 135#if 0 136#pragma mark - 137#pragma mark math helpers 138#endif 139 140static inline 141void vscale3(GLfixed* d, const GLfixed* m, GLfixed s) { 142 d[0] = gglMulx(m[0], s); 143 d[1] = gglMulx(m[1], s); 144 d[2] = gglMulx(m[2], s); 145} 146 147static inline 148void vsa3(GLfixed* d, const GLfixed* m, GLfixed s, const GLfixed* a) { 149 d[0] = gglMulAddx(m[0], s, a[0]); 150 d[1] = gglMulAddx(m[1], s, a[1]); 151 d[2] = gglMulAddx(m[2], s, a[2]); 152} 153 154static inline 155void vss3(GLfixed* d, const GLfixed* m, GLfixed s, const GLfixed* a) { 156 d[0] = gglMulSubx(m[0], s, a[0]); 157 d[1] = gglMulSubx(m[1], s, a[1]); 158 d[2] = gglMulSubx(m[2], s, a[2]); 159} 160 161static inline 162void vmla3(GLfixed* d, 163 const GLfixed* m0, const GLfixed* m1, const GLfixed* a) 164{ 165 d[0] = gglMulAddx(m0[0], m1[0], a[0]); 166 d[1] = gglMulAddx(m0[1], m1[1], a[1]); 167 d[2] = gglMulAddx(m0[2], m1[2], a[2]); 168} 169 170static inline 171void vmul3(GLfixed* d, const GLfixed* m0, const GLfixed* m1) { 172 d[0] = gglMulx(m0[0], m1[0]); 173 d[1] = gglMulx(m0[1], m1[1]); 174 d[2] = gglMulx(m0[2], m1[2]); 175} 176 177void vnorm3(GLfixed* d, const GLfixed* a) 178{ 179 // we must take care of overflows when normalizing a vector 180 GLfixed n; 181 int32_t x = a[0]; x = x>=0 ? x : -x; 182 int32_t y = a[1]; y = y>=0 ? y : -y; 183 int32_t z = a[2]; z = z>=0 ? z : -z; 184 if (ggl_likely(x<=0x6800 && y<=0x6800 && z<= 0x6800)) { 185 // in this case this will all fit on 32 bits 186 n = x*x + y*y + z*z; 187 n = gglSqrtRecipx(n); 188 n <<= 8; 189 } else { 190 // here norm^2 is at least 0x7EC00000 (>>32 == 0.495117) 191 n = vsquare3(x, y, z); 192 n = gglSqrtRecipx(n); 193 } 194 vscale3(d, a, n); 195} 196 197// ---------------------------------------------------------------------------- 198#if 0 199#pragma mark - 200#pragma mark lighting equations 201#endif 202 203static inline void light_picker(ogles_context_t* c) 204{ 205 if (ggl_likely(!c->lighting.enable)) { 206 c->lighting.lightVertex = lightVertexNop; 207 return; 208 } 209 if (c->lighting.colorMaterial.enable) { 210 c->lighting.lightVertex = lightVertexMaterial; 211 } else { 212 c->lighting.lightVertex = lightVertex; 213 } 214} 215 216static inline void validate_light_mvi(ogles_context_t* c) 217{ 218 uint32_t en = c->lighting.enabledLights; 219 while (en) { 220 const int i = 31 - gglClz(en); 221 en &= ~(1<<i); 222 light_t& l = c->lighting.lights[i]; 223 c->transforms.mvui.point4(&c->transforms.mvui, 224 &l.objPosition, &l.position); 225 vnorm3(l.normalizedObjPosition.v, l.objPosition.v); 226 } 227} 228 229static inline void validate_light(ogles_context_t* c) 230{ 231 // if colorMaterial is enabled, we get the color from the vertex 232 if (!c->lighting.colorMaterial.enable) { 233 material_t& material = c->lighting.front; 234 uint32_t en = c->lighting.enabledLights; 235 while (en) { 236 const int i = 31 - gglClz(en); 237 en &= ~(1<<i); 238 light_t& l = c->lighting.lights[i]; 239 vmul3(l.implicitAmbient.v, material.ambient.v, l.ambient.v); 240 vmul3(l.implicitDiffuse.v, material.diffuse.v, l.diffuse.v); 241 vmul3(l.implicitSpecular.v, material.specular.v, l.specular.v); 242 243 // this is just a flag to tell if we have a specular component 244 l.implicitSpecular.v[3] = 245 l.implicitSpecular.r | 246 l.implicitSpecular.g | 247 l.implicitSpecular.b; 248 249 l.rConstAttenuation = (l.attenuation[1] | l.attenuation[2])==0; 250 if (l.rConstAttenuation) 251 l.rConstAttenuation = gglRecipFast(l.attenuation[0]); 252 } 253 // emission and ambient for the whole scene 254 vmla3( c->lighting.implicitSceneEmissionAndAmbient.v, 255 c->lighting.lightModel.ambient.v, 256 material.ambient.v, 257 material.emission.v); 258 c->lighting.implicitSceneEmissionAndAmbient.a = material.diffuse.a; 259 } 260 validate_light_mvi(c); 261} 262 263void invalidate_lighting(ogles_context_t* c) 264{ 265 // TODO: pick lightVertexValidate or lightVertexValidateMVI 266 // instead of systematically the heavier lightVertexValidate() 267 c->lighting.lightVertex = lightVertexValidate; 268} 269 270void ogles_invalidate_lighting_mvui(ogles_context_t* c) 271{ 272 invalidate_lighting(c); 273} 274 275void lightVertexNop(ogles_context_t*, vertex_t* v) 276{ 277 // we should never end-up here 278} 279 280void lightVertexValidateMVI(ogles_context_t* c, vertex_t* v) 281{ 282 validate_light_mvi(c); 283 light_picker(c); 284 c->lighting.lightVertex(c, v); 285} 286 287void lightVertexValidate(ogles_context_t* c, vertex_t* v) 288{ 289 validate_light(c); 290 light_picker(c); 291 c->lighting.lightVertex(c, v); 292} 293 294void lightVertexMaterial(ogles_context_t* c, vertex_t* v) 295{ 296 // fetch the material color 297 const GLvoid* cp = c->arrays.color.element( 298 v->index & vertex_cache_t::INDEX_MASK); 299 c->arrays.color.fetch(c, v->color.v, cp); 300 301 // acquire the color-material from the vertex 302 material_t& material = c->lighting.front; 303 material.ambient = 304 material.diffuse = v->color; 305 // implicit arguments need to be computed per/vertex 306 uint32_t en = c->lighting.enabledLights; 307 while (en) { 308 const int i = 31 - gglClz(en); 309 en &= ~(1<<i); 310 light_t& l = c->lighting.lights[i]; 311 vmul3(l.implicitAmbient.v, material.ambient.v, l.ambient.v); 312 vmul3(l.implicitDiffuse.v, material.diffuse.v, l.diffuse.v); 313 vmul3(l.implicitSpecular.v, material.specular.v, l.specular.v); 314 // this is just a flag to tell if we have a specular component 315 l.implicitSpecular.v[3] = 316 l.implicitSpecular.r | 317 l.implicitSpecular.g | 318 l.implicitSpecular.b; 319 } 320 // emission and ambient for the whole scene 321 vmla3( c->lighting.implicitSceneEmissionAndAmbient.v, 322 c->lighting.lightModel.ambient.v, 323 material.ambient.v, 324 material.emission.v); 325 c->lighting.implicitSceneEmissionAndAmbient.a = material.diffuse.a; 326 327 // now we can light our vertex as usual 328 lightVertex(c, v); 329} 330 331void lightVertex(ogles_context_t* c, vertex_t* v) 332{ 333 // emission and ambient for the whole scene 334 vec4_t r = c->lighting.implicitSceneEmissionAndAmbient; 335 336 uint32_t en = c->lighting.enabledLights; 337 if (ggl_likely(en)) { 338 // since we do the lighting in object-space, we don't need to 339 // transform each normal. However, we might still have to normalize 340 // it if GL_NORMALIZE is enabled. 341 vec4_t n; 342 c->arrays.normal.fetch(c, n.v, 343 c->arrays.normal.element(v->index & vertex_cache_t::INDEX_MASK)); 344 345 // TODO: right now we handle GL_RESCALE_NORMALS as if ti were 346 // GL_NORMALIZE. We could optimize this by scaling mvui 347 // appropriately instead. 348 if (c->transforms.rescaleNormals) 349 vnorm3(n.v, n.v); 350 351 const material_t& material = c->lighting.front; 352 const int twoSide = c->lighting.lightModel.twoSide; 353 354 while (en) { 355 const int i = 31 - gglClz(en); 356 en &= ~(1<<i); 357 const light_t& l = c->lighting.lights[i]; 358 359 vec4_t d, t; 360 GLfixed s; 361 GLfixed sqDist = 0x10000; 362 363 // compute vertex-to-light vector 364 if (ggl_unlikely(l.position.w)) { 365 // lightPos/1.0 - vertex/vertex.w == lightPos*vertex.w - vertex 366 vss3(d.v, l.objPosition.v, v->obj.w, v->obj.v); 367 sqDist = dot3(d.v, d.v); 368 vscale3(d.v, d.v, gglSqrtRecipx(sqDist)); 369 } else { 370 // TODO: avoid copy here 371 d = l.normalizedObjPosition; 372 } 373 374 // ambient & diffuse 375 s = dot3(n.v, d.v); 376 s = (s<0) ? (twoSide?(-s):0) : s; 377 vsa3(t.v, l.implicitDiffuse.v, s, l.implicitAmbient.v); 378 379 // specular 380 if (ggl_unlikely(s && l.implicitSpecular.v[3])) { 381 vec4_t h; 382 h.x = d.x; 383 h.y = d.y; 384 h.z = d.z + 0x10000; 385 vnorm3(h.v, h.v); 386 s = dot3(n.v, h.v); 387 s = (s<0) ? (twoSide?(-s):0) : s; 388 if (s > 0) { 389 s = gglPowx(s, material.shininess); 390 vsa3(t.v, l.implicitSpecular.v, s, t.v); 391 } 392 } 393 394 // spot 395 if (ggl_unlikely(l.spotCutoff != gglIntToFixed(180))) { 396 GLfixed spotAtt = -dot3(l.normalizedSpotDir.v, d.v); 397 if (spotAtt >= l.spotCutoffCosine) { 398 vscale3(t.v, t.v, gglPowx(spotAtt, l.spotExp)); 399 } 400 } 401 402 // attenuation 403 if (ggl_unlikely(l.position.w)) { 404 if (l.rConstAttenuation) { 405 s = l.rConstAttenuation; 406 } else { 407 s = gglMulAddx(sqDist, l.attenuation[2], l.attenuation[0]); 408 if (l.attenuation[1]) 409 s = gglMulAddx(gglSqrtx(sqDist), l.attenuation[1], s); 410 s = gglRecipFast(s); 411 } 412 vscale3(t.v, t.v, s); 413 } 414 415 r.r += t.r; 416 r.g += t.g; 417 r.b += t.b; 418 } 419 } 420 v->color.r = gglClampx(r.r); 421 v->color.g = gglClampx(r.g); 422 v->color.b = gglClampx(r.b); 423 v->color.a = gglClampx(r.a); 424 v->flags |= vertex_t::LIT; 425} 426 427static void lightModelx(GLenum pname, GLfixed param, ogles_context_t* c) 428{ 429 if (ggl_unlikely(pname != GL_LIGHT_MODEL_TWO_SIDE)) { 430 ogles_error(c, GL_INVALID_ENUM); 431 return; 432 } 433 c->lighting.lightModel.twoSide = param ? GL_TRUE : GL_FALSE; 434 invalidate_lighting(c); 435} 436 437static void lightx(GLenum i, GLenum pname, GLfixed param, ogles_context_t* c) 438{ 439 if (ggl_unlikely(uint32_t(i-GL_LIGHT0) >= OGLES_MAX_LIGHTS)) { 440 ogles_error(c, GL_INVALID_ENUM); 441 return; 442 } 443 444 light_t& light = c->lighting.lights[i-GL_LIGHT0]; 445 const GLfixed kDegToRad = GLfixed((M_PI * gglIntToFixed(1)) / 180.0f); 446 switch (pname) { 447 case GL_SPOT_EXPONENT: 448 if (GGLfixed(param) >= gglIntToFixed(128)) { 449 ogles_error(c, GL_INVALID_VALUE); 450 return; 451 } 452 light.spotExp = param; 453 break; 454 case GL_SPOT_CUTOFF: 455 if (param!=gglIntToFixed(180) && GGLfixed(param)>=gglIntToFixed(90)) { 456 ogles_error(c, GL_INVALID_VALUE); 457 return; 458 } 459 light.spotCutoff = param; 460 light.spotCutoffCosine = 461 gglFloatToFixed(cosinef((M_PI/(180.0f*65536.0f))*param)); 462 break; 463 case GL_CONSTANT_ATTENUATION: 464 if (param < 0) { 465 ogles_error(c, GL_INVALID_VALUE); 466 return; 467 } 468 light.attenuation[0] = param; 469 break; 470 case GL_LINEAR_ATTENUATION: 471 if (param < 0) { 472 ogles_error(c, GL_INVALID_VALUE); 473 return; 474 } 475 light.attenuation[1] = param; 476 break; 477 case GL_QUADRATIC_ATTENUATION: 478 if (param < 0) { 479 ogles_error(c, GL_INVALID_VALUE); 480 return; 481 } 482 light.attenuation[2] = param; 483 break; 484 default: 485 ogles_error(c, GL_INVALID_ENUM); 486 return; 487 } 488 invalidate_lighting(c); 489} 490 491static void lightxv(GLenum i, GLenum pname, const GLfixed *params, ogles_context_t* c) 492{ 493 if (ggl_unlikely(uint32_t(i-GL_LIGHT0) >= OGLES_MAX_LIGHTS)) { 494 ogles_error(c, GL_INVALID_ENUM); 495 return; 496 } 497 498 GLfixed* what; 499 light_t& light = c->lighting.lights[i-GL_LIGHT0]; 500 switch (pname) { 501 case GL_AMBIENT: 502 what = light.ambient.v; 503 break; 504 case GL_DIFFUSE: 505 what = light.diffuse.v; 506 break; 507 case GL_SPECULAR: 508 what = light.specular.v; 509 break; 510 case GL_POSITION: { 511 ogles_validate_transform(c, transform_state_t::MODELVIEW); 512 transform_t& mv = c->transforms.modelview.transform; 513 memcpy(light.position.v, params, sizeof(light.position.v)); 514 mv.point4(&mv, &light.position, &light.position); 515 invalidate_lighting(c); 516 return; 517 } 518 case GL_SPOT_DIRECTION: { 519 ogles_validate_transform(c, transform_state_t::MVUI); 520 transform_t& mvui = c->transforms.mvui; 521 mvui.point3(&mvui, &light.spotDir, (vec4_t*)params); 522 vnorm3(light.normalizedSpotDir.v, light.spotDir.v); 523 invalidate_lighting(c); 524 return; 525 } 526 default: 527 lightx(i, pname, params[0], c); 528 return; 529 } 530 what[0] = params[0]; 531 what[1] = params[1]; 532 what[2] = params[2]; 533 what[3] = params[3]; 534 invalidate_lighting(c); 535} 536 537static void materialx(GLenum face, GLenum pname, GLfixed param, ogles_context_t* c) 538{ 539 if (ggl_unlikely(face != GL_FRONT_AND_BACK)) { 540 ogles_error(c, GL_INVALID_ENUM); 541 return; 542 } 543 if (ggl_unlikely(pname != GL_SHININESS)) { 544 ogles_error(c, GL_INVALID_ENUM); 545 return; 546 } 547 c->lighting.front.shininess = param; 548 invalidate_lighting(c); 549} 550 551static void fogx(GLenum pname, GLfixed param, ogles_context_t* c) 552{ 553 switch (pname) { 554 case GL_FOG_DENSITY: 555 if (param >= 0) { 556 c->fog.density = param; 557 break; 558 } 559 ogles_error(c, GL_INVALID_VALUE); 560 break; 561 case GL_FOG_START: 562 c->fog.start = param; 563 c->fog.invEndMinusStart = gglRecip(c->fog.end - c->fog.start); 564 break; 565 case GL_FOG_END: 566 c->fog.end = param; 567 c->fog.invEndMinusStart = gglRecip(c->fog.end - c->fog.start); 568 break; 569 case GL_FOG_MODE: 570 switch (param) { 571 case GL_LINEAR: 572 c->fog.mode = param; 573 c->fog.fog = fog_linear; 574 break; 575 case GL_EXP: 576 c->fog.mode = param; 577 c->fog.fog = fog_exp; 578 break; 579 case GL_EXP2: 580 c->fog.mode = param; 581 c->fog.fog = fog_exp2; 582 break; 583 default: 584 ogles_error(c, GL_INVALID_ENUM); 585 break; 586 } 587 break; 588 default: 589 ogles_error(c, GL_INVALID_ENUM); 590 break; 591 } 592} 593 594// ---------------------------------------------------------------------------- 595}; // namespace android 596// ---------------------------------------------------------------------------- 597 598using namespace android; 599 600#if 0 601#pragma mark - 602#pragma mark lighting APIs 603#endif 604 605void glShadeModel(GLenum mode) 606{ 607 ogles_context_t* c = ogles_context_t::get(); 608 if (ggl_unlikely(mode != GL_SMOOTH && mode != GL_FLAT)) { 609 ogles_error(c, GL_INVALID_ENUM); 610 return; 611 } 612 c->lighting.shadeModel = mode; 613} 614 615void glLightModelf(GLenum pname, GLfloat param) 616{ 617 ogles_context_t* c = ogles_context_t::get(); 618 lightModelx(pname, gglFloatToFixed(param), c); 619} 620 621void glLightModelx(GLenum pname, GLfixed param) 622{ 623 ogles_context_t* c = ogles_context_t::get(); 624 lightModelx(pname, param, c); 625} 626 627void glLightModelfv(GLenum pname, const GLfloat *params) 628{ 629 ogles_context_t* c = ogles_context_t::get(); 630 if (pname == GL_LIGHT_MODEL_TWO_SIDE) { 631 lightModelx(pname, gglFloatToFixed(params[0]), c); 632 return; 633 } 634 635 if (ggl_unlikely(pname != GL_LIGHT_MODEL_AMBIENT)) { 636 ogles_error(c, GL_INVALID_ENUM); 637 return; 638 } 639 640 c->lighting.lightModel.ambient.r = gglFloatToFixed(params[0]); 641 c->lighting.lightModel.ambient.g = gglFloatToFixed(params[1]); 642 c->lighting.lightModel.ambient.b = gglFloatToFixed(params[2]); 643 c->lighting.lightModel.ambient.a = gglFloatToFixed(params[3]); 644 invalidate_lighting(c); 645} 646 647void glLightModelxv(GLenum pname, const GLfixed *params) 648{ 649 ogles_context_t* c = ogles_context_t::get(); 650 if (pname == GL_LIGHT_MODEL_TWO_SIDE) { 651 lightModelx(pname, params[0], c); 652 return; 653 } 654 655 if (ggl_unlikely(pname != GL_LIGHT_MODEL_AMBIENT)) { 656 ogles_error(c, GL_INVALID_ENUM); 657 return; 658 } 659 660 c->lighting.lightModel.ambient.r = params[0]; 661 c->lighting.lightModel.ambient.g = params[1]; 662 c->lighting.lightModel.ambient.b = params[2]; 663 c->lighting.lightModel.ambient.a = params[3]; 664 invalidate_lighting(c); 665} 666 667// ---------------------------------------------------------------------------- 668#if 0 669#pragma mark - 670#endif 671 672void glLightf(GLenum i, GLenum pname, GLfloat param) 673{ 674 ogles_context_t* c = ogles_context_t::get(); 675 lightx(i, pname, gglFloatToFixed(param), c); 676} 677 678void glLightx(GLenum i, GLenum pname, GLfixed param) 679{ 680 ogles_context_t* c = ogles_context_t::get(); 681 lightx(i, pname, param, c); 682} 683 684void glLightfv(GLenum i, GLenum pname, const GLfloat *params) 685{ 686 ogles_context_t* c = ogles_context_t::get(); 687 switch (pname) { 688 case GL_SPOT_EXPONENT: 689 case GL_SPOT_CUTOFF: 690 case GL_CONSTANT_ATTENUATION: 691 case GL_LINEAR_ATTENUATION: 692 case GL_QUADRATIC_ATTENUATION: 693 lightx(i, pname, gglFloatToFixed(params[0]), c); 694 return; 695 } 696 697 GLfixed paramsx[4]; 698 paramsx[0] = gglFloatToFixed(params[0]); 699 paramsx[1] = gglFloatToFixed(params[1]); 700 paramsx[2] = gglFloatToFixed(params[2]); 701 if (pname != GL_SPOT_DIRECTION) 702 paramsx[3] = gglFloatToFixed(params[3]); 703 704 lightxv(i, pname, paramsx, c); 705} 706 707void glLightxv(GLenum i, GLenum pname, const GLfixed *params) 708{ 709 ogles_context_t* c = ogles_context_t::get(); 710 lightxv(i, pname, params, c); 711} 712 713// ---------------------------------------------------------------------------- 714#if 0 715#pragma mark - 716#endif 717 718void glMaterialf(GLenum face, GLenum pname, GLfloat param) 719{ 720 ogles_context_t* c = ogles_context_t::get(); 721 materialx(face, pname, gglFloatToFixed(param), c); 722} 723 724void glMaterialx(GLenum face, GLenum pname, GLfixed param) 725{ 726 ogles_context_t* c = ogles_context_t::get(); 727 materialx(face, pname, param, c); 728} 729 730void glMaterialfv( 731 GLenum face, GLenum pname, const GLfloat *params) 732{ 733 ogles_context_t* c = ogles_context_t::get(); 734 if (ggl_unlikely(face != GL_FRONT_AND_BACK)) { 735 ogles_error(c, GL_INVALID_ENUM); 736 return; 737 } 738 GLfixed* what=0; 739 GLfixed* other=0; 740 switch (pname) { 741 case GL_AMBIENT: what = c->lighting.front.ambient.v; break; 742 case GL_DIFFUSE: what = c->lighting.front.diffuse.v; break; 743 case GL_SPECULAR: what = c->lighting.front.specular.v; break; 744 case GL_EMISSION: what = c->lighting.front.emission.v; break; 745 case GL_AMBIENT_AND_DIFFUSE: 746 what = c->lighting.front.ambient.v; break; 747 other = c->lighting.front.diffuse.v; break; 748 break; 749 case GL_SHININESS: 750 c->lighting.front.shininess = gglFloatToFixed(params[0]); 751 invalidate_lighting(c); 752 return; 753 default: 754 ogles_error(c, GL_INVALID_ENUM); 755 return; 756 } 757 what[0] = gglFloatToFixed(params[0]); 758 what[1] = gglFloatToFixed(params[1]); 759 what[2] = gglFloatToFixed(params[2]); 760 what[3] = gglFloatToFixed(params[3]); 761 if (other) { 762 other[0] = what[0]; 763 other[1] = what[1]; 764 other[2] = what[2]; 765 other[3] = what[3]; 766 } 767 invalidate_lighting(c); 768} 769 770void glMaterialxv( 771 GLenum face, GLenum pname, const GLfixed *params) 772{ 773 ogles_context_t* c = ogles_context_t::get(); 774 if (ggl_unlikely(face != GL_FRONT_AND_BACK)) { 775 ogles_error(c, GL_INVALID_ENUM); 776 return; 777 } 778 GLfixed* what=0; 779 GLfixed* other=0; 780 switch (pname) { 781 case GL_AMBIENT: what = c->lighting.front.ambient.v; break; 782 case GL_DIFFUSE: what = c->lighting.front.diffuse.v; break; 783 case GL_SPECULAR: what = c->lighting.front.specular.v; break; 784 case GL_EMISSION: what = c->lighting.front.emission.v; break; 785 case GL_AMBIENT_AND_DIFFUSE: 786 what = c->lighting.front.ambient.v; break; 787 other= c->lighting.front.diffuse.v; break; 788 break; 789 case GL_SHININESS: 790 c->lighting.front.shininess = gglFloatToFixed(params[0]); 791 invalidate_lighting(c); 792 return; 793 default: 794 ogles_error(c, GL_INVALID_ENUM); 795 return; 796 } 797 what[0] = params[0]; 798 what[1] = params[1]; 799 what[2] = params[2]; 800 what[3] = params[3]; 801 if (other) { 802 other[0] = what[0]; 803 other[1] = what[1]; 804 other[2] = what[2]; 805 other[3] = what[3]; 806 } 807 invalidate_lighting(c); 808} 809 810// ---------------------------------------------------------------------------- 811#if 0 812#pragma mark - 813#pragma mark fog 814#endif 815 816void glFogf(GLenum pname, GLfloat param) { 817 ogles_context_t* c = ogles_context_t::get(); 818 GLfixed paramx = (GLfixed)param; 819 if (pname != GL_FOG_MODE) 820 paramx = gglFloatToFixed(param); 821 fogx(pname, paramx, c); 822} 823 824void glFogx(GLenum pname, GLfixed param) { 825 ogles_context_t* c = ogles_context_t::get(); 826 fogx(pname, param, c); 827} 828 829void glFogfv(GLenum pname, const GLfloat *params) 830{ 831 ogles_context_t* c = ogles_context_t::get(); 832 if (pname != GL_FOG_COLOR) { 833 GLfixed paramx = (GLfixed)params[0]; 834 if (pname != GL_FOG_MODE) 835 paramx = gglFloatToFixed(params[0]); 836 fogx(pname, paramx, c); 837 return; 838 } 839 GLfixed paramsx[4]; 840 paramsx[0] = gglFloatToFixed(params[0]); 841 paramsx[1] = gglFloatToFixed(params[1]); 842 paramsx[2] = gglFloatToFixed(params[2]); 843 paramsx[3] = gglFloatToFixed(params[3]); 844 c->rasterizer.procs.fogColor3xv(c, paramsx); 845} 846 847void glFogxv(GLenum pname, const GLfixed *params) 848{ 849 ogles_context_t* c = ogles_context_t::get(); 850 if (pname != GL_FOG_COLOR) { 851 fogx(pname, params[0], c); 852 return; 853 } 854 c->rasterizer.procs.fogColor3xv(c, params); 855} 856