diff options
Diffstat (limited to 'opengl/libagl/matrix.cpp')
-rw-r--r-- | opengl/libagl/matrix.cpp | 1145 |
1 files changed, 0 insertions, 1145 deletions
diff --git a/opengl/libagl/matrix.cpp b/opengl/libagl/matrix.cpp deleted file mode 100644 index f175cda..0000000 --- a/opengl/libagl/matrix.cpp +++ /dev/null @@ -1,1145 +0,0 @@ -/* libs/opengles/matrix.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <stdlib.h> -#include <stdio.h> - -#include "context.h" -#include "fp.h" -#include "state.h" -#include "matrix.h" -#include "vertex.h" -#include "light.h" - -#if defined(__arm__) && defined(__thumb__) -#warning "matrix.cpp should not be compiled in thumb on ARM." -#endif - -#define I(_i, _j) ((_j)+ 4*(_i)) - -namespace android { - -// ---------------------------------------------------------------------------- - -static const GLfloat gIdentityf[16] = { 1,0,0,0, - 0,1,0,0, - 0,0,1,0, - 0,0,0,1 }; - -static const matrixx_t gIdentityx = { - { 0x10000,0,0,0, - 0,0x10000,0,0, - 0,0,0x10000,0, - 0,0,0,0x10000 - } - }; - -static void point2__nop(transform_t const*, vec4_t* c, vec4_t const* o); -static void point3__nop(transform_t const*, vec4_t* c, vec4_t const* o); -static void point4__nop(transform_t const*, vec4_t* c, vec4_t const* o); -static void normal__nop(transform_t const*, vec4_t* c, vec4_t const* o); -static void point2__generic(transform_t const*, vec4_t* c, vec4_t const* o); -static void point3__generic(transform_t const*, vec4_t* c, vec4_t const* o); -static void point4__generic(transform_t const*, vec4_t* c, vec4_t const* o); -static void normal__generic(transform_t const*, vec4_t* c, vec4_t const* o); - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#endif - -void ogles_init_matrix(ogles_context_t* c) -{ - c->transforms.modelview.init(OGLES_MODELVIEW_STACK_DEPTH); - c->transforms.projection.init(OGLES_PROJECTION_STACK_DEPTH); - for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++) - c->transforms.texture[i].init(OGLES_TEXTURE_STACK_DEPTH); - - c->transforms.current = &c->transforms.modelview; - c->transforms.matrixMode = GL_MODELVIEW; - c->transforms.dirty = transform_state_t::VIEWPORT | - transform_state_t::MVUI | - transform_state_t::MVIT | - transform_state_t::MVP; - c->transforms.mvp.loadIdentity(); - c->transforms.mvp4.loadIdentity(); - c->transforms.mvit4.loadIdentity(); - c->transforms.mvui.loadIdentity(); - c->transforms.vpt.loadIdentity(); - c->transforms.vpt.zNear = 0.0f; - c->transforms.vpt.zFar = 1.0f; -} - -void ogles_uninit_matrix(ogles_context_t* c) -{ - c->transforms.modelview.uninit(); - c->transforms.projection.uninit(); - for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++) - c->transforms.texture[i].uninit(); -} - -static void validate_perspective(ogles_context_t* c, vertex_t* v) -{ - const uint32_t enables = c->rasterizer.state.enables; - c->arrays.perspective = (c->clipPlanes.enable) ? - ogles_vertex_clipAllPerspective3D : ogles_vertex_perspective3D; - if (enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)) { - c->arrays.perspective = ogles_vertex_perspective3DZ; - if (c->clipPlanes.enable || (enables&GGL_ENABLE_FOG)) - c->arrays.perspective = ogles_vertex_clipAllPerspective3DZ; - } - if ((c->arrays.vertex.size != 4) && - (c->transforms.mvp4.flags & transform_t::FLAGS_2D_PROJECTION)) { - c->arrays.perspective = ogles_vertex_perspective2D; - } - c->arrays.perspective(c, v); -} - -void ogles_invalidate_perspective(ogles_context_t* c) -{ - c->arrays.perspective = validate_perspective; -} - -void ogles_validate_transform_impl(ogles_context_t* c, uint32_t want) -{ - int dirty = c->transforms.dirty & want; - - // Validate the modelview - if (dirty & transform_state_t::MODELVIEW) { - c->transforms.modelview.validate(); - } - - // Validate the projection stack (in fact, it's never needed) - if (dirty & transform_state_t::PROJECTION) { - c->transforms.projection.validate(); - } - - // Validate the viewport transformation - if (dirty & transform_state_t::VIEWPORT) { - vp_transform_t& vpt = c->transforms.vpt; - vpt.transform.matrix.load(vpt.matrix); - vpt.transform.picker(); - } - - // We need to update the mvp (used to transform each vertex) - if (dirty & transform_state_t::MVP) { - c->transforms.update_mvp(); - // invalidate perspective (divide by W) and view volume clipping - ogles_invalidate_perspective(c); - } - - // Validate the mvui (for normal transformation) - if (dirty & transform_state_t::MVUI) { - c->transforms.update_mvui(); - ogles_invalidate_lighting_mvui(c); - } - - // Validate the texture stack - if (dirty & transform_state_t::TEXTURE) { - for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++) - c->transforms.texture[i].validate(); - } - - // Validate the mvit4 (user-clip planes) - if (dirty & transform_state_t::MVIT) { - c->transforms.update_mvit(); - } - - c->transforms.dirty &= ~want; -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark transform_t -#endif - -void transform_t::loadIdentity() { - matrix = gIdentityx; - flags = 0; - ops = OP_IDENTITY; - point2 = point2__nop; - point3 = point3__nop; - point4 = point4__nop; -} - - -static inline -int notZero(GLfixed v) { - return abs(v) & ~0x3; -} - -static inline -int notOne(GLfixed v) { - return notZero(v - 0x10000); -} - -void transform_t::picker() -{ - const GLfixed* const m = matrix.m; - - // XXX: picker needs to be smarter - flags = 0; - ops = OP_ALL; - point2 = point2__generic; - point3 = point3__generic; - point4 = point4__generic; - - // find out if this is a 2D projection - if (!(notZero(m[3]) | notZero(m[7]) | notZero(m[11]) | notOne(m[15]))) { - flags |= FLAGS_2D_PROJECTION; - } -} - -void mvui_transform_t::picker() -{ - flags = 0; - ops = OP_ALL; - point3 = normal__generic; -} - -void transform_t::dump(const char* what) -{ - GLfixed const * const m = matrix.m; - LOGD("%s:", what); - for (int i=0 ; i<4 ; i++) - LOGD("[%08x %08x %08x %08x] [%f %f %f %f]\n", - m[I(0,i)], m[I(1,i)], m[I(2,i)], m[I(3,i)], - fixedToFloat(m[I(0,i)]), - fixedToFloat(m[I(1,i)]), - fixedToFloat(m[I(2,i)]), - fixedToFloat(m[I(3,i)])); -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark matrixx_t -#endif - -void matrixx_t::load(const matrixf_t& rhs) { - GLfixed* xp = m; - GLfloat const* fp = rhs.elements(); - unsigned int i = 16; - do { - const GLfloat f = *fp++; - *xp++ = isZerof(f) ? 0 : gglFloatToFixed(f); - } while (--i); -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark matrixf_t -#endif - -void matrixf_t::multiply(matrixf_t& r, const matrixf_t& lhs, const matrixf_t& rhs) -{ - GLfloat const* const m = lhs.m; - for (int i=0 ; i<4 ; i++) { - register const float rhs_i0 = rhs.m[ I(i,0) ]; - register float ri0 = m[ I(0,0) ] * rhs_i0; - register float ri1 = m[ I(0,1) ] * rhs_i0; - register float ri2 = m[ I(0,2) ] * rhs_i0; - register float ri3 = m[ I(0,3) ] * rhs_i0; - for (int j=1 ; j<4 ; j++) { - register const float rhs_ij = rhs.m[ I(i,j) ]; - ri0 += m[ I(j,0) ] * rhs_ij; - ri1 += m[ I(j,1) ] * rhs_ij; - ri2 += m[ I(j,2) ] * rhs_ij; - ri3 += m[ I(j,3) ] * rhs_ij; - } - r.m[ I(i,0) ] = ri0; - r.m[ I(i,1) ] = ri1; - r.m[ I(i,2) ] = ri2; - r.m[ I(i,3) ] = ri3; - } -} - -void matrixf_t::dump(const char* what) { - LOGD("%s", what); - LOGD("[ %9f %9f %9f %9f ]", m[I(0,0)], m[I(1,0)], m[I(2,0)], m[I(3,0)]); - LOGD("[ %9f %9f %9f %9f ]", m[I(0,1)], m[I(1,1)], m[I(2,1)], m[I(3,1)]); - LOGD("[ %9f %9f %9f %9f ]", m[I(0,2)], m[I(1,2)], m[I(2,2)], m[I(3,2)]); - LOGD("[ %9f %9f %9f %9f ]", m[I(0,3)], m[I(1,3)], m[I(2,3)], m[I(3,3)]); -} - -void matrixf_t::loadIdentity() { - memcpy(m, gIdentityf, sizeof(m)); -} - -void matrixf_t::set(const GLfixed* rhs) { - load(rhs); -} - -void matrixf_t::set(const GLfloat* rhs) { - load(rhs); -} - -void matrixf_t::load(const GLfixed* rhs) { - GLfloat* fp = m; - unsigned int i = 16; - do { - *fp++ = fixedToFloat(*rhs++); - } while (--i); -} - -void matrixf_t::load(const GLfloat* rhs) { - memcpy(m, rhs, sizeof(m)); -} - -void matrixf_t::load(const matrixf_t& rhs) { - operator = (rhs); -} - -void matrixf_t::multiply(const matrixf_t& rhs) { - matrixf_t r; - multiply(r, *this, rhs); - operator = (r); -} - -void matrixf_t::translate(GLfloat x, GLfloat y, GLfloat z) { - for (int i=0 ; i<4 ; i++) { - m[12+i] += m[i]*x + m[4+i]*y + m[8+i]*z; - } -} - -void matrixf_t::scale(GLfloat x, GLfloat y, GLfloat z) { - for (int i=0 ; i<4 ; i++) { - m[ i] *= x; - m[4+i] *= y; - m[8+i] *= z; - } -} - -void matrixf_t::rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z) -{ - matrixf_t rotation; - GLfloat* r = rotation.m; - GLfloat c, s; - r[3] = 0; r[7] = 0; r[11]= 0; - r[12]= 0; r[13]= 0; r[14]= 0; r[15]= 1; - a *= GLfloat(M_PI / 180.0f); - sincosf(a, &s, &c); - if (isOnef(x) && isZerof(y) && isZerof(z)) { - r[5] = c; r[10]= c; - r[6] = s; r[9] = -s; - r[1] = 0; r[2] = 0; - r[4] = 0; r[8] = 0; - r[0] = 1; - } else if (isZerof(x) && isOnef(y) && isZerof(z)) { - r[0] = c; r[10]= c; - r[8] = s; r[2] = -s; - r[1] = 0; r[4] = 0; - r[6] = 0; r[9] = 0; - r[5] = 1; - } else if (isZerof(x) && isZerof(y) && isOnef(z)) { - r[0] = c; r[5] = c; - r[1] = s; r[4] = -s; - r[2] = 0; r[6] = 0; - r[8] = 0; r[9] = 0; - r[10]= 1; - } else { - const GLfloat len = sqrtf(x*x + y*y + z*z); - if (!isOnef(len)) { - const GLfloat recipLen = reciprocalf(len); - x *= recipLen; - y *= recipLen; - z *= recipLen; - } - const GLfloat nc = 1.0f - c; - const GLfloat xy = x * y; - const GLfloat yz = y * z; - const GLfloat zx = z * x; - const GLfloat xs = x * s; - const GLfloat ys = y * s; - const GLfloat zs = z * s; - r[ 0] = x*x*nc + c; r[ 4] = xy*nc - zs; r[ 8] = zx*nc + ys; - r[ 1] = xy*nc + zs; r[ 5] = y*y*nc + c; r[ 9] = yz*nc - xs; - r[ 2] = zx*nc - ys; r[ 6] = yz*nc + xs; r[10] = z*z*nc + c; - } - multiply(rotation); -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark matrix_stack_t -#endif - -void matrix_stack_t::init(int depth) { - stack = new matrixf_t[depth]; - ops = new uint8_t[depth]; - maxDepth = depth; - depth = 0; - dirty = 0; - loadIdentity(); -} - -void matrix_stack_t::uninit() { - delete [] stack; - delete [] ops; -} - -void matrix_stack_t::loadIdentity() { - transform.loadIdentity(); - stack[depth].loadIdentity(); - ops[depth] = OP_IDENTITY; -} - -void matrix_stack_t::load(const GLfixed* rhs) -{ - memcpy(transform.matrix.m, rhs, sizeof(transform.matrix.m)); - stack[depth].load(rhs); - ops[depth] = OP_ALL; // TODO: we should look at the matrix -} - -void matrix_stack_t::load(const GLfloat* rhs) -{ - stack[depth].load(rhs); - ops[depth] = OP_ALL; // TODO: we should look at the matrix -} - -void matrix_stack_t::multiply(const matrixf_t& rhs) -{ - stack[depth].multiply(rhs); - ops[depth] = OP_ALL; // TODO: we should look at the matrix -} - -void matrix_stack_t::translate(GLfloat x, GLfloat y, GLfloat z) -{ - stack[depth].translate(x,y,z); - ops[depth] |= OP_TRANSLATE; -} - -void matrix_stack_t::scale(GLfloat x, GLfloat y, GLfloat z) -{ - stack[depth].scale(x,y,z); - if (x==y && y==z) { - ops[depth] |= OP_UNIFORM_SCALE; - } else { - ops[depth] |= OP_SCALE; - } -} - -void matrix_stack_t::rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z) -{ - stack[depth].rotate(a,x,y,z); - ops[depth] |= OP_ROTATE; -} - -void matrix_stack_t::validate() -{ - if (dirty & DO_FLOAT_TO_FIXED) { - transform.matrix.load(top()); - } - if (dirty & DO_PICKER) { - transform.picker(); - } - dirty = 0; -} - -GLint matrix_stack_t::push() -{ - if (depth >= (maxDepth-1)) { - return GL_STACK_OVERFLOW; - } - stack[depth+1] = stack[depth]; - ops[depth+1] = ops[depth]; - depth++; - return 0; -} - -GLint matrix_stack_t::pop() -{ - if (depth == 0) { - return GL_STACK_UNDERFLOW; - } - depth--; - return 0; -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark vp_transform_t -#endif - -void vp_transform_t::loadIdentity() { - transform.loadIdentity(); - matrix.loadIdentity(); -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark transform_state_t -#endif - -void transform_state_t::invalidate() -{ - switch (matrixMode) { - case GL_MODELVIEW: dirty |= MODELVIEW | MVP | MVUI | MVIT; break; - case GL_PROJECTION: dirty |= PROJECTION | MVP; break; - case GL_TEXTURE: dirty |= TEXTURE | MVP; break; - } - current->dirty = matrix_stack_t::DO_PICKER | - matrix_stack_t::DO_FLOAT_TO_FIXED; -} - -void transform_state_t::update_mvp() -{ - matrixf_t temp_mvp; - matrixf_t::multiply(temp_mvp, projection.top(), modelview.top()); - mvp4.matrix.load(temp_mvp); - mvp4.picker(); - - if (mvp4.flags & transform_t::FLAGS_2D_PROJECTION) { - // the mvp matrix doesn't transform W, in this case we can - // premultiply it with the viewport transformation. In addition to - // being more efficient, this is also much more accurate and in fact - // is needed for 2D drawing with a resulting 1:1 mapping. - matrixf_t mvpv; - matrixf_t::multiply(mvpv, vpt.matrix, temp_mvp); - mvp.matrix.load(mvpv); - mvp.picker(); - } else { - mvp = mvp4; - } -} - -static inline -GLfloat det22(GLfloat a, GLfloat b, GLfloat c, GLfloat d) { - return a*d - b*c; -} - -static inline -GLfloat ndet22(GLfloat a, GLfloat b, GLfloat c, GLfloat d) { - return b*c - a*d; -} - -static __attribute__((noinline)) -void invert(GLfloat* inverse, const GLfloat* src) -{ - double t; - int i, j, k, swap; - GLfloat tmp[4][4]; - - memcpy(inverse, gIdentityf, sizeof(gIdentityf)); - memcpy(tmp, src, sizeof(GLfloat)*16); - - for (i = 0; i < 4; i++) { - // look for largest element in column - swap = i; - for (j = i + 1; j < 4; j++) { - if (fabs(tmp[j][i]) > fabs(tmp[i][i])) { - swap = j; - } - } - - if (swap != i) { - /* swap rows. */ - for (k = 0; k < 4; k++) { - t = tmp[i][k]; - tmp[i][k] = tmp[swap][k]; - tmp[swap][k] = t; - - t = inverse[i*4+k]; - inverse[i*4+k] = inverse[swap*4+k]; - inverse[swap*4+k] = t; - } - } - - t = 1.0f / tmp[i][i]; - for (k = 0; k < 4; k++) { - tmp[i][k] *= t; - inverse[i*4+k] *= t; - } - for (j = 0; j < 4; j++) { - if (j != i) { - t = tmp[j][i]; - for (k = 0; k < 4; k++) { - tmp[j][k] -= tmp[i][k]*t; - inverse[j*4+k] -= inverse[i*4+k]*t; - } - } - } - } -} - -void transform_state_t::update_mvit() -{ - GLfloat r[16]; - const GLfloat* const mv = modelview.top().elements(); - invert(r, mv); - // convert to fixed-point and transpose - GLfixed* const x = mvit4.matrix.m; - for (int i=0 ; i<4 ; i++) - for (int j=0 ; j<4 ; j++) - x[I(i,j)] = gglFloatToFixed(r[I(j,i)]); - mvit4.picker(); -} - -void transform_state_t::update_mvui() -{ - const GLfloat* const mv = modelview.top().elements(); - - /* - When transforming normals, we can use the upper 3x3 matrix, see: - http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node26.html - */ - - // Also note that: - // l(obj) = tr(M).l(eye) for infinite light - // l(obj) = inv(M).l(eye) for local light - - const uint32_t ops = modelview.top_ops() & ~OP_TRANSLATE; - if (ggl_likely((!(ops & ~OP_ROTATE)) || - (rescaleNormals && modelview.isRigidBody()))) { - // if the modelview matrix is a rigid body transformation - // (translation, rotation, uniform scaling), then we can bypass - // the inverse by transposing the matrix. - GLfloat rescale = 1.0f; - if (rescaleNormals == GL_RESCALE_NORMAL) { - if (!(ops & ~OP_UNIFORM_SCALE)) { - rescale = reciprocalf(mv[I(0,0)]); - } else { - rescale = rsqrtf( - sqrf(mv[I(2,0)]) + sqrf(mv[I(2,1)]) + sqrf(mv[I(2,2)])); - } - } - GLfixed* const x = mvui.matrix.m; - for (int i=0 ; i<3 ; i++) { - x[I(i,0)] = gglFloatToFixed(mv[I(0,i)] * rescale); - x[I(i,1)] = gglFloatToFixed(mv[I(1,i)] * rescale); - x[I(i,2)] = gglFloatToFixed(mv[I(2,i)] * rescale); - } - mvui.picker(); - return; - } - - GLfloat r[3][3]; - r[0][0] = det22(mv[I(1,1)], mv[I(2,1)], mv[I(1,2)], mv[I(2,2)]); - r[0][1] =ndet22(mv[I(0,1)], mv[I(2,1)], mv[I(0,2)], mv[I(2,2)]); - r[0][2] = det22(mv[I(0,1)], mv[I(1,1)], mv[I(0,2)], mv[I(1,2)]); - r[1][0] =ndet22(mv[I(1,0)], mv[I(2,0)], mv[I(1,2)], mv[I(2,2)]); - r[1][1] = det22(mv[I(0,0)], mv[I(2,0)], mv[I(0,2)], mv[I(2,2)]); - r[1][2] =ndet22(mv[I(0,0)], mv[I(1,0)], mv[I(0,2)], mv[I(1,2)]); - r[2][0] = det22(mv[I(1,0)], mv[I(2,0)], mv[I(1,1)], mv[I(2,1)]); - r[2][1] =ndet22(mv[I(0,0)], mv[I(2,0)], mv[I(0,1)], mv[I(2,1)]); - r[2][2] = det22(mv[I(0,0)], mv[I(1,0)], mv[I(0,1)], mv[I(1,1)]); - - GLfloat rdet; - if (rescaleNormals == GL_RESCALE_NORMAL) { - rdet = rsqrtf(sqrf(r[0][2]) + sqrf(r[1][2]) + sqrf(r[2][2])); - } else { - rdet = reciprocalf( - r[0][0]*mv[I(0,0)] + r[0][1]*mv[I(1,0)] + r[0][2]*mv[I(2,0)]); - } - - GLfixed* const x = mvui.matrix.m; - for (int i=0 ; i<3 ; i++) { - x[I(i,0)] = gglFloatToFixed(r[i][0] * rdet); - x[I(i,1)] = gglFloatToFixed(r[i][1] * rdet); - x[I(i,2)] = gglFloatToFixed(r[i][2] * rdet); - } - mvui.picker(); -} - - -// ---------------------------------------------------------------------------- -// transformation and matrices API -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark transformation and matrices API -#endif - -int ogles_surfaceport(ogles_context_t* c, GLint x, GLint y) -{ - c->viewport.surfaceport.x = x; - c->viewport.surfaceport.y = y; - - ogles_viewport(c, - c->viewport.x, - c->viewport.y, - c->viewport.w, - c->viewport.h); - - ogles_scissor(c, - c->viewport.scissor.x, - c->viewport.scissor.y, - c->viewport.scissor.w, - c->viewport.scissor.h); - - return 0; -} - -void ogles_scissor(ogles_context_t* c, - GLint x, GLint y, GLsizei w, GLsizei h) -{ - if ((w|h) < 0) { - ogles_error(c, GL_INVALID_VALUE); - return; - } - c->viewport.scissor.x = x; - c->viewport.scissor.y = y; - c->viewport.scissor.w = w; - c->viewport.scissor.h = h; - - x += c->viewport.surfaceport.x; - y += c->viewport.surfaceport.y; - - y = c->rasterizer.state.buffers.color.height - (y + h); - c->rasterizer.procs.scissor(c, x, y, w, h); -} - -void ogles_viewport(ogles_context_t* c, - GLint x, GLint y, GLsizei w, GLsizei h) -{ - if ((w|h)<0) { - ogles_error(c, GL_INVALID_VALUE); - return; - } - - c->viewport.x = x; - c->viewport.y = y; - c->viewport.w = w; - c->viewport.h = h; - - x += c->viewport.surfaceport.x; - y += c->viewport.surfaceport.y; - - GLint H = c->rasterizer.state.buffers.color.height; - GLfloat sx = div2f(w); - GLfloat ox = sx + x; - GLfloat sy = div2f(h); - GLfloat oy = sy - y + (H - h); - - GLfloat near = c->transforms.vpt.zNear; - GLfloat far = c->transforms.vpt.zFar; - GLfloat A = div2f(far - near); - GLfloat B = div2f(far + near); - - // compute viewport matrix - GLfloat* const f = c->transforms.vpt.matrix.editElements(); - f[0] = sx; f[4] = 0; f[ 8] = 0; f[12] = ox; - f[1] = 0; f[5] =-sy; f[ 9] = 0; f[13] = oy; - f[2] = 0; f[6] = 0; f[10] = A; f[14] = B; - f[3] = 0; f[7] = 0; f[11] = 0; f[15] = 1; - c->transforms.dirty |= transform_state_t::VIEWPORT; -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark matrix * vertex -#endif - -void point2__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) { - const GLfixed* const m = mx->matrix.m; - const GLfixed rx = rhs->x; - const GLfixed ry = rhs->y; - lhs->x = mla2a(rx, m[ 0], ry, m[ 4], m[12]); - lhs->y = mla2a(rx, m[ 1], ry, m[ 5], m[13]); - lhs->z = mla2a(rx, m[ 2], ry, m[ 6], m[14]); - lhs->w = mla2a(rx, m[ 3], ry, m[ 7], m[15]); -} - -void point3__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) { - const GLfixed* const m = mx->matrix.m; - const GLfixed rx = rhs->x; - const GLfixed ry = rhs->y; - const GLfixed rz = rhs->z; - lhs->x = mla3a(rx, m[ 0], ry, m[ 4], rz, m[ 8], m[12]); - lhs->y = mla3a(rx, m[ 1], ry, m[ 5], rz, m[ 9], m[13]); - lhs->z = mla3a(rx, m[ 2], ry, m[ 6], rz, m[10], m[14]); - lhs->w = mla3a(rx, m[ 3], ry, m[ 7], rz, m[11], m[15]); -} - -void point4__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) { - const GLfixed* const m = mx->matrix.m; - const GLfixed rx = rhs->x; - const GLfixed ry = rhs->y; - const GLfixed rz = rhs->z; - const GLfixed rw = rhs->w; - lhs->x = mla4(rx, m[ 0], ry, m[ 4], rz, m[ 8], rw, m[12]); - lhs->y = mla4(rx, m[ 1], ry, m[ 5], rz, m[ 9], rw, m[13]); - lhs->z = mla4(rx, m[ 2], ry, m[ 6], rz, m[10], rw, m[14]); - lhs->w = mla4(rx, m[ 3], ry, m[ 7], rz, m[11], rw, m[15]); -} - -void normal__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) { - const GLfixed* const m = mx->matrix.m; - const GLfixed rx = rhs->x; - const GLfixed ry = rhs->y; - const GLfixed rz = rhs->z; - lhs->x = mla3(rx, m[ 0], ry, m[ 4], rz, m[ 8]); - lhs->y = mla3(rx, m[ 1], ry, m[ 5], rz, m[ 9]); - lhs->z = mla3(rx, m[ 2], ry, m[ 6], rz, m[10]); -} - - -void point2__nop(transform_t const*, vec4_t* lhs, vec4_t const* rhs) { - lhs->z = 0; - lhs->w = 0x10000; - if (lhs != rhs) { - lhs->x = rhs->x; - lhs->y = rhs->y; - } -} - -void point3__nop(transform_t const*, vec4_t* lhs, vec4_t const* rhs) { - lhs->w = 0x10000; - if (lhs != rhs) { - lhs->x = rhs->x; - lhs->y = rhs->y; - lhs->z = rhs->z; - } -} - -void point4__nop(transform_t const*, vec4_t* lhs, vec4_t const* rhs) { - if (lhs != rhs) - *lhs = *rhs; -} - - -static void frustumf( - GLfloat left, GLfloat right, - GLfloat bottom, GLfloat top, - GLfloat zNear, GLfloat zFar, - ogles_context_t* c) - { - if (cmpf(left,right) || - cmpf(top, bottom) || - cmpf(zNear, zFar) || - isZeroOrNegativef(zNear) || - isZeroOrNegativef(zFar)) - { - ogles_error(c, GL_INVALID_VALUE); - return; - } - const GLfloat r_width = reciprocalf(right - left); - const GLfloat r_height = reciprocalf(top - bottom); - const GLfloat r_depth = reciprocalf(zNear - zFar); - const GLfloat x = mul2f(zNear * r_width); - const GLfloat y = mul2f(zNear * r_height); - const GLfloat A = mul2f((right + left) * r_width); - const GLfloat B = (top + bottom) * r_height; - const GLfloat C = (zFar + zNear) * r_depth; - const GLfloat D = mul2f(zFar * zNear * r_depth); - GLfloat f[16]; - f[ 0] = x; - f[ 5] = y; - f[ 8] = A; - f[ 9] = B; - f[10] = C; - f[14] = D; - f[11] = -1.0f; - f[ 1] = f[ 2] = f[ 3] = - f[ 4] = f[ 6] = f[ 7] = - f[12] = f[13] = f[15] = 0.0f; - - matrixf_t rhs; - rhs.set(f); - c->transforms.current->multiply(rhs); - c->transforms.invalidate(); -} - -static void orthof( - GLfloat left, GLfloat right, - GLfloat bottom, GLfloat top, - GLfloat zNear, GLfloat zFar, - ogles_context_t* c) -{ - if (cmpf(left,right) || - cmpf(top, bottom) || - cmpf(zNear, zFar)) - { - ogles_error(c, GL_INVALID_VALUE); - return; - } - const GLfloat r_width = reciprocalf(right - left); - const GLfloat r_height = reciprocalf(top - bottom); - const GLfloat r_depth = reciprocalf(zFar - zNear); - const GLfloat x = mul2f(r_width); - const GLfloat y = mul2f(r_height); - const GLfloat z = -mul2f(r_depth); - const GLfloat tx = -(right + left) * r_width; - const GLfloat ty = -(top + bottom) * r_height; - const GLfloat tz = -(zFar + zNear) * r_depth; - GLfloat f[16]; - f[ 0] = x; - f[ 5] = y; - f[10] = z; - f[12] = tx; - f[13] = ty; - f[14] = tz; - f[15] = 1.0f; - f[ 1] = f[ 2] = f[ 3] = - f[ 4] = f[ 6] = f[ 7] = - f[ 8] = f[ 9] = f[11] = 0.0f; - matrixf_t rhs; - rhs.set(f); - c->transforms.current->multiply(rhs); - c->transforms.invalidate(); -} - -static void depthRangef(GLclampf zNear, GLclampf zFar, ogles_context_t* c) -{ - zNear = clampToZerof(zNear > 1 ? 1 : zNear); - zFar = clampToZerof(zFar > 1 ? 1 : zFar); - GLfloat* const f = c->transforms.vpt.matrix.editElements(); - f[10] = div2f(zFar - zNear); - f[14] = div2f(zFar + zNear); - c->transforms.dirty |= transform_state_t::VIEWPORT; - c->transforms.vpt.zNear = zNear; - c->transforms.vpt.zFar = zFar; -} - - -// ---------------------------------------------------------------------------- -}; // namespace android - -using namespace android; - -void glMatrixMode(GLenum mode) -{ - ogles_context_t* c = ogles_context_t::get(); - matrix_stack_t* stack = 0; - switch (mode) { - case GL_MODELVIEW: - stack = &c->transforms.modelview; - break; - case GL_PROJECTION: - stack = &c->transforms.projection; - break; - case GL_TEXTURE: - stack = &c->transforms.texture[c->textures.active]; - break; - default: - ogles_error(c, GL_INVALID_ENUM); - return; - } - c->transforms.matrixMode = mode; - c->transforms.current = stack; -} - -void glLoadIdentity() -{ - ogles_context_t* c = ogles_context_t::get(); - c->transforms.current->loadIdentity(); // also loads the GLfixed transform - c->transforms.invalidate(); - c->transforms.current->dirty = 0; -} - -void glLoadMatrixf(const GLfloat* m) -{ - ogles_context_t* c = ogles_context_t::get(); - c->transforms.current->load(m); - c->transforms.invalidate(); -} - -void glLoadMatrixx(const GLfixed* m) -{ - ogles_context_t* c = ogles_context_t::get(); - c->transforms.current->load(m); // also loads the GLfixed transform - c->transforms.invalidate(); - c->transforms.current->dirty &= ~matrix_stack_t::DO_FLOAT_TO_FIXED; -} - -void glMultMatrixf(const GLfloat* m) -{ - ogles_context_t* c = ogles_context_t::get(); - matrixf_t rhs; - rhs.set(m); - c->transforms.current->multiply(rhs); - c->transforms.invalidate(); -} - -void glMultMatrixx(const GLfixed* m) -{ - ogles_context_t* c = ogles_context_t::get(); - matrixf_t rhs; - rhs.set(m); - c->transforms.current->multiply(rhs); - c->transforms.invalidate(); -} - -void glPopMatrix() -{ - ogles_context_t* c = ogles_context_t::get(); - GLint err = c->transforms.current->pop(); - if (ggl_unlikely(err)) { - ogles_error(c, err); - return; - } - c->transforms.invalidate(); -} - -void glPushMatrix() -{ - ogles_context_t* c = ogles_context_t::get(); - GLint err = c->transforms.current->push(); - if (ggl_unlikely(err)) { - ogles_error(c, err); - return; - } - c->transforms.invalidate(); -} - -void glFrustumf( - GLfloat left, GLfloat right, - GLfloat bottom, GLfloat top, - GLfloat zNear, GLfloat zFar) -{ - ogles_context_t* c = ogles_context_t::get(); - frustumf(left, right, bottom, top, zNear, zFar, c); -} - -void glFrustumx( - GLfixed left, GLfixed right, - GLfixed bottom, GLfixed top, - GLfixed zNear, GLfixed zFar) -{ - ogles_context_t* c = ogles_context_t::get(); - frustumf( fixedToFloat(left), fixedToFloat(right), - fixedToFloat(bottom), fixedToFloat(top), - fixedToFloat(zNear), fixedToFloat(zFar), - c); -} - -void glOrthof( - GLfloat left, GLfloat right, - GLfloat bottom, GLfloat top, - GLfloat zNear, GLfloat zFar) -{ - ogles_context_t* c = ogles_context_t::get(); - orthof(left, right, bottom, top, zNear, zFar, c); -} - -void glOrthox( - GLfixed left, GLfixed right, - GLfixed bottom, GLfixed top, - GLfixed zNear, GLfixed zFar) -{ - ogles_context_t* c = ogles_context_t::get(); - orthof( fixedToFloat(left), fixedToFloat(right), - fixedToFloat(bottom), fixedToFloat(top), - fixedToFloat(zNear), fixedToFloat(zFar), - c); -} - -void glRotatef(GLfloat a, GLfloat x, GLfloat y, GLfloat z) -{ - ogles_context_t* c = ogles_context_t::get(); - c->transforms.current->rotate(a, x, y, z); - c->transforms.invalidate(); -} - -void glRotatex(GLfixed a, GLfixed x, GLfixed y, GLfixed z) -{ - ogles_context_t* c = ogles_context_t::get(); - c->transforms.current->rotate( - fixedToFloat(a), fixedToFloat(x), - fixedToFloat(y), fixedToFloat(z)); - c->transforms.invalidate(); -} - -void glScalef(GLfloat x, GLfloat y, GLfloat z) -{ - ogles_context_t* c = ogles_context_t::get(); - c->transforms.current->scale(x, y, z); - c->transforms.invalidate(); -} - -void glScalex(GLfixed x, GLfixed y, GLfixed z) -{ - ogles_context_t* c = ogles_context_t::get(); - c->transforms.current->scale( - fixedToFloat(x), fixedToFloat(y), fixedToFloat(z)); - c->transforms.invalidate(); -} - -void glTranslatef(GLfloat x, GLfloat y, GLfloat z) -{ - ogles_context_t* c = ogles_context_t::get(); - c->transforms.current->translate(x, y, z); - c->transforms.invalidate(); -} - -void glTranslatex(GLfixed x, GLfixed y, GLfixed z) -{ - ogles_context_t* c = ogles_context_t::get(); - c->transforms.current->translate( - fixedToFloat(x), fixedToFloat(y), fixedToFloat(z)); - c->transforms.invalidate(); -} - -void glScissor(GLint x, GLint y, GLsizei w, GLsizei h) -{ - ogles_context_t* c = ogles_context_t::get(); - ogles_scissor(c, x, y, w, h); -} - -void glViewport(GLint x, GLint y, GLsizei w, GLsizei h) -{ - ogles_context_t* c = ogles_context_t::get(); - ogles_viewport(c, x, y, w, h); -} - -void glDepthRangef(GLclampf zNear, GLclampf zFar) -{ - ogles_context_t* c = ogles_context_t::get(); - depthRangef(zNear, zFar, c); -} - -void glDepthRangex(GLclampx zNear, GLclampx zFar) -{ - ogles_context_t* c = ogles_context_t::get(); - depthRangef(fixedToFloat(zNear), fixedToFloat(zFar), c); -} - -void glPolygonOffsetx(GLfixed factor, GLfixed units) -{ - ogles_context_t* c = ogles_context_t::get(); - c->polygonOffset.factor = factor; - c->polygonOffset.units = units; -} - -void glPolygonOffset(GLfloat factor, GLfloat units) -{ - ogles_context_t* c = ogles_context_t::get(); - c->polygonOffset.factor = gglFloatToFixed(factor); - c->polygonOffset.units = gglFloatToFixed(units); -} - -GLbitfield glQueryMatrixxOES(GLfixed* m, GLint* e) -{ - ogles_context_t* c = ogles_context_t::get(); - GLbitfield status = 0; - GLfloat const* f = c->transforms.current->top().elements(); - for (int i=0 ; i<16 ; i++) { - if (isnan(f[i]) || isinf(f[i])) { - status |= 1<<i; - continue; - } - e[i] = exponent(f[i]) - 7; - m[i] = mantissa(f[i]); - } - return status; -} |