noise.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:7k
源码类别:

GIS编程

开发平台:

Visual C++

  1. /* noise.c - by Simon Hui, 3Dfx Interactive */
  2. /* create an octave by filtering randomly generated noise */
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <math.h>
  6. #include <GL/glut.h>
  7. #if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2)
  8. #define glBindTexture glBindTextureEXT
  9. #endif
  10. static GLint texxsize = 256, texysize = 256;
  11. static GLint winxsize = 512, winysize = 512;
  12. static GLint freq = 4;
  13. /* texture object names */
  14. static GLuint basistex = 1;
  15. static GLuint noisetex = 2;
  16. void
  17. init_texture(void) {
  18.   int i, j, n;
  19.   int w, h;
  20.   GLubyte *basis, *tex;
  21.   
  22.   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  23.   basis = (GLubyte *) malloc(texxsize * texysize);
  24.   w = texxsize / 2;
  25.   h = texysize / 2;
  26.   for (j=0; j < h; j++) {
  27.     for (i=0; i < w; i++) {
  28.       GLint r;
  29.       float u = i / (w - 1.0);
  30.       float v = j / (h - 1.0);
  31.       float f = 3 * u * u - 2 * u * u * u;
  32.       float g = 3 * v * v - 2 * v * v * v;
  33.       
  34.       /* basis is a bicubic spline */
  35.       r = f * g * 0xff;
  36.       /* reflect around x and y axes */
  37.       basis[j * texxsize + i] = r;
  38.       basis[j * texxsize + texxsize-i-1] = r;
  39.       basis[(texysize-j-1) * texxsize + i] = r;
  40.       basis[(texysize-j-1) * texxsize + texxsize-i-1] = r;
  41.     }
  42.   }
  43.   glBindTexture(GL_TEXTURE_2D, basistex);
  44.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  45.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  46.   glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, texxsize, texysize, 0,
  47.        GL_RED, GL_UNSIGNED_BYTE, basis);
  48.   free(basis);
  49.   tex = (GLubyte *) malloc(4 * texxsize * texysize);
  50.   for (n=0; n < 4; n++) {
  51.     for (j=0; j < texysize; j++) {
  52.       for (i=0; i < texxsize; i++) {
  53. int r = rand();
  54. /* mix it up a little more */
  55. r = ((r & 0xff) + ((r & 0xff00) >> 8)) & 0xff;
  56. tex[j*texxsize + i] = r;
  57.       }
  58.     }
  59.     glBindTexture(GL_TEXTURE_2D, noisetex + n);
  60.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  61.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  62.     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, texxsize, texysize, 0,
  63.  GL_RED, GL_UNSIGNED_BYTE, tex);
  64.   }
  65.   free(tex);
  66. }
  67. void
  68. init(void) {
  69.   glClearColor(0.0, 0.0, 0.0, 1.0);
  70.   glMatrixMode(GL_PROJECTION);
  71.   glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
  72.   glMatrixMode(GL_MODELVIEW);
  73.   glViewport(0, 0, winxsize, winysize);
  74.   glBlendFunc(GL_DST_COLOR, GL_ZERO);
  75.   glEnable(GL_TEXTURE_2D);
  76.   init_texture();
  77. }
  78. void
  79. draw_basis(int tsize, int ssize, int xadj, int yadj) {
  80.   float tilessize = 1.0 / ssize;
  81.   float tiletsize = 1.0 / tsize;
  82.   float xoff = (xadj - 0.5) * 0.5 * tilessize;
  83.   float yoff = (yadj - 0.5) * 0.5 * tiletsize;
  84.   float xo, yo;
  85.   int i, j;
  86.   glBindTexture(GL_TEXTURE_2D, basistex);
  87.   glMatrixMode(GL_TEXTURE);
  88.   glLoadIdentity();
  89.   /* draw as many copies of the basis function as needed for this frequency */
  90.   for (j=0; j < tsize; j++) {
  91.     for (i=0; i < ssize; i++) {
  92.       xo = xoff + i * tilessize;
  93.       yo = yoff + j * tiletsize;
  94.       glBegin(GL_TRIANGLE_STRIP);
  95.       glTexCoord2f(0.f, 0.f); glVertex2f(xo, yo); 
  96.       glTexCoord2f(0.f, 1.f); glVertex2f(xo, yo + tiletsize); 
  97.       glTexCoord2f(1.f, 0.f); glVertex2f(xo + tilessize, yo); 
  98.       glTexCoord2f(1.f, 1.f); glVertex2f(xo + tilessize, yo + tiletsize); 
  99.       glEnd();
  100.     }
  101.   }
  102.   glFinish();
  103. }
  104. void
  105. draw_noise_texture(int tsize, int ssize, int xadj, int yadj, int texname) {
  106.   float tilessize = 1.0 / ssize;
  107.   float tiletsize = 1.0 / tsize;
  108.   float xoff = (xadj - 0.5) * 0.5 * tilessize;
  109.   float yoff = (yadj - 0.5) * 0.5 * tiletsize;
  110.   float scale = 1.0 / (texxsize / ssize);
  111.   glBindTexture(GL_TEXTURE_2D, texname);
  112.   /* scale the texture matrix to get a noise pattern of desired frequency */
  113.   glMatrixMode(GL_TEXTURE);
  114.   glLoadIdentity();
  115.   glScalef(scale,scale,scale);
  116.   glBegin(GL_TRIANGLE_STRIP);
  117.   glTexCoord2f(0.f, 0.f); glVertex2f(xoff, yoff); 
  118.   glTexCoord2f(0.f, 1.f); glVertex2f(xoff, yoff+1.0); 
  119.   glTexCoord2f(1.f, 0.f); glVertex2f(xoff + 1.0, yoff); 
  120.   glTexCoord2f(1.f, 1.f); glVertex2f(xoff + 1.0, yoff + 1.0); 
  121.   glEnd();
  122.   glFlush();
  123. }
  124. /* menu choices */
  125. enum {
  126.   BASIS, NOISE, BASIS_TIMES_NOISE, OCTAVE, HIGHER_FREQ, LOWER_FREQ, QUIT=27
  127. };
  128. GLint showmode = BASIS_TIMES_NOISE;
  129. void
  130. display(void) {
  131.   switch (showmode) {
  132.   case BASIS:
  133.     glClear(GL_COLOR_BUFFER_BIT);
  134.     draw_basis(freq, freq, 0, 0);
  135.     break;
  136.   case NOISE:
  137.     glClear(GL_COLOR_BUFFER_BIT);
  138.     draw_noise_texture(freq, freq, 0, 0, noisetex);
  139.     break;
  140.   case BASIS_TIMES_NOISE:
  141.     glClear(GL_COLOR_BUFFER_BIT);
  142.     glDisable(GL_BLEND);
  143.     draw_basis(freq, freq, 0, 0);
  144.     glEnable(GL_BLEND);
  145.     draw_noise_texture(freq, freq, 0, 0, noisetex);
  146.     glDisable(GL_BLEND);
  147.     break;
  148.   case OCTAVE:
  149.     /* put four sets together to get the final octave */
  150.     glClear(GL_COLOR_BUFFER_BIT);
  151.     glDisable(GL_BLEND);
  152.     draw_basis(freq, freq, 0, 0);
  153.     glEnable(GL_BLEND);
  154.     draw_noise_texture(freq, freq, 0, 0, noisetex);
  155.     glAccum(GL_LOAD, 1.0);
  156.     glClear(GL_COLOR_BUFFER_BIT);
  157.     glDisable(GL_BLEND);
  158.     draw_basis(freq, freq, 1, 0);
  159.     glEnable(GL_BLEND);
  160.     draw_noise_texture(freq, freq, 1, 0, noisetex + 1);
  161.     glAccum(GL_ACCUM, 1.0);
  162.     glClear(GL_COLOR_BUFFER_BIT);
  163.     glDisable(GL_BLEND);
  164.     draw_basis(freq, freq, 0, 1);
  165.     glEnable(GL_BLEND);
  166.     draw_noise_texture(freq, freq, 0, 1, noisetex + 2);
  167.     glAccum(GL_ACCUM, 1.0);
  168.     glClear(GL_COLOR_BUFFER_BIT);
  169.     glDisable(GL_BLEND);
  170.     draw_basis(freq, freq, 1, 1);
  171.     glEnable(GL_BLEND);
  172.     draw_noise_texture(freq, freq, 1, 1, noisetex + 3);
  173.     glAccum(GL_ACCUM, 1.0);
  174.     glDisable(GL_BLEND);
  175.     glClear(GL_COLOR_BUFFER_BIT);
  176.     glAccum(GL_RETURN, 1.0);
  177.     break;
  178.   }
  179.   glFlush();
  180. }
  181. void
  182. reshape(int w, int h) {
  183.   glViewport(0, 0, w, h);
  184.   glutPostRedisplay();
  185. }
  186. void
  187. menu(int value) {
  188.   switch (value) {
  189.   case BASIS:
  190.   case NOISE:
  191.   case BASIS_TIMES_NOISE:
  192.   case OCTAVE:
  193.     showmode = value;
  194.     break;
  195.   case HIGHER_FREQ:
  196.     if (freq < texxsize) freq *= 2;
  197.     break;
  198.   case LOWER_FREQ:
  199.     freq /= 2;
  200.     if (freq < 2) freq = 2;
  201.     break;
  202.   case QUIT:
  203.     exit(0);
  204.   }
  205.   glutPostRedisplay();
  206. }
  207. int
  208. main(int argc, char** argv) {
  209.   glutInitWindowSize(winxsize, winysize);
  210.   glutInit(&argc, argv);
  211.   glutInitDisplayMode(GLUT_RGBA | GLUT_ACCUM);
  212.   (void)glutCreateWindow("filtered noise function");
  213.   init();
  214.   glutDisplayFunc(display);
  215.   glutReshapeFunc(reshape);
  216.   glutCreateMenu(menu);
  217.   glutAddMenuEntry("Show One Basis", BASIS);
  218.   glutAddMenuEntry("Show One Noise", NOISE);
  219.   glutAddMenuEntry("Show One Basis x Noise", BASIS_TIMES_NOISE);
  220.   glutAddMenuEntry("Show Octave", OCTAVE);
  221.   glutAddMenuEntry("Higher Frequency", HIGHER_FREQ);
  222.   glutAddMenuEntry("Lower Frequency", LOWER_FREQ);
  223.   glutAddMenuEntry("Quit", QUIT);
  224.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  225.   glutMainLoop();
  226.   return 0;             /* ANSI C requires main to return int. */
  227. }