/opengles/ug/uglu.c

http://ftk.googlecode.com/ · C · 267 lines · 189 code · 50 blank · 28 comment · 19 complexity · 4d72c6fa943dd04ea64ef699dc0a9a41 MD5 · raw file

  1. /*
  2. * GLESonGL implementation
  3. * Version: 1.0
  4. *
  5. * Copyright (C) 2003 David Blythe All Rights Reserved.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the "Software"),
  9. * to deal in the Software without restriction, including without limitation
  10. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11. * and/or sell copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included
  15. * in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * DAVID BLYTHE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  21. * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. */
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <GLES/egl.h>
  27. #define __GL_FLOAT
  28. #ifdef __GL_FLOAT
  29. #include <math.h>
  30. #endif
  31. typedef long long __int64;
  32. #define __f2x(f) ((int)(f*65536))
  33. #define __mulx(a,b) ((((__int64)(a))*(b))>>16)
  34. #define __divx(a,b) (((__int64)(a)<<16)/(b))
  35. #define __PI 3.14159265358979323846f
  36. static const unsigned short __gl_sin_tab[] = {
  37. #include "gl_sin.h"
  38. };
  39. GLfixed
  40. __cosx(GLfixed a) {
  41. GLfixed v;
  42. /* reduce to [0,1) */
  43. while (a < 0) a += 2*__f2x(__PI);
  44. a *= __f2x(1.0f/(2.f*__PI));
  45. a >>= 16;
  46. a += 0x4000;
  47. /* now in the range [0, 0xffff], reduce to [0, 0xfff] */
  48. a >>= 4;
  49. v = (a & 0x400) ? __gl_sin_tab[0x3ff - (a & 0x3ff)] : __gl_sin_tab[a & 0x3ff];
  50. v = __mulx(v,__f2x(1));
  51. return (a & 0x800) ? -v : v;
  52. }
  53. GLfixed
  54. __sinx(GLfixed a) {
  55. GLfixed v;
  56. /* reduce to [0,1) */
  57. while (a < 0) a += 2*__f2x(__PI);
  58. a *= __f2x(1.0f/(2.f*__PI));
  59. a >>= 16;
  60. /* now in the range [0, 0xffff], reduce to [0, 0xfff] */
  61. a >>= 4;
  62. v = (a & 0x400) ? __gl_sin_tab[0x3ff - (a & 0x3ff)] : __gl_sin_tab[a & 0x3ff];
  63. v = __mulx(v,__f2x(1));
  64. return (a & 0x800) ? -v : v;
  65. }
  66. #ifdef __GL_FLOAT
  67. static void
  68. __identf(GLfloat m[]) {
  69. memset(m, 0, sizeof m[0]*16);
  70. m[0] = m[5] = m[10] = m[15] = 1.0f;
  71. }
  72. #endif
  73. static void
  74. __identx(GLfixed m[]) {
  75. memset(m, 0, sizeof m[0]*16);
  76. m[0] = m[5] = m[10] = m[15] = __f2x(1.0f);
  77. }
  78. #ifdef __GL_FLOAT
  79. void APIENTRY
  80. ugluPerspectivef(GLfloat fovy, GLfloat aspect, GLfloat n, GLfloat f)
  81. {
  82. GLfloat m[4][4];
  83. GLfloat s, cot, dz = f - n;
  84. GLfloat rad = fovy/2.f*__PI/180.f;
  85. s = sin(rad);
  86. if (dz == 0 || s == 0 || aspect == 0) return;
  87. cot = cos(rad)/s;
  88. __identf(&m[0][0]);
  89. m[0][0] = cot/aspect;
  90. m[1][1] = cot;
  91. m[2][2] = -(f + n)/dz;
  92. m[2][3] = -1.f;
  93. m[3][2] = -2.f*f*n/dz;
  94. m[3][3] = 0.f;
  95. glMultMatrixf(&m[0][0]);
  96. }
  97. #endif
  98. void APIENTRY
  99. ugluPerspectivex(GLfixed fovy, GLfixed aspect, GLfixed n, GLfixed f)
  100. {
  101. GLfixed m[4][4];
  102. GLfixed s, cot, dz = f - n;
  103. GLfixed rad = __mulx(fovy, __f2x(__PI/360.f));
  104. s = __sinx(rad);
  105. if (dz == 0 || s == 0 || aspect == 0) return;
  106. cot = __cosx(rad)/s;
  107. __identx(&m[0][0]);
  108. m[0][0] = __divx(cot, aspect);
  109. m[1][1] = cot;
  110. m[2][2] = -__divx((f + n), dz);
  111. m[2][3] = -__f2x(1);
  112. m[3][2] = __divx(-2*__mulx(f,n), dz);
  113. m[3][3] = 0;
  114. glMultMatrixx(&m[0][0]);
  115. }
  116. #ifdef __GL_FLOAT
  117. static void
  118. normalizef(float v[3]) {
  119. float r;
  120. r = (float)sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
  121. if (r == 0.0) return;
  122. r = 1.f/r;
  123. v[0] *= r;
  124. v[1] *= r;
  125. v[2] *= r;
  126. }
  127. static void
  128. crossf(float v0[3], float v1[3], float r[3])
  129. {
  130. r[0] = v0[1]*v1[2] - v0[2]*v1[1];
  131. r[1] = v0[2]*v1[0] - v0[0]*v1[2];
  132. r[2] = v0[0]*v1[1] - v0[1]*v1[0];
  133. }
  134. void APIENTRY
  135. ugluLookAtf(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx,
  136. GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy, GLfloat upz) {
  137. GLfloat forward[3], side[3], up[3];
  138. GLfloat m[4][4];
  139. forward[0] = centerx - eyex;
  140. forward[1] = centery - eyey;
  141. forward[2] = centerz - eyez;
  142. normalizef(forward);
  143. up[0] = upx;
  144. up[1] = upy;
  145. up[2] = upz;
  146. crossf(forward, up, side);
  147. normalizef(side);
  148. crossf(side, forward, up);
  149. __identf(&m[0][0]);
  150. m[0][0] = side[0];
  151. m[1][0] = side[1];
  152. m[2][0] = side[2];
  153. m[0][1] = up[0];
  154. m[1][1] = up[1];
  155. m[2][1] = up[2];
  156. m[0][2] = -forward[0];
  157. m[1][2] = -forward[1];
  158. m[2][2] = -forward[2];
  159. glMultMatrixf(&m[0][0]);
  160. glTranslatef(-eyex, -eyey, -eyez);
  161. }
  162. #endif
  163. GLfixed
  164. __sqrtx(GLfixed a) {
  165. GLfixed s;
  166. int i;
  167. s = (a + __f2x(1)) >> 1;
  168. /* 6 iterations to converge */
  169. for (i = 0; i < 6; i++)
  170. s = (s + __divx(a, s)) >> 1;
  171. return s;
  172. }
  173. static void
  174. normalizex(GLfixed v[3]) {
  175. float r;
  176. r = __sqrtx(__mulx(v[0],v[0]) + __mulx(v[1],v[1]) + __mulx(v[2],v[2]));
  177. if (r == 0.0f) return;
  178. r = __divx(1.f,r);
  179. v[0] *= r;
  180. v[1] *= r;
  181. v[2] *= r;
  182. }
  183. static void
  184. crossx(GLfixed v0[3], GLfixed v1[3], GLfixed r[3])
  185. {
  186. r[0] = __mulx(v0[1], v1[2]) - __mulx(v0[2], v1[1]);
  187. r[1] = __mulx(v0[2], v1[0]) - __mulx(v0[0], v1[2]);
  188. r[2] = __mulx(v0[0], v1[1]) - __mulx(v0[1], v1[0]);
  189. }
  190. void APIENTRY
  191. ugluLookAtx(GLfixed eyex, GLfixed eyey, GLfixed eyez, GLfixed centerx,
  192. GLfixed centery, GLfixed centerz, GLfixed upx, GLfixed upy, GLfixed upz) {
  193. GLfixed forward[3], side[3], up[3];
  194. GLfixed m[4][4];
  195. forward[0] = centerx - eyex;
  196. forward[1] = centery - eyey;
  197. forward[2] = centerz - eyez;
  198. normalizex(forward);
  199. up[0] = upx;
  200. up[1] = upy;
  201. up[2] = upz;
  202. crossx(forward, up, side);
  203. normalizex(side);
  204. crossx(side, forward, up);
  205. __identx(&m[0][0]);
  206. m[0][0] = side[0];
  207. m[1][0] = side[1];
  208. m[2][0] = side[2];
  209. m[0][1] = up[0];
  210. m[1][1] = up[1];
  211. m[2][1] = up[2];
  212. m[0][2] = -forward[0];
  213. m[1][2] = -forward[1];
  214. m[2][2] = -forward[2];
  215. glMultMatrixx(&m[0][0]);
  216. glTranslatex(-eyex, -eyey, -eyez);
  217. }