Merge branch 'mesa_7_6_branch'
[mesa.git] / progs / tests / arraytexture.c
1 /*
2 * (C) Copyright IBM Corporation 2007
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25 /**
26 * \file arraytexture.c
27 *
28 *
29 * \author Ian Romanick <idr@us.ibm.com>
30 */
31
32 #include <assert.h>
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <math.h>
37 #include <GL/glew.h>
38 #include <GL/glut.h>
39 #include <GL/glext.h>
40
41 #if !defined(GL_EXT_texture_array) && !defined(GL_MESA_texture_array)
42 # error "This demo requires enums for either GL_EXT_texture_array or GL_MESA_texture_array to build."
43 #endif
44
45 #include "readtex.h"
46
47 #define GL_CHECK_ERROR() \
48 do { \
49 GLenum err = glGetError(); \
50 if (err) { \
51 printf("%s:%u: %s (0x%04x)\n", __FILE__, __LINE__, \
52 gluErrorString(err), err); \
53 } \
54 } while (0)
55
56 static const char *const textures[] = {
57 "../images/girl.rgb",
58 "../images/girl2.rgb",
59 "../images/arch.rgb",
60 "../images/s128.rgb",
61
62 "../images/tree3.rgb",
63 "../images/bw.rgb",
64 "../images/reflect.rgb",
65 "../images/wrs_logo.rgb",
66 NULL
67 };
68
69 static const char frag_prog[] =
70 "!!ARBfp1.0\n"
71 "OPTION MESA_texture_array;\n"
72 "TEX result.color, fragment.texcoord[0], texture[0], ARRAY2D;\n"
73 "END\n";
74
75 static GLfloat Xrot = 0, Yrot = -30, Zrot = 0;
76 static GLfloat texZ = 0.0;
77 static GLfloat texZ_dir = 0.01;
78 static GLint num_layers;
79
80
81 static void
82 PrintString(const char *s)
83 {
84 while (*s) {
85 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
86 s++;
87 }
88 }
89
90
91 static void Idle(void)
92 {
93 static int lastTime = 0;
94 int t = glutGet(GLUT_ELAPSED_TIME);
95
96 if (lastTime == 0)
97 lastTime = t;
98 else if (t - lastTime < 10)
99 return;
100
101 lastTime = t;
102
103 texZ += texZ_dir;
104 if ((texZ < 0.0) || ((GLint) texZ > num_layers)) {
105 texZ_dir = -texZ_dir;
106 }
107
108 glutPostRedisplay();
109 }
110
111
112 static void Display(void)
113 {
114 char str[100];
115
116 glClear(GL_COLOR_BUFFER_BIT);
117
118 glMatrixMode(GL_PROJECTION);
119 glLoadIdentity();
120 glOrtho(-1, 1, -1, 1, -1, 1);
121 glMatrixMode(GL_MODELVIEW);
122 glLoadIdentity();
123
124 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0);
125 glColor3f(1,1,1);
126 glRasterPos3f(-0.9, -0.9, 0.0);
127 sprintf(str, "Texture Z coordinate = %4.1f", texZ);
128 PrintString(str);
129
130 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 1);
131 GL_CHECK_ERROR();
132 glEnable(GL_TEXTURE_2D_ARRAY_EXT);
133 GL_CHECK_ERROR();
134
135 glMatrixMode(GL_PROJECTION);
136 glLoadIdentity();
137 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
138 glMatrixMode(GL_MODELVIEW);
139 glLoadIdentity();
140 glTranslatef(0.0, 0.0, -8.0);
141
142 glPushMatrix();
143 glRotatef(Xrot, 1, 0, 0);
144 glRotatef(Yrot, 0, 1, 0);
145 glRotatef(Zrot, 0, 0, 1);
146
147 glBegin(GL_QUADS);
148 glTexCoord3f(0.0, 0.0, texZ); glVertex2f(-1.0, -1.0);
149 glTexCoord3f(2.0, 0.0, texZ); glVertex2f(1.0, -1.0);
150 glTexCoord3f(2.0, 2.0, texZ); glVertex2f(1.0, 1.0);
151 glTexCoord3f(0.0, 2.0, texZ); glVertex2f(-1.0, 1.0);
152 glEnd();
153
154 glPopMatrix();
155
156 glDisable(GL_TEXTURE_2D_ARRAY_EXT);
157 GL_CHECK_ERROR();
158 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0);
159 GL_CHECK_ERROR();
160
161 glutSwapBuffers();
162 }
163
164
165 static void Reshape(int width, int height)
166 {
167 glViewport(0, 0, width, height);
168 }
169
170
171 static void Key(unsigned char key, int x, int y)
172 {
173 (void) x;
174 (void) y;
175 switch (key) {
176 case 27:
177 exit(0);
178 break;
179 }
180 glutPostRedisplay();
181 }
182
183
184 static void SpecialKey(int key, int x, int y)
185 {
186 const GLfloat step = 3.0;
187 (void) x;
188 (void) y;
189 switch (key) {
190 case GLUT_KEY_UP:
191 Xrot -= step;
192 break;
193 case GLUT_KEY_DOWN:
194 Xrot += step;
195 break;
196 case GLUT_KEY_LEFT:
197 Yrot -= step;
198 break;
199 case GLUT_KEY_RIGHT:
200 Yrot += step;
201 break;
202 }
203 glutPostRedisplay();
204 }
205
206
207 static int FindLine(const char *program, int position)
208 {
209 int i, line = 1;
210 for (i = 0; i < position; i++) {
211 if (program[i] == '\n')
212 line++;
213 }
214 return line;
215 }
216
217
218 static void
219 compile_fragment_program(GLuint id, const char *prog)
220 {
221 int errorPos;
222 int err;
223
224 err = glGetError();
225 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, id);
226 glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
227 strlen(prog), (const GLubyte *) prog);
228
229 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorPos);
230 err = glGetError();
231 if (err != GL_NO_ERROR || errorPos != -1) {
232 int l = FindLine(prog, errorPos);
233
234 printf("Fragment Program Error (err=%d, pos=%d line=%d): %s\n",
235 err, errorPos, l,
236 (char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB));
237 exit(0);
238 }
239 }
240
241
242 static void require_extension(const char *ext)
243 {
244 if (!glutExtensionSupported(ext)) {
245 printf("Sorry, %s not supported by this renderer.\n", ext);
246 exit(1);
247 }
248 }
249
250
251 static void Init(void)
252 {
253 const char *const ver_string = (const char *const) glGetString(GL_VERSION);
254 unsigned i;
255
256 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
257 printf("GL_VERSION = %s\n", ver_string);
258
259 require_extension("GL_ARB_fragment_program");
260 require_extension("GL_MESA_texture_array");
261 require_extension("GL_SGIS_generate_mipmap");
262
263 for (num_layers = 0; textures[num_layers] != NULL; num_layers++)
264 /* empty */ ;
265
266 glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, 1);
267 glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_RGB8,
268 256, 256, num_layers, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
269 GL_CHECK_ERROR();
270
271 glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_GENERATE_MIPMAP_SGIS,
272 GL_TRUE);
273
274 for (i = 0; textures[i] != NULL; i++) {
275 GLint width, height;
276 GLenum format;
277
278 GLubyte *image = LoadRGBImage(textures[i], &width, &height, &format);
279 if (!image) {
280 printf("Error: could not load texture image %s\n", textures[i]);
281 exit(1);
282 }
283
284 /* resize to 256 x 256 */
285 if (width != 256 || height != 256) {
286 GLubyte *newImage = malloc(256 * 256 * 4);
287 gluScaleImage(format, width, height, GL_UNSIGNED_BYTE, image,
288 256, 256, GL_UNSIGNED_BYTE, newImage);
289 free(image);
290 image = newImage;
291 }
292
293 glTexSubImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0,
294 0, 0, i, 256, 256, 1,
295 format, GL_UNSIGNED_BYTE, image);
296 free(image);
297 }
298 GL_CHECK_ERROR();
299
300 glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_S, GL_REPEAT);
301 glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_T, GL_REPEAT);
302 glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
303
304 glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
305 GL_CHECK_ERROR();
306 glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
307 GL_CHECK_ERROR();
308
309 compile_fragment_program(1, frag_prog);
310 GL_CHECK_ERROR();
311 }
312
313
314 int main(int argc, char *argv[])
315 {
316 glutInit(&argc, argv);
317 glutInitWindowPosition(0, 0);
318 glutInitWindowSize(350, 350);
319 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
320 glutCreateWindow("Array texture test");
321 glewInit();
322 glutReshapeFunc(Reshape);
323 glutKeyboardFunc(Key);
324 glutSpecialFunc(SpecialKey);
325 glutDisplayFunc(Display);
326 glutIdleFunc(Idle);
327 Init();
328 glutMainLoop();
329 return 0;
330 }