132001f49Smrg/*----------------------------- 232001f49Smrg * stex3d.c GL example of the mesa 3d-texture extention to simulate procedural 332001f49Smrg * texturing, it uses a perlin noise and turbulence functions. 432001f49Smrg * 532001f49Smrg * Author: Daniel Barrero 632001f49Smrg * barrero@irit.fr 732001f49Smrg * dbarrero@pegasus.uniandes.edu.co 832001f49Smrg * 932001f49Smrg * Converted to GLUT by brianp on 1/1/98 1032001f49Smrg * Massive clean-up on 2002/10/23 by brianp 1132001f49Smrg * 1232001f49Smrg * 1332001f49Smrg * cc stex3d.c -o stex3d -lglut -lMesaGLU -lMesaGL -lX11 -lXext -lm 1432001f49Smrg * 1532001f49Smrg *---------------------------- */ 1632001f49Smrg 1732001f49Smrg#include <string.h> 1832001f49Smrg#include <stdio.h> 1932001f49Smrg#include <stdlib.h> 2032001f49Smrg#include <math.h> 2132001f49Smrg#include <GL/glew.h> 2232001f49Smrg#include "glut_wrap.h" 2332001f49Smrg 2432001f49Smrg 2532001f49Smrg#ifndef M_PI 2632001f49Smrg#define M_PI 3.14159265358979323846 2732001f49Smrg#endif 2832001f49Smrg 2932001f49Smrg#define NOISE_TEXTURE 1 3032001f49Smrg#define GRADIENT_TEXTURE 2 3132001f49Smrg 3232001f49Smrg#define TORUS 1 3332001f49Smrg#define SPHERE 2 3432001f49Smrg 3532001f49Smrgstatic int tex_width=64, tex_height=64, tex_depth=64; 3632001f49Smrgstatic float angx=0, angy=0, angz=0; 3732001f49Smrgstatic int texgen = 2, animate = 1, smooth = 1, wireframe = 0; 3832001f49Smrgstatic int CurTexture = NOISE_TEXTURE, CurObject = TORUS; 3932001f49Smrgstatic GLenum Filter = GL_LINEAR; 4032001f49Smrg 4132001f49Smrg 4232001f49Smrgstatic void 4332001f49SmrgBuildTorus(void) 4432001f49Smrg{ 4532001f49Smrg GLint i, j; 4632001f49Smrg float theta1, phi1, theta2, phi2, rings, sides; 4732001f49Smrg float v0[03], v1[3], v2[3], v3[3]; 4832001f49Smrg float t0[03], t1[3], t2[3], t3[3]; 4932001f49Smrg float n0[3], n1[3], n2[3], n3[3]; 5032001f49Smrg float innerRadius = 0.25; 5132001f49Smrg float outerRadius = 0.5; 5232001f49Smrg float scalFac; 5332001f49Smrg 5432001f49Smrg rings = 16; 5532001f49Smrg sides = 12; 5632001f49Smrg scalFac = 1 / (outerRadius * 2); 5732001f49Smrg 5832001f49Smrg glNewList(TORUS, GL_COMPILE); 5932001f49Smrg for (i = 0; i < rings; i++) { 6032001f49Smrg theta1 = (float) i *2.0 * M_PI / rings; 6132001f49Smrg theta2 = (float) (i + 1) * 2.0 * M_PI / rings; 6232001f49Smrg for (j = 0; j < sides; j++) { 6332001f49Smrg phi1 = (float) j *2.0 * M_PI / sides; 6432001f49Smrg phi2 = (float) (j + 1) * 2.0 * M_PI / sides; 6532001f49Smrg 6632001f49Smrg v0[0] = cos(theta1) * (outerRadius + innerRadius * cos(phi1)); 6732001f49Smrg v0[1] = -sin(theta1) * (outerRadius + innerRadius * cos(phi1)); 6832001f49Smrg v0[2] = innerRadius * sin(phi1); 6932001f49Smrg 7032001f49Smrg v1[0] = cos(theta2) * (outerRadius + innerRadius * cos(phi1)); 7132001f49Smrg v1[1] = -sin(theta2) * (outerRadius + innerRadius * cos(phi1)); 7232001f49Smrg v1[2] = innerRadius * sin(phi1); 7332001f49Smrg v2[0] = cos(theta2) * (outerRadius + innerRadius * cos(phi2)); 7432001f49Smrg v2[1] = -sin(theta2) * (outerRadius + innerRadius * cos(phi2)); 7532001f49Smrg v2[2] = innerRadius * sin(phi2); 7632001f49Smrg 7732001f49Smrg v3[0] = cos(theta1) * (outerRadius + innerRadius * cos(phi2)); 7832001f49Smrg v3[1] = -sin(theta1) * (outerRadius + innerRadius * cos(phi2)); 7932001f49Smrg v3[2] = innerRadius * sin(phi2); 8032001f49Smrg 8132001f49Smrg n0[0] = cos(theta1) * (cos(phi1)); 8232001f49Smrg n0[1] = -sin(theta1) * (cos(phi1)); 8332001f49Smrg n0[2] = sin(phi1); 8432001f49Smrg 8532001f49Smrg n1[0] = cos(theta2) * (cos(phi1)); 8632001f49Smrg n1[1] = -sin(theta2) * (cos(phi1)); 8732001f49Smrg n1[2] = sin(phi1); 8832001f49Smrg 8932001f49Smrg n2[0] = cos(theta2) * (cos(phi2)); 9032001f49Smrg n2[1] = -sin(theta2) * (cos(phi2)); 9132001f49Smrg n2[2] = sin(phi2); 9232001f49Smrg 9332001f49Smrg n3[0] = cos(theta1) * (cos(phi2)); 9432001f49Smrg n3[1] = -sin(theta1) * (cos(phi2)); 9532001f49Smrg n3[2] = sin(phi2); 9632001f49Smrg 9732001f49Smrg t0[0] = v0[0] * scalFac + 0.5; 9832001f49Smrg t0[1] = v0[1] * scalFac + 0.5; 9932001f49Smrg t0[2] = v0[2] * scalFac + 0.5; 10032001f49Smrg 10132001f49Smrg t1[0] = v1[0] * scalFac + 0.5; 10232001f49Smrg t1[1] = v1[1] * scalFac + 0.5; 10332001f49Smrg t1[2] = v1[2] * scalFac + 0.5; 10432001f49Smrg 10532001f49Smrg t2[0] = v2[0] * scalFac + 0.5; 10632001f49Smrg t2[1] = v2[1] * scalFac + 0.5; 10732001f49Smrg t2[2] = v2[2] * scalFac + 0.5; 10832001f49Smrg 10932001f49Smrg t3[0] = v3[0] * scalFac + 0.5; 11032001f49Smrg t3[1] = v3[1] * scalFac + 0.5; 11132001f49Smrg t3[2] = v3[2] * scalFac + 0.5; 11232001f49Smrg 11332001f49Smrg glBegin(GL_POLYGON); 11432001f49Smrg glNormal3fv(n3); 11532001f49Smrg glTexCoord3fv(t3); 11632001f49Smrg glVertex3fv(v3); 11732001f49Smrg glNormal3fv(n2); 11832001f49Smrg glTexCoord3fv(t2); 11932001f49Smrg glVertex3fv(v2); 12032001f49Smrg glNormal3fv(n1); 12132001f49Smrg glTexCoord3fv(t1); 12232001f49Smrg glVertex3fv(v1); 12332001f49Smrg glNormal3fv(n0); 12432001f49Smrg glTexCoord3fv(t0); 12532001f49Smrg glVertex3fv(v0); 12632001f49Smrg glEnd(); 12732001f49Smrg } 12832001f49Smrg } 12932001f49Smrg glEndList(); 13032001f49Smrg} 13132001f49Smrg 13232001f49Smrg 13332001f49Smrg/*-------------------------------------------------------------------- 13432001f49Smrg noise function over R3 - implemented by a pseudorandom tricubic spline 13532001f49Smrg EXCERPTED FROM SIGGRAPH 92, COURSE 23 13632001f49Smrg PROCEDURAL MODELING 13732001f49Smrg Ken Perlin 13832001f49Smrg New York University 13932001f49Smrg----------------------------------------------------------------------*/ 14032001f49Smrg 14132001f49Smrg 14232001f49Smrg#define DOT(a,b) (a[0] * b[0] + a[1] * b[1] + a[2] * b[2]) 14332001f49Smrg#define B 128 14432001f49Smrgstatic int p[B + B + 2]; 14532001f49Smrgstatic float g[B + B + 2][3]; 14632001f49Smrg#define setup(i,b0,b1,r0,r1) \ 14732001f49Smrg t = vec[i] + 10000.; \ 14832001f49Smrg b0 = ((int)t) & (B-1); \ 14932001f49Smrg b1 = (b0+1) & (B-1); \ 15032001f49Smrg r0 = t - (int)t; \ 15132001f49Smrg r1 = r0 - 1.; 15232001f49Smrg 15332001f49Smrgstatic float 15432001f49Smrgnoise3(float vec[3]) 15532001f49Smrg{ 15632001f49Smrg int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11; 15732001f49Smrg float rx0, rx1, ry0, ry1, rz0, rz1, *q, sx, sy, sz, a, b, c, d, t, u, v; 15832001f49Smrg register int i, j; 15932001f49Smrg 16032001f49Smrg setup(0, bx0, bx1, rx0, rx1); 16132001f49Smrg setup(1, by0, by1, ry0, ry1); 16232001f49Smrg setup(2, bz0, bz1, rz0, rz1); 16332001f49Smrg 16432001f49Smrg i = p[bx0]; 16532001f49Smrg j = p[bx1]; 16632001f49Smrg 16732001f49Smrg b00 = p[i + by0]; 16832001f49Smrg b10 = p[j + by0]; 16932001f49Smrg b01 = p[i + by1]; 17032001f49Smrg b11 = p[j + by1]; 17132001f49Smrg 17232001f49Smrg#define at(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] ) 17332001f49Smrg#define surve(t) ( t * t * (3. - 2. * t) ) 17432001f49Smrg#define lerp(t, a, b) ( a + t * (b - a) ) 17532001f49Smrg 17632001f49Smrg sx = surve(rx0); 17732001f49Smrg sy = surve(ry0); 17832001f49Smrg sz = surve(rz0); 17932001f49Smrg 18032001f49Smrg q = g[b00 + bz0]; 18132001f49Smrg u = at(rx0, ry0, rz0); 18232001f49Smrg q = g[b10 + bz0]; 18332001f49Smrg v = at(rx1, ry0, rz0); 18432001f49Smrg a = lerp(sx, u, v); 18532001f49Smrg 18632001f49Smrg q = g[b01 + bz0]; 18732001f49Smrg u = at(rx0, ry1, rz0); 18832001f49Smrg q = g[b11 + bz0]; 18932001f49Smrg v = at(rx1, ry1, rz0); 19032001f49Smrg b = lerp(sx, u, v); 19132001f49Smrg 19232001f49Smrg c = lerp(sy, a, b); /* interpolate in y at lo x */ 19332001f49Smrg 19432001f49Smrg q = g[b00 + bz1]; 19532001f49Smrg u = at(rx0, ry0, rz1); 19632001f49Smrg q = g[b10 + bz1]; 19732001f49Smrg v = at(rx1, ry0, rz1); 19832001f49Smrg a = lerp(sx, u, v); 19932001f49Smrg 20032001f49Smrg q = g[b01 + bz1]; 20132001f49Smrg u = at(rx0, ry1, rz1); 20232001f49Smrg q = g[b11 + bz1]; 20332001f49Smrg v = at(rx1, ry1, rz1); 20432001f49Smrg b = lerp(sx, u, v); 20532001f49Smrg 20632001f49Smrg d = lerp(sy, a, b); /* interpolate in y at hi x */ 20732001f49Smrg 20832001f49Smrg return 1.5 * lerp(sz, c, d); /* interpolate in z */ 20932001f49Smrg} 21032001f49Smrg 21132001f49Smrgstatic void 21232001f49SmrginitNoise(void) 21332001f49Smrg{ 21432001f49Smrg /*long random(); */ 21532001f49Smrg int i, j, k; 21632001f49Smrg float v[3], s; 21732001f49Smrg 21832001f49Smrg /* Create an array of random gradient vectors uniformly on the unit sphere */ 21932001f49Smrg /*srandom(1); */ 22032001f49Smrg srand(1); 22132001f49Smrg for (i = 0; i < B; i++) { 22232001f49Smrg do { /* Choose uniformly in a cube */ 22332001f49Smrg for (j = 0; j < 3; j++) 22432001f49Smrg v[j] = (float) ((rand() % (B + B)) - B) / B; 22532001f49Smrg s = DOT(v, v); 22632001f49Smrg } while (s > 1.0); /* If not in sphere try again */ 22732001f49Smrg s = sqrt(s); 22832001f49Smrg for (j = 0; j < 3; j++) /* Else normalize */ 22932001f49Smrg g[i][j] = v[j] / s; 23032001f49Smrg } 23132001f49Smrg 23232001f49Smrg /* Create a pseudorandom permutation of [1..B] */ 23332001f49Smrg for (i = 0; i < B; i++) 23432001f49Smrg p[i] = i; 23532001f49Smrg for (i = B; i > 0; i -= 2) { 23632001f49Smrg k = p[i]; 23732001f49Smrg p[i] = p[j = rand() % B]; 23832001f49Smrg p[j] = k; 23932001f49Smrg } 24032001f49Smrg 24132001f49Smrg /* Extend g and p arrays to allow for faster indexing */ 24232001f49Smrg for (i = 0; i < B + 2; i++) { 24332001f49Smrg p[B + i] = p[i]; 24432001f49Smrg for (j = 0; j < 3; j++) 24532001f49Smrg g[B + i][j] = g[i][j]; 24632001f49Smrg } 24732001f49Smrg} 24832001f49Smrg 24932001f49Smrg 25032001f49Smrgstatic float 25132001f49Smrgturbulence(float point[3], float lofreq, float hifreq) 25232001f49Smrg{ 25332001f49Smrg float freq, t, p[3]; 25432001f49Smrg 25532001f49Smrg p[0] = point[0] + 123.456; 25632001f49Smrg p[1] = point[1]; 25732001f49Smrg p[2] = point[2]; 25832001f49Smrg 25932001f49Smrg t = 0; 26032001f49Smrg for (freq = lofreq; freq < hifreq; freq *= 2.) { 26132001f49Smrg t += fabs(noise3(p)) / freq; 26232001f49Smrg p[0] *= 2.; 26332001f49Smrg p[1] *= 2.; 26432001f49Smrg p[2] *= 2.; 26532001f49Smrg } 26632001f49Smrg return t - 0.3; /* readjust to make mean value = 0.0 */ 26732001f49Smrg} 26832001f49Smrg 26932001f49Smrg 27032001f49Smrgstatic void 27132001f49Smrgcreate3Dtexture(void) 27232001f49Smrg{ 27332001f49Smrg unsigned char *voxels = NULL; 27432001f49Smrg int i, j, k; 27532001f49Smrg unsigned char *vp; 27632001f49Smrg float vec[3]; 27732001f49Smrg int tmp; 27832001f49Smrg 27932001f49Smrg printf("creating 3d textures...\n"); 28032001f49Smrg voxels = 28132001f49Smrg (unsigned char *) 28232001f49Smrg malloc((size_t) (4 * tex_width * tex_height * tex_depth)); 28332001f49Smrg vp = voxels; 28432001f49Smrg for (i = 0; i < tex_width; i++) { 28532001f49Smrg vec[0] = i; 28632001f49Smrg for (j = 0; j < tex_height; j++) { 28732001f49Smrg vec[1] = j; 28832001f49Smrg for (k = 0; k < tex_depth; k++) { 28932001f49Smrg vec[2] = k; 29032001f49Smrg tmp = (sin(k * i * j + turbulence(vec, 0.01, 1)) + 1) * 127.5; 29132001f49Smrg *vp++ = 0; 29232001f49Smrg *vp++ = 0; 29332001f49Smrg *vp++ = tmp; 29432001f49Smrg *vp++ = tmp + 128; 29532001f49Smrg } 29632001f49Smrg } 29732001f49Smrg } 29832001f49Smrg 29932001f49Smrg printf("setting up 3d texture...\n"); 30032001f49Smrg 30132001f49Smrg glBindTexture(GL_TEXTURE_3D, NOISE_TEXTURE); 30232001f49Smrg glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT); 30332001f49Smrg glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT); 30432001f49Smrg glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT); 30532001f49Smrg glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); 30632001f49Smrg 30732001f49Smrg glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 30832001f49Smrg glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 30932001f49Smrg tex_width, tex_height, tex_depth, 31032001f49Smrg 0, GL_RGBA, GL_UNSIGNED_BYTE, voxels); 31132001f49Smrg if (glGetError() == GL_OUT_OF_MEMORY) 31232001f49Smrg printf("stex3d: Out of memory allocating %d x %d x %d RGBA texture", 31332001f49Smrg tex_width, tex_height, tex_depth); 31432001f49Smrg 31532001f49Smrg free(voxels); 31632001f49Smrg 31732001f49Smrg printf("finished setting up 3d texture image.\n"); 31832001f49Smrg} 31932001f49Smrg 32032001f49Smrg 32132001f49Smrgstatic void 32232001f49SmrgprintHelp(void) 32332001f49Smrg{ 32432001f49Smrg printf("\nUsage: stex3d <cmd line options>\n"); 32532001f49Smrg printf(" cmd line options:\n"); 32632001f49Smrg printf(" -wxxx Width of the texture (Default=64)\n"); 32732001f49Smrg printf(" -hxxx Height of the texture (Default=64)\n"); 32832001f49Smrg printf(" -dxxx Depth of the texture (Default=64)\n"); 32932001f49Smrg printf(" Keyboard Options:\n"); 33032001f49Smrg printf(" up/down rotate around X\n"); 33132001f49Smrg printf(" left/right rotate around Y\n"); 33232001f49Smrg printf(" z/Z rotate around Z\n"); 33332001f49Smrg printf(" a toggle animation\n"); 33432001f49Smrg printf(" s toggle smooth shading\n"); 33532001f49Smrg printf(" t toggle texgen mode\n"); 33632001f49Smrg printf(" o toggle object: torus/sphere\n"); 33732001f49Smrg printf(" i toggle texture image: noise/gradient\n"); 33832001f49Smrg printf(" f toggle linear/nearest filtering\n"); 33932001f49Smrg} 34032001f49Smrg 34132001f49Smrg 34232001f49Smrgstatic GLenum 34332001f49SmrgparseCmdLine(int argc, char **argv) 34432001f49Smrg{ 34532001f49Smrg GLint i; 34632001f49Smrg 34732001f49Smrg for (i = 1; i < argc; i++) { 34832001f49Smrg if (strcmp(argv[i], "-help") == 0) { 34932001f49Smrg printHelp(); 35032001f49Smrg return GL_FALSE; 35132001f49Smrg } 35232001f49Smrg else if (strstr(argv[i], "-w") != NULL) { 35332001f49Smrg tex_width = atoi((argv[i]) + 2); 35432001f49Smrg } 35532001f49Smrg else if (strstr(argv[i], "-h") != NULL) { 35632001f49Smrg tex_height = atoi((argv[i]) + 2); 35732001f49Smrg } 35832001f49Smrg else if (strstr(argv[i], "-d") != NULL) { 35932001f49Smrg tex_depth = atoi((argv[i]) + 2); 36032001f49Smrg } 36132001f49Smrg else { 36232001f49Smrg printf("%s (Bad option).\n", argv[i]); 36332001f49Smrg printHelp(); 36432001f49Smrg return GL_FALSE; 36532001f49Smrg } 36632001f49Smrg } 36732001f49Smrg if (tex_width == 0 || tex_height == 0 || tex_depth == 0) { 36832001f49Smrg printf("%s (Bad option).\n", "size parameters can't be 0"); 36932001f49Smrg printHelp(); 37032001f49Smrg return GL_FALSE; 37132001f49Smrg } 37232001f49Smrg return GL_TRUE; 37332001f49Smrg} 37432001f49Smrg 37532001f49Smrg 37632001f49Smrgstatic void 37732001f49SmrgdrawScene(void) 37832001f49Smrg{ 37932001f49Smrg static const GLfloat sPlane[4] = { 0.5, 0, 0, -.5 }; 38032001f49Smrg static const GLfloat tPlane[4] = { 0, 0.5, 0, -.5 }; 38132001f49Smrg static const GLfloat rPlane[4] = { 0, 0, 0.5, -.5 }; 38232001f49Smrg 38332001f49Smrg glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 38432001f49Smrg glPushMatrix(); 38532001f49Smrg if (texgen == 2) { 38632001f49Smrg glTexGenfv(GL_S, GL_EYE_PLANE, sPlane); 38732001f49Smrg glTexGenfv(GL_T, GL_EYE_PLANE, tPlane); 38832001f49Smrg glTexGenfv(GL_R, GL_EYE_PLANE, rPlane); 38932001f49Smrg } 39032001f49Smrg 39132001f49Smrg glRotatef(angx, 1.0, 0.0, 0.0); 39232001f49Smrg glRotatef(angy, 0.0, 1.0, 0.0); 39332001f49Smrg glRotatef(angz, 0.0, 0.0, 1.0); 39432001f49Smrg 39532001f49Smrg if (texgen == 1) { 39632001f49Smrg glTexGenfv(GL_S, GL_EYE_PLANE, sPlane); 39732001f49Smrg glTexGenfv(GL_T, GL_EYE_PLANE, tPlane); 39832001f49Smrg glTexGenfv(GL_R, GL_EYE_PLANE, rPlane); 39932001f49Smrg } 40032001f49Smrg 40132001f49Smrg if (texgen) { 40232001f49Smrg glEnable(GL_TEXTURE_GEN_S); 40332001f49Smrg glEnable(GL_TEXTURE_GEN_T); 40432001f49Smrg glEnable(GL_TEXTURE_GEN_R); 40532001f49Smrg } 40632001f49Smrg else { 40732001f49Smrg glDisable(GL_TEXTURE_GEN_S); 40832001f49Smrg glDisable(GL_TEXTURE_GEN_T); 40932001f49Smrg glDisable(GL_TEXTURE_GEN_R); 41032001f49Smrg } 41132001f49Smrg 41232001f49Smrg glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, Filter); 41332001f49Smrg glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, Filter); 41432001f49Smrg 41532001f49Smrg glCallList(CurObject); 41632001f49Smrg glPopMatrix(); 41732001f49Smrg 41832001f49Smrg glutSwapBuffers(); 41932001f49Smrg} 42032001f49Smrg 42132001f49Smrg 42232001f49Smrgstatic void 42332001f49Smrgresize(int w, int h) 42432001f49Smrg{ 42532001f49Smrg float ar = (float) w / (float) h; 42632001f49Smrg float ax = 0.6 * ar; 42732001f49Smrg float ay = 0.6; 42832001f49Smrg glViewport(0, 0, (GLint) w, (GLint) h); 42932001f49Smrg glMatrixMode(GL_PROJECTION); 43032001f49Smrg glLoadIdentity(); 43132001f49Smrg glFrustum(-ax, ax, -ay, ay, 2, 20); 43232001f49Smrg /*glOrtho(-2, 2, -2, 2, -10, 10);*/ 43332001f49Smrg glMatrixMode(GL_MODELVIEW); 43432001f49Smrg glLoadIdentity(); 43532001f49Smrg glTranslatef(0, 0, -4); 43632001f49Smrg} 43732001f49Smrg 43832001f49Smrg 43932001f49Smrgstatic void 44032001f49SmrgIdle(void) 44132001f49Smrg{ 44232001f49Smrg float t = glutGet(GLUT_ELAPSED_TIME); 44332001f49Smrg angx = 0.01 * t; 44432001f49Smrg angy = 0.03 * t; 44532001f49Smrg angz += 0; 44632001f49Smrg glutPostRedisplay(); 44732001f49Smrg} 44832001f49Smrg 44932001f49Smrg 45032001f49Smrgstatic void 45132001f49SmrgSpecialKey(int k, int x, int y) 45232001f49Smrg{ 45332001f49Smrg switch (k) { 45432001f49Smrg case GLUT_KEY_UP: 45532001f49Smrg angx += 5.0; 45632001f49Smrg break; 45732001f49Smrg case GLUT_KEY_DOWN: 45832001f49Smrg angx -= 5.0; 45932001f49Smrg break; 46032001f49Smrg case GLUT_KEY_LEFT: 46132001f49Smrg angy += 5.0; 46232001f49Smrg break; 46332001f49Smrg case GLUT_KEY_RIGHT: 46432001f49Smrg angy -= 5.0; 46532001f49Smrg break; 46632001f49Smrg default: 46732001f49Smrg return; 46832001f49Smrg } 46932001f49Smrg glutPostRedisplay(); 47032001f49Smrg} 47132001f49Smrg 47232001f49Smrg 47332001f49Smrgstatic void 47432001f49SmrgKeyHandler(unsigned char key, int x, int y) 47532001f49Smrg{ 47632001f49Smrg static const char *mode[] = { 47732001f49Smrg "glTexCoord3f (no texgen)", 47832001f49Smrg "texgen fixed to object coords", 47932001f49Smrg "texgen fixed to eye coords" 48032001f49Smrg }; 48132001f49Smrg (void) x; 48232001f49Smrg (void) y; 48332001f49Smrg switch (key) { 48432001f49Smrg case 27: 48532001f49Smrg case 'q': 48632001f49Smrg case 'Q': /* quit game. */ 48732001f49Smrg exit(0); 48832001f49Smrg break; 48932001f49Smrg case 'z': 49032001f49Smrg angz += 10; 49132001f49Smrg break; 49232001f49Smrg case 'Z': 49332001f49Smrg angz -= 10; 49432001f49Smrg break; 49532001f49Smrg case 's': 49632001f49Smrg smooth = !smooth; 49732001f49Smrg if (smooth) 49832001f49Smrg glShadeModel(GL_SMOOTH); 49932001f49Smrg else 50032001f49Smrg glShadeModel(GL_FLAT); 50132001f49Smrg break; 50232001f49Smrg case 't': 50332001f49Smrg texgen++; 50432001f49Smrg if (texgen > 2) 50532001f49Smrg texgen = 0; 50632001f49Smrg printf("Texgen: %s\n", mode[texgen]); 50732001f49Smrg break; 50832001f49Smrg case 'o': 50932001f49Smrg if (CurObject == TORUS) 51032001f49Smrg CurObject = SPHERE; 51132001f49Smrg else 51232001f49Smrg CurObject = TORUS; 51332001f49Smrg break; 51432001f49Smrg case 'f': 51532001f49Smrg if (Filter == GL_LINEAR) 51632001f49Smrg Filter = GL_NEAREST; 51732001f49Smrg else 51832001f49Smrg Filter = GL_LINEAR; 51932001f49Smrg break; 52032001f49Smrg case 'i': 52132001f49Smrg if (CurTexture == NOISE_TEXTURE) 52232001f49Smrg CurTexture = GRADIENT_TEXTURE; 52332001f49Smrg else 52432001f49Smrg CurTexture = NOISE_TEXTURE; 52532001f49Smrg glBindTexture(GL_TEXTURE_3D, CurTexture); 52632001f49Smrg break; 52732001f49Smrg case 'a': 52832001f49Smrg case ' ': 52932001f49Smrg animate = !animate; 53032001f49Smrg if (animate) 53132001f49Smrg glutIdleFunc(Idle); 53232001f49Smrg else 53332001f49Smrg glutIdleFunc(NULL); 53432001f49Smrg break; 53532001f49Smrg case 'w': 53632001f49Smrg wireframe = !wireframe; 53732001f49Smrg if (wireframe) 53832001f49Smrg glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 53932001f49Smrg else 54032001f49Smrg glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 54132001f49Smrg break; 54232001f49Smrg default: 54332001f49Smrg break; 54432001f49Smrg } 54532001f49Smrg glutPostRedisplay(); 54632001f49Smrg} 54732001f49Smrg 54832001f49Smrg 54932001f49Smrgstatic void 55032001f49Smrgcreate3Dgradient(void) 55132001f49Smrg{ 55232001f49Smrg unsigned char *v; 55332001f49Smrg int i, j, k; 55432001f49Smrg unsigned char *voxels = NULL; 55532001f49Smrg 55632001f49Smrg voxels = (unsigned char *) malloc(4 * tex_width * tex_height * tex_depth); 55732001f49Smrg v = voxels; 55832001f49Smrg 55932001f49Smrg for (i = 0; i < tex_depth; i++) { 56032001f49Smrg for (j = 0; j < tex_height; j++) { 56132001f49Smrg for (k = 0; k < tex_width; k++) { 56232001f49Smrg GLint r = (255 * i) / (tex_depth - 1); 56332001f49Smrg GLint g = (255 * j) / (tex_height - 1); 56432001f49Smrg GLint b = (255 * k) / (tex_width - 1); 56532001f49Smrg *v++ = r; 56632001f49Smrg *v++ = g; 56732001f49Smrg *v++ = b; 56832001f49Smrg *v++ = 255; 56932001f49Smrg } 57032001f49Smrg } 57132001f49Smrg } 57232001f49Smrg 57332001f49Smrg 57432001f49Smrg glBindTexture(GL_TEXTURE_3D, GRADIENT_TEXTURE); 57532001f49Smrg glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT); 57632001f49Smrg glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT); 57732001f49Smrg glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT); 57832001f49Smrg glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); 57932001f49Smrg 58032001f49Smrg glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 58132001f49Smrg glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 58232001f49Smrg tex_width, tex_height, tex_depth, 58332001f49Smrg 0, GL_RGBA, GL_UNSIGNED_BYTE, voxels); 58432001f49Smrg if (glGetError() == GL_OUT_OF_MEMORY) 58532001f49Smrg printf("stex3d: Out of memory allocating %d x %d x %d RGBA texture", 58632001f49Smrg tex_width, tex_height, tex_depth); 58732001f49Smrg 58832001f49Smrg free(voxels); 58932001f49Smrg} 59032001f49Smrg 59132001f49Smrg 59232001f49Smrg 59332001f49Smrgstatic void 59432001f49Smrginit(void) 59532001f49Smrg{ 59632001f49Smrg static const GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; 59732001f49Smrg static const GLfloat mat_shininess[] = { 25.0 }; 59832001f49Smrg static const GLfloat gray[] = { 0.6, 0.6, 0.6, 0.0 }; 59932001f49Smrg static const GLfloat white[] = { 1.0, 1.0, 1.0, 0.0 }; 60032001f49Smrg static const GLfloat light_position[] = { 0.0, 1.0, 1.0, 0.0 }; 60132001f49Smrg 60232001f49Smrg int max; 60332001f49Smrg 60432001f49Smrg /* see if we have OpenGL 1.2 or later, for 3D texturing */ 60532001f49Smrg { 60632001f49Smrg const char *version = (const char *) glGetString(GL_VERSION); 60732001f49Smrg if (strncmp(version, "1.0", 3) == 0 || strncmp(version, "1.1", 3) == 0) { 60832001f49Smrg printf("Sorry, OpenGL 1.2 or later is required\n"); 60932001f49Smrg exit(1); 61032001f49Smrg } 61132001f49Smrg } 61232001f49Smrg printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER)); 61332001f49Smrg glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max); 61432001f49Smrg printf("GL_MAX_3D_TEXTURE_SIZE: %d\n", max); 61532001f49Smrg printf("Current 3D texture size: %d x %d x %d\n", 61632001f49Smrg tex_width, tex_height, tex_depth); 61732001f49Smrg 61832001f49Smrg /* init light */ 61932001f49Smrg glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); 62032001f49Smrg glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); 62132001f49Smrg glLightfv(GL_LIGHT1, GL_POSITION, light_position); 62232001f49Smrg glLightfv(GL_LIGHT1, GL_AMBIENT, gray); 62332001f49Smrg glLightfv(GL_LIGHT1, GL_DIFFUSE, white); 62432001f49Smrg glLightfv(GL_LIGHT1, GL_SPECULAR, white); 62532001f49Smrg glColorMaterial(GL_FRONT, GL_DIFFUSE); 62632001f49Smrg glEnable(GL_COLOR_MATERIAL); 62732001f49Smrg glEnable(GL_LIGHTING); 62832001f49Smrg glEnable(GL_LIGHT1); 62932001f49Smrg 63032001f49Smrg glClearColor(.5, .5, .5, 0); 63132001f49Smrg 63232001f49Smrg { 63332001f49Smrg GLUquadricObj *q; 63432001f49Smrg q = gluNewQuadric(); 63532001f49Smrg gluQuadricTexture( q, GL_TRUE ); 63632001f49Smrg glNewList(SPHERE, GL_COMPILE); 63732001f49Smrg gluSphere( q, 0.95, 30, 15 ); 63832001f49Smrg glEndList(); 63932001f49Smrg gluDeleteQuadric(q); 64032001f49Smrg } 64132001f49Smrg 64232001f49Smrg BuildTorus(); 64332001f49Smrg 64432001f49Smrg 64532001f49Smrg create3Dgradient(); 64632001f49Smrg 64732001f49Smrg initNoise(); 64832001f49Smrg create3Dtexture(); 64932001f49Smrg 65032001f49Smrg glEnable(GL_TEXTURE_3D); 65132001f49Smrg 65232001f49Smrg /* 65332001f49Smrg glBlendFunc(GL_SRC_COLOR, GL_SRC_ALPHA); 65432001f49Smrg glEnable(GL_BLEND); 65532001f49Smrg */ 65632001f49Smrg glEnable(GL_DEPTH_TEST); 65732001f49Smrg 65832001f49Smrg glColor3f(0.6, 0.7, 0.8); 65932001f49Smrg} 66032001f49Smrg 66132001f49Smrg 66232001f49Smrgint 66332001f49Smrgmain(int argc, char **argv) 66432001f49Smrg{ 66532001f49Smrg glutInit(&argc, argv); 66632001f49Smrg 66732001f49Smrg if (parseCmdLine(argc, argv) == GL_FALSE) { 66832001f49Smrg exit(0); 66932001f49Smrg } 67032001f49Smrg 67132001f49Smrg glutInitWindowPosition(0, 0); 67232001f49Smrg glutInitWindowSize(400, 400); 67332001f49Smrg glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); 67432001f49Smrg 67532001f49Smrg if (glutCreateWindow("stex3d") <= 0) { 67632001f49Smrg exit(0); 67732001f49Smrg } 67832001f49Smrg 67932001f49Smrg glewInit(); 68032001f49Smrg 68132001f49Smrg init(); 68232001f49Smrg 68332001f49Smrg printHelp(); 68432001f49Smrg 68532001f49Smrg glutReshapeFunc(resize); 68632001f49Smrg glutKeyboardFunc(KeyHandler); 68732001f49Smrg glutSpecialFunc(SpecialKey); 68832001f49Smrg glutDisplayFunc(drawScene); 68932001f49Smrg if (animate) 69032001f49Smrg glutIdleFunc(Idle); 69132001f49Smrg glutMainLoop(); 69232001f49Smrg return 0; 69332001f49Smrg} 69432001f49Smrg 695