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

GIS编程

开发平台:

Visual C++

  1. /* 
  2.  * Texture feedback demo
  3.  * Simon Green 6/97
  4.  * si@sgi.com
  5.  *
  6.  * Compile:  
  7.  * cc -o feedback feedback.c -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm
  8.  *
  9.  * Description:
  10.  * This is an old effect - it's kind of like pointing a video camera at a TV
  11.  * displaying the signal from itself.
  12.  * 
  13.  * It also demonstrates the OpenGL 1.1 glCopyTexImage2D function to copy
  14.  * texture data direct from the framebuffer. You'll need a machine with
  15.  * reasonably fast texture mapping for it to be fun.
  16.  *
  17.  * Usage:
  18.  * Start it up, hold down the left mouse button and move the mouse up and down
  19.  * and left and right slowly. Play with the menus. Enjoy!
  20.  *
  21.  * Left mouse button - zoom / rotate
  22.  * Right mouse button - translate (advanced users only)
  23.  *
  24.  * Bugs:
  25.  * Don't try resizing the window. Don't stare at it for too long.
  26.  */
  27. #include <math.h> 
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <GL/glut.h>
  32. #ifdef GL_VERSION_1_1
  33. /* Some <math.h> files do not define M_PI... */
  34. #ifndef M_PI
  35. #define M_PI 3.14159265358979323846
  36. #endif
  37. #define MAXSIZE 512             /* Set this to your maximum texture size (square)
  38. */
  39. #define TEXT_MESSAGE    "OpenGL"
  40. float ang = 2.0;
  41. float scale = 1.05;
  42. float tx = 0.0, ty = 0.0;
  43. int oldx, oldy;
  44. int lmb = 0;
  45. int mmb = 0;
  46. int autospin = 0;
  47. float atime = 0.0;
  48. int smooth = 1;
  49. int seedmode = 0;
  50. float seedsize = 0.1;
  51. int primtype = GL_LINES;
  52. float primsize = 1.0;
  53. int nprims = 10;
  54. float r, g, b;
  55. float dr, dg, db;
  56. int randomcolours = 0;
  57. /* returns a random floating point number between 0.0 and 1.0 */
  58. float frand(void) {
  59.     return (float) (rand() / 32767.0);
  60. }
  61. void init_colours(float speed)
  62. {
  63.     r = frand(); g = frand(); b = frand();
  64.     dr = frand() / speed; dg = frand() / speed; db = frand() / speed;    
  65. }
  66. void bounce(float *n, float *dn)
  67. {
  68.     *n += *dn;
  69.     if (*n > 1.0) { *n = 1.0; *dn = -*dn; }
  70.     if (*n < 0.0) { *n = 0.0; *dn = -*dn; }
  71. }
  72. /* generate pretty colours by bouncing rgb values up and down */
  73. void set_colour(void)
  74. {
  75.     if (randomcolours) {
  76.         glColor3f(frand(), frand(), frand());
  77.     } else {
  78.         bounce(&r, &dr);
  79.         bounce(&g, &dg);
  80.         bounce(&b, &db);
  81.         glColor3f(r, g, b);
  82.     }
  83. }
  84. /* seed pattern with some random primitives in centre of screen */
  85. void seed(void)
  86. {
  87.     int i;
  88.         
  89.     glBegin(primtype);
  90.     for(i=0; i<nprims; i++) {
  91.         set_colour();
  92.         glVertex2f((frand() - 0.5) * seedsize, (frand() - 0.5) * seedsize);
  93.     }
  94.     glEnd();
  95. }
  96. /* seed pattern with a circular pattern */
  97. void seed_circle(void)
  98. {   
  99.     int i;
  100.     double a;
  101.         
  102.     glBegin(primtype);
  103.         for(i=0; i<nprims; i++) {
  104.         a = ((double) i * 2 * M_PI) / nprims;
  105.         glColor4f(0.0, 0.0, 0.0, 1.0);
  106.         glVertex2d(0.0, 0.0);
  107.         set_colour();
  108.         glVertex2d(sin(a) * (seedsize / 2.0), cos(a) * (seedsize / 2.0));
  109.     }
  110.     glEnd();    
  111. }
  112. /* bit of a silly one, this */
  113. void seed_teapot(void)
  114. {
  115.     glLoadIdentity();
  116.     glTranslatef((frand() - 0.5) * seedsize, (frand() - 0.5) * seedsize, 0.0);
  117.     glRotatef(frand() * 360.0, frand(), frand(), frand());
  118.     set_colour();
  119.     glutWireTeapot(seedsize);
  120. }
  121. /* seed with text string */
  122. void seed_text(char *string)
  123. {
  124.     int i;
  125.     int width = 0;
  126.     for (i = 0; i < (int) strlen(string); i++) {
  127.         width += glutStrokeWidth(GLUT_STROKE_ROMAN, string[i]);
  128.     }
  129.     glLoadIdentity();
  130.     glScalef(seedsize / 100.0, seedsize / 100.0, seedsize / 100.0);
  131.     glTranslatef(-width / 2.0, -50.0, 0.0);
  132.     for (i = 0; i < (int) strlen(string); i++) {
  133.         set_colour();
  134.         glutStrokeCharacter(GLUT_STROKE_ROMAN, string[i]);
  135.     }
  136. }
  137. /* copy screen image to texture memory */
  138. void grab_screen(void)
  139. {
  140.     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, MAXSIZE, MAXSIZE,
  141. 0);
  142.     if (smooth) {
  143.         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  144.         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  145.     } else {
  146.         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  147.         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  148.     }
  149.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,  GL_DECAL);
  150.     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
  151. }
  152. void reset(void)
  153. {
  154.     ang = 0.0;
  155.     scale = 1.0;
  156.     tx = ty = 0.0;
  157.     autospin = 0;
  158.     glClear(GL_COLOR_BUFFER_BIT);
  159.     grab_screen();
  160. }
  161. void redraw(void)
  162. {
  163.     glClear(GL_COLOR_BUFFER_BIT);           
  164.     glMatrixMode(GL_MODELVIEW);
  165.     glLoadIdentity();
  166.     glTranslatef(tx, ty, 0.0);
  167.     glRotatef(ang, 0.0, 0.0, 1.0);
  168.     glScalef(scale, scale, scale);
  169.     if (autospin) {
  170.         ang = 3.0 * cos(atime);
  171.         scale = 1.0 + ( sin(atime / 4.0) * 0.1) ;
  172.         atime += 0.01;
  173.     }
  174.     /* draw feedback square */
  175.     glEnable(GL_TEXTURE_2D);
  176.     glBegin(GL_QUADS);
  177.         glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0);
  178.         glTexCoord2f(1.0, 0.0); glVertex2f(1.0, -1.0);
  179.         glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
  180.         glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0);
  181.     glEnd();
  182.     glDisable(GL_TEXTURE_2D);
  183.     
  184.     /* draw square outline */
  185.     glColor3f(1.0, 1.0, 1.0);
  186.     glBegin(GL_LINE_LOOP);
  187.         glVertex2f(-1.0, -1.0);
  188.         glVertex2f(1.0, -1.0);
  189.         glVertex2f(1.0, 1.0);
  190.         glVertex2f(-1.0, 1.0);
  191.     glEnd();
  192.     
  193.     /* seed pattern */
  194.     glLoadIdentity();
  195.     switch(seedmode) {
  196.     case 0:
  197.         seed();
  198.         break;
  199.     case 1:
  200.         seed_circle();
  201.         break;
  202.     case 2:
  203.         seed_teapot();
  204.         break;
  205.     case 3:
  206.         seed_text(TEXT_MESSAGE);
  207.         break;
  208.     }
  209.     /* grab screen as texture */
  210.     grab_screen();
  211.      
  212.     glutSwapBuffers();
  213. }
  214. void mouse(int button, int state, int x, int y)
  215. {
  216.     if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
  217.         lmb = 1;
  218.         oldx = x; oldy = y;
  219.     }
  220.     if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
  221.         lmb = 0;
  222.     }
  223.   
  224.     if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) {
  225.         mmb = 1;
  226.         oldx = x; oldy = y;
  227.     }
  228.     if (button == GLUT_MIDDLE_BUTTON && state == GLUT_UP) {
  229.         mmb = 0;
  230.     }
  231. }
  232. void motion(int x, int y)
  233. {
  234.     if (lmb) {
  235.         ang += ((oldx - x) / 4.0 );
  236.         scale += ((oldy - y) / 400.0);
  237.         oldx = x; oldy = y;
  238.         glutPostRedisplay();
  239.     }
  240.     if (mmb) {
  241.         tx += ((float) (x - oldx)) / 500.0;
  242.         ty += ((float) (oldy - y)) / 500.0;
  243.         oldx = x; oldy = y;
  244.         glutPostRedisplay();      
  245.     }
  246. }
  247. void main_menu(int i)
  248. {
  249.     switch(i) {
  250.     case 1:
  251.         autospin = !autospin;
  252.         atime = 0.0;
  253.         break;
  254.     case 2:
  255.         reset();
  256.         break;
  257.     case 3:
  258.         exit(0);
  259.     }
  260. }
  261. void mode_menu(int i)
  262. {
  263.     smooth = i;
  264. }
  265. void seed_menu(int i)
  266. {
  267.     seedmode = i;
  268. }
  269. void prim_menu(int i)
  270. {
  271.     primtype = i;
  272. }
  273. void size_menu(int i)
  274. {
  275.     seedsize = 1.0 / i;
  276. }
  277. void psize_menu(int i)
  278. {
  279.     primsize = (float) i;
  280.     glPointSize(primsize);
  281.     glLineWidth(primsize);
  282. }
  283. void no_menu(int i)
  284. {
  285.     nprims = i;
  286. }
  287. void colour_menu(int i)
  288. {
  289.     switch(i) {
  290.     case 0:
  291.         init_colours(500.0);
  292.         randomcolours = 0;
  293.         break;
  294.     case 1:
  295.         init_colours(100.0);
  296.         randomcolours = 0;
  297.         break;
  298.     case 2:
  299.         init_colours(10.0);
  300.         randomcolours = 0;
  301.         break;
  302.     case 3:
  303.         randomcolours = 1;
  304.         break;
  305.     }
  306. }
  307. int mainmenu;
  308. int modemenu, seedmenu, primmenu, sizemenu, psizemenu, nomenu,
  309. colourmenu;
  310. void create_menus(void)
  311. {
  312.     modemenu = glutCreateMenu(mode_menu);    
  313.     glutAddMenuEntry("Chunky", 0);
  314.     glutAddMenuEntry("Smooth", 1);
  315.     seedmenu = glutCreateMenu(seed_menu);    
  316.     glutAddMenuEntry("Primitives", 0);
  317.     glutAddMenuEntry("Circle", 1);
  318.     glutAddMenuEntry("Teapot", 2);
  319.     glutAddMenuEntry("Text", 3);    
  320.     colourmenu = glutCreateMenu(colour_menu);    
  321.     glutAddMenuEntry("Slow", 0);
  322.     glutAddMenuEntry("Medium", 1);
  323.     glutAddMenuEntry("Fast", 2);
  324.     glutAddMenuEntry("Random", 3);
  325.     
  326.     primmenu = glutCreateMenu(prim_menu);    
  327.     glutAddMenuEntry("Dots", GL_POINTS);
  328.     glutAddMenuEntry("Lines", GL_LINES);
  329.     glutAddMenuEntry("Triangles", GL_TRIANGLES);
  330.     sizemenu = glutCreateMenu(size_menu);
  331.     glutAddMenuEntry("Tiny", 20);
  332.     glutAddMenuEntry("Small", 10);
  333.     glutAddMenuEntry("Medium", 5);
  334.     glutAddMenuEntry("Large", 2);
  335.     nomenu = glutCreateMenu(no_menu);
  336.     glutAddMenuEntry("1", 1);
  337.     glutAddMenuEntry("2", 2);
  338.     glutAddMenuEntry("3", 3);
  339.     glutAddMenuEntry("5", 5);
  340.     glutAddMenuEntry("10", 10);
  341.     glutAddMenuEntry("20", 20);
  342.     glutAddMenuEntry("30", 30);
  343.     glutAddMenuEntry("50", 50);
  344.     psizemenu = glutCreateMenu(psize_menu);
  345.     glutAddMenuEntry("1", 1);
  346.     glutAddMenuEntry("3", 3);
  347.     glutAddMenuEntry("5", 5);
  348.     mainmenu = glutCreateMenu(main_menu);
  349.     glutAddSubMenu("Texture mode", modemenu);
  350.     glutAddSubMenu("Seed mode", seedmenu);
  351.     glutAddSubMenu("Seed size", sizemenu);
  352.     glutAddSubMenu("Colours", colourmenu);
  353.     glutAddMenuEntry("-----------", -1);
  354.     glutAddSubMenu("Primitive", primmenu);
  355.     glutAddSubMenu("Number", nomenu);
  356.     glutAddSubMenu("Size", psizemenu);
  357.     glutAddMenuEntry("-----------", 0);
  358.     glutAddMenuEntry("Autospin", 1);
  359.     glutAddMenuEntry("Reset", 2);
  360.     glutAddMenuEntry("Quit", 3);
  361.     
  362.     glutAttachMenu(GLUT_RIGHT_BUTTON);
  363. }
  364. int main(int argc, char **argv)
  365. {
  366.     glutInit(&argc, argv);
  367.     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
  368.     glutCreateWindow("feedback");
  369.     glutReshapeWindow(MAXSIZE, MAXSIZE);
  370.     glutDisplayFunc(redraw);
  371.     glutIdleFunc(redraw);
  372.     glutMouseFunc(mouse);
  373.     glutMotionFunc(motion);
  374.   
  375.     create_menus();
  376.     init_colours(100.0);
  377.   
  378.     glMatrixMode(GL_PROJECTION);
  379.     glLoadIdentity();
  380.     glOrtho(-1.0, 1.0, -1.0, 1.0, 0.0, 1.0);
  381.     glViewport(0, 0, MAXSIZE, MAXSIZE);
  382.     glMatrixMode(GL_MODELVIEW);
  383.     glLoadIdentity();
  384.     glutMainLoop();
  385.     return 0;             /* ANSI C requires main to return int. */
  386. }
  387. #else
  388. int
  389. main(int argc, char** argv)
  390. {
  391.     fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0.n");
  392.     fprintf (stderr, "If your implementation of OpenGL Version 1.0 has the right extensions,n");
  393.     fprintf (stderr, "you may be able to modify this program to make it run.n");
  394.     return 0;
  395. }
  396. #endif