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