Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/gl_tests/CubeMapTextureTest.cpp
1693 views
1
//
2
// Copyright 2015 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
#include "test_utils/ANGLETest.h"
8
#include "test_utils/gl_raii.h"
9
10
using namespace angle;
11
12
class CubeMapTextureTest : public ANGLETest
13
{
14
protected:
15
CubeMapTextureTest()
16
{
17
setWindowWidth(256);
18
setWindowHeight(256);
19
setConfigRedBits(8);
20
setConfigGreenBits(8);
21
setConfigBlueBits(8);
22
setConfigAlphaBits(8);
23
}
24
25
void testSetUp() override
26
{
27
mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
28
if (mProgram == 0)
29
{
30
FAIL() << "shader compilation failed.";
31
}
32
33
mColorLocation = glGetUniformLocation(mProgram, essl1_shaders::ColorUniform());
34
35
glUseProgram(mProgram);
36
37
glClearColor(0, 0, 0, 0);
38
glClearDepthf(0.0);
39
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
40
41
glEnable(GL_BLEND);
42
glDisable(GL_DEPTH_TEST);
43
44
ASSERT_GL_NO_ERROR();
45
}
46
47
void testTearDown() override { glDeleteProgram(mProgram); }
48
49
void runSampleCoordinateTransformTest(const char *shader);
50
51
GLuint mProgram;
52
GLint mColorLocation;
53
};
54
55
// Verify that rendering to the faces of a cube map consecutively will correctly render to each
56
// face.
57
TEST_P(CubeMapTextureTest, RenderToFacesConsecutively)
58
{
59
// TODO: Diagnose and fix. http://anglebug.com/2954
60
ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsWindows());
61
62
// http://anglebug.com/3145
63
ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsFuchsia());
64
65
// TODO(hqle): Find what wrong with NVIDIA GPU. http://anglebug.com/4138
66
ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsMetal());
67
68
const GLfloat faceColors[] = {
69
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
70
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
71
};
72
73
GLuint tex = 0;
74
glGenTextures(1, &tex);
75
glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
76
for (GLenum face = 0; face < 6; face++)
77
{
78
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
79
GL_UNSIGNED_BYTE, nullptr);
80
}
81
EXPECT_GL_NO_ERROR();
82
83
GLuint fbo = 0;
84
glGenFramebuffers(1, &fbo);
85
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
86
EXPECT_GL_NO_ERROR();
87
88
for (GLenum face = 0; face < 6; face++)
89
{
90
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
91
GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, tex, 0);
92
EXPECT_GL_NO_ERROR();
93
94
glUseProgram(mProgram);
95
96
const GLfloat *faceColor = faceColors + (face * 4);
97
glUniform4f(mColorLocation, faceColor[0], faceColor[1], faceColor[2], faceColor[3]);
98
99
drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
100
EXPECT_GL_NO_ERROR();
101
}
102
103
for (GLenum face = 0; face < 6; face++)
104
{
105
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
106
GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, tex, 0);
107
EXPECT_GL_NO_ERROR();
108
109
const GLfloat *faceColor = faceColors + (face * 4);
110
EXPECT_PIXEL_EQ(0, 0, faceColor[0] * 255, faceColor[1] * 255, faceColor[2] * 255,
111
faceColor[3] * 255);
112
EXPECT_GL_NO_ERROR();
113
}
114
115
glDeleteFramebuffers(1, &fbo);
116
glDeleteTextures(1, &tex);
117
118
EXPECT_GL_NO_ERROR();
119
}
120
121
void CubeMapTextureTest::runSampleCoordinateTransformTest(const char *shader)
122
{
123
// Fails to compile the shader. anglebug.com/3776
124
ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsWindows());
125
126
constexpr GLsizei kCubeFaceCount = 6;
127
constexpr GLsizei kCubeFaceSectionCount = 4;
128
constexpr GLsizei kCubeFaceSectionCountSqrt = 2;
129
130
constexpr GLColor faceColors[kCubeFaceCount][kCubeFaceSectionCount] = {
131
{GLColor(255, 0, 0, 255), GLColor(191, 0, 0, 255), GLColor(127, 0, 0, 255),
132
GLColor(63, 0, 0, 255)},
133
{GLColor(0, 255, 0, 255), GLColor(0, 191, 0, 255), GLColor(0, 127, 0, 255),
134
GLColor(0, 63, 0, 255)},
135
{GLColor(0, 0, 255, 255), GLColor(0, 0, 191, 255), GLColor(0, 0, 127, 255),
136
GLColor(0, 0, 63, 255)},
137
{GLColor(255, 63, 0, 255), GLColor(191, 127, 0, 255), GLColor(127, 191, 0, 255),
138
GLColor(63, 255, 0, 255)},
139
{GLColor(0, 255, 63, 255), GLColor(0, 191, 127, 255), GLColor(0, 127, 191, 255),
140
GLColor(0, 63, 255, 255)},
141
{GLColor(63, 0, 255, 255), GLColor(127, 0, 191, 255), GLColor(191, 0, 127, 255),
142
GLColor(255, 0, 63, 255)},
143
};
144
145
constexpr GLsizei kTextureSize = 32;
146
147
GLTexture tex;
148
glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
149
for (GLenum face = 0; face < kCubeFaceCount; face++)
150
{
151
std::vector<GLColor> faceData(kTextureSize * kTextureSize);
152
153
// Create the face with four sections, each with a solid color from |faceColors|.
154
for (size_t row = 0; row < kTextureSize / kCubeFaceSectionCountSqrt; ++row)
155
{
156
for (size_t col = 0; col < kTextureSize / kCubeFaceSectionCountSqrt; ++col)
157
{
158
for (size_t srow = 0; srow < kCubeFaceSectionCountSqrt; ++srow)
159
{
160
for (size_t scol = 0; scol < kCubeFaceSectionCountSqrt; ++scol)
161
{
162
size_t r = row + srow * kTextureSize / kCubeFaceSectionCountSqrt;
163
size_t c = col + scol * kTextureSize / kCubeFaceSectionCountSqrt;
164
size_t s = srow * kCubeFaceSectionCountSqrt + scol;
165
faceData[r * kTextureSize + c] = faceColors[face][s];
166
}
167
}
168
}
169
}
170
171
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, kTextureSize, kTextureSize,
172
0, GL_RGBA, GL_UNSIGNED_BYTE, faceData.data());
173
}
174
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
175
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
176
EXPECT_GL_NO_ERROR();
177
178
GLTexture fboTex;
179
glBindTexture(GL_TEXTURE_2D, fboTex);
180
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kCubeFaceCount, kCubeFaceSectionCount, 0, GL_RGBA,
181
GL_UNSIGNED_BYTE, nullptr);
182
183
GLFramebuffer fbo;
184
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
185
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTex, 0);
186
EXPECT_GL_NO_ERROR();
187
188
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), shader);
189
glUseProgram(program);
190
191
GLint texCubeLocation = glGetUniformLocation(program, "texCube");
192
ASSERT_NE(-1, texCubeLocation);
193
glUniform1i(texCubeLocation, 0);
194
195
drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
196
EXPECT_GL_NO_ERROR();
197
198
for (GLenum face = 0; face < kCubeFaceCount; face++)
199
{
200
// The following table defines the translation from textureCube coordinates to coordinates
201
// in each face. The framebuffer has width 6 and height 4. Every column corresponding to
202
// an x value represents one cube face. The values in rows are samples from the four
203
// sections of the face.
204
//
205
// Major Axis Direction Target sc tc ma
206
// +rx TEXTURE_CUBE_MAP_POSITIVE_X −rz −ry rx
207
// −rx TEXTURE_CUBE_MAP_NEGATIVE_X rz −ry rx
208
// +ry TEXTURE_CUBE_MAP_POSITIVE_Y rx rz ry
209
// −ry TEXTURE_CUBE_MAP_NEGATIVE_Y rx −rz ry
210
// +rz TEXTURE_CUBE_MAP_POSITIVE_Z rx −ry rz
211
// −rz TEXTURE_CUBE_MAP_NEGATIVE_Z −rx −ry rz
212
//
213
// This table is used only to determine the direction of growth for s and t. The shader
214
// always generates (row,col) coordinates (0, 0), (0, 1), (1, 0), (1, 1) which is the order
215
// the data is uploaded to the faces, but based on the table above, the sample order would
216
// be different.
217
constexpr size_t faceSampledSections[kCubeFaceCount][kCubeFaceSectionCount] = {
218
{3, 2, 1, 0}, {2, 3, 0, 1}, {0, 1, 2, 3}, {2, 3, 0, 1}, {2, 3, 0, 1}, {3, 2, 1, 0},
219
};
220
221
for (size_t section = 0; section < kCubeFaceSectionCount; ++section)
222
{
223
const GLColor sectionColor = faceColors[face][faceSampledSections[face][section]];
224
225
EXPECT_PIXEL_COLOR_EQ(face, section, sectionColor)
226
<< "face " << face << ", section " << section;
227
}
228
}
229
EXPECT_GL_NO_ERROR();
230
}
231
232
// Verify that cube map sampling follows the rules that map cubemap coordinates to coordinates
233
// within each face. See section 3.7.5 of GLES2.0 (Cube Map Texture Selection).
234
TEST_P(CubeMapTextureTest, SampleCoordinateTransform)
235
{
236
// http://anglebug.com/4092
237
ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D9());
238
// Create a program that samples from 6x4 directions of the cubemap, draw and verify that the
239
// colors match the right color from |faceColors|.
240
constexpr char kFS[] = R"(precision mediump float;
241
242
uniform samplerCube texCube;
243
244
const mat4 coordInSection = mat4(
245
vec4(-0.5, -0.5, 0, 0),
246
vec4( 0.5, -0.5, 0, 0),
247
vec4(-0.5, 0.5, 0, 0),
248
vec4( 0.5, 0.5, 0, 0)
249
);
250
251
void main()
252
{
253
vec3 coord;
254
if (gl_FragCoord.x < 2.0)
255
{
256
coord.x = gl_FragCoord.x < 1.0 ? 1.0 : -1.0;
257
coord.zy = coordInSection[int(gl_FragCoord.y)].xy;
258
}
259
else if (gl_FragCoord.x < 4.0)
260
{
261
coord.y = gl_FragCoord.x < 3.0 ? 1.0 : -1.0;
262
coord.xz = coordInSection[int(gl_FragCoord.y)].xy;
263
}
264
else
265
{
266
coord.z = gl_FragCoord.x < 5.0 ? 1.0 : -1.0;
267
coord.xy = coordInSection[int(gl_FragCoord.y)].xy;
268
}
269
270
gl_FragColor = textureCube(texCube, coord);
271
})";
272
273
runSampleCoordinateTransformTest(kFS);
274
}
275
276
// On Android Vulkan, unequal x and y derivatives cause this test to fail.
277
TEST_P(CubeMapTextureTest, SampleCoordinateTransformGrad)
278
{
279
ANGLE_SKIP_TEST_IF(IsAndroid() && IsVulkan()); // anglebug.com/3814
280
ANGLE_SKIP_TEST_IF(IsD3D11()); // anglebug.com/3856
281
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_texture_lod"));
282
// http://anglebug.com/4092
283
ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D9());
284
285
constexpr char kFS[] = R"(#extension GL_EXT_shader_texture_lod : require
286
precision mediump float;
287
288
uniform samplerCube texCube;
289
290
const mat4 coordInSection = mat4(
291
vec4(-0.5, -0.5, 0, 0),
292
vec4( 0.5, -0.5, 0, 0),
293
vec4(-0.5, 0.5, 0, 0),
294
vec4( 0.5, 0.5, 0, 0)
295
);
296
297
void main()
298
{
299
vec3 coord;
300
if (gl_FragCoord.x < 2.0)
301
{
302
coord.x = gl_FragCoord.x < 1.0 ? 1.0 : -1.0;
303
coord.zy = coordInSection[int(gl_FragCoord.y)].xy;
304
}
305
else if (gl_FragCoord.x < 4.0)
306
{
307
coord.y = gl_FragCoord.x < 3.0 ? 1.0 : -1.0;
308
coord.xz = coordInSection[int(gl_FragCoord.y)].xy;
309
}
310
else
311
{
312
coord.z = gl_FragCoord.x < 5.0 ? 1.0 : -1.0;
313
coord.xy = coordInSection[int(gl_FragCoord.y)].xy;
314
}
315
316
gl_FragColor = textureCubeGradEXT(texCube, coord,
317
vec3(10.0, 10.0, 0.0), vec3(0.0, 10.0, 10.0));
318
})";
319
320
runSampleCoordinateTransformTest(kFS);
321
}
322
323
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
324
// tests should be run against.
325
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(CubeMapTextureTest);
326
327