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

GIS编程

开发平台:

Visual C++

  1. /* Copyright (c) Mark J. Kilgard, 1997. */
  2. /* This program is freely distributable without licensing fees  and is
  3.    provided without guarantee or warrantee expressed or  implied. This
  4.    program is -not- in the public domain. */
  5. /* X compile line: cc -o txfdemo txfdemo.c -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm */
  6. #include <math.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <stdio.h>
  10. #include <GL/glut.h>
  11. #include "TexFont.h"
  12. /* Uncomment to debug various scenarios. */
  13. #if 0
  14. #undef GL_VERSION_1_1
  15. #undef GL_EXT_polygon_offset
  16. #endif
  17. #ifndef GL_VERSION_1_1
  18. #ifdef GL_EXT_polygon_offset
  19. #define GL_POLYGON_OFFSET_FILL GL_POLYGON_OFFSET_EXT
  20. #define glPolygonOffset(s,b) glPolygonOffsetEXT(s,b*0.001);
  21. #else
  22. /* Gag.  No polygon offset?  Artifacts will exist. */
  23. #define glPolygonOffset(s,b) /* nothing */
  24. #endif
  25. #endif
  26. #ifndef M_PI
  27. #define M_PI            3.14159265358979323846
  28. #endif
  29. static int doubleBuffer = 1;
  30. static char *filename = "rockfont.txf";
  31. static GLfloat angle = 20;
  32. static TexFont *txf;
  33. static int usePolygonOffset = 1;
  34. static int animation = 1;
  35. static int fullscreen = 0;
  36. void
  37. idle(void)
  38. {
  39.   angle += 4;
  40.   glutPostRedisplay();
  41. }
  42. void 
  43. visible(int vis)
  44. {
  45.   if (vis == GLUT_VISIBLE) {
  46.     if (animation) {
  47.       glutIdleFunc(idle);
  48.     }
  49.   } else {
  50.     glutIdleFunc(NULL);
  51.   }
  52. }
  53. void reshape(int w, int h)
  54. {
  55.    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
  56.    glMatrixMode(GL_PROJECTION);
  57.    glLoadIdentity();
  58.    gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
  59.    glMatrixMode(GL_MODELVIEW);
  60. }
  61. void
  62. cubeSide(void)
  63. {
  64.   glDisable(GL_TEXTURE_2D);
  65.   glDisable(GL_BLEND);
  66.   glDisable(GL_ALPHA_TEST);
  67.   glColor3f(0.3, 0.7, 0.3);
  68.   glRectf(-1.0, -1.0, 1.0, 1.0);
  69. }
  70. int alphaMode;
  71. void
  72. alphaModeSet(void)
  73. {
  74.   switch (alphaMode) {
  75.   case GL_ALPHA_TEST:
  76.     glDisable(GL_BLEND);
  77.     glEnable(GL_ALPHA_TEST);
  78.     glAlphaFunc(GL_GEQUAL, 0.5);
  79.     break;
  80.   case GL_BLEND:
  81.     glDisable(GL_ALPHA_TEST);
  82.     glEnable(GL_BLEND);
  83.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  84.     break;
  85.   case GL_ALPHA_TEST + GL_BLEND:
  86.     glEnable(GL_ALPHA_TEST);
  87.     glAlphaFunc(GL_GEQUAL, 0.0625);
  88.     glEnable(GL_BLEND);
  89.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  90.     break;
  91.   case GL_NONE:
  92.     glDisable(GL_ALPHA_TEST);
  93.     glDisable(GL_BLEND);
  94.     break;
  95.   }
  96. }
  97. void
  98. cubeSideWithOpenGLcircle(void)
  99. {
  100.   int w, ow, a, d;
  101.   char *text;
  102.   int len;
  103.   int i;
  104.   GLfloat flen;
  105.   cubeSide();
  106.   glPushMatrix();
  107.     alphaModeSet();
  108.     glEnable(GL_TEXTURE_2D);
  109.     if (usePolygonOffset) {
  110. #if defined(GL_EXT_polygon_offset) || defined(GL_VERSION_1_1)
  111.       glEnable(GL_POLYGON_OFFSET_FILL);
  112.       glPolygonOffset(0.0, -3);
  113. #endif
  114.     }
  115.     glColor3f(0.2, 0.2, 0.9);
  116.     txfGetStringMetrics(txf, "OpenGL", 6, &w, &a, &d);
  117.     text = "OpenGL OpenGL ";
  118.     len = (int) strlen(text);
  119.     txfGetStringMetrics(txf, text, len, &w, &a, &d);
  120.     txfGetStringMetrics(txf, "O", 1, &ow, &a, &d);
  121.     glScalef(5.6/w, 5.6/w, 5.6/w);
  122.     flen = len;
  123.     glTranslatef(-ow/2.0, -w/(M_PI*2.0), 0.0);
  124.     for (i=0; i<len; i++) {
  125.       if (text[i] == 'L' && usePolygonOffset) {
  126. /* Hack.  The "L" in OpenGL slightly overlaps the "G". Slightly
  127.    raise the "L" so that it will overlap the "G" in the depth
  128.    buffer to avoid a double blend.. */
  129.         glPolygonOffset(0.0, -4);
  130.         txfRenderGlyph(txf, text[i]);
  131.         glPolygonOffset(0.0, -3);
  132.       } else {
  133.         txfRenderGlyph(txf, text[i]);
  134.       }
  135.       glRotatef(360.0/flen, 0, 0, 1);
  136.     }
  137.     if (usePolygonOffset) {
  138. #if defined(GL_EXT_polygon_offset) || defined(GL_VERSION_1_1)
  139.       glDisable(GL_POLYGON_OFFSET_FILL);
  140. #endif
  141.     }
  142.   glPopMatrix();
  143. }
  144. void
  145. cubeSideWithText(char *text, int len)
  146. {
  147.   int w, a, d;
  148.   cubeSide();
  149.   glPushMatrix();
  150.     glEnable(GL_TEXTURE_2D);
  151.     alphaModeSet();
  152.     if (usePolygonOffset) {
  153. #if defined(GL_EXT_polygon_offset) || defined(GL_VERSION_1_1)
  154.       glEnable(GL_POLYGON_OFFSET_FILL);
  155.       glPolygonOffset(0.0, -3);
  156. #endif
  157.     }
  158.     glColor3f(0.2, 0.2, 0.9);
  159.     txfGetStringMetrics(txf, text, len, &w, &a, &d);
  160.     glScalef(1.8/w, 1.8/w, 1.8/w);
  161.     glTranslatef(-w/2.0, d-(a+d)/2.0, 0.0);
  162.     txfRenderFancyString(txf, text, len);
  163.     if (usePolygonOffset) {
  164. #if defined(GL_EXT_polygon_offset) || defined(GL_VERSION_1_1)
  165.       glDisable(GL_POLYGON_OFFSET_FILL);
  166. #endif
  167.     }
  168.   glPopMatrix();
  169. }
  170. void
  171. display(void)
  172. {
  173.   char *str;
  174.   /* Clear the color buffer. */
  175.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  176.   glPushMatrix();
  177.   glRotatef(-angle, 0, 1, 0);
  178.   glPushMatrix();
  179.     glTranslatef(0.0, 0.0, 1.0);
  180.     cubeSideWithOpenGLcircle();
  181.   glPopMatrix();
  182.   glPushMatrix();
  183.     glRotatef(90.0, 0, 1, 0);
  184.     glTranslatef(0.0, 0.0, 1.0);
  185.     str = "MAkes";
  186.     cubeSideWithText(str, (int) strlen(str));
  187.   glPopMatrix();
  188.   glPushMatrix();
  189.     glRotatef(180.0, 0, 1, 0);
  190.     glTranslatef(0.0, 0.0, 1.0);
  191.     str = "Text";
  192.     cubeSideWithText(str, (int) strlen(str));
  193.   glPopMatrix();
  194.   glPushMatrix();
  195.     glRotatef(270.0, 0, 1, 0);
  196.     glTranslatef(0.0, 0.0, 1.0);
  197.     str = "33T377000000003773D";
  198.     cubeSideWithText(str, 10);
  199.   glPopMatrix();
  200.   glPopMatrix();
  201.   /* Swap the buffers if necessary. */
  202.   if (doubleBuffer) {
  203.     glutSwapBuffers();
  204.   }
  205. }
  206. int savex;
  207. /* ARGSUSED23 */
  208. void
  209. mouse(int button, int state, int x, int y)
  210. {
  211.   if (button == GLUT_LEFT_BUTTON) {
  212.     if (state == GLUT_DOWN) {
  213.       glutIdleFunc(NULL);
  214.       savex = x;
  215.     } else {
  216.       if (animation)
  217.         glutIdleFunc(idle);
  218.     }
  219.   }
  220. }
  221. /* ARGSUSED1 */
  222. void
  223. motion(int x, int y)
  224. {
  225.   angle += (savex - x);
  226.   savex = x;
  227.   glutPostRedisplay();
  228. }
  229. int minifyMenu;
  230. void
  231. minifySelect(int value)
  232. {
  233.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, value);
  234.   glutPostRedisplay();
  235. }
  236. int alphaMenu;
  237. void
  238. alphaSelect(int value)
  239. {
  240.   alphaMode = value;
  241.   glutPostRedisplay();
  242. }
  243. int polygonOffsetMenu;
  244. void
  245. polygonOffsetSelect(int value)
  246. {
  247.   usePolygonOffset = value;
  248.   glutPostRedisplay();
  249. }
  250. int animationMenu;
  251. void
  252. animationSelect(int value)
  253. {
  254.   animation = value;
  255.   if (animation) {
  256.     glutIdleFunc(idle);
  257.   } else {
  258.     glutIdleFunc(NULL);
  259.   }
  260. }
  261. /* ARGSUSED1 */
  262. void
  263. keyboard(unsigned char c, int x, int y)
  264. {
  265.   switch(c) {
  266.   case 27:
  267.     exit(0);
  268.     break;
  269.   case ' ':
  270.     animation = 1 - animation;
  271.     if (animation) {
  272.       glutIdleFunc(idle);
  273.     } else  {
  274.       glutIdleFunc(NULL);
  275.     }
  276.     break;
  277.   }
  278. }
  279. void
  280. mainSelect(int value)
  281. {
  282.   if (value == 666) {
  283.     exit(0);
  284.   }
  285. }
  286. int
  287. main(int argc, char **argv)
  288. {
  289.   int i;
  290.   glutInit(&argc, argv);
  291.   for (i = 1; i < argc; i++) {
  292.     if (!strcmp(argv[i], "-sb")) {
  293.       doubleBuffer = 0;
  294.     } else if (!strcmp(argv[i], "-fullscreen")) {
  295.       fullscreen = 1;
  296.     } else {
  297.       filename = argv[i];
  298.     }
  299.   }
  300.   if (filename == NULL) {
  301.     fprintf(stderr, "usage: txfdemo [GLUT-options] [-sb] txf-filen");
  302.     exit(1);
  303.   }
  304.   txf = txfLoadFont(filename);
  305.   if (txf == NULL) {
  306.     fprintf(stderr, "Problem loading %s, %sn", filename, txfErrorString());
  307.     exit(1);
  308.   }
  309.   if (doubleBuffer) {
  310.     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
  311.   } else {
  312.     glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
  313.   }
  314.   glutInitWindowSize(300, 300);
  315.   if (fullscreen) {
  316.     glutGameModeString("640x480:16@60");
  317.     glutEnterGameMode();
  318.   } else {
  319.     glutCreateWindow("txfdemo");
  320.   }
  321.   glutDisplayFunc(display);
  322.   glutMouseFunc(mouse);
  323.   glutMotionFunc(motion);
  324.   glutKeyboardFunc(keyboard);
  325.   glutVisibilityFunc(visible);
  326.   glutReshapeFunc(reshape);
  327.   glMatrixMode(GL_PROJECTION);
  328.   glLoadIdentity();
  329.   gluPerspective(60.0, 1.0, 0.1, 20.0);
  330.   glMatrixMode(GL_MODELVIEW);
  331.   gluLookAt(0.0, 0.0, 4.0,
  332.     0.0, 0.0, 0.0,
  333.     0.0, 1.0, 0.0);
  334.   /* Use a gray background so the teximage with black backgrounds will show
  335.      against showtxf's background. */
  336.   glClearColor(0.0, 0.0, 0.0, 0.0);
  337.   glEnable(GL_DEPTH_TEST);
  338.   glEnable(GL_CULL_FACE);
  339.   alphaSelect(GL_ALPHA_TEST);
  340.   minifySelect(GL_NEAREST);
  341.   txfEstablishTexture(txf, 1, GL_TRUE);
  342.   if (!fullscreen) {
  343.     minifyMenu = glutCreateMenu(minifySelect);
  344.     glutAddMenuEntry("Nearest", GL_NEAREST);
  345.     glutAddMenuEntry("Linear", GL_LINEAR);
  346.     glutAddMenuEntry("Nearest mipmap nearest", GL_NEAREST_MIPMAP_NEAREST);
  347.     glutAddMenuEntry("Linear mipmap nearest", GL_LINEAR_MIPMAP_NEAREST);
  348.     glutAddMenuEntry("Nearest mipmap linear", GL_NEAREST_MIPMAP_LINEAR);
  349.     glutAddMenuEntry("Linear mipmap linear", GL_LINEAR_MIPMAP_LINEAR);
  350.     alphaMenu = glutCreateMenu(alphaSelect);
  351.     glutAddMenuEntry("Alpha testing", GL_ALPHA_TEST);
  352.     glutAddMenuEntry("Alpha blending", GL_BLEND);
  353.     glutAddMenuEntry("Both", GL_ALPHA_TEST + GL_BLEND);
  354.     glutAddMenuEntry("Nothing", GL_NONE);
  355.     polygonOffsetMenu = glutCreateMenu(polygonOffsetSelect);
  356.     glutAddMenuEntry("Enable", 1);
  357.     glutAddMenuEntry("Disable", 0);
  358.     animationMenu = glutCreateMenu(animationSelect);
  359.     glutAddMenuEntry("Start", 1);
  360.     glutAddMenuEntry("Stop", 0);
  361.     glutCreateMenu(mainSelect);
  362.     glutAddSubMenu("Filtering", minifyMenu);
  363.     glutAddSubMenu("Alpha", alphaMenu);
  364.     glutAddSubMenu("Polygon Offset", polygonOffsetMenu);
  365.     glutAddSubMenu("Animation", animationMenu);
  366.     glutAddMenuEntry("Quit", 666);
  367.     glutAttachMenu(GLUT_RIGHT_BUTTON);
  368.   }
  369. #if !defined(GL_EXT_polygon_offset) && !defined(GL_VERSION_1_1)
  370.   fprintf(stderr, "Warning: polygon offset not available; artifacts will results.n");
  371. #endif
  372.   glutMainLoop();
  373.   return 0;             /* ANSI C requires main to return int. */
  374. }