2 * Copyright © 2013 Intel Corporation
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 piglit-test-pattern.cpp
27 * This file defines the functions which can be utilized to draw test patterns
28 * in to color, depth or stencil buffers.
31 #include "piglit-test-pattern.h"
32 using namespace piglit_util_test_pattern
;
34 const float TestPattern::no_projection
[4][4] = {
42 void Triangles::compile()
44 /* Triangle coords within (-1,-1) to (1,1) rect */
45 static const float pos_within_tri
[][2] = {
51 /* Number of triangle instances across (and down) */
54 /* Total number of triangles drawn */
55 num_tris
= tris_across
* tris_across
;
57 /* Scaling factor uniformly applied to triangle coords */
58 float tri_scale
= 0.8 / tris_across
;
60 /* Amount each triangle should be rotated compared to prev */
61 float rotation_delta
= M_PI
* 2.0 / num_tris
;
63 /* Final scaling factor */
64 float final_scale
= 0.95;
66 static const char *vert
=
68 "attribute vec2 pos_within_tri;\n"
69 "uniform float tri_scale;\n"
70 "uniform float rotation_delta;\n"
71 "uniform int tris_across;\n"
72 "uniform float final_scale;\n"
73 "uniform mat4 proj;\n"
74 "uniform int tri_num; /* [0, num_tris) */\n"
78 " vec2 pos = tri_scale * pos_within_tri;\n"
79 " float rotation = rotation_delta * tri_num;\n"
80 " pos = mat2(cos(rotation), sin(rotation),\n"
81 " -sin(rotation), cos(rotation)) * pos;\n"
82 " int i = int(mod(float(tri_num), float(tris_across)));\n"
83 " int j = tris_across - 1 - tri_num / tris_across;\n"
84 " pos += (vec2(i, j) * 2.0 + 1.0) / tris_across - 1.0;\n"
85 " pos *= final_scale;\n"
86 " gl_Position = proj * vec4(pos, 0.0, 1.0);\n"
89 static const char *frag
=
93 " gl_FragColor = vec4(1.0);\n"
97 prog
= glCreateProgram();
98 GLint vs
= piglit_compile_shader_text(GL_VERTEX_SHADER
, vert
);
99 glAttachShader(prog
, vs
);
100 GLint fs
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, frag
);
101 glAttachShader(prog
, fs
);
102 glBindAttribLocation(prog
, 0, "pos_within_tri");
104 if (!piglit_link_check_status(prog
)) {
105 piglit_report_result(PIGLIT_FAIL
);
108 /* Set up uniforms */
110 glUniform1f(glGetUniformLocation(prog
, "tri_scale"), tri_scale
);
111 glUniform1f(glGetUniformLocation(prog
, "rotation_delta"),
113 glUniform1i(glGetUniformLocation(prog
, "tris_across"), tris_across
);
114 glUniform1f(glGetUniformLocation(prog
, "final_scale"), final_scale
);
115 proj_loc
= glGetUniformLocation(prog
, "proj");
116 tri_num_loc
= glGetUniformLocation(prog
, "tri_num");
118 /* Set up vertex array object */
119 glGenVertexArrays(1, &vao
);
120 glBindVertexArray(vao
);
122 /* Set up vertex input buffer */
123 glGenBuffers(1, &vertex_buf
);
124 glBindBuffer(GL_ARRAY_BUFFER
, vertex_buf
);
125 glBufferData(GL_ARRAY_BUFFER
, sizeof(pos_within_tri
), pos_within_tri
,
127 glEnableVertexAttribArray(0);
128 glVertexAttribPointer(0, ARRAY_SIZE(pos_within_tri
[0]), GL_FLOAT
,
129 GL_FALSE
, sizeof(pos_within_tri
[0]), (void *) 0);
132 void Triangles::draw(const float (*proj
)[4])
134 glClear(GL_COLOR_BUFFER_BIT
);
137 glUniformMatrix4fv(proj_loc
, 1, GL_TRUE
, &proj
[0][0]);
138 glBindVertexArray(vao
);
139 for (int tri_num
= 0; tri_num
< num_tris
; ++tri_num
) {
140 glUniform1i(tri_num_loc
, tri_num
);
141 glDrawArrays(GL_TRIANGLES
, 0, 3);
146 InterpolationTestPattern::InterpolationTestPattern(const char *frag
)
147 : frag(frag
), viewport_size_loc(0)
153 InterpolationTestPattern::compile()
155 static struct vertex_attributes
{
156 float pos_within_tri
[2];
157 float barycentric_coords
[3];
159 { { -0.5, -1.0 }, { 1, 0, 0 } },
160 { { 0.0, 1.0 }, { 0, 1, 0 } },
161 { { 0.5, -1.0 }, { 0, 0, 1 } }
164 /* Number of triangle instances across (and down) */
167 /* Total number of triangles drawn */
168 num_tris
= tris_across
* tris_across
;
170 /* Scaling factor uniformly applied to triangle coords */
171 float tri_scale
= 0.8 / tris_across
;
173 /* Amount each triangle should be rotated compared to prev */
174 float rotation_delta
= M_PI
* 2.0 / num_tris
;
176 /* Final scaling factor */
177 float final_scale
= 0.95;
179 static const char *vert
=
181 "attribute vec2 pos_within_tri;\n"
182 "attribute vec3 in_barycentric_coords;\n"
183 "varying vec3 barycentric_coords;\n"
184 "centroid varying vec3 barycentric_coords_centroid;\n"
185 "varying vec2 pixel_pos;\n"
186 "centroid varying vec2 pixel_pos_centroid;\n"
187 "uniform float tri_scale;\n"
188 "uniform float rotation_delta;\n"
189 "uniform int tris_across;\n"
190 "uniform float final_scale;\n"
191 "uniform mat4 proj;\n"
192 "uniform int tri_num; /* [0, num_tris) */\n"
193 "uniform ivec2 viewport_size;\n"
197 " vec2 pos = tri_scale * pos_within_tri;\n"
198 " float rotation = rotation_delta * tri_num;\n"
199 " pos = mat2(cos(rotation), sin(rotation),\n"
200 " -sin(rotation), cos(rotation)) * pos;\n"
201 " int i = int(mod(float(tri_num), float(tris_across)));\n"
202 " int j = tris_across - 1 - tri_num / tris_across;\n"
203 " pos += (vec2(i, j) * 2.0 + 1.0) / tris_across - 1.0;\n"
204 " pos *= final_scale;\n"
205 " gl_Position = proj * vec4(pos, 0.0, 1.0);\n"
206 " barycentric_coords = barycentric_coords_centroid =\n"
207 " in_barycentric_coords;\n"
208 " pixel_pos = pixel_pos_centroid =\n"
209 " vec2(viewport_size) * (pos + 1.0) / 2.0;\n"
212 /* Compile program */
213 prog
= glCreateProgram();
214 GLint vs
= piglit_compile_shader_text(GL_VERTEX_SHADER
, vert
);
215 glAttachShader(prog
, vs
);
216 GLint fs
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, frag
);
217 glAttachShader(prog
, fs
);
218 glBindAttribLocation(prog
, 0, "pos_within_tri");
219 glBindAttribLocation(prog
, 1, "in_barycentric_coords");
221 if (!piglit_link_check_status(prog
)) {
222 piglit_report_result(PIGLIT_FAIL
);
225 /* Set up uniforms */
227 glUniform1f(glGetUniformLocation(prog
, "tri_scale"), tri_scale
);
228 glUniform1f(glGetUniformLocation(prog
, "rotation_delta"),
230 glUniform1i(glGetUniformLocation(prog
, "tris_across"), tris_across
);
231 glUniform1f(glGetUniformLocation(prog
, "final_scale"), final_scale
);
232 proj_loc
= glGetUniformLocation(prog
, "proj");
233 tri_num_loc
= glGetUniformLocation(prog
, "tri_num");
234 viewport_size_loc
= glGetUniformLocation(prog
, "viewport_size");
236 /* Set up vertex array object */
237 glGenVertexArrays(1, &vao
);
238 glBindVertexArray(vao
);
240 /* Set up vertex input buffer */
241 glGenBuffers(1, &vertex_buf
);
242 glBindBuffer(GL_ARRAY_BUFFER
, vertex_buf
);
243 glBufferData(GL_ARRAY_BUFFER
, sizeof(vertex_data
), vertex_data
,
245 glEnableVertexAttribArray(0);
246 glVertexAttribPointer(0, ARRAY_SIZE(vertex_data
[0].pos_within_tri
),
247 GL_FLOAT
, GL_FALSE
, sizeof(vertex_data
[0]),
248 (void *) offsetof(vertex_attributes
,
250 glEnableVertexAttribArray(1);
251 glVertexAttribPointer(1, ARRAY_SIZE(vertex_data
[0].barycentric_coords
),
252 GL_FLOAT
, GL_FALSE
, sizeof(vertex_data
[0]),
253 (void *) offsetof(vertex_attributes
,
254 barycentric_coords
));
259 InterpolationTestPattern::draw(const float (*proj
)[4])
263 /* Depending what the fragment shader does, it's possible that
264 * viewport_size might get optimized away. Only set it if it
267 if (viewport_size_loc
!= -1) {
268 GLint viewport_dims
[4];
269 glGetIntegerv(GL_VIEWPORT
, viewport_dims
);
270 glUniform2i(viewport_size_loc
, viewport_dims
[2], viewport_dims
[3]);
273 Triangles::draw(proj
);
277 void Lines::compile()
279 /* Line coords within (-1,-1) to (1,1) rect */
280 static const float pos_line
[][2] = {
285 /* Number of line instances across (and down) */
286 int lines_across
= 4;
288 /* Total number of lines drawn */
289 num_lines
= lines_across
* lines_across
;
291 /* Amount each line should be rotated compared to prev */
292 float rotation_delta
= M_PI
* 2.0 / num_lines
;
294 /* Scaling factor uniformly applied to line coords */
295 float line_scale
= 0.8 / lines_across
;
297 /* Final scaling factor */
298 float final_scale
= 0.95;
300 static const char *vert
=
302 "attribute vec2 pos_line;\n"
303 "uniform float line_scale;\n"
304 "uniform float rotation_delta;\n"
305 "uniform int lines_across;\n"
306 "uniform float final_scale;\n"
307 "uniform mat4 proj;\n"
308 "uniform int line_num;\n"
312 " vec2 pos = line_scale * pos_line;\n"
313 " float rotation = rotation_delta * line_num;\n"
314 " pos = mat2(cos(rotation), sin(rotation),\n"
315 " -sin(rotation), cos(rotation)) * pos;\n"
316 " int i = int(mod(float(line_num), float(lines_across)));\n"
317 " int j = lines_across - 1 - line_num / lines_across;\n"
318 " pos += (vec2(i, j) * 2.0 + 1.0) / lines_across - 1.0;\n"
319 " pos *= final_scale;\n"
320 " gl_Position = proj * vec4(pos, 0.0, 1.0);\n"
323 static const char *frag
=
327 " gl_FragColor = vec4(1.0);\n"
330 /* Compile program */
331 prog
= glCreateProgram();
332 GLint vs
= piglit_compile_shader_text(GL_VERTEX_SHADER
, vert
);
333 glAttachShader(prog
, vs
);
334 GLint fs
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, frag
);
335 glAttachShader(prog
, fs
);
336 glBindAttribLocation(prog
, 0, "pos_line");
338 if (!piglit_link_check_status(prog
)) {
339 piglit_report_result(PIGLIT_FAIL
);
342 /* Set up uniforms */
344 glUniform1f(glGetUniformLocation(prog
, "line_scale"), line_scale
);
345 glUniform1f(glGetUniformLocation(prog
, "rotation_delta"),
347 glUniform1i(glGetUniformLocation(prog
, "lines_across"), lines_across
);
348 glUniform1f(glGetUniformLocation(prog
, "final_scale"), final_scale
);
349 proj_loc
= glGetUniformLocation(prog
, "proj");
350 line_num_loc
= glGetUniformLocation(prog
, "line_num");
352 /* Set up vertex array object */
353 glGenVertexArrays(1, &vao
);
354 glBindVertexArray(vao
);
356 /* Set up vertex input buffer */
357 glGenBuffers(1, &vertex_buf
);
358 glBindBuffer(GL_ARRAY_BUFFER
, vertex_buf
);
359 glBufferData(GL_ARRAY_BUFFER
, sizeof(pos_line
), pos_line
,
361 glEnableVertexAttribArray(0);
362 glVertexAttribPointer(0, ARRAY_SIZE(pos_line
[0]), GL_FLOAT
,
363 GL_FALSE
, sizeof(pos_line
[0]), (void *) 0);
366 void Lines::draw(const float (*proj
)[4])
368 glClear(GL_COLOR_BUFFER_BIT
);
370 glUniformMatrix4fv(proj_loc
, 1, GL_TRUE
, &proj
[0][0]);
371 glBindVertexArray(vao
);
372 for (int line_num
= 0; line_num
< num_lines
; ++line_num
) {
373 /* Draws with line width = 0.25, 0.75, 1.25,
374 * 1.75, 2.25, 2.75, 3.25, 3.75
376 glLineWidth((1 + 2 * line_num
) / 4.0);
377 glUniform1i(line_num_loc
, line_num
);
378 glDrawArrays(GL_LINES
, 0, 2);
382 void Points::compile()
384 /* Point coords within (-1,-1) to (1,1) rect */
385 static const float pos_point
[2] = { -0.5, -0.5 };
387 /* Number of point instances across (and down) */
388 int points_across
= 4;
390 /* Total number of points drawn */
391 num_points
= points_across
* points_across
;
393 /* Scaling factor uniformly applied to point coords */
394 float point_scale
= 0.8 / points_across
;
396 /* Final scaling factor */
397 float final_scale
= 0.95;
399 static const char *vert
=
401 "attribute vec2 pos_point;\n"
402 "uniform float point_scale;\n"
403 "uniform int points_across;\n"
404 "uniform float final_scale;\n"
405 "uniform mat4 proj;\n"
406 "uniform int point_num;\n"
407 "uniform float depth;\n"
411 " vec2 pos = point_scale * pos_point;\n"
412 " int i = int(mod(float(point_num), float(points_across)));\n"
413 " int j = points_across - 1 - point_num / points_across;\n"
414 " pos += (vec2(i, j) * 2.0 + 1.0) / points_across - 1.0;\n"
415 " pos *= final_scale;\n"
416 " gl_Position = proj * vec4(pos, depth, 1.0);\n"
419 static const char *frag
=
423 " gl_FragColor = vec4(1.0);\n"
426 /* Compile program */
427 prog
= glCreateProgram();
428 GLint vs
= piglit_compile_shader_text(GL_VERTEX_SHADER
, vert
);
429 glAttachShader(prog
, vs
);
430 GLint fs
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, frag
);
431 glAttachShader(prog
, fs
);
432 glBindAttribLocation(prog
, 0, "pos_point");
434 if (!piglit_link_check_status(prog
)) {
435 piglit_report_result(PIGLIT_FAIL
);
438 /* Set up uniforms */
440 glUniform1f(glGetUniformLocation(prog
, "point_scale"), point_scale
);
441 glUniform1i(glGetUniformLocation(prog
, "points_across"), points_across
);
442 glUniform1f(glGetUniformLocation(prog
, "final_scale"), final_scale
);
443 proj_loc
= glGetUniformLocation(prog
, "proj");
444 point_num_loc
= glGetUniformLocation(prog
, "point_num");
445 depth_loc
= glGetUniformLocation(prog
, "depth");
447 /* Set up vertex array object */
448 glGenVertexArrays(1, &vao
);
449 glBindVertexArray(vao
);
451 /* Set up vertex input buffer */
452 glGenBuffers(1, &vertex_buf
);
453 glBindBuffer(GL_ARRAY_BUFFER
, vertex_buf
);
454 glBufferData(GL_ARRAY_BUFFER
, sizeof(pos_point
), pos_point
,
456 glEnableVertexAttribArray(0);
457 glVertexAttribPointer(0, ARRAY_SIZE(pos_point
), GL_FLOAT
,
458 GL_FALSE
, 0, (void *) 0);
461 void Points::draw(const float (*proj
)[4])
463 glClear(GL_COLOR_BUFFER_BIT
);
465 glUniformMatrix4fv(proj_loc
, 1, GL_TRUE
, &proj
[0][0]);
466 glBindVertexArray(vao
);
467 glUniform1f(depth_loc
, 0.0);
468 for (int point_num
= 0; point_num
< num_points
; ++point_num
) {
469 glPointSize((1.0 + 4 * point_num
) / 4.0);
470 glUniform1i(point_num_loc
, point_num
);
471 glDrawArrays(GL_POINTS
, 0, 1);
476 : out_type(GL_UNSIGNED_NORMALIZED
),
477 compute_depth(false),
492 * Determine the GLSL type that should be used for rendering, based on
496 Sunburst::get_out_type_glsl() const
501 case GL_UNSIGNED_INT
:
503 case GL_UNSIGNED_NORMALIZED
:
507 printf("Unrecognized out_type: %s\n",
508 piglit_get_gl_enum_name(out_type
));
509 piglit_report_result(PIGLIT_FAIL
);
515 void Sunburst::compile()
517 static struct vertex_attributes
{
518 float pos_within_tri
[2];
519 float barycentric_coords
[3];
521 { { -0.3, -0.8 }, { 1, 0, 0 } },
522 { { 0.0, 1.0 }, { 0, 1, 0 } },
523 { { 0.3, -0.8 }, { 0, 0, 1 } }
525 bool need_glsl130
= out_type
== GL_INT
|| out_type
== GL_UNSIGNED_INT
;
528 piglit_require_gl_version(30);
531 /* Total number of triangles drawn */
534 static const char *vert_template
=
536 "attribute vec2 pos_within_tri;\n"
537 "attribute vec3 in_barycentric_coords;\n"
538 "varying vec3 barycentric_coords;\n"
539 "uniform float rotation;\n"
540 "uniform float vert_depth;\n"
541 "uniform mat4 proj;\n"
545 " vec2 pos = pos_within_tri;\n"
546 " pos = mat2(cos(rotation), sin(rotation),\n"
547 " -sin(rotation), cos(rotation)) * pos;\n"
548 " gl_Position = proj * vec4(pos, vert_depth, 1.0);\n"
549 " barycentric_coords = in_barycentric_coords;\n"
552 static const char *frag_template
=
554 "#define OUT_TYPE %s\n"
555 "#define COMPUTE_DEPTH %s\n"
556 "uniform float frag_depth;\n"
557 "varying vec3 barycentric_coords;\n"
558 "uniform mat3x4 draw_colors;\n"
559 "#if __VERSION__ == 130\n"
560 " out OUT_TYPE frag_out;\n"
565 "#if __VERSION__ == 130\n"
566 " frag_out = OUT_TYPE(draw_colors * barycentric_coords);\n"
568 " gl_FragColor = draw_colors * barycentric_coords;\n"
570 "#if COMPUTE_DEPTH\n"
571 " gl_FragDepth = (frag_depth + 1.0) / 2.0;\n"
575 /* Compile program */
576 prog
= glCreateProgram();
577 unsigned vert_alloc_len
=
578 strlen(vert_template
) + 4;
579 char *vert
= (char *) malloc(vert_alloc_len
);
580 sprintf(vert
, vert_template
, need_glsl130
? "130" : "120");
581 GLint vs
= piglit_compile_shader_text(GL_VERTEX_SHADER
, vert
);
583 glAttachShader(prog
, vs
);
585 const char *out_type_glsl
= get_out_type_glsl();
586 unsigned frag_alloc_len
=
587 strlen(frag_template
) + strlen(out_type_glsl
) + 4;
588 char *frag
= (char *) malloc(frag_alloc_len
);
589 sprintf(frag
, frag_template
, need_glsl130
? "130" : "120",
591 compute_depth
? "1" : "0");
592 GLint fs
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, frag
);
594 glAttachShader(prog
, fs
);
596 glBindAttribLocation(prog
, 0, "pos_within_tri");
597 glBindAttribLocation(prog
, 1, "in_barycentric_coords");
599 glBindFragDataLocation(prog
, 0, "frag_out");
602 if (!piglit_link_check_status(prog
)) {
603 piglit_report_result(PIGLIT_FAIL
);
606 /* Set up uniforms */
608 rotation_loc
= glGetUniformLocation(prog
, "rotation");
609 vert_depth_loc
= glGetUniformLocation(prog
, "vert_depth");
610 frag_depth_loc
= glGetUniformLocation(prog
, "frag_depth");
611 glUniform1f(vert_depth_loc
, 0.0);
612 glUniform1f(frag_depth_loc
, 0.0);
613 proj_loc
= glGetUniformLocation(prog
, "proj");
614 draw_colors_loc
= glGetUniformLocation(prog
, "draw_colors");
616 /* Set up vertex array object */
617 glGenVertexArrays(1, &vao
);
618 glBindVertexArray(vao
);
620 /* Set up vertex input buffer */
621 glGenBuffers(1, &vertex_buf
);
622 glBindBuffer(GL_ARRAY_BUFFER
, vertex_buf
);
623 glBufferData(GL_ARRAY_BUFFER
, sizeof(vertex_data
), vertex_data
,
625 glEnableVertexAttribArray(0);
626 glVertexAttribPointer(0, ARRAY_SIZE(vertex_data
[0].pos_within_tri
),
627 GL_FLOAT
, GL_FALSE
, sizeof(vertex_data
[0]),
629 glEnableVertexAttribArray(1);
630 glVertexAttribPointer(1, ARRAY_SIZE(vertex_data
[0].barycentric_coords
),
631 GL_FLOAT
, GL_FALSE
, sizeof(vertex_data
[0]),
632 (void *) offsetof(vertex_attributes
,
633 barycentric_coords
));
637 ColorGradientSunburst::ColorGradientSunburst(GLenum out_type
)
639 this->out_type
= out_type
;
644 * Draw the color gradient sunburst, but instead of using color
645 * components that range from 0.0 to 1.0, apply the given scaling
646 * factor and offset to each color component.
648 * The offset is also applied when clearing the color buffer.
651 ColorGradientSunburst::draw_with_scale_and_offset(const float (*proj
)[4],
652 float scale
, float offset
)
656 int clear_color
[4] = { offset
, offset
, offset
, offset
};
657 glClearBufferiv(GL_COLOR
, 0, clear_color
);
660 case GL_UNSIGNED_INT
: {
661 unsigned clear_color
[4] = { offset
, offset
, offset
, offset
};
662 glClearBufferuiv(GL_COLOR
, 0, clear_color
);
665 case GL_UNSIGNED_NORMALIZED
:
667 glClearColor(offset
, offset
, offset
, offset
);
668 glClear(GL_COLOR_BUFFER_BIT
);
672 printf("Unrecognized out_type: %s\n",
673 piglit_get_gl_enum_name(out_type
));
674 piglit_report_result(PIGLIT_FAIL
);
679 glUniformMatrix4fv(proj_loc
, 1, GL_TRUE
, &proj
[0][0]);
680 float draw_colors
[3][4] =
681 { { 1, 0, 0, 1.0 }, { 0, 1, 0, 0.5 }, { 0, 0, 1, 1.0 } };
682 for (int i
= 0; i
< 3; ++i
) {
683 for (int j
= 0; j
< 4; ++j
) {
684 draw_colors
[i
][j
] = scale
* draw_colors
[i
][j
] + offset
;
687 glUniformMatrix3x4fv(draw_colors_loc
, 1, GL_FALSE
,
689 glBindVertexArray(vao
);
690 for (int i
= 0; i
< num_tris
; ++i
) {
691 glUniform1f(rotation_loc
, M_PI
* 2.0 * i
/ num_tris
);
692 glDrawArrays(GL_TRIANGLES
, 0, 3);
698 ColorGradientSunburst::draw(const float (*proj
)[4])
700 draw_with_scale_and_offset(proj
, 1.0, 0.0);
705 StencilSunburst::draw(const float (*proj
)[4])
707 glEnable(GL_STENCIL_TEST
);
708 glStencilOp(GL_KEEP
, GL_KEEP
, GL_REPLACE
);
710 glClear(GL_COLOR_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
);
713 glUniformMatrix4fv(proj_loc
, 1, GL_TRUE
, &proj
[0][0]);
714 glBindVertexArray(vao
);
715 for (int i
= 0; i
< num_tris
; ++i
) {
716 glStencilFunc(GL_ALWAYS
, i
+1, 0xff);
717 glUniform1f(rotation_loc
, M_PI
* 2.0 * i
/ num_tris
);
718 glDrawArrays(GL_TRIANGLES
, 0, 3);
721 glDisable(GL_STENCIL_TEST
);
725 DepthSunburst::DepthSunburst(bool compute_depth
)
727 this->compute_depth
= compute_depth
;
732 DepthSunburst::draw(const float (*proj
)[4])
734 glEnable(GL_DEPTH_TEST
);
735 glDepthFunc(GL_LESS
);
737 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
740 glUniformMatrix4fv(proj_loc
, 1, GL_TRUE
, &proj
[0][0]);
741 glBindVertexArray(vao
);
742 for (int i
= 0; i
< num_tris
; ++i
) {
743 /* Draw triangles in a haphazard order so we can
744 * verify that depth comparisons sort them out
747 int triangle_to_draw
= (i
* 3) % num_tris
;
749 /* Note: with num_tris == 7, this causes us to draw
750 * triangles at depths of 3/4, 1/2, -1/4, 0, 1/4, 1/2,
753 glUniform1f(compute_depth
? frag_depth_loc
: vert_depth_loc
,
754 float(num_tris
- triangle_to_draw
* 2 - 1)
757 glUniform1f(rotation_loc
,
758 M_PI
* 2.0 * triangle_to_draw
/ num_tris
);
759 glDrawArrays(GL_TRIANGLES
, 0, 3);
762 glDisable(GL_DEPTH_TEST
);
767 ManifestStencil::compile()
769 static const char *vert
=
771 "attribute vec2 pos;\n"
774 " gl_Position = vec4(pos, 0.0, 1.0);\n"
777 static const char *frag
=
779 "uniform vec4 color;\n"
782 " gl_FragColor = color;\n"
785 /* Compile program */
786 prog
= glCreateProgram();
787 GLint vs
= piglit_compile_shader_text(GL_VERTEX_SHADER
, vert
);
788 glAttachShader(prog
, vs
);
789 GLint fs
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, frag
);
790 glAttachShader(prog
, fs
);
791 glBindAttribLocation(prog
, 0, "pos");
793 if (!piglit_link_check_status(prog
)) {
794 piglit_report_result(PIGLIT_FAIL
);
797 /* Set up uniforms */
799 color_loc
= glGetUniformLocation(prog
, "color");
801 /* Set up vertex array object */
802 glGenVertexArrays(1, &vao
);
803 glBindVertexArray(vao
);
805 /* Set up vertex input buffer */
806 float vertex_data
[4][2] = {
812 glGenBuffers(1, &vertex_buf
);
813 glBindBuffer(GL_ARRAY_BUFFER
, vertex_buf
);
814 glBufferData(GL_ARRAY_BUFFER
, sizeof(vertex_data
), vertex_data
,
816 glEnableVertexAttribArray(0);
817 glVertexAttribPointer(0, 2, GL_FLOAT
, GL_FALSE
, sizeof(vertex_data
[0]),
822 ManifestStencil::run()
824 static float colors
[8][4] = {
825 { 0.0, 0.0, 0.0, 1.0 },
826 { 0.0, 0.0, 1.0, 1.0 },
827 { 0.0, 1.0, 0.0, 1.0 },
828 { 0.0, 1.0, 1.0, 1.0 },
829 { 1.0, 0.0, 0.0, 1.0 },
830 { 1.0, 0.0, 1.0, 1.0 },
831 { 1.0, 1.0, 0.0, 1.0 },
832 { 1.0, 1.0, 1.0, 1.0 }
836 glBindVertexArray(vao
);
838 glEnable(GL_STENCIL_TEST
);
839 glStencilOp(GL_KEEP
, GL_KEEP
, GL_KEEP
);
841 /* Clear the color buffer to 0, in case the stencil buffer
842 * contains any values outside the range 0..7
844 glClear(GL_COLOR_BUFFER_BIT
);
846 for (int i
= 0; i
< 8; ++i
) {
847 glStencilFunc(GL_EQUAL
, i
, 0xff);
848 glUniform4fv(color_loc
, 1, colors
[i
]);
849 glDrawArrays(GL_TRIANGLE_STRIP
, 0, 4);
852 glDisable(GL_STENCIL_TEST
);
856 ManifestDepth::compile()
858 static const char *vert
=
860 "attribute vec2 pos;\n"
861 "uniform float depth;\n"
864 " gl_Position = vec4(pos, depth, 1.0);\n"
867 static const char *frag
=
869 "uniform vec4 color;\n"
872 " gl_FragColor = color;\n"
875 /* Compile program */
876 prog
= glCreateProgram();
877 GLint vs
= piglit_compile_shader_text(GL_VERTEX_SHADER
, vert
);
878 glAttachShader(prog
, vs
);
879 GLint fs
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, frag
);
880 glAttachShader(prog
, fs
);
881 glBindAttribLocation(prog
, 0, "pos");
883 if (!piglit_link_check_status(prog
)) {
884 piglit_report_result(PIGLIT_FAIL
);
887 /* Set up uniforms */
889 color_loc
= glGetUniformLocation(prog
, "color");
890 depth_loc
= glGetUniformLocation(prog
, "depth");
892 /* Set up vertex array object */
893 glGenVertexArrays(1, &vao
);
894 glBindVertexArray(vao
);
896 /* Set up vertex input buffer */
897 float vertex_data
[4][2] = {
903 glGenBuffers(1, &vertex_buf
);
904 glBindBuffer(GL_ARRAY_BUFFER
, vertex_buf
);
905 glBufferData(GL_ARRAY_BUFFER
, sizeof(vertex_data
), vertex_data
,
907 glEnableVertexAttribArray(0);
908 glVertexAttribPointer(0, 2, GL_FLOAT
, GL_FALSE
, sizeof(vertex_data
[0]),
915 static float colors
[8][4] = {
916 { 0.0, 0.0, 0.0, 1.0 },
917 { 0.0, 0.0, 1.0, 1.0 },
918 { 0.0, 1.0, 0.0, 1.0 },
919 { 0.0, 1.0, 1.0, 1.0 },
920 { 1.0, 0.0, 0.0, 1.0 },
921 { 1.0, 0.0, 1.0, 1.0 },
922 { 1.0, 1.0, 0.0, 1.0 },
923 { 1.0, 1.0, 1.0, 1.0 }
927 glBindVertexArray(vao
);
929 glEnable(GL_DEPTH_TEST
);
930 glDepthFunc(GL_LESS
);
931 glEnable(GL_STENCIL_TEST
);
932 glStencilOp(GL_KEEP
, GL_KEEP
, GL_INCR
);
933 glStencilFunc(GL_EQUAL
, 0, 0xff);
935 /* Clear the stencil buffer to 0, leaving depth and color
938 glClear(GL_STENCIL_BUFFER_BIT
);
940 for (int i
= 0; i
< 8; ++i
) {
941 glUniform4fv(color_loc
, 1, colors
[i
]);
942 glUniform1f(depth_loc
, float(7 - 2*i
)/8);
943 glDrawArrays(GL_TRIANGLE_STRIP
, 0, 4);
946 glDisable(GL_STENCIL_TEST
);
947 glDisable(GL_DEPTH_TEST
);