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 // LightsTest.cpp: Tests basic usage of glLight*.
8
9 #include "test_utils/ANGLETest.h"
10 #include "test_utils/gl_raii.h"
11
12 #include "common/matrix_utils.h"
13 #include "common/vector_utils.h"
14 #include "util/random_utils.h"
15
16 #include <stdint.h>
17
18 #include <vector>
19
20 using namespace angle;
21
22 class LightsTest : public ANGLETest
23 {
24 protected:
LightsTest()25 LightsTest()
26 {
27 setWindowWidth(32);
28 setWindowHeight(32);
29 setConfigRedBits(8);
30 setConfigGreenBits(8);
31 setConfigBlueBits(8);
32 setConfigAlphaBits(8);
33 setConfigDepthBits(24);
34 }
35 };
36
37 // Check that the initial lighting parameters state is correct,
38 // including spec minimum for light count.
TEST_P(LightsTest,InitialState)39 TEST_P(LightsTest, InitialState)
40 {
41 const GLColor32F kAmbientInitial(0.2f, 0.2f, 0.2f, 1.0f);
42 GLboolean kLightModelTwoSideInitial = GL_FALSE;
43
44 GLColor32F lightModelAmbient;
45 GLboolean lightModelTwoSide;
46
47 glGetFloatv(GL_LIGHT_MODEL_AMBIENT, &lightModelAmbient.R);
48 EXPECT_GL_NO_ERROR();
49 EXPECT_EQ(kAmbientInitial, lightModelAmbient);
50
51 glGetBooleanv(GL_LIGHT_MODEL_TWO_SIDE, &lightModelTwoSide);
52 EXPECT_GL_NO_ERROR();
53 EXPECT_EQ(kLightModelTwoSideInitial, lightModelTwoSide);
54
55 EXPECT_GL_FALSE(glIsEnabled(GL_LIGHTING));
56 EXPECT_GL_NO_ERROR();
57 EXPECT_GL_FALSE(glIsEnabled(GL_NORMALIZE));
58 EXPECT_GL_NO_ERROR();
59 EXPECT_GL_FALSE(glIsEnabled(GL_RESCALE_NORMAL));
60 EXPECT_GL_NO_ERROR();
61 EXPECT_GL_FALSE(glIsEnabled(GL_COLOR_MATERIAL));
62 EXPECT_GL_NO_ERROR();
63
64 GLint maxLights = 0;
65 glGetIntegerv(GL_MAX_LIGHTS, &maxLights);
66 EXPECT_GL_NO_ERROR();
67 EXPECT_GE(8, maxLights);
68
69 const GLColor32F kLightnAmbient(0.0f, 0.0f, 0.0f, 1.0f);
70 const GLColor32F kLightnDiffuse(0.0f, 0.0f, 0.0f, 1.0f);
71 const GLColor32F kLightnSpecular(0.0f, 0.0f, 0.0f, 1.0f);
72 const GLColor32F kLight0Diffuse(1.0f, 1.0f, 1.0f, 1.0f);
73 const GLColor32F kLight0Specular(1.0f, 1.0f, 1.0f, 1.0f);
74 const angle::Vector4 kLightnPosition(0.0f, 0.0f, 1.0f, 0.0f);
75 const angle::Vector3 kLightnDirection(0.0f, 0.0f, -1.0f);
76 const GLfloat kLightnSpotlightExponent = 0.0f;
77 const GLfloat kLightnSpotlightCutoffAngle = 180.0f;
78 const GLfloat kLightnAttenuationConst = 1.0f;
79 const GLfloat kLightnAttenuationLinear = 0.0f;
80 const GLfloat kLightnAttenuationQuadratic = 0.0f;
81
82 for (int i = 0; i < maxLights; i++)
83 {
84 EXPECT_GL_FALSE(glIsEnabled(GL_LIGHT0 + i));
85 EXPECT_GL_NO_ERROR();
86
87 GLColor32F actualColor;
88 angle::Vector4 actualPosition;
89 angle::Vector3 actualDirection;
90 GLfloat actualFloatValue;
91
92 glGetLightfv(GL_LIGHT0 + i, GL_AMBIENT, &actualColor.R);
93 EXPECT_GL_NO_ERROR();
94 EXPECT_EQ(kLightnAmbient, actualColor);
95
96 glGetLightfv(GL_LIGHT0 + i, GL_DIFFUSE, &actualColor.R);
97 EXPECT_GL_NO_ERROR();
98 EXPECT_EQ(i == 0 ? kLight0Diffuse : kLightnDiffuse, actualColor);
99
100 glGetLightfv(GL_LIGHT0 + i, GL_SPECULAR, &actualColor.R);
101 EXPECT_GL_NO_ERROR();
102 EXPECT_EQ(i == 0 ? kLight0Specular : kLightnSpecular, actualColor);
103
104 glGetLightfv(GL_LIGHT0 + i, GL_POSITION, actualPosition.data());
105 EXPECT_GL_NO_ERROR();
106 EXPECT_EQ(kLightnPosition, actualPosition);
107
108 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION, actualDirection.data());
109 EXPECT_GL_NO_ERROR();
110 EXPECT_EQ(kLightnDirection, actualDirection);
111
112 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_EXPONENT, &actualFloatValue);
113 EXPECT_GL_NO_ERROR();
114 EXPECT_EQ(kLightnSpotlightExponent, actualFloatValue);
115
116 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &actualFloatValue);
117 EXPECT_GL_NO_ERROR();
118 EXPECT_EQ(kLightnSpotlightCutoffAngle, actualFloatValue);
119
120 glGetLightfv(GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, &actualFloatValue);
121 EXPECT_GL_NO_ERROR();
122 EXPECT_EQ(kLightnAttenuationConst, actualFloatValue);
123
124 glGetLightfv(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, &actualFloatValue);
125 EXPECT_GL_NO_ERROR();
126 EXPECT_EQ(kLightnAttenuationLinear, actualFloatValue);
127
128 glGetLightfv(GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION, &actualFloatValue);
129 EXPECT_GL_NO_ERROR();
130 EXPECT_EQ(kLightnAttenuationQuadratic, actualFloatValue);
131 }
132 }
133
134 // Negative test for invalid parameter names.
TEST_P(LightsTest,NegativeInvalidEnum)135 TEST_P(LightsTest, NegativeInvalidEnum)
136 {
137 GLint maxLights = 0;
138 glGetIntegerv(GL_MAX_LIGHTS, &maxLights);
139
140 glIsEnabled(GL_LIGHT0 + maxLights);
141 EXPECT_GL_ERROR(GL_INVALID_ENUM);
142
143 glLightfv(GL_LIGHT0 + maxLights, GL_AMBIENT, nullptr);
144 EXPECT_GL_ERROR(GL_INVALID_ENUM);
145
146 glLightModelfv(GL_LIGHT0, nullptr);
147 EXPECT_GL_ERROR(GL_INVALID_ENUM);
148
149 glLightModelf(GL_LIGHT0, 0.0f);
150 EXPECT_GL_ERROR(GL_INVALID_ENUM);
151
152 for (int i = 0; i < maxLights; i++)
153 {
154 glLightf(GL_LIGHT0 + i, GL_TEXTURE_2D, 0.0f);
155 EXPECT_GL_ERROR(GL_INVALID_ENUM);
156
157 glLightfv(GL_LIGHT0 + i, GL_TEXTURE_2D, nullptr);
158 EXPECT_GL_ERROR(GL_INVALID_ENUM);
159 }
160 }
161
162 // Negative test for invalid parameter values.
TEST_P(LightsTest,NegativeInvalidValue)163 TEST_P(LightsTest, NegativeInvalidValue)
164 {
165 GLint maxLights = 0;
166 glGetIntegerv(GL_MAX_LIGHTS, &maxLights);
167
168 std::vector<GLenum> attenuationParams = {
169 GL_CONSTANT_ATTENUATION,
170 GL_LINEAR_ATTENUATION,
171 GL_QUADRATIC_ATTENUATION,
172 };
173
174 for (int i = 0; i < maxLights; i++)
175 {
176 glLightf(GL_LIGHT0 + i, GL_SPOT_EXPONENT, -1.0f);
177 EXPECT_GL_ERROR(GL_INVALID_VALUE);
178 GLfloat previousVal = -1.0f;
179 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_EXPONENT, &previousVal);
180 EXPECT_NE(-1.0f, previousVal);
181
182 glLightf(GL_LIGHT0 + i, GL_SPOT_EXPONENT, 128.1f);
183 EXPECT_GL_ERROR(GL_INVALID_VALUE);
184 previousVal = 128.1f;
185 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_EXPONENT, &previousVal);
186 EXPECT_NE(128.1f, previousVal);
187
188 glLightf(GL_LIGHT0 + i, GL_SPOT_CUTOFF, -1.0f);
189 EXPECT_GL_ERROR(GL_INVALID_VALUE);
190 previousVal = -1.0f;
191 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &previousVal);
192 EXPECT_NE(-1.0f, previousVal);
193
194 glLightf(GL_LIGHT0 + i, GL_SPOT_CUTOFF, 90.1f);
195 EXPECT_GL_ERROR(GL_INVALID_VALUE);
196 previousVal = 90.1f;
197 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &previousVal);
198 EXPECT_NE(90.1f, previousVal);
199
200 for (GLenum pname : attenuationParams)
201 {
202 glLightf(GL_LIGHT0 + i, pname, -1.0f);
203 EXPECT_GL_ERROR(GL_INVALID_VALUE);
204 previousVal = -1.0f;
205 glGetLightfv(GL_LIGHT0 + i, pname, &previousVal);
206 EXPECT_NE(-1.0f, previousVal);
207 }
208 }
209 }
210
211 // Test to see if we can set and retrieve the light parameters.
TEST_P(LightsTest,Set)212 TEST_P(LightsTest, Set)
213 {
214 angle::RNG rng(0);
215
216 GLint maxLights = 0;
217 glGetIntegerv(GL_MAX_LIGHTS, &maxLights);
218
219 constexpr int kNumTrials = 100;
220
221 GLColor32F actualColor;
222 angle::Vector4 actualPosition;
223 angle::Vector3 actualDirection;
224 GLfloat actualFloatValue;
225 GLboolean actualBooleanValue;
226
227 for (int k = 0; k < kNumTrials; ++k)
228 {
229 const GLColor32F lightModelAmbient(rng.randomFloat(), rng.randomFloat(), rng.randomFloat(),
230 rng.randomFloat());
231 const GLfloat lightModelTwoSide = rng.randomBool() ? 1.0f : 0.0f;
232
233 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, &lightModelAmbient.R);
234 EXPECT_GL_NO_ERROR();
235 glGetFloatv(GL_LIGHT_MODEL_AMBIENT, &actualColor.R);
236 EXPECT_EQ(lightModelAmbient, actualColor);
237
238 glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, lightModelTwoSide);
239 EXPECT_GL_NO_ERROR();
240 glGetFloatv(GL_LIGHT_MODEL_TWO_SIDE, &actualFloatValue);
241 EXPECT_EQ(lightModelTwoSide, actualFloatValue);
242 glGetBooleanv(GL_LIGHT_MODEL_TWO_SIDE, &actualBooleanValue);
243 EXPECT_EQ(lightModelTwoSide == 1.0f ? GL_TRUE : GL_FALSE, actualBooleanValue);
244
245 for (int i = 0; i < maxLights; i++)
246 {
247
248 const GLColor32F ambient(rng.randomFloat(), rng.randomFloat(), rng.randomFloat(),
249 rng.randomFloat());
250 const GLColor32F diffuse(rng.randomFloat(), rng.randomFloat(), rng.randomFloat(),
251 rng.randomFloat());
252 const GLColor32F specular(rng.randomFloat(), rng.randomFloat(), rng.randomFloat(),
253 rng.randomFloat());
254 const angle::Vector4 position(rng.randomFloat(), rng.randomFloat(), rng.randomFloat(),
255 rng.randomFloat());
256 const angle::Vector3 direction(rng.randomFloat(), rng.randomFloat(), rng.randomFloat());
257 const GLfloat spotlightExponent = rng.randomFloatBetween(0.0f, 128.0f);
258 const GLfloat spotlightCutoffAngle =
259 rng.randomBool() ? rng.randomFloatBetween(0.0f, 90.0f) : 180.0f;
260 const GLfloat attenuationConst = rng.randomFloatNonnegative();
261 const GLfloat attenuationLinear = rng.randomFloatNonnegative();
262 const GLfloat attenuationQuadratic = rng.randomFloatNonnegative();
263
264 glLightfv(GL_LIGHT0 + i, GL_AMBIENT, &ambient.R);
265 EXPECT_GL_NO_ERROR();
266 glGetLightfv(GL_LIGHT0 + i, GL_AMBIENT, &actualColor.R);
267 EXPECT_EQ(ambient, actualColor);
268
269 glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, &diffuse.R);
270 EXPECT_GL_NO_ERROR();
271 glGetLightfv(GL_LIGHT0 + i, GL_DIFFUSE, &actualColor.R);
272 EXPECT_EQ(diffuse, actualColor);
273
274 glLightfv(GL_LIGHT0 + i, GL_SPECULAR, &specular.R);
275 EXPECT_GL_NO_ERROR();
276 glGetLightfv(GL_LIGHT0 + i, GL_SPECULAR, &actualColor.R);
277 EXPECT_EQ(specular, actualColor);
278
279 glLightfv(GL_LIGHT0 + i, GL_POSITION, position.data());
280 EXPECT_GL_NO_ERROR();
281 glGetLightfv(GL_LIGHT0 + i, GL_POSITION, actualPosition.data());
282 EXPECT_EQ(position, actualPosition);
283
284 glLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION, direction.data());
285 EXPECT_GL_NO_ERROR();
286 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION, actualDirection.data());
287 EXPECT_EQ(direction, actualDirection);
288
289 glLightfv(GL_LIGHT0 + i, GL_SPOT_EXPONENT, &spotlightExponent);
290 EXPECT_GL_NO_ERROR();
291 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_EXPONENT, &actualFloatValue);
292 EXPECT_EQ(spotlightExponent, actualFloatValue);
293
294 glLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &spotlightCutoffAngle);
295 EXPECT_GL_NO_ERROR();
296 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &actualFloatValue);
297 EXPECT_EQ(spotlightCutoffAngle, actualFloatValue);
298
299 glLightfv(GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, &attenuationConst);
300 EXPECT_GL_NO_ERROR();
301 glGetLightfv(GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, &actualFloatValue);
302 EXPECT_EQ(attenuationConst, actualFloatValue);
303
304 glLightfv(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, &attenuationLinear);
305 EXPECT_GL_NO_ERROR();
306 glGetLightfv(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, &actualFloatValue);
307 EXPECT_EQ(attenuationLinear, actualFloatValue);
308
309 glLightfv(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, &attenuationQuadratic);
310 EXPECT_GL_NO_ERROR();
311 glGetLightfv(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, &actualFloatValue);
312 EXPECT_EQ(attenuationQuadratic, actualFloatValue);
313 }
314 }
315 }
316
317 ANGLE_INSTANTIATE_TEST_ES1(LightsTest);
318