📄 perfdraw.c
字号:
/*
* 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -