light.cpp 26 KB

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