/* * Copyright © 2011 * * 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. * * Authors: * Pierre-Eric Pelloux-Prayer * * Description: * This test represents a simple usage of GL_SELECT rendering mode. * It draws several squares to screen, with various GL_..._TEST active, * and then verifies the number of hits and the content of the select buffer. * Based on this documentation: http://glprogramming.com/red/chapter13.html * */ #include "piglit-util-gl-common.h" PIGLIT_GL_TEST_CONFIG_BEGIN config.supports_gl_compat_version = 10; config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_ALPHA | PIGLIT_GL_VISUAL_DEPTH | PIGLIT_GL_VISUAL_STENCIL; PIGLIT_GL_TEST_CONFIG_END GLuint ReferenceHitEntries[3][64]; #define NAME_STACK_DEPTH 0 #define MIN_Z 1 #define MAX_Z 2 #define NAME_STACK_0 3 /** * Draw 4 objects and handle name stack */ static void draw_objects() { float zscale = (float)(~0u); glInitNames(); /* no draw call issued for name '0' */ glPushName(0); /* OBJECT 1 */ glPushName(1); /* draw object */ glColor3f(1.0, 0.0, 0.0); piglit_draw_rect_z(0.8, 10, 30, 50, 50); /* fill reference buffer */ ReferenceHitEntries[0][NAME_STACK_DEPTH] = 2; ReferenceHitEntries[0][MIN_Z] = (GLuint)roundf(zscale * ((1 - 0.8) * 0.5)); ReferenceHitEntries[0][MAX_Z] = ReferenceHitEntries[0][MIN_Z]; ReferenceHitEntries[0][NAME_STACK_0] = 0; ReferenceHitEntries[0][NAME_STACK_0 + 1] = 1; /* OBJECT 2 */ /* 2 draw calls for name '2' */ glPushName(2); glColor3f(0.0, 1.0, 0.0); piglit_draw_rect_z(0.5, 40, 5, 25, 30); piglit_draw_rect_z(0.4, 10, 75, 25, 10); /* fill reference buffer */ ReferenceHitEntries[1][NAME_STACK_DEPTH] = 3; ReferenceHitEntries[1][MIN_Z] = (GLuint)roundf(zscale * ((1 - 0.5)*0.5)); ReferenceHitEntries[1][MAX_Z] = (GLuint)roundf(zscale * ((1 - 0.4)*0.5)); ReferenceHitEntries[1][NAME_STACK_0] = 0; ReferenceHitEntries[1][NAME_STACK_0 + 1] = 1; ReferenceHitEntries[1][NAME_STACK_0 + 2] = 2; /* OBJECT 3 */ glPopName(); glPushName(3); /* drawn offscreen */ piglit_draw_rect_z(0.3, 250, 45, 280, 20); /* OBJECT 4 */ /* glLoadName instead of glPushName */ glLoadName(4); glColor3f(0.0, 0.0, 1.0); piglit_draw_rect_z(0.2, 50, 45, 80, 20); /* fill reference buffer */ ReferenceHitEntries[2][NAME_STACK_DEPTH] = 3; ReferenceHitEntries[2][MIN_Z] = (GLuint)roundf(zscale * ((1 - 0.2)*0.5)); ReferenceHitEntries[2][MAX_Z] = ReferenceHitEntries[2][MIN_Z]; ReferenceHitEntries[2][NAME_STACK_0] = 0; ReferenceHitEntries[2][NAME_STACK_0 + 1] = 1; ReferenceHitEntries[2][NAME_STACK_0 + 2] = 4; } /** * Helper function to compare 2 hit records */ static bool compare_hit_record(GLuint* hit1, GLuint* hit2) { int i; float zscale = (float)(~0u); float diffz; if (hit1[NAME_STACK_DEPTH] != hit2[NAME_STACK_DEPTH]) { printf("\t%s : Incorrect name stack depth : %u %u\n", __FUNCTION__, hit1[NAME_STACK_DEPTH], hit2[NAME_STACK_DEPTH]); return false; } diffz = abs(hit1[MIN_Z] - hit2[MIN_Z])/zscale; if (diffz > 0.1) { printf("\t%s : Incorrect Minz : %u %u (%f %f) %f\n", __FUNCTION__, hit1[MIN_Z], hit2[MIN_Z], hit1[MIN_Z] / zscale, hit2[MIN_Z] / zscale, diffz); return false; } diffz = abs(hit1[MAX_Z] - hit2[MAX_Z])/zscale; if (diffz > 0.1) { printf("\t%s : Incorrect Maxz : %u %u (%f %f) %f\n", __FUNCTION__, hit1[MAX_Z], hit2[MAX_Z], hit1[MAX_Z] / zscale, hit2[MAX_Z] / zscale, diffz); return false; } for (i=0; i