home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / System / Mesa-3.1 / demos / stex3d.c < prev    next >
C/C++ Source or Header  |  2000-01-07  |  17KB  |  587 lines

  1. /* $Id: stex3d.c,v 1.2.2.1 1999/12/16 08:53:51 brianp Exp $ */
  2.  
  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
  12.  *
  13.  *      
  14.  * cc stex3d.c -o stex3d -lglut -lMesaGLU -lMesaGL -lX11 -lXext -lm 
  15.  *
  16.  *---------------------------- */
  17.  
  18. /*
  19.  * $Log: stex3d.c,v $
  20.  * Revision 1.2.2.1  1999/12/16 08:53:51  brianp
  21.  * added a cast to malloc call
  22.  *
  23.  * Revision 1.2  1999/09/17 12:27:01  brianp
  24.  * silenced some warnings
  25.  *
  26.  * Revision 1.1.1.1  1999/08/19 00:55:40  jtg
  27.  * Imported sources
  28.  *
  29.  * Revision 3.1  1998/06/09 01:53:49  brianp
  30.  * main() should return an int
  31.  *
  32.  * Revision 3.0  1998/02/14 18:42:29  brianp
  33.  * initial rev
  34.  *
  35.  */
  36.  
  37.  
  38. #include <string.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <math.h>
  42. #include <GL/gl.h>
  43. #include <GL/glut.h>
  44. /* function declarations */
  45. #ifndef M_PI
  46. #define M_PI            3.14159265358979323846
  47. #endif
  48.  
  49. void init(void),
  50.      printHelp(void),
  51.      create3Dtexture(void),
  52.      setDefaults(void),
  53.      drawScene(void),
  54.      resize(int w, int h),
  55.      buildFigure(void),
  56.      initNoise(void);
  57. float turbulence(float point[3], float lofreq, float hifreq);
  58.  
  59. int isExtSupported(char *ext);
  60. void KeyHandler( unsigned char key, int x, int y );
  61. GLenum parseCmdLine(int argc, char **argv);
  62. float noise3(float vec[3]);
  63.       
  64. /* global variables */
  65. GLenum rgb, doubleBuffer, directRender, windType; /* visualization state*/
  66. float tex_width,tex_height,tex_depth;        /* texture volume dimensions  */
  67. unsigned char *voxels;                       /* texture data ptr */
  68. int angx,angy,angz;
  69. GLuint figure;
  70.  
  71. /*function definitions */
  72. int main(int argc, char **argv)
  73. {
  74.  
  75.  if (parseCmdLine(argc, argv) == GL_FALSE) {
  76.     exit(0);
  77.  }
  78.  
  79.  glutInitWindowPosition(0, 0);
  80.  glutInitWindowSize(400, 400);
  81.  windType = (rgb) ? GLUT_RGB : GLUT_INDEX;
  82.  windType |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
  83.  windType |= GLUT_DEPTH;
  84.  glutInitDisplayMode(windType);
  85.  
  86.  if (glutCreateWindow("stex3d") <= 0) {
  87.     exit(0);
  88.  }
  89.  /* init all */
  90.  init();
  91.  
  92.  glutReshapeFunc(resize);
  93.  glutKeyboardFunc(KeyHandler);
  94.  glutDisplayFunc(drawScene);
  95.  glutMainLoop();
  96.  return 0;
  97. }
  98.  
  99. void init()
  100.  /* init light */
  101.  GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
  102.  GLfloat mat_shininess[] = { 25.0 };
  103.  GLfloat gray[] = { 0.6, 0.6, 0.6, 0.0 };
  104.  GLfloat white[] = { 1.0, 1.0, 1.0, 0.0 };
  105.  GLfloat light_position[] = { 0.0, 1.0, 1.0, 0.0 };
  106.  
  107.  glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
  108.  glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
  109.  glLightfv(GL_LIGHT1, GL_POSITION, light_position);
  110.  glLightfv(GL_LIGHT1, GL_AMBIENT, gray);
  111.  glLightfv(GL_LIGHT1, GL_DIFFUSE, white);
  112.  glLightfv(GL_LIGHT1, GL_SPECULAR, white);
  113.  glColorMaterial(GL_FRONT, GL_DIFFUSE);
  114.  glEnable(GL_COLOR_MATERIAL);
  115.  glEnable(GL_LIGHTING);
  116.  glEnable(GL_LIGHT1);
  117.  
  118.  /* create torus for texturing */
  119.  figure=glGenLists(1); 
  120.  buildFigure();
  121. /* tkSolidTorus(figure,0.3,1.2);*/
  122.  
  123.  /* start the noise function variables */
  124.  initNoise();
  125.  
  126.  /* see if the texture 3d extention is supported */
  127.  if (!isExtSupported("GL_EXT_texture3D")) {
  128.    printf("Sorry this GL implementation (%s) does not support 3d texture extentions\n",
  129.         (char *)(glGetString(GL_RENDERER)));
  130. /*   tkQuit();*/
  131.  }
  132.  
  133.  /* if texture is supported then generate the texture */
  134.  create3Dtexture(); 
  135.  
  136.  glEnable(GL_TEXTURE_3D_EXT); 
  137.  /*
  138.  glBlendFunc(GL_SRC_COLOR, GL_SRC_ALPHA);
  139.  glEnable(GL_BLEND); 
  140.  */
  141.  glEnable(GL_DEPTH_TEST);
  142.  
  143.  glShadeModel(GL_FLAT);
  144.  glColor3f(0.6,0.7,0.8);
  145. }
  146.  
  147. void buildFigure(void)
  148. {   GLint i, j;
  149.     float theta1, phi1, theta2, phi2, rings, sides;
  150.     float v0[03], v1[3], v2[3], v3[3];
  151.     float t0[03], t1[3], t2[3], t3[3];
  152.     float n0[3], n1[3], n2[3], n3[3];
  153.     float innerRadius=0.4;
  154.     float outerRadius=0.8;
  155.     float scalFac;
  156.  
  157.     rings = 8;
  158.     sides = 10;
  159.     scalFac=1/(outerRadius*2);
  160.  
  161.     glNewList(figure, GL_COMPILE);
  162.     for (i = 0; i < rings; i++) {
  163.         theta1 = (float)i * 2.0 * M_PI / rings;
  164.         theta2 = (float)(i + 1) * 2.0 * M_PI / rings;
  165.         for (j = 0; j < sides; j++) {
  166.             phi1 = (float)j * 2.0 * M_PI / sides;
  167.             phi2 = (float)(j + 1) * 2.0 * M_PI / sides;
  168.  
  169.             v0[0] = cos(theta1) * (outerRadius + innerRadius * cos(phi1));
  170.             v0[1] = -sin(theta1) * (outerRadius + innerRadius * cos(phi1));
  171.             v0[2] = innerRadius * sin(phi1);
  172.  
  173.             v1[0] = cos(theta2) * (outerRadius + innerRadius * cos(phi1));
  174.             v1[1] = -sin(theta2) * (outerRadius + innerRadius * cos(phi1));
  175.             v1[2] = innerRadius * sin(phi1);
  176.             v2[0] = cos(theta2) * (outerRadius + innerRadius * cos(phi2));
  177.             v2[1] = -sin(theta2) * (outerRadius + innerRadius * cos(phi2));
  178.             v2[2] = innerRadius * sin(phi2);
  179.  
  180.             v3[0] = cos(theta1) * (outerRadius + innerRadius * cos(phi2));
  181.             v3[1] = -sin(theta1) * (outerRadius + innerRadius * cos(phi2));
  182.             v3[2] = innerRadius * sin(phi2);
  183.  
  184.             n0[0] = cos(theta1) * (cos(phi1));
  185.             n0[1] = -sin(theta1) * (cos(phi1));
  186.             n0[2] = sin(phi1);
  187.  
  188.             n1[0] = cos(theta2) * (cos(phi1));
  189.             n1[1] = -sin(theta2) * (cos(phi1));
  190.             n1[2] = sin(phi1);
  191.  
  192.             n2[0] = cos(theta2) * (cos(phi2));
  193.             n2[1] = -sin(theta2) * (cos(phi2));
  194.             n2[2] = sin(phi2);
  195.  
  196.             n3[0] = cos(theta1) * (cos(phi2));
  197.             n3[1] = -sin(theta1) * (cos(phi2));
  198.             n3[2] = sin(phi2);
  199.  
  200.             t0[0] = v0[0]*scalFac + 0.5;
  201.             t0[1] = v0[1]*scalFac + 0.5;
  202.             t0[2] = v0[2]*scalFac + 0.5;
  203.  
  204.             t1[0] = v1[0]*scalFac + 0.5;
  205.             t1[1] = v1[1]*scalFac + 0.5;
  206.             t1[2] = v1[2]*scalFac + 0.5;
  207.  
  208.             t2[0] = v2[0]*scalFac + 0.5;
  209.             t2[1] = v2[1]*scalFac + 0.5;
  210.             t2[2] = v2[2]*scalFac + 0.5;
  211.  
  212.             t3[0] = v3[0]*scalFac + 0.5;
  213.             t3[1] = v3[1]*scalFac + 0.5;
  214.             t3[2] = v3[2]*scalFac + 0.5;
  215.  
  216.             glBegin(GL_POLYGON);
  217.                 glNormal3fv(n3); glTexCoord3fv(t3); glVertex3fv(v3);
  218.                 glNormal3fv(n2); glTexCoord3fv(t2); glVertex3fv(v2);
  219.                 glNormal3fv(n1); glTexCoord3fv(t1); glVertex3fv(v1);
  220.                 glNormal3fv(n0); glTexCoord3fv(t0); glVertex3fv(v0);
  221.             glEnd();
  222.         }
  223.     }
  224.     glEndList();
  225. }
  226.  
  227. void create3Dtexture()
  228. {
  229.  int i,j,k;
  230.  unsigned char *vp;
  231.  float vec[3];
  232.  int tmp;
  233.  
  234.  printf("creating 3d textures...\n");
  235.  voxels = (unsigned char  *) malloc((size_t) (4*tex_width*tex_height*tex_depth));
  236.  vp=voxels;
  237.  for (i=0;i<tex_width;i++){
  238.     vec[0]=i;
  239.     for (j=0;j<tex_height;j++) {
  240.       vec[1]=j;
  241.        for (k=0;k<tex_depth;k++) {
  242.            vec[2]=k;
  243.            tmp=(sin(k*i*j+turbulence(vec,0.01,1))+1)*127.5; 
  244.            *vp++=0;
  245.            *vp++=0;
  246.            *vp++=tmp; 
  247.            *vp++=tmp+128; 
  248.        }
  249.      }
  250.  }
  251.  
  252.  printf("setting up 3d texture...\n");
  253.  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  254.  glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  255.  glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  256.  glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_S,     GL_REPEAT);
  257.  glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_T,     GL_REPEAT);
  258.  glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_R_EXT, GL_REPEAT);
  259.  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  260.  
  261.  glTexImage3DEXT(GL_TEXTURE_3D_EXT, 0, GL_RGBA,
  262.                     tex_width, tex_height, tex_depth,
  263.                     0, GL_RGBA, GL_UNSIGNED_BYTE, voxels);
  264.  
  265.  printf("finished setting up 3d texture image...\n");
  266. }
  267.  
  268. int isExtSupported(char *ext)
  269. {
  270.     /* routine to find whether a specified OpenGL extension is supported */
  271.  
  272.     char *c;
  273.     int len;
  274.     char *allext = (char *)(glGetString(GL_EXTENSIONS));
  275.  
  276.     len = strlen(ext);
  277.     if (len <= 0) return 0;
  278.  
  279.     c = allext;
  280.     while (c) {
  281.         if (!strncmp(c,ext,len)) return 1;
  282.         c = strchr(c+1,'G');
  283.     }
  284.     return 0;
  285. }
  286.  
  287. void printHelp()
  288. {
  289.   printf("\nUsage: stex3d  <cmd line options>\n"); 
  290.   printf(" cmd line options:\n");
  291.   printf("      -help   print this help!\n");
  292.   printf("      -rgb     RGBA mode. (Default)\n");
  293.   printf("      -ci     Color index mode.\n");
  294.   printf("      -sb     Single buffer mode. (Default)\n");
  295.   printf("      -db     Double buffer mode. \n");
  296.   printf("      -dr     Direct render mode.\n");
  297.   printf("      -ir     Indirect render mode. (Default)\n");
  298.   printf("      -wxxx   Width of the texture (Default=64)\n");
  299.   printf("      -hxxx   Height of the texture (Default=64)\n");
  300.   printf("      -dxxx   Depth of the texture (Default=64)\n");
  301.   printf(" Keyboard Options:\n");
  302.   printf("       1      Object Texture coordinates (Default)\n");
  303.   printf("       2      Eye Texture coordinates \n");
  304.   printf("       x      rotate around x clockwise\n");
  305.   printf("       X      rotate around x counter clockwise\n");
  306.   printf("       y      rotate around y clockwise\n");
  307.   printf("       Y      rotate around y counter clockwise\n");
  308.   printf("       z      rotate around z clockwise\n");
  309.   printf("       Z      rotate around z counter clockwise\n");
  310.   printf("       t      enable 3-D texuring (Default)\n");
  311.   printf("       T      disable 3-D texuring\n");
  312.   printf("       s      smooth shading \n");
  313.   printf("       S      flat shading (Default)\n");
  314. }
  315.  
  316. void setDefaults()
  317. {
  318.  /* visualization defaults */
  319.   rgb = GL_TRUE;
  320.   doubleBuffer = GL_FALSE;
  321.   directRender = GL_TRUE;
  322.   angx=130;
  323.   angy=30;
  324.   angz=0; 
  325.  /* texture values */
  326.  tex_width=64;
  327.  tex_height=64;
  328.  tex_depth=64;
  329. }
  330.  
  331. GLenum parseCmdLine(int argc, char **argv)
  332. {
  333.   GLint i;
  334.  
  335.   setDefaults();
  336.  
  337.   for (i = 1; i < argc; i++) {
  338.       if (strcmp(argv[i], "-ci") == 0) {
  339.           rgb = GL_FALSE;
  340.       } else if (strcmp(argv[i], "-rgb") == 0) {
  341.           rgb = GL_TRUE;
  342.       } else if (strcmp(argv[i], "-sb") == 0) {
  343.           doubleBuffer = GL_FALSE;
  344.       } else if (strcmp(argv[i], "-db") == 0) {
  345.           doubleBuffer = GL_TRUE;
  346.       } else if (strcmp(argv[i], "-dr") == 0) {
  347.           directRender = GL_TRUE;
  348.       } else if (strcmp(argv[i], "-ir") == 0) {
  349.           directRender = GL_FALSE;
  350.       } else if (strstr(argv[i], "-w") == 0) {
  351.           tex_width=atoi((argv[i])+2);
  352.       } else if (strstr(argv[i], "-h") == 0) {
  353.           tex_height=atoi((argv[i])+2);
  354.       } else if (strstr(argv[i], "-d") == 0) {
  355.           tex_depth=atoi((argv[i])+2);
  356.       } else if (strcmp(argv[i], "-help") == 0) {
  357.           printHelp();
  358.           return GL_FALSE;
  359.       } else {
  360.           printf("%s (Bad option).\n", argv[i]);
  361.           printHelp();
  362.           return GL_FALSE;
  363.       }
  364.   }
  365.  if(tex_width==0 || tex_height==0 || tex_depth==0) {
  366.    printf("%s (Bad option).\n", "size parameters can't be 0");
  367.    printHelp();
  368.    return GL_FALSE;
  369.  }
  370.   return GL_TRUE;
  371. }
  372.  
  373. void drawScene()
  374. {
  375.  /* clear background, z buffer etc */
  376.  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  377.  glPushMatrix();
  378.  glRotatef(angx,1.0,0.0,0.0);
  379.  glRotatef(angy,0.0,1.0,0.0);
  380.  glRotatef(angz,0.0,0.0,1.0);
  381.  
  382.  glCallList(figure);     
  383.  glPopMatrix();
  384.  glFlush();
  385.  if(doubleBuffer)
  386.     glutSwapBuffers();
  387.  ;
  388. }
  389.  
  390. void resize(int w, int h)
  391.  glViewport(0, 0, (GLint)w, (GLint)h);
  392.  glMatrixMode(GL_PROJECTION);
  393.  glLoadIdentity();
  394.  glOrtho(-2,2,-2,2,-5,10);
  395.  glMatrixMode(GL_MODELVIEW);
  396.  glLoadIdentity();
  397.  glTranslatef(0,0,-5);
  398. }
  399.  
  400. void cleanEverything(void)
  401. {
  402. /*  free(voxels); */
  403. }
  404.  
  405.  
  406. void KeyHandler( unsigned char key, int x, int y )
  407. {
  408.    (void) x;
  409.    (void) y;
  410.    switch(key) {
  411.       case 27:
  412.       case 'q':
  413.       case 'Q': /* quit game. */
  414.          cleanEverything();
  415.          exit(0);
  416.          break;
  417.       case 'x':
  418.          angx+=10;
  419.          break;
  420.       case 'X': 
  421.          angx-=10; 
  422.          break;
  423.       case 'y':
  424.          angy+=10;
  425.          break;
  426.       case 'Y': 
  427.          angy-=10; 
  428.          break;
  429.       case 'z':
  430.          angz+=10;
  431.          break;
  432.       case 'Z': 
  433.          angz-=10; 
  434.          break;
  435.       case 't':
  436.          glEnable(GL_TEXTURE_3D_EXT); 
  437.          break;
  438.       case 'T':
  439.          glDisable(GL_TEXTURE_3D_EXT);
  440.          break;
  441.       case 's':
  442.          glShadeModel(GL_SMOOTH);
  443.          break;
  444.       case 'S':
  445.          glShadeModel(GL_FLAT);
  446.          break;
  447.       case '1':
  448.          glDisable(GL_TEXTURE_GEN_S);
  449.          glDisable(GL_TEXTURE_GEN_T);
  450.          glDisable(GL_TEXTURE_GEN_R);
  451.          break;
  452.       case '2':
  453.          glEnable(GL_TEXTURE_GEN_S);
  454.          glEnable(GL_TEXTURE_GEN_T);
  455.          glEnable(GL_TEXTURE_GEN_R);
  456.          break;
  457.       default:
  458.          break;
  459.    }
  460.    glutPostRedisplay();
  461. }
  462.  
  463. /*--------------------------------------------------------------------
  464.  noise function over R3 - implemented by a pseudorandom tricubic spline 
  465.               EXCERPTED FROM SIGGRAPH 92, COURSE 23
  466.                         PROCEDURAL MODELING
  467.                              Ken Perlin
  468.                            New York University
  469. ----------------------------------------------------------------------*/
  470.  
  471.  
  472. #define DOT(a,b) (a[0] * b[0] + a[1] * b[1] + a[2] * b[2])
  473. #define B 256
  474. static int p[B + B + 2];
  475. static float g[B + B + 2][3];
  476. #define setup(i,b0,b1,r0,r1) \
  477.         t = vec[i] + 10000.; \
  478.         b0 = ((int)t) & (B-1); \
  479.         b1 = (b0+1) & (B-1); \
  480.         r0 = t - (int)t; \
  481.         r1 = r0 - 1.;
  482.  
  483. float noise3(float vec[3])
  484. {
  485.         int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
  486.         float rx0, rx1, ry0, ry1, rz0, rz1, *q, sx, sy, sz, a, b, c, d, t, u, v;
  487.         register int i, j;
  488.  
  489.         setup(0, bx0,bx1, rx0,rx1);
  490.         setup(1, by0,by1, ry0,ry1);
  491.         setup(2, bz0,bz1, rz0,rz1);
  492.  
  493.         i = p[ bx0 ];
  494.         j = p[ bx1 ];
  495.  
  496.         b00 = p[ i + by0 ];
  497.         b10 = p[ j + by0 ];
  498.         b01 = p[ i + by1 ];
  499.         b11 = p[ j + by1 ];
  500.  
  501. #define at(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
  502. #define surve(t) ( t * t * (3. - 2. * t) )
  503. #define lerp(t, a, b) ( a + t * (b - a) )
  504.  
  505.         sx = surve(rx0);
  506.         sy = surve(ry0);
  507.         sz = surve(rz0);
  508.  
  509.         q = g[ b00 + bz0 ] ; u = at(rx0,ry0,rz0);
  510.         q = g[ b10 + bz0 ] ; v = at(rx1,ry0,rz0);
  511.         a = lerp(sx, u, v);
  512.  
  513.         q = g[ b01 + bz0 ] ; u = at(rx0,ry1,rz0);
  514.         q = g[ b11 + bz0 ] ; v = at(rx1,ry1,rz0);
  515.         b = lerp(sx, u, v);
  516.  
  517.         c = lerp(sy, a, b);          /* interpolate in y at lo x */
  518.  
  519.         q = g[ b00 + bz1 ] ; u = at(rx0,ry0,rz1);
  520.         q = g[ b10 + bz1 ] ; v = at(rx1,ry0,rz1);
  521.         a = lerp(sx, u, v);
  522.  
  523.         q = g[ b01 + bz1 ] ; u = at(rx0,ry1,rz1);
  524.         q = g[ b11 + bz1 ] ; v = at(rx1,ry1,rz1);
  525.         b = lerp(sx, u, v);
  526.  
  527.         d = lerp(sy, a, b);          /* interpolate in y at hi x */
  528.  
  529.         return 1.5 * lerp(sz, c, d); /* interpolate in z */
  530. }
  531.  
  532. void initNoise()
  533. {
  534.         /*long random();*/
  535.         int i, j, k;
  536.         float v[3], s;
  537.  
  538. /* Create an array of random gradient vectors uniformly on the unit sphere */
  539.         /*srandom(1);*/
  540.         srand(1);
  541.         for (i = 0 ; i < B ; i++) {
  542.                 do {                            /* Choose uniformly in a cube */                        for (j=0 ; j<3 ; j++)
  543.                                 v[j] = (float)((rand() % (B + B)) - B) / B;
  544.                         s = DOT(v,v);
  545.                 } while (s > 1.0);              /* If not in sphere try again */                s = sqrt(s);
  546.                 for (j = 0 ; j < 3 ; j++)       /* Else normalize */
  547.                         g[i][j] = v[j] / s;
  548.         }
  549.  
  550. /* Create a pseudorandom permutation of [1..B] */
  551.         for (i = 0 ; i < B ; i++)
  552.                 p[i] = i;
  553.         for (i = B ; i > 0 ; i -= 2) {
  554.                 k = p[i];
  555.                 p[i] = p[j = rand() % B];
  556.                 p[j] = k;
  557.         }
  558.  
  559. /* Extend g and p arrays to allow for faster indexing */
  560.         for (i = 0 ; i < B + 2 ; i++) {
  561.                 p[B + i] = p[i];
  562.                 for (j = 0 ; j < 3 ; j++)
  563.                         g[B + i][j] = g[i][j];
  564.         }
  565. }
  566.  
  567. float turbulence(float point[3], float lofreq, float hifreq)
  568. {
  569.         float freq, t, p[3];
  570.  
  571.         p[0] = point[0] + 123.456;
  572.         p[1] = point[1];
  573.         p[2] = point[2];
  574.  
  575.         t = 0;
  576.         for (freq = lofreq ; freq < hifreq ; freq *= 2.) {
  577.                 t += fabs(noise3(p)) / freq;
  578.                 p[0] *= 2.;
  579.                 p[1] *= 2.;
  580.                 p[2] *= 2.;
  581.         }
  582.         return t - 0.3; /* readjust to make mean value = 0.0 */
  583. }
  584.  
  585.