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

GIS编程

开发平台:

Visual C++

  1. /* comp.c - by David Blythe, SGI */
  2. /* Porter/Duff compositing operations using OpenGL alpha blending. */
  3. /* NOTE:  This program uses OpenGL blending functions that need the    frame
  4.    buffer to retain a destination alpha component.  Examples of such
  5.    hardware:  O2, IMPACT, RealityEngine, and InfiniteReality. */
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <math.h>
  9. #include <GL/glut.h>
  10. #include "texture.h"
  11. static int w = 640, h = 640;
  12. void
  13. myReshape(int nw, int nh)
  14. {
  15.   w = nw, h = nh;
  16.   glClearColor(0, 0, 0, 0);
  17.   glViewport(0, 0, w, h);
  18.   glMatrixMode(GL_PROJECTION);
  19.   glLoadIdentity();
  20.   glMatrixMode(GL_MODELVIEW);
  21.   glLoadIdentity();
  22. }
  23. static unsigned *a_data = 0, *b_data = 0;
  24. static int a_width, a_height, b_width, b_height;
  25. void
  26. init_tris(void)
  27. {
  28.   if (a_data)
  29.     free(a_data);
  30.   if (b_data)
  31.     free(b_data);
  32.   a_data = (unsigned *) malloc(w * h);
  33.   b_data = (unsigned *) malloc(w * h);
  34.   glViewport(0, 0, w / 2, h / 2);
  35.   glClear(GL_COLOR_BUFFER_BIT);
  36.   glColor4f(1, 0, 0, 1);
  37.   glBegin(GL_TRIANGLES);
  38.   glVertex2f(-1, -1);
  39.   glVertex2f(-1, 1);
  40.   glVertex2f(.5, 1);
  41.   glEnd();
  42.   glReadPixels(0, 0, w / 2, h / 2, GL_RGBA, GL_UNSIGNED_BYTE, a_data);
  43.   glClear(GL_COLOR_BUFFER_BIT);
  44.   glColor4f(0, 1, 0, 1);
  45.   glBegin(GL_TRIANGLES);
  46.   glVertex2f(1, -1);
  47.   glVertex2f(1, 1);
  48.   glVertex2f(-.5, 1);
  49.   glEnd();
  50.   glReadPixels(0, 0, w / 2, h / 2, GL_RGBA, GL_UNSIGNED_BYTE, b_data);
  51.   a_width = b_width = w / 2, a_height = b_height = h / 2;
  52. }
  53. void
  54. init_images(void)
  55. {
  56.   int comp;
  57.   a_data = read_texture("a.rgb", &a_width, &a_height, &comp);
  58.   printf("%dx%dx%dn", a_width, a_height, comp);
  59.   b_data = read_texture("b.rgb", &b_width, &b_height, &comp);
  60.   printf("%dx%dx%dn", b_width, b_height, comp);
  61. }
  62. void
  63. display(void)
  64. {
  65.   int i;
  66.   glDrawBuffer(GL_FRONT_AND_BACK);
  67.   glClear(GL_COLOR_BUFFER_BIT);
  68.   glDrawBuffer(GL_BACK);
  69.   glBlendFunc(GL_SRC_ALPHA, GL_ZERO);
  70.   /* image A */
  71.   glViewport(0, 0, w / 2, h / 2);
  72.   glRasterPos2f(-1, -1);
  73.   glDrawPixels(a_width, a_height, GL_RGBA, GL_UNSIGNED_BYTE,
  74.     a_data);
  75.   glEnable(GL_BLEND);
  76.   glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
  77.   glCopyPixels(0, 0, w / 2, h / 2, GL_COLOR);
  78.   glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  79.   glDisable(GL_BLEND);
  80.   /* image B */
  81.   glViewport(w / 2, 0, w / 2, h / 2);
  82.   glRasterPos2f(-1, -1);
  83.   glDrawPixels(b_width, b_height, GL_RGBA, GL_UNSIGNED_BYTE,
  84.     b_data);
  85.   glEnable(GL_BLEND);
  86.   glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
  87.   glCopyPixels(w / 2, 0, w / 2, h / 2, GL_COLOR);
  88.   glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  89.   glReadBuffer(GL_BACK);
  90.   glDrawBuffer(GL_FRONT);
  91.   for (i = 0; i < 4; i++) {
  92.     glDisable(GL_BLEND);
  93.     switch (i) {
  94.     case 0:            /* a over b */
  95.       glViewport(0, 0, w / 2, h / 2);
  96.       glRasterPos2f(-1, -1);
  97.       glCopyPixels(0, 0, w / 2, h / 2, GL_COLOR);
  98.       glEnable(GL_BLEND);
  99.       glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);
  100.       glCopyPixels(w / 2, 0, w / 2, h / 2, GL_COLOR);
  101.       break;
  102.     case 1:            /* a under b */
  103.       glViewport(w / 2, 0, w / 2, h / 2);
  104.       glRasterPos2f(-1, -1);
  105.       glCopyPixels(0, 0, w / 2, h / 2, GL_COLOR);
  106.       glEnable(GL_BLEND);
  107.       glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  108.       glCopyPixels(w / 2, 0, w / 2, h / 2, GL_COLOR);
  109.       break;
  110.     case 2:            /* b in a */
  111.       glViewport(0, h / 2, w / 2, h / 2);
  112.       glRasterPos2f(-1, -1);
  113.       glCopyPixels(0, 0, w / 2, h / 2, GL_COLOR);
  114.       glEnable(GL_BLEND);
  115.       glBlendFunc(GL_DST_ALPHA, GL_ZERO);
  116.       glCopyPixels(w / 2, 0, w / 2, h / 2, GL_COLOR);
  117.       break;
  118.     case 3:            /* b out of a */
  119.       glViewport(w / 2, h / 2, w / 2, h / 2);
  120.       glRasterPos2f(-1, -1);
  121.       glCopyPixels(0, 0, w / 2, h / 2, GL_COLOR);
  122.       glEnable(GL_BLEND);
  123.       glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ZERO);
  124.       glCopyPixels(w / 2, 0, w / 2, h / 2, GL_COLOR);
  125.       break;
  126.     }
  127.   }
  128.   glViewport(0, 0, w, h);
  129.   glEnable(GL_BLEND);
  130.   glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);
  131.   glColor4f(1., 1., 1., 0.);
  132.   glRectf(-1, -1, 1, 1);
  133.   glFlush();
  134. }
  135. /* ARGSUSED1 */
  136. void
  137. key(unsigned char key, int x, int y)
  138. {
  139.   if (key == '33')
  140.     exit(0);
  141. }
  142. int
  143. main(int argc, char *argv[])
  144. {
  145.   glutInit(&argc, argv);
  146.   glutInitWindowSize(w, h);
  147.   glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA);
  148.   if (!glutGet(GLUT_DISPLAY_MODE_POSSIBLE)) {
  149.     printf("comp: requires a frame buffer with destination alphan");
  150.     exit(1);
  151.   }
  152.   glutCreateWindow("comp");
  153.   if (argc > 1)
  154.     init_images();
  155.   else
  156.     init_tris();
  157.   glutDisplayFunc(display);
  158.   glutReshapeFunc(myReshape);
  159.   glutKeyboardFunc(key);
  160.   glutMainLoop();
  161.   return 0;             /* ANSI C requires main to return int. */
  162. }