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 void drawTestQuad();
37 };
38
39 // Check that the initial lighting parameters state is correct,
40 // including spec minimum for light count.
TEST_P(LightsTest,InitialState)41 TEST_P(LightsTest, InitialState)
42 {
43 const GLColor32F kAmbientInitial(0.2f, 0.2f, 0.2f, 1.0f);
44 GLboolean kLightModelTwoSideInitial = GL_FALSE;
45
46 GLColor32F lightModelAmbient;
47 GLboolean lightModelTwoSide;
48
49 glGetFloatv(GL_LIGHT_MODEL_AMBIENT, &lightModelAmbient.R);
50 EXPECT_GL_NO_ERROR();
51 EXPECT_EQ(kAmbientInitial, lightModelAmbient);
52
53 glGetBooleanv(GL_LIGHT_MODEL_TWO_SIDE, &lightModelTwoSide);
54 EXPECT_GL_NO_ERROR();
55 EXPECT_EQ(kLightModelTwoSideInitial, lightModelTwoSide);
56
57 EXPECT_GL_FALSE(glIsEnabled(GL_LIGHTING));
58 EXPECT_GL_NO_ERROR();
59 EXPECT_GL_FALSE(glIsEnabled(GL_NORMALIZE));
60 EXPECT_GL_NO_ERROR();
61 EXPECT_GL_FALSE(glIsEnabled(GL_RESCALE_NORMAL));
62 EXPECT_GL_NO_ERROR();
63 EXPECT_GL_FALSE(glIsEnabled(GL_COLOR_MATERIAL));
64 EXPECT_GL_NO_ERROR();
65
66 GLint maxLights = 0;
67 glGetIntegerv(GL_MAX_LIGHTS, &maxLights);
68 EXPECT_GL_NO_ERROR();
69 EXPECT_GE(8, maxLights);
70
71 const GLColor32F kLightnAmbient(0.0f, 0.0f, 0.0f, 1.0f);
72 const GLColor32F kLightnDiffuse(0.0f, 0.0f, 0.0f, 1.0f);
73 const GLColor32F kLightnSpecular(0.0f, 0.0f, 0.0f, 1.0f);
74 const GLColor32F kLight0Diffuse(1.0f, 1.0f, 1.0f, 1.0f);
75 const GLColor32F kLight0Specular(1.0f, 1.0f, 1.0f, 1.0f);
76 const angle::Vector4 kLightnPosition(0.0f, 0.0f, 1.0f, 0.0f);
77 const angle::Vector3 kLightnDirection(0.0f, 0.0f, -1.0f);
78 const GLfloat kLightnSpotlightExponent = 0.0f;
79 const GLfloat kLightnSpotlightCutoffAngle = 180.0f;
80 const GLfloat kLightnAttenuationConst = 1.0f;
81 const GLfloat kLightnAttenuationLinear = 0.0f;
82 const GLfloat kLightnAttenuationQuadratic = 0.0f;
83
84 for (int i = 0; i < maxLights; i++)
85 {
86 EXPECT_GL_FALSE(glIsEnabled(GL_LIGHT0 + i));
87 EXPECT_GL_NO_ERROR();
88
89 GLColor32F actualColor;
90 angle::Vector4 actualPosition;
91 angle::Vector3 actualDirection;
92 GLfloat actualFloatValue;
93
94 glGetLightfv(GL_LIGHT0 + i, GL_AMBIENT, &actualColor.R);
95 EXPECT_GL_NO_ERROR();
96 EXPECT_EQ(kLightnAmbient, actualColor);
97
98 glGetLightfv(GL_LIGHT0 + i, GL_DIFFUSE, &actualColor.R);
99 EXPECT_GL_NO_ERROR();
100 EXPECT_EQ(i == 0 ? kLight0Diffuse : kLightnDiffuse, actualColor);
101
102 glGetLightfv(GL_LIGHT0 + i, GL_SPECULAR, &actualColor.R);
103 EXPECT_GL_NO_ERROR();
104 EXPECT_EQ(i == 0 ? kLight0Specular : kLightnSpecular, actualColor);
105
106 glGetLightfv(GL_LIGHT0 + i, GL_POSITION, actualPosition.data());
107 EXPECT_GL_NO_ERROR();
108 EXPECT_EQ(kLightnPosition, actualPosition);
109
110 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION, actualDirection.data());
111 EXPECT_GL_NO_ERROR();
112 EXPECT_EQ(kLightnDirection, actualDirection);
113
114 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_EXPONENT, &actualFloatValue);
115 EXPECT_GL_NO_ERROR();
116 EXPECT_EQ(kLightnSpotlightExponent, actualFloatValue);
117
118 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &actualFloatValue);
119 EXPECT_GL_NO_ERROR();
120 EXPECT_EQ(kLightnSpotlightCutoffAngle, actualFloatValue);
121
122 glGetLightfv(GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, &actualFloatValue);
123 EXPECT_GL_NO_ERROR();
124 EXPECT_EQ(kLightnAttenuationConst, actualFloatValue);
125
126 glGetLightfv(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, &actualFloatValue);
127 EXPECT_GL_NO_ERROR();
128 EXPECT_EQ(kLightnAttenuationLinear, actualFloatValue);
129
130 glGetLightfv(GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION, &actualFloatValue);
131 EXPECT_GL_NO_ERROR();
132 EXPECT_EQ(kLightnAttenuationQuadratic, actualFloatValue);
133 }
134 }
135
136 // Negative test for invalid parameter names.
TEST_P(LightsTest,NegativeInvalidEnum)137 TEST_P(LightsTest, NegativeInvalidEnum)
138 {
139 GLint maxLights = 0;
140 glGetIntegerv(GL_MAX_LIGHTS, &maxLights);
141
142 glIsEnabled(GL_LIGHT0 + maxLights);
143 EXPECT_GL_ERROR(GL_INVALID_ENUM);
144
145 glLightfv(GL_LIGHT0 + maxLights, GL_AMBIENT, nullptr);
146 EXPECT_GL_ERROR(GL_INVALID_ENUM);
147
148 glLightModelfv(GL_LIGHT0, nullptr);
149 EXPECT_GL_ERROR(GL_INVALID_ENUM);
150
151 glLightModelf(GL_LIGHT0, 0.0f);
152 EXPECT_GL_ERROR(GL_INVALID_ENUM);
153
154 for (int i = 0; i < maxLights; i++)
155 {
156 glLightf(GL_LIGHT0 + i, GL_TEXTURE_2D, 0.0f);
157 EXPECT_GL_ERROR(GL_INVALID_ENUM);
158
159 glLightfv(GL_LIGHT0 + i, GL_TEXTURE_2D, nullptr);
160 EXPECT_GL_ERROR(GL_INVALID_ENUM);
161 }
162 }
163
164 // Negative test for invalid parameter values.
TEST_P(LightsTest,NegativeInvalidValue)165 TEST_P(LightsTest, NegativeInvalidValue)
166 {
167 GLint maxLights = 0;
168 glGetIntegerv(GL_MAX_LIGHTS, &maxLights);
169
170 std::vector<GLenum> attenuationParams = {
171 GL_CONSTANT_ATTENUATION,
172 GL_LINEAR_ATTENUATION,
173 GL_QUADRATIC_ATTENUATION,
174 };
175
176 for (int i = 0; i < maxLights; i++)
177 {
178 glLightf(GL_LIGHT0 + i, GL_SPOT_EXPONENT, -1.0f);
179 EXPECT_GL_ERROR(GL_INVALID_VALUE);
180 GLfloat previousVal = -1.0f;
181 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_EXPONENT, &previousVal);
182 EXPECT_NE(-1.0f, previousVal);
183
184 glLightf(GL_LIGHT0 + i, GL_SPOT_EXPONENT, 128.1f);
185 EXPECT_GL_ERROR(GL_INVALID_VALUE);
186 previousVal = 128.1f;
187 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_EXPONENT, &previousVal);
188 EXPECT_NE(128.1f, previousVal);
189
190 glLightf(GL_LIGHT0 + i, GL_SPOT_CUTOFF, -1.0f);
191 EXPECT_GL_ERROR(GL_INVALID_VALUE);
192 previousVal = -1.0f;
193 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &previousVal);
194 EXPECT_NE(-1.0f, previousVal);
195
196 glLightf(GL_LIGHT0 + i, GL_SPOT_CUTOFF, 90.1f);
197 EXPECT_GL_ERROR(GL_INVALID_VALUE);
198 previousVal = 90.1f;
199 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &previousVal);
200 EXPECT_NE(90.1f, previousVal);
201
202 for (GLenum pname : attenuationParams)
203 {
204 glLightf(GL_LIGHT0 + i, pname, -1.0f);
205 EXPECT_GL_ERROR(GL_INVALID_VALUE);
206 previousVal = -1.0f;
207 glGetLightfv(GL_LIGHT0 + i, pname, &previousVal);
208 EXPECT_NE(-1.0f, previousVal);
209 }
210 }
211 }
212
213 // Test to see if we can set and retrieve the light parameters.
TEST_P(LightsTest,Set)214 TEST_P(LightsTest, Set)
215 {
216 angle::RNG rng(0);
217
218 GLint maxLights = 0;
219 glGetIntegerv(GL_MAX_LIGHTS, &maxLights);
220
221 constexpr int kNumTrials = 100;
222
223 GLColor32F actualColor;
224 angle::Vector4 actualPosition;
225 angle::Vector3 actualDirection;
226 GLfloat actualFloatValue;
227 GLboolean actualBooleanValue;
228
229 for (int k = 0; k < kNumTrials; ++k)
230 {
231 const GLColor32F lightModelAmbient(rng.randomFloat(), rng.randomFloat(), rng.randomFloat(),
232 rng.randomFloat());
233 const GLfloat lightModelTwoSide = rng.randomBool() ? 1.0f : 0.0f;
234
235 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, &lightModelAmbient.R);
236 EXPECT_GL_NO_ERROR();
237 glGetFloatv(GL_LIGHT_MODEL_AMBIENT, &actualColor.R);
238 EXPECT_EQ(lightModelAmbient, actualColor);
239
240 glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, lightModelTwoSide);
241 EXPECT_GL_NO_ERROR();
242 glGetFloatv(GL_LIGHT_MODEL_TWO_SIDE, &actualFloatValue);
243 EXPECT_EQ(lightModelTwoSide, actualFloatValue);
244 glGetBooleanv(GL_LIGHT_MODEL_TWO_SIDE, &actualBooleanValue);
245 EXPECT_EQ(lightModelTwoSide == 1.0f ? GL_TRUE : GL_FALSE, actualBooleanValue);
246
247 for (int i = 0; i < maxLights; i++)
248 {
249
250 const GLColor32F ambient(rng.randomFloat(), rng.randomFloat(), rng.randomFloat(),
251 rng.randomFloat());
252 const GLColor32F diffuse(rng.randomFloat(), rng.randomFloat(), rng.randomFloat(),
253 rng.randomFloat());
254 const GLColor32F specular(rng.randomFloat(), rng.randomFloat(), rng.randomFloat(),
255 rng.randomFloat());
256 const angle::Vector4 position(rng.randomFloat(), rng.randomFloat(), rng.randomFloat(),
257 rng.randomFloat());
258 const angle::Vector3 direction(rng.randomFloat(), rng.randomFloat(), rng.randomFloat());
259 const GLfloat spotlightExponent = rng.randomFloatBetween(0.0f, 128.0f);
260 const GLfloat spotlightCutoffAngle =
261 rng.randomBool() ? rng.randomFloatBetween(0.0f, 90.0f) : 180.0f;
262 const GLfloat attenuationConst = rng.randomFloatNonnegative();
263 const GLfloat attenuationLinear = rng.randomFloatNonnegative();
264 const GLfloat attenuationQuadratic = rng.randomFloatNonnegative();
265
266 glLightfv(GL_LIGHT0 + i, GL_AMBIENT, &ambient.R);
267 EXPECT_GL_NO_ERROR();
268 glGetLightfv(GL_LIGHT0 + i, GL_AMBIENT, &actualColor.R);
269 EXPECT_EQ(ambient, actualColor);
270
271 glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, &diffuse.R);
272 EXPECT_GL_NO_ERROR();
273 glGetLightfv(GL_LIGHT0 + i, GL_DIFFUSE, &actualColor.R);
274 EXPECT_EQ(diffuse, actualColor);
275
276 glLightfv(GL_LIGHT0 + i, GL_SPECULAR, &specular.R);
277 EXPECT_GL_NO_ERROR();
278 glGetLightfv(GL_LIGHT0 + i, GL_SPECULAR, &actualColor.R);
279 EXPECT_EQ(specular, actualColor);
280
281 glLightfv(GL_LIGHT0 + i, GL_POSITION, position.data());
282 EXPECT_GL_NO_ERROR();
283 glGetLightfv(GL_LIGHT0 + i, GL_POSITION, actualPosition.data());
284 EXPECT_EQ(position, actualPosition);
285
286 glLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION, direction.data());
287 EXPECT_GL_NO_ERROR();
288 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION, actualDirection.data());
289 EXPECT_EQ(direction, actualDirection);
290
291 glLightfv(GL_LIGHT0 + i, GL_SPOT_EXPONENT, &spotlightExponent);
292 EXPECT_GL_NO_ERROR();
293 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_EXPONENT, &actualFloatValue);
294 EXPECT_EQ(spotlightExponent, actualFloatValue);
295
296 glLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &spotlightCutoffAngle);
297 EXPECT_GL_NO_ERROR();
298 glGetLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &actualFloatValue);
299 EXPECT_EQ(spotlightCutoffAngle, actualFloatValue);
300
301 glLightfv(GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, &attenuationConst);
302 EXPECT_GL_NO_ERROR();
303 glGetLightfv(GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, &actualFloatValue);
304 EXPECT_EQ(attenuationConst, actualFloatValue);
305
306 glLightfv(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, &attenuationLinear);
307 EXPECT_GL_NO_ERROR();
308 glGetLightfv(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, &actualFloatValue);
309 EXPECT_EQ(attenuationLinear, actualFloatValue);
310
311 glLightfv(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, &attenuationQuadratic);
312 EXPECT_GL_NO_ERROR();
313 glGetLightfv(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, &actualFloatValue);
314 EXPECT_EQ(attenuationQuadratic, actualFloatValue);
315 }
316 }
317 }
318
319 // Check a case that approximates the one caught in the wild
TEST_P(LightsTest,DiffuseGradient)320 TEST_P(LightsTest, DiffuseGradient)
321 {
322 GLTexture texture;
323 glBindTexture(GL_TEXTURE_2D, texture);
324 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
325
326 std::vector<GLColor> colors;
327 for (uint32_t x = 0; x < 1024; x++)
328 {
329 for (uint32_t y = 0; y < 1024; y++)
330 {
331 float x_ratio = (float)x / 1024.0f;
332 GLubyte v = (GLubyte)(255u * x_ratio);
333
334 GLColor color = {v, v, v, 255u};
335 colors.push_back(color);
336 }
337 }
338 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE,
339 colors.data());
340
341 glMatrixMode(GL_PROJECTION);
342
343 const GLfloat projectionMatrix[16] = {
344 0.615385, 0, 0, 0, 0, 1.333333, 0, 0, 0, 0, 1, 1, 0, 0, -2, 0,
345 };
346 glLoadMatrixf(projectionMatrix);
347
348 glEnable(GL_LIGHT0);
349 glEnable(GL_TEXTURE_2D);
350 glEnable(GL_LIGHTING);
351
352 glEnableClientState(GL_VERTEX_ARRAY);
353 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
354
355 glClearColor(1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f, 1.0f);
356 glClear(GL_COLOR_BUFFER_BIT);
357
358 glViewport(0.0f, 0.0f, 32.0f, 32.0f);
359
360 const GLfloat ambient[4] = {2.0f, 2.0f, 2.0f, 1.0f};
361 const GLfloat diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f};
362 const GLfloat position[4] = {0.0f, 0.0f, 0.0f, 1.0f};
363
364 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
365 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
366 glLightfv(GL_LIGHT0, GL_POSITION, position);
367
368 glMatrixMode(GL_MODELVIEW);
369
370 const GLfloat modelMatrix[16] = {
371 0.976656, 0.000000, -0.214807, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
372 0.214807, 0.000000, 0.976656, 0.000000, -96.007507, 0.000000, 200.000000, 1.000000,
373 };
374 glLoadMatrixf(modelMatrix);
375
376 glBindTexture(GL_TEXTURE_2D, texture);
377
378 std::vector<float> positions = {
379 -64.0f, -89.0f, 1.0f, -64.0f, 89.0f, 1.0f, 64.0f, -89.0f, 1.0f, 64.0f, 89.0f, 1.0f,
380 };
381
382 std::vector<float> uvs = {
383 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
384 };
385
386 std::vector<float> normals = {
387 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
388 };
389
390 glVertexPointer(3, GL_FLOAT, 0, positions.data());
391 glTexCoordPointer(2, GL_FLOAT, 0, uvs.data());
392 glNormalPointer(GL_FLOAT, 0, normals.data());
393
394 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
395
396 EXPECT_GL_NO_ERROR();
397
398 EXPECT_PIXEL_COLOR_NEAR(11, 11, GLColor(29, 29, 29, 255), 1);
399 }
400
drawTestQuad()401 void LightsTest::drawTestQuad()
402 {
403 struct Vertex
404 {
405 GLfloat position[3];
406 GLfloat normal[3];
407 };
408
409 glClearColor(0.4f, 0.4f, 0.4f, 1.0f);
410 glClear(GL_COLOR_BUFFER_BIT);
411
412 glMatrixMode(GL_PROJECTION);
413 glLoadIdentity();
414 glFrustumf(-1, 1, -1, 1, 5.0, 60.0);
415
416 glMatrixMode(GL_MODELVIEW);
417 glLoadIdentity();
418 glTranslatef(0.0f, 0.0f, -8.0f);
419 glRotatef(150, 0, 1, 0);
420
421 glEnableClientState(GL_VERTEX_ARRAY);
422 glEnableClientState(GL_NORMAL_ARRAY);
423
424 {
425 GLfloat ambientAndDiffuse[4] = {1.0f, 0.0f, 0.0f, 1.0f};
426 GLfloat specular[4] = {0.0f, 0.0f, 10.0f, 1.0f};
427 GLfloat shininess = 2.0f;
428
429 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, ambientAndDiffuse);
430 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
431 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
432 }
433
434 std::vector<Vertex> vertices = {
435 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}},
436 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}},
437 {{1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}},
438 {{1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}},
439 };
440 glVertexPointer(3, GL_FLOAT, sizeof vertices[0], &vertices[0].position);
441 glNormalPointer(GL_FLOAT, sizeof vertices[0], &vertices[0].normal);
442
443 glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size());
444
445 EXPECT_GL_NO_ERROR();
446 }
447
448 // Check smooth lighting
TEST_P(LightsTest,SmoothLitMesh)449 TEST_P(LightsTest, SmoothLitMesh)
450 {
451 {
452 GLfloat position[4] = {0.0f, 0.0f, -20.0f, 1.0f};
453 GLfloat diffuse[4] = {0.7f, 0.7f, 0.7f, 1.0f};
454 GLfloat specular[4] = {0.1f, 0.1f, 1.0f, 1.0f};
455
456 glEnable(GL_LIGHTING);
457 glEnable(GL_LIGHT0);
458 glLightfv(GL_LIGHT0, GL_POSITION, position);
459 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
460 glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
461 }
462
463 drawTestQuad();
464 EXPECT_PIXEL_COLOR_NEAR(16, 16, GLColor(205, 0, 92, 255), 1);
465 }
466
467 // Check flat lighting
TEST_P(LightsTest,FlatLitMesh)468 TEST_P(LightsTest, FlatLitMesh)
469 {
470 {
471 GLfloat position[4] = {0.0f, 0.0f, -20.0f, 1.0f};
472 GLfloat diffuse[4] = {0.7f, 0.7f, 0.7f, 1.0f};
473 GLfloat specular[4] = {0.1f, 0.1f, 1.0f, 1.0f};
474
475 glEnable(GL_LIGHTING);
476 glShadeModel(GL_FLAT);
477 glEnable(GL_LIGHT0);
478 glLightfv(GL_LIGHT0, GL_POSITION, position);
479 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
480 glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
481 }
482
483 drawTestQuad();
484 EXPECT_PIXEL_COLOR_NEAR(16, 16, GLColor(211, 0, 196, 255), 1);
485 }
486
487 ANGLE_INSTANTIATE_TEST_ES1(LightsTest);
488