Add more structure constructor tests.
[piglit/hramrach.git] / tests / glean / tpaths.cpp
blob7807a0894c4d7e5fcd66ec6b72872b3063382949
1 // BEGIN_COPYRIGHT -*- glean -*-
2 //
3 // Copyright (C) 1999 Allen Akin All Rights Reserved.
4 //
5 // Permission is hereby granted, free of charge, to any person
6 // obtaining a copy of this software and associated documentation
7 // files (the "Software"), to deal in the Software without
8 // restriction, including without limitation the rights to use,
9 // copy, modify, merge, publish, distribute, sublicense, and/or
10 // sell copies of the Software, and to permit persons to whom the
11 // Software is furnished to do so, subject to the following
12 // conditions:
13 //
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the
16 // Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
19 // KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
20 // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
21 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ALLEN AKIN BE
22 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 // AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 // DEALINGS IN THE SOFTWARE.
26 //
27 // END_COPYRIGHT
30 // tpaths.h: Basic test of GL rendering paths.
31 // This test verifies that basic, trival OpenGL paths work as expected.
32 // For example, glAlphaFunc(GL_GEQUAL, 0.0) should always pass and
33 // glAlphaFunc(GL_LESS, 0.0) should always fail. We setup trivial
34 // pass and fail conditions for each of alpha test, blending, color mask,
35 // depth test, logic ops, scissor, stencil, stipple, and texture and
36 // make sure they work as expected. We also setup trival-pass for all
37 // these paths simultaneously and test that as well.
39 // To test for pass/fail we examine the color buffer for white or black,
40 // respectively.
42 // Author: Brian Paul (brianp@valinux.com) November 2000
44 #include <stdlib.h>
45 #include "tpaths.h"
46 #include <cstdlib>
48 namespace GLEAN {
50 void
51 PathsTest::SetPathState(Path path, State state) const {
53 switch (path) {
54 case ALPHA:
55 if (state == ALWAYS_PASS) {
56 glAlphaFunc(GL_GEQUAL, 0.0);
57 glEnable(GL_ALPHA_TEST);
59 else if (state == ALWAYS_FAIL) {
60 glAlphaFunc(GL_GREATER, 1.0);
61 glEnable(GL_ALPHA_TEST);
63 else {
64 glDisable(GL_ALPHA_TEST);
66 break;
67 case BLEND:
68 if (state == ALWAYS_PASS) {
69 glBlendFunc(GL_ONE, GL_ZERO);
70 glEnable(GL_BLEND);
72 else if (state == ALWAYS_FAIL) {
73 glBlendFunc(GL_ZERO, GL_ONE);
74 glEnable(GL_BLEND);
76 else {
77 glDisable(GL_BLEND);
79 break;
80 case COLOR_MASK:
81 if (state == ALWAYS_PASS) {
82 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
84 else if (state == ALWAYS_FAIL) {
85 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
87 else {
88 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
90 break;
91 case DEPTH:
92 if (state == ALWAYS_PASS) {
93 glDepthFunc(GL_ALWAYS);
94 glEnable(GL_DEPTH_TEST);
96 else if (state == ALWAYS_FAIL) {
97 glDepthFunc(GL_NEVER);
98 glEnable(GL_DEPTH_TEST);
100 else {
101 glDisable(GL_DEPTH_TEST);
103 break;
104 case LOGIC:
105 if (state == ALWAYS_PASS) {
106 glLogicOp(GL_OR);
107 glEnable(GL_COLOR_LOGIC_OP);
109 else if (state == ALWAYS_FAIL) {
110 glLogicOp(GL_AND);
111 glEnable(GL_COLOR_LOGIC_OP);
113 else {
114 glDisable(GL_COLOR_LOGIC_OP);
116 break;
117 case SCISSOR:
118 if (state == ALWAYS_PASS) {
119 glScissor(0, 0, 10, 10);
120 glEnable(GL_SCISSOR_TEST);
122 else if (state == ALWAYS_FAIL) {
123 glScissor(0, 0, 0, 0);
124 glEnable(GL_SCISSOR_TEST);
126 else {
127 glDisable(GL_SCISSOR_TEST);
129 break;
130 case STENCIL:
131 if (state == ALWAYS_PASS) {
132 // pass if reference <= stencil value (ref = 0)
133 glStencilFunc(GL_LEQUAL, 0, ~0);
134 glEnable(GL_STENCIL_TEST);
136 else if (state == ALWAYS_FAIL) {
137 // pass if reference > stencil value (ref = 0)
138 glStencilFunc(GL_GREATER, 0, ~0);
139 glEnable(GL_STENCIL_TEST);
141 else {
142 glDisable(GL_STENCIL_TEST);
144 break;
145 case STIPPLE:
146 if (state == ALWAYS_PASS) {
147 GLubyte stipple[4*32];
148 for (int i = 0; i < 4*32; i++)
149 stipple[i] = 0xff;
150 glPolygonStipple(stipple);
151 glEnable(GL_POLYGON_STIPPLE);
153 else if (state == ALWAYS_FAIL) {
154 GLubyte stipple[4*32];
155 for (int i = 0; i < 4*32; i++)
156 stipple[i] = 0x0;
157 glPolygonStipple(stipple);
158 glEnable(GL_POLYGON_STIPPLE);
160 else {
161 glDisable(GL_POLYGON_STIPPLE);
163 break;
164 case TEXTURE:
165 if (state == DISABLE) {
166 glDisable(GL_TEXTURE_2D);
168 else {
169 GLubyte val = (state == ALWAYS_PASS) ? 0xff : 0x00;
170 int i;
171 GLubyte texImage[4*4*4];
172 for (i = 0; i < 4*4*4; i++)
173 texImage[i] = val;
174 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0,
175 GL_RGBA, GL_UNSIGNED_BYTE, texImage);
176 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
177 GL_NEAREST);
178 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
179 GL_NEAREST);
180 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
181 GL_MODULATE);
182 glEnable(GL_TEXTURE_2D);
184 break;
185 default:
186 abort(); // error
191 const char *
192 PathsTest::PathName(Path path) const {
194 switch (path) {
195 case ALPHA:
196 return "Alpha Test";
197 case BLEND:
198 return "Blending";
199 case COLOR_MASK:
200 return "Color Mask";
201 case DEPTH:
202 return "Depth Test";
203 case LOGIC:
204 return "LogicOp";
205 case SCISSOR:
206 return "Scissor Test";
207 case STENCIL:
208 return "Stencil Test";
209 case STIPPLE:
210 return "Polygon Stipple";
211 case TEXTURE:
212 return "Modulated Texture";
213 case ZZZ:
214 return "paths";
215 default:
216 return "???";
221 void
222 PathsTest::FailMessage(BasicResult &r, Path path, State state, GLfloat pixel[3])
223 const {
224 env->log << name << ": FAIL "
225 << r.config->conciseDescription() << '\n';
226 if (state == ALWAYS_PASS) {
227 env->log << "\t" << PathName(path)
228 << " should have had no effect (1, 1, 1)"
229 << " but actually modified the fragment: "
230 << "(" << pixel[0] << "," << pixel[1] << ","
231 << pixel[2] << ")\n";
233 else {
234 env->log << "\t" << PathName(path)
235 << " should have culled the fragment (0, 0, 0)"
236 << " but actually didn't: (" << pixel[0] << ","
237 << pixel[1] << "," << pixel[2] << ")\n";
242 ///////////////////////////////////////////////////////////////////////////////
243 // runOne: Run a single test case
244 ///////////////////////////////////////////////////////////////////////////////
245 void
246 PathsTest::runOne(BasicResult& r, Window&) {
248 Path p, paths[1000];
249 int i, numPaths = 0;
251 // draw 10x10 pixel quads
252 glViewport(0, 0, 10, 10);
254 glDisable(GL_DITHER);
256 // Build the list of paths to exercise. Skip depth test if we have no
257 // depth buffer. Skip stencil test if we have no stencil buffer.
258 for (p = ALPHA; p != ZZZ; p = (Path) (p + 1)) {
259 if (!((p == DEPTH && r.config->z == 0) ||
260 (p == STENCIL && r.config->s == 0))) {
261 paths[numPaths++] = p;
265 // test always-pass paths
266 for (i = 0; i < numPaths; i++) {
267 glClear(GL_COLOR_BUFFER_BIT);
269 SetPathState(paths[i], ALWAYS_PASS);
271 // draw polygon
272 glColor4f(1, 1, 1, 1);
273 glBegin(GL_POLYGON);
274 glVertex2f(-1, -1);
275 glVertex2f( 1, -1);
276 glVertex2f( 1, 1);
277 glVertex2f(-1, 1);
278 glEnd();
280 SetPathState(paths[i], DISABLE);
282 // test buffer
283 GLfloat pixel[3];
284 glReadPixels(4, 4, 1, 1, GL_RGB, GL_FLOAT, pixel);
285 if (pixel[0] != 1.0 || pixel[1] != 1.0 || pixel[2] != 1.0) {
286 FailMessage(r, paths[i], ALWAYS_PASS, pixel);
287 r.pass = false;
288 return;
292 // enable all always-pass paths
294 glClear(GL_COLOR_BUFFER_BIT);
296 for (i = 0; i < numPaths; i++) {
297 SetPathState(paths[i], ALWAYS_PASS);
300 // draw polygon
301 glColor4f(1, 1, 1, 1);
302 glBegin(GL_POLYGON);
303 glVertex2f(-1, -1);
304 glVertex2f( 1, -1);
305 glVertex2f( 1, 1);
306 glVertex2f(-1, 1);
307 glEnd();
309 for (i = 0; i < numPaths; i++) {
310 SetPathState(paths[i], DISABLE);
313 // test buffer
314 GLfloat pixel[3];
315 glReadPixels(4, 4, 1, 1, GL_RGB, GL_FLOAT, pixel);
316 if (pixel[0] != 1.0 || pixel[1] != 1.0 || pixel[2] != 1.0) {
317 FailMessage(r, paths[i], ALWAYS_PASS, pixel);
318 r.pass = false;
319 return;
323 // test never-pass paths
324 for (i = 0; i < numPaths; i++) {
325 glClear(GL_COLOR_BUFFER_BIT);
327 SetPathState(paths[i], ALWAYS_FAIL);
329 // draw polygon
330 glColor4f(1, 1, 1, 1);
331 glBegin(GL_POLYGON);
332 glVertex2f(-1, -1);
333 glVertex2f( 1, -1);
334 glVertex2f( 1, 1);
335 glVertex2f(-1, 1);
336 glEnd();
338 SetPathState(paths[i], DISABLE);
340 // test buffer
341 GLfloat pixel[3];
342 glReadPixels(4, 4, 1, 1, GL_RGB, GL_FLOAT, pixel);
343 if (pixel[0] != 0.0 || pixel[1] != 0.0 || pixel[2] != 0.0) {
344 FailMessage(r, paths[i], ALWAYS_FAIL, pixel);
345 r.pass = false;
346 return;
350 // success
351 r.pass = true;
352 } // PathsTest::runOne
354 ///////////////////////////////////////////////////////////////////////////////
355 // logOne: Log a single test case
356 ///////////////////////////////////////////////////////////////////////////////
357 void
358 PathsTest::logOne(BasicResult& r) {
359 if (r.pass) {
360 logPassFail(r);
361 logConcise(r);
363 } // PathsTest::logOne
365 ///////////////////////////////////////////////////////////////////////////////
366 // The test object itself:
367 ///////////////////////////////////////////////////////////////////////////////
368 PathsTest pathsTest("paths", "window, rgb",
370 "This test verifies that basic OpenGL operations such as the alpha\n"
371 "test, depth test, blending, stippling, and texturing work for\n"
372 "trivial cases.\n");
375 } // namespace GLEAN