fbo-mrt-alphatest: Actually require MRTs to be available.
[piglit.git] / tests / general / hiz.c
blob6bdeeff985b1550786ceba3bbdcf57f30b644549
1 /*
2 * Copyright © 2010 Marek Olšák <maraeo@gmail.com>
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
13 * Software.
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
21 * IN THE SOFTWARE.
23 * Authors:
24 * Marek Olšák <maraeo@gmail.com>
28 /** @file r300-hiz-bug.c
30 * Tests that two overlapping triangles are rendered correctly.
33 #include "piglit-util-gl.h"
35 PIGLIT_GL_TEST_CONFIG_BEGIN
37 config.supports_gl_compat_version = 10;
39 config.window_width = 400;
40 config.window_height = 400;
41 config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DEPTH | PIGLIT_GL_VISUAL_DOUBLE;
43 PIGLIT_GL_TEST_CONFIG_END
45 enum {
46 INSIDE,
47 EDGE,
48 OUTSIDE
51 int tri_point_intersect_2d(const float v0[2],
52 const float v1[2],
53 const float v2[2],
54 const float p[2],
55 float dist_eps)
57 float n0[2];
58 float n1[2];
59 float n2[3];
60 float l0, l1, l2;
61 float c0, c1, c2;
62 float d0, d1, d2;
64 /* compute edge normals */
65 n0[0] = v1[1] - v0[1];
66 n0[1] = v0[0] - v1[0];
68 n1[0] = v2[1] - v1[1];
69 n1[1] = v1[0] - v2[0];
71 n2[0] = v0[1] - v2[1];
72 n2[1] = v2[0] - v0[0];
74 /* compute inverse lengths of the normals */
75 l0 = 1 / sqrt(n0[0]*n0[0] + n0[1]*n0[1]);
76 l1 = 1 / sqrt(n1[0]*n1[0] + n1[1]*n1[1]);
77 l2 = 1 / sqrt(n2[0]*n2[0] + n2[1]*n2[1]);
79 /* normalize the normals */
80 n0[0] *= l0;
81 n0[1] *= l0;
82 n1[0] *= l1;
83 n1[1] *= l1;
84 n2[0] *= l2;
85 n2[1] *= l2;
87 /* compute negative dot products between normals and vertices
88 * to get ray equations in the form nx*x + ny*y + c = 0. */
89 c0 = - n0[0]*v0[0] - n0[1]*v0[1];
90 c1 = - n1[0]*v1[0] - n1[1]*v1[1];
91 c2 = - n2[0]*v2[0] - n2[1]*v2[1];
93 /* compute the distances between the point and the edges. */
94 d0 = n0[0]*p[0] + n0[1]*p[1] + c0;
95 d1 = n1[0]*p[0] + n1[1]*p[1] + c1;
96 d2 = n2[0]*p[0] + n2[1]*p[1] + c2;
98 /* the point is inside the triangle */
99 if (d0 < -dist_eps && d1 < -dist_eps && d2 < -dist_eps) {
100 return INSIDE;
103 /* the point is outside the triangle */
104 if (d0 > dist_eps || d1 > dist_eps || d2 > dist_eps) {
105 return OUTSIDE;
108 return EDGE;
111 GLboolean pix_equal(int x, int y, const float probe[3], const float expected[3])
113 int i;
114 GLboolean ret = GL_TRUE;
116 for (i = 0; i < 3; i++) {
117 if (fabs(probe[i] - expected[i]) > 0.01) {
118 ret = GL_FALSE;
119 break;
123 if (!ret) {
124 printf("Probe color at (%i,%i)\n", x, y);
125 printf(" Expected: %f %f %f\n", expected[0], expected[1], expected[2]);
126 printf(" Observed: %f %f %f\n", probe[0], probe[1], probe[2]);
128 return ret;
131 GLboolean test_less()
133 const float bg[3] = {0.1, 0.1, 0.1};
134 const float c1[3] = {1.0, 0.3, 0.3};
135 const float v11[3] = {0, 1, -1};
136 const float v12[3] = {0, 0, -1};
137 const float v13[3] = {1, 0.5, 1};
138 const float c2[3] = {0.0, 1.0, 1};
139 const float v21[3] = {1, 1, 0};
140 const float v22[3] = {0, 0.5, 0};
141 const float v23[3] = {1, 0, 0};
142 float *pix;
143 int i,j;
144 float dist_eps = 1.0f / MIN2(piglit_width, piglit_height);
146 glClearDepth(1);
147 glDepthFunc(GL_LESS);
149 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
151 glBegin (GL_TRIANGLES);
152 glColor3fv(c1);
153 glVertex3fv(v11);
154 glVertex3fv(v12);
155 glVertex3fv(v13);
156 glEnd();
158 glBegin (GL_TRIANGLES);
159 glColor3fv(c2);
160 glVertex3fv(v21);
161 glVertex3fv(v22);
162 glVertex3fv(v23);
163 glEnd();
165 pix = malloc(piglit_width * piglit_height * 3 * sizeof(float));
166 glReadPixels(0, 0, piglit_width, piglit_height, GL_RGB, GL_FLOAT, pix);
168 /* check pixels */
169 for (j = 0; j < piglit_height; j++) {
170 for (i = 0; i < piglit_width; i++) {
171 float *px = &pix[(j*piglit_width + i) * 3];
172 float p[2];
173 int t1_intersect, t2_intersect;
175 p[0] = i / (float)(piglit_width-1);
176 p[1] = j / (float)(piglit_height-1);
178 t1_intersect = tri_point_intersect_2d(v11, v12, v13, p, dist_eps);
179 t2_intersect = tri_point_intersect_2d(v21, v22, v23, p, dist_eps);
181 if (t1_intersect == EDGE || t2_intersect == EDGE) {
182 //printf(" ");
183 continue;
186 if (t1_intersect == INSIDE) {
187 if (t2_intersect == INSIDE) {
188 if (fabs(p[0] - 0.5) < dist_eps) {
189 //printf(" ");
190 continue;
192 if (p[0] < 0.5) {
193 //printf("2");
194 if (!pix_equal(i, j, px, c2)) {
195 free(pix);
196 return GL_FALSE;
198 } else {
199 //printf("1");
200 if (!pix_equal(i, j, px, c1)) {
201 free(pix);
202 return GL_FALSE;
205 } else {
206 //printf("1");
207 if (!pix_equal(i, j, px, c1)) {
208 free(pix);
209 return GL_FALSE;
212 } else {
213 if (t2_intersect == INSIDE) {
214 //printf("2");
215 if (!pix_equal(i, j, px, c2)) {
216 free(pix);
217 return GL_FALSE;
219 } else {
220 //printf("0");
221 if (!pix_equal(i, j, px, bg)) {
222 free(pix);
223 return GL_FALSE;
228 /*if (i == piglit_width-1)
229 printf("\n");*/
233 free(pix);
234 return GL_TRUE;
237 enum piglit_result piglit_display()
239 GLboolean pass = GL_TRUE;
241 pass = pass && test_less();
242 piglit_present_results();
243 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
246 void piglit_init(int argc, char**argv)
248 glClearColor(0.1, 0.1, 0.1, 0.1);
249 glEnable(GL_DEPTH_TEST);
251 glMatrixMode(GL_PROJECTION);
252 glLoadIdentity();
253 glOrtho(0.0, 1.0, 0.0, 1.0, -1, 1);
255 printf("First the red triangle is drawn, then the blue one.\n");