xref: /aosp_15_r20/external/libkmsxx/kmscube/esTransform.cpp (revision f0687c8a10b3e371dbe09214db6664e37c283cca)
1*f0687c8aSRaman Tenneti //
2*f0687c8aSRaman Tenneti // Book:      OpenGL(R) ES 2.0 Programming Guide
3*f0687c8aSRaman Tenneti // Authors:   Aaftab Munshi, Dan Ginsburg, Dave Shreiner
4*f0687c8aSRaman Tenneti // ISBN-10:   0321502795
5*f0687c8aSRaman Tenneti // ISBN-13:   9780321502797
6*f0687c8aSRaman Tenneti // Publisher: Addison-Wesley Professional
7*f0687c8aSRaman Tenneti // URLs:      http://safari.informit.com/9780321563835
8*f0687c8aSRaman Tenneti //            http://www.opengles-book.com
9*f0687c8aSRaman Tenneti //
10*f0687c8aSRaman Tenneti 
11*f0687c8aSRaman Tenneti /*
12*f0687c8aSRaman Tenneti  * (c) 2009 Aaftab Munshi, Dan Ginsburg, Dave Shreiner
13*f0687c8aSRaman Tenneti  *
14*f0687c8aSRaman Tenneti  * Permission is hereby granted, free of charge, to any person obtaining a
15*f0687c8aSRaman Tenneti  * copy of this software and associated documentation files (the "Software"),
16*f0687c8aSRaman Tenneti  * to deal in the Software without restriction, including without limitation
17*f0687c8aSRaman Tenneti  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18*f0687c8aSRaman Tenneti  * and/or sell copies of the Software, and to permit persons to whom the
19*f0687c8aSRaman Tenneti  * Software is furnished to do so, subject to the following conditions:
20*f0687c8aSRaman Tenneti  *
21*f0687c8aSRaman Tenneti  * The above copyright notice and this permission notice shall be included
22*f0687c8aSRaman Tenneti  * in all copies or substantial portions of the Software.
23*f0687c8aSRaman Tenneti  *
24*f0687c8aSRaman Tenneti  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25*f0687c8aSRaman Tenneti  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26*f0687c8aSRaman Tenneti  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27*f0687c8aSRaman Tenneti  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28*f0687c8aSRaman Tenneti  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29*f0687c8aSRaman Tenneti  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30*f0687c8aSRaman Tenneti  * DEALINGS IN THE SOFTWARE.
31*f0687c8aSRaman Tenneti  */
32*f0687c8aSRaman Tenneti 
33*f0687c8aSRaman Tenneti // ESUtil.c
34*f0687c8aSRaman Tenneti //
35*f0687c8aSRaman Tenneti //    A utility library for OpenGL ES.  This library provides a
36*f0687c8aSRaman Tenneti //    basic common framework for the example applications in the
37*f0687c8aSRaman Tenneti //    OpenGL ES 2.0 Programming Guide.
38*f0687c8aSRaman Tenneti //
39*f0687c8aSRaman Tenneti 
40*f0687c8aSRaman Tenneti ///
41*f0687c8aSRaman Tenneti //  Includes
42*f0687c8aSRaman Tenneti //
43*f0687c8aSRaman Tenneti #include "esTransform.h"
44*f0687c8aSRaman Tenneti #include <math.h>
45*f0687c8aSRaman Tenneti #include <string.h>
46*f0687c8aSRaman Tenneti 
47*f0687c8aSRaman Tenneti #define PI 3.1415926535897932384626433832795f
48*f0687c8aSRaman Tenneti 
esScale(ESMatrix * result,GLfloat sx,GLfloat sy,GLfloat sz)49*f0687c8aSRaman Tenneti void esScale(ESMatrix* result, GLfloat sx, GLfloat sy, GLfloat sz)
50*f0687c8aSRaman Tenneti {
51*f0687c8aSRaman Tenneti 	result->m[0][0] *= sx;
52*f0687c8aSRaman Tenneti 	result->m[0][1] *= sx;
53*f0687c8aSRaman Tenneti 	result->m[0][2] *= sx;
54*f0687c8aSRaman Tenneti 	result->m[0][3] *= sx;
55*f0687c8aSRaman Tenneti 
56*f0687c8aSRaman Tenneti 	result->m[1][0] *= sy;
57*f0687c8aSRaman Tenneti 	result->m[1][1] *= sy;
58*f0687c8aSRaman Tenneti 	result->m[1][2] *= sy;
59*f0687c8aSRaman Tenneti 	result->m[1][3] *= sy;
60*f0687c8aSRaman Tenneti 
61*f0687c8aSRaman Tenneti 	result->m[2][0] *= sz;
62*f0687c8aSRaman Tenneti 	result->m[2][1] *= sz;
63*f0687c8aSRaman Tenneti 	result->m[2][2] *= sz;
64*f0687c8aSRaman Tenneti 	result->m[2][3] *= sz;
65*f0687c8aSRaman Tenneti }
66*f0687c8aSRaman Tenneti 
esTranslate(ESMatrix * result,GLfloat tx,GLfloat ty,GLfloat tz)67*f0687c8aSRaman Tenneti void esTranslate(ESMatrix* result, GLfloat tx, GLfloat ty, GLfloat tz)
68*f0687c8aSRaman Tenneti {
69*f0687c8aSRaman Tenneti 	result->m[3][0] += (result->m[0][0] * tx + result->m[1][0] * ty + result->m[2][0] * tz);
70*f0687c8aSRaman Tenneti 	result->m[3][1] += (result->m[0][1] * tx + result->m[1][1] * ty + result->m[2][1] * tz);
71*f0687c8aSRaman Tenneti 	result->m[3][2] += (result->m[0][2] * tx + result->m[1][2] * ty + result->m[2][2] * tz);
72*f0687c8aSRaman Tenneti 	result->m[3][3] += (result->m[0][3] * tx + result->m[1][3] * ty + result->m[2][3] * tz);
73*f0687c8aSRaman Tenneti }
74*f0687c8aSRaman Tenneti 
esRotate(ESMatrix * result,GLfloat angle,GLfloat x,GLfloat y,GLfloat z)75*f0687c8aSRaman Tenneti void esRotate(ESMatrix* result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
76*f0687c8aSRaman Tenneti {
77*f0687c8aSRaman Tenneti 	GLfloat sinAngle, cosAngle;
78*f0687c8aSRaman Tenneti 	GLfloat mag = sqrtf(x * x + y * y + z * z);
79*f0687c8aSRaman Tenneti 
80*f0687c8aSRaman Tenneti 	sinAngle = sinf(angle * PI / 180.0f);
81*f0687c8aSRaman Tenneti 	cosAngle = cosf(angle * PI / 180.0f);
82*f0687c8aSRaman Tenneti 	if (mag > 0.0f) {
83*f0687c8aSRaman Tenneti 		GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs;
84*f0687c8aSRaman Tenneti 		GLfloat oneMinusCos;
85*f0687c8aSRaman Tenneti 		ESMatrix rotMat;
86*f0687c8aSRaman Tenneti 
87*f0687c8aSRaman Tenneti 		x /= mag;
88*f0687c8aSRaman Tenneti 		y /= mag;
89*f0687c8aSRaman Tenneti 		z /= mag;
90*f0687c8aSRaman Tenneti 
91*f0687c8aSRaman Tenneti 		xx = x * x;
92*f0687c8aSRaman Tenneti 		yy = y * y;
93*f0687c8aSRaman Tenneti 		zz = z * z;
94*f0687c8aSRaman Tenneti 		xy = x * y;
95*f0687c8aSRaman Tenneti 		yz = y * z;
96*f0687c8aSRaman Tenneti 		zx = z * x;
97*f0687c8aSRaman Tenneti 		xs = x * sinAngle;
98*f0687c8aSRaman Tenneti 		ys = y * sinAngle;
99*f0687c8aSRaman Tenneti 		zs = z * sinAngle;
100*f0687c8aSRaman Tenneti 		oneMinusCos = 1.0f - cosAngle;
101*f0687c8aSRaman Tenneti 
102*f0687c8aSRaman Tenneti 		rotMat.m[0][0] = (oneMinusCos * xx) + cosAngle;
103*f0687c8aSRaman Tenneti 		rotMat.m[0][1] = (oneMinusCos * xy) - zs;
104*f0687c8aSRaman Tenneti 		rotMat.m[0][2] = (oneMinusCos * zx) + ys;
105*f0687c8aSRaman Tenneti 		rotMat.m[0][3] = 0.0F;
106*f0687c8aSRaman Tenneti 
107*f0687c8aSRaman Tenneti 		rotMat.m[1][0] = (oneMinusCos * xy) + zs;
108*f0687c8aSRaman Tenneti 		rotMat.m[1][1] = (oneMinusCos * yy) + cosAngle;
109*f0687c8aSRaman Tenneti 		rotMat.m[1][2] = (oneMinusCos * yz) - xs;
110*f0687c8aSRaman Tenneti 		rotMat.m[1][3] = 0.0F;
111*f0687c8aSRaman Tenneti 
112*f0687c8aSRaman Tenneti 		rotMat.m[2][0] = (oneMinusCos * zx) - ys;
113*f0687c8aSRaman Tenneti 		rotMat.m[2][1] = (oneMinusCos * yz) + xs;
114*f0687c8aSRaman Tenneti 		rotMat.m[2][2] = (oneMinusCos * zz) + cosAngle;
115*f0687c8aSRaman Tenneti 		rotMat.m[2][3] = 0.0F;
116*f0687c8aSRaman Tenneti 
117*f0687c8aSRaman Tenneti 		rotMat.m[3][0] = 0.0F;
118*f0687c8aSRaman Tenneti 		rotMat.m[3][1] = 0.0F;
119*f0687c8aSRaman Tenneti 		rotMat.m[3][2] = 0.0F;
120*f0687c8aSRaman Tenneti 		rotMat.m[3][3] = 1.0F;
121*f0687c8aSRaman Tenneti 
122*f0687c8aSRaman Tenneti 		esMatrixMultiply(result, &rotMat, result);
123*f0687c8aSRaman Tenneti 	}
124*f0687c8aSRaman Tenneti }
125*f0687c8aSRaman Tenneti 
esFrustum(ESMatrix * result,float left,float right,float bottom,float top,float nearZ,float farZ)126*f0687c8aSRaman Tenneti void esFrustum(ESMatrix* result, float left, float right, float bottom, float top, float nearZ, float farZ)
127*f0687c8aSRaman Tenneti {
128*f0687c8aSRaman Tenneti 	float deltaX = right - left;
129*f0687c8aSRaman Tenneti 	float deltaY = top - bottom;
130*f0687c8aSRaman Tenneti 	float deltaZ = farZ - nearZ;
131*f0687c8aSRaman Tenneti 	ESMatrix frust;
132*f0687c8aSRaman Tenneti 
133*f0687c8aSRaman Tenneti 	if ((nearZ <= 0.0f) || (farZ <= 0.0f) ||
134*f0687c8aSRaman Tenneti 	    (deltaX <= 0.0f) || (deltaY <= 0.0f) || (deltaZ <= 0.0f))
135*f0687c8aSRaman Tenneti 		return;
136*f0687c8aSRaman Tenneti 
137*f0687c8aSRaman Tenneti 	frust.m[0][0] = 2.0f * nearZ / deltaX;
138*f0687c8aSRaman Tenneti 	frust.m[0][1] = frust.m[0][2] = frust.m[0][3] = 0.0f;
139*f0687c8aSRaman Tenneti 
140*f0687c8aSRaman Tenneti 	frust.m[1][1] = 2.0f * nearZ / deltaY;
141*f0687c8aSRaman Tenneti 	frust.m[1][0] = frust.m[1][2] = frust.m[1][3] = 0.0f;
142*f0687c8aSRaman Tenneti 
143*f0687c8aSRaman Tenneti 	frust.m[2][0] = (right + left) / deltaX;
144*f0687c8aSRaman Tenneti 	frust.m[2][1] = (top + bottom) / deltaY;
145*f0687c8aSRaman Tenneti 	frust.m[2][2] = -(nearZ + farZ) / deltaZ;
146*f0687c8aSRaman Tenneti 	frust.m[2][3] = -1.0f;
147*f0687c8aSRaman Tenneti 
148*f0687c8aSRaman Tenneti 	frust.m[3][2] = -2.0f * nearZ * farZ / deltaZ;
149*f0687c8aSRaman Tenneti 	frust.m[3][0] = frust.m[3][1] = frust.m[3][3] = 0.0f;
150*f0687c8aSRaman Tenneti 
151*f0687c8aSRaman Tenneti 	esMatrixMultiply(result, &frust, result);
152*f0687c8aSRaman Tenneti }
153*f0687c8aSRaman Tenneti 
esPerspective(ESMatrix * result,float fovy,float aspect,float nearZ,float farZ)154*f0687c8aSRaman Tenneti void esPerspective(ESMatrix* result, float fovy, float aspect, float nearZ, float farZ)
155*f0687c8aSRaman Tenneti {
156*f0687c8aSRaman Tenneti 	GLfloat frustumW, frustumH;
157*f0687c8aSRaman Tenneti 
158*f0687c8aSRaman Tenneti 	frustumH = tanf(fovy / 360.0f * PI) * nearZ;
159*f0687c8aSRaman Tenneti 	frustumW = frustumH * aspect;
160*f0687c8aSRaman Tenneti 
161*f0687c8aSRaman Tenneti 	esFrustum(result, -frustumW, frustumW, -frustumH, frustumH, nearZ, farZ);
162*f0687c8aSRaman Tenneti }
163*f0687c8aSRaman Tenneti 
esOrtho(ESMatrix * result,float left,float right,float bottom,float top,float nearZ,float farZ)164*f0687c8aSRaman Tenneti void esOrtho(ESMatrix* result, float left, float right, float bottom, float top, float nearZ, float farZ)
165*f0687c8aSRaman Tenneti {
166*f0687c8aSRaman Tenneti 	float deltaX = right - left;
167*f0687c8aSRaman Tenneti 	float deltaY = top - bottom;
168*f0687c8aSRaman Tenneti 	float deltaZ = farZ - nearZ;
169*f0687c8aSRaman Tenneti 	ESMatrix ortho;
170*f0687c8aSRaman Tenneti 
171*f0687c8aSRaman Tenneti 	if ((deltaX == 0.0f) || (deltaY == 0.0f) || (deltaZ == 0.0f))
172*f0687c8aSRaman Tenneti 		return;
173*f0687c8aSRaman Tenneti 
174*f0687c8aSRaman Tenneti 	esMatrixLoadIdentity(&ortho);
175*f0687c8aSRaman Tenneti 	ortho.m[0][0] = 2.0f / deltaX;
176*f0687c8aSRaman Tenneti 	ortho.m[3][0] = -(right + left) / deltaX;
177*f0687c8aSRaman Tenneti 	ortho.m[1][1] = 2.0f / deltaY;
178*f0687c8aSRaman Tenneti 	ortho.m[3][1] = -(top + bottom) / deltaY;
179*f0687c8aSRaman Tenneti 	ortho.m[2][2] = -2.0f / deltaZ;
180*f0687c8aSRaman Tenneti 	ortho.m[3][2] = -(nearZ + farZ) / deltaZ;
181*f0687c8aSRaman Tenneti 
182*f0687c8aSRaman Tenneti 	esMatrixMultiply(result, &ortho, result);
183*f0687c8aSRaman Tenneti }
184*f0687c8aSRaman Tenneti 
esMatrixMultiply(ESMatrix * result,ESMatrix * srcA,ESMatrix * srcB)185*f0687c8aSRaman Tenneti void esMatrixMultiply(ESMatrix* result, ESMatrix* srcA, ESMatrix* srcB)
186*f0687c8aSRaman Tenneti {
187*f0687c8aSRaman Tenneti 	ESMatrix tmp;
188*f0687c8aSRaman Tenneti 	int i;
189*f0687c8aSRaman Tenneti 
190*f0687c8aSRaman Tenneti 	for (i = 0; i < 4; i++) {
191*f0687c8aSRaman Tenneti 		tmp.m[i][0] = (srcA->m[i][0] * srcB->m[0][0]) +
192*f0687c8aSRaman Tenneti 			      (srcA->m[i][1] * srcB->m[1][0]) +
193*f0687c8aSRaman Tenneti 			      (srcA->m[i][2] * srcB->m[2][0]) +
194*f0687c8aSRaman Tenneti 			      (srcA->m[i][3] * srcB->m[3][0]);
195*f0687c8aSRaman Tenneti 
196*f0687c8aSRaman Tenneti 		tmp.m[i][1] = (srcA->m[i][0] * srcB->m[0][1]) +
197*f0687c8aSRaman Tenneti 			      (srcA->m[i][1] * srcB->m[1][1]) +
198*f0687c8aSRaman Tenneti 			      (srcA->m[i][2] * srcB->m[2][1]) +
199*f0687c8aSRaman Tenneti 			      (srcA->m[i][3] * srcB->m[3][1]);
200*f0687c8aSRaman Tenneti 
201*f0687c8aSRaman Tenneti 		tmp.m[i][2] = (srcA->m[i][0] * srcB->m[0][2]) +
202*f0687c8aSRaman Tenneti 			      (srcA->m[i][1] * srcB->m[1][2]) +
203*f0687c8aSRaman Tenneti 			      (srcA->m[i][2] * srcB->m[2][2]) +
204*f0687c8aSRaman Tenneti 			      (srcA->m[i][3] * srcB->m[3][2]);
205*f0687c8aSRaman Tenneti 
206*f0687c8aSRaman Tenneti 		tmp.m[i][3] = (srcA->m[i][0] * srcB->m[0][3]) +
207*f0687c8aSRaman Tenneti 			      (srcA->m[i][1] * srcB->m[1][3]) +
208*f0687c8aSRaman Tenneti 			      (srcA->m[i][2] * srcB->m[2][3]) +
209*f0687c8aSRaman Tenneti 			      (srcA->m[i][3] * srcB->m[3][3]);
210*f0687c8aSRaman Tenneti 	}
211*f0687c8aSRaman Tenneti 	memcpy(result, &tmp, sizeof(ESMatrix));
212*f0687c8aSRaman Tenneti }
213*f0687c8aSRaman Tenneti 
esMatrixLoadIdentity(ESMatrix * result)214*f0687c8aSRaman Tenneti void esMatrixLoadIdentity(ESMatrix* result)
215*f0687c8aSRaman Tenneti {
216*f0687c8aSRaman Tenneti 	memset(result, 0x0, sizeof(ESMatrix));
217*f0687c8aSRaman Tenneti 	result->m[0][0] = 1.0f;
218*f0687c8aSRaman Tenneti 	result->m[1][1] = 1.0f;
219*f0687c8aSRaman Tenneti 	result->m[2][2] = 1.0f;
220*f0687c8aSRaman Tenneti 	result->m[3][3] = 1.0f;
221*f0687c8aSRaman Tenneti }
222