1#include "ANGLETest.h"
2
3class LineLoopTest : public ANGLETest
4{
5protected:
6    LineLoopTest()
7    {
8        setWindowWidth(256);
9        setWindowHeight(256);
10        setConfigRedBits(8);
11        setConfigGreenBits(8);
12        setConfigBlueBits(8);
13        setConfigAlphaBits(8);
14    }
15
16    virtual void SetUp()
17    {
18        ANGLETest::SetUp();
19
20        const std::string vsSource = SHADER_SOURCE
21        (
22            attribute highp vec4 position;
23            attribute highp vec4 in_color;
24
25            varying highp vec4 color;
26
27            void main(void)
28            {
29                gl_Position = position;
30                color = in_color;
31            }
32        );
33
34        const std::string fsSource = SHADER_SOURCE
35        (
36            varying highp vec4 color;
37            void main(void)
38            {
39                gl_FragColor = color;
40            }
41        );
42
43        mProgram = CompileProgram(vsSource, fsSource);
44        if (mProgram == 0)
45        {
46            FAIL() << "shader compilation failed.";
47        }
48
49        mPositionLocation = glGetAttribLocation(mProgram, "position");
50        mColorLocation = glGetAttribLocation(mProgram, "in_color");
51
52        glBlendFunc(GL_ONE, GL_ONE);
53        glEnable(GL_BLEND);
54
55        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
56        glClear(GL_COLOR_BUFFER_BIT);
57
58        ASSERT_GL_NO_ERROR();
59    }
60
61    virtual void TearDown()
62    {
63        glDeleteProgram(mProgram);
64
65        ANGLETest::TearDown();
66    }
67
68    void runTest(GLenum indexType, GLubyte indexBuffer, const GLvoid *indexPtr)
69    {
70        static const GLfloat loopPositions[] =
71        {
72             0.0f,  0.0f,
73             0.0f,  0.0f,
74             0.0f,  0.0f,
75             0.0f,  0.0f,
76             0.0f,  0.0f,
77             0.0f,  0.0f,
78            -0.5f, -0.5f,
79            -0.5f,  0.5f,
80             0.5f,  0.5f,
81             0.5f, -0.5f
82        };
83
84        static const GLfloat stripPositions[] =
85        {
86            -0.5f, -0.5f,
87            -0.5f,  0.5f,
88             0.5f,  0.5f,
89             0.5f, -0.5f
90        };
91        static const GLubyte stripIndices[] =
92        {
93            2, 0, 3, 1, 2
94        };
95
96        glUseProgram(mProgram);
97        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
98        glEnableVertexAttribArray(mPositionLocation);
99        glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, loopPositions);
100        glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
101        glDrawElements(GL_LINE_LOOP, 4, indexType, indexPtr);
102
103        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
104        glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, stripPositions);
105        glUniform4f(mColorLocation, 0, 1, 0, 1);
106        glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_BYTE, stripIndices);
107
108        std::vector<GLubyte> pixels(getWindowWidth() * getWindowHeight() * 4);
109        glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
110
111        for (int y = 0; y < getWindowHeight(); y++)
112        {
113            for (int x = 0; x < getWindowWidth(); x++)
114            {
115                const GLubyte* pixel = pixels.data() + ((y * getWindowWidth() + x) * 4);
116
117                EXPECT_EQ(pixel[0], 0);
118                EXPECT_EQ(pixel[1], pixel[2]);
119                EXPECT_EQ(pixel[3], 255);
120            }
121        }
122    }
123
124    GLuint mProgram;
125    GLint mPositionLocation;
126    GLint mColorLocation;
127};
128
129TEST_F(LineLoopTest, LineLoopUByteIndices)
130{
131    static const GLubyte indices[] = { 0, 7, 6, 9, 8, 0 };
132    runTest(GL_UNSIGNED_BYTE, 0, indices + 1);
133}
134
135TEST_F(LineLoopTest, LineLoopUShortIndices)
136{
137    static const GLushort indices[] = { 0, 7, 6, 9, 8, 0 };
138    runTest(GL_UNSIGNED_SHORT, 0, indices + 1);
139}
140
141TEST_F(LineLoopTest, LineLoopUIntIndices)
142{
143    if (!extensionEnabled("GL_OES_element_index_uint"))
144    {
145        return;
146    }
147
148    static const GLuint indices[] = { 0, 7, 6, 9, 8, 0 };
149    runTest(GL_UNSIGNED_INT, 0, indices + 1);
150}
151
152TEST_F(LineLoopTest, LineLoopUByteIndexBuffer)
153{
154    static const GLubyte indices[] = { 0, 7, 6, 9, 8, 0 };
155
156    GLuint buf;
157    glGenBuffers(1, &buf);
158    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
159    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
160
161    runTest(GL_UNSIGNED_BYTE, buf, reinterpret_cast<const void *>(sizeof(GLubyte)));
162
163    glDeleteBuffers(1, &buf);
164}
165
166TEST_F(LineLoopTest, LineLoopUShortIndexBuffer)
167{
168    static const GLushort indices[] = { 0, 7, 6, 9, 8, 0 };
169
170    GLuint buf;
171    glGenBuffers(1, &buf);
172    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
173    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
174
175    runTest(GL_UNSIGNED_SHORT, buf, reinterpret_cast<const void *>(sizeof(GLushort)));
176
177    glDeleteBuffers(1, &buf);
178}
179
180TEST_F(LineLoopTest, LineLoopUIntIndexBuffer)
181{
182    if (!extensionEnabled("GL_OES_element_index_uint"))
183    {
184        return;
185    }
186
187    static const GLuint indices[] = { 0, 7, 6, 9, 8, 0 };
188
189    GLuint buf;
190    glGenBuffers(1, &buf);
191    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
192    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
193
194    runTest(GL_UNSIGNED_INT, buf, reinterpret_cast<const void *>(sizeof(GLuint)));
195
196    glDeleteBuffers(1, &buf);
197}
198