---
 tests/spec/gl-1.0/CMakeLists.gl.txt |   1 +
 tests/spec/gl-1.0/orthpos.c         | 689 ++++++++++++++++++++++++++++++++++++
 2 files changed, 690 insertions(+)
 create mode 100644 tests/spec/gl-1.0/orthpos.c

diff --git a/tests/spec/gl-1.0/CMakeLists.gl.txt 
b/tests/spec/gl-1.0/CMakeLists.gl.txt
index 8726cf2..1ed735d 100644
--- a/tests/spec/gl-1.0/CMakeLists.gl.txt
+++ b/tests/spec/gl-1.0/CMakeLists.gl.txt
@@ -21,6 +21,7 @@ piglit_add_executable (gl-1.0-rendermode-feedback 
rendermode-feedback.c)
 piglit_add_executable (gl-1.0-swapbuffers-behavior swapbuffers-behavior.c)
 piglit_add_executable (gl-1.0-polygon-line-aa polygon-line-aa.c)
 piglit_add_executable (gl-1.0-blend-func blend.c)
+piglit_add_executable (gl-1.0-ortho-pos orthpos.c)
 piglit_add_executable (gl-1.0-fpexceptions fpexceptions.c)
 
 # vim: ft=cmake:
diff --git a/tests/spec/gl-1.0/orthpos.c b/tests/spec/gl-1.0/orthpos.c
new file mode 100644
index 0000000..9dcf750
--- /dev/null
+++ b/tests/spec/gl-1.0/orthpos.c
@@ -0,0 +1,689 @@
+/*
+ * BEGIN_COPYRIGHT -*- glean -*-
+ * 
+ * Copyright (C) 2000  Allen Akin   All Rights Reserved.
+ * 
+ * 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 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 ALLEN AKIN 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.
+ * 
+ * END_COPYRIGHT
+ */
+
+/*
+ * Copyright 2014 Intel Corporation
+ *
+ * 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.
+ */
+
+/** @file orthopos.c
+ * 
+ *  Test positioning of primitives in orthographic projection.
+ *
+ *  Some applications use OpenGL extensively for 2D rendering:  portable
+ *  GUI toolkits, heads-up display generators, etc.  These apps require
+ *  primitives to be drawn with reliable position and size in orthographic
+ *  projections.  There are some potential pitfalls; for a good discussion,
+ *  see the OpenGL Programming Guide (the Red Book).  In the second edition,
+ *  see the OpenGL Correctness Tips on page 601.
+ */
+
+#include "piglit-util-gl.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define window_size piglit_width
+#define drawing_size window_size - 2
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+       config.supports_gl_compat_version = 13;
+
+       config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+struct orthpos_result {
+       bool has_gaps, has_overlaps, has_bad_edges;
+};
+
+static int img_bytes;
+static GLubyte* img;
+
+void
+piglit_init(int argc, char **argv)
+{
+       srand(0);
+       img_bytes = window_size * window_size * 
+               piglit_num_components(GL_RGB) * sizeof(GLubyte);
+       img = malloc(img_bytes);
+
+       /* Common setup */
+       piglit_ortho_projection(window_size, window_size, GL_FALSE);
+       glTranslatef(0.375f, 0.375f, 0);
+
+       glFrontFace(GL_CCW);
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+       glEnable(GL_BLEND);
+       glDisable(GL_DITHER);
+       glCullFace(GL_BACK);
+       glEnable(GL_CULL_FACE);
+       glShadeModel(GL_FLAT);
+}
+
+bool
+log_results(const char* title, struct orthpos_result* r) {
+       bool pass = true;
+       printf("\t%s: ", title);
+       if (r->has_gaps || r->has_overlaps || r->has_bad_edges) {
+               printf("%s %s %s\n", (r->has_gaps? "Gaps.": ""),
+                       (r->has_overlaps? " Overlaps.": ""),
+                       (r->has_bad_edges? " Incorrect edges.": ""));
+               pass = false;
+       } else {
+               printf(" No gaps, overlaps, or incorrect edges.\n");
+       }
+       return pass;
+} /* log_results */
+
+GLubyte
+logical_sum(GLubyte* start, int stride, int count) {
+       GLubyte* p = start;
+       GLubyte sum = 0;
+       int i;
+       for (i = 0; i < count; ++i) {
+               sum |= p[0];
+               sum |= p[1];
+               sum |= p[2];
+               p += stride;
+       }
+       return sum;
+}
+
+bool
+verify_orth_pos(const GLubyte* img, GLsizei img_row_size_in_bytes, 
+       const char* title) {
+
+       /*
+        * All of the tests in this group are constructed so that the
+        * "correct" image covers a square of exactly drawing_size by
+        * drawing_size pixels, embedded in a window that's two pixels
+        * larger in both dimensions.  The border consists of pixels
+        * with all components set to zero.  Within the image, all
+        * pixels should be either red (only the red component is
+        * nonzero) or green (only the green component is nonzero).  If
+        * any pixels with all zero components are found, that indicates
+        * the presence of gaps.  If any pixels with both red and green
+        * nonzero components are found, that indicates the presence of
+        * overlaps.
+        */
+
+       /* For logging results */
+       struct orthpos_result res;
+
+       /* For examining edges */
+       GLubyte* row0 = (GLubyte*) img;
+       GLubyte* row1 = row0 + img_row_size_in_bytes;
+       GLubyte* row_last = row0 + (window_size - 1) * img_row_size_in_bytes;
+       GLubyte* row_next_last = row_last - img_row_size_in_bytes;
+
+       /* For examining the drawing area */
+       int i, j, idx;
+       GLubyte red, green, blue;
+
+       /* Initialize results */
+       res.has_gaps = false;
+       res.has_overlaps = false;
+       res.has_bad_edges = false;
+
+       /* Check the bottom horizontal edge; it must be all zero. */
+       if (logical_sum(row0, 3, window_size)) {
+               printf("\t%s:  bottom border (at Y==0) was touched\n", title);
+               res.has_bad_edges = true;
+       }
+       /* Repeat the process for the top horizontal edge. */
+       if (logical_sum(row_last, 3, window_size)) {
+               printf("\t%s:  top border (at Y==%i) was touched\n",
+                       title, window_size - 1);
+               res.has_bad_edges = true;
+       }
+       /*
+        * Check the second row; there must be at least one nonzero
+        * pixel in the "drawn" region (excluding the first and last
+        * column).
+        */
+       if (!logical_sum(row1 + 3/*skip first pixel's RGB*/, 3, drawing_size)) {
+               printf("\t%s:  first row (at Y==1) was not drawn\n", title);
+               res.has_bad_edges = true;
+       }
+       /* Repeat the process for the last row. */
+       if (!logical_sum(row_next_last + 3, 3, drawing_size)) {
+               printf("\t%s:  last row (at Y==%i) was not drawn\n",
+                       title, window_size - 2);
+               res.has_bad_edges = true;
+       }
+
+       /* Check the left-hand vertical edge; it must be all zero. */
+       if (logical_sum(row0, img_row_size_in_bytes, window_size)) {
+               printf("\t%s:  left border (at X==0) was touched\n", title);
+               res.has_bad_edges = true;
+       }
+       /* Repeat for the right-hand vertical edge. */
+       if (logical_sum(row0 + 3 * (window_size - 1), img_row_size_in_bytes,
+           window_size)) {
+               printf("\t%s:  right border (at X==%i) was touched\n",
+                       title, window_size - 1);
+               res.has_bad_edges = true;
+       }
+       /* Check the left-hand column; something must be nonzero. */
+       if (!logical_sum(row1 + 3, img_row_size_in_bytes, drawing_size)) {
+               printf("\t%s:  first column (at X==1) was not drawn\n", title);
+               res.has_bad_edges = true;
+       }
+       /* And repeat for the right-hand column: */
+       if (!logical_sum(row1 + 3 * (drawing_size - 1), img_row_size_in_bytes,
+           drawing_size)) {
+               printf("\t%s:  last column (at X==%i) was not drawn\n",
+                       title, window_size - 2);
+               res.has_bad_edges = true;
+       }
+       
+       /*
+        * Scan the drawing area.  Anytime we find a pixel with all zero
+        * components, that's a gap.  Anytime we find a pixel with both
+        * red and green components nonzero, that's an overlap.
+        */
+       /* Not sure what was wrong with the original, but this works. */
+       for (i = 1; i < window_size - 1; ++i) {
+               for (j = 1; j < window_size - 1; ++j) {
+                       idx = 3*(window_size*i + j);
+                       red = img[idx + 0];
+                       green = img[idx + 1];
+                       blue = img[idx + 2];
+
+                       if (!red && !green && !blue) {
+                               if (!res.has_gaps) {
+                                       printf("\t%s:  found first gap at 
X==%i, Y==%i\n",
+                                               title, j, i);
+                                       res.has_gaps = true;
+                               }
+                       }
+                       if (red && green) {
+                               if (!res.has_overlaps) {
+                                       printf("\t%s:  found first overlap at 
X==%i, Y==%i\n",
+                                               title, j + 1, i + 1);
+                                       res.has_overlaps = true;
+                               }
+                       }
+               }
+       }
+
+       return log_results(title, &res);
+} /* verify_orth_pos */
+
+void
+subdivide_rects(int minx, int maxx, int miny, int maxy,
+    bool split_horiz, bool draw_in_red) {
+       /*
+        * Basically we're just splitting the input rectangle
+        * recursively.  At each step we alternate between splitting
+        * horizontally (dividing along Y) or vertically (along X).  We
+        * also toggle colors (between red and green) at various times,
+        * in order to give us some adjacent edges of different colors
+        * that we can check for overlaps.  Recursion bottoms out when
+        * the axis of interest drops below 30 pixels in length.
+        */
+       int split;
+
+       int min = split_horiz? miny: minx;
+       int max = split_horiz? maxy: maxx;
+       if (min + 30 > max) {
+               glColor4f(draw_in_red? 1.0: 0.0, draw_in_red? 0.0: 1.0,
+                       0.0, 0.5);
+               glBegin(GL_QUADS);
+               glVertex2i(minx, miny);
+               glVertex2i(maxx, miny);
+               glVertex2i(maxx, maxy);
+               glVertex2i(minx, maxy);
+               glEnd();
+               return;
+       }
+
+       split = min + (int) ((max - min) * 
+               ((float) rand() / RAND_MAX)); /* Float in range [0.0f, 1.0f] */
+       if (split_horiz) {
+               subdivide_rects(minx, maxx, miny, split,
+                       !split_horiz, draw_in_red);
+               subdivide_rects(minx, maxx, split, maxy,
+                       !split_horiz, !draw_in_red);
+       } else {
+               subdivide_rects(minx, split, miny, maxy,
+                       !split_horiz, draw_in_red);
+               subdivide_rects(split, maxx, miny, maxy,
+                       !split_horiz, !draw_in_red);
+       }
+}
+
+/**
+ * This test checks the positioning of unit-sized points under
+ * orthographic projection.  (This is important for apps that
+ * want to use OpenGL for precise 2D drawing.)  It fills in an
+ * entire rectangle one pixel at a time, drawing adjacent pixels
+ * with different colors and with blending enabled.  If there are
+ * gaps (pixels that are the background color, and thus haven't
+ * been filled), overlaps (pixels that show a blend of more than
+ * one color), or improper edges (pixels around the edge of the
+ * rectangle that haven't been filled, or pixels just outside the
+ * edge that have), then the test fails.
+ * 
+ * This test generally fails for one of several reasons.  First,
+ * the coordinate transformation process may have an incorrect bias;
+ * this usually will cause a bad edge.  Second, the coordinate
+ * transformation process may round pixel coordinates incorrectly;
+ * this will usually cause gaps and/or overlaps.  Third, the point
+ * rasterization process may not be filling the correct pixels;
+ * this can cause gaps, overlaps, or bad edges.
+ */
+
+bool
+ortho_pos_points() {
+       int x, y;
+
+       /* Draw the image */
+       glClear(GL_COLOR_BUFFER_BIT);
+       glBegin(GL_POINTS);
+       for (x = 1; x <= drawing_size; ++x) {
+               for (y = 1; y <= drawing_size; ++y) {
+                       if ((x ^ y) & 1) {
+                               glColor4f(0.0, 1.0, 0.0, 0.5);
+                       }
+                       else {
+                               glColor4f(1.0, 0.0, 0.0, 0.5);
+                       }
+                       glVertex2i(x, y);
+               }
+       }
+       glEnd();
+
+       /* Read the image */
+       glReadPixels(0, 0, window_size, window_size, GL_RGB, GL_UNSIGNED_BYTE, 
img);
+
+       /* Show the image */
+       if (!piglit_automatic) {
+               piglit_present_results();
+       }
+
+       /* Check the results */
+       return verify_orth_pos(img, img_bytes/window_size, "Immediate-mode 
points");
+} /* ortho_pos_points */
+
+/**
+ * This test checks the positioning of unit-width vertical lines
+ * under orthographic projection.      (This is important for apps
+ * that want to use OpenGL for precise 2D drawing.)  It fills in
+ * an entire rectangle with a collection of vertical lines, drawing
+ * adjacent lines with different colors and with blending enabled.
+ * If there are gaps (pixels that are the background color, and
+ * thus haven't been filled), overlaps (pixels that show a blend
+ * of more than one color), or improper edges (pixels around the
+ * edge of the rectangle that haven't been filled, or pixels just
+ * outside the edge that have), then the test fails.
+ * 
+ * This test generally fails for one of several reasons.  First,
+ * the coordinate transformation process may have an incorrect bias;
+ * this usually will cause a bad edge.  Second, the coordinate
+ * transformation process may round pixel coordinates incorrectly;
+ * this will usually cause gaps and/or overlaps.  Third, the
+ * line rasterization process may not be filling the correct
+ * pixels; this can cause gaps, overlaps, or bad edges.  Fourth,
+ * the OpenGL implementation may not handle the diamond-exit rule
+ * (section 3.4.1 in version 1.2.1 of the OpenGL spec) correctly;
+ * this should cause a bad border or bad top edge.
+ * 
+ * It can be argued that this test is more strict that the OpenGL
+ * specification requires.  However, it is necessary to be this
+ * strict in order for the results to be useful to app developers
+ * using OpenGL for 2D drawing.
+ */
+bool
+ortho_pos_vlines() {
+       /*
+        * Immediate-mode vertical lines
+        *      Note that these are a little tricky, because of
+        *      OpenGL's "diamond-exit rule" line semantics.  In
+        *      this case, we can safely treat them as half-open
+        *      lines, where the terminal point isn't drawn.  Thus
+        *      we need to specify a terminal coordinate one pixel
+        *      beyond the last pixel we wish to be drawn.
+        */
+
+       int x;
+
+       /* Draw the image */
+       glClear(GL_COLOR_BUFFER_BIT);
+       glBegin(GL_LINES);
+       for (x = 1; x <= drawing_size; ++x) {
+               if (x & 1)
+                       glColor4f(0.0, 1.0, 0.0, 0.5);
+               else
+                       glColor4f(1.0, 0.0, 0.0, 0.5);
+               glVertex2i(x, 1);
+               glVertex2i(x, drawing_size + 1);
+       }
+       glEnd();
+
+       /* Read the image */
+       glReadPixels(0, 0, window_size, window_size, GL_RGB, GL_UNSIGNED_BYTE, 
img);
+
+       /* Show the image */
+       if (!piglit_automatic) {
+               piglit_present_results();
+       }
+
+       /* Check the results */
+       return verify_orth_pos(img, img_bytes/window_size, "Immediate-mode 
vertical lines");
+} /* ortho_pos_vlines */
+
+/**
+ * This test checks the positioning of unit-width horizontal lines
+ * under orthographic projection.      (This is important for apps
+ * that want to use OpenGL for precise 2D drawing.)  It fills in
+ * an entire rectangle with a stack of horizontal lines, drawing
+ * adjacent lines with different colors and with blending enabled.
+ * If there are gaps (pixels that are the background color, and
+ * thus haven't been filled), overlaps (pixels that show a blend
+ * of more than one color), or improper edges (pixels around the
+ * edge of the rectangle that haven't been filled, or pixels just
+ * outside the edge that have), then the test fails.
+ * 
+ * This test generally fails for one of several reasons.  First,
+ * the coordinate transformation process may have an incorrect bias;
+ * this usually will cause a bad edge.  Second, the coordinate
+ * transformation process may round pixel coordinates incorrectly;
+ * this will usually cause gaps and/or overlaps.  Third, the
+ * line rasterization process may not be filling the correct
+ * pixels; this can cause gaps, overlaps, or bad edges.  Fourth,
+ * the OpenGL implementation may not handle the diamond-exit rule
+ * (section 3.4.1 in version 1.2.1 of the OpenGL spec) correctly;
+ * this should cause a bad border or bad right edge.
+ * 
+ * It can be argued that this test is more strict that the OpenGL
+ * specification requires.  However, it is necessary to be this
+ * strict in order for the results to be useful to app developers
+ * using OpenGL for 2D drawing.
+ */
+bool
+ortho_pos_hlines() {
+       /*
+        * Immediate-mode horizontal lines
+        * See the comments in the vertical line case above.
+        */
+       int y;
+       
+       /* Draw the image */
+       glClear(GL_COLOR_BUFFER_BIT);
+       glBegin(GL_LINES);
+       for (y = 1; y <= drawing_size; ++y) {
+               if (y & 1)
+                       glColor4f(0.0, 1.0, 0.0, 0.5);
+               else
+                       glColor4f(1.0, 0.0, 0.0, 0.5);
+               glVertex2i(1, y);
+               glVertex2i(drawing_size + 1, y);
+       }
+       glEnd();
+
+       /* Read the image */
+       glReadPixels(0, 0, window_size, window_size, GL_RGB, GL_UNSIGNED_BYTE, 
img);
+
+       /* Show the image */
+       if (!piglit_automatic) {
+               piglit_present_results();
+       }
+
+       /* Check the results */
+       return verify_orth_pos(img, img_bytes/window_size, "Immediate-mode 
horizontal lines");
+} /* ortho_pos_hlines */
+
+/**
+ * This test checks the positioning of 1x1-pixel quadrilaterals
+ * under orthographic projection.      (This is important for apps
+ * that want to use OpenGL for precise 2D drawing.)  It fills in
+ * an entire rectangle with an array of quadrilaterals, drawing
+ * adjacent quads with different colors and with blending enabled.
+ * If there are gaps (pixels that are the background color, and
+ * thus haven't been filled), overlaps (pixels that show a blend
+ * of more than one color), or improper edges (pixels around the
+ * edge of the rectangle that haven't been filled, or pixels just
+ * outside the edge that have), then the test fails.
+ * 
+ * This test generally fails for one of several reasons.  First,
+ * the coordinate transformation process may have an incorrect bias;
+ * this usually will cause a bad edge.  Second, the coordinate
+ * transformation process may round pixel coordinates incorrectly;
+ * this will usually cause gaps and/or overlaps.  Third, the
+ * quad rasterization process may not be filling the correct
+ * pixels; this can cause gaps, overlaps, or bad edges.
+ */
+bool
+ortho_pos_tiny_quads() {
+       /*
+        * Immediate-mode 1x1-pixel quads
+        */
+
+       int x, y;
+       
+       /* Draw the image */
+       glClear(GL_COLOR_BUFFER_BIT);
+       glBegin(GL_QUADS);
+       for (x = 1; x <= drawing_size; ++x)
+               for (y = 1; y <= drawing_size; ++y) {
+                       if ((x ^ y) & 1)
+                               glColor4f(0.0, 1.0, 0.0, 0.5);
+                       else
+                               glColor4f(1.0, 0.0, 0.0, 0.5);
+                       glVertex2i(x, y);
+                       glVertex2i(x + 1, y);
+                       glVertex2i(x + 1, y + 1);
+                       glVertex2i(x, y + 1);
+       }
+       glEnd();
+
+       /* Read the image */
+       glReadPixels(0, 0, window_size, window_size, GL_RGB, GL_UNSIGNED_BYTE, 
img);
+
+       /* Show the image */
+       if (!piglit_automatic) {
+               piglit_present_results();
+       }
+
+       /* Check the results */
+       return verify_orth_pos(img, img_bytes/window_size, "Immediate-mode 1x1 
quads");
+} /* ortho_pos_tiny_quads */
+
+/**
+ * This test checks the positioning of axis-aligned rectangles
+ * under orthographic projection.      (This is important for apps
+ * that want to use OpenGL for precise 2D drawing.)  It fills in
+ * an entire rectangle with an array of smaller rects, drawing
+ * adjacent rects with different colors and with blending enabled.
+ * If there are gaps (pixels that are the background color, and
+ * thus haven't been filled), overlaps (pixels that show a blend
+ * of more than one color), or improper edges (pixels around the
+ * edge of the rectangle that haven't been filled, or pixels just
+ * outside the edge that have), then the test fails.
+ * 
+ * This test generally fails for one of several reasons.  First,
+ * the coordinate transformation process may have an incorrect bias;
+ * this usually will cause a bad edge.  Second, the coordinate
+ * transformation process may round pixel coordinates incorrectly;
+ * this will usually cause gaps and/or overlaps.  Third, the
+ * rectangle rasterization process may not be filling the correct
+ * pixels; this can cause gaps, overlaps, or bad edges.
+ */
+bool
+ortho_pos_rand_rects() {
+       /*
+        * Immediate-mode random axis-aligned rectangles
+        */
+
+       /* Draw the image */
+       glClear(GL_COLOR_BUFFER_BIT);
+       subdivide_rects(1, drawing_size + 1, 1, drawing_size + 1,
+               true, true);
+
+       /* Read the image */
+       glReadPixels(0, 0, window_size, window_size, GL_RGB, GL_UNSIGNED_BYTE, 
img);
+
+       /* Show the image */
+       if (!piglit_automatic) {
+               piglit_present_results();
+       }
+
+       /* Check the results */
+       return verify_orth_pos(img, img_bytes/window_size, 
+               "Immediate-mode random axis-aligned rectangles");
+} /* ortho_pos_rand_rects */
+
+/* Factory for generating random mesh just like Glean's RandomMesh2D class */
+float*
+random_mesh_2d(float minx, float maxx, int xpoints,
+       float miny, float maxy, int ypoints)
+{
+       int x, y, idx;
+       float* mesh = malloc(xpoints * ypoints * 2 * sizeof(float));
+       double deltax = 0.7 * (maxx - minx) / (xpoints - 1);
+       double deltay = 0.7 * (maxy - miny) / (ypoints - 1);
+       float rand_no;
+
+       for (y = 0; y < ypoints; ++y) {
+               for (x = 0; x < xpoints; ++x) {
+
+                       idx = 2 * (xpoints * y + x);
+
+                       /* Generate an unperturbed, uniform mesh */
+                       mesh[idx + 0] = minx + (x * (maxx - minx)) / (xpoints - 
1);
+                       mesh[idx + 1] = miny + (y * (maxy - miny)) / (ypoints - 
1);
+
+                       /* Perturb the interior points of the mesh */
+                       if ((x != 0) && (y != 0) && (x != xpoints - 1) && (y != 
ypoints - 1))
+                       {
+                               rand_no = (float) rand() / RAND_MAX; /* Float 
in range [0.0f, 1.0f] */
+                               mesh[idx + 0] += deltax * (rand_no - 0.5);
+                               rand_no = (float) rand() / RAND_MAX; 
+                               mesh[idx + 1] += deltay * (rand_no - 0.5);
+                       }
+               }
+       }
+
+       return mesh;
+} /* random_mesh_2d */
+
+/**
+ * This test checks the positioning of random triangles under
+ * orthographic projection.  (This is important for apps that
+ * want to use OpenGL for precise 2D drawing.)  It fills in an
+ * entire rectangle with an array of randomly-generated triangles,
+ * drawing adjacent triangles with different colors and with blending
+ * enabled.  If there are gaps (pixels that are the background color,
+ * and thus haven't been filled), overlaps (pixels that show a blend
+ * of more than one color), or improper edges (pixels around the
+ * edge of the rectangle that haven't been filled, or pixels just
+ * outside the edge that have), then the test fails.
+ * 
+ * This test generally fails for one of several reasons.  First,
+ * the coordinate transformation process may have an incorrect bias;
+ * this usually will cause a bad edge.  Second, the coordinate
+ * transformation process may round pixel coordinates incorrectly;
+ * this will usually cause gaps and/or overlaps.  Third, the
+ * triangle rasterization process may not be filling the correct
+ * pixels; this can cause gaps, overlaps, or bad edges.
+ */
+bool
+ortho_pos_rand_tris() {
+       /*
+        * Immediate-mode random triangles
+        */
+       int i, j;
+       int npoints = 10;
+       float* mesh;
+
+       /* Draw the image */
+       glClear(GL_COLOR_BUFFER_BIT);
+       mesh = random_mesh_2d(1, drawing_size + 1, npoints,
+               1, drawing_size + 1, npoints);
+       for (i = npoints - 1; i > 0; --i) {
+               glBegin(GL_TRIANGLE_STRIP);
+               for (j = 0; j < npoints; ++j) {
+                       glColor4f(1.0, 0.0, 0.0, 0.5);
+                       glVertex2fv(mesh + 2 * (npoints * i + j)); /* mesh[i, 
j] */
+                       glColor4f(0.0, 1.0, 0.0, 0.5);
+                       glVertex2fv(mesh + 2 * (npoints * (i - 1) + j)); /* 
mesh[i - 1, j] */
+               }
+               glEnd();
+       }
+       free(mesh);
+
+       /* Read the image */
+       glReadPixels(0, 0, window_size, window_size, GL_RGB, GL_UNSIGNED_BYTE, 
img);
+
+       /* Show the image */
+       if (!piglit_automatic) {
+               piglit_present_results();
+       }
+
+       /* Check the results */
+       return verify_orth_pos(img, img_bytes/window_size, 
+               "Immediate-mode random triangles");
+} /* ortho_pos_rand_tris */
+
+enum piglit_result
+piglit_display(void)
+{
+       bool pass = true;
+
+       pass &= ortho_pos_points();
+       pass &= ortho_pos_vlines();
+       pass &= ortho_pos_hlines();
+       pass &= ortho_pos_tiny_quads();
+       pass &= ortho_pos_rand_rects();
+       pass &= ortho_pos_rand_tris();
+
+       return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
-- 
2.1.0

_______________________________________________
Piglit mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/piglit

Reply via email to