2 * Copyright © 2017 Fabian Bieler
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 DEALINGS
25 * @file long-line-loop.c
26 * Draw cricles with line loops and a line strips blended on top of each
27 * other and check that the renderings match.
30 #include "piglit-util-gl.h"
32 PIGLIT_GL_TEST_CONFIG_BEGIN
34 config
.supports_gl_compat_version
= 10;
35 config
.window_width
= 1024;
36 config
.window_height
= 1024;
37 config
.window_visual
= PIGLIT_GL_VISUAL_RGB
;
38 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
40 PIGLIT_GL_TEST_CONFIG_END
42 static int max_vertices
;
43 static int num_vertices
;
44 static int probe_location
[2];
45 static const float radius
= 0.9;
48 print_usage_and_exit(const char *prog_name
)
50 printf("Usage: %s [<vertex_count>]\n"
51 " where <vertex_count> is the number of vertices to test.\n"
53 " If omitted, sequentially test from 16 to max_vertices by "
55 " where max_vertices is GL_MAX_ELEMENTS_VERTICES clamped to "
56 "[0x10000, 0x40000].\n",
58 piglit_report_result(PIGLIT_FAIL
);
62 piglit_init(int argc
, char **argv
)
64 glBlendFunc(GL_ONE
, GL_ONE
);
66 piglit_ortho_projection(piglit_width
, piglit_height
, false);
69 /* This isn't a hard limit, but staying below should help
72 * XXX: It could be interesting to go beyond this limit to
73 * test a different code path in the GL implementation.
75 glGetIntegerv(GL_MAX_ELEMENTS_VERTICES
, &max_vertices
);
76 max_vertices
= CLAMP(max_vertices
, 0x10000, 0x40000);
77 } else if (argc
== 2) {
79 num_vertices
= strtol(argv
[1], &endptr
, 0);
80 if (endptr
!= argv
[1] + strlen(argv
[1]))
81 print_usage_and_exit(argv
[0]);
83 print_usage_and_exit(argv
[0]);
85 print_usage_and_exit(argv
[0]);
90 draw_circle(int segments
)
92 /* The first (segments - 1) vertices describe the arc of a circle
93 * slice with central angle (360° - alpha).
94 * The last vertex is identical to the first vertex.
95 * alpha is chosen so that the last line segment covers two pixels.
97 const float alpha
= asinf(2.0 / (piglit_width
/ 2 * radius
));
102 } *vertex
= malloc(sizeof(vertex
[0]) * segments
);
104 for (int i
= 0; i
< segments
- 1; ++i
) {
105 const float phi
= alpha
-
107 (float)(segments
- 2) *
110 vertex
[i
].pos
[0] = round(piglit_width
/ 2 *
111 (1 + radius
* cosf(phi
))) + 0.5;
112 vertex
[i
].pos
[1] = round(piglit_height
/ 2 *
113 (1 + radius
* sinf(phi
))) + 0.5;
114 vertex
[i
].pos
[2] = 0;
115 vertex
[i
].pos
[3] = 1;
116 vertex
[i
].green
[0] = 0;
117 vertex
[i
].green
[1] = 1;
118 vertex
[i
].green
[2] = 0;
119 vertex
[i
].green
[3] = 1;
120 vertex
[i
].blue
[0] = 0;
121 vertex
[i
].blue
[1] = 0;
122 vertex
[i
].blue
[2] = 1;
123 vertex
[i
].blue
[3] = 1;
125 memcpy(&vertex
[segments
- 1], &vertex
[0], sizeof(vertex
[0]));
127 /* Find a pixel in the last line segment: */
128 for (int i
= 0; i
< 2; ++i
)
129 probe_location
[i
] = round((vertex
[segments
- 2].pos
[i
] +
130 vertex
[segments
- 1].pos
[i
] -
134 glClear(GL_COLOR_BUFFER_BIT
);
136 glVertexPointer(4, GL_FLOAT
, sizeof(vertex
[0]), vertex
[0].pos
);
137 glColorPointer(4, GL_FLOAT
, sizeof(vertex
[0]), vertex
[0].green
);
139 glEnableClientState(GL_VERTEX_ARRAY
);
140 glEnableClientState(GL_COLOR_ARRAY
);
142 glDrawArrays(GL_LINE_LOOP
, 0, segments
- 1);
145 glColorPointer(4, GL_FLOAT
, sizeof(vertex
[0]), vertex
[0].blue
);
146 glDrawArrays(GL_LINE_STRIP
, 0, segments
);
151 piglit_present_results();
158 const float teal
[] = {0, 1, 1};
159 const float black
[] = {0, 0, 0};
161 /* check that the two renderings are identical */
162 pass
= piglit_probe_rect_two_rgb(0, 0, piglit_width
, piglit_height
,
163 black
, teal
) && pass
;
165 /* belt + suspenders: Additionally check that the last line segment
168 pass
= piglit_probe_pixel_rgb(probe_location
[0], probe_location
[1],
171 /* ...and that the center of the circle is black */
172 const int x
= ceil(piglit_width
/ 2 * radius
/ M_SQRT2
) + 1;
173 const int y
= ceil(piglit_height
/ 2 * radius
/ M_SQRT2
) + 1;
174 pass
= piglit_probe_rect_rgb(x
, y
, piglit_width
- 2 * x
,
175 piglit_height
- 2 * y
, black
) && pass
;
186 for (int vertices
= 16;
187 vertices
<= max_vertices
;
189 draw_circle(vertices
);
190 pass
= check_circle() && pass
;
193 draw_circle(num_vertices
);
194 pass
= check_circle() && pass
;
197 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;