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 
9 using namespace angle;
10 
11 template <typename IndexType, GLenum IndexTypeName>
12 class IndexedPointsTest : public ANGLETest
13 {
14   protected:
IndexedPointsTest()15     IndexedPointsTest()
16     {
17         setWindowWidth(128);
18         setWindowHeight(128);
19         setConfigRedBits(8);
20         setConfigGreenBits(8);
21         setConfigBlueBits(8);
22         setConfigAlphaBits(8);
23         setConfigDepthBits(24);
24     }
25 
getIndexPositionX(size_t idx)26     float getIndexPositionX(size_t idx)
27     {
28         return (idx == 0 || idx == 3) ? -0.5f : 0.5f;
29     }
30 
getIndexPositionY(size_t idx)31     float getIndexPositionY(size_t idx)
32     {
33         return (idx == 2 || idx == 3) ? -0.5f : 0.5f;
34     }
35 
SetUp()36     virtual void SetUp()
37     {
38         ANGLETest::SetUp();
39 
40         const std::string vertexShaderSource = SHADER_SOURCE
41         (
42             precision highp float;
43             attribute vec2 position;
44 
45             void main()
46             {
47                 gl_PointSize = 5.0;
48                 gl_Position = vec4(position, 0.0, 1.0);
49             }
50         );
51 
52         const std::string fragmentShaderSource = SHADER_SOURCE
53         (
54             precision highp float;
55 
56             void main()
57             {
58                 gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
59             }
60         );
61 
62         mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
63         ASSERT_NE(0u, mProgram);
64 
65         const std::string vertexShaderSource2 = SHADER_SOURCE
66         (
67             precision highp float;
68             attribute vec2 position;
69             attribute vec4 color;
70             varying vec4 vcolor;
71 
72             void main()
73             {
74                 gl_PointSize = 5.0;
75                 gl_Position = vec4(position, 0.0, 1.0);
76                 vcolor = color;
77             }
78         );
79 
80         const std::string fragmentShaderSource2 = SHADER_SOURCE
81         (
82             precision highp float;
83             varying vec4 vcolor;
84             void main()
85             {
86                 gl_FragColor = vec4(vcolor.xyz, 1.0);
87             }
88         );
89 
90         mVertexWithColorBufferProgram = CompileProgram(vertexShaderSource2, fragmentShaderSource2);
91         ASSERT_NE(0u, mVertexWithColorBufferProgram);
92 
93         // Construct a vertex buffer of position values and color values
94         // contained in a single structure
95         const float verticesWithColor[] =
96         {
97             getIndexPositionX(0), getIndexPositionY(0), 0.0f, 1.0f, 0.0f,
98             getIndexPositionX(2), getIndexPositionY(2), 0.0f, 1.0f, 0.0f,
99             getIndexPositionX(1), getIndexPositionY(1), 0.0f, 1.0f, 0.0f,
100             getIndexPositionX(3), getIndexPositionY(3), 0.0f, 1.0f, 0.0f,
101         };
102 
103         glGenBuffers(1, &mVertexWithColorBuffer);
104         glBindBuffer(GL_ARRAY_BUFFER, mVertexWithColorBuffer);
105         glBufferData(GL_ARRAY_BUFFER, sizeof(verticesWithColor), &verticesWithColor[0], GL_STATIC_DRAW);
106 
107         // Construct a vertex buffer of position values only
108         const GLfloat vertices[] =
109         {
110             getIndexPositionX(0), getIndexPositionY(0),
111             getIndexPositionX(2), getIndexPositionY(2),
112             getIndexPositionX(1), getIndexPositionY(1),
113             getIndexPositionX(3), getIndexPositionY(3),
114         };
115         glGenBuffers(1, &mVertexBuffer);
116         glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
117         glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_STATIC_DRAW);
118 
119         // The indices buffer is shared between both variations of tests
120         const IndexType indices[] = { 0, 2, 1, 3 };
121         glGenBuffers(1, &mIndexBuffer);
122         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
123         glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), &indices[0], GL_STATIC_DRAW);
124     }
125 
TearDown()126     virtual void TearDown()
127     {
128         glDeleteBuffers(1, &mVertexBuffer);
129         glDeleteBuffers(1, &mIndexBuffer);
130         glDeleteProgram(mProgram);
131 
132         glDeleteBuffers(1, &mVertexWithColorBuffer);
133         glDeleteProgram(mVertexWithColorBufferProgram);
134         ANGLETest::TearDown();
135     }
136 
runTest(GLuint firstIndex,bool useVertexBufferWithColor=false)137     void runTest(GLuint firstIndex, bool useVertexBufferWithColor = false)
138     {
139         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
140         glClear(GL_COLOR_BUFFER_BIT);
141 
142         GLint viewportSize[4];
143         glGetIntegerv(GL_VIEWPORT, viewportSize);
144 
145         // Choose appropriate program to apply for the test
146         GLuint program = useVertexBufferWithColor ? mVertexWithColorBufferProgram : mProgram;
147 
148         if (useVertexBufferWithColor)
149         {
150             glBindBuffer(GL_ARRAY_BUFFER, mVertexWithColorBuffer);
151             GLint vertexLocation = glGetAttribLocation(program, "position");
152             glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE,
153                                   static_cast<const GLsizei>(VertexWithColorSize), 0);
154             glEnableVertexAttribArray(vertexLocation);
155 
156             GLint vertexColorLocation = glGetAttribLocation(program, "color");
157             glVertexAttribPointer(vertexColorLocation, 3, GL_FLOAT, GL_FALSE,
158                                   static_cast<const GLsizei>(VertexWithColorSize),
159                                   (GLvoid *)((sizeof(float) * 2)));
160             glEnableVertexAttribArray(vertexColorLocation);
161         }
162         else
163         {
164             glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
165             GLint vertexLocation = glGetAttribLocation(program, "position");
166             glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
167             glEnableVertexAttribArray(vertexLocation);
168         }
169 
170         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
171         glUseProgram(program);
172 
173         glDrawElements(GL_POINTS, mPointCount - firstIndex, IndexTypeName, reinterpret_cast<void*>(firstIndex * sizeof(IndexType)));
174 
175         for (size_t i = 0; i < mPointCount; i++)
176         {
177             GLuint x = static_cast<GLuint>(viewportSize[0] + (getIndexPositionX(i) * 0.5f + 0.5f) * (viewportSize[2] - viewportSize[0]));
178             GLuint y = static_cast<GLuint>(viewportSize[1] + (getIndexPositionY(i) * 0.5f + 0.5f) * (viewportSize[3] - viewportSize[1]));
179 
180             if (i < firstIndex)
181             {
182                 EXPECT_PIXEL_EQ(x, y, 0, 0, 0, 255);
183             }
184             else
185             {
186                 if (useVertexBufferWithColor)
187                 {
188                     // Pixel data is assumed to be GREEN
189                     EXPECT_PIXEL_EQ(x, y, 0, 255, 0, 255);
190                 }
191                 else
192                 {
193                     // Pixel data is assumed to be RED
194                     EXPECT_PIXEL_EQ(x, y, 255, 0, 0, 255);
195                 }
196             }
197         }
198         swapBuffers();
199     }
200 
201     GLuint mProgram;
202     GLuint mVertexBuffer;
203     GLuint mIndexBuffer;
204 
205     GLuint mVertexWithColorBufferProgram;
206     GLuint mVertexWithColorBuffer;
207 
208     static const GLuint mPointCount = 4;
209 
210   private:
211     const size_t VertexWithColorSize = sizeof(float) * 5;
212 };
213 
214 typedef IndexedPointsTest<GLubyte, GL_UNSIGNED_BYTE> IndexedPointsTestUByte;
215 
TEST_P(IndexedPointsTestUByte,UnsignedByteOffset0)216 TEST_P(IndexedPointsTestUByte, UnsignedByteOffset0)
217 {
218     runTest(0);
219 }
220 
TEST_P(IndexedPointsTestUByte,UnsignedByteOffset1)221 TEST_P(IndexedPointsTestUByte, UnsignedByteOffset1)
222 {
223     runTest(1);
224 }
225 
TEST_P(IndexedPointsTestUByte,UnsignedByteOffset2)226 TEST_P(IndexedPointsTestUByte, UnsignedByteOffset2)
227 {
228     runTest(2);
229 }
230 
TEST_P(IndexedPointsTestUByte,UnsignedByteOffset3)231 TEST_P(IndexedPointsTestUByte, UnsignedByteOffset3)
232 {
233     runTest(3);
234 }
235 
TEST_P(IndexedPointsTestUByte,VertexWithColorUnsignedByteOffset0)236 TEST_P(IndexedPointsTestUByte, VertexWithColorUnsignedByteOffset0)
237 {
238     runTest(0, true);
239 }
240 
TEST_P(IndexedPointsTestUByte,VertexWithColorUnsignedByteOffset1)241 TEST_P(IndexedPointsTestUByte, VertexWithColorUnsignedByteOffset1)
242 {
243     runTest(1, true);
244 }
245 
TEST_P(IndexedPointsTestUByte,VertexWithColorUnsignedByteOffset2)246 TEST_P(IndexedPointsTestUByte, VertexWithColorUnsignedByteOffset2)
247 {
248     runTest(2, true);
249 }
250 
TEST_P(IndexedPointsTestUByte,VertexWithColorUnsignedByteOffset3)251 TEST_P(IndexedPointsTestUByte, VertexWithColorUnsignedByteOffset3)
252 {
253     runTest(3, true);
254 }
255 
256 typedef IndexedPointsTest<GLushort, GL_UNSIGNED_SHORT> IndexedPointsTestUShort;
257 
TEST_P(IndexedPointsTestUShort,UnsignedShortOffset0)258 TEST_P(IndexedPointsTestUShort, UnsignedShortOffset0)
259 {
260     runTest(0);
261 }
262 
TEST_P(IndexedPointsTestUShort,UnsignedShortOffset1)263 TEST_P(IndexedPointsTestUShort, UnsignedShortOffset1)
264 {
265     runTest(1);
266 }
267 
TEST_P(IndexedPointsTestUShort,UnsignedShortOffset2)268 TEST_P(IndexedPointsTestUShort, UnsignedShortOffset2)
269 {
270     runTest(2);
271 }
272 
TEST_P(IndexedPointsTestUShort,UnsignedShortOffset3)273 TEST_P(IndexedPointsTestUShort, UnsignedShortOffset3)
274 {
275     runTest(3);
276 }
277 
TEST_P(IndexedPointsTestUShort,VertexWithColorUnsignedShortOffset0)278 TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffset0)
279 {
280     runTest(0, true);
281 }
282 
TEST_P(IndexedPointsTestUShort,VertexWithColorUnsignedShortOffset1)283 TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffset1)
284 {
285     runTest(1, true);
286 }
287 
TEST_P(IndexedPointsTestUShort,VertexWithColorUnsignedShortOffset2)288 TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffset2)
289 {
290     runTest(2, true);
291 }
292 
TEST_P(IndexedPointsTestUShort,VertexWithColorUnsignedShortOffset3)293 TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffset3)
294 {
295     runTest(3, true);
296 }
297 
TEST_P(IndexedPointsTestUShort,VertexWithColorUnsignedShortOffsetChangingIndices)298 TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffsetChangingIndices)
299 {
300     runTest(3, true);
301     runTest(1, true);
302     runTest(0, true);
303     runTest(2, true);
304 }
305 
306 typedef IndexedPointsTest<GLuint, GL_UNSIGNED_INT> IndexedPointsTestUInt;
307 
TEST_P(IndexedPointsTestUInt,UnsignedIntOffset0)308 TEST_P(IndexedPointsTestUInt, UnsignedIntOffset0)
309 {
310     if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint"))
311     {
312         return;
313     }
314 
315     runTest(0);
316 }
317 
TEST_P(IndexedPointsTestUInt,UnsignedIntOffset1)318 TEST_P(IndexedPointsTestUInt, UnsignedIntOffset1)
319 {
320     if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint"))
321     {
322         return;
323     }
324 
325     runTest(1);
326 }
327 
TEST_P(IndexedPointsTestUInt,UnsignedIntOffset2)328 TEST_P(IndexedPointsTestUInt, UnsignedIntOffset2)
329 {
330     if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint"))
331     {
332         return;
333     }
334 
335     runTest(2);
336 }
337 
TEST_P(IndexedPointsTestUInt,UnsignedIntOffset3)338 TEST_P(IndexedPointsTestUInt, UnsignedIntOffset3)
339 {
340     if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint"))
341     {
342         return;
343     }
344 
345     runTest(3);
346 }
347 
TEST_P(IndexedPointsTestUInt,VertexWithColorUnsignedIntOffset0)348 TEST_P(IndexedPointsTestUInt, VertexWithColorUnsignedIntOffset0)
349 {
350     if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint"))
351     {
352         return;
353     }
354 
355     runTest(0, false);
356 }
357 
TEST_P(IndexedPointsTestUInt,VertexWithColorUnsignedIntOffset1)358 TEST_P(IndexedPointsTestUInt, VertexWithColorUnsignedIntOffset1)
359 {
360     if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint"))
361     {
362         return;
363     }
364 
365     runTest(1, false);
366 }
367 
TEST_P(IndexedPointsTestUInt,VertexWithColorUnsignedIntOffset2)368 TEST_P(IndexedPointsTestUInt, VertexWithColorUnsignedIntOffset2)
369 {
370     if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint"))
371     {
372         return;
373     }
374 
375     runTest(2, false);
376 }
377 
TEST_P(IndexedPointsTestUInt,VertexWithColorUnsignedIntOffset3)378 TEST_P(IndexedPointsTestUInt, VertexWithColorUnsignedIntOffset3)
379 {
380     if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint"))
381     {
382         return;
383     }
384 
385     runTest(3, false);
386 }
387 
388 // TODO(geofflang): Figure out why this test fails on Intel OpenGL
389 ANGLE_INSTANTIATE_TEST(IndexedPointsTestUByte,
390                        ES2_D3D11(),
391                        ES2_D3D11_FL9_3(),
392                        ES2_OPENGL(),
393                        ES2_OPENGLES());
394 ANGLE_INSTANTIATE_TEST(IndexedPointsTestUShort,
395                        ES2_D3D11(),
396                        ES2_D3D11_FL9_3(),
397                        ES2_OPENGL(),
398                        ES2_OPENGLES());
399 ANGLE_INSTANTIATE_TEST(IndexedPointsTestUInt,
400                        ES2_D3D11(),
401                        ES2_D3D11_FL9_3(),
402                        ES2_OPENGL(),
403                        ES2_OPENGLES());
404