Merge branch 'master' into i915-unification
[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/glut.h>
38 #include <GL/glext.h>
39
40 #if !defined(GL_EXT_texture_array) && !defined(GL_MESA_texture_array)
41 # error "This demo requires enums for either GL_EXT_texture_array or GL_MESA_texture_array to build."
42 #endif
43
44 #include "readtex.h"
45
46 #define GL_CHECK_ERROR() \
47 do { \
48 GLenum err = glGetError(); \
49 if (err) { \
50 printf("%s:%u: %s (0x%04x)\n", __FILE__, __LINE__, \
51 gluErrorString(err), err); \
52 } \
53 } while (0)
54
55 static const char *const textures[] = {
56 "../images/girl.rgb",
57 "../images/girl2.rgb",
58 "../images/arch.rgb",
59 "../images/s128.rgb",
60
61 "../images/tree3.rgb",
62 "../images/bw.rgb",
63 "../images/reflect.rgb",
64 "../images/wrs_logo.rgb",
65 NULL
66 };
67
68 static const char frag_prog[] =
69 "!!ARBfp1.0\n"
70 "OPTION MESA_texture_array;\n"
71 "TEX result.color, fragment.texcoord[0], texture[0], ARRAY2D;\n"
72 "END\n";
73
74 static GLfloat Xrot = 0, Yrot = -30, Zrot = 0;
75 static GLfloat texZ = 0.0;
76 static GLfloat texZ_dir = 0.01;
77 static GLint num_layers;
78
79 static PFNGLBINDPROGRAMARBPROC bind_program;
80 static PFNGLPROGRAMSTRINGARBPROC program_string;
81 static PFNGLGENPROGRAMSARBPROC gen_programs;
82
83
84 static void
85 PrintString(const char *s)
86 {
87 while (*s) {
88 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
89 s++;
90 }
91 }
92
93
94 static void Idle(void)
95 {
96 static int lastTime = 0;
97 int t = glutGet(GLUT_ELAPSED_TIME);
98
99 if (lastTime == 0)
100 lastTime = t;
101 else if (t - lastTime < 10)
102 return;
103
104 lastTime = t;
105
106 texZ += texZ_dir;
107 if ((texZ < 0.0) || ((GLint) texZ > num_layers)) {
108 texZ_dir = -texZ_dir;
109 }
110
111 glutPostRedisplay();
112 }
113
114
115 static void Display(void)
116 {
117 char str[100];
118
119 glClear(GL_COLOR_BUFFER_BIT);
120
121 glMatrixMode(GL_PROJECTION);
122 glLoadIdentity();
123 glOrtho(-1, 1, -1, 1, -1, 1);
124 glMatrixMode(GL_MODELVIEW);
125 glLoadIdentity();
126
127 (*bind_program)(GL_FRAGMENT_PROGRAM_ARB, 0);
128 glColor3f(1,1,1);
129 glRasterPos3f(-0.9, -0.9, 0.0);
130 sprintf(str, "Texture Z coordinate = %4.1f", texZ);
131 PrintString(str);
132
133 (*bind_program)(GL_FRAGMENT_PROGRAM_ARB, 1);
134 GL_CHECK_ERROR();
135 glEnable(GL_TEXTURE_2D_ARRAY_EXT);
136 GL_CHECK_ERROR();
137
138 glMatrixMode(GL_PROJECTION);
139 glLoadIdentity();
140 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
141 glMatrixMode(GL_MODELVIEW);
142 glLoadIdentity();
143 glTranslatef(0.0, 0.0, -8.0);
144
145 glPushMatrix();
146 glRotatef(Xrot, 1, 0, 0);
147 glRotatef(Yrot, 0, 1, 0);
148 glRotatef(Zrot, 0, 0, 1);
149
150 glBegin(GL_QUADS);
151 glTexCoord3f(0.0, 0.0, texZ); glVertex2f(-1.0, -1.0);
152 glTexCoord3f(2.0, 0.0, texZ); glVertex2f(1.0, -1.0);
153 glTexCoord3f(2.0, 2.0, texZ); glVertex2f(1.0, 1.0);
154 glTexCoord3f(0.0, 2.0, texZ); glVertex2f(-1.0, 1.0);
155 glEnd();
156
157 glPopMatrix();
158
159 glDisable(GL_TEXTURE_2D_ARRAY_EXT);
160 GL_CHECK_ERROR();
161 (*bind_program)(GL_FRAGMENT_PROGRAM_ARB, 0);
162 GL_CHECK_ERROR();
163
164 glutSwapBuffers();
165 }
166
167
168 static void Reshape(int width, int height)
169 {
170 glViewport(0, 0, width, height);
171 }
172
173
174 static void Key(unsigned char key, int x, int y)
175 {
176 (void) x;
177 (void) y;
178 switch (key) {
179 case 27:
180 exit(0);
181 break;
182 }
183 glutPostRedisplay();
184 }
185
186
187 static void SpecialKey(int key, int x, int y)
188 {
189 const GLfloat step = 3.0;
190 (void) x;
191 (void) y;
192 switch (key) {
193 case GLUT_KEY_UP:
194 Xrot -= step;
195 break;
196 case GLUT_KEY_DOWN:
197 Xrot += step;
198 break;
199 case GLUT_KEY_LEFT:
200 Yrot -= step;
201 break;
202 case GLUT_KEY_RIGHT:
203 Yrot += step;
204 break;
205 }
206 glutPostRedisplay();
207 }
208
209
210 static int FindLine(const char *program, int position)
211 {
212 int i, line = 1;
213 for (i = 0; i < position; i++) {
214 if (program[i] == '\n')
215 line++;
216 }
217 return line;
218 }
219
220
221 static void
222 compile_fragment_program(GLuint id, const char *prog)
223 {
224 int errorPos;
225 int err;
226
227 err = glGetError();
228 (*bind_program)(GL_FRAGMENT_PROGRAM_ARB, id);
229 (*program_string)(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
230 strlen(prog), (const GLubyte *) prog);
231
232 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorPos);
233 err = glGetError();
234 if (err != GL_NO_ERROR || errorPos != -1) {
235 int l = FindLine(prog, errorPos);
236
237 printf("Fragment Program Error (err=%d, pos=%d line=%d): %s\n",
238 err, errorPos, l,
239 (char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB));
240 exit(0);
241 }
242 }
243
244
245 static void require_extension(const char *ext)
246 {
247 if (!glutExtensionSupported(ext)) {
248 printf("Sorry, %s not supported by this renderer.\n", ext);
249 exit(1);
250 }
251 }
252
253
254 static void Init(void)
255 {
256 const char *const ver_string = (const char *const) glGetString(GL_VERSION);
257 unsigned i;
258
259 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
260 printf("GL_VERSION = %s\n", ver_string);
261
262 require_extension("GL_ARB_fragment_program");
263 require_extension("GL_MESA_texture_array");
264 require_extension("GL_SGIS_generate_mipmap");
265
266 bind_program = glutGetProcAddress("glBindProgramARB");
267 program_string = glutGetProcAddress("glProgramStringARB");
268 gen_programs = glutGetProcAddress("glGenProgramsARB");
269
270
271 for (num_layers = 0; textures[num_layers] != NULL; num_layers++)
272 /* empty */ ;
273
274 glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, 1);
275 glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_RGB8,
276 256, 256, num_layers, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
277 GL_CHECK_ERROR();
278
279 glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_GENERATE_MIPMAP_SGIS,
280 GL_TRUE);
281
282 for (i = 0; textures[i] != NULL; i++) {
283 GLint width, height;
284 GLenum format;
285
286 GLubyte *image = LoadRGBImage(textures[i], &width, &height, &format);
287 if (!image) {
288 printf("Error: could not load texture image %s\n", textures[i]);
289 exit(1);
290 }
291
292 /* resize to 256 x 256 */
293 if (width != 256 || height != 256) {
294 GLubyte *newImage = malloc(256 * 256 * 4);
295 gluScaleImage(format, width, height, GL_UNSIGNED_BYTE, image,
296 256, 256, GL_UNSIGNED_BYTE, newImage);
297 free(image);
298 image = newImage;
299 }
300
301 glTexSubImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0,
302 0, 0, i, 256, 256, 1,
303 format, GL_UNSIGNED_BYTE, image);
304 free(image);
305 }
306 GL_CHECK_ERROR();
307
308 glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_S, GL_REPEAT);
309 glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_T, GL_REPEAT);
310 glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
311
312 glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
313 GL_CHECK_ERROR();
314 glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
315 GL_CHECK_ERROR();
316
317 compile_fragment_program(1, frag_prog);
318 GL_CHECK_ERROR();
319 }
320
321
322 int main(int argc, char *argv[])
323 {
324 glutInit(&argc, argv);
325 glutInitWindowPosition(0, 0);
326 glutInitWindowSize(350, 350);
327 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
328 glutCreateWindow("Array texture test");
329 glutReshapeFunc(Reshape);
330 glutKeyboardFunc(Key);
331 glutSpecialFunc(SpecialKey);
332 glutDisplayFunc(Display);
333 glutIdleFunc(Idle);
334 Init();
335 glutMainLoop();
336 return 0;
337 }