[Piglit] [PATCH] gl-3.2-adj-prims: new test of adjacency primitives with rendering options
Brian Paul
brianp at vmware.com
Fri May 27 16:02:38 UTC 2016
Test GL_LINES_ADJACENCY, GL_LINE_STRIP_ADJACENCY, GL_TRIANGLES_ADJACENCY
and GL_TRIANGLE_STRIP_ADJACENCY primitive rendering with several options:
- First and last provoking vertex
- Front and back-face culling
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
There's also a "ref" (reference) option that draws the primitive in
terms of regular lines/triangles so that the "extra" lines/triangles in
an adjacency primitive are displayed.
v2: call glBindAttribLocation() for "vertex" and "color", plus minor
clean-ups.
---
tests/all.py | 10 +
tests/spec/gl-3.2/CMakeLists.gl.txt | 1 +
tests/spec/gl-3.2/adj-prims.c | 800 ++++++++++++++++++++++++++++++++++++
3 files changed, 811 insertions(+)
create mode 100644 tests/spec/gl-3.2/adj-prims.c
diff --git a/tests/all.py b/tests/all.py
index cda2baa..a7b3120 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -1235,6 +1235,16 @@ with profile.group_manager(
g(['gl-3.2-basevertex-vertexid'],
'gl_VertexID used with glMultiDrawElementsBaseVertex')
g(['gl-3.2-minmax'], 'minmax')
+ g(['gl-3.2-adj-prims', 'pv-first'])
+ g(['gl-3.2-adj-prims', 'pv-last'])
+ g(['gl-3.2-adj-prims', 'cull-front pv-first'])
+ g(['gl-3.2-adj-prims', 'cull-front pv-last'])
+ g(['gl-3.2-adj-prims', 'cull-back pv-first'])
+ g(['gl-3.2-adj-prims', 'cull-back pv-last'])
+ g(['gl-3.2-adj-prims', 'line cull-front pv-first'])
+ g(['gl-3.2-adj-prims', 'line cull-front pv-last'])
+ g(['gl-3.2-adj-prims', 'line cull-back pv-first'])
+ g(['gl-3.2-adj-prims', 'line cull-back pv-last'])
g(['gl-3.2-clear-no-buffers'], 'clear-no-buffers')
g(['gl-3.2-depth-tex-sampling'], 'depth-tex-sampling')
g(['gl-3.2-get-buffer-parameter-i64v'], 'get-buffer-parameter-i64v')
diff --git a/tests/spec/gl-3.2/CMakeLists.gl.txt b/tests/spec/gl-3.2/CMakeLists.gl.txt
index c1c7811..bfd7cc4 100644
--- a/tests/spec/gl-3.2/CMakeLists.gl.txt
+++ b/tests/spec/gl-3.2/CMakeLists.gl.txt
@@ -8,6 +8,7 @@ link_libraries (
${OPENGL_gl_LIBRARY}
)
+piglit_add_executable (gl-3.2-adj-prims adj-prims.c)
piglit_add_executable (gl-3.2-minmax minmax.c)
piglit_add_executable (gl-3.2-basevertex-vertexid basevertex-vertexid.c)
piglit_add_executable (gl-3.2-clear-no-buffers clear-no-buffers.c)
diff --git a/tests/spec/gl-3.2/adj-prims.c b/tests/spec/gl-3.2/adj-prims.c
new file mode 100644
index 0000000..a215d60
--- /dev/null
+++ b/tests/spec/gl-3.2/adj-prims.c
@@ -0,0 +1,800 @@
+/*
+ * Copyright 2016 VMware, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/**
+ * Test rendering of GS adjacency primitives, with:
+ * - First and last provoking vertex
+ * - Front and back-face culling
+ * - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
+ * See code for command line arguments.
+ *
+ * Brian Paul
+ * May 2016
+ */
+
+
+#include "piglit-util-gl.h"
+#include "piglit-matrix.h"
+
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+ config.window_width = 800;
+ config.window_height = 200;
+ config.supports_gl_core_version = 32;
+ config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
+PIGLIT_GL_TEST_CONFIG_END
+
+
+#define VERTEX_SIZE (2 * sizeof(GLfloat))
+
+static const float gray[4] = { 0.5, 0.5, 0.5, 1.0 };
+static const float black[4] = { 0.0, 0.0, 0.0, 0.0 };
+
+static const float colors[18][4] = {
+ {1.0, 0.2, 0.2, 1.0},
+ {0.2, 1.0, 0.2, 1.0},
+ {0.2, 0.2, 1.0, 1.0},
+ {1.0, 1.0, 1.0, 1.0},
+ {0.2, 1.0, 1.0, 1.0},
+ {1.0, 0.2, 1.0, 1.0},
+ {1.0, 1.0, 0.2, 1.0},
+ {0.5, 1.0, 1.0, 1.0},
+ {1.0, 0.5, 1.0, 1.0},
+ {1.0, 1.0, 0.5, 1.0},
+ {0.7, 1.0, 1.0, 1.0},
+ {1.0, 0.7, 1.0, 1.0},
+ {1.0, 1.0, 0.7, 1.0},
+ {1.0, 0.2, 0.2, 1.0},
+ {0.2, 1.0, 0.2, 1.0},
+ {0.2, 0.2, 1.0, 1.0},
+ {1.0, 1.0, 1.0, 1.0},
+ {0.5, 0.5, 0.5, 1.0}
+};
+
+static const float lines_adj_verts[8][2] = {
+ // first line
+ {-1, -.75},
+ {-0.5, -0.25},
+ { 0.5, -0.25},
+ { 1.0, -.75},
+ // second line
+ {-1, 0.0},
+ {-0.5, 0.5},
+ { 0.5, 0.5},
+ { 1.0, 0.0}
+};
+
+static const float line_strip_adj_verts[7][2] = {
+ {-1.5, .3},
+ {-1, -.3},
+ {-0.5, .3},
+ { 0.0, -.3},
+ { 0.5, .3},
+ { 1.0, -.3},
+ { 1.5, .3},
+};
+
+static const float triangles_adj_verts[6][2] = {
+ {0, -.5},
+ {-1.2, 0},
+ {-.75, 1},
+ {0, 1.5},
+ {0.75, 1},
+ {1.2, 0},
+};
+
+static const float triangle_strip_adj_verts[][2] = {
+ {-1.5, -0.5}, // 0
+ {-1.9, 0.0}, // 1
+ {-1.5, 0.5}, // 2
+ {-1, -1}, // 3 *
+ {-1, -.5}, // 4
+ {-1.5, 1}, // 5 *
+ {-1, 0.5}, // 6
+ {-.5, -1}, // 7 *
+ {-.5, -.5}, // 8
+ {-1, 1}, // 9 *
+ {-.5, .5}, // 10
+ {0, -1}, // 11 *
+ {0, -.5}, // 12
+ {-.5, 1}, // 13 *
+ {0, 0.5}, // 14
+ {0.5, -1}, // 15 *
+ {0.5, -.5}, // 16
+ {1, 0}, // 17
+};
+
+#define NUM_VERTS(ARRAY) (sizeof(ARRAY) / VERTEX_SIZE)
+
+static GLfloat ortho_matrix[16];
+
+static GLuint lines_adj_vao;
+static GLuint line_strip_adj_vao;
+static GLuint triangles_adj_vao;
+static GLuint triangle_strip_adj_vao;
+
+static GLenum polygon_mode = GL_FILL;
+static GLenum cull_mode = GL_NONE;
+static GLenum provoking_vertex = GL_LAST_VERTEX_CONVENTION;
+
+static GLuint gs_lines_program;
+static GLuint gs_line_strip_program;
+static GLuint gs_triangles_program;
+static GLuint gs_triangle_strip_program;
+static GLuint ref_program;
+static GLint colorUniform, modelViewProjUniform;
+
+// if false, draw without GS, also draw the 'extra' lines/tris. For debugging.
+static bool draw_with_gs = true;
+
+
+/**
+ * Given a primitive type (adjacency type only), and the first/last provoking
+ * vertex mode, and a primitive (line, triangle) index, return the index of
+ * the vertex which will specify the primitive's flat-shaded color.
+ */
+static unsigned
+provoking_vertex_index(GLenum prim_mode, GLenum pv_mode, unsigned prim_index)
+{
+ switch (prim_mode) {
+ case GL_LINES_ADJACENCY:
+ if (pv_mode == GL_FIRST_VERTEX_CONVENTION)
+ return prim_index * 4 + 1;
+ else
+ return prim_index * 4 + 2;
+ case GL_LINE_STRIP_ADJACENCY:
+ if (pv_mode == GL_FIRST_VERTEX_CONVENTION)
+ return prim_index + 1;
+ else
+ return prim_index + 2;
+ case GL_TRIANGLES_ADJACENCY:
+ if (pv_mode == GL_FIRST_VERTEX_CONVENTION)
+ return prim_index * 6 + 0;
+ else
+ return prim_index * 6 + 4;
+ case GL_TRIANGLE_STRIP_ADJACENCY:
+ if (pv_mode == GL_FIRST_VERTEX_CONVENTION)
+ return prim_index * 2;
+ else
+ return prim_index * 2 + 4;
+ default:
+ assert(!"Unexpected prim_mode");
+ return 0;
+ }
+}
+
+
+/**
+ * Given a primitive type and a primitive (line/triangle) index, return
+ * the (x,y) screen coordinate for probing.
+ */
+static void
+compute_probe_location(GLenum prim_mode, unsigned prim_index,
+ const float verts[][2],
+ int vp_x, int vp_y, int *x, int *y)
+{
+ int i0, i1, i2 = -1;
+ float coord[4], ndc[4], win[3];
+
+ switch (prim_mode) {
+ case GL_LINES_ADJACENCY:
+ i0 = prim_index * 4 + 1;
+ i1 = prim_index * 4 + 2;
+ break;
+ case GL_LINE_STRIP_ADJACENCY:
+ i0 = prim_index + 1;
+ i1 = prim_index + 2;
+ break;
+ case GL_TRIANGLES_ADJACENCY:
+ i0 = prim_index * 6 + 0;
+ i1 = prim_index * 6 + 2;
+ if (polygon_mode != GL_LINE)
+ i2 = prim_index * 6 + 4;
+ break;
+ case GL_TRIANGLE_STRIP_ADJACENCY:
+ i0 = prim_index * 2;
+ i1 = prim_index * 2 + 2;
+ if (polygon_mode != GL_LINE)
+ i2 = prim_index * 2 + 4;
+ break;
+ default:
+ assert(!"Unexpected prim_mode");
+ *x = *y = 0;
+ return;
+ }
+
+ /* average of 2 or 3 points */
+ if (i2 == -1) {
+ coord[0] = (verts[i0][0] + verts[i1][0]) / 2.0;
+ coord[1] = (verts[i0][1] + verts[i1][1]) / 2.0;
+ } else {
+ coord[0] = (verts[i0][0] + verts[i1][0] + verts[i2][0]) / 3.0;
+ coord[1] = (verts[i0][1] + verts[i1][1] + verts[i2][1]) / 3.0;
+ }
+ coord[2] = 0.0;
+ coord[3] = 1.0;
+
+ piglit_matrix_mul_vector(ndc, ortho_matrix, coord);
+ piglit_ndc_to_window(win, ndc, vp_x, vp_y,
+ piglit_width/4, piglit_height);
+
+ *x = (int) win[0];
+ *y = (int) win[1];
+}
+
+
+/**
+ * Do the colors match, within an epsilon?
+ */
+static bool
+colors_match(const float c1[4], const float c2[4])
+{
+ const float epsilon = 1.0 / 256.0;
+
+ if (fabs(c1[0] - c2[0]) > epsilon ||
+ fabs(c1[1] - c2[1]) > epsilon ||
+ fabs(c1[2] - c2[2]) > epsilon ||
+ fabs(c1[3] - c2[3]) > epsilon)
+ return false;
+ else
+ return true;
+}
+
+
+/**
+ * Given a primitive type and a number of vertices, return the number of
+ * primitives (lines/tris) that'll be drawn.
+ */
+static unsigned
+num_gs_prims(GLenum prim_mode, unsigned num_verts)
+{
+ switch (prim_mode) {
+ case GL_LINES_ADJACENCY:
+ assert(num_verts % 4 == 0);
+ return num_verts / 4;
+ case GL_LINE_STRIP_ADJACENCY:
+ assert(num_verts >= 4);
+ return num_verts - 3;
+ case GL_TRIANGLES_ADJACENCY:
+ assert(num_verts % 6 == 0);
+ return num_verts / 6;
+ case GL_TRIANGLE_STRIP_ADJACENCY:
+ assert(num_verts >= 6);
+ return (num_verts - 4) / 2;
+ default:
+ assert(!"Unexpected prim_mode");
+ return 0;
+ }
+}
+
+
+/**
+ * Check if a primitive strip was rendered correctly by doing color probing.
+ * vp_pos is the viewport position (0..3).
+ */
+static bool
+probe_prims(GLenum prim_mode, const float verts[][2], unsigned num_verts,
+ unsigned vp_pos)
+{
+ const int vp_w = piglit_width / 4;
+ const unsigned num_prims = num_gs_prims(prim_mode, num_verts);
+ unsigned prim;
+
+ for (prim = 0; prim < num_prims; prim++) {
+ bool pass = false;
+ const float *expected_color = NULL, *bad_color = NULL;
+ int x, y, i;
+
+ compute_probe_location(prim_mode, prim, verts,
+ vp_pos * vp_w, 0, &x, &y);
+
+ if (cull_mode == GL_FRONT &&
+ (prim_mode == GL_TRIANGLES_ADJACENCY ||
+ prim_mode == GL_TRIANGLE_STRIP_ADJACENCY)) {
+ // All triangles should be front facing.
+ // With front culling, all should be discarded.
+ // Region should be black.
+ if (piglit_probe_rect_rgba(x-1, y-1, 3, 3, black)) {
+ pass = true;
+ }
+ } else {
+ GLfloat buf[9][4];
+ unsigned pvi = provoking_vertex_index(prim_mode,
+ provoking_vertex, prim);
+ expected_color = colors[pvi];
+
+ // Read a 3x3 region for line probing
+ glReadPixels(x-1, y-1, 3, 3, GL_RGBA, GL_FLOAT, buf);
+
+ // look for non-black pixel
+ for (i = 0; i < 9; i++) {
+ if (buf[i][0] != 0 || buf[i][1] != 0 ||
+ buf[i][2] != 0 || buf[i][3] != 0) {
+ // check for expected color
+ if (colors_match(expected_color, buf[i]))
+ pass = true;
+ else
+ bad_color = buf[i];
+ }
+ }
+ }
+
+ if (!pass) {
+ printf("Failure for %s, "
+ "prim %u wrong color at (%d,%d)\n",
+ piglit_get_prim_name(prim_mode), prim, x, y);
+ if (expected_color && bad_color) {
+ printf("Expected %.1g, %.1g, %.1g, %.1g\n",
+ expected_color[0],
+ expected_color[1],
+ expected_color[2],
+ expected_color[3]);
+ printf("Found %.1g, %.1g, %.1g, %.1g\n",
+ bad_color[0],
+ bad_color[1],
+ bad_color[2],
+ bad_color[3]);
+ }
+
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+
+static GLuint
+make_gs_program(GLenum input_prim)
+{
+ static const char *vs_text =
+ "#version 150 \n"
+ "in vec4 vertex; \n"
+ "in vec4 color; \n"
+ "uniform mat4 modelViewProj; \n"
+ "out vec4 pos;\n"
+ "out vec4 vs_gs_color; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = vertex * modelViewProj; \n"
+ " pos = vertex * modelViewProj; \n"
+ " vs_gs_color = color; \n"
+ "} \n";
+ static const char *gs_text_lines =
+ "#version 150 \n"
+ "layout(lines_adjacency) in;\n"
+ "layout(line_strip, max_vertices = 2) out;\n"
+ "in vec4 pos[]; \n"
+ "in vec4 vs_gs_color[4]; \n"
+ "flat out vec4 gs_fs_color; \n"
+ "void main() \n"
+ "{ \n"
+ " gs_fs_color = vs_gs_color[1]; \n"
+ " gl_Position = pos[1]; \n"
+ " EmitVertex(); \n"
+ " gs_fs_color = vs_gs_color[2]; \n"
+ " gl_Position = pos[2]; \n"
+ " EmitVertex(); \n"
+ " EndPrimitive(); \n"
+ "} \n";
+ static const char *gs_text_triangles =
+ "#version 150 \n"
+ "layout(triangles_adjacency) in;\n"
+ "layout(triangle_strip, max_vertices = 3) out;\n"
+ "in vec4 pos[]; \n"
+ "in vec4 vs_gs_color[6]; \n"
+ "flat out vec4 gs_fs_color; \n"
+ "void main() \n"
+ "{ \n"
+ " gs_fs_color = vs_gs_color[0]; \n"
+ " gl_Position = pos[0]; \n"
+ " EmitVertex(); \n"
+ " gs_fs_color = vs_gs_color[2]; \n"
+ " gl_Position = pos[2]; \n"
+ " EmitVertex(); \n"
+ " gs_fs_color = vs_gs_color[4]; \n"
+ " gl_Position = pos[4]; \n"
+ " EmitVertex(); \n"
+ " //EndPrimitive(); \n"
+ "} \n";
+ static const char *fs_text =
+ "#version 150 \n"
+ "flat in vec4 gs_fs_color; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = gs_fs_color; \n"
+ "} \n";
+ const char *gs_text;
+ GLuint program;
+
+ switch (input_prim) {
+ case GL_LINES_ADJACENCY:
+ case GL_LINE_STRIP_ADJACENCY:
+ gs_text = gs_text_lines;
+ break;
+ case GL_TRIANGLES_ADJACENCY:
+ case GL_TRIANGLE_STRIP_ADJACENCY:
+ gs_text = gs_text_triangles;
+ break;
+ }
+
+ program = piglit_build_simple_program_unlinked_multiple_shaders(
+ GL_VERTEX_SHADER, vs_text,
+ GL_GEOMETRY_SHADER, gs_text,
+ GL_FRAGMENT_SHADER, fs_text,
+ 0);
+
+ assert(program);
+
+ glBindAttribLocation(program, 0, "vertex");
+ glBindAttribLocation(program, 1, "color");
+
+ glLinkProgram(program);
+
+ return program;
+}
+
+
+static GLuint
+make_ref_program(void)
+{
+ static const char *vs_text =
+ "#version 150 \n"
+ "in vec4 vertex; \n"
+ "uniform vec4 color; \n"
+ "uniform mat4 modelViewProj; \n"
+ "out vec4 vs_fs_color; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = vertex * modelViewProj; \n"
+ " vs_fs_color = color; \n"
+ "} \n";
+
+ static const char *fs_text =
+ "#version 150 \n"
+ "in vec4 vs_fs_color; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = vs_fs_color; \n"
+ "} \n";
+
+ GLuint program = piglit_build_simple_program_unlinked_multiple_shaders(
+ GL_VERTEX_SHADER, vs_text,
+ GL_FRAGMENT_SHADER, fs_text,
+ 0);
+
+ glBindAttribLocation(program, 0, "vertex");
+ glBindAttribLocation(program, 1, "color");
+
+ glLinkProgram(program);
+
+ return program;
+}
+
+
+static void
+draw_elements3(GLenum mode, unsigned v0, unsigned v1, unsigned v2)
+{
+ GLushort elements[3];
+ elements[0] = v0;
+ elements[1] = v1;
+ elements[2] = v2;
+ glDrawElements(mode, 3, GL_UNSIGNED_SHORT, elements);
+}
+
+
+static void
+set_color(const GLfloat c[4])
+{
+ glUniform4fv(colorUniform, 1, c);
+}
+
+
+static void
+draw_lines_adj(GLuint vao, unsigned n)
+{
+ assert(n % 4 == 0);
+
+ glBindVertexArray(vao);
+ {
+ unsigned i;
+ for (i = 0; i < n; i += 4) {
+ unsigned pvi =
+ provoking_vertex_index(GL_LINES_ADJACENCY,
+ provoking_vertex, i/4);
+ set_color(gray);
+
+ // draw preceeding "wing" line
+ glDrawArrays(GL_LINES, i, 2);
+ // draw trailing "wing" line
+ glDrawArrays(GL_LINES, i+2, 2);
+
+ set_color(colors[pvi]);
+ // draw "real" line
+ glDrawArrays(GL_LINES, i+1, 2);
+ }
+ }
+}
+
+
+static void
+draw_line_strip_adj(GLuint vao, unsigned n)
+{
+ unsigned i;
+
+ assert(n >= 4);
+
+ glBindVertexArray(vao);
+
+ set_color(gray);
+ glDrawArrays(GL_LINES, 0, 2);
+ glDrawArrays(GL_LINES, n-2, 2);
+
+ for (i = 1; i < n-2; i++) {
+ unsigned pvi =
+ provoking_vertex_index(GL_LINE_STRIP_ADJACENCY,
+ provoking_vertex, i-1);
+ set_color(colors[pvi]);
+ glDrawArrays(GL_LINES, i, 2);
+ }
+}
+
+
+static void
+draw_triangles_adj(GLuint vao, unsigned n)
+{
+ unsigned i;
+
+ assert(n % 6 == 0);
+
+ glBindVertexArray(vao);
+
+ for (i = 0; i < n; i += 6) {
+ unsigned pvi =
+ provoking_vertex_index(GL_TRIANGLES_ADJACENCY,
+ provoking_vertex, i/6);
+
+ // draw gray outlines of "wing" triangles
+ set_color(gray);
+ draw_elements3(GL_LINE_LOOP, i, i+1, i+2);
+ draw_elements3(GL_LINE_LOOP, i+2, i+3, i+4);
+ draw_elements3(GL_LINE_LOOP, i, i+4, i+5);
+
+ // draw "real" triangle
+ set_color(colors[pvi]);
+ draw_elements3(GL_TRIANGLES, i, i+2, i+4);
+ }
+}
+
+
+static void
+draw_triangle_strip_adj(GLuint vao, unsigned n)
+{
+ unsigned i;
+
+ assert(n >= 6);
+
+ glBindVertexArray(vao);
+
+ // draw first "wing" triangle
+ set_color(gray);
+ glDrawArrays(GL_LINE_LOOP, 0, 3);
+
+ for (i = 0; i < n-4; i += 2) {
+ unsigned pvi =
+ provoking_vertex_index(GL_TRIANGLE_STRIP_ADJACENCY,
+ provoking_vertex, i/2);
+
+ if (i % 4 == 2) {
+ // even tri
+ set_color(gray);
+ draw_elements3(GL_LINE_LOOP, i, i+3, i+4);
+ set_color(colors[pvi]);
+ draw_elements3(GL_TRIANGLES, i, i+4, i+2);
+ }
+ else {
+ // odd tri
+ set_color(gray);
+ draw_elements3(GL_LINE_LOOP, i, i+4, i+3);
+ set_color(colors[pvi]);
+ draw_elements3(GL_TRIANGLES, i, i+2, i+4);
+ }
+ }
+
+ // draw last "wing" triangle
+ set_color(gray);
+ draw_elements3(GL_LINE_LOOP, i, i+2, i+3);
+}
+
+
+static void
+use_program(GLuint program)
+{
+ glUseProgram(program);
+ modelViewProjUniform = glGetUniformLocation(program, "modelViewProj");
+ colorUniform = glGetUniformLocation(program, "color");
+
+ piglit_ortho_matrix(ortho_matrix, -2, 2, -2, 2, -1, 1);
+ glUniformMatrix4fv(modelViewProjUniform, 1, GL_FALSE, ortho_matrix);
+}
+
+
+static void
+set_viewport(unsigned pos)
+{
+ int vp_w = piglit_width / 4;
+ assert(pos < 4);
+ glViewport(pos * vp_w, 0, vp_w, piglit_height);
+}
+
+
+enum piglit_result
+piglit_display(void)
+{
+ bool pass = true;
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ if (draw_with_gs) {
+ use_program(gs_lines_program);
+ set_viewport(0);
+ glBindVertexArray(lines_adj_vao);
+ glDrawArrays(GL_LINES_ADJACENCY, 0,
+ NUM_VERTS(lines_adj_verts));
+
+ use_program(gs_line_strip_program);
+ set_viewport(1);
+ glBindVertexArray(line_strip_adj_vao);
+ glDrawArrays(GL_LINE_STRIP_ADJACENCY, 0,
+ NUM_VERTS(line_strip_adj_verts));
+
+ use_program(gs_triangles_program);
+ set_viewport(2);
+ glBindVertexArray(triangles_adj_vao);
+ glDrawArrays(GL_TRIANGLES_ADJACENCY, 0,
+ NUM_VERTS(triangles_adj_verts));
+
+ use_program(gs_triangle_strip_program);
+ set_viewport(3);
+ glBindVertexArray(triangle_strip_adj_vao);
+ glDrawArrays(GL_TRIANGLE_STRIP_ADJACENCY, 0,
+ NUM_VERTS(triangle_strip_adj_verts));
+ }
+ else {
+ /* This path is basically for debugging and visualizing the
+ * "extra" lines and tris in adjacency primitives.
+ */
+ use_program(ref_program);
+
+ set_viewport(0);
+ draw_lines_adj(lines_adj_vao, 8);
+
+ set_viewport(1);
+ draw_line_strip_adj(line_strip_adj_vao, 7);
+
+ set_viewport(2);
+ draw_triangles_adj(triangles_adj_vao, 6);
+
+ set_viewport(3);
+ draw_triangle_strip_adj(triangle_strip_adj_vao, 17);
+ }
+
+ /* check the rendering */
+ pass = probe_prims(GL_LINES_ADJACENCY,
+ lines_adj_verts,
+ NUM_VERTS(lines_adj_verts), 0) && pass;
+
+ pass = probe_prims(GL_LINE_STRIP_ADJACENCY,
+ line_strip_adj_verts,
+ NUM_VERTS(line_strip_adj_verts), 1) && pass;
+
+ pass = probe_prims(GL_TRIANGLES_ADJACENCY,
+ triangles_adj_verts,
+ NUM_VERTS(triangles_adj_verts), 2) && pass;
+
+ pass = probe_prims(GL_TRIANGLE_STRIP_ADJACENCY,
+ triangle_strip_adj_verts,
+ NUM_VERTS(triangle_strip_adj_verts), 3) && pass;
+
+ piglit_present_results();
+
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+
+static GLuint
+create_vao(const GLfloat (*verts)[2], GLuint numVerts)
+{
+ GLuint vao, vbo;
+
+ glGenVertexArrays(1, &vao);
+ glBindVertexArray(vao);
+
+ // positions
+ glGenBuffers(1, &vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, numVerts * VERTEX_SIZE,
+ verts, GL_STATIC_DRAW);
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, VERTEX_SIZE, NULL);
+ glEnableVertexAttribArray(0);
+
+ // colors
+ glGenBuffers(1, &vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
+ glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), NULL);
+ glEnableVertexAttribArray(1);
+
+ return vao;
+}
+
+
+void
+piglit_init(int argc, char **argv)
+{
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "line") == 0)
+ polygon_mode = GL_LINE;
+ else if (strcmp(argv[i], "cull-back") == 0)
+ cull_mode = GL_BACK;
+ else if (strcmp(argv[i], "cull-front") == 0)
+ cull_mode = GL_FRONT;
+ else if (strcmp(argv[i], "ref") == 0)
+ draw_with_gs = GL_FALSE;
+ else if (strcmp(argv[i], "pv-last") == 0)
+ provoking_vertex = GL_LAST_VERTEX_CONVENTION;
+ else if (strcmp(argv[i], "pv-first") == 0)
+ provoking_vertex = GL_FIRST_VERTEX_CONVENTION;
+ else
+ printf("Unexpected %s argument\n", argv[i]);
+ }
+
+ glPolygonMode(GL_FRONT_AND_BACK, polygon_mode);
+ if (cull_mode != GL_NONE) {
+ glCullFace(cull_mode);
+ glEnable(GL_CULL_FACE);
+ glFrontFace(GL_CW);
+ }
+ glProvokingVertex(provoking_vertex);
+
+ lines_adj_vao = create_vao(lines_adj_verts,
+ NUM_VERTS(lines_adj_verts));
+
+ line_strip_adj_vao = create_vao(line_strip_adj_verts,
+ NUM_VERTS(line_strip_adj_verts));
+
+ triangles_adj_vao = create_vao(triangles_adj_verts,
+ NUM_VERTS(triangles_adj_verts));
+
+ triangle_strip_adj_vao = create_vao(triangle_strip_adj_verts,
+ NUM_VERTS(triangle_strip_adj_verts));
+
+ gs_lines_program = make_gs_program(GL_LINES_ADJACENCY);
+ gs_line_strip_program = make_gs_program(GL_LINE_STRIP_ADJACENCY);
+ gs_triangles_program = make_gs_program(GL_TRIANGLES_ADJACENCY);
+ gs_triangle_strip_program = make_gs_program(GL_TRIANGLE_STRIP_ADJACENCY);
+ ref_program = make_ref_program();
+}
--
1.9.1
More information about the Piglit
mailing list