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