perfdraw.c

来自「学习c++必备」· C语言 代码 · 共 332 行

C
332
字号
/* * perfdraw.c - $Revision: 1.4 $ */#include <GL/glut.h>#include <math.h>#include <stdio.h>#include "skyfly.h"#if !defined(GL_VERSION_1_1)#if defined(GL_EXT_texture_object)#define glBindTexture(A,B)     glBindTextureEXT(A,B)#define glGenTextures(A,B)     glGenTexturesEXT(A,B)#define glDeleteTextures(A,B)  glDeleteTexturesEXT(A,B)#else#define glBindTexture(A,B)#define glGenTextures(A,B)#define glDeleteTextures(A,B)#endif#endif/* static routine decls */extern int clouds;static void drawlitmesh_11(float *objdata);static void drawcolrtexmesh_10(float *objdata);static void drawclouds(float *objdata);void drawperfobj(perfobj_t *perfobj){    float     *vdata_ptr =(float *) perfobj->vdata;    extern void texenv(int), lightpos(void);    unsigned int *flagsptr = perfobj->flags;    float     *dp;    for (;;) {        switch (*flagsptr) {		/*		 * A paper plane is a single tmesh folded on itself so the orientations		 * of some triangles in the mesh are incorrect with respect to		 * their normals. This is solved by drawing the tmesh twice;		 * first draw only backfaces, then only frontfaces.		 */		case PD_DRAW_PAPER_PLANE:			flagsptr += 1;			glCullFace(GL_FRONT);			drawlitmesh_11(vdata_ptr);			glCullFace(GL_BACK);			drawlitmesh_11((float *)((perfobj_vert_t *) vdata_ptr + 11));			glPopMatrix();			break;		case PD_DRAW_TERRAIN_CELL:			dp = *(float **) (flagsptr + 1);			flagsptr += 2;			drawcolrtexmesh_10(dp);			break;		case PD_DRAW_CLOUDS:                        if (rgbmode) {#if 0                            glColor3ub(0x30, 0x40, 0xb0);#else                            glColor3f(1.0f, 1.0f, 1.0f);#endif                        }			glDisable(GL_CULL_FACE);			glDisable(GL_DEPTH_TEST);			/*texenv(2);*/			drawclouds(vdata_ptr);			glEnable(GL_DEPTH_TEST);			glEnable(GL_CULL_FACE);			flagsptr += 1;			break;		case PD_PAPER_PLANE_MODE:			switch (*(flagsptr + 1)) {			case PLANES_START:                            glShadeModel(GL_FLAT);                            glEnable(GL_LIGHTING);                            glDisable(GL_TEXTURE_2D);                            if (fog && !rgbmode)                                glDisable(GL_FOG);                            break;			case PLANES_END:                            glShadeModel(GL_SMOOTH);                            glDisable(GL_LIGHTING);                            if (fog && !rgbmode && FOG_LEVELS > 1)                                glEnable(GL_FOG);                            break;                        }				flagsptr += 2;			break;		case PD_PAPER_PLANE_POS:        /* contains the pushmatrix */			glPushMatrix();			glTranslatef(*(vdata_ptr), *(vdata_ptr + 1), *(vdata_ptr + 2));			glRotatef(*(vdata_ptr + 3), 0.0, 0.0, 1.0);			glRotatef(*(vdata_ptr + 4), 0.0, 1.0, 0.0);			glRotatef(*(vdata_ptr + 5), 1.0, 0.0, 0.0);			flagsptr += 1;			break;		case PD_VIEWER_POS:			glLoadIdentity();			glRotatef(-90., 1.0, 0., 0.);			glRotatef(*(vdata_ptr + 3) * RAD_TO_DEG, 0.0, 0.0, 1.0); /* yaw */			lightpos();			glTranslatef(-*(vdata_ptr), -*(vdata_ptr + 1), -*(vdata_ptr + 2));			flagsptr += 1;			break;		case PD_TEXTURE_BIND:			glBindTexture(GL_TEXTURE_2D, *(flagsptr + 1));			texenv(*(flagsptr + 1));			glEnable(GL_TEXTURE_2D);			flagsptr += 2;			break;		case PD_END:			return;		default:			fprintf(stderr, "Bad PD primitive %d\n", *flagsptr);			flagsptr++;			break;		}	}}/* * Notice how the following routines unwind loops and pre-compute indexes * at compile time. This is crucial in obtaining the maximum data transfer  * from cpu to the graphics pipe. */static void drawlitmesh_11(float *op){    glBegin(GL_TRIANGLE_STRIP);    /* one */    glNormal3fv((op + PD_V_NORMAL));    glVertex3fv((op + PD_V_POINT));    /* two */    glNormal3fv((op + (PD_V_SIZE + PD_V_NORMAL)));    glVertex3fv((op + (PD_V_SIZE + PD_V_POINT)));    /* three */    glNormal3fv((op + (2 * PD_V_SIZE + PD_V_NORMAL)));    glVertex3fv((op + (2 * PD_V_SIZE + PD_V_POINT)));    /* four */    glNormal3fv((op + (3 * PD_V_SIZE + PD_V_NORMAL)));    glVertex3fv((op + (3 * PD_V_SIZE + PD_V_POINT)));    /* five */    glNormal3fv((op + (4 * PD_V_SIZE + PD_V_NORMAL)));    glVertex3fv((op + (4 * PD_V_SIZE + PD_V_POINT)));    /* six */    glNormal3fv((op + (5 * PD_V_SIZE + PD_V_NORMAL)));    glVertex3fv((op + (5 * PD_V_SIZE + PD_V_POINT)));    /* seven */    glNormal3fv((op + (6 * PD_V_SIZE + PD_V_NORMAL)));    glVertex3fv((op + (6 * PD_V_SIZE + PD_V_POINT)));    /* eight */    glNormal3fv((op + (7 * PD_V_SIZE + PD_V_NORMAL)));    glVertex3fv((op + (7 * PD_V_SIZE + PD_V_POINT)));    /* nine */    glNormal3fv((op + (8 * PD_V_SIZE + PD_V_NORMAL)));    glVertex3fv((op + (8 * PD_V_SIZE + PD_V_POINT)));    /* ten */    glNormal3fv((op + (9 * PD_V_SIZE + PD_V_NORMAL)));    glVertex3fv((op + (9 * PD_V_SIZE + PD_V_POINT)));    /* eleven */    glNormal3fv((op + (10 * PD_V_SIZE + PD_V_NORMAL)));    glVertex3fv((op + (10 * PD_V_SIZE + PD_V_POINT)));	glEnd();}static void drawcolrtexmesh_10(float *op){    glBegin(GL_TRIANGLE_STRIP);	/* one */    glTexCoord2fv((op + PD_V_TEX));    glColor3fv((op + PD_V_COLOR));    glVertex3fv((op + PD_V_POINT));    /* two */    glTexCoord2fv((op + (PD_V_SIZE + PD_V_TEX)));    glColor3fv((op + (PD_V_SIZE + PD_V_COLOR)));    glVertex3fv((op + (PD_V_SIZE + PD_V_POINT)));    /* three */    glTexCoord2fv((op + (2 * PD_V_SIZE + PD_V_TEX)));    glColor3fv((op + (2 * PD_V_SIZE + PD_V_COLOR)));    glVertex3fv((op + (2 * PD_V_SIZE + PD_V_POINT)));    /* four */    glTexCoord2fv((op + (3 * PD_V_SIZE + PD_V_TEX)));    glColor3fv((op + (3 * PD_V_SIZE + PD_V_COLOR)));    glVertex3fv((op + (3 * PD_V_SIZE + PD_V_POINT)));    /* five */    glTexCoord2fv((op + (4 * PD_V_SIZE + PD_V_TEX)));    glColor3fv((op + (4 * PD_V_SIZE + PD_V_COLOR)));    glVertex3fv((op + (4 * PD_V_SIZE + PD_V_POINT)));    /* six */    glTexCoord2fv((op + (5 * PD_V_SIZE + PD_V_TEX)));    glColor3fv((op + (5 * PD_V_SIZE + PD_V_COLOR)));    glVertex3fv((op + (5 * PD_V_SIZE + PD_V_POINT)));    /* seven */    glTexCoord2fv((op + (6 * PD_V_SIZE + PD_V_TEX)));    glColor3fv((op + (6 * PD_V_SIZE + PD_V_COLOR)));    glVertex3fv((op + (6 * PD_V_SIZE + PD_V_POINT)));    /* eight */    glTexCoord2fv((op + (7 * PD_V_SIZE + PD_V_TEX)));    glColor3fv((op + (7 * PD_V_SIZE + PD_V_COLOR)));    glVertex3fv((op + (7 * PD_V_SIZE + PD_V_POINT)));    /* nine */    glTexCoord2fv((op + (8 * PD_V_SIZE + PD_V_TEX)));    glColor3fv((op + (8 * PD_V_SIZE + PD_V_COLOR)));    glVertex3fv((op + (8 * PD_V_SIZE + PD_V_POINT)));    /* ten */    glTexCoord2fv((op + (9 * PD_V_SIZE + PD_V_TEX)));    glColor3fv((op + (9 * PD_V_SIZE + PD_V_COLOR)));    glVertex3fv((op + (9 * PD_V_SIZE + PD_V_POINT)));    glEnd();}static void drawclouds(float *op){#define SKY_STRIPS 24	/* Break into quad strips so cheap fog works better */	if (0 == clouds) {        GLfloat *vc0, *vc1, *vc2;        GLfloat *tc0, *tc1, *tc2;        GLfloat sky_s0, sky_s1, sky_t0, sky_t1;        GLfloat sky_x0, sky_x1, sky_y0, sky_y1, sky_z;        int ii, jj;        GLfloat s0, s1, t0, t1;        GLfloat x0, x1, y0, y1, z0;        vc0 = op + PD_V_POINT;        vc1 = op + PD_V_POINT + PD_V_SIZE;        vc2 = op + PD_V_POINT + PD_V_SIZE * 2;        tc0 = op + PD_V_TEX;        tc1 = op + PD_V_TEX + PD_V_SIZE;        tc2 = op + PD_V_TEX + PD_V_SIZE * 2;        sky_s0 = tc0[0];        sky_s1 = tc1[0];        sky_t0 = tc0[1];        sky_t1 = tc2[1];        sky_x0 = vc0[0];        sky_x1 = vc1[0];        sky_y0 = vc0[1];        sky_y1 = vc2[1];        sky_z  = vc0[2];        clouds = glGenLists(1);        glNewList(clouds, GL_COMPILE);        s1 = (1.0f / SKY_STRIPS) * (sky_s1 - sky_s0);        t1 = (1.0f / SKY_STRIPS) * (sky_t1 - sky_t0);        x1 = (1.0f / SKY_STRIPS) * (sky_x1 - sky_x0);        y1 = (1.0f / SKY_STRIPS) * (sky_y1 - sky_y0);        z0 = sky_z;        s0 = sky_s0;        x0 = sky_x0;        for (ii = 0; ii < SKY_STRIPS; ii++, s0 += s1, x0 += x1) {            t0 = sky_t0;            y0 = sky_y0;            glBegin(GL_QUAD_STRIP);            glTexCoord2f(s0, t0);            glVertex3f(x0, y0, z0);            glTexCoord2f(s0 + s1, t0);            glVertex3f(x0 + x1, y0, z0);            for (jj = 0; jj < SKY_STRIPS; jj++, t0 += t1, y0 += y1) {                glTexCoord2f(s0 + s1, t0 + t1);                glVertex3f(x0 + x1, y0 + y1, z0);                glTexCoord2f(s0, t0 + t1);                glVertex3f(x0, y0 + y1, z0);            }            glEnd();        }        glEndList();    }	glCallList(clouds);}void putv3fdata(float *v, perfobj_vert_t *ptr){  ptr->vert[0] = v[0];  ptr->vert[1] = v[1];  ptr->vert[2] = v[2];}void putc3fdata(float *c, perfobj_vert_t *ptr){  ptr->color[0] = c[0];  ptr->color[1] = c[1];  ptr->color[2] = c[2];}void putn3fdata(float *n, perfobj_vert_t *ptr){  ptr->normal[0] = n[0];  ptr->normal[1] = n[1];  ptr->normal[2] = n[2];}void putt2fdata(float *t, perfobj_vert_t *ptr){  ptr->texture[0] = t[0];  ptr->texture[1] = t[1];}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?