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
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
26 * Tests glPolygonMode.
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";
50 static const GLfloat Positions
[VERTS
][2] = {
51 /* counter-clockwise, front facing */
57 /* clockwise, back facing */
63 /* counter-clockwise, front facing */
69 /* clockwise, back facing */
76 static const GLfloat Colors
[VERTS
][4] = {
101 get_prim_mode(GLenum mode
)
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
131 probe_region(float px
, float py
, const GLfloat expectedColor
[4])
133 GLfloat img
[3][3][4];
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]) {
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
163 identify_primitive(const GLfloat positions
[4][2],
164 const GLfloat expectedColor
[4])
167 float cx
= (positions
[0][0] + positions
[2][0]) / 2.0;
168 float cy
= (positions
[0][1] + positions
[2][1]) / 2.0;
170 float lx
= positions
[0][0];
173 float rx
= positions
[2][0];
177 float by
= positions
[0][1];
180 float ty
= positions
[2][1];
183 if (probe_region(cx
, cy
, expectedColor
))
186 /* probe left edge */
187 if (probe_region(lx
, ly
, expectedColor
)) {
188 /* and bottom edge */
189 if (probe_region(bx
, by
, expectedColor
)) {
191 if (probe_region(rx
, ry
, expectedColor
)) {
193 if (probe_region(tx
, ty
, expectedColor
)) {
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
)) {
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];
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
;
251 /* back-facing quad */
252 if (cullMode
== GL_NONE
|| cullMode
== GL_FRONT
) {
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 */
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
));
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
);
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
]));
305 piglit_present_results();
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
;
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
])) {
344 if (!test_polygonmode())
352 piglit_init(int argc
, char **argv
)
354 glMatrixMode(GL_PROJECTION
);
356 glOrtho(ortho_left
, ortho_right
, ortho_bottom
, ortho_top
, -1, 1);
358 glMatrixMode(GL_MODELVIEW
);