1 //
2 // Copyright 2018 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // MatrixBuiltinsTest.cpp: Tests basic usage of builtin matrix operations.
8
9 #include "test_utils/ANGLETest.h"
10 #include "test_utils/gl_raii.h"
11
12 #include "common/matrix_utils.h"
13 #include "util/random_utils.h"
14
15 #include <stdint.h>
16
17 using namespace angle;
18
19 class MatrixBuiltinsTest : public ANGLETest<>
20 {
21 protected:
MatrixBuiltinsTest()22 MatrixBuiltinsTest()
23 {
24 setWindowWidth(32);
25 setWindowHeight(32);
26 setConfigRedBits(8);
27 setConfigGreenBits(8);
28 setConfigBlueBits(8);
29 setConfigAlphaBits(8);
30 setConfigDepthBits(24);
31 }
32 };
33
34 // Test rotation and check the matrix for closeness to a rotation matrix.
TEST_P(MatrixBuiltinsTest,Rotate)35 TEST_P(MatrixBuiltinsTest, Rotate)
36 {
37 constexpr float angle = 90.0f;
38 constexpr float x = 1.0f;
39 constexpr float y = 1.0f;
40 constexpr float z = 1.0f;
41
42 angle::Mat4 testMatrix = angle::Mat4::Rotate(angle, angle::Vector3(x, y, z));
43
44 glRotatef(angle, x, y, z);
45 EXPECT_GL_NO_ERROR();
46
47 angle::Mat4 outputMatrix;
48 glGetFloatv(GL_MODELVIEW_MATRIX, outputMatrix.data());
49 EXPECT_GL_NO_ERROR();
50
51 EXPECT_TRUE(testMatrix.nearlyEqual(0.00001f, outputMatrix));
52 }
53
54 // Test that rotation of a (0, 0, 0) Vector doesn't result in NaN values.
TEST_P(MatrixBuiltinsTest,RotateAxisZero)55 TEST_P(MatrixBuiltinsTest, RotateAxisZero)
56 {
57 constexpr float angle = 90.0f;
58 constexpr float x = 0.0f;
59 constexpr float y = 0.0f;
60 constexpr float z = 0.0f;
61
62 angle::Mat4 testMatrix = angle::Mat4::Rotate(angle, angle::Vector3(x, y, z));
63
64 glRotatef(angle, x, y, z);
65 EXPECT_GL_NO_ERROR();
66
67 angle::Mat4 outputMatrix;
68 glGetFloatv(GL_MODELVIEW_MATRIX, outputMatrix.data());
69 EXPECT_GL_NO_ERROR();
70
71 const float *inputArray = testMatrix.data();
72 const float *outputArray = outputMatrix.data();
73 for (int index = 0; index < 16; index++)
74 {
75 EXPECT_FALSE(isnan(inputArray[index]));
76 EXPECT_FALSE(isnan(outputArray[index]));
77 }
78 }
79
80 // Test translation and check the matrix for closeness to a translation matrix.
TEST_P(MatrixBuiltinsTest,Translate)81 TEST_P(MatrixBuiltinsTest, Translate)
82 {
83 constexpr float x = 1.0f;
84 constexpr float y = 1.0f;
85 constexpr float z = 1.0f;
86
87 angle::Mat4 testMatrix = angle::Mat4::Translate(angle::Vector3(x, y, z));
88
89 glTranslatef(1.0f, 0.0f, 0.0f);
90 glTranslatef(0.0f, 1.0f, 0.0f);
91 glTranslatef(0.0f, 0.0f, 1.0f);
92 EXPECT_GL_NO_ERROR();
93
94 angle::Mat4 outputMatrix;
95 glGetFloatv(GL_MODELVIEW_MATRIX, outputMatrix.data());
96 EXPECT_GL_NO_ERROR();
97
98 EXPECT_TRUE(testMatrix.nearlyEqual(0.00001f, outputMatrix));
99 }
100
101 // Test scale and check the matrix for closeness to a scale matrix.
TEST_P(MatrixBuiltinsTest,Scale)102 TEST_P(MatrixBuiltinsTest, Scale)
103 {
104 constexpr float x = 3.0f;
105 constexpr float y = 9.0f;
106 constexpr float z = 27.0f;
107
108 angle::Mat4 testMatrix = angle::Mat4::Scale(angle::Vector3(x, y, z));
109
110 glScalef(3.0f, 3.0f, 3.0f);
111 glScalef(1.0f, 3.0f, 3.0f);
112 glScalef(1.0f, 1.0f, 3.0f);
113 EXPECT_GL_NO_ERROR();
114
115 angle::Mat4 outputMatrix;
116 glGetFloatv(GL_MODELVIEW_MATRIX, outputMatrix.data());
117 EXPECT_GL_NO_ERROR();
118
119 EXPECT_TRUE(testMatrix.nearlyEqual(0.00001f, outputMatrix));
120 }
121
122 // Test frustum projection and check the matrix values.
TEST_P(MatrixBuiltinsTest,Frustum)123 TEST_P(MatrixBuiltinsTest, Frustum)
124 {
125
126 constexpr float l = -1.0f;
127 constexpr float r = 1.0f;
128 constexpr float b = -1.0f;
129 constexpr float t = 1.0f;
130 constexpr float n = 0.1f;
131 constexpr float f = 1.0f;
132
133 angle::Mat4 testMatrix = angle::Mat4::Frustum(l, r, b, t, n, f);
134
135 glFrustumf(l, r, b, t, n, f);
136 EXPECT_GL_NO_ERROR();
137
138 angle::Mat4 outputMatrix;
139 glGetFloatv(GL_MODELVIEW_MATRIX, outputMatrix.data());
140 EXPECT_GL_NO_ERROR();
141
142 EXPECT_TRUE(testMatrix.nearlyEqual(0.00001f, outputMatrix));
143 }
144
145 // Test orthographic projection and check the matrix values.
TEST_P(MatrixBuiltinsTest,Ortho)146 TEST_P(MatrixBuiltinsTest, Ortho)
147 {
148 constexpr float l = -1.0f;
149 constexpr float r = 1.0f;
150 constexpr float b = -1.0f;
151 constexpr float t = 1.0f;
152 constexpr float n = 0.1f;
153 constexpr float f = 1.0f;
154
155 angle::Mat4 testMatrix = angle::Mat4::Ortho(l, r, b, t, n, f);
156
157 glOrthof(l, r, b, t, n, f);
158 EXPECT_GL_NO_ERROR();
159
160 angle::Mat4 outputMatrix;
161 glGetFloatv(GL_MODELVIEW_MATRIX, outputMatrix.data());
162 EXPECT_GL_NO_ERROR();
163
164 EXPECT_TRUE(testMatrix.nearlyEqual(0.00001f, outputMatrix));
165 }
166
167 // Test that GL_INVALID_VALUE is issued if potential divide by zero situations happen for
168 // glFrustumf.
TEST_P(MatrixBuiltinsTest,FrustumNegative)169 TEST_P(MatrixBuiltinsTest, FrustumNegative)
170 {
171 glFrustumf(1.0f, 1.0f, 0.0f, 1.0f, 0.1f, 1.0f);
172 EXPECT_GL_ERROR(GL_INVALID_VALUE);
173 glFrustumf(0.0f, 1.0f, 1.0f, 1.0f, 0.1f, 1.0f);
174 EXPECT_GL_ERROR(GL_INVALID_VALUE);
175 glFrustumf(0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f);
176 EXPECT_GL_ERROR(GL_INVALID_VALUE);
177 glFrustumf(0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f);
178 EXPECT_GL_ERROR(GL_INVALID_VALUE);
179 glFrustumf(0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f);
180 EXPECT_GL_ERROR(GL_INVALID_VALUE);
181 glFrustumf(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
182 EXPECT_GL_ERROR(GL_INVALID_VALUE);
183 }
184
185 // Test that GL_INVALID_VALUE is issued if potential divide by zero situations happen for glOrthof.
TEST_P(MatrixBuiltinsTest,OrthoNegative)186 TEST_P(MatrixBuiltinsTest, OrthoNegative)
187 {
188 glOrthof(1.0f, 1.0f, 0.0f, 1.0f, 0.1f, 1.0f);
189 EXPECT_GL_ERROR(GL_INVALID_VALUE);
190 glOrthof(0.0f, 1.0f, 1.0f, 1.0f, 0.1f, 1.0f);
191 EXPECT_GL_ERROR(GL_INVALID_VALUE);
192 glOrthof(0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f);
193 EXPECT_GL_ERROR(GL_INVALID_VALUE);
194 }
195
196 // Test that glOrtho{fx} don't issue error result if near or far is negative.
TEST_P(MatrixBuiltinsTest,OrthoNegativeNearFar)197 TEST_P(MatrixBuiltinsTest, OrthoNegativeNearFar)
198 {
199 glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 0.0f);
200 EXPECT_GL_NO_ERROR();
201 glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, -1.0f);
202 EXPECT_GL_NO_ERROR();
203 glOrthox(-1, 1, -1, 1, -1, 0);
204 EXPECT_GL_NO_ERROR();
205 glOrthox(-1, 1, -1, 1, 0, -1);
206 EXPECT_GL_NO_ERROR();
207 }
208
209 ANGLE_INSTANTIATE_TEST_ES1(MatrixBuiltinsTest);
210