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

GIS编程

开发平台:

Visual C++

  1. #include <assert.h>
  2. #include <math.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <GL/glut.h>
  6. #include "texture.h"
  7. static char defaultFile0[] = "../data/sgi.bw";
  8. static char defaultFile1[] = "../data/mandrill.rgb";
  9. static char defaultFile2[] = "../data/brick.rgb";
  10. GLuint *img0, *img1, *img2;
  11. GLsizei w, h;
  12. GLsizei w0, w1, w2, h0, h1, h2;
  13. GLint comp;
  14. GLfloat key[3] = {0, 0, 0};
  15. #define RW 0.3086
  16. #define GW 0.6094
  17. #define BW 0.0820
  18. void init(void)
  19. {
  20. }
  21. GLuint *load_img(const char *fname, GLsizei *imgW, GLsizei *imgH)
  22. {
  23.   GLuint *img;
  24.   img = read_texture(fname, imgW, imgH, &comp);
  25.   if (!img) {
  26.     fprintf(stderr, "Could not open %sn", fname);
  27.     exit(1);
  28.   }
  29.   return img;
  30. }
  31. GLuint *
  32. resize_img(GLuint *img, GLsizei curW, GLsizei curH)
  33. {
  34.   glPixelZoom((float)w / (float)curW, (float)h / (float)curH);
  35.   glRasterPos2i(0, 0);
  36.   glDrawPixels(curW, curH, GL_RGBA, GL_UNSIGNED_BYTE, img);
  37.   free(img);
  38.   img = (GLuint *)malloc(w * h * sizeof(GLuint));
  39.   if (!img) {
  40.     fprintf(stderr, "Malloc of %d bytes failed.n", 
  41.     curW * curH * sizeof(GLuint));
  42.     exit(1);
  43.   }
  44.   glPixelZoom(1, 1);
  45.   glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img);
  46.   return img;
  47. }
  48. void reshape(GLsizei winW, GLsizei winH) 
  49. {
  50.     glViewport(0, 0, 2*w, 2*h);
  51.     glLoadIdentity();
  52.     glOrtho(0, 2*w, 0, 2*h, 0, 5);
  53. }
  54. void compute_matte(void)
  55. {
  56.   glClear(GL_ACCUM_BUFFER_BIT);
  57.   /* draw rectangle in (key color + 1) / 2 */
  58.   glBegin(GL_QUADS);
  59.   glColor3f(key[0], key[1], key[2]);
  60.   glVertex2f(0, 0);
  61.   glVertex2f(w, 0);
  62.   glVertex2f(w, h);
  63.   glVertex2f(0, h);
  64.   glEnd();
  65.   glFlush();
  66.   /* negate & accumulate  */
  67.   glAccum(GL_LOAD, -1);
  68.   /* compute & return (image - key) */
  69.   glRasterPos2f(0, 0);
  70.   glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img0);
  71.   glAccum(GL_ACCUM, 1);
  72.   glAccum(GL_RETURN, 1);
  73.   /* move to right hand side of window */
  74.   glRasterPos2f(w, 0);
  75.   glCopyPixels(0, 0, w, h, GL_COLOR);
  76.   /* compute & return (key - image) */
  77.   glEnable(GL_SCISSOR_TEST);
  78.   glScissor(0, 0, w, h);
  79.   glAccum(GL_MULT, -1);
  80.   glAccum(GL_RETURN, 1);
  81.   glScissor(0, 0, 2*w, h);
  82.   glDisable(GL_SCISSOR_TEST);
  83.   /* assemble to get fabs(key - image) */
  84.   glBlendFunc(GL_ONE, GL_ONE);
  85.   glEnable(GL_BLEND);
  86.   glRasterPos2i(0, 0);
  87.   glCopyPixels(w, 0, w, h, GL_COLOR);
  88.   glDisable(GL_BLEND);
  89.   /* assemble into alpha channel */
  90.   {
  91.     GLfloat mat[] = {
  92.       RW, RW, RW, RW,
  93.       GW, GW, GW, GW,
  94.       BW, BW, BW, BW,
  95.       0, 0, 0, 0,
  96.     };
  97.     glMatrixMode(GL_COLOR);
  98.     glLoadMatrixf(mat);
  99.     glRasterPos2i(w, 0);
  100.     glCopyPixels(0, 0, w, h, GL_COLOR);
  101.     glLoadIdentity();
  102.     glMatrixMode(GL_MODELVIEW);
  103.   }
  104.   /* copy matte to right */
  105.   glRasterPos2i(0, 0);
  106.   glCopyPixels(w, 0, w, h, GL_COLOR);
  107.   /* draw the third image */
  108.   glColorMask(1, 1, 1, 0);
  109.   glRasterPos2i(w, 0);
  110.   glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img2);
  111.   glColorMask(1, 1, 1, 1);
  112.   glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
  113.   glEnable(GL_BLEND);
  114.   glRasterPos2i(w, 0);
  115.   glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img1);
  116.   /* this is for matte display... */
  117.   glColor3f(1, 1, 1);
  118.   glBegin(GL_QUADS);
  119.   glVertex2f(0, 0);
  120.   glVertex2f(w, 0);
  121.   glVertex2f(w, h);
  122.   glVertex2f(0, h);
  123.   glEnd();
  124.   glDisable(GL_BLEND);
  125. }
  126. void draw(void)
  127. {
  128.   GLenum err;
  129.   static int first = 1;
  130.   
  131.   if (first) {
  132.     printf("Scaling images to %d by %dn", w, h);
  133.     if (w0 != w || h0 != h) {
  134.       img0 = resize_img(img0, w0, h0);
  135.     }
  136.     if (w1 != w || h1 != h) {
  137.       img1 = resize_img(img1, w1, h1);
  138.     }
  139.     if (w2 != w || h2 != h) {
  140.       img2 = resize_img(img2, w2, h2);
  141.     }
  142.     first = 0;
  143.   }
  144.   
  145.   
  146.   glClear(GL_COLOR_BUFFER_BIT);
  147.   compute_matte();
  148.   
  149.   glRasterPos2i(w/2, h);
  150.   glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img0);
  151.   err = glGetError();
  152.   if (err != GL_NO_ERROR) printf("Error:  %sn", gluErrorString(err));
  153. }
  154. /* ARGSUSED */
  155. void button(int button, int state, int xpos, int ypos)
  156. {
  157.   if (state != GLUT_UP) return;
  158.   ypos = 2*h - ypos;
  159.   glReadPixels(xpos, ypos, 1, 1, GL_RGB, GL_FLOAT, key);
  160.   printf("Key is (%f %f %f)n", key[0], key[1], key[2]);
  161.   draw();
  162. }
  163. /* ARGSUSED1 */
  164. void keyPress(unsigned char whichKey, int x, int y)
  165. {
  166.   if (whichKey == 27) exit(0);
  167. }
  168. void show_usage(void) 
  169. {
  170.   fprintf(stderr, "Usage:n");
  171.   fprintf(stderr, "chromakey mattefile file0 file1 [matteR matteG matteB]n");
  172.   fprintf(stderr, "chromakey mattefileAndfile0 file1 [matteR matteG matteB]n");
  173. }
  174. main(int argc, char *argv[])
  175. {
  176.   char *fileName0 = defaultFile0, *fileName1 = defaultFile1, 
  177.   *fileName2 = defaultFile2;
  178.   
  179.   glutInit(&argc, argv);
  180.   if (argc > 1) {
  181.     fileName0 = fileName1 = argv[1];
  182.   }
  183.   if (argc > 2) {
  184.     fileName2 = argv[2];
  185.   }
  186.   if (argc > 3) {
  187.     fileName1 = fileName2;
  188.     fileName2 = argv[3];
  189.   }
  190.   if (argc > 4) {
  191.     if (argc == 6 || argc == 7) {
  192.       key[0] = atof(argv[argc-3]);
  193.       key[1] = atof(argv[argc-2]);
  194.       key[2] = atof(argv[argc-1]);
  195.     } else {
  196.       show_usage();
  197.       exit(1);
  198.     }
  199.   }
  200.   
  201.   printf("Matte file is %sn", fileName0);
  202.   printf("Image file 1 is %sn", fileName1);
  203.   printf("Image file 2 is %sn", fileName2);
  204.   printf("Key is (%f %f %f)n", key[0], key[1], key[2]);
  205.   img0 = load_img(fileName0, &w0, &h0);
  206.   img1 = load_img(fileName1, &w1, &h1);
  207.   img2 = load_img(fileName2, &w2, &h2);
  208.   
  209. #define MAX(a, b) ((a) > (b) ? (a) : (b))
  210.   w = MAX(MAX(w0, w1), w2);
  211.   h = MAX(MAX(h0, h1), h2);
  212.   
  213.   glutInitWindowSize(2*w, 2*h);
  214.   glutInitWindowPosition(0, 0);
  215.   glutInitDisplayMode(GLUT_RGBA | GLUT_ACCUM | GLUT_ALPHA);
  216.   glutCreateWindow(argv[0]);
  217.   glutDisplayFunc(draw);
  218.   glutKeyboardFunc(keyPress);
  219.   glutReshapeFunc(reshape);
  220.   glutMouseFunc(button);
  221.   init();
  222.   
  223.   reshape(w, h);
  224.   glutMainLoop();
  225.   return 0;
  226. }