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

GIS编程

开发平台:

Visual C++

  1. /* textrim.c - by David Blythe, SGI */
  2. /* Trimming textures: demonstrates how alpha blending or alpha testing
  3.    can be used to "trim" the shape of textures to arbitrary shapes. 
  4.    Alpha testing is generally cheaper than alpha blending, but
  5.    blending permits antialiased edges. */
  6. /* Try: "textrim tree.rgb" where tree.rgb is a SGI .rgb file including
  7.    an alpha component. */
  8.    
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <GL/glut.h>
  12. #include <math.h>
  13. #include "texture.h"
  14. static float scale = 1.4;
  15. static float transx, transy, rotx, roty;
  16. static int ox = -1, oy = -1;
  17. static int mot = 0;
  18. #define PAN 1
  19. #define ROT 2
  20. void
  21. pan(int x, int y)
  22. {
  23.   transx += (x - ox) / 500.;
  24.   transy -= (y - oy) / 500.;
  25.   ox = x;
  26.   oy = y;
  27.   glutPostRedisplay();
  28. }
  29. void
  30. rotate(int x, int y)
  31. {
  32.   rotx += x - ox;
  33.   if (rotx > 360.)
  34.     rotx -= 360.;
  35.   else if (rotx < -360.)
  36.     rotx += 360.;
  37.   roty += y - oy;
  38.   if (roty > 360.)
  39.     roty -= 360.;
  40.   else if (roty < -360.)
  41.     roty += 360.;
  42.   ox = x;
  43.   oy = y;
  44.   glutPostRedisplay();
  45. }
  46. void
  47. motion(int x, int y)
  48. {
  49.   if (mot == PAN)
  50.     pan(x, y);
  51.   else if (mot == ROT)
  52.     rotate(x, y);
  53. }
  54. void
  55. mouse(int button, int state, int x, int y)
  56. {
  57.   if (state == GLUT_DOWN) {
  58.     switch (button) {
  59.     case GLUT_LEFT_BUTTON:
  60.       mot = PAN;
  61.       motion(ox = x, oy = y);
  62.       break;
  63.     case GLUT_MIDDLE_BUTTON:
  64.       mot = ROT;
  65.       motion(ox = x, oy = y);
  66.       break;
  67.     }
  68.   } else if (state == GLUT_UP) {
  69.     mot = 0;
  70.   }
  71. }
  72. void 
  73. afunc(void)
  74. {
  75.   static int state;
  76.   if (state ^= 1) {
  77.     glAlphaFunc(GL_GREATER, .01);
  78.     glEnable(GL_ALPHA_TEST);
  79.   } else {
  80.     glDisable(GL_ALPHA_TEST);
  81.   }
  82. }
  83. void 
  84. bfunc(void)
  85. {
  86.   static int state;
  87.   if (state ^= 1) {
  88.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  89.     glEnable(GL_BLEND);
  90.   } else {
  91.     glDisable(GL_BLEND);
  92.   }
  93. }
  94. void 
  95. up(void)
  96. {
  97.   scale += .1;
  98. }
  99. void 
  100. down(void)
  101. {
  102.   scale -= .1;
  103. }
  104. void 
  105. help(void)
  106. {
  107.   printf("Usage: textrim [image]n");
  108.   printf("'h'            - helpn");
  109.   printf("'a'            - toggle alpha testn");
  110.   printf("'b'            - toggle blendn");
  111.   printf("'UP'           - scale upn");
  112.   printf("'DOWN'         - scale downn");
  113.   printf("left mouse     - pann");
  114.   printf("middle mouse   - rotaten");
  115. }
  116. void 
  117. init(char *filename)
  118. {
  119.   static unsigned *image;
  120.   static int width, height, components;
  121.   if (filename) {
  122.     image = read_texture(filename, &width, &height, &components);
  123.     if (image == NULL) {
  124.       fprintf(stderr, "Error: Can't load image file "%s".n",
  125.         filename);
  126.       exit(1);
  127.     } else {
  128.       printf("%d x %d image loadedn", width, height);
  129.     }
  130.     if (components != 4) {
  131.       printf("must be an RGBA imagen");
  132.       exit(1);
  133.     }
  134.   } else {
  135.     int i, j;
  136.     unsigned char *img;
  137.     components = 4;
  138.     width = height = 512;
  139.     image = (unsigned *) malloc(width * height * sizeof(unsigned));
  140.     img = (unsigned char *) image;
  141.     for (j = 0; j < height; j++)
  142.       for (i = 0; i < width; i++) {
  143.         int w2 = width / 2, h2 = height / 2;
  144.         if (i & 32)
  145.           img[4 * (i + j * width) + 0] = 0xff;
  146.         else
  147.           img[4 * (i + j * width) + 1] = 0xff;
  148.         if (j & 32)
  149.           img[4 * (i + j * width) + 2] = 0xff;
  150.         if ((i - w2) * (i - w2) + (j - h2) * (j - h2) > 64 * 64 &&
  151.           (i - w2) * (i - w2) + (j - h2) * (j - h2) < 300 * 300)
  152.           img[4 * (i + j * width) + 3] = 0xff;
  153.       }
  154.   }
  155.   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  156.   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  157.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  158.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  159.   glTexImage2D(GL_TEXTURE_2D, 0, components, width,
  160.     height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
  161.     image);
  162.   glEnable(GL_TEXTURE_2D);
  163.   glMatrixMode(GL_PROJECTION);
  164.   glLoadIdentity();
  165.   gluPerspective(50., 1., .1, 10.);
  166.   glMatrixMode(GL_MODELVIEW);
  167.   glLoadIdentity();
  168.   glTranslatef(0., 0., -5.5);
  169.   glClearColor(.25f, .25f, .25f, .25f);
  170. }
  171. void 
  172. display(void)
  173. {
  174.   glClear(GL_COLOR_BUFFER_BIT);
  175.   glPushMatrix();
  176.   glTranslatef(transx, transy, 0.f);
  177.   glRotatef(rotx, 0., 1., 0.);
  178.   glRotatef(roty, 1., 0., 0.);
  179.   glScalef(scale, scale, 0.);
  180.   glBegin(GL_POLYGON);
  181.   glTexCoord2f(0.0, 0.0);
  182.   glVertex2f(-1.0, -1.0);
  183.   glTexCoord2f(1.0, 0.0);
  184.   glVertex2f(1.0, -1.0);
  185.   glTexCoord2f(1.0, 1.0);
  186.   glVertex2f(1.0, 1.0);
  187.   glTexCoord2f(0.0, 1.0);
  188.   glVertex2f(-1.0, 1.0);
  189.   glEnd();
  190.   glPopMatrix();
  191.   glutSwapBuffers();
  192. }
  193. void 
  194. reshape(int w, int h)
  195. {
  196.   glViewport(0, 0, w, h);
  197. }
  198. /* ARGSUSED1 */
  199. void
  200. key(unsigned char key, int x, int y)
  201. {
  202.   switch (key) {
  203.   case 'A':
  204.   case 'a':
  205.     afunc();
  206.     break;
  207.   case 'B':
  208.   case 'b':
  209.     bfunc();
  210.     break;
  211.   case 'H':
  212.   case 'h':
  213.     help();
  214.     break;
  215.   case '33':
  216.     exit(0);
  217.     break;
  218.   default:
  219.     break;
  220.   }
  221.   glutPostRedisplay();
  222. }
  223. /* ARGSUSED1 */
  224. void
  225. special(int key, int x, int y)
  226. {
  227.   switch (key) {
  228.   case GLUT_KEY_UP:
  229.     up();
  230.     break;
  231.   case GLUT_KEY_DOWN:
  232.     down();
  233.     break;
  234.   default:
  235.     return;
  236.   }
  237.   glutPostRedisplay();
  238. }
  239. void
  240. menu(int value)
  241. {
  242.   key((unsigned char) value, 0, 0);
  243. }
  244. int 
  245. main(int argc, char **argv)
  246. {
  247.   glutInit(&argc, argv);
  248.   glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
  249.   (void) glutCreateWindow("textrim");
  250.   init(argv[1]);
  251.   glutDisplayFunc(display);
  252.   glutKeyboardFunc(key);
  253.   glutSpecialFunc(special);
  254.   glutReshapeFunc(reshape);
  255.   glutMouseFunc(mouse);
  256.   glutMotionFunc(motion);
  257.   glutCreateMenu(menu);
  258.   glutAddMenuEntry("Toggle alpha testing", 'a');
  259.   glutAddMenuEntry("Toggle alpha blending", 'b');
  260.   glutAddMenuEntry("Quit", '33');
  261.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  262.   glutMainLoop();
  263.   return 0;             /* ANSI C requires main to return int. */
  264. }