1 // BEGIN_COPYRIGHT -*- glean -*-
3 // Copyright (C) 1999 Allen Akin All Rights Reserved.
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
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the
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.
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,
42 // Author: Brian Paul (brianp@valinux.com) November 2000
51 PathsTest::SetPathState(Path path
, State state
) const {
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
);
64 glDisable(GL_ALPHA_TEST
);
68 if (state
== ALWAYS_PASS
) {
69 glBlendFunc(GL_ONE
, GL_ZERO
);
72 else if (state
== ALWAYS_FAIL
) {
73 glBlendFunc(GL_ZERO
, GL_ONE
);
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
);
88 glColorMask(GL_TRUE
, GL_TRUE
, GL_TRUE
, GL_TRUE
);
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
);
101 glDisable(GL_DEPTH_TEST
);
105 if (state
== ALWAYS_PASS
) {
107 glEnable(GL_COLOR_LOGIC_OP
);
109 else if (state
== ALWAYS_FAIL
) {
111 glEnable(GL_COLOR_LOGIC_OP
);
114 glDisable(GL_COLOR_LOGIC_OP
);
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
);
127 glDisable(GL_SCISSOR_TEST
);
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
);
142 glDisable(GL_STENCIL_TEST
);
146 if (state
== ALWAYS_PASS
) {
147 GLubyte stipple
[4*32];
148 for (int i
= 0; i
< 4*32; i
++)
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
++)
157 glPolygonStipple(stipple
);
158 glEnable(GL_POLYGON_STIPPLE
);
161 glDisable(GL_POLYGON_STIPPLE
);
165 if (state
== DISABLE
) {
166 glDisable(GL_TEXTURE_2D
);
169 GLubyte val
= (state
== ALWAYS_PASS
) ? 0xff : 0x00;
171 GLubyte texImage
[4*4*4];
172 for (i
= 0; i
< 4*4*4; i
++)
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
,
178 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
,
180 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
,
182 glEnable(GL_TEXTURE_2D
);
192 PathsTest::PathName(Path path
) const {
206 return "Scissor Test";
208 return "Stencil Test";
210 return "Polygon Stipple";
212 return "Modulated Texture";
222 PathsTest::FailMessage(BasicResult
&r
, Path path
, State state
, GLfloat pixel
[3])
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";
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 ///////////////////////////////////////////////////////////////////////////////
246 PathsTest::runOne(BasicResult
& r
, Window
&) {
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
);
272 glColor4f(1, 1, 1, 1);
280 SetPathState(paths
[i
], DISABLE
);
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
);
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
);
301 glColor4f(1, 1, 1, 1);
309 for (i
= 0; i
< numPaths
; i
++) {
310 SetPathState(paths
[i
], DISABLE
);
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
);
323 // test never-pass paths
324 for (i
= 0; i
< numPaths
; i
++) {
325 glClear(GL_COLOR_BUFFER_BIT
);
327 SetPathState(paths
[i
], ALWAYS_FAIL
);
330 glColor4f(1, 1, 1, 1);
338 SetPathState(paths
[i
], DISABLE
);
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
);
352 } // PathsTest::runOne
354 ///////////////////////////////////////////////////////////////////////////////
355 // logOne: Log a single test case
356 ///////////////////////////////////////////////////////////////////////////////
358 PathsTest::logOne(BasicResult
& 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"