Add more structure constructor tests.
[piglit/hramrach.git] / tests / general / primitive-restart.c
blob4298b5eed36a3224c2a0a8fc2fd3b05709e371c0
1 /*
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
13 * Software.
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.
24 /**
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!
29 * Authors:
30 * Brian Paul
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;
49 static GLboolean
50 check_rendering(void)
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;
55 GLfloat x;
57 for (x = x0 + 0.5 * dx; x < x1; x += dx) {
58 GLboolean pass;
59 const int ix = (int) x;
61 if (draw) {
62 /* there should be triangle drawing here */
63 pass = piglit_probe_pixel_rgb(ix, iy, green);
65 else {
66 /* there should not be triangle drawing here */
67 pass = piglit_probe_pixel_rgb(ix, iy, black);
70 /* debug */
71 if (0) {
72 glWindowPos2i(ix, iy);
73 glDrawPixels(1, 1, GL_RGBA, GL_FLOAT, red);
76 if (!pass) {
77 return GL_FALSE;
80 draw = !draw;
83 return GL_TRUE;
87 /**
88 * Test glBegin(GL_TRIANGLE/LINE_STRIP), glPrimitiveRestartNV(), glEnd().
90 static GLboolean
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;
95 GLfloat x, y;
96 GLint vert;
97 GLboolean pass;
99 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
101 glClear(GL_COLOR_BUFFER_BIT);
103 glColor4fv(green);
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);
110 vert = 0;
111 for (x = x0; x <= x1; x += dx) {
112 for (y = y0; y <= y1; y += dy) {
113 glVertex2f(x, y);
116 vert++;
117 if (vert % 2 == 0)
118 glPrimitiveRestartNV();
120 glEnd();
122 else {
123 /* Draw a line strip across the window, using restart to actually render
124 * a series of disconnected lines.
126 glLineWidth(5.0);
127 glBegin(GL_LINE_STRIP);
128 vert = 0;
129 for (x = x0; x <= x1; x += dx) {
130 y = 0.5 * piglit_height;
132 glVertex2f(x, y);
134 vert++;
135 if (vert % 2 == 0)
136 glPrimitiveRestartNV();
138 glEnd();
141 glFinish();
143 pass = check_rendering();
144 if (!pass) {
145 fprintf(stderr, "%s: failure drawing with glBegin(%s) / glEnd()\n",
146 TestName,
147 (primMode == GL_TRIANGLE_STRIP
148 ? "GL_TRIANGLE_STRIP" : "GL_LINE_STRIP"));
151 glutSwapBuffers();
153 return pass;
158 * Test glDrawElements() with glPrimitiveRestartIndexNV().
160 static GLboolean
161 test_draw_elements(GLenum primMode, GLenum indexType)
163 #define NUM_VERTS 48
164 #define NUM_ELEMS (NUM_VERTS * 5 / 4)
165 GLfloat verts[NUM_VERTS+2][2];
166 GLuint elements[NUM_ELEMS];
167 GLfloat x, dx;
168 GLuint restart_index;
169 GLuint num_elems;
170 GLboolean pass;
171 const char *typeStr = NULL, *primStr = NULL;
173 switch (indexType) {
174 case GL_UNSIGNED_BYTE:
175 restart_index = 255;
176 typeStr = "GL_UNSIGNED_BYTE";
177 break;
178 case GL_UNSIGNED_SHORT:
179 restart_index = 1000;
180 typeStr = "GL_UNSIGNED_SHORT";
181 break;
182 case GL_UNSIGNED_INT:
183 restart_index = 1000 * 1000;
184 typeStr = "GL_UNSIGNED_INT";
185 break;
186 default:
187 assert(0);
190 x = 0.0;
191 dx = 20.0;
193 if (primMode == GL_TRIANGLE_STRIP) {
194 GLuint i, j;
195 const GLfloat y = 0.5 * piglit_height - 10.0, dy = 20.0;
196 for (i = 0; i < NUM_VERTS / 2; i++) {
197 verts[i*2+0][0] = x;
198 verts[i*2+0][1] = y;
199 verts[i*2+1][0] = x;
200 verts[i*2+1][1] = y + dy;
201 x += dx;
204 /* setup elements to draw series of squares w/ tri strip */
205 for (i = j = 0; i < NUM_VERTS; i++) {
206 elements[j++] = i;
207 if (i > 0 && i % 4 == 3)
208 elements[j++] = restart_index;
211 num_elems = j;
212 primStr = "GL_TRIANGLE_STRIP";
214 else {
215 GLuint i, j;
216 const GLfloat y = 0.5 * piglit_height;
218 assert(primMode == GL_LINE_STRIP);
220 glLineWidth(5.0);
223 for (i = 0; i < NUM_VERTS; i++) {
224 verts[i][0] = x;
225 verts[i][1] = y;
226 x += dx;
229 /* setup elements to draw series of disjoint lines w/ line strip */
230 for (i = j = 0; i < NUM_VERTS / 2; i++) {
231 elements[j++] = i;
232 if (i > 0 && i % 2 == 1)
233 elements[j++] = restart_index;
236 num_elems = j;
237 primStr = "GL_LINE_STRIP";
240 assert(num_elems <= NUM_ELEMS);
242 /* debug */
243 if (0) {
244 GLint i;
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);
253 glColor4fv(green);
255 glVertexPointer(2, GL_FLOAT, 2*sizeof(GLfloat), verts);
256 glEnableClientState(GL_VERTEX_ARRAY);
258 assert(glGetError()==0);
259 /* Setup prim restart */
260 if (TestGL31) {
261 #ifdef GL_VERSION_3_1
262 glEnable(GL_PRIMITIVE_RESTART);
263 glPrimitiveRestartIndex(restart_index);
264 #endif
266 else {
267 glEnableClientState(GL_PRIMITIVE_RESTART_NV);
268 glPrimitiveRestartIndexNV(restart_index);
271 /* Draw */
272 if (0) {
273 /* XXX also test non-indexed drawing someday */
274 glDrawArrays(primMode, 0, NUM_VERTS);
276 else {
277 switch (indexType) {
278 case GL_UNSIGNED_BYTE:
280 GLubyte ub_elements[NUM_ELEMS];
281 int i;
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);
286 break;
287 case GL_UNSIGNED_SHORT:
289 GLushort us_elements[NUM_ELEMS];
290 int i;
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);
295 break;
296 case GL_UNSIGNED_INT:
297 glDrawElements(primMode, num_elems, GL_UNSIGNED_INT, elements);
298 break;
299 default:
300 assert(0);
304 if (TestGL31) {
305 #ifdef GL_VERSION_3_1
306 glDisable(GL_PRIMITIVE_RESTART);
307 #endif
309 else {
310 glDisableClientState(GL_PRIMITIVE_RESTART_NV);
312 glDisableClientState(GL_VERTEX_ARRAY);
314 pass = check_rendering();
315 if (!pass) {
316 fprintf(stderr, "%s: failure drawing with glDrawElements(%s, %s)\n",
317 TestName, primStr, typeStr);
320 glutSwapBuffers();
322 return pass;
326 enum piglit_result
327 piglit_display(void)
329 GLboolean pass = GL_TRUE;
331 if (Have_NV) {
332 TestGL31 = GL_FALSE;
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);
343 if (Have_31) {
344 TestGL31 = GL_TRUE;
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;
357 void
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");
363 #else
364 Have_31 = GL_FALSE;
365 #endif
367 /* Debug */
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!
372 if (0) {
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);
379 exit(1);
382 glClearColor(0, 0, 0, 0);