132001f49Smrg/* 232001f49Smrg * (C) Copyright IBM Corporation 2007 332001f49Smrg * All Rights Reserved. 432001f49Smrg * 532001f49Smrg * Permission is hereby granted, free of charge, to any person obtaining a 632001f49Smrg * copy of this software and associated documentation files (the "Software"), 732001f49Smrg * to deal in the Software without restriction, including without limitation 832001f49Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub 932001f49Smrg * license, and/or sell copies of the Software, and to permit persons to whom 1032001f49Smrg * the Software is furnished to do so, subject to the following conditions: 1132001f49Smrg * 1232001f49Smrg * The above copyright notice and this permission notice (including the next 1332001f49Smrg * paragraph) shall be included in all copies or substantial portions of the 1432001f49Smrg * Software. 1532001f49Smrg * 1632001f49Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1732001f49Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1832001f49Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 1932001f49Smrg * IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2032001f49Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2132001f49Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2232001f49Smrg * IN THE SOFTWARE. 2332001f49Smrg */ 2432001f49Smrg 2532001f49Smrg/** 2632001f49Smrg * \file arraytexture.c 2732001f49Smrg * 2832001f49Smrg * 2932001f49Smrg * \author Ian Romanick <idr@us.ibm.com> 3032001f49Smrg */ 3132001f49Smrg 3232001f49Smrg#include <assert.h> 3332001f49Smrg#include <stdlib.h> 3432001f49Smrg#include <stdio.h> 3532001f49Smrg#include <string.h> 3632001f49Smrg#include <math.h> 3732001f49Smrg#include <GL/glew.h> 3832001f49Smrg#include "glut_wrap.h" 3932001f49Smrg 4032001f49Smrg#if !defined(GL_EXT_texture_array) && !defined(GL_MESA_texture_array) 4132001f49Smrg# error "This demo requires enums for either GL_EXT_texture_array or GL_MESA_texture_array to build." 4232001f49Smrg#endif 4332001f49Smrg 4432001f49Smrg#include "readtex.h" 4532001f49Smrg 4632001f49Smrg#define GL_CHECK_ERROR() \ 4732001f49Smrg do { \ 4832001f49Smrg GLenum err = glGetError(); \ 4932001f49Smrg if (err) { \ 5032001f49Smrg printf("%s:%u: %s (0x%04x)\n", __FILE__, __LINE__, \ 5132001f49Smrg gluErrorString(err), err); \ 5232001f49Smrg } \ 5332001f49Smrg } while (0) 5432001f49Smrg 5532001f49Smrgstatic const char *const textures[] = { 5632001f49Smrg DEMOS_DATA_DIR "girl.rgb", 5732001f49Smrg DEMOS_DATA_DIR "girl2.rgb", 5832001f49Smrg DEMOS_DATA_DIR "arch.rgb", 5932001f49Smrg DEMOS_DATA_DIR "s128.rgb", 6032001f49Smrg 6132001f49Smrg DEMOS_DATA_DIR "tree3.rgb", 6232001f49Smrg DEMOS_DATA_DIR "bw.rgb", 6332001f49Smrg DEMOS_DATA_DIR "reflect.rgb", 6432001f49Smrg DEMOS_DATA_DIR "wrs_logo.rgb", 6532001f49Smrg NULL 6632001f49Smrg}; 6732001f49Smrg 6832001f49Smrgstatic const char frag_prog[] = 6932001f49Smrg "!!ARBfp1.0\n" 7032001f49Smrg "OPTION MESA_texture_array;\n" 7132001f49Smrg "TEX result.color, fragment.texcoord[0], texture[0], ARRAY2D;\n" 7232001f49Smrg "END\n"; 7332001f49Smrg 7432001f49Smrgstatic GLfloat Xrot = 0, Yrot = -30, Zrot = 0; 7532001f49Smrgstatic GLfloat texZ = 0.0; 7632001f49Smrgstatic GLfloat texZ_dir = 0.01; 7732001f49Smrgstatic GLint num_layers; 7832001f49Smrg 7932001f49Smrg 8032001f49Smrgstatic void 8132001f49SmrgPrintString(const char *s) 8232001f49Smrg{ 8332001f49Smrg while (*s) { 8432001f49Smrg glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); 8532001f49Smrg s++; 8632001f49Smrg } 8732001f49Smrg} 8832001f49Smrg 8932001f49Smrg 9032001f49Smrgstatic void Idle(void) 9132001f49Smrg{ 9232001f49Smrg static int lastTime = 0; 9332001f49Smrg int t = glutGet(GLUT_ELAPSED_TIME); 9432001f49Smrg 9532001f49Smrg if (lastTime == 0) 9632001f49Smrg lastTime = t; 9732001f49Smrg else if (t - lastTime < 10) 9832001f49Smrg return; 9932001f49Smrg 10032001f49Smrg lastTime = t; 10132001f49Smrg 10232001f49Smrg texZ += texZ_dir; 10332001f49Smrg if ((texZ < 0.0) || ((GLint) texZ > num_layers)) { 10432001f49Smrg texZ_dir = -texZ_dir; 10532001f49Smrg } 10632001f49Smrg 10732001f49Smrg glutPostRedisplay(); 10832001f49Smrg} 10932001f49Smrg 11032001f49Smrg 11132001f49Smrgstatic void Display(void) 11232001f49Smrg{ 11332001f49Smrg char str[100]; 11432001f49Smrg 11532001f49Smrg glClear(GL_COLOR_BUFFER_BIT); 11632001f49Smrg 11732001f49Smrg glMatrixMode(GL_PROJECTION); 11832001f49Smrg glLoadIdentity(); 11932001f49Smrg glOrtho(-1, 1, -1, 1, -1, 1); 12032001f49Smrg glMatrixMode(GL_MODELVIEW); 12132001f49Smrg glLoadIdentity(); 12232001f49Smrg 12332001f49Smrg glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0); 12432001f49Smrg glColor3f(1,1,1); 12532001f49Smrg glRasterPos3f(-0.9, -0.9, 0.0); 12632001f49Smrg sprintf(str, "Texture Z coordinate = %4.1f", texZ); 12732001f49Smrg PrintString(str); 12832001f49Smrg 12932001f49Smrg glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 1); 13032001f49Smrg GL_CHECK_ERROR(); 13132001f49Smrg glEnable(GL_TEXTURE_2D_ARRAY_EXT); 13232001f49Smrg GL_CHECK_ERROR(); 13332001f49Smrg 13432001f49Smrg glMatrixMode(GL_PROJECTION); 13532001f49Smrg glLoadIdentity(); 13632001f49Smrg glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); 13732001f49Smrg glMatrixMode(GL_MODELVIEW); 13832001f49Smrg glLoadIdentity(); 13932001f49Smrg glTranslatef(0.0, 0.0, -8.0); 14032001f49Smrg 14132001f49Smrg glPushMatrix(); 14232001f49Smrg glRotatef(Xrot, 1, 0, 0); 14332001f49Smrg glRotatef(Yrot, 0, 1, 0); 14432001f49Smrg glRotatef(Zrot, 0, 0, 1); 14532001f49Smrg 14632001f49Smrg glBegin(GL_QUADS); 14732001f49Smrg glTexCoord3f(0.0, 0.0, texZ); glVertex2f(-1.0, -1.0); 14832001f49Smrg glTexCoord3f(2.0, 0.0, texZ); glVertex2f(1.0, -1.0); 14932001f49Smrg glTexCoord3f(2.0, 2.0, texZ); glVertex2f(1.0, 1.0); 15032001f49Smrg glTexCoord3f(0.0, 2.0, texZ); glVertex2f(-1.0, 1.0); 15132001f49Smrg glEnd(); 15232001f49Smrg 15332001f49Smrg glPopMatrix(); 15432001f49Smrg 15532001f49Smrg glDisable(GL_TEXTURE_2D_ARRAY_EXT); 15632001f49Smrg GL_CHECK_ERROR(); 15732001f49Smrg glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0); 15832001f49Smrg GL_CHECK_ERROR(); 15932001f49Smrg 16032001f49Smrg glutSwapBuffers(); 16132001f49Smrg} 16232001f49Smrg 16332001f49Smrg 16432001f49Smrgstatic void Reshape(int width, int height) 16532001f49Smrg{ 16632001f49Smrg glViewport(0, 0, width, height); 16732001f49Smrg} 16832001f49Smrg 16932001f49Smrg 17032001f49Smrgstatic void Key(unsigned char key, int x, int y) 17132001f49Smrg{ 17232001f49Smrg (void) x; 17332001f49Smrg (void) y; 17432001f49Smrg switch (key) { 17532001f49Smrg case 27: 17632001f49Smrg exit(0); 17732001f49Smrg break; 17832001f49Smrg } 17932001f49Smrg glutPostRedisplay(); 18032001f49Smrg} 18132001f49Smrg 18232001f49Smrg 18332001f49Smrgstatic void SpecialKey(int key, int x, int y) 18432001f49Smrg{ 18532001f49Smrg const GLfloat step = 3.0; 18632001f49Smrg (void) x; 18732001f49Smrg (void) y; 18832001f49Smrg switch (key) { 18932001f49Smrg case GLUT_KEY_UP: 19032001f49Smrg Xrot -= step; 19132001f49Smrg break; 19232001f49Smrg case GLUT_KEY_DOWN: 19332001f49Smrg Xrot += step; 19432001f49Smrg break; 19532001f49Smrg case GLUT_KEY_LEFT: 19632001f49Smrg Yrot -= step; 19732001f49Smrg break; 19832001f49Smrg case GLUT_KEY_RIGHT: 19932001f49Smrg Yrot += step; 20032001f49Smrg break; 20132001f49Smrg } 20232001f49Smrg glutPostRedisplay(); 20332001f49Smrg} 20432001f49Smrg 20532001f49Smrg 20632001f49Smrgstatic int FindLine(const char *program, int position) 20732001f49Smrg{ 20832001f49Smrg int i, line = 1; 20932001f49Smrg for (i = 0; i < position; i++) { 21032001f49Smrg if (program[i] == '\n') 21132001f49Smrg line++; 21232001f49Smrg } 21332001f49Smrg return line; 21432001f49Smrg} 21532001f49Smrg 21632001f49Smrg 21732001f49Smrgstatic void 21832001f49Smrgcompile_fragment_program(GLuint id, const char *prog) 21932001f49Smrg{ 22032001f49Smrg int errorPos; 22132001f49Smrg int err; 22232001f49Smrg 22332001f49Smrg err = glGetError(); 22432001f49Smrg glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, id); 22532001f49Smrg glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, 22632001f49Smrg strlen(prog), (const GLubyte *) prog); 22732001f49Smrg 22832001f49Smrg glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorPos); 22932001f49Smrg err = glGetError(); 23032001f49Smrg if (err != GL_NO_ERROR || errorPos != -1) { 23132001f49Smrg int l = FindLine(prog, errorPos); 23232001f49Smrg 23332001f49Smrg printf("Fragment Program Error (err=%d, pos=%d line=%d): %s\n", 23432001f49Smrg err, errorPos, l, 23532001f49Smrg (char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB)); 23632001f49Smrg exit(0); 23732001f49Smrg } 23832001f49Smrg} 23932001f49Smrg 24032001f49Smrg 24132001f49Smrgstatic void require_extension(const char *ext) 24232001f49Smrg{ 24332001f49Smrg if (!glutExtensionSupported(ext)) { 24432001f49Smrg printf("Sorry, %s not supported by this renderer.\n", ext); 24532001f49Smrg exit(1); 24632001f49Smrg } 24732001f49Smrg} 24832001f49Smrg 24932001f49Smrg 25032001f49Smrgstatic void Init(void) 25132001f49Smrg{ 25232001f49Smrg const char *const ver_string = (const char *) glGetString(GL_VERSION); 25332001f49Smrg unsigned i; 25432001f49Smrg 25532001f49Smrg printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); 25632001f49Smrg printf("GL_VERSION = %s\n", ver_string); 25732001f49Smrg 25832001f49Smrg require_extension("GL_ARB_fragment_program"); 25932001f49Smrg require_extension("GL_MESA_texture_array"); 26032001f49Smrg require_extension("GL_SGIS_generate_mipmap"); 26132001f49Smrg 26232001f49Smrg for (num_layers = 0; textures[num_layers] != NULL; num_layers++) 26332001f49Smrg /* empty */ ; 26432001f49Smrg 26532001f49Smrg glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, 1); 26632001f49Smrg glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_RGB8, 26732001f49Smrg 256, 256, num_layers, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); 26832001f49Smrg GL_CHECK_ERROR(); 26932001f49Smrg 27032001f49Smrg glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_GENERATE_MIPMAP_SGIS, 27132001f49Smrg GL_TRUE); 27232001f49Smrg 27332001f49Smrg for (i = 0; textures[i] != NULL; i++) { 27432001f49Smrg GLint width, height; 27532001f49Smrg GLenum format; 27632001f49Smrg 27732001f49Smrg GLubyte *image = LoadRGBImage(textures[i], &width, &height, &format); 27832001f49Smrg if (!image) { 27932001f49Smrg printf("Error: could not load texture image %s\n", textures[i]); 28032001f49Smrg exit(1); 28132001f49Smrg } 28232001f49Smrg 28332001f49Smrg /* resize to 256 x 256 */ 28432001f49Smrg if (width != 256 || height != 256) { 28532001f49Smrg GLubyte *newImage = malloc(256 * 256 * 4); 28632001f49Smrg gluScaleImage(format, width, height, GL_UNSIGNED_BYTE, image, 28732001f49Smrg 256, 256, GL_UNSIGNED_BYTE, newImage); 28832001f49Smrg free(image); 28932001f49Smrg image = newImage; 29032001f49Smrg } 29132001f49Smrg 29232001f49Smrg glTexSubImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, 29332001f49Smrg 0, 0, i, 256, 256, 1, 29432001f49Smrg format, GL_UNSIGNED_BYTE, image); 29532001f49Smrg free(image); 29632001f49Smrg } 29732001f49Smrg GL_CHECK_ERROR(); 29832001f49Smrg 29932001f49Smrg glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_S, GL_REPEAT); 30032001f49Smrg glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_T, GL_REPEAT); 30132001f49Smrg glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 30232001f49Smrg 30332001f49Smrg glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 30432001f49Smrg GL_CHECK_ERROR(); 30532001f49Smrg glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 30632001f49Smrg GL_CHECK_ERROR(); 30732001f49Smrg 30832001f49Smrg compile_fragment_program(1, frag_prog); 30932001f49Smrg GL_CHECK_ERROR(); 31032001f49Smrg} 31132001f49Smrg 31232001f49Smrg 31332001f49Smrgint main(int argc, char *argv[]) 31432001f49Smrg{ 31532001f49Smrg glutInit(&argc, argv); 31632001f49Smrg glutInitWindowPosition(0, 0); 31732001f49Smrg glutInitWindowSize(350, 350); 31832001f49Smrg glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 31932001f49Smrg glutCreateWindow("Array texture test"); 32032001f49Smrg glewInit(); 32132001f49Smrg glutReshapeFunc(Reshape); 32232001f49Smrg glutKeyboardFunc(Key); 32332001f49Smrg glutSpecialFunc(SpecialKey); 32432001f49Smrg glutDisplayFunc(Display); 32532001f49Smrg glutIdleFunc(Idle); 32632001f49Smrg Init(); 32732001f49Smrg glutMainLoop(); 32832001f49Smrg return 0; 32932001f49Smrg} 330