blob: b7ba1e9b0f3fc6c891a51dbc98f36a6e7216cd30 [file] [log] [blame]
Brian Paul55b0ff22003-03-31 16:51:38 +00001/* $Id: stex3d.c,v 1.9 2003/03/31 16:51:38 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;
Brian Paul55b0ff22003-03-31 16:51:38 +000039static int texgen = 2, animate = 1, smooth = 1, wireframe = 0;
Brian Paul4fbdedc2002-10-23 14:00:01 +000040static int CurTexture = NOISE_TEXTURE, CurObject = TORUS;
41
42
43static void
44BuildTorus(void)
jtgafb833d1999-08-19 00:55:39 +000045{
Brian Paul4fbdedc2002-10-23 14:00:01 +000046 GLint i, j;
47 float theta1, phi1, theta2, phi2, rings, sides;
48 float v0[03], v1[3], v2[3], v3[3];
49 float t0[03], t1[3], t2[3], t3[3];
50 float n0[3], n1[3], n2[3], n3[3];
51 float innerRadius = 0.25;
52 float outerRadius = 0.5;
53 float scalFac;
jtgafb833d1999-08-19 00:55:39 +000054
Brian Paul4fbdedc2002-10-23 14:00:01 +000055 rings = 16;
56 sides = 12;
57 scalFac = 1 / (outerRadius * 2);
jtgafb833d1999-08-19 00:55:39 +000058
Brian Paul4fbdedc2002-10-23 14:00:01 +000059 glNewList(TORUS, GL_COMPILE);
60 for (i = 0; i < rings; i++) {
61 theta1 = (float) i *2.0 * M_PI / rings;
62 theta2 = (float) (i + 1) * 2.0 * M_PI / rings;
63 for (j = 0; j < sides; j++) {
64 phi1 = (float) j *2.0 * M_PI / sides;
65 phi2 = (float) (j + 1) * 2.0 * M_PI / sides;
jtgafb833d1999-08-19 00:55:39 +000066
Brian Paul4fbdedc2002-10-23 14:00:01 +000067 v0[0] = cos(theta1) * (outerRadius + innerRadius * cos(phi1));
68 v0[1] = -sin(theta1) * (outerRadius + innerRadius * cos(phi1));
69 v0[2] = innerRadius * sin(phi1);
jtgafb833d1999-08-19 00:55:39 +000070
Brian Paul4fbdedc2002-10-23 14:00:01 +000071 v1[0] = cos(theta2) * (outerRadius + innerRadius * cos(phi1));
72 v1[1] = -sin(theta2) * (outerRadius + innerRadius * cos(phi1));
73 v1[2] = innerRadius * sin(phi1);
74 v2[0] = cos(theta2) * (outerRadius + innerRadius * cos(phi2));
75 v2[1] = -sin(theta2) * (outerRadius + innerRadius * cos(phi2));
76 v2[2] = innerRadius * sin(phi2);
jtgafb833d1999-08-19 00:55:39 +000077
Brian Paul4fbdedc2002-10-23 14:00:01 +000078 v3[0] = cos(theta1) * (outerRadius + innerRadius * cos(phi2));
79 v3[1] = -sin(theta1) * (outerRadius + innerRadius * cos(phi2));
80 v3[2] = innerRadius * sin(phi2);
jtgafb833d1999-08-19 00:55:39 +000081
Brian Paul4fbdedc2002-10-23 14:00:01 +000082 n0[0] = cos(theta1) * (cos(phi1));
83 n0[1] = -sin(theta1) * (cos(phi1));
84 n0[2] = sin(phi1);
jtgafb833d1999-08-19 00:55:39 +000085
Brian Paul4fbdedc2002-10-23 14:00:01 +000086 n1[0] = cos(theta2) * (cos(phi1));
87 n1[1] = -sin(theta2) * (cos(phi1));
88 n1[2] = sin(phi1);
jtgafb833d1999-08-19 00:55:39 +000089
Brian Paul4fbdedc2002-10-23 14:00:01 +000090 n2[0] = cos(theta2) * (cos(phi2));
91 n2[1] = -sin(theta2) * (cos(phi2));
92 n2[2] = sin(phi2);
jtgafb833d1999-08-19 00:55:39 +000093
Brian Paul4fbdedc2002-10-23 14:00:01 +000094 n3[0] = cos(theta1) * (cos(phi2));
95 n3[1] = -sin(theta1) * (cos(phi2));
96 n3[2] = sin(phi2);
jtgafb833d1999-08-19 00:55:39 +000097
Brian Paul4fbdedc2002-10-23 14:00:01 +000098 t0[0] = v0[0] * scalFac + 0.5;
99 t0[1] = v0[1] * scalFac + 0.5;
100 t0[2] = v0[2] * scalFac + 0.5;
jtgafb833d1999-08-19 00:55:39 +0000101
Brian Paul4fbdedc2002-10-23 14:00:01 +0000102 t1[0] = v1[0] * scalFac + 0.5;
103 t1[1] = v1[1] * scalFac + 0.5;
104 t1[2] = v1[2] * scalFac + 0.5;
jtgafb833d1999-08-19 00:55:39 +0000105
Brian Paul4fbdedc2002-10-23 14:00:01 +0000106 t2[0] = v2[0] * scalFac + 0.5;
107 t2[1] = v2[1] * scalFac + 0.5;
108 t2[2] = v2[2] * scalFac + 0.5;
jtgafb833d1999-08-19 00:55:39 +0000109
Brian Paul4fbdedc2002-10-23 14:00:01 +0000110 t3[0] = v3[0] * scalFac + 0.5;
111 t3[1] = v3[1] * scalFac + 0.5;
112 t3[2] = v3[2] * scalFac + 0.5;
jtgafb833d1999-08-19 00:55:39 +0000113
Brian Paul4fbdedc2002-10-23 14:00:01 +0000114 glBegin(GL_POLYGON);
115 glNormal3fv(n3);
116 glTexCoord3fv(t3);
117 glVertex3fv(v3);
118 glNormal3fv(n2);
119 glTexCoord3fv(t2);
120 glVertex3fv(v2);
121 glNormal3fv(n1);
122 glTexCoord3fv(t1);
123 glVertex3fv(v1);
124 glNormal3fv(n0);
125 glTexCoord3fv(t0);
126 glVertex3fv(v0);
127 glEnd();
jtgafb833d1999-08-19 00:55:39 +0000128 }
jtgafb833d1999-08-19 00:55:39 +0000129 }
Brian Paul4fbdedc2002-10-23 14:00:01 +0000130 glEndList();
jtgafb833d1999-08-19 00:55:39 +0000131}
132
Brian Paul4fbdedc2002-10-23 14:00:01 +0000133
jtgafb833d1999-08-19 00:55:39 +0000134/*--------------------------------------------------------------------
135 noise function over R3 - implemented by a pseudorandom tricubic spline
136 EXCERPTED FROM SIGGRAPH 92, COURSE 23
137 PROCEDURAL MODELING
138 Ken Perlin
139 New York University
140----------------------------------------------------------------------*/
141
142
143#define DOT(a,b) (a[0] * b[0] + a[1] * b[1] + a[2] * b[2])
Brian Paul4fbdedc2002-10-23 14:00:01 +0000144#define B 128
jtgafb833d1999-08-19 00:55:39 +0000145static int p[B + B + 2];
146static float g[B + B + 2][3];
147#define setup(i,b0,b1,r0,r1) \
148 t = vec[i] + 10000.; \
149 b0 = ((int)t) & (B-1); \
150 b1 = (b0+1) & (B-1); \
151 r0 = t - (int)t; \
152 r1 = r0 - 1.;
153
Brian Paul4fbdedc2002-10-23 14:00:01 +0000154static float
155noise3(float vec[3])
jtgafb833d1999-08-19 00:55:39 +0000156{
Brian Paul4fbdedc2002-10-23 14:00:01 +0000157 int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
158 float rx0, rx1, ry0, ry1, rz0, rz1, *q, sx, sy, sz, a, b, c, d, t, u, v;
159 register int i, j;
jtgafb833d1999-08-19 00:55:39 +0000160
Brian Paul4fbdedc2002-10-23 14:00:01 +0000161 setup(0, bx0, bx1, rx0, rx1);
162 setup(1, by0, by1, ry0, ry1);
163 setup(2, bz0, bz1, rz0, rz1);
jtgafb833d1999-08-19 00:55:39 +0000164
Brian Paul4fbdedc2002-10-23 14:00:01 +0000165 i = p[bx0];
166 j = p[bx1];
jtgafb833d1999-08-19 00:55:39 +0000167
Brian Paul4fbdedc2002-10-23 14:00:01 +0000168 b00 = p[i + by0];
169 b10 = p[j + by0];
170 b01 = p[i + by1];
171 b11 = p[j + by1];
jtgafb833d1999-08-19 00:55:39 +0000172
173#define at(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
174#define surve(t) ( t * t * (3. - 2. * t) )
175#define lerp(t, a, b) ( a + t * (b - a) )
176
Brian Paul4fbdedc2002-10-23 14:00:01 +0000177 sx = surve(rx0);
178 sy = surve(ry0);
179 sz = surve(rz0);
jtgafb833d1999-08-19 00:55:39 +0000180
Brian Paul4fbdedc2002-10-23 14:00:01 +0000181 q = g[b00 + bz0];
182 u = at(rx0, ry0, rz0);
183 q = g[b10 + bz0];
184 v = at(rx1, ry0, rz0);
185 a = lerp(sx, u, v);
jtgafb833d1999-08-19 00:55:39 +0000186
Brian Paul4fbdedc2002-10-23 14:00:01 +0000187 q = g[b01 + bz0];
188 u = at(rx0, ry1, rz0);
189 q = g[b11 + bz0];
190 v = at(rx1, ry1, rz0);
191 b = lerp(sx, u, v);
jtgafb833d1999-08-19 00:55:39 +0000192
Brian Paul4fbdedc2002-10-23 14:00:01 +0000193 c = lerp(sy, a, b); /* interpolate in y at lo x */
jtgafb833d1999-08-19 00:55:39 +0000194
Brian Paul4fbdedc2002-10-23 14:00:01 +0000195 q = g[b00 + bz1];
196 u = at(rx0, ry0, rz1);
197 q = g[b10 + bz1];
198 v = at(rx1, ry0, rz1);
199 a = lerp(sx, u, v);
jtgafb833d1999-08-19 00:55:39 +0000200
Brian Paul4fbdedc2002-10-23 14:00:01 +0000201 q = g[b01 + bz1];
202 u = at(rx0, ry1, rz1);
203 q = g[b11 + bz1];
204 v = at(rx1, ry1, rz1);
205 b = lerp(sx, u, v);
jtgafb833d1999-08-19 00:55:39 +0000206
Brian Paul4fbdedc2002-10-23 14:00:01 +0000207 d = lerp(sy, a, b); /* interpolate in y at hi x */
jtgafb833d1999-08-19 00:55:39 +0000208
Brian Paul4fbdedc2002-10-23 14:00:01 +0000209 return 1.5 * lerp(sz, c, d); /* interpolate in z */
jtgafb833d1999-08-19 00:55:39 +0000210}
211
Brian Paul4fbdedc2002-10-23 14:00:01 +0000212static void
213initNoise(void)
jtgafb833d1999-08-19 00:55:39 +0000214{
Brian Paul4fbdedc2002-10-23 14:00:01 +0000215 /*long random(); */
216 int i, j, k;
217 float v[3], s;
jtgafb833d1999-08-19 00:55:39 +0000218
Brian Paul4fbdedc2002-10-23 14:00:01 +0000219 /* Create an array of random gradient vectors uniformly on the unit sphere */
220 /*srandom(1); */
221 srand(1);
222 for (i = 0; i < B; i++) {
223 do { /* Choose uniformly in a cube */
224 for (j = 0; j < 3; j++)
225 v[j] = (float) ((rand() % (B + B)) - B) / B;
226 s = DOT(v, v);
227 } while (s > 1.0); /* If not in sphere try again */
228 s = sqrt(s);
229 for (j = 0; j < 3; j++) /* Else normalize */
230 g[i][j] = v[j] / s;
231 }
jtgafb833d1999-08-19 00:55:39 +0000232
Brian Paul4fbdedc2002-10-23 14:00:01 +0000233 /* Create a pseudorandom permutation of [1..B] */
234 for (i = 0; i < B; i++)
235 p[i] = i;
236 for (i = B; i > 0; i -= 2) {
237 k = p[i];
238 p[i] = p[j = rand() % B];
239 p[j] = k;
240 }
jtgafb833d1999-08-19 00:55:39 +0000241
Brian Paul4fbdedc2002-10-23 14:00:01 +0000242 /* Extend g and p arrays to allow for faster indexing */
243 for (i = 0; i < B + 2; i++) {
244 p[B + i] = p[i];
245 for (j = 0; j < 3; j++)
246 g[B + i][j] = g[i][j];
247 }
jtgafb833d1999-08-19 00:55:39 +0000248}
249
Brian Paul4fbdedc2002-10-23 14:00:01 +0000250
251static float
252turbulence(float point[3], float lofreq, float hifreq)
jtgafb833d1999-08-19 00:55:39 +0000253{
Brian Paul4fbdedc2002-10-23 14:00:01 +0000254 float freq, t, p[3];
jtgafb833d1999-08-19 00:55:39 +0000255
Brian Paul4fbdedc2002-10-23 14:00:01 +0000256 p[0] = point[0] + 123.456;
257 p[1] = point[1];
258 p[2] = point[2];
jtgafb833d1999-08-19 00:55:39 +0000259
Brian Paul4fbdedc2002-10-23 14:00:01 +0000260 t = 0;
261 for (freq = lofreq; freq < hifreq; freq *= 2.) {
262 t += fabs(noise3(p)) / freq;
263 p[0] *= 2.;
264 p[1] *= 2.;
265 p[2] *= 2.;
266 }
267 return t - 0.3; /* readjust to make mean value = 0.0 */
268}
269
270
271static void
272create3Dtexture(void)
273{
274 unsigned char *voxels = NULL;
275 int i, j, k;
276 unsigned char *vp;
277 float vec[3];
278 int tmp;
279
280 printf("creating 3d textures...\n");
281 voxels =
282 (unsigned char *)
283 malloc((size_t) (4 * tex_width * tex_height * tex_depth));
284 vp = voxels;
285 for (i = 0; i < tex_width; i++) {
286 vec[0] = i;
287 for (j = 0; j < tex_height; j++) {
288 vec[1] = j;
289 for (k = 0; k < tex_depth; k++) {
290 vec[2] = k;
291 tmp = (sin(k * i * j + turbulence(vec, 0.01, 1)) + 1) * 127.5;
292 *vp++ = 0;
293 *vp++ = 0;
294 *vp++ = tmp;
295 *vp++ = tmp + 128;
296 }
297 }
298 }
299
300 printf("setting up 3d texture...\n");
301
302 glBindTexture(GL_TEXTURE_3D, NOISE_TEXTURE);
303 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
304 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
305 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
306 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
307 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
308 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
309
310 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
311 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA,
312 tex_width, tex_height, tex_depth,
313 0, GL_RGBA, GL_UNSIGNED_BYTE, voxels);
314
315 free(voxels);
316
317 printf("finished setting up 3d texture image.\n");
318}
319
320
321static void
322printHelp(void)
323{
324 printf("\nUsage: stex3d <cmd line options>\n");
325 printf(" cmd line options:\n");
326 printf(" -wxxx Width of the texture (Default=64)\n");
327 printf(" -hxxx Height of the texture (Default=64)\n");
328 printf(" -dxxx Depth of the texture (Default=64)\n");
329 printf(" Keyboard Options:\n");
330 printf(" up/down rotate around X\n");
331 printf(" left/right rotate around Y\n");
332 printf(" z/Z rotate around Z\n");
333 printf(" a toggle animation\n");
334 printf(" s toggle smooth shading\n");
335 printf(" t toggle texgen mode\n");
336 printf(" o toggle object: torus/sphere\n");
337 printf(" i toggle texture image: noise/gradient\n");
338}
339
340
341static GLenum
342parseCmdLine(int argc, char **argv)
343{
344 GLint i;
345
346 for (i = 1; i < argc; i++) {
347 if (strstr(argv[i], "-w") == 0) {
348 tex_width = atoi((argv[i]) + 2);
349 }
350 else if (strstr(argv[i], "-h") == 0) {
351 tex_height = atoi((argv[i]) + 2);
352 }
353 else if (strstr(argv[i], "-d") == 0) {
354 tex_depth = atoi((argv[i]) + 2);
355 }
356 else if (strcmp(argv[i], "-help") == 0) {
357 printHelp();
358 return GL_FALSE;
359 }
360 else {
361 printf("%s (Bad option).\n", argv[i]);
362 printHelp();
363 return GL_FALSE;
364 }
365 }
366 if (tex_width == 0 || tex_height == 0 || tex_depth == 0) {
367 printf("%s (Bad option).\n", "size parameters can't be 0");
368 printHelp();
369 return GL_FALSE;
370 }
371 return GL_TRUE;
372}
373
374
375static void
376drawScene(void)
377{
378 static const GLfloat sPlane[4] = { 0.5, 0, 0, -.5 };
379 static const GLfloat tPlane[4] = { 0, 0.5, 0, -.5 };
380 static const GLfloat rPlane[4] = { 0, 0, 0.5, -.5 };
381
382 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
383 glPushMatrix();
384 if (texgen == 2) {
385 glTexGenfv(GL_S, GL_EYE_PLANE, sPlane);
386 glTexGenfv(GL_T, GL_EYE_PLANE, tPlane);
387 glTexGenfv(GL_R, GL_EYE_PLANE, rPlane);
388 }
389
390 glRotatef(angx, 1.0, 0.0, 0.0);
391 glRotatef(angy, 0.0, 1.0, 0.0);
392 glRotatef(angz, 0.0, 0.0, 1.0);
393
394 if (texgen == 1) {
395 glTexGenfv(GL_S, GL_EYE_PLANE, sPlane);
396 glTexGenfv(GL_T, GL_EYE_PLANE, tPlane);
397 glTexGenfv(GL_R, GL_EYE_PLANE, rPlane);
398 }
399
400 if (texgen) {
401 glEnable(GL_TEXTURE_GEN_S);
402 glEnable(GL_TEXTURE_GEN_T);
403 glEnable(GL_TEXTURE_GEN_R);
404 }
405 else {
406 glDisable(GL_TEXTURE_GEN_S);
407 glDisable(GL_TEXTURE_GEN_T);
408 glDisable(GL_TEXTURE_GEN_R);
409 }
410
411 glCallList(CurObject);
412 glPopMatrix();
413
414 glutSwapBuffers();
415}
416
417
418static void
419resize(int w, int h)
420{
421 float ar = (float) w / (float) h;
422 float ax = 0.6 * ar;
423 float ay = 0.6;
424 glViewport(0, 0, (GLint) w, (GLint) h);
425 glMatrixMode(GL_PROJECTION);
426 glLoadIdentity();
427 glFrustum(-ax, ax, -ay, ay, 2, 20);
428 /*glOrtho(-2, 2, -2, 2, -10, 10);*/
429 glMatrixMode(GL_MODELVIEW);
430 glLoadIdentity();
431 glTranslatef(0, 0, -4);
432}
433
434
435static void
436Idle(void)
437{
438 float t = glutGet(GLUT_ELAPSED_TIME);
439 angx = 0.01 * t;
440 angy = 0.03 * t;
441 angz += 0;
442 glutPostRedisplay();
443}
444
445
446static void
447SpecialKey(int k, int x, int y)
448{
449 switch (k) {
450 case GLUT_KEY_UP:
451 angx += 5.0;
452 break;
453 case GLUT_KEY_DOWN:
454 angx -= 5.0;
455 break;
456 case GLUT_KEY_LEFT:
457 angy += 5.0;
458 break;
459 case GLUT_KEY_RIGHT:
460 angy -= 5.0;
461 break;
462 default:
463 return;
464 }
465 glutPostRedisplay();
466}
467
468
469static void
470KeyHandler(unsigned char key, int x, int y)
471{
472 static const char *mode[] = {
473 "glTexCoord3f (no texgen)",
Brian Paulc3105702003-03-29 16:40:23 +0000474 "texgen fixed to object coords",
475 "texgen fixed to eye coords"
Brian Paul4fbdedc2002-10-23 14:00:01 +0000476 };
477 (void) x;
478 (void) y;
479 switch (key) {
480 case 27:
481 case 'q':
482 case 'Q': /* quit game. */
483 exit(0);
484 break;
485 case 'z':
486 angz += 10;
487 break;
488 case 'Z':
489 angz -= 10;
490 break;
491 case 's':
492 smooth = !smooth;
493 if (smooth)
494 glShadeModel(GL_SMOOTH);
495 else
496 glShadeModel(GL_FLAT);
497 break;
498 case 't':
499 texgen++;
500 if (texgen > 2)
501 texgen = 0;
502 printf("Texgen: %s\n", mode[texgen]);
503 break;
504 case 'o':
505 if (CurObject == TORUS)
506 CurObject = SPHERE;
507 else
508 CurObject = TORUS;
509 break;
510 case 'i':
511 if (CurTexture == NOISE_TEXTURE)
512 CurTexture = GRADIENT_TEXTURE;
513 else
514 CurTexture = NOISE_TEXTURE;
515 glBindTexture(GL_TEXTURE_3D, CurTexture);
516 break;
517 case 'a':
518 animate = !animate;
519 if (animate)
520 glutIdleFunc(Idle);
521 else
522 glutIdleFunc(NULL);
523 break;
Brian Paul55b0ff22003-03-31 16:51:38 +0000524 case 'w':
525 wireframe = !wireframe;
526 if (wireframe)
527 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
528 else
529 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
530 break;
Brian Paul4fbdedc2002-10-23 14:00:01 +0000531 default:
532 break;
533 }
534 glutPostRedisplay();
535}
536
537
538void
539create3Dgradient(void)
540{
541 unsigned char *v;
542 int i, j, k;
543 unsigned char *voxels = NULL;
544
545 voxels = (unsigned char *) malloc(4 * tex_width * tex_height * tex_depth);
546 v = voxels;
547
548 for (i = 0; i < tex_depth; i++) {
549 for (j = 0; j < tex_height; j++) {
550 for (k = 0; k < tex_width; k++) {
551 GLint r = (255 * i) / (tex_depth - 1);
552 GLint g = (255 * j) / (tex_height - 1);
553 GLint b = (255 * k) / (tex_width - 1);
554 *v++ = r;
555 *v++ = g;
556 *v++ = b;
557 *v++ = 255;
558 }
559 }
560 }
561
562
563 glBindTexture(GL_TEXTURE_3D, GRADIENT_TEXTURE);
564 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
565 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
566 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
567 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
568 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
569 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
570
571 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
572 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA,
573 tex_width, tex_height, tex_depth,
574 0, GL_RGBA, GL_UNSIGNED_BYTE, voxels);
575
576 free(voxels);
577}
578
579
580
581static void
582init(void)
583{
584 static const GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
585 static const GLfloat mat_shininess[] = { 25.0 };
586 static const GLfloat gray[] = { 0.6, 0.6, 0.6, 0.0 };
587 static const GLfloat white[] = { 1.0, 1.0, 1.0, 0.0 };
588 static const GLfloat light_position[] = { 0.0, 1.0, 1.0, 0.0 };
589
590 int max;
591
592 /* see if we have OpenGL 1.2 or later, for 3D texturing */
593 {
594 const char *version = (const char *) glGetString(GL_VERSION);
595 if (strncmp(version, "1.0", 3) == 0 || strncmp(version, "1.1", 3) == 0) {
596 printf("Sorry, OpenGL 1.2 or later is required\n");
597 exit(1);
598 }
599 }
600 printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
601 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max);
602 printf("GL_MAX_3D_TEXTURE_SIZE: %d\n", max);
603 printf("Current 3D texture size: %d x %d x %d\n",
604 tex_width, tex_height, tex_depth);
605
606 /* init light */
607 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
608 glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
609 glLightfv(GL_LIGHT1, GL_POSITION, light_position);
610 glLightfv(GL_LIGHT1, GL_AMBIENT, gray);
611 glLightfv(GL_LIGHT1, GL_DIFFUSE, white);
612 glLightfv(GL_LIGHT1, GL_SPECULAR, white);
613 glColorMaterial(GL_FRONT, GL_DIFFUSE);
614 glEnable(GL_COLOR_MATERIAL);
615 glEnable(GL_LIGHTING);
616 glEnable(GL_LIGHT1);
617
618 glClearColor(.5, .5, .5, 0);
619
Brian Paul55b0ff22003-03-31 16:51:38 +0000620 {
621 GLUquadricObj *q;
622 q = gluNewQuadric();
623 gluQuadricTexture( q, GL_TRUE );
624 glNewList(SPHERE, GL_COMPILE);
625 gluSphere( q, 0.95, 30, 15 );
626 glEndList();
627 gluDeleteQuadric(q);
628 }
Brian Paul4fbdedc2002-10-23 14:00:01 +0000629
630 BuildTorus();
631
632
633 create3Dgradient();
634
635 initNoise();
636 create3Dtexture();
637
638 glEnable(GL_TEXTURE_3D);
639
640 /*
641 glBlendFunc(GL_SRC_COLOR, GL_SRC_ALPHA);
642 glEnable(GL_BLEND);
643 */
644 glEnable(GL_DEPTH_TEST);
645
646 glColor3f(0.6, 0.7, 0.8);
647}
648
649
650int
651main(int argc, char **argv)
652{
653 glutInit(&argc, argv);
654
655 if (parseCmdLine(argc, argv) == GL_FALSE) {
656 exit(0);
657 }
658
659 glutInitWindowPosition(0, 0);
660 glutInitWindowSize(400, 400);
661 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
662
663 if (glutCreateWindow("stex3d") <= 0) {
664 exit(0);
665 }
666
667 init();
668
669 printHelp();
670
671 glutReshapeFunc(resize);
672 glutKeyboardFunc(KeyHandler);
673 glutSpecialFunc(SpecialKey);
674 glutDisplayFunc(drawScene);
675 if (animate)
676 glutIdleFunc(Idle);
677 glutMainLoop();
678 return 0;
jtgafb833d1999-08-19 00:55:39 +0000679}
680