Add more structure constructor tests.
[piglit/hramrach.git] / tests / texturing / cubemap.c
blob5a6f3c067adfbc73305548bc9ac6d88c0f8818f1
1 /*
2 * Copyright © 2008-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
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 * Eric Anholt <eric@anholt.net>
28 #include "piglit-util.h"
30 #define MAX_SIZE 64
31 #define PAD 5
33 #define WIN_WIDTH ((MAX_SIZE * 6 + PAD * 9) * 2)
34 #define WIN_HEIGHT 400
36 int piglit_window_mode = GLUT_DOUBLE | GLUT_RGB;
37 int piglit_width = WIN_WIDTH;
38 int piglit_height = WIN_HEIGHT;
40 static GLfloat colors[][3] = {
41 {1.0, 1.0, 1.0},
42 {1.0, 1.0, 0.0},
43 {1.0, 0.0, 0.0},
44 {1.0, 0.0, 1.0},
45 {0.0, 0.0, 1.0},
46 {0.0, 1.0, 1.0},
47 {0.0, 1.0, 0.0},
50 #if defined(_MSC_VER)
51 /**
52 * Find the first bit set in i and return the index set of that bit.
54 static int
55 ffs(int i)
57 int bit;
59 if (i == 0) {
60 return 0;
63 for (bit = 1; !(i & 1); bit++) {
64 i = i >> 1;
67 return bit;
69 #endif
71 static void
72 set_face_image(int level, GLenum face, int size, int color)
74 GLfloat *color1 = colors[color];
75 GLfloat *color2 = colors[(color + 1) % ARRAY_SIZE(colors)];
76 GLfloat *tex;
77 int x, y;
79 tex = malloc(size * size * 3 * sizeof(GLfloat));
81 /* Set the texture for this face to one corner being color2 and the
82 * rest color1. If the texture is 1x1, then it's all color1.
84 for (y = 0; y < size; y++) {
85 for (x = 0; x < size; x++) {
86 GLfloat *chosen_color;
88 if (y >= (size / 2) || x >= (size / 2))
89 chosen_color = color1;
90 else
91 chosen_color = color2;
93 tex[(y * size + x) * 3 + 0] = chosen_color[0];
94 tex[(y * size + x) * 3 + 1] = chosen_color[1];
95 tex[(y * size + x) * 3 + 2] = chosen_color[2];
99 glTexImage2D(face, level, GL_RGB, size, size, 0, GL_RGB, GL_FLOAT, tex);
101 free(tex);
105 * Tests that the mipmap drawn at (x,y)-(x+size,y+size) has the majority color,
106 * with color+1 in bottom left.
108 static GLboolean
109 test_results(int x, int y, int size, int level, int face, GLboolean mipmapped,
110 int color)
112 GLfloat *color1 = colors[color];
113 GLfloat *color2 = colors[(color + 1) % ARRAY_SIZE(colors)];
114 GLboolean pass = GL_TRUE;
115 int x1 = x + size / 4, x2 = x + size * 3 / 4;
116 int y1 = y + size / 4, y2 = y + size * 3 / 4;
118 if (size == 1) {
119 pass = pass && piglit_probe_pixel_rgb(x1, y1, color1);
120 } else {
121 pass = pass && piglit_probe_pixel_rgb(x1, y1, color2);
122 pass = pass && piglit_probe_pixel_rgb(x2, y1, color1);
123 pass = pass && piglit_probe_pixel_rgb(x2, y2, color1);
124 pass = pass && piglit_probe_pixel_rgb(x1, y2, color1);
127 if (!pass) {
128 int base_size = size * (1 << level);
129 printf("Cube map failed at size %dx%d, level %d (%dx%d), face %s%s\n",
130 base_size, base_size, level, size, size,
131 cube_face_names[face],
132 mipmapped ? ", mipmapped" : "");
135 return pass;
138 static GLboolean
139 draw_at_size(int size, int x_offset, int y_offset, GLboolean mipmapped)
141 GLfloat row_y = PAD + y_offset;
142 int dim, face;
143 int color = 0, level = 0;
144 GLuint texname;
145 GLboolean pass = GL_TRUE;
147 /* Create the texture. */
148 glGenTextures(1, &texname);
149 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, texname);
151 /* For each face drawing, we want to only see that face's contents at
152 * that mipmap level.
154 if (mipmapped) {
155 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,
156 GL_TEXTURE_MIN_FILTER,
157 GL_NEAREST_MIPMAP_NEAREST);
158 } else {
159 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,
160 GL_TEXTURE_MIN_FILTER,
161 GL_NEAREST);
163 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,
164 GL_TEXTURE_MAG_FILTER, GL_NEAREST);
165 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,
166 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
167 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,
168 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
170 /* Fill in faces on each level */
171 for (dim = size; dim > 0; dim /= 2) {
172 for (face = 0; face < 6; face++) {
173 set_face_image(level, cube_face_targets[face],
174 dim, color);
175 color = (color + 1) % ARRAY_SIZE(colors);
177 if (!mipmapped)
178 break;
180 level++;
183 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
185 color = 0;
186 level = 0;
187 for (dim = size; dim > 0; dim /= 2) {
188 GLfloat row_x = PAD + x_offset;
190 for (face = 0; face < 6; face++) {
191 GLfloat base_x = row_x + face * (MAX_SIZE + PAD);
192 GLfloat base_y = row_y;
194 glBegin(GL_QUADS);
196 glTexCoord3fv(cube_face_texcoords[face][0]);
197 glVertex2f(base_x, base_y);
199 glTexCoord3fv(cube_face_texcoords[face][1]);
200 glVertex2f(base_x + dim, base_y);
202 glTexCoord3fv(cube_face_texcoords[face][2]);
203 glVertex2f(base_x + dim, base_y + dim);
205 glTexCoord3fv(cube_face_texcoords[face][3]);
206 glVertex2f(base_x, base_y + dim);
208 glEnd();
210 if (dim > 2) {
211 pass = test_results(base_x, base_y,
212 dim, level, face,
213 mipmapped,
214 color) && pass;
217 color = (color + 1) % ARRAY_SIZE(colors);
220 if (!mipmapped)
221 break;
223 row_y += dim + PAD;
224 level++;
227 glDeleteTextures(1, &texname);
229 return pass;
233 enum piglit_result
234 piglit_display(void)
236 int dim;
237 GLboolean pass = GL_TRUE;
238 int i = 0, y_offset = 0;
239 int row_dim = 0;
241 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
243 /* Clear background to gray */
244 glClearColor(0.5, 0.5, 0.5, 1.0);
245 glClear(GL_COLOR_BUFFER_BIT);
247 /* First, do each size from MAX_SIZExMAX_SIZE to 1x1 as a
248 * single texture level.
250 y_offset = 0;
251 for (dim = MAX_SIZE; dim > 0; dim /= 2) {
252 pass = draw_at_size(dim, 0, y_offset, GL_FALSE) && pass;
253 y_offset += dim + PAD;
256 /* Next, do each size with mipmaps from MAX_SIZExMAX_SIZE
257 * to 1x1.
259 y_offset = 0;
260 for (dim = MAX_SIZE; dim > 0; dim /= 2) {
261 int x_offset = (i % 2 == 1) ? 0 : WIN_WIDTH / 2;
263 row_dim = (row_dim < dim) ? dim : row_dim;
265 pass &= draw_at_size(dim, x_offset, y_offset, GL_TRUE);
266 if (i % 2 == 0) {
267 y_offset += row_dim * 2 + (ffs(dim) + 3) * PAD;
268 row_dim = 0;
270 i++;
273 glutSwapBuffers();
275 return pass ? PIGLIT_SUCCESS : PIGLIT_FAILURE;
278 void
279 piglit_init(int argc, char **argv)
281 piglit_require_extension("GL_ARB_texture_cube_map");