PageRenderTime 265ms CodeModel.GetById 110ms app.highlight 66ms RepoModel.GetById 85ms app.codeStats 0ms

/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
 25#include <stdlib.h>
 26#include <string.h>
 27#include <GLES/egl.h>
 28
 29#define __GL_FLOAT
 30#ifdef __GL_FLOAT
 31#include <math.h>
 32#endif
 33
 34typedef long long __int64;
 35
 36#define __f2x(f)	((int)(f*65536))
 37#define __mulx(a,b)	((((__int64)(a))*(b))>>16)
 38#define __divx(a,b)	(((__int64)(a)<<16)/(b))
 39#define __PI		3.14159265358979323846f
 40
 41static const unsigned short __gl_sin_tab[] = {
 42#include "gl_sin.h"
 43};
 44
 45GLfixed
 46__cosx(GLfixed a) {
 47    GLfixed v;
 48    /* reduce to [0,1) */
 49    while (a < 0) a += 2*__f2x(__PI);
 50    a *= __f2x(1.0f/(2.f*__PI));
 51    a >>= 16;
 52    a += 0x4000;
 53
 54    /* now in the range [0, 0xffff], reduce to [0, 0xfff] */
 55    a >>= 4;
 56
 57    v = (a & 0x400) ? __gl_sin_tab[0x3ff - (a & 0x3ff)] : __gl_sin_tab[a & 0x3ff];
 58    v = __mulx(v,__f2x(1));
 59    return (a & 0x800) ? -v : v;
 60}
 61
 62GLfixed
 63__sinx(GLfixed a) {
 64    GLfixed v;
 65
 66    /* reduce to [0,1) */
 67    while (a < 0) a += 2*__f2x(__PI);
 68    a *= __f2x(1.0f/(2.f*__PI));
 69    a >>= 16;
 70
 71    /* now in the range [0, 0xffff], reduce to [0, 0xfff] */
 72    a >>= 4;
 73
 74    v = (a & 0x400) ? __gl_sin_tab[0x3ff - (a & 0x3ff)] : __gl_sin_tab[a & 0x3ff];
 75    v = __mulx(v,__f2x(1));
 76    return (a & 0x800) ? -v : v;
 77}
 78
 79#ifdef __GL_FLOAT
 80static void
 81__identf(GLfloat m[]) {
 82    memset(m, 0, sizeof m[0]*16);
 83    m[0] = m[5] = m[10] = m[15] = 1.0f;
 84}
 85#endif
 86
 87static void
 88__identx(GLfixed m[]) {
 89    memset(m, 0, sizeof m[0]*16);
 90    m[0] = m[5] = m[10] = m[15] = __f2x(1.0f);
 91}
 92
 93#ifdef __GL_FLOAT
 94void APIENTRY
 95ugluPerspectivef(GLfloat fovy, GLfloat aspect, GLfloat n, GLfloat f)
 96{
 97    GLfloat m[4][4];
 98    GLfloat s, cot, dz = f - n;
 99    GLfloat rad = fovy/2.f*__PI/180.f;
100
101    s = sin(rad);
102    if (dz == 0 || s == 0 || aspect == 0) return;
103
104    cot = cos(rad)/s;
105
106    __identf(&m[0][0]);
107    m[0][0] = cot/aspect;
108    m[1][1] = cot;
109    m[2][2] = -(f + n)/dz;
110    m[2][3] = -1.f;
111    m[3][2] = -2.f*f*n/dz;
112    m[3][3] = 0.f;
113    glMultMatrixf(&m[0][0]);
114}
115#endif
116
117void APIENTRY
118ugluPerspectivex(GLfixed fovy, GLfixed aspect, GLfixed n, GLfixed f)
119{
120    GLfixed m[4][4];
121    GLfixed s, cot, dz = f - n;
122    GLfixed rad = __mulx(fovy,  __f2x(__PI/360.f));
123
124    s = __sinx(rad);
125    if (dz == 0 || s == 0 || aspect == 0) return;
126
127    cot = __cosx(rad)/s;
128
129    __identx(&m[0][0]);
130    m[0][0] = __divx(cot, aspect);
131    m[1][1] = cot;
132    m[2][2] = -__divx((f + n), dz);
133    m[2][3] = -__f2x(1);
134    m[3][2] = __divx(-2*__mulx(f,n), dz);
135    m[3][3] = 0;
136    glMultMatrixx(&m[0][0]);
137}
138
139#ifdef __GL_FLOAT
140static void
141normalizef(float v[3]) {
142    float r;
143
144    r = (float)sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
145    if (r == 0.0) return;
146    r = 1.f/r;
147
148    v[0] *= r;
149    v[1] *= r;
150    v[2] *= r;
151}
152
153static void
154crossf(float v0[3], float v1[3], float r[3])
155{
156    r[0] = v0[1]*v1[2] - v0[2]*v1[1];
157    r[1] = v0[2]*v1[0] - v0[0]*v1[2];
158    r[2] = v0[0]*v1[1] - v0[1]*v1[0];
159}
160
161void APIENTRY
162ugluLookAtf(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx,
163      GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy, GLfloat upz) {
164    GLfloat forward[3], side[3], up[3];
165    GLfloat m[4][4];
166
167    forward[0] = centerx - eyex;
168    forward[1] = centery - eyey;
169    forward[2] = centerz - eyez;
170
171    normalizef(forward);
172
173    up[0] = upx;
174    up[1] = upy;
175    up[2] = upz;
176
177    crossf(forward, up, side);
178
179    normalizef(side);
180    crossf(side, forward, up);
181
182    __identf(&m[0][0]);
183    m[0][0] = side[0];
184    m[1][0] = side[1];
185    m[2][0] = side[2];
186
187    m[0][1] = up[0];
188    m[1][1] = up[1];
189    m[2][1] = up[2];
190
191    m[0][2] = -forward[0];
192    m[1][2] = -forward[1];
193    m[2][2] = -forward[2];
194
195    glMultMatrixf(&m[0][0]);
196    glTranslatef(-eyex, -eyey, -eyez);
197}
198#endif
199
200GLfixed
201__sqrtx(GLfixed a) {
202    GLfixed s;
203    int i;
204    s = (a + __f2x(1)) >> 1;
205    /* 6 iterations to converge */
206    for (i = 0; i < 6; i++)
207	s = (s + __divx(a, s)) >> 1;
208    return s;
209}
210static void
211normalizex(GLfixed v[3]) {
212    float r;
213
214    r = __sqrtx(__mulx(v[0],v[0]) + __mulx(v[1],v[1]) + __mulx(v[2],v[2]));
215    if (r == 0.0f) return;
216    r = __divx(1.f,r);
217
218    v[0] *= r;
219    v[1] *= r;
220    v[2] *= r;
221}
222
223static void
224crossx(GLfixed v0[3], GLfixed v1[3], GLfixed r[3])
225{
226    r[0] = __mulx(v0[1], v1[2]) - __mulx(v0[2], v1[1]);
227    r[1] = __mulx(v0[2], v1[0]) - __mulx(v0[0], v1[2]);
228    r[2] = __mulx(v0[0], v1[1]) - __mulx(v0[1], v1[0]);
229}
230
231void APIENTRY
232ugluLookAtx(GLfixed eyex, GLfixed eyey, GLfixed eyez, GLfixed centerx,
233      GLfixed centery, GLfixed centerz, GLfixed upx, GLfixed upy, GLfixed upz) {
234    GLfixed forward[3], side[3], up[3];
235    GLfixed m[4][4];
236
237    forward[0] = centerx - eyex;
238    forward[1] = centery - eyey;
239    forward[2] = centerz - eyez;
240
241    normalizex(forward);
242
243    up[0] = upx;
244    up[1] = upy;
245    up[2] = upz;
246
247    crossx(forward, up, side);
248
249    normalizex(side);
250    crossx(side, forward, up);
251
252    __identx(&m[0][0]);
253    m[0][0] = side[0];
254    m[1][0] = side[1];
255    m[2][0] = side[2];
256
257    m[0][1] = up[0];
258    m[1][1] = up[1];
259    m[2][1] = up[2];
260
261    m[0][2] = -forward[0];
262    m[1][2] = -forward[1];
263    m[2][2] = -forward[2];
264
265    glMultMatrixx(&m[0][0]);
266    glTranslatex(-eyex, -eyey, -eyez);
267}