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.
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
);
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
];
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
,
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
,
68 0.0f
, 0.0f
,-1.0f
, 0.0f
,
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
,
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
,
97 void CMatrixGL::Scalef(GLfloat x
, GLfloat y
, GLfloat z
)
99 const CMatrixGL matrix
{ x
, 0.0f
, 0.0f
, 0.0f
,
102 0.0f
, 0.0f
, 0.0f
, 1.0f
};
106 void CMatrixGL::Rotatef(GLfloat angle
, GLfloat x
, GLfloat y
, GLfloat z
)
108 GLfloat modulus
= std::sqrt((x
*x
)+(y
*y
)+(z
*z
));
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
,
130 0.0f
, 0.0f
, 0.0f
, 1.0f
};
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
);
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
;
178 GLfloat tmp
= std::sqrt(forward
[0]*forward
[0] + forward
[1]*forward
[1] + forward
[2]*forward
[2]);
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]);
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
,
210 Translatef(-eyex
, -eyey
, -eyez
);
213 static void __gluMultMatrixVecf(const GLfloat matrix
[16], const GLfloat in
[4], GLfloat out
[4])
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
)
236 __gluMultMatrixVecf(modelMatrix
, in
, out
);
237 __gluMultMatrixVecf(projMatrix
, out
, in
);
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];
258 void CMatrixGLStack::Load()