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

GIS编程

开发平台:

Visual C++

  1. /*
  2.  * perfdraw.c - $Revision: 1.4 $
  3.  */
  4. #include <GL/glut.h>
  5. #include <math.h>
  6. #include <stdio.h>
  7. #include "skyfly.h"
  8. #if !defined(GL_VERSION_1_1)
  9. #if defined(GL_EXT_texture_object)
  10. #define glBindTexture(A,B)     glBindTextureEXT(A,B)
  11. #define glGenTextures(A,B)     glGenTexturesEXT(A,B)
  12. #define glDeleteTextures(A,B)  glDeleteTexturesEXT(A,B)
  13. #else
  14. #define glBindTexture(A,B)
  15. #define glGenTextures(A,B)
  16. #define glDeleteTextures(A,B)
  17. #endif
  18. #endif
  19. /* static routine decls */
  20. extern int clouds;
  21. static void drawlitmesh_11(float *objdata);
  22. static void drawcolrtexmesh_10(float *objdata);
  23. static void drawclouds(float *objdata);
  24. void drawperfobj(perfobj_t *perfobj)
  25. {
  26.     float     *vdata_ptr =(float *) perfobj->vdata;
  27.     extern void texenv(int), lightpos(void);
  28.     unsigned int *flagsptr = perfobj->flags;
  29.     float     *dp;
  30.     for (;;) {
  31.         switch (*flagsptr) {
  32. /*
  33.  * A paper plane is a single tmesh folded on itself so the orientations
  34.  * of some triangles in the mesh are incorrect with respect to
  35.  * their normals. This is solved by drawing the tmesh twice;
  36.  * first draw only backfaces, then only frontfaces.
  37.  */
  38. case PD_DRAW_PAPER_PLANE:
  39. flagsptr += 1;
  40. glCullFace(GL_FRONT);
  41. drawlitmesh_11(vdata_ptr);
  42. glCullFace(GL_BACK);
  43. drawlitmesh_11((float *)((perfobj_vert_t *) vdata_ptr + 11));
  44. glPopMatrix();
  45. break;
  46. case PD_DRAW_TERRAIN_CELL:
  47. dp = *(float **) (flagsptr + 1);
  48. flagsptr += 2;
  49. drawcolrtexmesh_10(dp);
  50. break;
  51. case PD_DRAW_CLOUDS:
  52.                         if (rgbmode) {
  53. #if 0
  54.                             glColor3ub(0x30, 0x40, 0xb0);
  55. #else
  56.                             glColor3f(1.0f, 1.0f, 1.0f);
  57. #endif
  58.                         }
  59. glDisable(GL_CULL_FACE);
  60. glDisable(GL_DEPTH_TEST);
  61. /*texenv(2);*/
  62. drawclouds(vdata_ptr);
  63. glEnable(GL_DEPTH_TEST);
  64. glEnable(GL_CULL_FACE);
  65. flagsptr += 1;
  66. break;
  67. case PD_PAPER_PLANE_MODE:
  68. switch (*(flagsptr + 1)) {
  69. case PLANES_START:
  70.                             glShadeModel(GL_FLAT);
  71.                             glEnable(GL_LIGHTING);
  72.                             glDisable(GL_TEXTURE_2D);
  73.                             if (fog && !rgbmode)
  74.                                 glDisable(GL_FOG);
  75.                             break;
  76. case PLANES_END:
  77.                             glShadeModel(GL_SMOOTH);
  78.                             glDisable(GL_LIGHTING);
  79.                             if (fog && !rgbmode && FOG_LEVELS > 1)
  80.                                 glEnable(GL_FOG);
  81.                             break;
  82.                         }
  83. flagsptr += 2;
  84. break;
  85. case PD_PAPER_PLANE_POS:        /* contains the pushmatrix */
  86. glPushMatrix();
  87. glTranslatef(*(vdata_ptr), *(vdata_ptr + 1), *(vdata_ptr + 2));
  88. glRotatef(*(vdata_ptr + 3), 0.0, 0.0, 1.0);
  89. glRotatef(*(vdata_ptr + 4), 0.0, 1.0, 0.0);
  90. glRotatef(*(vdata_ptr + 5), 1.0, 0.0, 0.0);
  91. flagsptr += 1;
  92. break;
  93. case PD_VIEWER_POS:
  94. glLoadIdentity();
  95. glRotatef(-90., 1.0, 0., 0.);
  96. glRotatef(*(vdata_ptr + 3) * RAD_TO_DEG, 0.0, 0.0, 1.0); /* yaw */
  97. lightpos();
  98. glTranslatef(-*(vdata_ptr), -*(vdata_ptr + 1), -*(vdata_ptr + 2));
  99. flagsptr += 1;
  100. break;
  101. case PD_TEXTURE_BIND:
  102. glBindTexture(GL_TEXTURE_2D, *(flagsptr + 1));
  103. texenv(*(flagsptr + 1));
  104. glEnable(GL_TEXTURE_2D);
  105. flagsptr += 2;
  106. break;
  107. case PD_END:
  108. return;
  109. default:
  110. fprintf(stderr, "Bad PD primitive %dn", *flagsptr);
  111. flagsptr++;
  112. break;
  113. }
  114. }
  115. }
  116. /*
  117.  * Notice how the following routines unwind loops and pre-compute indexes
  118.  * at compile time. This is crucial in obtaining the maximum data transfer 
  119.  * from cpu to the graphics pipe.
  120.  */
  121. static void drawlitmesh_11(float *op)
  122. {
  123.     glBegin(GL_TRIANGLE_STRIP);
  124.     /* one */
  125.     glNormal3fv((op + PD_V_NORMAL));
  126.     glVertex3fv((op + PD_V_POINT));
  127.     /* two */
  128.     glNormal3fv((op + (PD_V_SIZE + PD_V_NORMAL)));
  129.     glVertex3fv((op + (PD_V_SIZE + PD_V_POINT)));
  130.     /* three */
  131.     glNormal3fv((op + (2 * PD_V_SIZE + PD_V_NORMAL)));
  132.     glVertex3fv((op + (2 * PD_V_SIZE + PD_V_POINT)));
  133.     /* four */
  134.     glNormal3fv((op + (3 * PD_V_SIZE + PD_V_NORMAL)));
  135.     glVertex3fv((op + (3 * PD_V_SIZE + PD_V_POINT)));
  136.     /* five */
  137.     glNormal3fv((op + (4 * PD_V_SIZE + PD_V_NORMAL)));
  138.     glVertex3fv((op + (4 * PD_V_SIZE + PD_V_POINT)));
  139.     /* six */
  140.     glNormal3fv((op + (5 * PD_V_SIZE + PD_V_NORMAL)));
  141.     glVertex3fv((op + (5 * PD_V_SIZE + PD_V_POINT)));
  142.     /* seven */
  143.     glNormal3fv((op + (6 * PD_V_SIZE + PD_V_NORMAL)));
  144.     glVertex3fv((op + (6 * PD_V_SIZE + PD_V_POINT)));
  145.     /* eight */
  146.     glNormal3fv((op + (7 * PD_V_SIZE + PD_V_NORMAL)));
  147.     glVertex3fv((op + (7 * PD_V_SIZE + PD_V_POINT)));
  148.     /* nine */
  149.     glNormal3fv((op + (8 * PD_V_SIZE + PD_V_NORMAL)));
  150.     glVertex3fv((op + (8 * PD_V_SIZE + PD_V_POINT)));
  151.     /* ten */
  152.     glNormal3fv((op + (9 * PD_V_SIZE + PD_V_NORMAL)));
  153.     glVertex3fv((op + (9 * PD_V_SIZE + PD_V_POINT)));
  154.     /* eleven */
  155.     glNormal3fv((op + (10 * PD_V_SIZE + PD_V_NORMAL)));
  156.     glVertex3fv((op + (10 * PD_V_SIZE + PD_V_POINT)));
  157. glEnd();
  158. }
  159. static void drawcolrtexmesh_10(float *op)
  160. {
  161.     glBegin(GL_TRIANGLE_STRIP);
  162. /* one */
  163.     glTexCoord2fv((op + PD_V_TEX));
  164.     glColor3fv((op + PD_V_COLOR));
  165.     glVertex3fv((op + PD_V_POINT));
  166.     /* two */
  167.     glTexCoord2fv((op + (PD_V_SIZE + PD_V_TEX)));
  168.     glColor3fv((op + (PD_V_SIZE + PD_V_COLOR)));
  169.     glVertex3fv((op + (PD_V_SIZE + PD_V_POINT)));
  170.     /* three */
  171.     glTexCoord2fv((op + (2 * PD_V_SIZE + PD_V_TEX)));
  172.     glColor3fv((op + (2 * PD_V_SIZE + PD_V_COLOR)));
  173.     glVertex3fv((op + (2 * PD_V_SIZE + PD_V_POINT)));
  174.     /* four */
  175.     glTexCoord2fv((op + (3 * PD_V_SIZE + PD_V_TEX)));
  176.     glColor3fv((op + (3 * PD_V_SIZE + PD_V_COLOR)));
  177.     glVertex3fv((op + (3 * PD_V_SIZE + PD_V_POINT)));
  178.     /* five */
  179.     glTexCoord2fv((op + (4 * PD_V_SIZE + PD_V_TEX)));
  180.     glColor3fv((op + (4 * PD_V_SIZE + PD_V_COLOR)));
  181.     glVertex3fv((op + (4 * PD_V_SIZE + PD_V_POINT)));
  182.     /* six */
  183.     glTexCoord2fv((op + (5 * PD_V_SIZE + PD_V_TEX)));
  184.     glColor3fv((op + (5 * PD_V_SIZE + PD_V_COLOR)));
  185.     glVertex3fv((op + (5 * PD_V_SIZE + PD_V_POINT)));
  186.     /* seven */
  187.     glTexCoord2fv((op + (6 * PD_V_SIZE + PD_V_TEX)));
  188.     glColor3fv((op + (6 * PD_V_SIZE + PD_V_COLOR)));
  189.     glVertex3fv((op + (6 * PD_V_SIZE + PD_V_POINT)));
  190.     /* eight */
  191.     glTexCoord2fv((op + (7 * PD_V_SIZE + PD_V_TEX)));
  192.     glColor3fv((op + (7 * PD_V_SIZE + PD_V_COLOR)));
  193.     glVertex3fv((op + (7 * PD_V_SIZE + PD_V_POINT)));
  194.     /* nine */
  195.     glTexCoord2fv((op + (8 * PD_V_SIZE + PD_V_TEX)));
  196.     glColor3fv((op + (8 * PD_V_SIZE + PD_V_COLOR)));
  197.     glVertex3fv((op + (8 * PD_V_SIZE + PD_V_POINT)));
  198.     /* ten */
  199.     glTexCoord2fv((op + (9 * PD_V_SIZE + PD_V_TEX)));
  200.     glColor3fv((op + (9 * PD_V_SIZE + PD_V_COLOR)));
  201.     glVertex3fv((op + (9 * PD_V_SIZE + PD_V_POINT)));
  202.     glEnd();
  203. }
  204. static void drawclouds(float *op)
  205. {
  206. #define SKY_STRIPS 24
  207. /* Break into quad strips so cheap fog works better */
  208. if (0 == clouds) {
  209.         GLfloat *vc0, *vc1, *vc2;
  210.         GLfloat *tc0, *tc1, *tc2;
  211.         GLfloat sky_s0, sky_s1, sky_t0, sky_t1;
  212.         GLfloat sky_x0, sky_x1, sky_y0, sky_y1, sky_z;
  213.         int ii, jj;
  214.         GLfloat s0, s1, t0, t1;
  215.         GLfloat x0, x1, y0, y1, z0;
  216.         vc0 = op + PD_V_POINT;
  217.         vc1 = op + PD_V_POINT + PD_V_SIZE;
  218.         vc2 = op + PD_V_POINT + PD_V_SIZE * 2;
  219.         tc0 = op + PD_V_TEX;
  220.         tc1 = op + PD_V_TEX + PD_V_SIZE;
  221.         tc2 = op + PD_V_TEX + PD_V_SIZE * 2;
  222.         sky_s0 = tc0[0];
  223.         sky_s1 = tc1[0];
  224.         sky_t0 = tc0[1];
  225.         sky_t1 = tc2[1];
  226.         sky_x0 = vc0[0];
  227.         sky_x1 = vc1[0];
  228.         sky_y0 = vc0[1];
  229.         sky_y1 = vc2[1];
  230.         sky_z  = vc0[2];
  231.         clouds = glGenLists(1);
  232.         glNewList(clouds, GL_COMPILE);
  233.         s1 = (1.0f / SKY_STRIPS) * (sky_s1 - sky_s0);
  234.         t1 = (1.0f / SKY_STRIPS) * (sky_t1 - sky_t0);
  235.         x1 = (1.0f / SKY_STRIPS) * (sky_x1 - sky_x0);
  236.         y1 = (1.0f / SKY_STRIPS) * (sky_y1 - sky_y0);
  237.         z0 = sky_z;
  238.         s0 = sky_s0;
  239.         x0 = sky_x0;
  240.         for (ii = 0; ii < SKY_STRIPS; ii++, s0 += s1, x0 += x1) {
  241.             t0 = sky_t0;
  242.             y0 = sky_y0;
  243.             glBegin(GL_QUAD_STRIP);
  244.             glTexCoord2f(s0, t0);
  245.             glVertex3f(x0, y0, z0);
  246.             glTexCoord2f(s0 + s1, t0);
  247.             glVertex3f(x0 + x1, y0, z0);
  248.             for (jj = 0; jj < SKY_STRIPS; jj++, t0 += t1, y0 += y1) {
  249.                 glTexCoord2f(s0 + s1, t0 + t1);
  250.                 glVertex3f(x0 + x1, y0 + y1, z0);
  251.                 glTexCoord2f(s0, t0 + t1);
  252.                 glVertex3f(x0, y0 + y1, z0);
  253.             }
  254.             glEnd();
  255.         }
  256.         glEndList();
  257.     }
  258. glCallList(clouds);
  259. }
  260. void putv3fdata(float *v, perfobj_vert_t *ptr)
  261. {
  262.   ptr->vert[0] = v[0];
  263.   ptr->vert[1] = v[1];
  264.   ptr->vert[2] = v[2];
  265. }
  266. void putc3fdata(float *c, perfobj_vert_t *ptr)
  267. {
  268.   ptr->color[0] = c[0];
  269.   ptr->color[1] = c[1];
  270.   ptr->color[2] = c[2];
  271. }
  272. void putn3fdata(float *n, perfobj_vert_t *ptr)
  273. {
  274.   ptr->normal[0] = n[0];
  275.   ptr->normal[1] = n[1];
  276.   ptr->normal[2] = n[2];
  277. }
  278. void putt2fdata(float *t, perfobj_vert_t *ptr)
  279. {
  280.   ptr->texture[0] = t[0];
  281.   ptr->texture[1] = t[1];
  282. }