| // |
| // Book: OpenGL(R) ES 2.0 Programming Guide |
| // Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner |
| // ISBN-10: 0321502795 |
| // ISBN-13: 9780321502797 |
| // Publisher: Addison-Wesley Professional |
| // URLs: http://safari.informit.com/9780321563835 |
| // http://www.opengles-book.com |
| // |
| |
| /* |
| * (c) 2009 Aaftab Munshi, Dan Ginsburg, Dave Shreiner |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included |
| * in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
| * DEALINGS IN THE SOFTWARE. |
| */ |
| |
| // ESUtil.c |
| // |
| // A utility library for OpenGL ES. This library provides a |
| // basic common framework for the example applications in the |
| // OpenGL ES 2.0 Programming Guide. |
| // |
| |
| /// |
| // Includes |
| // |
| #include "esTransform.h" |
| #include <math.h> |
| #include <string.h> |
| |
| #define PI 3.1415926535897932384626433832795f |
| |
| void esScale(ESMatrix* result, GLfloat sx, GLfloat sy, GLfloat sz) |
| { |
| result->m[0][0] *= sx; |
| result->m[0][1] *= sx; |
| result->m[0][2] *= sx; |
| result->m[0][3] *= sx; |
| |
| result->m[1][0] *= sy; |
| result->m[1][1] *= sy; |
| result->m[1][2] *= sy; |
| result->m[1][3] *= sy; |
| |
| result->m[2][0] *= sz; |
| result->m[2][1] *= sz; |
| result->m[2][2] *= sz; |
| result->m[2][3] *= sz; |
| } |
| |
| void esTranslate(ESMatrix* result, GLfloat tx, GLfloat ty, GLfloat tz) |
| { |
| result->m[3][0] += (result->m[0][0] * tx + result->m[1][0] * ty + result->m[2][0] * tz); |
| result->m[3][1] += (result->m[0][1] * tx + result->m[1][1] * ty + result->m[2][1] * tz); |
| result->m[3][2] += (result->m[0][2] * tx + result->m[1][2] * ty + result->m[2][2] * tz); |
| result->m[3][3] += (result->m[0][3] * tx + result->m[1][3] * ty + result->m[2][3] * tz); |
| } |
| |
| void esRotate(ESMatrix* result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z) |
| { |
| GLfloat sinAngle, cosAngle; |
| GLfloat mag = sqrtf(x * x + y * y + z * z); |
| |
| sinAngle = sinf(angle * PI / 180.0f); |
| cosAngle = cosf(angle * PI / 180.0f); |
| if (mag > 0.0f) { |
| GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs; |
| GLfloat oneMinusCos; |
| ESMatrix rotMat; |
| |
| x /= mag; |
| y /= mag; |
| z /= mag; |
| |
| xx = x * x; |
| yy = y * y; |
| zz = z * z; |
| xy = x * y; |
| yz = y * z; |
| zx = z * x; |
| xs = x * sinAngle; |
| ys = y * sinAngle; |
| zs = z * sinAngle; |
| oneMinusCos = 1.0f - cosAngle; |
| |
| rotMat.m[0][0] = (oneMinusCos * xx) + cosAngle; |
| rotMat.m[0][1] = (oneMinusCos * xy) - zs; |
| rotMat.m[0][2] = (oneMinusCos * zx) + ys; |
| rotMat.m[0][3] = 0.0F; |
| |
| rotMat.m[1][0] = (oneMinusCos * xy) + zs; |
| rotMat.m[1][1] = (oneMinusCos * yy) + cosAngle; |
| rotMat.m[1][2] = (oneMinusCos * yz) - xs; |
| rotMat.m[1][3] = 0.0F; |
| |
| rotMat.m[2][0] = (oneMinusCos * zx) - ys; |
| rotMat.m[2][1] = (oneMinusCos * yz) + xs; |
| rotMat.m[2][2] = (oneMinusCos * zz) + cosAngle; |
| rotMat.m[2][3] = 0.0F; |
| |
| rotMat.m[3][0] = 0.0F; |
| rotMat.m[3][1] = 0.0F; |
| rotMat.m[3][2] = 0.0F; |
| rotMat.m[3][3] = 1.0F; |
| |
| esMatrixMultiply(result, &rotMat, result); |
| } |
| } |
| |
| void esFrustum(ESMatrix* result, float left, float right, float bottom, float top, float nearZ, float farZ) |
| { |
| float deltaX = right - left; |
| float deltaY = top - bottom; |
| float deltaZ = farZ - nearZ; |
| ESMatrix frust; |
| |
| if ((nearZ <= 0.0f) || (farZ <= 0.0f) || |
| (deltaX <= 0.0f) || (deltaY <= 0.0f) || (deltaZ <= 0.0f)) |
| return; |
| |
| frust.m[0][0] = 2.0f * nearZ / deltaX; |
| frust.m[0][1] = frust.m[0][2] = frust.m[0][3] = 0.0f; |
| |
| frust.m[1][1] = 2.0f * nearZ / deltaY; |
| frust.m[1][0] = frust.m[1][2] = frust.m[1][3] = 0.0f; |
| |
| frust.m[2][0] = (right + left) / deltaX; |
| frust.m[2][1] = (top + bottom) / deltaY; |
| frust.m[2][2] = -(nearZ + farZ) / deltaZ; |
| frust.m[2][3] = -1.0f; |
| |
| frust.m[3][2] = -2.0f * nearZ * farZ / deltaZ; |
| frust.m[3][0] = frust.m[3][1] = frust.m[3][3] = 0.0f; |
| |
| esMatrixMultiply(result, &frust, result); |
| } |
| |
| void esPerspective(ESMatrix* result, float fovy, float aspect, float nearZ, float farZ) |
| { |
| GLfloat frustumW, frustumH; |
| |
| frustumH = tanf(fovy / 360.0f * PI) * nearZ; |
| frustumW = frustumH * aspect; |
| |
| esFrustum(result, -frustumW, frustumW, -frustumH, frustumH, nearZ, farZ); |
| } |
| |
| void esOrtho(ESMatrix* result, float left, float right, float bottom, float top, float nearZ, float farZ) |
| { |
| float deltaX = right - left; |
| float deltaY = top - bottom; |
| float deltaZ = farZ - nearZ; |
| ESMatrix ortho; |
| |
| if ((deltaX == 0.0f) || (deltaY == 0.0f) || (deltaZ == 0.0f)) |
| return; |
| |
| esMatrixLoadIdentity(&ortho); |
| ortho.m[0][0] = 2.0f / deltaX; |
| ortho.m[3][0] = -(right + left) / deltaX; |
| ortho.m[1][1] = 2.0f / deltaY; |
| ortho.m[3][1] = -(top + bottom) / deltaY; |
| ortho.m[2][2] = -2.0f / deltaZ; |
| ortho.m[3][2] = -(nearZ + farZ) / deltaZ; |
| |
| esMatrixMultiply(result, &ortho, result); |
| } |
| |
| void esMatrixMultiply(ESMatrix* result, ESMatrix* srcA, ESMatrix* srcB) |
| { |
| ESMatrix tmp; |
| int i; |
| |
| for (i = 0; i < 4; i++) { |
| tmp.m[i][0] = (srcA->m[i][0] * srcB->m[0][0]) + |
| (srcA->m[i][1] * srcB->m[1][0]) + |
| (srcA->m[i][2] * srcB->m[2][0]) + |
| (srcA->m[i][3] * srcB->m[3][0]); |
| |
| tmp.m[i][1] = (srcA->m[i][0] * srcB->m[0][1]) + |
| (srcA->m[i][1] * srcB->m[1][1]) + |
| (srcA->m[i][2] * srcB->m[2][1]) + |
| (srcA->m[i][3] * srcB->m[3][1]); |
| |
| tmp.m[i][2] = (srcA->m[i][0] * srcB->m[0][2]) + |
| (srcA->m[i][1] * srcB->m[1][2]) + |
| (srcA->m[i][2] * srcB->m[2][2]) + |
| (srcA->m[i][3] * srcB->m[3][2]); |
| |
| tmp.m[i][3] = (srcA->m[i][0] * srcB->m[0][3]) + |
| (srcA->m[i][1] * srcB->m[1][3]) + |
| (srcA->m[i][2] * srcB->m[2][3]) + |
| (srcA->m[i][3] * srcB->m[3][3]); |
| } |
| memcpy(result, &tmp, sizeof(ESMatrix)); |
| } |
| |
| void esMatrixLoadIdentity(ESMatrix* result) |
| { |
| memset(result, 0x0, sizeof(ESMatrix)); |
| result->m[0][0] = 1.0f; |
| result->m[1][1] = 1.0f; |
| result->m[2][2] = 1.0f; |
| result->m[3][3] = 1.0f; |
| } |