132001f49Smrg 232001f49Smrg/* projtex.c - by David Yu and David Blythe, SGI */ 332001f49Smrg 432001f49Smrg/** 532001f49Smrg ** Demonstrates simple projective texture mapping. 632001f49Smrg ** 732001f49Smrg ** Button1 changes view, Button2 moves texture. 832001f49Smrg ** 932001f49Smrg ** (See: Segal, Korobkin, van Widenfelt, Foran, and Haeberli 1032001f49Smrg ** "Fast Shadows and Lighting Effects Using Texture Mapping", SIGGRAPH '92) 1132001f49Smrg ** 1232001f49Smrg ** 1994,1995 -- David G Yu 1332001f49Smrg ** 1432001f49Smrg ** cc -o projtex projtex.c texture.c -lglut -lGLU -lGL -lX11 -lm 1532001f49Smrg **/ 1632001f49Smrg 1732001f49Smrg#include <assert.h> 1832001f49Smrg#include <stdio.h> 1932001f49Smrg#include <stdlib.h> 2032001f49Smrg#include <math.h> 2132001f49Smrg#include <GL/glew.h> 2232001f49Smrg#include "glut_wrap.h" 2332001f49Smrg#include "readtex.h" 2432001f49Smrg 2532001f49Smrg 2632001f49Smrg/* Some <math.h> files do not define M_PI... */ 2732001f49Smrg#ifndef M_PI 2832001f49Smrg#define M_PI 3.14159265358979323846 2932001f49Smrg#endif 3032001f49Smrg 3132001f49Smrg#define MAX_TEX 4 3232001f49Smrgint NumTextures = 1; 3332001f49Smrg 3432001f49Smrgint winWidth, winHeight; 3532001f49Smrg 3632001f49SmrgGLboolean redrawContinuously = GL_FALSE; 3732001f49Smrg 3832001f49Smrgfloat angle, axis[3]; 3932001f49Smrgenum MoveModes { 4032001f49Smrg MoveNone, MoveView, MoveObject, MoveTexture 4132001f49Smrg}; 4232001f49Smrgenum MoveModes mode = MoveNone; 4332001f49Smrg 4432001f49SmrgGLfloat objectXform[4][4]; 4532001f49SmrgGLfloat textureXform[MAX_TEX][4][4]; 4632001f49Smrg 4732001f49Smrgvoid (*drawObject) (void); 4832001f49Smrgvoid (*loadTexture) (void); 4932001f49SmrgGLboolean textureEnabled = GL_TRUE; 5032001f49SmrgGLboolean showProjection = GL_TRUE; 5132001f49SmrgGLboolean linearFilter = GL_TRUE; 5232001f49Smrg 5332001f49Smrgchar *texFilename[MAX_TEX] = { 5432001f49Smrg DEMOS_DATA_DIR "girl.rgb", 5532001f49Smrg DEMOS_DATA_DIR "tile.rgb", 5632001f49Smrg DEMOS_DATA_DIR "bw.rgb", 5732001f49Smrg DEMOS_DATA_DIR "reflect.rgb" 5832001f49Smrg}; 5932001f49Smrg 6032001f49Smrg 6132001f49SmrgGLfloat zoomFactor = 1.0; 6232001f49Smrg 6332001f49Smrg/*****************************************************************/ 6432001f49Smrg 6532001f49Smrg 6632001f49Smrgstatic void 6732001f49SmrgActiveTexture(int i) 6832001f49Smrg{ 6932001f49Smrg glActiveTextureARB(i); 7032001f49Smrg} 7132001f49Smrg 7232001f49Smrg 7332001f49Smrg/* matrix = identity */ 7432001f49Smrgstatic void 7532001f49SmrgmatrixIdentity(GLfloat matrix[16]) 7632001f49Smrg{ 7732001f49Smrg matrix[0] = 1.0; 7832001f49Smrg matrix[1] = 0.0; 7932001f49Smrg matrix[2] = 0.0; 8032001f49Smrg matrix[3] = 0.0; 8132001f49Smrg matrix[4] = 0.0; 8232001f49Smrg matrix[5] = 1.0; 8332001f49Smrg matrix[6] = 0.0; 8432001f49Smrg matrix[7] = 0.0; 8532001f49Smrg matrix[8] = 0.0; 8632001f49Smrg matrix[9] = 0.0; 8732001f49Smrg matrix[10] = 1.0; 8832001f49Smrg matrix[11] = 0.0; 8932001f49Smrg matrix[12] = 0.0; 9032001f49Smrg matrix[13] = 0.0; 9132001f49Smrg matrix[14] = 0.0; 9232001f49Smrg matrix[15] = 1.0; 9332001f49Smrg} 9432001f49Smrg 9532001f49Smrg/* matrix2 = transpose(matrix1) */ 9632001f49Smrgstatic void 9732001f49SmrgmatrixTranspose(GLfloat matrix2[16], GLfloat matrix1[16]) 9832001f49Smrg{ 9932001f49Smrg matrix2[0] = matrix1[0]; 10032001f49Smrg matrix2[1] = matrix1[4]; 10132001f49Smrg matrix2[2] = matrix1[8]; 10232001f49Smrg matrix2[3] = matrix1[12]; 10332001f49Smrg 10432001f49Smrg matrix2[4] = matrix1[1]; 10532001f49Smrg matrix2[5] = matrix1[5]; 10632001f49Smrg matrix2[6] = matrix1[9]; 10732001f49Smrg matrix2[7] = matrix1[13]; 10832001f49Smrg 10932001f49Smrg matrix2[8] = matrix1[2]; 11032001f49Smrg matrix2[9] = matrix1[6]; 11132001f49Smrg matrix2[10] = matrix1[10]; 11232001f49Smrg matrix2[11] = matrix1[14]; 11332001f49Smrg 11432001f49Smrg matrix2[12] = matrix1[3]; 11532001f49Smrg matrix2[13] = matrix1[7]; 11632001f49Smrg matrix2[14] = matrix1[14]; 11732001f49Smrg matrix2[15] = matrix1[15]; 11832001f49Smrg} 11932001f49Smrg 12032001f49Smrg/*****************************************************************/ 12132001f49Smrg 12232001f49Smrg/* load SGI .rgb image (pad with a border of the specified width and color) */ 12332001f49Smrg#if 0 12432001f49Smrgstatic void 12532001f49SmrgimgLoad(char *filenameIn, int borderIn, GLfloat borderColorIn[4], 12632001f49Smrg int *wOut, int *hOut, GLubyte ** imgOut) 12732001f49Smrg{ 12832001f49Smrg int border = borderIn; 12932001f49Smrg int width, height; 13032001f49Smrg int w, h; 13132001f49Smrg GLubyte *image, *img, *p; 13232001f49Smrg int i, j, components; 13332001f49Smrg 13432001f49Smrg image = (GLubyte *) read_texture(filenameIn, &width, &height, &components); 13532001f49Smrg w = width + 2 * border; 13632001f49Smrg h = height + 2 * border; 13732001f49Smrg img = (GLubyte *) calloc(w * h, 4 * sizeof(unsigned char)); 13832001f49Smrg 13932001f49Smrg p = img; 14032001f49Smrg for (j = -border; j < height + border; ++j) { 14132001f49Smrg for (i = -border; i < width + border; ++i) { 14232001f49Smrg if (0 <= j && j <= height - 1 && 0 <= i && i <= width - 1) { 14332001f49Smrg p[0] = image[4 * (j * width + i) + 0]; 14432001f49Smrg p[1] = image[4 * (j * width + i) + 1]; 14532001f49Smrg p[2] = image[4 * (j * width + i) + 2]; 14632001f49Smrg p[3] = 0xff; 14732001f49Smrg } else { 14832001f49Smrg p[0] = borderColorIn[0] * 0xff; 14932001f49Smrg p[1] = borderColorIn[1] * 0xff; 15032001f49Smrg p[2] = borderColorIn[2] * 0xff; 15132001f49Smrg p[3] = borderColorIn[3] * 0xff; 15232001f49Smrg } 15332001f49Smrg p += 4; 15432001f49Smrg } 15532001f49Smrg } 15632001f49Smrg free(image); 15732001f49Smrg *wOut = w; 15832001f49Smrg *hOut = h; 15932001f49Smrg *imgOut = img; 16032001f49Smrg} 16132001f49Smrg#endif 16232001f49Smrg 16332001f49Smrg 16432001f49Smrg/*****************************************************************/ 16532001f49Smrg 16632001f49Smrg/* Load the image file specified on the command line as the current texture */ 16732001f49Smrgstatic void 16832001f49SmrgloadImageTextures(void) 16932001f49Smrg{ 17032001f49Smrg GLfloat borderColor[4] = 17132001f49Smrg {1.0, 1.0, 1.0, 1.0}; 17232001f49Smrg int tex; 17332001f49Smrg 17432001f49Smrg for (tex = 0; tex < NumTextures; tex++) { 17532001f49Smrg GLubyte *image, *texData3, *texData4; 17632001f49Smrg GLint imgWidth, imgHeight; 17732001f49Smrg GLenum imgFormat; 17832001f49Smrg int i, j; 17932001f49Smrg 18032001f49Smrg printf("loading %s\n", texFilename[tex]); 18132001f49Smrg image = LoadRGBImage(texFilename[tex], &imgWidth, &imgHeight, &imgFormat); 18232001f49Smrg if (!image) { 18332001f49Smrg printf("can't find %s\n", texFilename[tex]); 18432001f49Smrg exit(1); 18532001f49Smrg } 18632001f49Smrg assert(imgFormat == GL_RGB); 18732001f49Smrg 18832001f49Smrg /* scale to 256x256 */ 18932001f49Smrg texData3 = malloc(256 * 256 * 4); 19032001f49Smrg texData4 = malloc(256 * 256 * 4); 19132001f49Smrg assert(texData3); 19232001f49Smrg assert(texData4); 19332001f49Smrg gluScaleImage(imgFormat, imgWidth, imgHeight, GL_UNSIGNED_BYTE, image, 19432001f49Smrg 256, 256, GL_UNSIGNED_BYTE, texData3); 19532001f49Smrg 19632001f49Smrg /* convert to rgba */ 19732001f49Smrg for (i = 0; i < 256 * 256; i++) { 19832001f49Smrg texData4[i*4+0] = texData3[i*3+0]; 19932001f49Smrg texData4[i*4+1] = texData3[i*3+1]; 20032001f49Smrg texData4[i*4+2] = texData3[i*3+2]; 20132001f49Smrg texData4[i*4+3] = 128; 20232001f49Smrg } 20332001f49Smrg 20432001f49Smrg /* put transparent border around image */ 20532001f49Smrg for (i = 0; i < 256; i++) { 20632001f49Smrg texData4[i*4+0] = 255; 20732001f49Smrg texData4[i*4+1] = 255; 20832001f49Smrg texData4[i*4+2] = 255; 20932001f49Smrg texData4[i*4+3] = 0; 21032001f49Smrg } 21132001f49Smrg j = 256 * 255 * 4; 21232001f49Smrg for (i = 0; i < 256; i++) { 21332001f49Smrg texData4[j + i*4+0] = 255; 21432001f49Smrg texData4[j + i*4+1] = 255; 21532001f49Smrg texData4[j + i*4+2] = 255; 21632001f49Smrg texData4[j + i*4+3] = 0; 21732001f49Smrg } 21832001f49Smrg for (i = 0; i < 256; i++) { 21932001f49Smrg j = i * 256 * 4; 22032001f49Smrg texData4[j+0] = 255; 22132001f49Smrg texData4[j+1] = 255; 22232001f49Smrg texData4[j+2] = 255; 22332001f49Smrg texData4[j+3] = 0; 22432001f49Smrg } 22532001f49Smrg for (i = 0; i < 256; i++) { 22632001f49Smrg j = i * 256 * 4 + 255 * 4; 22732001f49Smrg texData4[j+0] = 255; 22832001f49Smrg texData4[j+1] = 255; 22932001f49Smrg texData4[j+2] = 255; 23032001f49Smrg texData4[j+3] = 0; 23132001f49Smrg } 23232001f49Smrg 23332001f49Smrg ActiveTexture(GL_TEXTURE0_ARB + tex); 23432001f49Smrg glBindTexture(GL_TEXTURE_2D, tex + 1); 23532001f49Smrg 23632001f49Smrg glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 23732001f49Smrg glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, 23832001f49Smrg GL_RGBA, GL_UNSIGNED_BYTE, texData4); 23932001f49Smrg 24032001f49Smrg if (linearFilter) { 24132001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 24232001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 24332001f49Smrg } else { 24432001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 24532001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 24632001f49Smrg } 24732001f49Smrg glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); 24832001f49Smrg 24932001f49Smrg free(texData3); 25032001f49Smrg free(texData4); 25132001f49Smrg free(image); 25232001f49Smrg } 25332001f49Smrg} 25432001f49Smrg 25532001f49Smrg/* Create a simple spotlight pattern and make it the current texture */ 25632001f49Smrgstatic void 25732001f49SmrgloadSpotlightTexture(void) 25832001f49Smrg{ 25932001f49Smrg static int texWidth = 64, texHeight = 64; 26032001f49Smrg static GLubyte *texData; 26132001f49Smrg GLfloat borderColor[4] = 26232001f49Smrg {0.1, 0.1, 0.1, 1.0}; 26332001f49Smrg 26432001f49Smrg if (!texData) { 26532001f49Smrg GLubyte *p; 26632001f49Smrg int i, j; 26732001f49Smrg 26832001f49Smrg texData = (GLubyte *) malloc(texWidth * texHeight * 4 * sizeof(GLubyte)); 26932001f49Smrg 27032001f49Smrg p = texData; 27132001f49Smrg for (j = 0; j < texHeight; ++j) { 27232001f49Smrg float dy = (texHeight * 0.5 - j + 0.5) / (texHeight * 0.5); 27332001f49Smrg 27432001f49Smrg for (i = 0; i < texWidth; ++i) { 27532001f49Smrg float dx = (texWidth * 0.5 - i + 0.5) / (texWidth * 0.5); 27632001f49Smrg float r = cos(M_PI / 2.0 * sqrt(dx * dx + dy * dy)); 27732001f49Smrg float c; 27832001f49Smrg 27932001f49Smrg r = (r < 0) ? 0 : r * r; 28032001f49Smrg c = 0xff * (r + borderColor[0]); 28132001f49Smrg p[0] = (c <= 0xff) ? c : 0xff; 28232001f49Smrg c = 0xff * (r + borderColor[1]); 28332001f49Smrg p[1] = (c <= 0xff) ? c : 0xff; 28432001f49Smrg c = 0xff * (r + borderColor[2]); 28532001f49Smrg p[2] = (c <= 0xff) ? c : 0xff; 28632001f49Smrg c = 0xff * (r + borderColor[3]); 28732001f49Smrg p[3] = (c <= 0xff) ? c : 0xff; 28832001f49Smrg p += 4; 28932001f49Smrg } 29032001f49Smrg } 29132001f49Smrg } 29232001f49Smrg if (linearFilter) { 29332001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 29432001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 29532001f49Smrg } else { 29632001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 29732001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 29832001f49Smrg } 29932001f49Smrg glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); 30032001f49Smrg gluBuild2DMipmaps(GL_TEXTURE_2D, 4, texWidth, texHeight, 30132001f49Smrg GL_RGBA, GL_UNSIGNED_BYTE, texData); 30232001f49Smrg} 30332001f49Smrg 30432001f49Smrg/*****************************************************************/ 30532001f49Smrg 30632001f49Smrgstatic void 30732001f49SmrgcheckErrors(void) 30832001f49Smrg{ 30932001f49Smrg GLenum error; 31032001f49Smrg while ((error = glGetError()) != GL_NO_ERROR) { 31132001f49Smrg fprintf(stderr, "Error: %s\n", (char *) gluErrorString(error)); 31232001f49Smrg } 31332001f49Smrg} 31432001f49Smrg 31532001f49Smrgstatic void 31632001f49SmrgdrawCube(void) 31732001f49Smrg{ 31832001f49Smrg glBegin(GL_QUADS); 31932001f49Smrg 32032001f49Smrg glNormal3f(-1.0, 0.0, 0.0); 32132001f49Smrg glColor3f(0.80, 0.50, 0.50); 32232001f49Smrg glVertex3f(-0.5, -0.5, -0.5); 32332001f49Smrg glVertex3f(-0.5, -0.5, 0.5); 32432001f49Smrg glVertex3f(-0.5, 0.5, 0.5); 32532001f49Smrg glVertex3f(-0.5, 0.5, -0.5); 32632001f49Smrg 32732001f49Smrg glNormal3f(1.0, 0.0, 0.0); 32832001f49Smrg glColor3f(0.50, 0.80, 0.50); 32932001f49Smrg glVertex3f(0.5, 0.5, 0.5); 33032001f49Smrg glVertex3f(0.5, -0.5, 0.5); 33132001f49Smrg glVertex3f(0.5, -0.5, -0.5); 33232001f49Smrg glVertex3f(0.5, 0.5, -0.5); 33332001f49Smrg 33432001f49Smrg glNormal3f(0.0, -1.0, 0.0); 33532001f49Smrg glColor3f(0.50, 0.50, 0.80); 33632001f49Smrg glVertex3f(-0.5, -0.5, -0.5); 33732001f49Smrg glVertex3f(0.5, -0.5, -0.5); 33832001f49Smrg glVertex3f(0.5, -0.5, 0.5); 33932001f49Smrg glVertex3f(-0.5, -0.5, 0.5); 34032001f49Smrg 34132001f49Smrg glNormal3f(0.0, 1.0, 0.0); 34232001f49Smrg glColor3f(0.50, 0.80, 0.80); 34332001f49Smrg glVertex3f(0.5, 0.5, 0.5); 34432001f49Smrg glVertex3f(0.5, 0.5, -0.5); 34532001f49Smrg glVertex3f(-0.5, 0.5, -0.5); 34632001f49Smrg glVertex3f(-0.5, 0.5, 0.5); 34732001f49Smrg 34832001f49Smrg glNormal3f(0.0, 0.0, -1.0); 34932001f49Smrg glColor3f(0.80, 0.50, 0.80); 35032001f49Smrg glVertex3f(-0.5, -0.5, -0.5); 35132001f49Smrg glVertex3f(-0.5, 0.5, -0.5); 35232001f49Smrg glVertex3f(0.5, 0.5, -0.5); 35332001f49Smrg glVertex3f(0.5, -0.5, -0.5); 35432001f49Smrg 35532001f49Smrg glNormal3f(0.0, 0.0, 1.0); 35632001f49Smrg glColor3f(1.00, 0.80, 0.50); 35732001f49Smrg glVertex3f(0.5, 0.5, 0.5); 35832001f49Smrg glVertex3f(-0.5, 0.5, 0.5); 35932001f49Smrg glVertex3f(-0.5, -0.5, 0.5); 36032001f49Smrg glVertex3f(0.5, -0.5, 0.5); 36132001f49Smrg glEnd(); 36232001f49Smrg} 36332001f49Smrg 36432001f49Smrgstatic void 36532001f49SmrgdrawDodecahedron(void) 36632001f49Smrg{ 36732001f49Smrg#define A (0.5 * 1.61803) /* (sqrt(5) + 1) / 2 */ 36832001f49Smrg#define B (0.5 * 0.61803) /* (sqrt(5) - 1) / 2 */ 36932001f49Smrg#define C (0.5 * 1.0) 37032001f49Smrg GLfloat vertexes[20][3] = 37132001f49Smrg { 37232001f49Smrg {-A, 0.0, B}, 37332001f49Smrg {-A, 0.0, -B}, 37432001f49Smrg {A, 0.0, -B}, 37532001f49Smrg {A, 0.0, B}, 37632001f49Smrg {B, -A, 0.0}, 37732001f49Smrg {-B, -A, 0.0}, 37832001f49Smrg {-B, A, 0.0}, 37932001f49Smrg {B, A, 0.0}, 38032001f49Smrg {0.0, B, -A}, 38132001f49Smrg {0.0, -B, -A}, 38232001f49Smrg {0.0, -B, A}, 38332001f49Smrg {0.0, B, A}, 38432001f49Smrg {-C, -C, C}, 38532001f49Smrg {-C, -C, -C}, 38632001f49Smrg {C, -C, -C}, 38732001f49Smrg {C, -C, C}, 38832001f49Smrg {-C, C, C}, 38932001f49Smrg {-C, C, -C}, 39032001f49Smrg {C, C, -C}, 39132001f49Smrg {C, C, C}, 39232001f49Smrg }; 39332001f49Smrg#undef A 39432001f49Smrg#undef B 39532001f49Smrg#undef C 39632001f49Smrg GLint polygons[12][5] = 39732001f49Smrg { 39832001f49Smrg {0, 12, 10, 11, 16}, 39932001f49Smrg {1, 17, 8, 9, 13}, 40032001f49Smrg {2, 14, 9, 8, 18}, 40132001f49Smrg {3, 19, 11, 10, 15}, 40232001f49Smrg {4, 14, 2, 3, 15}, 40332001f49Smrg {5, 12, 0, 1, 13}, 40432001f49Smrg {6, 17, 1, 0, 16}, 40532001f49Smrg {7, 19, 3, 2, 18}, 40632001f49Smrg {8, 17, 6, 7, 18}, 40732001f49Smrg {9, 14, 4, 5, 13}, 40832001f49Smrg {10, 12, 5, 4, 15}, 40932001f49Smrg {11, 19, 7, 6, 16}, 41032001f49Smrg }; 41132001f49Smrg int i; 41232001f49Smrg 41332001f49Smrg glColor3f(0.75, 0.75, 0.75); 41432001f49Smrg for (i = 0; i < 12; ++i) { 41532001f49Smrg GLfloat *p0, *p1, *p2, d; 41632001f49Smrg GLfloat u[3], v[3], n[3]; 41732001f49Smrg 41832001f49Smrg p0 = &vertexes[polygons[i][0]][0]; 41932001f49Smrg p1 = &vertexes[polygons[i][1]][0]; 42032001f49Smrg p2 = &vertexes[polygons[i][2]][0]; 42132001f49Smrg 42232001f49Smrg u[0] = p2[0] - p1[0]; 42332001f49Smrg u[1] = p2[1] - p1[1]; 42432001f49Smrg u[2] = p2[2] - p1[2]; 42532001f49Smrg 42632001f49Smrg v[0] = p0[0] - p1[0]; 42732001f49Smrg v[1] = p0[1] - p1[1]; 42832001f49Smrg v[2] = p0[2] - p1[2]; 42932001f49Smrg 43032001f49Smrg n[0] = u[1] * v[2] - u[2] * v[1]; 43132001f49Smrg n[1] = u[2] * v[0] - u[0] * v[2]; 43232001f49Smrg n[2] = u[0] * v[1] - u[1] * v[0]; 43332001f49Smrg 43432001f49Smrg d = 1.0 / sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]); 43532001f49Smrg n[0] *= d; 43632001f49Smrg n[1] *= d; 43732001f49Smrg n[2] *= d; 43832001f49Smrg 43932001f49Smrg glBegin(GL_POLYGON); 44032001f49Smrg glNormal3fv(n); 44132001f49Smrg glVertex3fv(p0); 44232001f49Smrg glVertex3fv(p1); 44332001f49Smrg glVertex3fv(p2); 44432001f49Smrg glVertex3fv(vertexes[polygons[i][3]]); 44532001f49Smrg glVertex3fv(vertexes[polygons[i][4]]); 44632001f49Smrg glEnd(); 44732001f49Smrg } 44832001f49Smrg} 44932001f49Smrg 45032001f49Smrgstatic void 45132001f49SmrgdrawSphere(void) 45232001f49Smrg{ 45332001f49Smrg int numMajor = 24; 45432001f49Smrg int numMinor = 32; 45532001f49Smrg float radius = 0.8; 45632001f49Smrg double majorStep = (M_PI / numMajor); 45732001f49Smrg double minorStep = (2.0 * M_PI / numMinor); 45832001f49Smrg int i, j; 45932001f49Smrg 46032001f49Smrg glColor3f(0.50, 0.50, 0.50); 46132001f49Smrg for (i = 0; i < numMajor; ++i) { 46232001f49Smrg double a = i * majorStep; 46332001f49Smrg double b = a + majorStep; 46432001f49Smrg double r0 = radius * sin(a); 46532001f49Smrg double r1 = radius * sin(b); 46632001f49Smrg GLfloat z0 = radius * cos(a); 46732001f49Smrg GLfloat z1 = radius * cos(b); 46832001f49Smrg 46932001f49Smrg glBegin(GL_TRIANGLE_STRIP); 47032001f49Smrg for (j = 0; j <= numMinor; ++j) { 47132001f49Smrg double c = j * minorStep; 47232001f49Smrg GLfloat x = cos(c); 47332001f49Smrg GLfloat y = sin(c); 47432001f49Smrg 47532001f49Smrg glNormal3f((x * r0) / radius, (y * r0) / radius, z0 / radius); 47632001f49Smrg glTexCoord2f(j / (GLfloat) numMinor, i / (GLfloat) numMajor); 47732001f49Smrg glVertex3f(x * r0, y * r0, z0); 47832001f49Smrg 47932001f49Smrg glNormal3f((x * r1) / radius, (y * r1) / radius, z1 / radius); 48032001f49Smrg glTexCoord2f(j / (GLfloat) numMinor, (i + 1) / (GLfloat) numMajor); 48132001f49Smrg glVertex3f(x * r1, y * r1, z1); 48232001f49Smrg } 48332001f49Smrg glEnd(); 48432001f49Smrg } 48532001f49Smrg} 48632001f49Smrg 48732001f49Smrg/*****************************************************************/ 48832001f49Smrg 48932001f49Smrgfloat xmin = -0.035, xmax = 0.035; 49032001f49Smrgfloat ymin = -0.035, ymax = 0.035; 49132001f49Smrgfloat nnear = 0.1; 49232001f49Smrgfloat ffar = 1.9; 49332001f49Smrgfloat distance = -1.0; 49432001f49Smrg 49532001f49Smrgstatic void 49632001f49SmrgloadTextureProjection(int texUnit, GLfloat m[16]) 49732001f49Smrg{ 49832001f49Smrg GLfloat mInverse[4][4]; 49932001f49Smrg 50032001f49Smrg /* Should use true inverse, but since m consists only of rotations, we can 50132001f49Smrg just use the transpose. */ 50232001f49Smrg matrixTranspose((GLfloat *) mInverse, m); 50332001f49Smrg 50432001f49Smrg ActiveTexture(GL_TEXTURE0_ARB + texUnit); 50532001f49Smrg glMatrixMode(GL_TEXTURE); 50632001f49Smrg glLoadIdentity(); 50732001f49Smrg glTranslatef(0.5, 0.5, 0.0); 50832001f49Smrg glScalef(0.5, 0.5, 1.0); 50932001f49Smrg glFrustum(xmin, xmax, ymin, ymax, nnear, ffar); 51032001f49Smrg glTranslatef(0.0, 0.0, distance); 51132001f49Smrg glMultMatrixf((GLfloat *) mInverse); 51232001f49Smrg glMatrixMode(GL_MODELVIEW); 51332001f49Smrg} 51432001f49Smrg 51532001f49Smrgstatic void 51632001f49SmrgdrawTextureProjection(void) 51732001f49Smrg{ 51832001f49Smrg float t = ffar / nnear; 51932001f49Smrg GLfloat n[4][3]; 52032001f49Smrg GLfloat f[4][3]; 52132001f49Smrg 52232001f49Smrg n[0][0] = xmin; 52332001f49Smrg n[0][1] = ymin; 52432001f49Smrg n[0][2] = -(nnear + distance); 52532001f49Smrg 52632001f49Smrg n[1][0] = xmax; 52732001f49Smrg n[1][1] = ymin; 52832001f49Smrg n[1][2] = -(nnear + distance); 52932001f49Smrg 53032001f49Smrg n[2][0] = xmax; 53132001f49Smrg n[2][1] = ymax; 53232001f49Smrg n[2][2] = -(nnear + distance); 53332001f49Smrg 53432001f49Smrg n[3][0] = xmin; 53532001f49Smrg n[3][1] = ymax; 53632001f49Smrg n[3][2] = -(nnear + distance); 53732001f49Smrg 53832001f49Smrg f[0][0] = xmin * t; 53932001f49Smrg f[0][1] = ymin * t; 54032001f49Smrg f[0][2] = -(ffar + distance); 54132001f49Smrg 54232001f49Smrg f[1][0] = xmax * t; 54332001f49Smrg f[1][1] = ymin * t; 54432001f49Smrg f[1][2] = -(ffar + distance); 54532001f49Smrg 54632001f49Smrg f[2][0] = xmax * t; 54732001f49Smrg f[2][1] = ymax * t; 54832001f49Smrg f[2][2] = -(ffar + distance); 54932001f49Smrg 55032001f49Smrg f[3][0] = xmin * t; 55132001f49Smrg f[3][1] = ymax * t; 55232001f49Smrg f[3][2] = -(ffar + distance); 55332001f49Smrg 55432001f49Smrg glColor3f(1.0, 1.0, 0.0); 55532001f49Smrg glBegin(GL_LINE_LOOP); 55632001f49Smrg glVertex3fv(n[0]); 55732001f49Smrg glVertex3fv(n[1]); 55832001f49Smrg glVertex3fv(n[2]); 55932001f49Smrg glVertex3fv(n[3]); 56032001f49Smrg glVertex3fv(f[3]); 56132001f49Smrg glVertex3fv(f[2]); 56232001f49Smrg glVertex3fv(f[1]); 56332001f49Smrg glVertex3fv(f[0]); 56432001f49Smrg glVertex3fv(n[0]); 56532001f49Smrg glVertex3fv(n[1]); 56632001f49Smrg glVertex3fv(f[1]); 56732001f49Smrg glVertex3fv(f[0]); 56832001f49Smrg glVertex3fv(f[3]); 56932001f49Smrg glVertex3fv(f[2]); 57032001f49Smrg glVertex3fv(n[2]); 57132001f49Smrg glVertex3fv(n[3]); 57232001f49Smrg glEnd(); 57332001f49Smrg} 57432001f49Smrg 57532001f49Smrg/*****************************************************************/ 57632001f49Smrg 57732001f49Smrgstatic void 57832001f49Smrginitialize(void) 57932001f49Smrg{ 58032001f49Smrg GLfloat light0Pos[4] = 58132001f49Smrg {0.3, 0.3, 0.0, 1.0}; 58232001f49Smrg GLfloat matAmb[4] = 58332001f49Smrg {0.01, 0.01, 0.01, 1.00}; 58432001f49Smrg GLfloat matDiff[4] = 58532001f49Smrg {0.65, 0.65, 0.65, 1.00}; 58632001f49Smrg GLfloat matSpec[4] = 58732001f49Smrg {0.30, 0.30, 0.30, 1.00}; 58832001f49Smrg GLfloat matShine = 10.0; 58932001f49Smrg GLfloat eyePlaneS[] = 59032001f49Smrg {1.0, 0.0, 0.0, 0.0}; 59132001f49Smrg GLfloat eyePlaneT[] = 59232001f49Smrg {0.0, 1.0, 0.0, 0.0}; 59332001f49Smrg GLfloat eyePlaneR[] = 59432001f49Smrg {0.0, 0.0, 1.0, 0.0}; 59532001f49Smrg GLfloat eyePlaneQ[] = 59632001f49Smrg {0.0, 0.0, 0.0, 1.0}; 59732001f49Smrg int i; 59832001f49Smrg 59932001f49Smrg /* Setup Misc. */ 60032001f49Smrg glClearColor(0.41, 0.41, 0.31, 0.0); 60132001f49Smrg 60232001f49Smrg glEnable(GL_DEPTH_TEST); 60332001f49Smrg 60432001f49Smrg /* glLineWidth(2.0);*/ 60532001f49Smrg 60632001f49Smrg glCullFace(GL_FRONT); 60732001f49Smrg glEnable(GL_CULL_FACE); 60832001f49Smrg 60932001f49Smrg glMatrixMode(GL_PROJECTION); 61032001f49Smrg glFrustum(-0.5, 0.5, -0.5, 0.5, 1, 3); 61132001f49Smrg glMatrixMode(GL_MODELVIEW); 61232001f49Smrg glTranslatef(0, 0, -2); 61332001f49Smrg 61432001f49Smrg matrixIdentity((GLfloat *) objectXform); 61532001f49Smrg for (i = 0; i < NumTextures; i++) { 61632001f49Smrg matrixIdentity((GLfloat *) textureXform[i]); 61732001f49Smrg } 61832001f49Smrg 61932001f49Smrg glMatrixMode(GL_PROJECTION); 62032001f49Smrg glPushMatrix(); 62132001f49Smrg glLoadIdentity(); 62232001f49Smrg glOrtho(0, 1, 0, 1, -1, 1); 62332001f49Smrg glMatrixMode(GL_MODELVIEW); 62432001f49Smrg glPushMatrix(); 62532001f49Smrg glLoadIdentity(); 62632001f49Smrg 62732001f49Smrg glRasterPos2i(0, 0); 62832001f49Smrg 62932001f49Smrg glPopMatrix(); 63032001f49Smrg glMatrixMode(GL_PROJECTION); 63132001f49Smrg glPopMatrix(); 63232001f49Smrg glMatrixMode(GL_MODELVIEW); 63332001f49Smrg 63432001f49Smrg /* Setup Lighting */ 63532001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmb); 63632001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiff); 63732001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matSpec); 63832001f49Smrg glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, matShine); 63932001f49Smrg 64032001f49Smrg glEnable(GL_COLOR_MATERIAL); 64132001f49Smrg 64232001f49Smrg glLightfv(GL_LIGHT0, GL_POSITION, light0Pos); 64332001f49Smrg glEnable(GL_LIGHT0); 64432001f49Smrg 64532001f49Smrg glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); 64632001f49Smrg glEnable(GL_LIGHTING); 64732001f49Smrg 64832001f49Smrg /* Setup Texture */ 64932001f49Smrg 65032001f49Smrg (*loadTexture) (); 65132001f49Smrg 65232001f49Smrg 65332001f49Smrg for (i = 0; i < NumTextures; i++) { 65432001f49Smrg ActiveTexture(GL_TEXTURE0_ARB + i); 65532001f49Smrg 65632001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 65732001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 65832001f49Smrg glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 65932001f49Smrg 66032001f49Smrg glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); 66132001f49Smrg glTexGenfv(GL_S, GL_EYE_PLANE, eyePlaneS); 66232001f49Smrg 66332001f49Smrg glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); 66432001f49Smrg glTexGenfv(GL_T, GL_EYE_PLANE, eyePlaneT); 66532001f49Smrg 66632001f49Smrg glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); 66732001f49Smrg glTexGenfv(GL_R, GL_EYE_PLANE, eyePlaneR); 66832001f49Smrg 66932001f49Smrg glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); 67032001f49Smrg glTexGenfv(GL_Q, GL_EYE_PLANE, eyePlaneQ); 67132001f49Smrg } 67232001f49Smrg} 67332001f49Smrg 67432001f49Smrgstatic void 67532001f49Smrgdisplay(void) 67632001f49Smrg{ 67732001f49Smrg int i; 67832001f49Smrg 67932001f49Smrg glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 68032001f49Smrg 68132001f49Smrg if (textureEnabled) { 68232001f49Smrg if (mode == MoveTexture || mode == MoveView) { 68332001f49Smrg /* Have OpenGL compute the new transformation (simple but slow). */ 68432001f49Smrg for (i = 0; i < NumTextures; i++) { 68532001f49Smrg glPushMatrix(); 68632001f49Smrg glLoadIdentity(); 68732001f49Smrg#if 0 68832001f49Smrg if (i & 1) 68932001f49Smrg glRotatef(angle, axis[0], axis[1], axis[2]); 69032001f49Smrg else 69132001f49Smrg#endif 69232001f49Smrg glRotatef(angle*(i+1), axis[0], axis[1], axis[2]); 69332001f49Smrg 69432001f49Smrg glMultMatrixf((GLfloat *) textureXform[i]); 69532001f49Smrg glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) textureXform[i]); 69632001f49Smrg glPopMatrix(); 69732001f49Smrg } 69832001f49Smrg } 69932001f49Smrg for (i = 0; i < NumTextures; i++) { 70032001f49Smrg loadTextureProjection(i, (GLfloat *) textureXform[i]); 70132001f49Smrg } 70232001f49Smrg 70332001f49Smrg if (showProjection) { 70432001f49Smrg for (i = 0; i < NumTextures; i++) { 70532001f49Smrg ActiveTexture(GL_TEXTURE0_ARB + i); 70632001f49Smrg glPushMatrix(); 70732001f49Smrg glMultMatrixf((GLfloat *) textureXform[i]); 70832001f49Smrg glDisable(GL_LIGHTING); 70932001f49Smrg drawTextureProjection(); 71032001f49Smrg glEnable(GL_LIGHTING); 71132001f49Smrg glPopMatrix(); 71232001f49Smrg } 71332001f49Smrg } 71432001f49Smrg for (i = 0; i < NumTextures; i++) { 71532001f49Smrg ActiveTexture(GL_TEXTURE0_ARB + i); 71632001f49Smrg glEnable(GL_TEXTURE_2D); 71732001f49Smrg glEnable(GL_TEXTURE_GEN_S); 71832001f49Smrg glEnable(GL_TEXTURE_GEN_T); 71932001f49Smrg glEnable(GL_TEXTURE_GEN_R); 72032001f49Smrg glEnable(GL_TEXTURE_GEN_Q); 72132001f49Smrg } 72232001f49Smrg } 72332001f49Smrg if (mode == MoveObject || mode == MoveView) { 72432001f49Smrg /* Have OpenGL compute the new transformation (simple but slow). */ 72532001f49Smrg glPushMatrix(); 72632001f49Smrg glLoadIdentity(); 72732001f49Smrg glRotatef(angle, axis[0], axis[1], axis[2]); 72832001f49Smrg glMultMatrixf((GLfloat *) objectXform); 72932001f49Smrg glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) objectXform); 73032001f49Smrg glPopMatrix(); 73132001f49Smrg } 73232001f49Smrg glPushMatrix(); 73332001f49Smrg glMultMatrixf((GLfloat *) objectXform); 73432001f49Smrg (*drawObject) (); 73532001f49Smrg glPopMatrix(); 73632001f49Smrg 73732001f49Smrg for (i = 0; i < NumTextures; i++) { 73832001f49Smrg ActiveTexture(GL_TEXTURE0_ARB + i); 73932001f49Smrg glDisable(GL_TEXTURE_2D); 74032001f49Smrg glDisable(GL_TEXTURE_GEN_S); 74132001f49Smrg glDisable(GL_TEXTURE_GEN_T); 74232001f49Smrg glDisable(GL_TEXTURE_GEN_R); 74332001f49Smrg glDisable(GL_TEXTURE_GEN_Q); 74432001f49Smrg } 74532001f49Smrg 74632001f49Smrg if (zoomFactor > 1.0) { 74732001f49Smrg glDisable(GL_DEPTH_TEST); 74832001f49Smrg glCopyPixels(0, 0, winWidth / zoomFactor, winHeight / zoomFactor, GL_COLOR); 74932001f49Smrg glEnable(GL_DEPTH_TEST); 75032001f49Smrg } 75132001f49Smrg glFlush(); 75232001f49Smrg glutSwapBuffers(); 75332001f49Smrg checkErrors(); 75432001f49Smrg} 75532001f49Smrg 75632001f49Smrg/*****************************************************************/ 75732001f49Smrg 75832001f49Smrg/* simple trackball-like motion control */ 75932001f49Smrgstatic float lastPos[3]; 76032001f49Smrgstatic int lastTime; 76132001f49Smrg 76232001f49Smrgstatic void 76332001f49Smrgptov(int x, int y, int width, int height, float v[3]) 76432001f49Smrg{ 76532001f49Smrg float d, a; 76632001f49Smrg 76732001f49Smrg /* project x,y onto a hemi-sphere centered within width, height */ 76832001f49Smrg v[0] = (2.0 * x - width) / width; 76932001f49Smrg v[1] = (height - 2.0 * y) / height; 77032001f49Smrg d = sqrt(v[0] * v[0] + v[1] * v[1]); 77132001f49Smrg v[2] = cos((M_PI / 2.0) * ((d < 1.0) ? d : 1.0)); 77232001f49Smrg a = 1.0 / sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); 77332001f49Smrg v[0] *= a; 77432001f49Smrg v[1] *= a; 77532001f49Smrg v[2] *= a; 77632001f49Smrg} 77732001f49Smrg 77832001f49Smrgstatic void 77932001f49SmrgstartMotion(int x, int y, int but, int time) 78032001f49Smrg{ 78132001f49Smrg if (but == GLUT_LEFT_BUTTON) { 78232001f49Smrg mode = MoveView; 78332001f49Smrg } else if (but == GLUT_MIDDLE_BUTTON) { 78432001f49Smrg mode = MoveTexture; 78532001f49Smrg } else { 78632001f49Smrg return; 78732001f49Smrg } 78832001f49Smrg 78932001f49Smrg lastTime = time; 79032001f49Smrg ptov(x, y, winWidth, winHeight, lastPos); 79132001f49Smrg} 79232001f49Smrg 79332001f49Smrgstatic void 79432001f49Smrganimate(void) 79532001f49Smrg{ 79632001f49Smrg glutPostRedisplay(); 79732001f49Smrg} 79832001f49Smrg 79932001f49Smrgstatic void 80032001f49Smrgvis(int visible) 80132001f49Smrg{ 80232001f49Smrg if (visible == GLUT_VISIBLE) { 80332001f49Smrg if (redrawContinuously) 80432001f49Smrg glutIdleFunc(animate); 80532001f49Smrg } else { 80632001f49Smrg if (redrawContinuously) 80732001f49Smrg glutIdleFunc(NULL); 80832001f49Smrg } 80932001f49Smrg} 81032001f49Smrg 81132001f49Smrgstatic void 81232001f49SmrgstopMotion(int but, int time) 81332001f49Smrg{ 81432001f49Smrg if ((but == GLUT_LEFT_BUTTON && mode == MoveView) || 81532001f49Smrg (but == GLUT_MIDDLE_BUTTON && mode == MoveTexture)) { 81632001f49Smrg } else { 81732001f49Smrg return; 81832001f49Smrg } 81932001f49Smrg 82032001f49Smrg if (time == lastTime) { 82132001f49Smrg /* redrawContinuously = GL_TRUE;*/ 82232001f49Smrg glutIdleFunc(animate); 82332001f49Smrg } else { 82432001f49Smrg angle = 0.0; 82532001f49Smrg redrawContinuously = GL_FALSE; 82632001f49Smrg glutIdleFunc(0); 82732001f49Smrg } 82832001f49Smrg if (!redrawContinuously) { 82932001f49Smrg mode = MoveNone; 83032001f49Smrg } 83132001f49Smrg} 83232001f49Smrg 83332001f49Smrgstatic void 83432001f49SmrgtrackMotion(int x, int y) 83532001f49Smrg{ 83632001f49Smrg float curPos[3], dx, dy, dz; 83732001f49Smrg 83832001f49Smrg ptov(x, y, winWidth, winHeight, curPos); 83932001f49Smrg 84032001f49Smrg dx = curPos[0] - lastPos[0]; 84132001f49Smrg dy = curPos[1] - lastPos[1]; 84232001f49Smrg dz = curPos[2] - lastPos[2]; 84332001f49Smrg angle = 90.0 * sqrt(dx * dx + dy * dy + dz * dz); 84432001f49Smrg 84532001f49Smrg axis[0] = lastPos[1] * curPos[2] - lastPos[2] * curPos[1]; 84632001f49Smrg axis[1] = lastPos[2] * curPos[0] - lastPos[0] * curPos[2]; 84732001f49Smrg axis[2] = lastPos[0] * curPos[1] - lastPos[1] * curPos[0]; 84832001f49Smrg 84932001f49Smrg lastTime = glutGet(GLUT_ELAPSED_TIME); 85032001f49Smrg lastPos[0] = curPos[0]; 85132001f49Smrg lastPos[1] = curPos[1]; 85232001f49Smrg lastPos[2] = curPos[2]; 85332001f49Smrg glutPostRedisplay(); 85432001f49Smrg} 85532001f49Smrg 85632001f49Smrg/*****************************************************************/ 85732001f49Smrg 85832001f49Smrgstatic void 85932001f49Smrgobject(void) 86032001f49Smrg{ 86132001f49Smrg static int object; 86232001f49Smrg 86332001f49Smrg object++; 86432001f49Smrg object %= 3; 86532001f49Smrg switch (object) { 86632001f49Smrg case 0: 86732001f49Smrg drawObject = drawCube; 86832001f49Smrg break; 86932001f49Smrg case 1: 87032001f49Smrg drawObject = drawDodecahedron; 87132001f49Smrg break; 87232001f49Smrg case 2: 87332001f49Smrg drawObject = drawSphere; 87432001f49Smrg break; 87532001f49Smrg default: 87632001f49Smrg break; 87732001f49Smrg } 87832001f49Smrg} 87932001f49Smrg 88032001f49Smrgstatic void 88132001f49Smrgnop(void) 88232001f49Smrg{ 88332001f49Smrg} 88432001f49Smrg 88532001f49Smrgstatic void 88632001f49Smrgtexture(void) 88732001f49Smrg{ 88832001f49Smrg static int texture = 0; 88932001f49Smrg 89032001f49Smrg texture++; 89132001f49Smrg texture %= 3; 89232001f49Smrg if (texture == 1 && texFilename == NULL) { 89332001f49Smrg /* Skip file texture if not loaded. */ 89432001f49Smrg texture++; 89532001f49Smrg } 89632001f49Smrg switch (texture) { 89732001f49Smrg case 0: 89832001f49Smrg loadTexture = nop; 89932001f49Smrg textureEnabled = GL_FALSE; 90032001f49Smrg break; 90132001f49Smrg case 1: 90232001f49Smrg loadTexture = loadImageTextures; 90332001f49Smrg (*loadTexture) (); 90432001f49Smrg textureEnabled = GL_TRUE; 90532001f49Smrg break; 90632001f49Smrg case 2: 90732001f49Smrg loadTexture = loadSpotlightTexture; 90832001f49Smrg (*loadTexture) (); 90932001f49Smrg textureEnabled = GL_TRUE; 91032001f49Smrg break; 91132001f49Smrg default: 91232001f49Smrg break; 91332001f49Smrg } 91432001f49Smrg} 91532001f49Smrg 91632001f49Smrgstatic void 91732001f49Smrghelp(void) 91832001f49Smrg{ 91932001f49Smrg printf("'h' - help\n"); 92032001f49Smrg printf("'l' - toggle linear/nearest filter\n"); 92132001f49Smrg printf("'s' - toggle projection frustum\n"); 92232001f49Smrg printf("'t' - toggle projected texture\n"); 92332001f49Smrg printf("'o' - toggle object\n"); 92432001f49Smrg printf("'z' - increase zoom factor\n"); 92532001f49Smrg printf("'Z' - decrease zoom factor\n"); 92632001f49Smrg printf("left mouse - move view\n"); 92732001f49Smrg printf("middle mouse - move projection\n"); 92832001f49Smrg} 92932001f49Smrg 93032001f49Smrg/* ARGSUSED1 */ 93132001f49Smrgstatic void 93232001f49Smrgkey(unsigned char key, int x, int y) 93332001f49Smrg{ 93432001f49Smrg switch (key) { 93532001f49Smrg case '\033': 93632001f49Smrg exit(0); 93732001f49Smrg break; 93832001f49Smrg case 'l': 93932001f49Smrg linearFilter = !linearFilter; 94032001f49Smrg (*loadTexture) (); 94132001f49Smrg break; 94232001f49Smrg case 's': 94332001f49Smrg showProjection = !showProjection; 94432001f49Smrg break; 94532001f49Smrg case 't': 94632001f49Smrg texture(); 94732001f49Smrg break; 94832001f49Smrg case 'o': 94932001f49Smrg object(); 95032001f49Smrg break; 95132001f49Smrg case 'z': 95232001f49Smrg zoomFactor += 1.0; 95332001f49Smrg glPixelZoom(zoomFactor, zoomFactor); 95432001f49Smrg glViewport(0, 0, winWidth / zoomFactor, winHeight / zoomFactor); 95532001f49Smrg break; 95632001f49Smrg case 'Z': 95732001f49Smrg zoomFactor -= 1.0; 95832001f49Smrg if (zoomFactor < 1.0) 95932001f49Smrg zoomFactor = 1.0; 96032001f49Smrg glPixelZoom(zoomFactor, zoomFactor); 96132001f49Smrg glViewport(0, 0, winWidth / zoomFactor, winHeight / zoomFactor); 96232001f49Smrg break; 96332001f49Smrg case 'h': 96432001f49Smrg help(); 96532001f49Smrg break; 96632001f49Smrg } 96732001f49Smrg glutPostRedisplay(); 96832001f49Smrg} 96932001f49Smrg 97032001f49Smrgstatic void 97132001f49Smrgmouse(int button, int state, int x, int y) 97232001f49Smrg{ 97332001f49Smrg if (state == GLUT_DOWN) 97432001f49Smrg startMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME)); 97532001f49Smrg else if (state == GLUT_UP) 97632001f49Smrg stopMotion(button, glutGet(GLUT_ELAPSED_TIME)); 97732001f49Smrg glutPostRedisplay(); 97832001f49Smrg} 97932001f49Smrg 98032001f49Smrgstatic void 98132001f49Smrgreshape(int w, int h) 98232001f49Smrg{ 98332001f49Smrg winWidth = w; 98432001f49Smrg winHeight = h; 98532001f49Smrg glViewport(0, 0, w / zoomFactor, h / zoomFactor); 98632001f49Smrg} 98732001f49Smrg 98832001f49Smrg 98932001f49Smrgstatic void 99032001f49Smrgmenu(int selection) 99132001f49Smrg{ 99232001f49Smrg if (selection == 666) { 99332001f49Smrg exit(0); 99432001f49Smrg } 99532001f49Smrg key((unsigned char) selection, 0, 0); 99632001f49Smrg} 99732001f49Smrg 99832001f49Smrgint 99932001f49Smrgmain(int argc, char **argv) 100032001f49Smrg{ 100132001f49Smrg glutInitWindowSize(500,500); 100232001f49Smrg glutInit(&argc, argv); 100332001f49Smrg glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); 100432001f49Smrg (void) glutCreateWindow("projtex"); 100532001f49Smrg glewInit(); 100632001f49Smrg 100732001f49Smrg if (argc > 1) { 100832001f49Smrg NumTextures = atoi(argv[1]); 100932001f49Smrg } 101032001f49Smrg assert(NumTextures <= MAX_TEX); 101132001f49Smrg 101232001f49Smrg loadTexture = loadImageTextures; 101332001f49Smrg drawObject = drawCube; 101432001f49Smrg initialize(); 101532001f49Smrg glutDisplayFunc(display); 101632001f49Smrg glutKeyboardFunc(key); 101732001f49Smrg glutReshapeFunc(reshape); 101832001f49Smrg glutMouseFunc(mouse); 101932001f49Smrg glutMotionFunc(trackMotion); 102032001f49Smrg glutVisibilityFunc(vis); 102132001f49Smrg glutCreateMenu(menu); 102232001f49Smrg glutAddMenuEntry("Toggle showing projection", 's'); 102332001f49Smrg glutAddMenuEntry("Switch texture", 't'); 102432001f49Smrg glutAddMenuEntry("Switch object", 'o'); 102532001f49Smrg glutAddMenuEntry("Toggle filtering", 'l'); 102632001f49Smrg glutAddMenuEntry("Quit", 666); 102732001f49Smrg glutAttachMenu(GLUT_RIGHT_BUTTON); 102832001f49Smrg texture(); 102932001f49Smrg glutMainLoop(); 103032001f49Smrg return 0; /* ANSI C requires main to return int. */ 103132001f49Smrg} 1032