| // |
| // Copyright 2018 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. |
| // |
| |
| // DrawTextureTest.cpp: Tests basic usage of glDrawTex*. |
| |
| #include "test_utils/ANGLETest.h" |
| #include "test_utils/gl_raii.h" |
| |
| #include <memory> |
| #include <vector> |
| |
| using namespace angle; |
| |
| class DrawTextureTest : public ANGLETest<> |
| { |
| protected: |
| DrawTextureTest() |
| { |
| setWindowWidth(kWindowWidth); |
| setWindowHeight(kWindowHeight); |
| setConfigRedBits(8); |
| setConfigGreenBits(8); |
| setConfigBlueBits(8); |
| setConfigAlphaBits(8); |
| setConfigDepthBits(24); |
| } |
| |
| void testSetUp() override |
| { |
| mTexture.reset(new GLTexture()); |
| glEnable(GL_TEXTURE_2D); |
| glBindTexture(GL_TEXTURE_2D, mTexture->get()); |
| } |
| |
| void testTearDown() override { mTexture.reset(); } |
| |
| std::unique_ptr<GLTexture> mTexture; |
| |
| static constexpr int kWindowWidth = 32; |
| static constexpr int kWindowHeight = 32; |
| }; |
| |
| // Negative test for invalid width/height values. |
| TEST_P(DrawTextureTest, NegativeValue) |
| { |
| glDrawTexiOES(0, 0, 0, 0, 0); |
| EXPECT_GL_ERROR(GL_INVALID_VALUE); |
| glDrawTexiOES(0, 0, 0, -1, 0); |
| EXPECT_GL_ERROR(GL_INVALID_VALUE); |
| glDrawTexiOES(0, 0, 0, 0, -1); |
| EXPECT_GL_ERROR(GL_INVALID_VALUE); |
| glDrawTexiOES(0, 0, 0, -1, -1); |
| EXPECT_GL_ERROR(GL_INVALID_VALUE); |
| } |
| |
| // Basic draw. |
| TEST_P(DrawTextureTest, Basic) |
| { |
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green); |
| glDrawTexiOES(0, 0, 0, 1, 1); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); |
| } |
| |
| // Tests that odd viewport dimensions are handled correctly. |
| // If the viewport dimension is even, then the incorrect way |
| // of getting the center screen coordinate by dividing by 2 and |
| // converting to integer will work in that case, but not if |
| // the viewport dimension is odd. |
| TEST_P(DrawTextureTest, CorrectNdcForOddViewportDimensions) |
| { |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| |
| // clang-format off |
| std::array<GLColor, 2> textureData = { |
| GLColor::green, GLColor::green |
| }; |
| // clang-format on |
| |
| glViewport(0, 0, 3, 3); |
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData.data()); |
| |
| GLint cropRect[] = {0, 0, 2, 1}; |
| glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| EXPECT_GL_NO_ERROR(); |
| |
| GLint x = 1; |
| GLint y = 1; |
| glDrawTexiOES(x, y, 0, 2, 1); |
| EXPECT_GL_NO_ERROR(); |
| |
| EXPECT_PIXEL_COLOR_EQ(x, y, GLColor::green); |
| EXPECT_PIXEL_COLOR_EQ(x + 1, y, GLColor::green); |
| |
| EXPECT_PIXEL_COLOR_EQ(x, y + 1, GLColor::black); |
| EXPECT_PIXEL_COLOR_EQ(x + 1, y + 1, GLColor::black); |
| EXPECT_PIXEL_COLOR_EQ(x + 2, y, GLColor::black); |
| EXPECT_PIXEL_COLOR_EQ(x + 3, y, GLColor::black); |
| } |
| |
| // Tests that vertex attributes enabled with fewer than 6 verts do not cause a crash. |
| TEST_P(DrawTextureTest, VertexAttributesNoCrash) |
| { |
| glEnableClientState(GL_COLOR_ARRAY); |
| glColorPointer(4, GL_FLOAT, 0, &GLColor::white); |
| |
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green); |
| EXPECT_GL_NO_ERROR(); |
| |
| glDrawTexiOES(0, 0, 0, 1, 1); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); |
| } |
| |
| // Tests that the color array, if enabled, is not used as the vertex color. |
| TEST_P(DrawTextureTest, ColorArrayNotUsed) |
| { |
| glEnableClientState(GL_COLOR_ARRAY); |
| |
| // This color is set to black on purpose to ensure that the color in the upcoming vertex array |
| // is not used in the texture draw. If it is used, then the texture we want to read will be |
| // modulated with the color in the vertex array instead of GL_CURRENT_COLOR (which at the moment |
| // is white (1.0, 1.0, 1.0, 1.0). |
| glColorPointer(4, GL_FLOAT, 0, &GLColor::black); |
| |
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green); |
| EXPECT_GL_NO_ERROR(); |
| |
| glDrawTexiOES(0, 0, 0, 1, 1); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); |
| } |
| |
| // Tests that values of differenty types are properly normalized with glColorPointer |
| TEST_P(DrawTextureTest, ColorArrayDifferentTypes) |
| { |
| constexpr GLubyte kTextureColorData[] = {0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, |
| 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF}; |
| constexpr GLfloat kVertexPtrData[] = {-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f}; |
| constexpr GLfloat kTexCoordPtrData[] = {0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f}; |
| constexpr GLubyte kGLubyteData[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; |
| constexpr GLfloat kGLfloatData[] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, |
| 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; |
| constexpr GLfixed kGLfixedData[] = {0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, |
| 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, |
| 0x10000, 0x10000, 0x10000, 0x10000}; |
| |
| // We check a pixel coordinate at the border of where linear interpolation starts as |
| // we fail to get correct interpolated values when we do not normalize the GLbyte values. |
| constexpr GLint kCheckedPixelX = 16; |
| constexpr GLint kCheckedPixelY = 8; |
| constexpr unsigned int kPixelTolerance = 10u; |
| |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| glEnableClientState(GL_VERTEX_ARRAY); |
| glEnableClientState(GL_COLOR_ARRAY); |
| glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, kTextureColorData); |
| glVertexPointer(2, GL_FLOAT, 0, kVertexPtrData); |
| glTexCoordPointer(2, GL_FLOAT, 0, kTexCoordPtrData); |
| |
| // Ensure the results do not change unexpectedly regardless of the color data format |
| |
| // Test GLubyte |
| glColorPointer(4, GL_UNSIGNED_BYTE, 0, kGLubyteData); |
| glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_COLOR_NEAR(kCheckedPixelX, kCheckedPixelY, GLColor::red, kPixelTolerance); |
| |
| // Test GLfloat |
| glColorPointer(4, GL_FLOAT, 0, kGLfloatData); |
| glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_COLOR_NEAR(kCheckedPixelX, kCheckedPixelY, GLColor::red, kPixelTolerance); |
| |
| // Test GLfixed |
| glColorPointer(4, GL_FIXED, 0, kGLfixedData); |
| glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_COLOR_NEAR(kCheckedPixelX, kCheckedPixelY, GLColor::red, kPixelTolerance); |
| } |
| |
| // Tests that drawing a primitive works with enabled tex coord pointer, but with texture disabled. |
| TEST_P(DrawTextureTest, DrawWithTexCoordPtrDataAndDisabledTexture2D) |
| { |
| std::vector<GLfloat> vertexPtrData = {-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f}; |
| std::vector<GLfloat> texCoordPtrData = {0.0f}; |
| |
| glEnableClientState(GL_VERTEX_ARRAY); |
| glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| |
| // Draw a triangle fan that covers the entire window. GL_TEXTURE_2D is disabled even though |
| // texture coord pointer is set. |
| glVertexPointer(2, GL_FLOAT, 0, vertexPtrData.data()); |
| glTexCoordPointer(2, GL_FLOAT, 0, texCoordPtrData.data()); |
| glDisable(GL_TEXTURE_2D); |
| glColor4ub(0, 0xFF, 0xFF, 0xFF); |
| glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_RECT_EQ(0, 0, kWindowWidth, kWindowHeight, GLColor::cyan); |
| } |
| |
| // Tests that drawing a primitive works with enabled tex coord pointer and texture environment set |
| // so the used texture replaces the current color. |
| TEST_P(DrawTextureTest, DrawWithTexCoordPtrDataAndEnvModeReplace) |
| { |
| std::vector<GLfloat> vertexPtrData = {-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f}; |
| std::vector<GLfloat> texCoordPtrData = {0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f}; |
| |
| glEnableClientState(GL_VERTEX_ARRAY); |
| glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| |
| // Set up the texture. By default, the texture is multiplied by the current color set through |
| // glColor calls. Here the environment is set so it would replace the color instead. |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red); |
| glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); |
| |
| // Draw a triangle fan that covers the entire window. The texture should replace the color |
| // regardless of the value of the current color. |
| glVertexPointer(2, GL_FLOAT, 0, vertexPtrData.data()); |
| glTexCoordPointer(2, GL_FLOAT, 0, texCoordPtrData.data()); |
| glColor4f(0.0f, 0.0f, 0.0f, 1.0f); |
| glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_RECT_EQ(0, 0, kWindowWidth, kWindowHeight, GLColor::red); |
| } |
| |
| // Tests that tex coord pointer is only used when texture is enabled, and that it is possible to |
| // disable the texture and draw another primitive by setting a color without using the texture data. |
| TEST_P(DrawTextureTest, DrawWithTexCoordPtrThenDisableTexture2DAndDrawAnother) |
| { |
| // There will be two vertex arrays for triangle fan draws. Both cover the entire screen, but the |
| // one with no texture uses more vertices. |
| std::vector<GLfloat> vertexPtrDataWithTexture = {-1.0f, -1.0f, -1.0f, 1.0f, |
| 1.0f, 1.0f, 1.0f, -1.0f}; |
| std::vector<GLfloat> vertexPtrDataNoTexture = {-1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, |
| 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f}; |
| std::vector<GLfloat> texCoordPtrData = {0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f}; |
| |
| // Enable vertex and texture coordinate pointers. Also set up texture data with four colors; one |
| // color per corner. |
| glEnableClientState(GL_VERTEX_ARRAY); |
| glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
| |
| constexpr GLColor kColorCornerBL = GLColor(0x11, 0x22, 0x33, 0xFF); |
| constexpr GLColor kColorCornerBR = GLColor(0x44, 0x55, 0x66, 0xFF); |
| constexpr GLColor kColorCornerTL = GLColor(0x77, 0x88, 0x99, 0xFF); |
| constexpr GLColor kColorCornerTR = GLColor(0xAA, 0xBB, 0xCC, 0xFF); |
| |
| std::vector<GLColor> textureData; |
| textureData.push_back(kColorCornerBL); |
| textureData.push_back(kColorCornerBR); |
| textureData.push_back(kColorCornerTL); |
| textureData.push_back(kColorCornerTR); |
| |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData.data()); |
| |
| // Draw the first triangle fan using texture coord pointer. |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| glEnable(GL_TEXTURE_2D); |
| |
| glVertexPointer(2, GL_FLOAT, 0, vertexPtrDataWithTexture.data()); |
| glTexCoordPointer(2, GL_FLOAT, 0, texCoordPtrData.data()); |
| glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_RECT_EQ(0, 0, kWindowWidth / 2, kWindowHeight / 2, kColorCornerBL); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, 0, kWindowWidth / 2, kWindowHeight / 2, kColorCornerBR); |
| EXPECT_PIXEL_RECT_EQ(0, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, kColorCornerTL); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, |
| kColorCornerTR); |
| |
| // Disable texture and draw the second triangle fan. This time, the draw uses more vertex |
| // coordinates and a preset color. Note that the texture coord pointer must no longer be used. |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| glDisable(GL_TEXTURE_2D); |
| |
| glVertexPointer(2, GL_FLOAT, 0, vertexPtrDataNoTexture.data()); |
| glColor4ub(0, 0, 0xFF, 0xFF); |
| glDrawArrays(GL_TRIANGLE_FAN, 0, 6); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_RECT_EQ(0, 0, kWindowWidth, kWindowHeight, GLColor::blue); |
| |
| // Re-enable texture and draw using the same vertex pointer. This is to make sure that enabling |
| // GL_TEXTURE_2D is enough to use the texture data. |
| // There is no need to set the texture coord pointer again. However, since GL_TEXTURE_ENV_MODE |
| // is set to the default GL_MODULATE, the effect of glColor4ub() from before should be reversed |
| // by resetting the color to the default (1, 1, 1, 1). |
| // In addition, since the tex coord pointer is not defined for the current vertex pointer, the |
| // texture colors will shift position to be mapped to the new primitive, which will only cover |
| // the top-left half of the window. |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| glEnable(GL_TEXTURE_2D); |
| |
| glColor4f(1.0f, 1.0f, 1.0f, 1.0f); |
| glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_COLOR_EQ(0, kWindowHeight / 4, kColorCornerBL); |
| EXPECT_PIXEL_COLOR_EQ(kWindowWidth * 3 / 4, kWindowHeight - 1, kColorCornerBR); |
| EXPECT_PIXEL_COLOR_EQ(0, kWindowHeight * 3 / 4, kColorCornerTL); |
| EXPECT_PIXEL_COLOR_EQ(kWindowWidth / 2, kWindowHeight - 1, kColorCornerTR); |
| |
| // Update the vertex pointer to the original and draw a final triangle fan. |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| |
| glVertexPointer(2, GL_FLOAT, 0, vertexPtrDataWithTexture.data()); |
| glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_RECT_EQ(0, 0, kWindowWidth / 2, kWindowHeight / 2, kColorCornerBL); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, 0, kWindowWidth / 2, kWindowHeight / 2, kColorCornerBR); |
| EXPECT_PIXEL_RECT_EQ(0, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, kColorCornerTL); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, |
| kColorCornerTR); |
| } |
| |
| // Tests that vertex and tex coord pointers are used correctly. |
| // Draw same non-zero texture twice with same vertex and tex coord pointers, but do not disable |
| // texture. |
| TEST_P(DrawTextureTest, DrawNonZeroSameTexWithSameVertexPtrWithoutDisabledTexture2D) |
| { |
| // Set up texture with four colors; one color per corner to verify if the texture will be |
| // uploaded with appropriate vertex attributes. |
| std::vector<GLColor> textureColors = {GLColor::red, GLColor::yellow, GLColor::green, |
| GLColor::blue}; |
| GLTexture tex2D; |
| glBindTexture(GL_TEXTURE_2D, tex2D); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, |
| textureColors.data()); |
| |
| // Set up vertex and texture coordinate pointers. |
| std::vector<GLfloat> vertexPtrData = {-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f}; |
| std::vector<GLfloat> texCoordPtrData = {0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f}; |
| glVertexPointer(2, GL_FLOAT, 0, vertexPtrData.data()); |
| glTexCoordPointer(2, GL_FLOAT, 0, texCoordPtrData.data()); |
| |
| glEnable(GL_TEXTURE_2D); |
| glEnableClientState(GL_VERTEX_ARRAY); |
| glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
| |
| // Bind tex2D and draw. |
| // ----------------------- |
| // | Green | Blue | |
| // | Red | Yellow | |
| // ----------------------- |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| glBindTexture(GL_TEXTURE_2D, tex2D); |
| glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_RECT_EQ(0, 0, kWindowWidth / 2, kWindowHeight / 2, GLColor::red); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, 0, kWindowWidth / 2, kWindowHeight / 2, GLColor::yellow); |
| EXPECT_PIXEL_RECT_EQ(0, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, GLColor::green); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, |
| GLColor::blue); |
| |
| // Bind tex2D and draw again. Expect the vertex attributes remain. |
| // ----------------------- |
| // | Green | Blue | |
| // | Red | Yellow | |
| // ----------------------- |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| glBindTexture(GL_TEXTURE_2D, tex2D); |
| glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_RECT_EQ(0, 0, kWindowWidth / 2, kWindowHeight / 2, GLColor::red); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, 0, kWindowWidth / 2, kWindowHeight / 2, GLColor::yellow); |
| EXPECT_PIXEL_RECT_EQ(0, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, GLColor::green); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, |
| GLColor::blue); |
| } |
| |
| // Tests that vertex and tex coord pointers are used correctly. |
| // Draw same non-zero texture twice with different vertex pointer, but do not disable texture. |
| TEST_P(DrawTextureTest, DrawNonZeroSameTexWithDifferentVertexPtrWithoutDisabledTexture2D) |
| { |
| // Set up texture with four colors; one color per corner to verify if the texture will be |
| // uploaded with appropriate vertex attributes. |
| std::vector<GLColor> textureColors = {GLColor::red, GLColor::yellow, GLColor::green, |
| GLColor::blue}; |
| GLTexture tex2D; |
| glBindTexture(GL_TEXTURE_2D, tex2D); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, |
| textureColors.data()); |
| |
| // Set up vertex and texture coordinate pointers. |
| std::vector<GLfloat> vertexPtrData_1 = {-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f}; |
| std::vector<GLfloat> texCoordPtrData = {0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f}; |
| glVertexPointer(2, GL_FLOAT, 0, vertexPtrData_1.data()); |
| glTexCoordPointer(2, GL_FLOAT, 0, texCoordPtrData.data()); |
| |
| glEnable(GL_TEXTURE_2D); |
| glEnableClientState(GL_VERTEX_ARRAY); |
| glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
| |
| // Bind tex2D and draw. |
| // ----------------------- |
| // | Green | Blue | |
| // | Red | Yellow | |
| // ----------------------- |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| glBindTexture(GL_TEXTURE_2D, tex2D); |
| glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_RECT_EQ(0, 0, kWindowWidth / 2, kWindowHeight / 2, GLColor::red); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, 0, kWindowWidth / 2, kWindowHeight / 2, GLColor::yellow); |
| EXPECT_PIXEL_RECT_EQ(0, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, GLColor::green); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, |
| GLColor::blue); |
| |
| // Change vertex data. |
| std::vector<GLfloat> vertexPtrData_2 = {-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f}; |
| glVertexPointer(2, GL_FLOAT, 0, vertexPtrData_2.data()); |
| |
| // Bind tex2D and draw. |
| // ----------------------- |
| // | Yellow | Blue | |
| // | Red | Green | |
| // ----------------------- |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| glBindTexture(GL_TEXTURE_2D, tex2D); |
| glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_RECT_EQ(0, 0, kWindowWidth / 2, kWindowHeight / 2, GLColor::red); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, 0, kWindowWidth / 2, kWindowHeight / 2, GLColor::green); |
| EXPECT_PIXEL_RECT_EQ(0, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, |
| GLColor::yellow); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, |
| GLColor::blue); |
| } |
| |
| // Test that vertex and tex coord pointers are used correctly. |
| // Draw two different non-zero textures with different vertex pointer, but do not disable texture. |
| TEST_P(DrawTextureTest, DrawNonZeroTwoTexWithDifferentVertexPtrWithoutDisableTexture2D) |
| { |
| // Set up texture with four colors; one color per corner to verify if the texture will be |
| // uploaded with appropriate vertex attributes. |
| std::vector<GLColor> textureColors_1 = {GLColor::red, GLColor::yellow, GLColor::green, |
| GLColor::blue}; |
| GLTexture tex2D_1; |
| glBindTexture(GL_TEXTURE_2D, tex2D_1); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, |
| textureColors_1.data()); |
| |
| // Set up vertex and texture coordinate pointers. |
| std::vector<GLfloat> vertexPtrData_1 = {-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f}; |
| std::vector<GLfloat> texCoordPtrData = {0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f}; |
| glVertexPointer(2, GL_FLOAT, 0, vertexPtrData_1.data()); |
| glTexCoordPointer(2, GL_FLOAT, 0, texCoordPtrData.data()); |
| |
| glEnable(GL_TEXTURE_2D); |
| glEnableClientState(GL_VERTEX_ARRAY); |
| glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
| |
| // Bind tex2D and draw. |
| // ----------------------- |
| // | Green | Blue | |
| // | Red | Yellow | |
| // ----------------------- |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_RECT_EQ(0, 0, kWindowWidth / 2, kWindowHeight / 2, GLColor::red); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, 0, kWindowWidth / 2, kWindowHeight / 2, GLColor::yellow); |
| EXPECT_PIXEL_RECT_EQ(0, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, GLColor::green); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, |
| GLColor::blue); |
| |
| // Change texture to bind. |
| std::vector<GLColor> textureColors_2 = {GLColor::magenta, GLColor::transparentBlack, |
| GLColor::white, GLColor::cyan}; |
| GLTexture tex2D_2; |
| glBindTexture(GL_TEXTURE_2D, tex2D_2); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, |
| textureColors_2.data()); |
| |
| // Change vertex data. |
| std::vector<GLfloat> vertexPtrData_2 = {-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f}; |
| glVertexPointer(2, GL_FLOAT, 0, vertexPtrData_2.data()); |
| |
| // Bind tex2D and draw. |
| // ----------------------------------- |
| // | TransparentBlack | Cyan | |
| // | Magenta | White | |
| // ----------------------------------- |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_RECT_EQ(0, 0, kWindowWidth / 2, kWindowHeight / 2, GLColor::magenta); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, 0, kWindowWidth / 2, kWindowHeight / 2, GLColor::white); |
| EXPECT_PIXEL_RECT_EQ(0, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, |
| GLColor::transparentBlack); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, |
| GLColor::cyan); |
| } |
| |
| // Tests that vertex and tex coord pointers are used correctly. |
| // Draw zero texture first then draw tex2D with same vertex and tex coord pointers, but do not |
| // disable texture. |
| TEST_P(DrawTextureTest, DrawZeroTexWithSameVertexPtrWithoutDisableTexture2D) |
| { |
| // Set up texture with four colors; one color per corner to verify if the texture will be |
| // uploaded with appropriate vertex attributes. |
| std::vector<GLColor> textureColors = {GLColor::red, GLColor::yellow, GLColor::green, |
| GLColor::blue}; |
| GLTexture tex2D; |
| glBindTexture(GL_TEXTURE_2D, tex2D); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, |
| textureColors.data()); |
| |
| // Set up vertex and texture coordinate pointers. |
| std::vector<GLfloat> vertexPtrData = {-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f}; |
| std::vector<GLfloat> texCoordPtrData = {0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f}; |
| glVertexPointer(2, GL_FLOAT, 0, vertexPtrData.data()); |
| glTexCoordPointer(2, GL_FLOAT, 0, texCoordPtrData.data()); |
| |
| glEnable(GL_TEXTURE_2D); |
| glEnableClientState(GL_VERTEX_ARRAY); |
| glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
| |
| // Bind zero texture and draw. |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| glBindTexture(GL_TEXTURE_2D, 0); |
| glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| EXPECT_GL_NO_ERROR(); |
| |
| // Bind tex2D and draw. Expect the vertex attributes remain. |
| // ----------------------- |
| // | Green | Blue | |
| // | Red | Yellow | |
| // ----------------------- |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| glBindTexture(GL_TEXTURE_2D, tex2D); |
| glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_RECT_EQ(0, 0, kWindowWidth / 2, kWindowHeight / 2, GLColor::red); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, 0, kWindowWidth / 2, kWindowHeight / 2, GLColor::yellow); |
| EXPECT_PIXEL_RECT_EQ(0, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, GLColor::green); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, |
| GLColor::blue); |
| } |
| |
| // Tests that vertex and tex coord pointers are used correctly. |
| // Draw zero texture first then draw tex2D with different vertex pointers, but do not disable |
| // texture. |
| TEST_P(DrawTextureTest, DrawZeroTexWithDifferentVertexPtrWithoutDisableTexture2D) |
| { |
| // Set up texture with four colors; one color per corner to verify if the texture will be |
| // uploaded with appropriate vertex attributes. |
| std::vector<GLColor> textureColors = {GLColor::red, GLColor::yellow, GLColor::green, |
| GLColor::blue}; |
| GLTexture tex2D; |
| glBindTexture(GL_TEXTURE_2D, tex2D); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, |
| textureColors.data()); |
| |
| // Set up vertex and texture coordinate pointers. |
| std::vector<GLfloat> vertexPtrData_1 = {-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f}; |
| std::vector<GLfloat> texCoordPtrData = {0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f}; |
| glVertexPointer(2, GL_FLOAT, 0, vertexPtrData_1.data()); |
| glTexCoordPointer(2, GL_FLOAT, 0, texCoordPtrData.data()); |
| |
| glEnable(GL_TEXTURE_2D); |
| glEnableClientState(GL_VERTEX_ARRAY); |
| glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
| |
| // Bind zero texture and draw. |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| glBindTexture(GL_TEXTURE_2D, 0); |
| glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| EXPECT_GL_NO_ERROR(); |
| |
| // Change vertex data. |
| std::vector<GLfloat> vertexPtrData_2 = {-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f}; |
| glVertexPointer(2, GL_FLOAT, 0, vertexPtrData_2.data()); |
| |
| // Bind tex2D and draw. |
| // ----------------------- |
| // | Yellow | Blue | |
| // | Red | Green | |
| // ----------------------- |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| glBindTexture(GL_TEXTURE_2D, tex2D); |
| glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| EXPECT_GL_NO_ERROR(); |
| EXPECT_PIXEL_RECT_EQ(0, 0, kWindowWidth / 2, kWindowHeight / 2, GLColor::red); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, 0, kWindowWidth / 2, kWindowHeight / 2, GLColor::green); |
| EXPECT_PIXEL_RECT_EQ(0, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, |
| GLColor::yellow); |
| EXPECT_PIXEL_RECT_EQ(kWindowWidth / 2, kWindowHeight / 2, kWindowWidth / 2, kWindowHeight / 2, |
| GLColor::blue); |
| } |
| |
| ANGLE_INSTANTIATE_TEST_ES1(DrawTextureTest); |