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

GIS编程

开发平台:

Visual C++

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <GL/glut.h>
  5. #include "texture.h"
  6. #include <string.h>
  7. #if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2)
  8. #define glTexSubImage2D glTexSubImage2DEXT
  9. #endif
  10. static unsigned *image, *bgdtile;
  11. static int width, height, components;
  12. static int grid, zoom, texture;
  13. #define TSIZE 128
  14. #define TILES 16
  15. #define TILESIZE 32
  16. static struct tile {
  17.     void *data;
  18. } tiles[TILES][TILES];
  19. static int x = TILES*TILESIZE/2, y = TILES*TILESIZE/2;
  20. /*
  21.  * make an rgb tile for the background.
  22.  */
  23. static void
  24. background_tile(void) {
  25.     int i,j,grid;
  26.     unsigned char *ptr;
  27.     bgdtile = (unsigned *) malloc(TILESIZE*TILESIZE*sizeof(unsigned));
  28.     grid = 8;
  29.     ptr = (unsigned char *) bgdtile;
  30.     for (i=0; i<TILESIZE; i++) {
  31. for(j=0; j<TILESIZE; j++) {
  32.    if(i%grid == 0 || j%grid == 0) {
  33. *ptr++ = 0x0; *ptr++ = 0x0; *ptr++ = 0x40; ptr++;
  34.    } else {
  35. *ptr++ = 0x40; *ptr++ = 0x40; *ptr++ = 0x40; ptr++;
  36.    }
  37.         }
  38.     }
  39. }
  40. static void
  41. tile_image(unsigned *image) {
  42.     int i, j;
  43.     int w = width/TILESIZE;
  44.     int h = height/TILESIZE, w2 = w/2, h2 = h/2;
  45.     background_tile();
  46.     for(i = 0; i < TILES; i++) {
  47. for(j = 0; j < TILES; j++) {
  48.     if (i >= TILES/2-w2 && i < TILES/2-w2+w && j >= TILES/2-h2 && j < TILES/2-h2+h) {
  49. /* interior */
  50. int x, y, k;
  51. tiles[j][i].data = malloc(TILESIZE*TILESIZE*sizeof(*image));
  52. x = TILESIZE*(i-TILES/2+w2);
  53. y = TILESIZE*(j-TILES/2+h2);
  54. for(k = 0; k < TILESIZE; k++)
  55.     memcpy((unsigned *)tiles[j][i].data+k*TILESIZE,
  56.     image+width*(y+k)+x, TILESIZE*sizeof *image);
  57.     }
  58.     else
  59. tiles[j][i].data = bgdtile;
  60. }
  61.     }
  62.     for(i = 0; i < TILES; i++) {
  63. for(j = 0; j < TILES; j++) {
  64.     printf("%d ", tiles[j][i].data != bgdtile);
  65. }
  66. printf("n");
  67.     }
  68. }
  69. #define MAXMESH 64
  70. static float Ml[4*2*(MAXMESH+1)*2 * (MAXMESH+1)];
  71. static void
  72. mesh0(float x0, float x1, float y0, float y1,
  73.           float s0, float s1, float t0, float t1, float z, int nx,int ny)
  74. {
  75.     float y,x,s,t,dx,dy,ds,dt,vb[3],tb[2];
  76.     float *mp = Ml;
  77.     dx = (x1-x0)/nx;
  78.     dy = (y1-y0)/ny;
  79.     ds = (s1-s0)/nx;
  80.     dt = (t1-t0)/ny;
  81.     y = y0;
  82.     t = t0;
  83.     vb[2] = z;
  84.     while (y < y1) {
  85.         x = x0;
  86.         s = s0;
  87.         while(x <= x1) {
  88.             tb[0] = s; tb[1] = t;
  89.             vb[0] = x; vb[1] = y;
  90.             vb[2] = 0.0;
  91.             *mp++ = tb[0];
  92.             *mp++ = tb[1];
  93.             mp += 2;
  94.             *mp++ = vb[0];
  95.             *mp++ = vb[1];
  96.             *mp++ = vb[2];
  97.             mp++;
  98.             tb[1] = t+dt;
  99.             vb[1] = y+dy;
  100.             vb[2] = 0.0;
  101.             *mp++ = tb[0];
  102.             *mp++ = tb[1];
  103.             mp += 2;
  104.             *mp++ = vb[0];
  105.             *mp++ = vb[1];
  106.             *mp++ = vb[2];
  107.             mp++;
  108.             x += dx;
  109.             s += ds;
  110.         }
  111.         y += dy;
  112.         t += dt;
  113.     }
  114. }
  115. static void
  116. drawmesh(int nx,int ny) {
  117.     float *mp = Ml;
  118.     int i,j;
  119.     glPushMatrix();
  120.     if (zoom) glScalef(1.5f, 1.5f, 1.f);
  121.     glColor4f(1,1,1,1);
  122.     for (i = ny+1; i; i--) {
  123.         glBegin(GL_TRIANGLE_STRIP);
  124.         for (j = nx+1; j; j--) {
  125.             glTexCoord2fv(mp);
  126.             glVertex3fv(mp+4);
  127.             glTexCoord2fv(mp+8);
  128.             glVertex3fv(mp+12); mp += 16;
  129.         }
  130.         glEnd();
  131.     }
  132.     glPopMatrix();
  133. }
  134. static void
  135. help(void) {
  136.     printf("'h'      - helpn");
  137.     printf("'left'   - pan leftn");
  138.     printf("'right'  - pan rightn");
  139.     printf("'up'     - pan upn");
  140.     printf("'down'   - pan downn");
  141.     printf("'t'      - toggle texture memory displayn");
  142.     printf("'g'      - toggle gridn");
  143.     printf("'x'      - toggle auto pann");
  144.     printf("'z'      - toggle zoomn");
  145. }
  146. static void
  147. gfunc(void) {
  148.     grid ^= 1;
  149. }
  150. static void
  151. tfunc(void) {
  152.     texture ^= 1;
  153. }
  154. static void anim(void);
  155. static void
  156. xfunc(void) {
  157.     static int state;
  158.     glutIdleFunc((state ^= 1) ? anim : NULL);
  159. }
  160. static void
  161. zfunc(void) {
  162.     zoom ^= 1;
  163. }
  164. #define CLAMP(v) { int w = TSIZE/2; 
  165.     if (v < w) v = w; 
  166.     else if (v > TILES*TILESIZE-w) v = TILES*TILESIZE-w; }
  167. static void
  168. up(void) {
  169.     y += 8;
  170.     CLAMP(y);
  171. }
  172. static void
  173. pfunc(void) {
  174.     static int delta = -1;
  175.     int xx = x + delta;
  176.     x += delta; CLAMP(x);
  177.     y += delta; CLAMP(y);
  178.     if (x != xx) delta = -delta;
  179. }
  180. static void
  181. down(void) {
  182.     y -= 8;
  183.     CLAMP(y);
  184. }
  185. static void
  186. right(void) {
  187.     x += 8;
  188.     CLAMP(x);
  189. }
  190. static void
  191. left(void) {
  192.     x -= 8;
  193.     CLAMP(x);
  194. }
  195. static void
  196. anim(void) {
  197.     static int delta = -1;
  198.     int xx = x + delta;
  199.     x += delta;
  200.     CLAMP(x);
  201.     y += delta;
  202.     CLAMP(y);
  203.     if (x != xx) delta = -delta;
  204.     glutPostRedisplay();
  205. }
  206. static void
  207. loadtiles(void) {
  208.     int lx, rx, ty, by; /* image bounding box */
  209.     static int ox = TILES*TILESIZE/2, oy = TILES*TILESIZE/2;  /* image origin */
  210.     static int ot = 0, os = 0;
  211.     int dx = 0, dy = 0, nx = -1, ny = -1;
  212.     float trx, try;
  213. #define S_TSIZE (TSIZE-TILESIZE) /* visible portion of texture = TSIZE less one tile for slop */
  214.     /* calculate tile #'s at corners of visible region */
  215.     lx = x - S_TSIZE/2;
  216.     rx = lx + S_TSIZE;
  217.     by = y - S_TSIZE/2;
  218.     ty = by + S_TSIZE;
  219.     lx /= TILESIZE; rx /= TILESIZE;
  220.     by /= TILESIZE; ty /= TILESIZE;
  221.     dx = ((x - S_TSIZE/2)/TILESIZE) - ((ox - S_TSIZE/2)/TILESIZE);
  222.     
  223.     nx = lx; ny = by;
  224.     if (dx < 0) {
  225. /* add on left */
  226. os -= TILESIZE;
  227. if (os < 0) os += TSIZE;
  228. nx = lx;
  229.     } else if (dx > 0) {
  230. nx = rx;
  231.     }
  232.     dy = ((y - S_TSIZE/2) / TILESIZE) - ((oy - S_TSIZE/2) / TILESIZE);
  233.     if (dy > 0) {
  234. /* add on bottom */
  235. ny = ty;
  236.     } else if (dy < 0) {
  237. /* add on top */
  238. ot -= TILESIZE;
  239. if (ot < 0) ot += TSIZE;
  240. ny = by;
  241.     }
  242. if (dx || dy) printf("dx %d dy %d   lx %d rx %d   by %d ty %d   nx %d ny %d   os %d ot %dn", dx, dy, lx, rx, by, ty, nx, ny, os, ot);
  243.     if (dx) {
  244. int t;
  245. for(t = 0; t < TSIZE; t += TILESIZE) {
  246.     glTexSubImage2D(GL_TEXTURE_2D, 0, os, (t+ot) % TSIZE, TILESIZE,
  247.                  TILESIZE, GL_RGBA, GL_UNSIGNED_BYTE,
  248.                  tiles[ny+t/TILESIZE][nx].data);
  249. printf("load %d %d  %d %dn", nx, ny+t/TILESIZE, os, (t+ot) % TSIZE);
  250. }
  251.     }
  252.     if (dy) {
  253. int s;
  254. for(s = 0; s < TSIZE; s += TILESIZE) {
  255.     glTexSubImage2D(GL_TEXTURE_2D, 0, (s+os) % TSIZE, ot, TILESIZE,
  256.                  TILESIZE, GL_RGBA, GL_UNSIGNED_BYTE,
  257.                  tiles[ny][nx+s/TILESIZE].data);
  258. printf("load %d %d  %d %dn", nx+s/TILESIZE, ny, (s+os) % TSIZE, ot);
  259. }
  260.     }
  261.     if (dx > 0) {
  262. os += TILESIZE;
  263. if (os >= TSIZE) os -= TSIZE;
  264.     }
  265.     if (dy > 0) {
  266. ot += TILESIZE;
  267. if (ot >= TSIZE) ot -= TSIZE;
  268.     }
  269.     ox = x; oy = y;
  270.     glMatrixMode(GL_TEXTURE);
  271.     glLoadIdentity();
  272.     trx = (float)((x-TILES*TILESIZE/2) % TSIZE)/TSIZE;
  273.     try = (float)((y-TILES*TILESIZE/2) % TSIZE)/TSIZE;
  274.     glTranslatef(trx, try, 0.f);
  275.     glMatrixMode(GL_MODELVIEW);
  276. }
  277. static void
  278. init(char *filename) {
  279.     int i;
  280.     mesh0(-1.f,1.f,-1.f,1.f,0.f,1.f,0.f,1.f,0.f,64,64);
  281.     if (filename) {
  282. image = read_texture(filename, &width, &height, &components);
  283. if (image == NULL) {
  284.     fprintf(stderr, "Error: Can't load image file "%s".n",
  285.     filename);
  286.     exit(EXIT_FAILURE);
  287. } else {
  288.     printf("%d x %d image loadedn", width, height);
  289. }
  290. if (components < 3 || components > 4) {
  291.     printf("must be RGB or RGBA imagen");
  292.     exit(EXIT_FAILURE);
  293. }
  294.     } else {
  295. int i, j;
  296. components = 4; width = height = TSIZE;
  297. image = (unsigned *) malloc(width*height*sizeof(unsigned));
  298. for (j = 0; j < height; j++)
  299.     for (i = 0; i < width; i++) {
  300. if (i & 1)
  301.     image[i+j*width] = 0xff;
  302. else
  303.     image[i+j*width] = 0xff00;
  304. if (j&1)
  305.     image[i+j*width] |= 0xff0000;
  306.     }
  307.     }
  308.     if (width % TILESIZE || height % TILESIZE) {
  309. #define TXSIZE 192
  310. unsigned *newimage = malloc(TXSIZE*TXSIZE*sizeof *newimage);
  311. gluScaleImage(GL_RGBA, width, height, GL_UNSIGNED_BYTE, image,
  312. TXSIZE, TXSIZE, GL_UNSIGNED_BYTE, newimage);
  313. free(image);
  314. image = newimage; width = height = TXSIZE; components = 4;
  315.     }
  316.     tile_image(image);
  317.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  318.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  319.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  320.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  321.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
  322.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
  323.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TSIZE,
  324.                  TSIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  325.     for(i = 0; i < TILES; i++) {
  326. int j;
  327. for(j = 0; j < TILES; j++) {
  328.     glTexSubImage2D(GL_TEXTURE_2D, 0, i*TILESIZE, j*TILESIZE, TILESIZE,
  329.  TILESIZE, GL_RGBA, GL_UNSIGNED_BYTE, 
  330.  tiles[(TILES-TSIZE/TILESIZE)/2+j][(TILES-TSIZE/TILESIZE)/2+i].data);
  331. }
  332.     }
  333.     glEnable(GL_TEXTURE_2D);
  334.     glMatrixMode(GL_PROJECTION);
  335.     glLoadIdentity();
  336.     gluPerspective(90.,1.,.1,10.);
  337.     glMatrixMode(GL_MODELVIEW);
  338.     glLoadIdentity();
  339.     glTranslatef(0.,0.,-1.0);
  340.     glLineWidth(3.0);
  341.     glClearColor(.25, .25, .25, .25);
  342.     /* start at center of image */
  343.     x = TILES*TILESIZE/2;
  344.     y = TILES*TILESIZE/2;
  345. }
  346. void
  347. showgrid(void) {
  348.     GLfloat mat[16];
  349.     int i;
  350.     glPushMatrix();
  351.     glDisable(GL_TEXTURE_2D);
  352.     glPushMatrix();
  353.     glColor3f(0.f, 0.f, 0.f);
  354.     if (!zoom) glScalef(1.f/1.5f, 1.f/1.5f, 1.f);
  355.     glBegin(GL_LINE_LOOP);
  356. glVertex2f(-1.f,-1.f);
  357. glVertex2f(-1.f, 1.f);
  358. glVertex2f( 1.f, 1.f);
  359. glVertex2f( 1.f,-1.f);
  360.     glEnd();
  361.     glPopMatrix();
  362.     glGetFloatv(GL_TEXTURE_MATRIX,mat);
  363.     glPushMatrix();
  364.     if (zoom) glScalef(1.5f,1.5f,1.f);
  365.     glTranslatef(-1.f,-1.f,-1.f);
  366.     glScalef(2.f,2.f,1.f);
  367.     glTranslatef(-mat[12], -mat[13], 1.0f);
  368. #if 1
  369.     glColor3f(1.f,1.f,1.f);
  370. #else
  371.     glColor3f(1.f,0.f,0.f);
  372. #endif
  373.     glBegin(GL_LINES);
  374.     for(i = -TSIZE; i <= 2*TSIZE; i+=TILESIZE) {
  375. GLfloat x = (GLfloat)i/(GLfloat)TSIZE;
  376. glVertex2f(-1.f,x);
  377. glVertex2f(2.f,x);
  378. glVertex2f(x,-1.f);
  379. glVertex2f(x,2.f);
  380.     }
  381.     glEnd();
  382.     glPopMatrix();
  383.     glEnable(GL_TEXTURE_2D);
  384.     glPopMatrix();
  385. }
  386. static void
  387. drawtexture(void) {
  388.     glMatrixMode(GL_TEXTURE);
  389.     glPushMatrix();
  390.     glLoadIdentity();
  391.     glColor3f(1.f,1.f,1.f);
  392.     glBegin(GL_QUADS);
  393. glTexCoord2f(0.f, 0.f); glVertex2f(-1.f, -1.f);
  394. glTexCoord2f(0.f, 1.f); glVertex2f(-1.f,  1.f);
  395. glTexCoord2f(1.f, 1.f); glVertex2f( 1.f,  1.f);
  396. glTexCoord2f(1.f, 0.f); glVertex2f( 1.f, -1.f);
  397.     glEnd();
  398.     glPopMatrix();
  399.     glMatrixMode(GL_MODELVIEW);
  400. }
  401. static void
  402. display(void) {
  403.     glClear(GL_COLOR_BUFFER_BIT);
  404.     loadtiles();
  405.     if (texture) {
  406. drawtexture();
  407.     } else {
  408. drawmesh(64,64);
  409. if (grid) showgrid();
  410.     }
  411.     glutSwapBuffers();
  412. }
  413. static void
  414. reshape(int w, int h) {
  415.     glViewport(0, 0, w, h);
  416. }
  417. /*ARGSUSED1*/
  418. static void
  419. key(unsigned char key, int x, int y) {
  420.     switch(key) {
  421.     case 'h': help(); break;
  422.     case 'g': gfunc(); break;
  423.     case 't': tfunc(); break;
  424.     case 'z': zfunc(); break;
  425.     case 'x': xfunc(); break;
  426.     case 'p': pfunc(); break;
  427.     case '33': exit(EXIT_SUCCESS); break;
  428.     default: break;
  429.     }
  430.     glutPostRedisplay();
  431. }
  432. /*ARGSUSED1*/
  433. static void
  434. special(int key, int x, int y) {
  435.     switch(key) {
  436.     case GLUT_KEY_UP: up(); break;
  437.     case GLUT_KEY_DOWN: down(); break;
  438.     case GLUT_KEY_LEFT: left(); break;
  439.     case GLUT_KEY_RIGHT:right(); break;
  440.     }
  441.     glutPostRedisplay();
  442. }
  443. int main(int argc, char* argv[]) {
  444.     glutInitWindowSize(512, 512);
  445.     glutInit(&argc, argv);
  446.     glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
  447.     (void)glutCreateWindow(argv[0]);
  448.     init(argv[1] ? argv[1] : "../data/fendi.rgb");
  449.     glutDisplayFunc(display);
  450.     glutKeyboardFunc(key);
  451.     glutSpecialFunc(special);
  452.     glutReshapeFunc(reshape);
  453.     glutMainLoop();
  454.     return 0;
  455. }