/* * Copyright (c) The Piglit project 2008 * * 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 * on the rights to use, copy, modify, merge, publish, distribute, sub * license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS 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 * Test basic line stippling functionality. */ #include "piglit-util-gl.h" PIGLIT_GL_TEST_CONFIG_BEGIN config.supports_gl_compat_version = 10; config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE; PIGLIT_GL_TEST_CONFIG_END struct vertex { GLuint x; GLuint y; }; struct stipple_line { const char *name; GLint factor; GLuint pattern; GLfloat color[3]; GLuint primitive; GLuint nvertices; struct vertex *vertices; }; static const int basex = 10; static const int basey = 10; static float background[3] = { 0, 0, 0 }; /** * @note Only horizontal and vertical lines supported right now. */ static bool probe_line(const struct stipple_line *line, int v1i, int v2i, GLuint *fragment) { const struct vertex *v1 = &line->vertices[v1i]; const struct vertex *v2 = &line->vertices[v2i]; int x = v1->x; int y = v1->y; int length, dx = 0, dy = 0; if (v2->x != v1->x) { if (v2->x > v1->x) dx = 1; else dx = -1; length = (v2->x - v1->x)*dx; } else { if (v2->y > v1->y) dy = 1; else dy = -1; length = (v2->y - v1->y)*dy; } while (length) { GLuint s = ((*fragment) / line->factor) & 15; const float *color; if (line->pattern & (1 << s)) color = line->color; else color = background; if (!piglit_probe_pixel_rgb(basex + x, basex + y, color)) { return false; } length--; (*fragment)++; x += dx; y += dy; } return true; } static enum piglit_result test_line(void *data) { struct stipple_line *line = data; GLuint i; glLineStipple(line->factor, line->pattern); glColor3f(line->color[0], line->color[1], line->color[2]); glBegin(line->primitive); for (i = 0; i < line->nvertices; ++i) glVertex2f(line->vertices[i].x + 0.5, line->vertices[i].y + 0.5); glEnd(); glReadBuffer(GL_BACK); if (line->primitive == GL_LINES) { for (i = 0; i + 1 < line->nvertices; i += 2) { GLuint fragment = 0; if (!probe_line(line, i, i + 1, &fragment)) return PIGLIT_FAIL; } } else { GLuint fragment = 0; for (i = 0; i + 1 < line->nvertices; ++i) { if (!probe_line(line, i, i + 1, &fragment)) return PIGLIT_FAIL; } if (line->primitive == GL_LINE_LOOP) { if (!probe_line(line, i, 0, &fragment)) return PIGLIT_FAIL; } } return PIGLIT_PASS; } static struct vertex BaselineVertices[] = { { 0, 0 }, { 24, 0 } }; static struct vertex RestartVertices[] = { { 0, 2 }, { 24, 2 }, { 0, 4 }, { 24, 4 } }; static struct vertex LinestripVertices[] = { { 0, 6 }, { 24, 6 }, { 24, 30 } }; static struct vertex LineloopVertices[] = { { 26, 0 }, { 46, 0 }, { 46, 20 }, { 26, 20 } }; static struct vertex Factor2Vertices[] = { { 0, 32 }, { 32, 32 }, { 32, 33 }, { 0, 33 } }; static struct vertex Factor3Vertices[] = { { 0, 35 }, { 63, 35 }, { 63, 36 }, { 0, 36 } }; static struct stipple_line Lines[] = { { /* Baseline */ "Baseline", 1, 0xffff, { 1.0, 1.0, 1.0 }, GL_LINES, 2, BaselineVertices }, { /* Restarting lines within a single Begin/End block */ "Restarting lines within a single Begin-End block", 1, 0x00ff, { 1.0, 0.0, 0.0 }, GL_LINES, 4, RestartVertices }, { /* Line strip */ "Line strip", 1, 0x0f8f, { 1.0, 1.0, 0.0 }, GL_LINE_STRIP, 3, LinestripVertices }, { /* Line loop */ "Line loop", 1, 0x8cef, { 0.0, 1.0, 0.0 }, GL_LINE_LOOP, 4, LineloopVertices }, { /* Factor 2x */ "Factor 2x", 2, 0x838f, { 0.0, 0.0, 1.0 }, GL_LINE_LOOP, 4, Factor2Vertices }, { /* Factor 3x */ "Factor 3x", 3, 0xf731, { 0.0, 1.0, 1.0 }, GL_LINE_LOOP, 4, Factor3Vertices } }; enum piglit_result piglit_display(void) { enum piglit_result result = PIGLIT_PASS; piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_LINE_STIPPLE); glPushMatrix(); glTranslatef(basex, basey, 0.0); struct piglit_subtest tests[ARRAY_SIZE(Lines) + 1]; for (int i = 0; i < ARRAY_SIZE(Lines); ++i) { tests[i].name = Lines[i].name; tests[i].option = ""; tests[i].subtest_func = test_line; tests[i].data = &Lines[i]; } tests[ARRAY_SIZE(Lines)].name = NULL; result = piglit_run_selected_subtests(tests, NULL, 0, result); glPopMatrix(); piglit_present_results(); return result; } void piglit_init(int argc, char **argv) { }