2 * Copyright 2010 VMware, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
25 * Test GL_NV_primitive_restart and/or GL 3.1 primitive restart.
26 * Note that these two extensions/features use different enum values
27 * and Enable/Disable functions!
33 #include "piglit-util.h"
35 int piglit_width
= 400, piglit_height
= 300;
36 int piglit_window_mode
= GLUT_RGB
| GLUT_DOUBLE
;
38 static const char *TestName
= "primitive-restart";
40 static const GLfloat red
[4] = {1.0, 0.0, 0.0, 1.0};
41 static const GLfloat green
[4] = {0.0, 1.0, 0.0, 0.0};
42 static const GLfloat black
[4] = {0.0, 0.0, 0.0, 0.0};
44 static GLboolean Have_NV
;
45 static GLboolean Have_31
;
46 static GLboolean TestGL31
;
52 const GLfloat x0
= 0.0, x1
= piglit_width
- 10.0, dx
= 20.0;
53 const GLint iy
= piglit_height
/ 2;
54 GLboolean draw
= GL_TRUE
;
57 for (x
= x0
+ 0.5 * dx
; x
< x1
; x
+= dx
) {
59 const int ix
= (int) x
;
62 /* there should be triangle drawing here */
63 pass
= piglit_probe_pixel_rgb(ix
, iy
, green
);
66 /* there should not be triangle drawing here */
67 pass
= piglit_probe_pixel_rgb(ix
, iy
, black
);
72 glWindowPos2i(ix
, iy
);
73 glDrawPixels(1, 1, GL_RGBA
, GL_FLOAT
, red
);
88 * Test glBegin(GL_TRIANGLE/LINE_STRIP), glPrimitiveRestartNV(), glEnd().
91 test_begin_end(GLenum primMode
)
93 const GLfloat x0
= 0.0, x1
= piglit_width
- 10.0, dx
= 20.0;
94 const GLfloat y0
= 0.5 * piglit_height
- 10.0, y1
= y0
+ 20.0, dy
= 20.0;
99 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
101 glClear(GL_COLOR_BUFFER_BIT
);
105 if (primMode
== GL_TRIANGLE_STRIP
) {
106 /* Draw a tri-strip across the window, using restart to actually render
107 * a series of quads/boxes.
109 glBegin(GL_TRIANGLE_STRIP
);
111 for (x
= x0
; x
<= x1
; x
+= dx
) {
112 for (y
= y0
; y
<= y1
; y
+= dy
) {
118 glPrimitiveRestartNV();
123 /* Draw a line strip across the window, using restart to actually render
124 * a series of disconnected lines.
127 glBegin(GL_LINE_STRIP
);
129 for (x
= x0
; x
<= x1
; x
+= dx
) {
130 y
= 0.5 * piglit_height
;
136 glPrimitiveRestartNV();
143 pass
= check_rendering();
145 fprintf(stderr
, "%s: failure drawing with glBegin(%s) / glEnd()\n",
147 (primMode
== GL_TRIANGLE_STRIP
148 ? "GL_TRIANGLE_STRIP" : "GL_LINE_STRIP"));
158 * Test glDrawElements() with glPrimitiveRestartIndexNV().
161 test_draw_elements(GLenum primMode
, GLenum indexType
)
164 #define NUM_ELEMS (NUM_VERTS * 5 / 4)
165 GLfloat verts
[NUM_VERTS
+2][2];
166 GLuint elements
[NUM_ELEMS
];
168 GLuint restart_index
;
171 const char *typeStr
= NULL
, *primStr
= NULL
;
174 case GL_UNSIGNED_BYTE
:
176 typeStr
= "GL_UNSIGNED_BYTE";
178 case GL_UNSIGNED_SHORT
:
179 restart_index
= 1000;
180 typeStr
= "GL_UNSIGNED_SHORT";
182 case GL_UNSIGNED_INT
:
183 restart_index
= 1000 * 1000;
184 typeStr
= "GL_UNSIGNED_INT";
193 if (primMode
== GL_TRIANGLE_STRIP
) {
195 const GLfloat y
= 0.5 * piglit_height
- 10.0, dy
= 20.0;
196 for (i
= 0; i
< NUM_VERTS
/ 2; i
++) {
200 verts
[i
*2+1][1] = y
+ dy
;
204 /* setup elements to draw series of squares w/ tri strip */
205 for (i
= j
= 0; i
< NUM_VERTS
; i
++) {
207 if (i
> 0 && i
% 4 == 3)
208 elements
[j
++] = restart_index
;
212 primStr
= "GL_TRIANGLE_STRIP";
216 const GLfloat y
= 0.5 * piglit_height
;
218 assert(primMode
== GL_LINE_STRIP
);
223 for (i
= 0; i
< NUM_VERTS
; i
++) {
229 /* setup elements to draw series of disjoint lines w/ line strip */
230 for (i
= j
= 0; i
< NUM_VERTS
/ 2; i
++) {
232 if (i
> 0 && i
% 2 == 1)
233 elements
[j
++] = restart_index
;
237 primStr
= "GL_LINE_STRIP";
240 assert(num_elems
<= NUM_ELEMS
);
245 for (i
= 0; i
< num_elems
; i
++)
246 printf("%2d: %d\n", i
, elements
[i
]);
249 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
251 glClear(GL_COLOR_BUFFER_BIT
);
255 glVertexPointer(2, GL_FLOAT
, 2*sizeof(GLfloat
), verts
);
256 glEnableClientState(GL_VERTEX_ARRAY
);
258 assert(glGetError()==0);
259 /* Setup prim restart */
261 #ifdef GL_VERSION_3_1
262 glEnable(GL_PRIMITIVE_RESTART
);
263 glPrimitiveRestartIndex(restart_index
);
267 glEnableClientState(GL_PRIMITIVE_RESTART_NV
);
268 glPrimitiveRestartIndexNV(restart_index
);
273 /* XXX also test non-indexed drawing someday */
274 glDrawArrays(primMode
, 0, NUM_VERTS
);
278 case GL_UNSIGNED_BYTE
:
280 GLubyte ub_elements
[NUM_ELEMS
];
282 for (i
= 0; i
< num_elems
; i
++)
283 ub_elements
[i
] = (GLubyte
) elements
[i
];
284 glDrawElements(primMode
, num_elems
, GL_UNSIGNED_BYTE
, ub_elements
);
287 case GL_UNSIGNED_SHORT
:
289 GLushort us_elements
[NUM_ELEMS
];
291 for (i
= 0; i
< num_elems
; i
++)
292 us_elements
[i
] = (GLushort
) elements
[i
];
293 glDrawElements(primMode
, num_elems
, GL_UNSIGNED_SHORT
, us_elements
);
296 case GL_UNSIGNED_INT
:
297 glDrawElements(primMode
, num_elems
, GL_UNSIGNED_INT
, elements
);
305 #ifdef GL_VERSION_3_1
306 glDisable(GL_PRIMITIVE_RESTART
);
310 glDisableClientState(GL_PRIMITIVE_RESTART_NV
);
312 glDisableClientState(GL_VERTEX_ARRAY
);
314 pass
= check_rendering();
316 fprintf(stderr
, "%s: failure drawing with glDrawElements(%s, %s)\n",
317 TestName
, primStr
, typeStr
);
329 GLboolean pass
= GL_TRUE
;
333 pass
= pass
&& test_begin_end(GL_TRIANGLE_STRIP
);
334 pass
= pass
&& test_begin_end(GL_LINE_STRIP
);
335 pass
= pass
&& test_draw_elements(GL_TRIANGLE_STRIP
, GL_UNSIGNED_BYTE
);
336 pass
= pass
&& test_draw_elements(GL_TRIANGLE_STRIP
, GL_UNSIGNED_SHORT
);
337 pass
= pass
&& test_draw_elements(GL_TRIANGLE_STRIP
, GL_UNSIGNED_INT
);
338 pass
= pass
&& test_draw_elements(GL_LINE_STRIP
, GL_UNSIGNED_BYTE
);
339 pass
= pass
&& test_draw_elements(GL_LINE_STRIP
, GL_UNSIGNED_SHORT
);
340 pass
= pass
&& test_draw_elements(GL_LINE_STRIP
, GL_UNSIGNED_INT
);
345 pass
= pass
&& test_draw_elements(GL_TRIANGLE_STRIP
, GL_UNSIGNED_BYTE
);
346 pass
= pass
&& test_draw_elements(GL_TRIANGLE_STRIP
, GL_UNSIGNED_SHORT
);
347 pass
= pass
&& test_draw_elements(GL_TRIANGLE_STRIP
, GL_UNSIGNED_INT
);
348 pass
= pass
&& test_draw_elements(GL_LINE_STRIP
, GL_UNSIGNED_BYTE
);
349 pass
= pass
&& test_draw_elements(GL_LINE_STRIP
, GL_UNSIGNED_SHORT
);
350 pass
= pass
&& test_draw_elements(GL_LINE_STRIP
, GL_UNSIGNED_INT
);
353 return pass
? PIGLIT_SUCCESS
: PIGLIT_FAILURE
;
358 piglit_init(int argc
, char **argv
)
360 Have_NV
= glewIsSupported("GL_NV_primitive_restart");
361 #ifdef GL_VERSION_3_1
362 Have_31
= glewIsSupported("GL_VERSION_3_1");
368 /* NOTE! glew 1.5.2's OpenGL 3.1 detection is broken. You'll need
369 * to upgrade to a newer version if you want to test the GL 3.1
370 * primitive restart feature!
373 printf("Have NV: %d\n", Have_NV
);
374 printf("Have 31: %d\n", Have_31
);
377 if (!Have_NV
&& !Have_31
) {
378 piglit_report_result(PIGLIT_SKIP
);
382 glClearColor(0, 0, 0, 0);