Merge pull request #26220 from 78andyp/blurayfixes
[xbmc.git] / xbmc / rendering / MatrixGL.cpp
blob6e903831de11a1ce27c91fbf84b5390888535d19
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "MatrixGL.h"
11 #include "ServiceBroker.h"
12 #include "utils/TransformMatrix.h"
14 #if defined(HAS_NEON) && !defined(__LP64__)
15 #include "utils/CPUInfo.h"
16 void Matrix4Mul(float* src_mat_1, const float* src_mat_2);
17 #endif
19 #include <cmath>
21 CMatrixGLStack glMatrixModview = CMatrixGLStack();
22 CMatrixGLStack glMatrixProject = CMatrixGLStack();
23 CMatrixGLStack glMatrixTexture = CMatrixGLStack();
25 CMatrixGL::CMatrixGL(const TransformMatrix &src) noexcept
27 for(int i = 0; i < 3; i++)
28 for(int j = 0; j < 4; j++)
29 m_pMatrix[j * 4 + i] = src.m[i][j];
31 m_pMatrix[3] = 0.0f;
32 m_pMatrix[7] = 0.0f;
33 m_pMatrix[11] = 0.0f;
34 m_pMatrix[15] = 1.0f;
37 void CMatrixGL::LoadIdentity()
39 m_pMatrix[0] = 1.0f; m_pMatrix[4] = 0.0f; m_pMatrix[8] = 0.0f; m_pMatrix[12] = 0.0f;
40 m_pMatrix[1] = 0.0f; m_pMatrix[5] = 1.0f; m_pMatrix[9] = 0.0f; m_pMatrix[13] = 0.0f;
41 m_pMatrix[2] = 0.0f; m_pMatrix[6] = 0.0f; m_pMatrix[10] = 1.0f; m_pMatrix[14] = 0.0f;
42 m_pMatrix[3] = 0.0f; m_pMatrix[7] = 0.0f; m_pMatrix[11] = 0.0f; m_pMatrix[15] = 1.0f;
45 void CMatrixGL::Ortho(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f)
47 GLfloat u = 2.0f / (r - l);
48 GLfloat v = 2.0f / (t - b);
49 GLfloat w = -2.0f / (f - n);
50 GLfloat x = - (r + l) / (r - l);
51 GLfloat y = - (t + b) / (t - b);
52 GLfloat z = - (f + n) / (f - n);
53 const CMatrixGL matrix{ u, 0.0f, 0.0f, 0.0f,
54 0.0f, v, 0.0f, 0.0f,
55 0.0f, 0.0f, w, 0.0f,
56 x, y, z, 1.0f};
57 MultMatrixf(matrix);
60 void CMatrixGL::Ortho2D(GLfloat l, GLfloat r, GLfloat b, GLfloat t)
62 GLfloat u = 2.0f / (r - l);
63 GLfloat v = 2.0f / (t - b);
64 GLfloat x = - (r + l) / (r - l);
65 GLfloat y = - (t + b) / (t - b);
66 const CMatrixGL matrix{ u, 0.0f, 0.0f, 0.0f,
67 0.0f, v, 0.0f, 0.0f,
68 0.0f, 0.0f,-1.0f, 0.0f,
69 x, y, 0.0f, 1.0f};
70 MultMatrixf(matrix);
73 void CMatrixGL::Frustum(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f)
75 GLfloat u = (2.0f * n) / (r - l);
76 GLfloat v = (2.0f * n) / (t - b);
77 GLfloat w = (r + l) / (r - l);
78 GLfloat x = (t + b) / (t - b);
79 GLfloat y = - (f + n) / (f - n);
80 GLfloat z = - (2.0f * f * n) / (f - n);
81 const CMatrixGL matrix{ u, 0.0f, 0.0f, 0.0f,
82 0.0f, v, 0.0f, 0.0f,
83 w, x, y,-1.0f,
84 0.0f, 0.0f, z, 0.0f};
85 MultMatrixf(matrix);
88 void CMatrixGL::Translatef(GLfloat x, GLfloat y, GLfloat z)
90 const CMatrixGL matrix{1.0f, 0.0f, 0.0f, 0.0f,
91 0.0f, 1.0f, 0.0f, 0.0f,
92 0.0f, 0.0f, 1.0f, 0.0f,
93 x, y, z, 1.0f};
94 MultMatrixf(matrix);
97 void CMatrixGL::Scalef(GLfloat x, GLfloat y, GLfloat z)
99 const CMatrixGL matrix{ x, 0.0f, 0.0f, 0.0f,
100 0.0f, y, 0.0f, 0.0f,
101 0.0f, 0.0f, z, 0.0f,
102 0.0f, 0.0f, 0.0f, 1.0f};
103 MultMatrixf(matrix);
106 void CMatrixGL::Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
108 GLfloat modulus = std::sqrt((x*x)+(y*y)+(z*z));
109 if (modulus != 0.0f)
111 x /= modulus;
112 y /= modulus;
113 z /= modulus;
115 GLfloat cosine = std::cos(angle);
116 GLfloat sine = std::sin(angle);
117 GLfloat cos1 = 1 - cosine;
118 GLfloat a = (x*x*cos1) + cosine;
119 GLfloat b = (x*y*cos1) - (z*sine);
120 GLfloat c = (x*z*cos1) + (y*sine);
121 GLfloat d = (y*x*cos1) + (z*sine);
122 GLfloat e = (y*y*cos1) + cosine;
123 GLfloat f = (y*z*cos1) - (x*sine);
124 GLfloat g = (z*x*cos1) - (y*sine);
125 GLfloat h = (z*y*cos1) + (x*sine);
126 GLfloat i = (z*z*cos1) + cosine;
127 const CMatrixGL matrix{ a, d, g, 0.0f,
128 b, e, h, 0.0f,
129 c, f, i, 0.0f,
130 0.0f, 0.0f, 0.0f, 1.0f};
131 MultMatrixf(matrix);
134 void CMatrixGL::MultMatrixf(const CMatrixGL &matrix) noexcept
136 #if defined(HAS_NEON) && !defined(__LP64__)
137 if ((CServiceBroker::GetCPUInfo()->GetCPUFeatures() & CPU_FEATURE_NEON) == CPU_FEATURE_NEON)
139 Matrix4Mul(m_pMatrix, matrix.m_pMatrix);
140 return;
142 #endif
143 GLfloat a = (matrix.m_pMatrix[0] * m_pMatrix[0]) + (matrix.m_pMatrix[1] * m_pMatrix[4]) + (matrix.m_pMatrix[2] * m_pMatrix[8]) + (matrix.m_pMatrix[3] * m_pMatrix[12]);
144 GLfloat b = (matrix.m_pMatrix[0] * m_pMatrix[1]) + (matrix.m_pMatrix[1] * m_pMatrix[5]) + (matrix.m_pMatrix[2] * m_pMatrix[9]) + (matrix.m_pMatrix[3] * m_pMatrix[13]);
145 GLfloat c = (matrix.m_pMatrix[0] * m_pMatrix[2]) + (matrix.m_pMatrix[1] * m_pMatrix[6]) + (matrix.m_pMatrix[2] * m_pMatrix[10]) + (matrix.m_pMatrix[3] * m_pMatrix[14]);
146 GLfloat d = (matrix.m_pMatrix[0] * m_pMatrix[3]) + (matrix.m_pMatrix[1] * m_pMatrix[7]) + (matrix.m_pMatrix[2] * m_pMatrix[11]) + (matrix.m_pMatrix[3] * m_pMatrix[15]);
147 GLfloat e = (matrix.m_pMatrix[4] * m_pMatrix[0]) + (matrix.m_pMatrix[5] * m_pMatrix[4]) + (matrix.m_pMatrix[6] * m_pMatrix[8]) + (matrix.m_pMatrix[7] * m_pMatrix[12]);
148 GLfloat f = (matrix.m_pMatrix[4] * m_pMatrix[1]) + (matrix.m_pMatrix[5] * m_pMatrix[5]) + (matrix.m_pMatrix[6] * m_pMatrix[9]) + (matrix.m_pMatrix[7] * m_pMatrix[13]);
149 GLfloat g = (matrix.m_pMatrix[4] * m_pMatrix[2]) + (matrix.m_pMatrix[5] * m_pMatrix[6]) + (matrix.m_pMatrix[6] * m_pMatrix[10]) + (matrix.m_pMatrix[7] * m_pMatrix[14]);
150 GLfloat h = (matrix.m_pMatrix[4] * m_pMatrix[3]) + (matrix.m_pMatrix[5] * m_pMatrix[7]) + (matrix.m_pMatrix[6] * m_pMatrix[11]) + (matrix.m_pMatrix[7] * m_pMatrix[15]);
151 GLfloat i = (matrix.m_pMatrix[8] * m_pMatrix[0]) + (matrix.m_pMatrix[9] * m_pMatrix[4]) + (matrix.m_pMatrix[10] * m_pMatrix[8]) + (matrix.m_pMatrix[11] * m_pMatrix[12]);
152 GLfloat j = (matrix.m_pMatrix[8] * m_pMatrix[1]) + (matrix.m_pMatrix[9] * m_pMatrix[5]) + (matrix.m_pMatrix[10] * m_pMatrix[9]) + (matrix.m_pMatrix[11] * m_pMatrix[13]);
153 GLfloat k = (matrix.m_pMatrix[8] * m_pMatrix[2]) + (matrix.m_pMatrix[9] * m_pMatrix[6]) + (matrix.m_pMatrix[10] * m_pMatrix[10]) + (matrix.m_pMatrix[11] * m_pMatrix[14]);
154 GLfloat l = (matrix.m_pMatrix[8] * m_pMatrix[3]) + (matrix.m_pMatrix[9] * m_pMatrix[7]) + (matrix.m_pMatrix[10] * m_pMatrix[11]) + (matrix.m_pMatrix[11] * m_pMatrix[15]);
155 GLfloat m = (matrix.m_pMatrix[12] * m_pMatrix[0]) + (matrix.m_pMatrix[13] * m_pMatrix[4]) + (matrix.m_pMatrix[14] * m_pMatrix[8]) + (matrix.m_pMatrix[15] * m_pMatrix[12]);
156 GLfloat n = (matrix.m_pMatrix[12] * m_pMatrix[1]) + (matrix.m_pMatrix[13] * m_pMatrix[5]) + (matrix.m_pMatrix[14] * m_pMatrix[9]) + (matrix.m_pMatrix[15] * m_pMatrix[13]);
157 GLfloat o = (matrix.m_pMatrix[12] * m_pMatrix[2]) + (matrix.m_pMatrix[13] * m_pMatrix[6]) + (matrix.m_pMatrix[14] * m_pMatrix[10]) + (matrix.m_pMatrix[15] * m_pMatrix[14]);
158 GLfloat p = (matrix.m_pMatrix[12] * m_pMatrix[3]) + (matrix.m_pMatrix[13] * m_pMatrix[7]) + (matrix.m_pMatrix[14] * m_pMatrix[11]) + (matrix.m_pMatrix[15] * m_pMatrix[15]);
159 m_pMatrix[0] = a; m_pMatrix[4] = e; m_pMatrix[8] = i; m_pMatrix[12] = m;
160 m_pMatrix[1] = b; m_pMatrix[5] = f; m_pMatrix[9] = j; m_pMatrix[13] = n;
161 m_pMatrix[2] = c; m_pMatrix[6] = g; m_pMatrix[10] = k; m_pMatrix[14] = o;
162 m_pMatrix[3] = d; m_pMatrix[7] = h; m_pMatrix[11] = l; m_pMatrix[15] = p;
165 // gluLookAt implementation taken from Mesa3D
166 void CMatrixGL::LookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx, GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy, GLfloat upz)
168 GLfloat forward[3], side[3], up[3];
170 forward[0] = centerx - eyex;
171 forward[1] = centery - eyey;
172 forward[2] = centerz - eyez;
174 up[0] = upx;
175 up[1] = upy;
176 up[2] = upz;
178 GLfloat tmp = std::sqrt(forward[0]*forward[0] + forward[1]*forward[1] + forward[2]*forward[2]);
179 if (tmp != 0.0f)
181 forward[0] /= tmp;
182 forward[1] /= tmp;
183 forward[2] /= tmp;
186 side[0] = forward[1]*up[2] - forward[2]*up[1];
187 side[1] = forward[2]*up[0] - forward[0]*up[2];
188 side[2] = forward[0]*up[1] - forward[1]*up[0];
190 tmp = std::sqrt(side[0]*side[0] + side[1]*side[1] + side[2]*side[2]);
191 if (tmp != 0.0f)
193 side[0] /= tmp;
194 side[1] /= tmp;
195 side[2] /= tmp;
198 up[0] = side[1]*forward[2] - side[2]*forward[1];
199 up[1] = side[2]*forward[0] - side[0]*forward[2];
200 up[2] = side[0]*forward[1] - side[1]*forward[0];
202 const CMatrixGL matrix{
203 side[0], up[0], -forward[0], 0.0f,
204 side[1], up[1], -forward[1], 0.0f,
205 side[2], up[2], -forward[2], 0.0f,
206 0.0f, 0.0f, 0.0f, 1.0f,
209 MultMatrixf(matrix);
210 Translatef(-eyex, -eyey, -eyez);
213 static void __gluMultMatrixVecf(const GLfloat matrix[16], const GLfloat in[4], GLfloat out[4])
215 int i;
217 for (i=0; i<4; i++)
219 out[i] = in[0] * matrix[0*4+i] +
220 in[1] * matrix[1*4+i] +
221 in[2] * matrix[2*4+i] +
222 in[3] * matrix[3*4+i];
226 // gluProject implementation taken from Mesa3D
227 bool CMatrixGL::Project(GLfloat objx, GLfloat objy, GLfloat objz, const GLfloat modelMatrix[16], const GLfloat projMatrix[16], const GLint viewport[4], GLfloat* winx, GLfloat* winy, GLfloat* winz)
229 GLfloat in[4];
230 GLfloat out[4];
232 in[0]=objx;
233 in[1]=objy;
234 in[2]=objz;
235 in[3]=1.0;
236 __gluMultMatrixVecf(modelMatrix, in, out);
237 __gluMultMatrixVecf(projMatrix, out, in);
238 if (in[3] == 0.0f)
239 return false;
240 in[0] /= in[3];
241 in[1] /= in[3];
242 in[2] /= in[3];
243 /* Map x, y and z to range 0-1 */
244 in[0] = in[0] * 0.5f + 0.5f;
245 in[1] = in[1] * 0.5f + 0.5f;
246 in[2] = in[2] * 0.5f + 0.5f;
248 /* Map x,y to viewport */
249 in[0] = in[0] * viewport[2] + viewport[0];
250 in[1] = in[1] * viewport[3] + viewport[1];
252 *winx=in[0];
253 *winy=in[1];
254 *winz=in[2];
255 return true;
258 void CMatrixGLStack::Load()