xref: /aosp_15_r20/external/angle/src/tests/gl_tests/gles1/FogTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 // FogTest.cpp: Tests basic usage of glFog.
8 
9 #include "test_utils/ANGLETest.h"
10 #include "test_utils/gl_raii.h"
11 
12 #include "util/random_utils.h"
13 
14 #include <stdint.h>
15 
16 using namespace angle;
17 
18 class FogTest : public ANGLETest<>
19 {
20   protected:
FogTest()21     FogTest()
22     {
23         setWindowWidth(32);
24         setWindowHeight(32);
25         setConfigRedBits(8);
26         setConfigGreenBits(8);
27         setConfigBlueBits(8);
28         setConfigAlphaBits(8);
29         setConfigDepthBits(24);
30     }
31 };
32 
33 // Initial state check.
TEST_P(FogTest,InitialState)34 TEST_P(FogTest, InitialState)
35 {
36     EXPECT_GL_FALSE(glIsEnabled(GL_FOG));
37     EXPECT_GL_NO_ERROR();
38 
39     GLint fogMode;
40     glGetIntegerv(GL_FOG_MODE, &fogMode);
41     EXPECT_GL_NO_ERROR();
42     EXPECT_GLENUM_EQ(GL_EXP, fogMode);
43 
44     GLfloat fogModeAsFloat;
45     glGetFloatv(GL_FOG_MODE, &fogModeAsFloat);
46     EXPECT_GL_NO_ERROR();
47     EXPECT_GLENUM_EQ(GL_EXP, fogModeAsFloat);
48 
49     GLfloat fogStart;
50     GLfloat fogEnd;
51     GLfloat fogDensity;
52 
53     glGetFloatv(GL_FOG_START, &fogStart);
54     EXPECT_GL_NO_ERROR();
55     glGetFloatv(GL_FOG_END, &fogEnd);
56     EXPECT_GL_NO_ERROR();
57     glGetFloatv(GL_FOG_DENSITY, &fogDensity);
58     EXPECT_GL_NO_ERROR();
59 
60     EXPECT_EQ(0.0f, fogStart);
61     EXPECT_EQ(1.0f, fogEnd);
62     EXPECT_EQ(1.0f, fogDensity);
63 
64     const GLColor32F kInitialFogColor(0.0f, 0.0f, 0.0f, 0.0f);
65     GLColor32F initialFogColor;
66     glGetFloatv(GL_FOG_COLOR, &initialFogColor.R);
67     EXPECT_GL_NO_ERROR();
68 
69     EXPECT_EQ(kInitialFogColor, initialFogColor);
70 }
71 
72 // Negative test for parameter names.
TEST_P(FogTest,NegativeParameter)73 TEST_P(FogTest, NegativeParameter)
74 {
75     glFogfv(0, nullptr);
76     EXPECT_GL_ERROR(GL_INVALID_ENUM);
77 }
78 
79 // Negative test for parameter values.
TEST_P(FogTest,NegativeValues)80 TEST_P(FogTest, NegativeValues)
81 {
82     glFogf(GL_FOG_MODE, 0.0f);
83     EXPECT_GL_ERROR(GL_INVALID_VALUE);
84 
85     glFogf(GL_FOG_DENSITY, -1.0f);
86     EXPECT_GL_ERROR(GL_INVALID_VALUE);
87 }
88 
89 // Checks that fog state can be set.
TEST_P(FogTest,Set)90 TEST_P(FogTest, Set)
91 {
92     GLfloat fogValue[4] = {};
93 
94     glFogf(GL_FOG_MODE, GL_EXP2);
95     EXPECT_GL_NO_ERROR();
96 
97     glGetFloatv(GL_FOG_MODE, fogValue);
98     EXPECT_GL_NO_ERROR();
99     EXPECT_GLENUM_EQ(GL_EXP2, fogValue[0]);
100 
101     glFogf(GL_FOG_DENSITY, 2.0f);
102     EXPECT_GL_NO_ERROR();
103 
104     glGetFloatv(GL_FOG_DENSITY, fogValue);
105     EXPECT_GL_NO_ERROR();
106     EXPECT_GLENUM_EQ(2.0f, fogValue[0]);
107 
108     glFogf(GL_FOG_START, 2.0f);
109     EXPECT_GL_NO_ERROR();
110 
111     glGetFloatv(GL_FOG_START, fogValue);
112     EXPECT_GL_NO_ERROR();
113     EXPECT_GLENUM_EQ(2.0f, fogValue[0]);
114 
115     glFogf(GL_FOG_END, 2.0f);
116     EXPECT_GL_NO_ERROR();
117 
118     glGetFloatv(GL_FOG_END, fogValue);
119     EXPECT_GL_NO_ERROR();
120     EXPECT_GLENUM_EQ(2.0f, fogValue[0]);
121 
122     const GLColor32F testColor(0.1f, 0.2f, 0.3f, 0.4f);
123     glFogfv(GL_FOG_COLOR, &testColor.R);
124     EXPECT_GL_NO_ERROR();
125     glGetFloatv(GL_FOG_COLOR, fogValue);
126     EXPECT_GL_NO_ERROR();
127     EXPECT_EQ(0.1f, fogValue[0]);
128     EXPECT_EQ(0.2f, fogValue[1]);
129     EXPECT_EQ(0.3f, fogValue[2]);
130     EXPECT_EQ(0.4f, fogValue[3]);
131 }
132 
133 class FogBlendTest : public ANGLETest<>
134 {
135   protected:
FogBlendTest()136     FogBlendTest()
137     {
138         setWindowWidth(512);
139         setWindowHeight(512);
140         setConfigRedBits(8);
141         setConfigGreenBits(8);
142         setConfigBlueBits(8);
143         setConfigAlphaBits(8);
144         setConfigDepthBits(24);
145     }
146 };
147 
148 // Draws a circle with a shadow effect using fog and blending. As seen in Street Fighter IV.
TEST_P(FogBlendTest,ShadowEffect)149 TEST_P(FogBlendTest, ShadowEffect)
150 {
151     glEnableClientState(GL_VERTEX_ARRAY);
152     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
153 
154     glEnable(GL_TEXTURE_2D);
155     glEnable(GL_BLEND);
156     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
157 
158     int32_t w = getWindowWidth();
159     int32_t h = getWindowHeight();
160 
161     int32_t radius = h / 4;
162 
163     std::vector<GLColor> colors;
164     for (int32_t y = 0; y < h; y++)
165     {
166         for (int32_t x = 0; x < w; x++)
167         {
168             int32_t centerDistanceX = x - w / 2;
169             int32_t centerDistanceY = y - h / 2;
170 
171             float centerDistance =
172                 sqrt(centerDistanceX * centerDistanceX + centerDistanceY * centerDistanceY);
173 
174             if (centerDistance > static_cast<float>(radius))
175             {
176                 colors.push_back(GLColor::transparentBlack);
177             }
178             else
179             {
180                 colors.push_back(GLColor::green);
181             }
182         }
183     }
184 
185     GLTexture texture;
186     glBindTexture(GL_TEXTURE_2D, texture);
187     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
188     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
189     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
190     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
191     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
192 
193     glClearColor(GLColor::red.R, GLColor::red.G, GLColor::red.B, GLColor::red.A);
194     glClearDepthf(1);
195     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
196     glViewport(0, 0, w, h);
197     glMatrixMode(GL_PROJECTION);
198     glLoadIdentity();
199     glOrthof(0, w, h, 0, 0, 1);
200     glMatrixMode(GL_MODELVIEW);
201     glLoadIdentity();
202     glShadeModel(GL_FLAT);
203 
204     // TODO(http://anglebug.com/42266063): This currently renders incorrectly on ANGLE
205     // Draw shadow effect
206     glEnable(GL_FOG);
207     const GLfloat fogColor[4] = {0.0f, 0.0f, 0.0f, 1.0f};
208     glFogfv(GL_FOG_COLOR, fogColor);
209 
210     glFogf(GL_FOG_MODE, GL_LINEAR);
211     glFogf(GL_FOG_START, -1);
212     glFogf(GL_FOG_END, -0.1);
213 
214     GLfloat shadowOffset = 32.0f;
215     GLfloat wf           = static_cast<GLfloat>(w);
216     GLfloat hf           = static_cast<GLfloat>(h);
217 
218     const GLfloat shadowPositions[8] = {shadowOffset,      0, shadowOffset,      hf,
219                                         wf + shadowOffset, 0, wf + shadowOffset, hf};
220     glVertexPointer(2, GL_FLOAT, 0, shadowPositions);
221 
222     const GLfloat texcoords[8] = {0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0};
223     glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
224 
225     glColor4f(1, 1, 1, 0.6);
226 
227     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
228 
229     // Draws color circle
230     glDisable(GL_FOG);
231 
232     const GLfloat positions[8] = {
233         0, 0, 0, hf, wf, 0, wf, hf,
234     };
235     glVertexPointer(2, GL_FLOAT, 0, positions);
236 
237     glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
238 
239     glColor4f(1, 1, 1, 1);
240 
241     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
242 
243     // The circle should be green
244     EXPECT_PIXEL_COLOR_NEAR(w / 2, h / 2, GLColor::green, 0);
245 
246     // The background should be red
247     EXPECT_PIXEL_COLOR_NEAR(w / 8, h / 8, GLColor::red, 0);
248     EXPECT_PIXEL_COLOR_NEAR(w - w / 8, h / 8, GLColor::red, 0);
249     EXPECT_PIXEL_COLOR_NEAR(w / 8, h - h / 8, GLColor::red, 0);
250     EXPECT_PIXEL_COLOR_NEAR(w - w / 8, h - h / 8, GLColor::red, 0);
251 
252     // The shadow should be darkened red
253     float shadowCenterX = w / 2 + radius + shadowOffset / 2.0f;
254     EXPECT_PIXEL_COLOR_NEAR(shadowCenterX, h / 2, GLColor(102u, 0, 0, 194u), 0);
255 }
256 
257 ANGLE_INSTANTIATE_TEST_ES1(FogTest);
258 ANGLE_INSTANTIATE_TEST_ES1(FogBlendTest);
259