home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / mesa / demos / stex3d.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-09  |  14.2 KB  |  560 lines

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