blob: 427d1f3a50cc0e1a5287e2c5c596da7faed0b246 [file] [log] [blame]
Brian Paul4fbdedc2002-10-23 14:00:01 +00001/* $Id: stex3d.c,v 1.7 2002/10/23 14:00:01 brianp Exp $ */
jtgafb833d1999-08-19 00:55:39 +00002
3/*-----------------------------
4 * stex3d.c GL example of the mesa 3d-texture extention to simulate procedural
5 * texturing, it uses a perlin noise and turbulence functions.
6 *
7 * Author: Daniel Barrero
8 * barrero@irit.fr
9 * dbarrero@pegasus.uniandes.edu.co
10 *
11 * Converted to GLUT by brianp on 1/1/98
Brian Paul4fbdedc2002-10-23 14:00:01 +000012 * Massive clean-up on 2002/10/23 by brianp
jtgafb833d1999-08-19 00:55:39 +000013 *
14 *
15 * cc stex3d.c -o stex3d -lglut -lMesaGLU -lMesaGL -lX11 -lXext -lm
16 *
17 *---------------------------- */
18
jtgafb833d1999-08-19 00:55:39 +000019#include <string.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <math.h>
23#include <GL/gl.h>
24#include <GL/glut.h>
Brian Paul4fbdedc2002-10-23 14:00:01 +000025
26
jtgafb833d1999-08-19 00:55:39 +000027#ifndef M_PI
28#define M_PI 3.14159265358979323846
29#endif
jtgafb833d1999-08-19 00:55:39 +000030
Brian Paul4fbdedc2002-10-23 14:00:01 +000031#define NOISE_TEXTURE 1
32#define GRADIENT_TEXTURE 2
jtgafb833d1999-08-19 00:55:39 +000033
Brian Paul4fbdedc2002-10-23 14:00:01 +000034#define TORUS 1
35#define SPHERE 2
36
37static int tex_width=64, tex_height=64, tex_depth=64;
38static float angx=0, angy=0, angz=0;
39static GLuint DList;
40static int texgen = 2, animate = 1, smooth = 1;
41static int CurTexture = NOISE_TEXTURE, CurObject = TORUS;
42
43
44static void
45BuildTorus(void)
jtgafb833d1999-08-19 00:55:39 +000046{
Brian Paul4fbdedc2002-10-23 14:00:01 +000047 GLint i, j;
48 float theta1, phi1, theta2, phi2, rings, sides;
49 float v0[03], v1[3], v2[3], v3[3];
50 float t0[03], t1[3], t2[3], t3[3];
51 float n0[3], n1[3], n2[3], n3[3];
52 float innerRadius = 0.25;
53 float outerRadius = 0.5;
54 float scalFac;
jtgafb833d1999-08-19 00:55:39 +000055
Brian Paul4fbdedc2002-10-23 14:00:01 +000056 rings = 16;
57 sides = 12;
58 scalFac = 1 / (outerRadius * 2);
jtgafb833d1999-08-19 00:55:39 +000059
Brian Paul4fbdedc2002-10-23 14:00:01 +000060 glNewList(TORUS, GL_COMPILE);
61 for (i = 0; i < rings; i++) {
62 theta1 = (float) i *2.0 * M_PI / rings;
63 theta2 = (float) (i + 1) * 2.0 * M_PI / rings;
64 for (j = 0; j < sides; j++) {
65 phi1 = (float) j *2.0 * M_PI / sides;
66 phi2 = (float) (j + 1) * 2.0 * M_PI / sides;
jtgafb833d1999-08-19 00:55:39 +000067
Brian Paul4fbdedc2002-10-23 14:00:01 +000068 v0[0] = cos(theta1) * (outerRadius + innerRadius * cos(phi1));
69 v0[1] = -sin(theta1) * (outerRadius + innerRadius * cos(phi1));
70 v0[2] = innerRadius * sin(phi1);
jtgafb833d1999-08-19 00:55:39 +000071
Brian Paul4fbdedc2002-10-23 14:00:01 +000072 v1[0] = cos(theta2) * (outerRadius + innerRadius * cos(phi1));
73 v1[1] = -sin(theta2) * (outerRadius + innerRadius * cos(phi1));
74 v1[2] = innerRadius * sin(phi1);
75 v2[0] = cos(theta2) * (outerRadius + innerRadius * cos(phi2));
76 v2[1] = -sin(theta2) * (outerRadius + innerRadius * cos(phi2));
77 v2[2] = innerRadius * sin(phi2);
jtgafb833d1999-08-19 00:55:39 +000078
Brian Paul4fbdedc2002-10-23 14:00:01 +000079 v3[0] = cos(theta1) * (outerRadius + innerRadius * cos(phi2));
80 v3[1] = -sin(theta1) * (outerRadius + innerRadius * cos(phi2));
81 v3[2] = innerRadius * sin(phi2);
jtgafb833d1999-08-19 00:55:39 +000082
Brian Paul4fbdedc2002-10-23 14:00:01 +000083 n0[0] = cos(theta1) * (cos(phi1));
84 n0[1] = -sin(theta1) * (cos(phi1));
85 n0[2] = sin(phi1);
jtgafb833d1999-08-19 00:55:39 +000086
Brian Paul4fbdedc2002-10-23 14:00:01 +000087 n1[0] = cos(theta2) * (cos(phi1));
88 n1[1] = -sin(theta2) * (cos(phi1));
89 n1[2] = sin(phi1);
jtgafb833d1999-08-19 00:55:39 +000090
Brian Paul4fbdedc2002-10-23 14:00:01 +000091 n2[0] = cos(theta2) * (cos(phi2));
92 n2[1] = -sin(theta2) * (cos(phi2));
93 n2[2] = sin(phi2);
jtgafb833d1999-08-19 00:55:39 +000094
Brian Paul4fbdedc2002-10-23 14:00:01 +000095 n3[0] = cos(theta1) * (cos(phi2));
96 n3[1] = -sin(theta1) * (cos(phi2));
97 n3[2] = sin(phi2);
jtgafb833d1999-08-19 00:55:39 +000098
Brian Paul4fbdedc2002-10-23 14:00:01 +000099 t0[0] = v0[0] * scalFac + 0.5;
100 t0[1] = v0[1] * scalFac + 0.5;
101 t0[2] = v0[2] * scalFac + 0.5;
jtgafb833d1999-08-19 00:55:39 +0000102
Brian Paul4fbdedc2002-10-23 14:00:01 +0000103 t1[0] = v1[0] * scalFac + 0.5;
104 t1[1] = v1[1] * scalFac + 0.5;
105 t1[2] = v1[2] * scalFac + 0.5;
jtgafb833d1999-08-19 00:55:39 +0000106
Brian Paul4fbdedc2002-10-23 14:00:01 +0000107 t2[0] = v2[0] * scalFac + 0.5;
108 t2[1] = v2[1] * scalFac + 0.5;
109 t2[2] = v2[2] * scalFac + 0.5;
jtgafb833d1999-08-19 00:55:39 +0000110
Brian Paul4fbdedc2002-10-23 14:00:01 +0000111 t3[0] = v3[0] * scalFac + 0.5;
112 t3[1] = v3[1] * scalFac + 0.5;
113 t3[2] = v3[2] * scalFac + 0.5;
jtgafb833d1999-08-19 00:55:39 +0000114
Brian Paul4fbdedc2002-10-23 14:00:01 +0000115 glBegin(GL_POLYGON);
116 glNormal3fv(n3);
117 glTexCoord3fv(t3);
118 glVertex3fv(v3);
119 glNormal3fv(n2);
120 glTexCoord3fv(t2);
121 glVertex3fv(v2);
122 glNormal3fv(n1);
123 glTexCoord3fv(t1);
124 glVertex3fv(v1);
125 glNormal3fv(n0);
126 glTexCoord3fv(t0);
127 glVertex3fv(v0);
128 glEnd();
jtgafb833d1999-08-19 00:55:39 +0000129 }
jtgafb833d1999-08-19 00:55:39 +0000130 }
Brian Paul4fbdedc2002-10-23 14:00:01 +0000131 glEndList();
jtgafb833d1999-08-19 00:55:39 +0000132}
133
Brian Paul4fbdedc2002-10-23 14:00:01 +0000134
jtgafb833d1999-08-19 00:55:39 +0000135/*--------------------------------------------------------------------
136 noise function over R3 - implemented by a pseudorandom tricubic spline
137 EXCERPTED FROM SIGGRAPH 92, COURSE 23
138 PROCEDURAL MODELING
139 Ken Perlin
140 New York University
141----------------------------------------------------------------------*/
142
143
144#define DOT(a,b) (a[0] * b[0] + a[1] * b[1] + a[2] * b[2])
Brian Paul4fbdedc2002-10-23 14:00:01 +0000145#define B 128
jtgafb833d1999-08-19 00:55:39 +0000146static int p[B + B + 2];
147static float g[B + B + 2][3];
148#define setup(i,b0,b1,r0,r1) \
149 t = vec[i] + 10000.; \
150 b0 = ((int)t) & (B-1); \
151 b1 = (b0+1) & (B-1); \
152 r0 = t - (int)t; \
153 r1 = r0 - 1.;
154
Brian Paul4fbdedc2002-10-23 14:00:01 +0000155static float
156noise3(float vec[3])
jtgafb833d1999-08-19 00:55:39 +0000157{
Brian Paul4fbdedc2002-10-23 14:00:01 +0000158 int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
159 float rx0, rx1, ry0, ry1, rz0, rz1, *q, sx, sy, sz, a, b, c, d, t, u, v;
160 register int i, j;
jtgafb833d1999-08-19 00:55:39 +0000161
Brian Paul4fbdedc2002-10-23 14:00:01 +0000162 setup(0, bx0, bx1, rx0, rx1);
163 setup(1, by0, by1, ry0, ry1);
164 setup(2, bz0, bz1, rz0, rz1);
jtgafb833d1999-08-19 00:55:39 +0000165
Brian Paul4fbdedc2002-10-23 14:00:01 +0000166 i = p[bx0];
167 j = p[bx1];
jtgafb833d1999-08-19 00:55:39 +0000168
Brian Paul4fbdedc2002-10-23 14:00:01 +0000169 b00 = p[i + by0];
170 b10 = p[j + by0];
171 b01 = p[i + by1];
172 b11 = p[j + by1];
jtgafb833d1999-08-19 00:55:39 +0000173
174#define at(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
175#define surve(t) ( t * t * (3. - 2. * t) )
176#define lerp(t, a, b) ( a + t * (b - a) )
177
Brian Paul4fbdedc2002-10-23 14:00:01 +0000178 sx = surve(rx0);
179 sy = surve(ry0);
180 sz = surve(rz0);
jtgafb833d1999-08-19 00:55:39 +0000181
Brian Paul4fbdedc2002-10-23 14:00:01 +0000182 q = g[b00 + bz0];
183 u = at(rx0, ry0, rz0);
184 q = g[b10 + bz0];
185 v = at(rx1, ry0, rz0);
186 a = lerp(sx, u, v);
jtgafb833d1999-08-19 00:55:39 +0000187
Brian Paul4fbdedc2002-10-23 14:00:01 +0000188 q = g[b01 + bz0];
189 u = at(rx0, ry1, rz0);
190 q = g[b11 + bz0];
191 v = at(rx1, ry1, rz0);
192 b = lerp(sx, u, v);
jtgafb833d1999-08-19 00:55:39 +0000193
Brian Paul4fbdedc2002-10-23 14:00:01 +0000194 c = lerp(sy, a, b); /* interpolate in y at lo x */
jtgafb833d1999-08-19 00:55:39 +0000195
Brian Paul4fbdedc2002-10-23 14:00:01 +0000196 q = g[b00 + bz1];
197 u = at(rx0, ry0, rz1);
198 q = g[b10 + bz1];
199 v = at(rx1, ry0, rz1);
200 a = lerp(sx, u, v);
jtgafb833d1999-08-19 00:55:39 +0000201
Brian Paul4fbdedc2002-10-23 14:00:01 +0000202 q = g[b01 + bz1];
203 u = at(rx0, ry1, rz1);
204 q = g[b11 + bz1];
205 v = at(rx1, ry1, rz1);
206 b = lerp(sx, u, v);
jtgafb833d1999-08-19 00:55:39 +0000207
Brian Paul4fbdedc2002-10-23 14:00:01 +0000208 d = lerp(sy, a, b); /* interpolate in y at hi x */
jtgafb833d1999-08-19 00:55:39 +0000209
Brian Paul4fbdedc2002-10-23 14:00:01 +0000210 return 1.5 * lerp(sz, c, d); /* interpolate in z */
jtgafb833d1999-08-19 00:55:39 +0000211}
212
Brian Paul4fbdedc2002-10-23 14:00:01 +0000213static void
214initNoise(void)
jtgafb833d1999-08-19 00:55:39 +0000215{
Brian Paul4fbdedc2002-10-23 14:00:01 +0000216 /*long random(); */
217 int i, j, k;
218 float v[3], s;
jtgafb833d1999-08-19 00:55:39 +0000219
Brian Paul4fbdedc2002-10-23 14:00:01 +0000220 /* Create an array of random gradient vectors uniformly on the unit sphere */
221 /*srandom(1); */
222 srand(1);
223 for (i = 0; i < B; i++) {
224 do { /* Choose uniformly in a cube */
225 for (j = 0; j < 3; j++)
226 v[j] = (float) ((rand() % (B + B)) - B) / B;
227 s = DOT(v, v);
228 } while (s > 1.0); /* If not in sphere try again */
229 s = sqrt(s);
230 for (j = 0; j < 3; j++) /* Else normalize */
231 g[i][j] = v[j] / s;
232 }
jtgafb833d1999-08-19 00:55:39 +0000233
Brian Paul4fbdedc2002-10-23 14:00:01 +0000234 /* Create a pseudorandom permutation of [1..B] */
235 for (i = 0; i < B; i++)
236 p[i] = i;
237 for (i = B; i > 0; i -= 2) {
238 k = p[i];
239 p[i] = p[j = rand() % B];
240 p[j] = k;
241 }
jtgafb833d1999-08-19 00:55:39 +0000242
Brian Paul4fbdedc2002-10-23 14:00:01 +0000243 /* Extend g and p arrays to allow for faster indexing */
244 for (i = 0; i < B + 2; i++) {
245 p[B + i] = p[i];
246 for (j = 0; j < 3; j++)
247 g[B + i][j] = g[i][j];
248 }
jtgafb833d1999-08-19 00:55:39 +0000249}
250
Brian Paul4fbdedc2002-10-23 14:00:01 +0000251
252static float
253turbulence(float point[3], float lofreq, float hifreq)
jtgafb833d1999-08-19 00:55:39 +0000254{
Brian Paul4fbdedc2002-10-23 14:00:01 +0000255 float freq, t, p[3];
jtgafb833d1999-08-19 00:55:39 +0000256
Brian Paul4fbdedc2002-10-23 14:00:01 +0000257 p[0] = point[0] + 123.456;
258 p[1] = point[1];
259 p[2] = point[2];
jtgafb833d1999-08-19 00:55:39 +0000260
Brian Paul4fbdedc2002-10-23 14:00:01 +0000261 t = 0;
262 for (freq = lofreq; freq < hifreq; freq *= 2.) {
263 t += fabs(noise3(p)) / freq;
264 p[0] *= 2.;
265 p[1] *= 2.;
266 p[2] *= 2.;
267 }
268 return t - 0.3; /* readjust to make mean value = 0.0 */
269}
270
271
272static void
273create3Dtexture(void)
274{
275 unsigned char *voxels = NULL;
276 int i, j, k;
277 unsigned char *vp;
278 float vec[3];
279 int tmp;
280
281 printf("creating 3d textures...\n");
282 voxels =
283 (unsigned char *)
284 malloc((size_t) (4 * tex_width * tex_height * tex_depth));
285 vp = voxels;
286 for (i = 0; i < tex_width; i++) {
287 vec[0] = i;
288 for (j = 0; j < tex_height; j++) {
289 vec[1] = j;
290 for (k = 0; k < tex_depth; k++) {
291 vec[2] = k;
292 tmp = (sin(k * i * j + turbulence(vec, 0.01, 1)) + 1) * 127.5;
293 *vp++ = 0;
294 *vp++ = 0;
295 *vp++ = tmp;
296 *vp++ = tmp + 128;
297 }
298 }
299 }
300
301 printf("setting up 3d texture...\n");
302
303 glBindTexture(GL_TEXTURE_3D, NOISE_TEXTURE);
304 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
305 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
306 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
307 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
308 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
309 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
310
311 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
312 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA,
313 tex_width, tex_height, tex_depth,
314 0, GL_RGBA, GL_UNSIGNED_BYTE, voxels);
315
316 free(voxels);
317
318 printf("finished setting up 3d texture image.\n");
319}
320
321
322static void
323printHelp(void)
324{
325 printf("\nUsage: stex3d <cmd line options>\n");
326 printf(" cmd line options:\n");
327 printf(" -wxxx Width of the texture (Default=64)\n");
328 printf(" -hxxx Height of the texture (Default=64)\n");
329 printf(" -dxxx Depth of the texture (Default=64)\n");
330 printf(" Keyboard Options:\n");
331 printf(" up/down rotate around X\n");
332 printf(" left/right rotate around Y\n");
333 printf(" z/Z rotate around Z\n");
334 printf(" a toggle animation\n");
335 printf(" s toggle smooth shading\n");
336 printf(" t toggle texgen mode\n");
337 printf(" o toggle object: torus/sphere\n");
338 printf(" i toggle texture image: noise/gradient\n");
339}
340
341
342static GLenum
343parseCmdLine(int argc, char **argv)
344{
345 GLint i;
346
347 for (i = 1; i < argc; i++) {
348 if (strstr(argv[i], "-w") == 0) {
349 tex_width = atoi((argv[i]) + 2);
350 }
351 else if (strstr(argv[i], "-h") == 0) {
352 tex_height = atoi((argv[i]) + 2);
353 }
354 else if (strstr(argv[i], "-d") == 0) {
355 tex_depth = atoi((argv[i]) + 2);
356 }
357 else if (strcmp(argv[i], "-help") == 0) {
358 printHelp();
359 return GL_FALSE;
360 }
361 else {
362 printf("%s (Bad option).\n", argv[i]);
363 printHelp();
364 return GL_FALSE;
365 }
366 }
367 if (tex_width == 0 || tex_height == 0 || tex_depth == 0) {
368 printf("%s (Bad option).\n", "size parameters can't be 0");
369 printHelp();
370 return GL_FALSE;
371 }
372 return GL_TRUE;
373}
374
375
376static void
377drawScene(void)
378{
379 static const GLfloat sPlane[4] = { 0.5, 0, 0, -.5 };
380 static const GLfloat tPlane[4] = { 0, 0.5, 0, -.5 };
381 static const GLfloat rPlane[4] = { 0, 0, 0.5, -.5 };
382
383 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
384 glPushMatrix();
385 if (texgen == 2) {
386 glTexGenfv(GL_S, GL_EYE_PLANE, sPlane);
387 glTexGenfv(GL_T, GL_EYE_PLANE, tPlane);
388 glTexGenfv(GL_R, GL_EYE_PLANE, rPlane);
389 }
390
391 glRotatef(angx, 1.0, 0.0, 0.0);
392 glRotatef(angy, 0.0, 1.0, 0.0);
393 glRotatef(angz, 0.0, 0.0, 1.0);
394
395 if (texgen == 1) {
396 glTexGenfv(GL_S, GL_EYE_PLANE, sPlane);
397 glTexGenfv(GL_T, GL_EYE_PLANE, tPlane);
398 glTexGenfv(GL_R, GL_EYE_PLANE, rPlane);
399 }
400
401 if (texgen) {
402 glEnable(GL_TEXTURE_GEN_S);
403 glEnable(GL_TEXTURE_GEN_T);
404 glEnable(GL_TEXTURE_GEN_R);
405 }
406 else {
407 glDisable(GL_TEXTURE_GEN_S);
408 glDisable(GL_TEXTURE_GEN_T);
409 glDisable(GL_TEXTURE_GEN_R);
410 }
411
412 glCallList(CurObject);
413 glPopMatrix();
414
415 glutSwapBuffers();
416}
417
418
419static void
420resize(int w, int h)
421{
422 float ar = (float) w / (float) h;
423 float ax = 0.6 * ar;
424 float ay = 0.6;
425 glViewport(0, 0, (GLint) w, (GLint) h);
426 glMatrixMode(GL_PROJECTION);
427 glLoadIdentity();
428 glFrustum(-ax, ax, -ay, ay, 2, 20);
429 /*glOrtho(-2, 2, -2, 2, -10, 10);*/
430 glMatrixMode(GL_MODELVIEW);
431 glLoadIdentity();
432 glTranslatef(0, 0, -4);
433}
434
435
436static void
437Idle(void)
438{
439 float t = glutGet(GLUT_ELAPSED_TIME);
440 angx = 0.01 * t;
441 angy = 0.03 * t;
442 angz += 0;
443 glutPostRedisplay();
444}
445
446
447static void
448SpecialKey(int k, int x, int y)
449{
450 switch (k) {
451 case GLUT_KEY_UP:
452 angx += 5.0;
453 break;
454 case GLUT_KEY_DOWN:
455 angx -= 5.0;
456 break;
457 case GLUT_KEY_LEFT:
458 angy += 5.0;
459 break;
460 case GLUT_KEY_RIGHT:
461 angy -= 5.0;
462 break;
463 default:
464 return;
465 }
466 glutPostRedisplay();
467}
468
469
470static void
471KeyHandler(unsigned char key, int x, int y)
472{
473 static const char *mode[] = {
474 "glTexCoord3f (no texgen)",
475 "texgen fixed to eye coords",
476 "texgen fixed to object coords"
477 };
478 (void) x;
479 (void) y;
480 switch (key) {
481 case 27:
482 case 'q':
483 case 'Q': /* quit game. */
484 exit(0);
485 break;
486 case 'z':
487 angz += 10;
488 break;
489 case 'Z':
490 angz -= 10;
491 break;
492 case 's':
493 smooth = !smooth;
494 if (smooth)
495 glShadeModel(GL_SMOOTH);
496 else
497 glShadeModel(GL_FLAT);
498 break;
499 case 't':
500 texgen++;
501 if (texgen > 2)
502 texgen = 0;
503 printf("Texgen: %s\n", mode[texgen]);
504 break;
505 case 'o':
506 if (CurObject == TORUS)
507 CurObject = SPHERE;
508 else
509 CurObject = TORUS;
510 break;
511 case 'i':
512 if (CurTexture == NOISE_TEXTURE)
513 CurTexture = GRADIENT_TEXTURE;
514 else
515 CurTexture = NOISE_TEXTURE;
516 glBindTexture(GL_TEXTURE_3D, CurTexture);
517 break;
518 case 'a':
519 animate = !animate;
520 if (animate)
521 glutIdleFunc(Idle);
522 else
523 glutIdleFunc(NULL);
524 break;
525 default:
526 break;
527 }
528 glutPostRedisplay();
529}
530
531
532void
533create3Dgradient(void)
534{
535 unsigned char *v;
536 int i, j, k;
537 unsigned char *voxels = NULL;
538
539 voxels = (unsigned char *) malloc(4 * tex_width * tex_height * tex_depth);
540 v = voxels;
541
542 for (i = 0; i < tex_depth; i++) {
543 for (j = 0; j < tex_height; j++) {
544 for (k = 0; k < tex_width; k++) {
545 GLint r = (255 * i) / (tex_depth - 1);
546 GLint g = (255 * j) / (tex_height - 1);
547 GLint b = (255 * k) / (tex_width - 1);
548 *v++ = r;
549 *v++ = g;
550 *v++ = b;
551 *v++ = 255;
552 }
553 }
554 }
555
556
557 glBindTexture(GL_TEXTURE_3D, GRADIENT_TEXTURE);
558 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
559 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
560 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
561 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
562 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
563 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
564
565 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
566 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA,
567 tex_width, tex_height, tex_depth,
568 0, GL_RGBA, GL_UNSIGNED_BYTE, voxels);
569
570 free(voxels);
571}
572
573
574
575static void
576init(void)
577{
578 static const GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
579 static const GLfloat mat_shininess[] = { 25.0 };
580 static const GLfloat gray[] = { 0.6, 0.6, 0.6, 0.0 };
581 static const GLfloat white[] = { 1.0, 1.0, 1.0, 0.0 };
582 static const GLfloat light_position[] = { 0.0, 1.0, 1.0, 0.0 };
583
584 int max;
585
586 /* see if we have OpenGL 1.2 or later, for 3D texturing */
587 {
588 const char *version = (const char *) glGetString(GL_VERSION);
589 if (strncmp(version, "1.0", 3) == 0 || strncmp(version, "1.1", 3) == 0) {
590 printf("Sorry, OpenGL 1.2 or later is required\n");
591 exit(1);
592 }
593 }
594 printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
595 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max);
596 printf("GL_MAX_3D_TEXTURE_SIZE: %d\n", max);
597 printf("Current 3D texture size: %d x %d x %d\n",
598 tex_width, tex_height, tex_depth);
599
600 /* init light */
601 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
602 glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
603 glLightfv(GL_LIGHT1, GL_POSITION, light_position);
604 glLightfv(GL_LIGHT1, GL_AMBIENT, gray);
605 glLightfv(GL_LIGHT1, GL_DIFFUSE, white);
606 glLightfv(GL_LIGHT1, GL_SPECULAR, white);
607 glColorMaterial(GL_FRONT, GL_DIFFUSE);
608 glEnable(GL_COLOR_MATERIAL);
609 glEnable(GL_LIGHTING);
610 glEnable(GL_LIGHT1);
611
612 glClearColor(.5, .5, .5, 0);
613
614 /* create torus for texturing */
615 DList = glGenLists(1);
616
617 glNewList(SPHERE, GL_COMPILE);
618 glutSolidSphere(0.95, 30, 15);
619 glEndList();
620
621 BuildTorus();
622
623
624 create3Dgradient();
625
626 initNoise();
627 create3Dtexture();
628
629 glEnable(GL_TEXTURE_3D);
630
631 /*
632 glBlendFunc(GL_SRC_COLOR, GL_SRC_ALPHA);
633 glEnable(GL_BLEND);
634 */
635 glEnable(GL_DEPTH_TEST);
636
637 glColor3f(0.6, 0.7, 0.8);
638}
639
640
641int
642main(int argc, char **argv)
643{
644 glutInit(&argc, argv);
645
646 if (parseCmdLine(argc, argv) == GL_FALSE) {
647 exit(0);
648 }
649
650 glutInitWindowPosition(0, 0);
651 glutInitWindowSize(400, 400);
652 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
653
654 if (glutCreateWindow("stex3d") <= 0) {
655 exit(0);
656 }
657
658 init();
659
660 printHelp();
661
662 glutReshapeFunc(resize);
663 glutKeyboardFunc(KeyHandler);
664 glutSpecialFunc(SpecialKey);
665 glutDisplayFunc(drawScene);
666 if (animate)
667 glutIdleFunc(Idle);
668 glutMainLoop();
669 return 0;
jtgafb833d1999-08-19 00:55:39 +0000670}
671