fbo-mrt-alphatest: Actually require MRTs to be available.
[piglit.git] / tests / general / polygon-mode.c
blob709c6db2d345ae4a452dce6ce3bfbdaab103ac5d
1 /*
2 * Copyright (c) 2011 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 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the 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,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NON-INFRINGEMENT. IN NO EVENT SHALL VMWARE AND/OR THEIR SUPPLIERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
25 /**
26 * Tests glPolygonMode.
27 * Brian Paul
28 * April 2011
31 #include "piglit-util-gl.h"
33 PIGLIT_GL_TEST_CONFIG_BEGIN
35 config.supports_gl_compat_version = 10;
37 config.window_width = 500;
38 config.window_height = 100;
39 config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
40 config.khr_no_error_support = PIGLIT_NO_ERRORS;
42 PIGLIT_GL_TEST_CONFIG_END
44 static float ortho_left = -1, ortho_right = 8, ortho_bottom = -2, ortho_top = 2;
46 static const char *TestName = "polygon-mode";
48 #define VERTS 16
50 static const GLfloat Positions[VERTS][2] = {
51 /* counter-clockwise, front facing */
52 { 0, -1 },
53 { 1, -1 },
54 { 1, 1 },
55 { 0, 1 },
57 /* clockwise, back facing */
58 { 2, -1 },
59 { 2, 1 },
60 { 3, 1 },
61 { 3, -1 },
63 /* counter-clockwise, front facing */
64 { 4, -1 },
65 { 5, -1 },
66 { 5, 1 },
67 { 4, 1 },
69 /* clockwise, back facing */
70 { 6, -1 },
71 { 6, 1 },
72 { 7, 1 },
73 { 7, -1 }
76 static const GLfloat Colors[VERTS][4] = {
77 {1, 0, 0, 1},
78 {1, 0, 0, 1},
79 {1, 0, 0, 1},
80 {1, 0, 0, 1},
82 {0, 1, 0, 1},
83 {0, 1, 0, 1},
84 {0, 1, 0, 1},
85 {0, 1, 0, 1},
87 {0, 0, 1, 1},
88 {0, 0, 1, 1},
89 {0, 0, 1, 1},
90 {0, 0, 1, 1},
92 {1, 1, 1, 1},
93 {1, 1, 1, 1},
94 {1, 1, 1, 1},
95 {1, 1, 1, 1}
100 static GLenum
101 get_prim_mode(GLenum mode)
103 switch (mode) {
104 case GL_POINT:
105 return GL_POINTS;
106 case GL_LINE:
107 return GL_LINE_LOOP;
108 case GL_FILL:
109 return GL_QUADS;
110 default:
111 return 0;
116 static void
117 obj_pos_to_win_pos(float x, float y, int *wx, int *wy)
119 float ortho_width = ortho_right - ortho_left;
120 float ortho_height = ortho_top - ortho_bottom;
121 *wx = (int) ((x - ortho_left) / ortho_width * piglit_width);
122 *wy = (int) ((y - ortho_bottom) / ortho_height * piglit_height);
127 * Probe a 3x3 pixel region to see if any of the pixels matches the
128 * expected color.
130 static GLboolean
131 probe_region(float px, float py, const GLfloat expectedColor[4])
133 GLfloat img[3][3][4];
134 int i, j;
135 int wx, wy;
137 obj_pos_to_win_pos(px, py, &wx, &wy);
139 glReadPixels(wx-1, wy-1, 3, 3, GL_RGBA, GL_FLOAT, img);
141 /* see if any of the pixels matches the expected color */
142 for (i = 0; i < 3; i++) {
143 for (j = 0; j < 3; j++) {
144 if (img[i][j][0] == expectedColor[0] &&
145 img[i][j][1] == expectedColor[1] &&
146 img[i][j][2] == expectedColor[2] &&
147 img[i][j][3] == expectedColor[3]) {
148 return GL_TRUE;
153 return GL_FALSE;
158 * Examine the pixels drawn by a rect using the four vertex positions
159 * and determine if it was drawn filled, outlined, or as four points.
160 * \return GL_FILL, GL_LINE, GL_POINT or GL_NONE
162 static GLenum
163 identify_primitive(const GLfloat positions[4][2],
164 const GLfloat expectedColor[4])
166 /* center */
167 float cx = (positions[0][0] + positions[2][0]) / 2.0;
168 float cy = (positions[0][1] + positions[2][1]) / 2.0;
169 /* left edge */
170 float lx = positions[0][0];
171 float ly = cy;
172 /* right edge */
173 float rx = positions[2][0];
174 float ry = cy;
175 /* bottom edge */
176 float bx = cx;
177 float by = positions[0][1];
178 /* bottom edge */
179 float tx = cx;
180 float ty = positions[2][1];
182 /* probe center */
183 if (probe_region(cx, cy, expectedColor))
184 return GL_FILL;
186 /* probe left edge */
187 if (probe_region(lx, ly, expectedColor)) {
188 /* and bottom edge */
189 if (probe_region(bx, by, expectedColor)) {
190 /* and right edge */
191 if (probe_region(rx, ry, expectedColor)) {
192 /* and top edge */
193 if (probe_region(tx, ty, expectedColor)) {
194 return GL_LINE;
200 /* probe lower-left corner */
201 if (probe_region(lx, by, expectedColor)) {
202 /* probe lower-right corner */
203 if (probe_region(rx, by, expectedColor)) {
204 /* probe top-left corner */
205 if (probe_region(lx, ty, expectedColor)) {
206 /* probe top-right corner */
207 if (probe_region(rx, ty, expectedColor)) {
208 return GL_POINT;
214 return GL_NONE;
219 static GLboolean
220 test_combo(GLenum frontMode, GLenum backMode, GLenum cullMode)
222 GLenum frontPrim = get_prim_mode(frontMode);
223 GLenum backPrim = get_prim_mode(backMode);
224 GLboolean pass = GL_TRUE;
225 GLenum expectedPrims[4];
226 int i;
228 glDisable(GL_CULL_FACE);
230 /* Draw reference image */
231 glClear(GL_COLOR_BUFFER_BIT);
232 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
233 if (cullMode == GL_NONE || cullMode == GL_BACK) {
234 glDrawArrays(frontPrim, 0, 4);
236 if (cullMode == GL_NONE || cullMode == GL_FRONT) {
237 glDrawArrays(backPrim, 4, 4);
239 if (cullMode == GL_NONE || cullMode == GL_BACK) {
240 glDrawArrays(frontPrim, 8, 4);
242 if (cullMode == GL_NONE || cullMode == GL_FRONT) {
243 glDrawArrays(backPrim, 12, 4);
246 /* determine what kind of primitives were drawn */
247 for (i = 0; i < 4; i++) {
248 GLenum testMode = GL_NONE;
250 if (i & 1) {
251 /* back-facing quad */
252 if (cullMode == GL_NONE || cullMode == GL_FRONT) {
253 testMode = backMode;
255 } else {
256 /* front-facing quad */
257 if (cullMode == GL_NONE || cullMode == GL_BACK) {
258 testMode = frontMode;
262 expectedPrims[i] = identify_primitive(&Positions[4 * i], Colors[4 * i]);
264 if (expectedPrims[i] != testMode) {
265 /* we didn't get the expected reference primitive */
266 fprintf(stderr,
267 "%s: reference drawing failed for frontPrim=%s, backPrim=%s, cull=%s\n",
268 TestName, piglit_get_gl_enum_name(frontMode),
269 piglit_get_gl_enum_name(backMode),
270 piglit_get_gl_enum_name(cullMode));
271 fprintf(stderr, "At position %d, found prim %s instead of %s\n",
272 i, piglit_get_gl_enum_name(expectedPrims[i]),
273 piglit_get_gl_enum_name(testMode));
274 return GL_FALSE;
278 /* Draw test image */
279 glClear(GL_COLOR_BUFFER_BIT);
280 glPolygonMode(GL_FRONT, frontMode);
281 glPolygonMode(GL_BACK, backMode);
282 if (cullMode == GL_NONE) {
283 glDisable(GL_CULL_FACE);
284 } else {
285 glEnable(GL_CULL_FACE);
286 glCullFace(cullMode);
288 glDrawArrays(GL_QUADS, 0, 16);
290 /* check that these prims match the reference prims */
291 for (i = 0; i < 4; i++) {
292 GLenum prim = identify_primitive(&Positions[4 * i], Colors[4 * i]);
293 if (prim != expectedPrims[i]) {
294 fprintf(stderr, "%s: glPolygonMode(front=%s, back=%s), glCullMode(%s) failed\n",
295 TestName, piglit_get_gl_enum_name(frontMode),
296 piglit_get_gl_enum_name(backMode),
297 piglit_get_gl_enum_name(cullMode));
298 fprintf(stderr, "At position %d, found prim %s instead of %s\n",
299 i, piglit_get_gl_enum_name(prim),
300 piglit_get_gl_enum_name(expectedPrims[i]));
301 pass = GL_FALSE;
305 piglit_present_results();
307 return pass;
311 static GLboolean
312 test_polygonmode(void)
314 static const GLenum cullModes[] =
315 { GL_NONE, GL_FRONT, GL_BACK, GL_FRONT_AND_BACK };
316 static const GLenum fillModes[] =
317 { GL_FILL, GL_LINE, GL_POINT };
318 GLenum pass = GL_TRUE;
319 int i, j, k;
321 glVertexPointer(2, GL_FLOAT, 0, Positions);
322 glColorPointer(4, GL_FLOAT, 0, Colors);
324 glEnableClientState(GL_VERTEX_ARRAY);
325 glEnableClientState(GL_COLOR_ARRAY);
327 for (i = 0; i < ARRAY_SIZE(cullModes); i++) {
328 for (j = 0; j < ARRAY_SIZE(fillModes); j++) {
329 for (k = 0; k < ARRAY_SIZE(fillModes); k++) {
330 if (!test_combo(fillModes[k], fillModes[j], cullModes[i])) {
331 pass = GL_FALSE;
337 return pass;
341 enum piglit_result
342 piglit_display(void)
344 if (!test_polygonmode())
345 return PIGLIT_FAIL;
347 return PIGLIT_PASS;
351 void
352 piglit_init(int argc, char **argv)
354 glMatrixMode(GL_PROJECTION);
355 glLoadIdentity();
356 glOrtho(ortho_left, ortho_right, ortho_bottom, ortho_top, -1, 1);
358 glMatrixMode(GL_MODELVIEW);
359 glLoadIdentity();