flightsim.c
来自「飞机飞行界面」· C语言 代码 · 共 1,162 行 · 第 1/3 页
C
1,162 行
if (Position[2] > (0.45 * TERRAIN_SIZE))
{
Position[2] = 0.45 * TERRAIN_SIZE;
Orientation[1] += 10.0 * distance;
}
i = (Position[0] + 0.5 * TERRAIN_SIZE) / TERRAIN_SPACING + 0.5;
j = (0.5 * TERRAIN_SIZE - Position[2]) / TERRAIN_SPACING + 0.5;
if (Position[1] < (5.0 + Terrain[i][j].v[1]))
{
Position[1] = 5.0 + Terrain[i][j].v[1];
Orientation[0] += 5.0 * distance;
}
if (Position[1] > (0.2 * TERRAIN_SIZE))
{
Position[1] = 0.2 * TERRAIN_SIZE;
Orientation[0] -= 5.0 * distance;
}
if (Orientation[0] < -90.0)
{
Orientation[0] = -180.0 - Orientation[0];
Orientation[2] += 180.0;
}
else if (Orientation[0] > 90.0)
{
Orientation[0] = 180.0 - Orientation[0];
Orientation[2] -= 180.0;
}
if (Orientation[1] < 0.0)
Orientation[1] += 360.0;
else if (Orientation[1] > 360.0)
Orientation[1] -= 360.0;
if (Orientation[2] < -180.0)
Orientation[2] += 360.0;
else if (Orientation[2] > 180.0)
Orientation[2] -= 360.0;
/* Update instruments as needed... */
if (fabs(Orientation[0] - Horizon[0]) > 1.0 ||
fabs(Orientation[2] - Horizon[1]) > 1.0)
RedrawHorizon = 1;
if (fabs(Orientation[1] - Compass) > 1.0 &&
fabs(Orientation[1] - Compass) < 359.0)
RedrawCompass = 1;
if (Position[1] != Altimeter)
RedrawAltimeter = 1;
/* Update the frames-per-second value */
FPSTime += distance;
FPSCount ++;
if (FPSCount >= 20)
{
FPS = FPSCount / FPSTime + 0.5;
FPSTime = 0.0;
FPSCount = 0;
}
RedrawAll = -1;
Redraw();
}
/*
* 'Joystick()' - Handle joystick movement.
*/
void
Joystick(unsigned state, /* I - Button state */
int x, /* I - X position (-1000 to 1000) */
int y, /* I - Y position (-1000 to 1000) */
int z) /* I - Z position (-1000 to 1000) */
{
float new_velocity; /* New velocity value */
static int last_state = 0; /* Last button state */
if (last_state != state)
{
/* Button changed state; see what the new state is... */
if (state && !last_state)
{
/* Start flying */
MouseStartX = MouseX = x / 2;
MouseStartY = MouseY = y / 2;
LastTime = GetClock();
glutIdleFunc(Idle);
}
else if (!state && last_state)
{
/* Stop flying */
glutIdleFunc((void (*)(void))0);
}
last_state = state;
}
/* Update the joystick/mouse position */
if (state)
{
MouseX = x / 2;
MouseY = y / 2;
}
if (z > -999)
Velocity = (999 - z) * 0.045 + 10.0;
if (fabs(Velocity - Airspeed) >= 1.0)
RedrawAirspeed = 1;
}
/*
* 'Keyboard()' - Handle key presses...
*/
void
Keyboard(unsigned char key, /* I - Key that was pressed */
int x, /* I - Mouse X position */
int y) /* I - Mouse Y position */
{
switch (key)
{
case 0x1b :
puts("");
exit(0);
break;
case ',' :
if (Velocity > 5.0)
{
RedrawAirspeed = 1;
Velocity -= 5.0;
}
break;
case '.' :
if (Velocity < 100.0)
{
RedrawAirspeed = 1;
Velocity += 5.0;
}
break;
case '<' :
RedrawAirspeed = 1;
Velocity = 10.0;
break;
case '>' :
RedrawAirspeed = 1;
Velocity = 100.0;
break;
case '3' :
ShowTerrain = !ShowTerrain;
break;
case 'l' :
ShowLighting = !ShowLighting;
break;
case 's' :
ShowSky = !ShowSky;
break;
case 't' :
UseTexturing = !UseTexturing;
break;
case 'w' :
ShowWater = !ShowWater;
break;
case 'W' :
if (PolyMode == GL_FILL)
PolyMode = GL_LINE;
else
PolyMode = GL_FILL;
break;
}
glutPostRedisplay();
}
/*
* 'Motion()' - Handle mouse pointer motion.
*/
void
Motion(int x, /* I - Current mouse X position */
int y) /* I - Current mouse Y position */
{
MouseX = x;
MouseY = y;
}
/*
* 'Mouse()' - Handle mouse button events.
*/
void
Mouse(int button, /* I - Button that changed */
int state, /* I - Current button states */
int x, /* I - Current mouse X position */
int y) /* I - Current mouse Y position */
{
if (state == GLUT_DOWN)
{
/* Start flying */
MouseStartX = MouseX = x;
MouseStartY = MouseY = y;
LastTime = GetClock();
glutIdleFunc(Idle);
}
else
{
/* Stop flying */
glutIdleFunc((void (*)(void))0);
}
}
/*
* 'draw_instrument()' - Draws an instrument frame.
*/
void
draw_instrument(int ix, int iy, int isize)
{
float theta; /* Angle for circle */
glColor3f(0.5, 0.5, 0.525);
glBegin(GL_QUADS);
glVertex2i(ix, iy);
glVertex2i(ix + isize - 1, iy);
glVertex2i(ix + isize - 1, iy + isize - 1);
glVertex2i(ix, iy + isize - 1);
glEnd();
glColor3f(0.75, 0.75, 0.788);
glBegin(GL_LINE_STRIP);
glVertex2i(ix, iy);
glVertex2i(ix, iy + isize - 1);
glVertex2i(ix + isize - 1, iy + isize - 1);
glEnd();
glColor3f(0.25, 0.25, 0.262);
glBegin(GL_LINE_STRIP);
glVertex2i(ix, iy);
glVertex2i(ix + isize - 1, iy);
glVertex2i(ix + isize - 1, iy + isize - 1);
glEnd();
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_TRIANGLE_FAN);
glVertex2f(ix + isize * 0.5f, iy + isize * 0.5f);
for (theta = 0.0f; theta < (2.0f * M_PI + M_PI / 18.0f); theta += M_PI / 18.0f)
glVertex2f(ix + isize * 0.5f + cos(theta) * isize * 0.4f,
iy + isize * 0.5f + sin(theta) * isize * 0.4f);
glEnd();
}
/*
* 'Redraw()' - Redraw the window...
*/
void
Redraw(void)
{
int i, j;
int ix, iy, isize;
TP *tp;
float theta, st, ct;
static GLfloat sunpos[4] = { -0.7071, -0.7071, 0.0, 0.0 };
static GLfloat suncolor[4] = { 1.0, 1.0, 0.8, 1.0 };
static GLfloat sunambient[4] = { 0.25, 0.25, 0.2, 1.0 };
static GLfloat s_vector[4] = { 50.0 / TERRAIN_SIZE, 0.0, 0.0, 0.0 };
static GLfloat t_vector[4] = { 0.0, 0.0, 50.0 / TERRAIN_SIZE, 0.0 };
/* Force a full redraw for normal situations; Idle sets it to -1 */
RedrawAll ++;
/* Reset the viewport... */
glViewport(0, 3 * Height / 8, Width, Height - 3 * Height / 8);
glScissor(0, 3 * Height / 8, Width, Height - 3 * Height / 8);
glEnable(GL_SCISSOR_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(22.5, 2.0f * (float)Width / (float)Height, 4.0,
TERRAIN_VIEW);
glMatrixMode(GL_MODELVIEW);
/* Clear the window to light blue... */
if (ShowSky && UseTexturing && PolyMode == GL_FILL)
glClear(GL_DEPTH_BUFFER_BIT);
else
{
glClearColor(0.75, 0.75, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
/* Setup viewing transformations for the current orientation... */
glPushMatrix();
glRotatef((float)ViewAngle, 0.0, 1.0, 0.0);
glRotatef(Orientation[2], 0.0, 0.0, 1.0);
glRotatef(Orientation[0], -1.0, 0.0, 0.0);
glRotatef(Orientation[1], 0.0, 1.0, 0.0);
glTranslatef(0.0, -Position[1], 0.0);
glPolygonMode(GL_FRONT_AND_BACK, PolyMode);
/* Draw the sky */
if (UseTexturing && SkyTexture && ShowSky && PolyMode == GL_FILL)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, SkyTexture);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_TRIANGLE_FAN);
glTexCoord2f(0.5, 0.5);
glVertex3f(0.0, TERRAIN_VIEW, 0.0);
for (theta = 0.0; theta < (2.1 * M_PI); theta += M_PI / 8)
{
ct = cos(theta);
st = sin(theta);
glTexCoord2f(0.5 + 0.3 * ct, 0.5 + 0.3 * st);
glVertex3f(ct * TERRAIN_VIEW * 0.7071,
TERRAIN_VIEW * 0.7071,
st * TERRAIN_VIEW * 0.7071);
}
glEnd();
glBegin(GL_TRIANGLE_STRIP);
for (theta = 0.0; theta < (2.1 * M_PI); theta += M_PI / 8)
{
ct = cos(theta);
st = sin(theta);
glTexCoord2f(0.5 + 0.3 * ct, 0.5 + 0.3 * st);
glVertex3f(ct * TERRAIN_VIEW * 0.7071,
TERRAIN_VIEW * 0.7071,
st * TERRAIN_VIEW * 0.7071);
glTexCoord2f(0.5 + 0.5 * ct, 0.5 + 0.5 * st);
glVertex3f(ct * TERRAIN_VIEW, -100.0,
st * TERRAIN_VIEW);
}
glEnd();
}
/* Setup lighting if needed... */
glEnable(GL_LIGHTING);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, sunambient);
glEnable(GL_COLOR_MATERIAL);
if (ShowLighting)
{
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, sunpos);
glLightfv(GL_LIGHT0, GL_DIFFUSE, suncolor);
glLightfv(GL_LIGHT0, GL_AMBIENT, sunambient);
}
else
glDisable(GL_LIGHT0);
/* Then draw the terrain... */
if (UseTexturing && LandTexture && PolyMode == GL_FILL)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, LandTexture);
}
glTranslatef(-Position[0], 0.0, -Position[2]);
glColor3f(0.3, 0.8, 0.2);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_PLANE, s_vector);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_T, GL_OBJECT_PLANE, t_vector);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
if (ShowTerrain)
{
glEnable(GL_CULL_FACE);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?