2 * Copyright © 2009 Intel Corporation
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
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
24 * Eric Anholt <eric@anholt.net>
30 * Tests that drawing to each depth of a 3D texture FBO and then drawing views
31 * of those individual depths to the window system framebuffer succeeds.
34 #include "piglit-util.h"
38 int piglit_width
= 200;
39 int piglit_height
= 100;
40 int piglit_window_mode
= GLUT_DOUBLE
| GLUT_RGB
;
44 float depth_color
[NUM_DEPTHS
][4] = {
61 pot_depth
= glutExtensionSupported("GL_ARB_texture_non_power_of_two") ?
62 NUM_DEPTHS
: POT_DEPTHS
;
64 glGenTextures(1, &tex
);
65 glBindTexture(GL_TEXTURE_3D
, tex
);
67 /* allocate empty 3D texture */
68 glTexImage3D(GL_TEXTURE_3D
, 0, GL_RGBA
,
69 BUF_WIDTH
, BUF_HEIGHT
, pot_depth
,
71 GL_RGBA
, GL_UNSIGNED_BYTE
, NULL
);
72 assert(glGetError() == 0);
74 glGenFramebuffersEXT(1, &fb
);
75 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, fb
);
77 /* draw something into each slice of the 3D texture */
78 for (depth
= 0; depth
< NUM_DEPTHS
; depth
++) {
79 glFramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT
,
80 GL_COLOR_ATTACHMENT0_EXT
,
86 assert(glGetError() == 0);
88 status
= glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT
);
89 if (status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
90 fprintf(stderr
, "FBO incomplete\n");
94 glViewport(0, 0, BUF_WIDTH
, BUF_HEIGHT
);
95 piglit_ortho_projection(BUF_WIDTH
, BUF_HEIGHT
, GL_FALSE
);
97 /* solid color quad */
98 glColor4fv(depth_color
[depth
]);
99 piglit_draw_rect(-2, -2, BUF_WIDTH
+ 2, BUF_HEIGHT
+ 2);
104 glDeleteFramebuffersEXT(1, &fb
);
109 /* Draw a textured quad, sampling only the given depth/slice of the
113 draw_depth(int x
, int y
, int depth
)
115 float depth_coord
= (float)depth
/ (pot_depth
- 1);
117 glViewport(0, 0, piglit_width
, piglit_height
);
118 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
120 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, 0);
122 glEnable(GL_TEXTURE_3D
);
123 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
124 glTexParameteri(GL_TEXTURE_3D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
125 glTexParameteri(GL_TEXTURE_3D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
126 glTexParameteri(GL_TEXTURE_3D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
127 glTexParameteri(GL_TEXTURE_3D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
128 glTexParameteri(GL_TEXTURE_3D
, GL_TEXTURE_WRAP_R
, GL_CLAMP_TO_EDGE
);
132 glTexCoord3f(0, 0, depth_coord
);
135 glTexCoord3f(1, 0, depth_coord
);
136 glVertex2f(x
+ BUF_WIDTH
, y
);
138 glTexCoord3f(1, 1, depth_coord
);
139 glVertex2f(x
+ BUF_WIDTH
, y
+ BUF_HEIGHT
);
141 glTexCoord3f(0, 1, depth_coord
);
142 glVertex2f(x
, y
+ BUF_HEIGHT
);
147 static GLboolean
test_depth_drawing(int start_x
, int start_y
, float *expected
)
149 GLboolean pass
= GL_TRUE
;
152 for (y
= start_y
; y
< start_y
+ BUF_HEIGHT
; y
++) {
153 for (x
= start_x
; x
< start_x
+ BUF_WIDTH
; x
++) {
154 pass
&= piglit_probe_pixel_rgb(x
, y
, expected
);
164 GLboolean pass
= GL_TRUE
;
168 glClearColor(1.0, 1.0, 1.0, 1.0);
169 glClear(GL_COLOR_BUFFER_BIT
);
171 tex
= create_3d_fbo();
173 for (depth
= 0; depth
< NUM_DEPTHS
; depth
++) {
174 int x
= 1 + depth
* (BUF_WIDTH
+ 1);
176 draw_depth(x
, y
, depth
);
179 for (depth
= 0; depth
< NUM_DEPTHS
; depth
++) {
180 int x
= 1 + depth
* (BUF_WIDTH
+ 1);
182 pass
&= test_depth_drawing(x
, y
, depth_color
[depth
]);
185 glDeleteTextures(1, &tex
);
189 return pass
? PIGLIT_SUCCESS
: PIGLIT_FAILURE
;
192 void piglit_init(int argc
, char **argv
)
194 piglit_require_extension("GL_EXT_texture3D");