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

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 defaultFile[] = "../data/mandrill.rgb";
  8. GLuint *img;
  9. GLsizei w, h;
  10. GLint comp;
  11. GLfloat kernScale;
  12. /* a few filters... */
  13. GLfloat horizontalEdge3x3[] = {
  14.     -1, -1, -1,
  15.     2,  2,  2,
  16.     -1, -1, -1,
  17. };
  18. GLfloat verticalEdge3x3[] = {
  19.     -1,  2, -1,
  20.     -1,  2, -1,
  21.     -1,  2, -1,  
  22. };
  23. GLfloat allEdge3x3[] = {
  24.     -2, 1, -2,
  25.     1, 4,  1,
  26.     -2, 1, -2,
  27. };
  28. GLfloat smooth3x3[] = {
  29.     1, 2, 1,
  30.     2, 4, 2,
  31.     1, 2, 1,
  32. };
  33. GLfloat highpass3x3[] = {
  34.     -1, -1, -1, 
  35.     -1,  9, -1,
  36.     -1, -1, -1,
  37. };
  38. GLfloat laplacian5x5[] = {
  39.     1,  1,  1,  1,  1,  
  40.     1,  1,  1,  1,  1,  
  41.     1,  1, 24,  1,  1,  
  42.     1,  1,  1,  1,  1,  
  43.     1,  1,  1,  1,  1,  
  44. };
  45. GLfloat box3x3[] = {
  46.     1, 1, 1,
  47.     1, 1, 1,
  48.     1, 1, 1,
  49. };
  50. GLfloat box5x5[] = {
  51.     1, 1, 1, 1, 1, 
  52.     1, 1, 1, 1, 1, 
  53.     1, 1, 1, 1, 1, 
  54.     1, 1, 1, 1, 1, 
  55.     1, 1, 1, 1, 1, 
  56. };
  57. struct Kernel {
  58.     const char *name;
  59.     GLfloat *kern;
  60.     GLsizei w, h;
  61. } filters[] = {
  62.     {"horizontal edge detect", horizontalEdge3x3, 3, 3},
  63.     {"vertical edge detect", verticalEdge3x3, 3, 3},
  64.     {"all edge detect", allEdge3x3, 3, 3},
  65.     {"3x3 smooth", smooth3x3, 3, 3},
  66.     {"3x3 highpass", highpass3x3, 3, 3},
  67.     {"5x5 laplacian", laplacian5x5, 5, 5},
  68.     {"3x3 box", box3x3, 3, 3},
  69.     {"5x5 box", box5x5, 5, 5},
  70. };
  71. struct Kernel *kern;
  72. void kern_normalize(void)
  73. {
  74.     GLfloat total, scale, *k;
  75.     int i;
  76.     k = kern->kern;
  77.     total = 0;
  78.     for (i = 0; i < kern->w*kern->h; i++) {
  79. total += *k++;
  80.     }
  81.     if (!total) {
  82. /* kernel sums to 0... */
  83. return;
  84.     } else {
  85. scale = 1. / total;
  86. k = kern->kern;
  87. for (i = 0; i < kern->w * kern->h; i++) {
  88.     *k *= scale;
  89.     k++;
  90. }
  91.     }
  92. }
  93. GLfloat acc_kern_scale(void)
  94. {
  95.     GLfloat minPossible = 0, maxPossible = 1;
  96.     GLfloat *k;
  97.     int i;
  98.   
  99.     k = kern->kern;
  100.     for (i = 0; i < kern->w*kern->h; i++) {
  101. if (*k < 0) {
  102.     minPossible += *k;
  103. } else {
  104.     maxPossible += *k;
  105. }
  106. k++;
  107.     }
  108.     return(1. / ((-minPossible > maxPossible) ? -minPossible : maxPossible));
  109. }
  110. void init(void)
  111. {
  112.     kern = &filters[4];
  113.     kern_normalize();
  114.     kernScale = acc_kern_scale();
  115. }
  116. void load_img(const char *fname)
  117. {
  118.     img = read_texture(fname, &w, &h, &comp);
  119.     if (!img) {
  120. fprintf(stderr, "Could not open %sn", fname);
  121. exit(1);
  122.     }
  123. }
  124. void reshape(GLsizei winW, GLsizei winH) 
  125. {
  126.     glViewport(0, 0, w, h);
  127.     glLoadIdentity();
  128.     glOrtho(0, winW, 0, winH, 0, 5);
  129. }
  130. void acc_convolve(void)
  131. {
  132.     int x, y;
  133.     for (y = 0; y < kern->h; y++) {
  134. for (x = 0; x < kern->w; x++) {
  135.     glRasterPos2i(0, 0); 
  136.     glBitmap(0, 0, 0, 0, -x, -y, 0);
  137.     glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img);
  138.     glAccum(GL_ACCUM, kern->kern[y*kern->w + x]*kernScale);
  139. }
  140.     }
  141.     glAccum(GL_RETURN, 1./kernScale);
  142. }
  143. void draw(void)
  144. {
  145.     GLenum err;
  146.     glutSetCursor(GLUT_CURSOR_WAIT);
  147.     glClear(GL_COLOR_BUFFER_BIT | GL_ACCUM_BUFFER_BIT);
  148.     acc_convolve();
  149.     err = glGetError();
  150.     if (err != GL_NO_ERROR) printf("Error:  %sn", gluErrorString(err));
  151.     glutSetCursor(GLUT_CURSOR_INHERIT);
  152. }
  153. /* ARGSUSED1 */
  154. void key(unsigned char key, int x, int y)
  155. {
  156.     if (key == 27) exit(0);
  157. }
  158. void menu(int val)
  159. {
  160.     kern = &filters[val];
  161.     kern_normalize();
  162.     kernScale= acc_kern_scale();
  163.     draw();
  164. }
  165. main(int argc, char *argv[])
  166. {
  167.     int i;
  168.     glutInit(&argc, argv);
  169.     if (argc > 1) {
  170. load_img(argv[1]);
  171.     } else {
  172. load_img(defaultFile);
  173.     }
  174.     glutInitWindowSize(w, h);
  175.     glutInitWindowPosition(0, 0);
  176.     glutInitDisplayMode(GLUT_RGB | GLUT_ACCUM);
  177.     glutCreateWindow(argv[0]);
  178.     glutDisplayFunc(draw);
  179.     glutKeyboardFunc(key);
  180.     glutReshapeFunc(reshape);
  181.   
  182.     glutCreateMenu(menu);
  183.     for (i = 0; i < sizeof(filters) / sizeof(filters[0]); i++) {
  184. glutAddMenuEntry(filters[i].name, i);
  185.     }
  186.     glutAttachMenu(GLUT_RIGHT_BUTTON);
  187.   
  188.     init();
  189.   
  190.     glutMainLoop();
  191.     return 0;
  192. }