blob: 530765351157ad1a97a9938ba4a270b2154c805a [file] [edit]
//
// Copyright 2026 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// OESTextureCubeMapTest:
// Tests for GL_OES_texture_cube_map in OpenGL ES 1.1.
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
using namespace angle;
class OESTextureCubeMapTest : public ANGLETest<>
{
protected:
OESTextureCubeMapTest()
{
setWindowWidth(128);
setWindowHeight(128);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
}
void setupCommonTestState()
{
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_CUBE_MAP_OES);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, mQuadPositions.data());
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}
void teardownCommonTestState()
{
glDisable(GL_TEXTURE_CUBE_MAP_OES);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
std::array<float, 12> mQuadPositions = {
-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
};
};
// Test pure GL_TEXTURE_CUBE_MAP_OES base level sampling on different texture units.
TEST_P(OESTextureCubeMapTest, CubeMapTextureUnitsRender)
{
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_cube_map"));
GLint maxTexUnits = 1;
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxTexUnits);
// Cap at 3 units because unit 3 is not supported for cubemaps by the current GLES1
// ubershader implementation.
maxTexUnits = std::min(maxTexUnits, 3);
for (GLint unit = 0; unit < maxTexUnits; ++unit)
{
glActiveTexture(GL_TEXTURE0 + unit);
glClientActiveTexture(GL_TEXTURE0 + unit);
setupCommonTestState();
GLTexture texture;
glBindTexture(GL_TEXTURE_CUBE_MAP_OES, texture);
// Define 6 distinct colors for the 6 faces
std::vector<GLColor> colors = {
GLColor::red, // +X
GLColor::green, // -X
GLColor::blue, // +Y
GLColor::yellow, // -Y
GLColor::cyan, // +Z
GLColor::magenta, // -Z
};
for (int i = 0; i < 6; ++i)
{
GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES + i;
std::vector<GLColor> faceData(4 * 4, colors[i]);
glTexImage2D(face, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, faceData.data());
}
glTexParameteri(GL_TEXTURE_CUBE_MAP_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
EXPECT_GL_NO_ERROR();
glViewport(0, 0, 4, 4);
std::vector<std::array<float, 3>> faceDirections = {
{1.0f, 0.0f, 0.0f}, // +X
{-1.0f, 0.0f, 0.0f}, // -X
{0.0f, 1.0f, 0.0f}, // +Y
{0.0f, -1.0f, 0.0f}, // -Y
{0.0f, 0.0f, 1.0f}, // +Z
{0.0f, 0.0f, -1.0f}, // -Z
};
for (size_t i = 0; i < 6; ++i)
{
std::array<float, 12> texCoords;
for (int v = 0; v < 4; ++v)
{
texCoords[v * 3 + 0] = faceDirections[i][0];
texCoords[v * 3 + 1] = faceDirections[i][1];
texCoords[v * 3 + 2] = faceDirections[i][2];
}
glTexCoordPointer(3, GL_FLOAT, 0, texCoords.data());
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
GLColor actualColor = ReadColor(0, 0);
EXPECT_EQ(colors[i], actualColor) << "Mismatch on unit " << unit << " face " << i;
}
teardownCommonTestState();
}
glActiveTexture(GL_TEXTURE0);
glClientActiveTexture(GL_TEXTURE0);
}
// Test GL_TEXTURE_CUBE_MAP_OES mipmap sampling.
TEST_P(OESTextureCubeMapTest, CubeMapMipmapRender)
{
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_cube_map"));
setupCommonTestState();
GLTexture texture;
glBindTexture(GL_TEXTURE_CUBE_MAP_OES, texture);
// Level 0: 16x16, Red
// Level 1: 8x8, Green
// Level 2: 4x4, Blue
// Level 3: 2x2, Yellow
// Level 4: 1x1, Cyan
std::vector<GLColor> level0Data(16 * 16, GLColor::red);
std::vector<GLColor> level1Data(8 * 8, GLColor::green);
std::vector<GLColor> level2Data(4 * 4, GLColor::blue);
std::vector<GLColor> level3Data(2 * 2, GLColor::yellow);
std::vector<GLColor> level4Data(1 * 1, GLColor::cyan);
for (int i = 0; i < 6; ++i)
{
GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES + i;
glTexImage2D(face, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, level0Data.data());
glTexImage2D(face, 1, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, level1Data.data());
glTexImage2D(face, 2, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, level2Data.data());
glTexImage2D(face, 3, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, level3Data.data());
glTexImage2D(face, 4, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, level4Data.data());
}
glTexParameteri(GL_TEXTURE_CUBE_MAP_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
EXPECT_GL_NO_ERROR();
// Use +X face for testing
std::vector<std::array<float, 3>> faceCoords = {
{1.0f, -1.0f, -1.0f}, // Bottom Left
{1.0f, 1.0f, -1.0f}, // Bottom Right
{1.0f, -1.0f, 1.0f}, // Top Left
{1.0f, 1.0f, 1.0f}, // Top Right
};
std::array<float, 12> texCoords;
for (int v = 0; v < 4; ++v)
{
texCoords[v * 3 + 0] = faceCoords[v][0];
texCoords[v * 3 + 1] = faceCoords[v][1];
texCoords[v * 3 + 2] = faceCoords[v][2];
}
glTexCoordPointer(3, GL_FLOAT, 0, texCoords.data());
// Test Level 0 (16x16 viewport)
glViewport(0, 0, 16, 16);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
GLColor colorLevel0 = ReadColor(8, 8);
EXPECT_EQ(GLColor::red, colorLevel0) << "Expected Red from Level 0";
// Test Level 1 (8x8 viewport)
glViewport(0, 0, 8, 8);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
GLColor colorLevel1 = ReadColor(4, 4);
EXPECT_EQ(GLColor::green, colorLevel1) << "Expected Green from Level 1";
// Test Level 2 (4x4 viewport)
glViewport(0, 0, 4, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
GLColor colorLevel2 = ReadColor(2, 2);
EXPECT_EQ(GLColor::blue, colorLevel2) << "Expected Blue from Level 2";
teardownCommonTestState();
}
ANGLE_INSTANTIATE_TEST_ES1(OESTextureCubeMapTest);