1 // 2 // Book: OpenGL(R) ES 2.0 Programming Guide 3 // Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner 4 // ISBN-10: 0321502795 5 // ISBN-13: 9780321502797 6 // Publisher: Addison-Wesley Professional 7 // URLs: http://safari.informit.com/9780321563835 8 // http://www.opengles-book.com 9 // 10 11 // ESUtil.c 12 // 13 // A utility library for OpenGL ES. This library provides a 14 // basic common framework for the example applications in the 15 // OpenGL ES 2.0 Programming Guide. 16 // 17 18 /// 19 // Includes 20 // 21 #include "esUtil.h" 22 #include <math.h> 23 24 #define PI 3.1415926535897932384626433832795f 25 26 void ESUTIL_API 27 esScale(ESMatrix *result, GLfloat sx, GLfloat sy, GLfloat sz) 28 { 29 result->m[0][0] *= sx; 30 result->m[0][1] *= sx; 31 result->m[0][2] *= sx; 32 result->m[0][3] *= sx; 33 34 result->m[1][0] *= sy; 35 result->m[1][1] *= sy; 36 result->m[1][2] *= sy; 37 result->m[1][3] *= sy; 38 39 result->m[2][0] *= sz; 40 result->m[2][1] *= sz; 41 result->m[2][2] *= sz; 42 result->m[2][3] *= sz; 43 } 44 45 void ESUTIL_API 46 esTranslate(ESMatrix *result, GLfloat tx, GLfloat ty, GLfloat tz) 47 { 48 result->m[3][0] += (result->m[0][0] * tx + result->m[1][0] * ty + result->m[2][0] * tz); 49 result->m[3][1] += (result->m[0][1] * tx + result->m[1][1] * ty + result->m[2][1] * tz); 50 result->m[3][2] += (result->m[0][2] * tx + result->m[1][2] * ty + result->m[2][2] * tz); 51 result->m[3][3] += (result->m[0][3] * tx + result->m[1][3] * ty + result->m[2][3] * tz); 52 } 53 54 void ESUTIL_API 55 esRotate(ESMatrix *result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z) 56 { 57 GLfloat sinAngle, cosAngle; 58 GLfloat mag = sqrtf(x * x + y * y + z * z); 59 60 sinAngle = sinf ( angle * PI / 180.0f ); 61 cosAngle = cosf ( angle * PI / 180.0f ); 62 if ( mag > 0.0f ) 63 { 64 GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs; 65 GLfloat oneMinusCos; 66 ESMatrix rotMat; 67 68 x /= mag; 69 y /= mag; 70 z /= mag; 71 72 xx = x * x; 73 yy = y * y; 74 zz = z * z; 75 xy = x * y; 76 yz = y * z; 77 zx = z * x; 78 xs = x * sinAngle; 79 ys = y * sinAngle; 80 zs = z * sinAngle; 81 oneMinusCos = 1.0f - cosAngle; 82 83 rotMat.m[0][0] = (oneMinusCos * xx) + cosAngle; 84 rotMat.m[0][1] = (oneMinusCos * xy) - zs; 85 rotMat.m[0][2] = (oneMinusCos * zx) + ys; 86 rotMat.m[0][3] = 0.0F; 87 88 rotMat.m[1][0] = (oneMinusCos * xy) + zs; 89 rotMat.m[1][1] = (oneMinusCos * yy) + cosAngle; 90 rotMat.m[1][2] = (oneMinusCos * yz) - xs; 91 rotMat.m[1][3] = 0.0F; 92 93 rotMat.m[2][0] = (oneMinusCos * zx) - ys; 94 rotMat.m[2][1] = (oneMinusCos * yz) + xs; 95 rotMat.m[2][2] = (oneMinusCos * zz) + cosAngle; 96 rotMat.m[2][3] = 0.0F; 97 98 rotMat.m[3][0] = 0.0F; 99 rotMat.m[3][1] = 0.0F; 100 rotMat.m[3][2] = 0.0F; 101 rotMat.m[3][3] = 1.0F; 102 103 esMatrixMultiply( result, &rotMat, result ); 104 } 105 } 106 107 void ESUTIL_API 108 esFrustum(ESMatrix *result, float left, float right, float bottom, float top, float nearZ, float farZ) 109 { 110 float deltaX = right - left; 111 float deltaY = top - bottom; 112 float deltaZ = farZ - nearZ; 113 ESMatrix frust; 114 115 if ( (nearZ <= 0.0f) || (farZ <= 0.0f) || 116 (deltaX <= 0.0f) || (deltaY <= 0.0f) || (deltaZ <= 0.0f) ) 117 return; 118 119 frust.m[0][0] = 2.0f * nearZ / deltaX; 120 frust.m[0][1] = frust.m[0][2] = frust.m[0][3] = 0.0f; 121 122 frust.m[1][1] = 2.0f * nearZ / deltaY; 123 frust.m[1][0] = frust.m[1][2] = frust.m[1][3] = 0.0f; 124 125 frust.m[2][0] = (right + left) / deltaX; 126 frust.m[2][1] = (top + bottom) / deltaY; 127 frust.m[2][2] = -(nearZ + farZ) / deltaZ; 128 frust.m[2][3] = -1.0f; 129 130 frust.m[3][2] = -2.0f * nearZ * farZ / deltaZ; 131 frust.m[3][0] = frust.m[3][1] = frust.m[3][3] = 0.0f; 132 133 esMatrixMultiply(result, &frust, result); 134 } 135 136 137 void ESUTIL_API 138 esPerspective(ESMatrix *result, float fovy, float aspect, float nearZ, float farZ) 139 { 140 GLfloat frustumW, frustumH; 141 142 frustumH = tanf( fovy / 360.0f * PI ) * nearZ; 143 frustumW = frustumH * aspect; 144 145 esFrustum( result, -frustumW, frustumW, -frustumH, frustumH, nearZ, farZ ); 146 } 147 148 void ESUTIL_API 149 esOrtho(ESMatrix *result, float left, float right, float bottom, float top, float nearZ, float farZ) 150 { 151 float deltaX = right - left; 152 float deltaY = top - bottom; 153 float deltaZ = farZ - nearZ; 154 ESMatrix ortho; 155 156 if ( (deltaX == 0.0f) || (deltaY == 0.0f) || (deltaZ == 0.0f) ) 157 return; 158 159 esMatrixLoadIdentity(&ortho); 160 ortho.m[0][0] = 2.0f / deltaX; 161 ortho.m[3][0] = -(right + left) / deltaX; 162 ortho.m[1][1] = 2.0f / deltaY; 163 ortho.m[3][1] = -(top + bottom) / deltaY; 164 ortho.m[2][2] = -2.0f / deltaZ; 165 ortho.m[3][2] = -(nearZ + farZ) / deltaZ; 166 167 esMatrixMultiply(result, &ortho, result); 168 } 169 170 171 void ESUTIL_API 172 esMatrixMultiply(ESMatrix *result, ESMatrix *srcA, ESMatrix *srcB) 173 { 174 ESMatrix tmp = { 0.0f }; 175 int i; 176 177 for (i=0; i<4; i++) 178 { 179 tmp.m[i][0] = (srcA->m[i][0] * srcB->m[0][0]) + 180 (srcA->m[i][1] * srcB->m[1][0]) + 181 (srcA->m[i][2] * srcB->m[2][0]) + 182 (srcA->m[i][3] * srcB->m[3][0]) ; 183 184 tmp.m[i][1] = (srcA->m[i][0] * srcB->m[0][1]) + 185 (srcA->m[i][1] * srcB->m[1][1]) + 186 (srcA->m[i][2] * srcB->m[2][1]) + 187 (srcA->m[i][3] * srcB->m[3][1]) ; 188 189 tmp.m[i][2] = (srcA->m[i][0] * srcB->m[0][2]) + 190 (srcA->m[i][1] * srcB->m[1][2]) + 191 (srcA->m[i][2] * srcB->m[2][2]) + 192 (srcA->m[i][3] * srcB->m[3][2]) ; 193 194 tmp.m[i][3] = (srcA->m[i][0] * srcB->m[0][3]) + 195 (srcA->m[i][1] * srcB->m[1][3]) + 196 (srcA->m[i][2] * srcB->m[2][3]) + 197 (srcA->m[i][3] * srcB->m[3][3]) ; 198 } 199 memcpy(result, &tmp, sizeof(ESMatrix)); 200 } 201 202 203 void ESUTIL_API 204 esMatrixLoadIdentity(ESMatrix *result) 205 { 206 memset(result, 0x0, sizeof(ESMatrix)); 207 result->m[0][0] = 1.0f; 208 result->m[1][1] = 1.0f; 209 result->m[2][2] = 1.0f; 210 result->m[3][3] = 1.0f; 211 } 212 213