📄 terrain3dtestview.cpp
字号:
if(nChar==49) // 按下'1'键
{
_Throttle = 1;
}
if(nChar==50) // 按下'2'键
{
_Throttle = 2;
}
if(nChar==51) // 按下'3'键
{
_Throttle = 3;
}
if(nChar==52) // 按下'4'键
{
_Throttle = 4;
}
if(nChar==53) // 按下'5'键
{
_Throttle = 5;
}
if(nChar==54) // 按下'6'键
{
_Throttle = 6;
}
if(nChar==55) // 按下'7'键
{
_Throttle = 7;
}
if(nChar==56) // 按下'8'键
{
_Throttle = 8;
}
if(nChar==57) // 按下'9'键
{
_Throttle = 9;
}
if(nChar==48) // 按下'0'键
{
_Throttle = 15;
}
if(nChar==VK_UP)
{
pitch -= 15 / (ABS(Speed)+1);
}
if(nChar==VK_DOWN)
{
pitch += 15 / (ABS(Speed)+1);
}
if(nChar==VK_LEFT)
{
zprot += 5/(ABS(Speed)+1);
Throttle*=.99;
}
if(nChar==VK_RIGHT)
{
zprot -= 5/(ABS(Speed)+1);
Throttle*=.99;
}
if (Throttle == 15)
{
Afterburner = true;
}
else
{
Afterburner = false;
}
if(nChar==76||nChar==108) // 按下'L'键
{
water=!water;
}
if(nChar==87||nChar==119) // 按下'W'键
{
wireframe=!wireframe;
}
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
bool CTerrain3DTestView::InitTerrain(GLvoid)
{
int i,i2;
field[0][0].y=(GLfloat(rand()%100)-50)/3;
// 生成地形数据
for (i = 0; i < MAX; i++)
{
for (i2 = 0; i2 < MAX; i2++)
{
if (i<10 || i2<10 || i>MAX-10 || i2>MAX-10)
field[i][i2].y=0;
else
field[i][i2].y=(GLfloat(rand()%151)-75)/50+(field[i-1][i2-1].y+field[i-1][i2].y+field[i-1][i2+1].y+field[i-1][i2-2].y+field[i-1][i2+2].y)/5.05; //Calculate the y coordinate on the same principle.
}
}
// 地形光滑处理
for (int cnt = 0; cnt < 3; cnt++)
{
for (int t = 1; t < MAX-1; t++)
{
for (int t2 = 1; t2 < MAX-1; t2++)
{
field[t][t2].y = (field[t+1][t2].y+field[t][t2-1].y+field[t-1][t2].y+field[t][t2+1].y)/4;
if (cnt == 0)
{
if (field[t][t2].y < -1 && field[t][t2].y > -1-.5)
field[t][t2].y -= .45, field[t][t2].y *= 2;
else if (field[t][t2].y > -1 && field[t][t2].y < -1+.5)
field[t][t2].y += .5, field[t][t2].y /= 5;
}
}
}
}
return true;
}
bool CTerrain3DTestView::InitSmoke(GLvoid)
{
// 粒子系统的初始化
for (loop=0;loop<MAX_PARTICLES;loop++)
{
particle[loop].active=true; // 使所有的粒子激活
particle[loop].life=1.0f; // 给予新的生命
particle[loop].fade=GLfloat(rand()%100)/7500 + 0.0075f; // 随机淡化数值
if (loop < MAX_PARTICLES/2)
particle[loop].x= .75f;
else
particle[loop].x= -.75f;
particle[loop].y= -.15; // Center On Y Axis
particle[loop].z= 3; // Center On Z Axis
V = (GLfloat((rand()%5))+2)/5;
Angle = GLfloat(rand()%360);
particle[loop].zg = .15;
particle[loop].xi = sin(Angle) * V;
particle[loop].yi = cos(Angle) * V;
particle[loop].zi = ((rand()%10)-5)/5;
}
return true;
}
bool CTerrain3DTestView::DrawWireframe(GLvoid)
{
int i;
int i2;
int t, t2;
glDisable(GL_TEXTURE_2D);
glColor4f(0.0f,0.0f,0.0f,1.0f);
for (t = xrange1; t < xrange2; t+=quality)
{
for (t2 = zrange1; t2 < zrange2; t2+=quality)
{
i = t;
i2 = t2;
while (i < 0) i += MAX;
while (i > MAX) i -= MAX;
while (i2 < 0) i2 += MAX;
while (i2 > MAX) i2 -= MAX;
int coord=t-MAX;
int coord2=t2-MAX;
glBegin(GL_LINE_LOOP);
glVertex3f(coord,field[i][i2].y,coord2);
glVertex3f(coord+quality,field[i+quality][i2].y,coord2);
glVertex3f(coord+quality,field[i+quality][i2+quality].y,coord2+quality);
glVertex3f(coord,field[i][i2+quality].y,coord2+quality);
glVertex3f(coord+quality,field[i+quality][i2].y,coord2);
glEnd();
}
}
glEnable(GL_TEXTURE_2D);
glLoadIdentity();
glTranslatef(0,-.5f,-10);
glRotatef(yaw,0,1,0);
glRotatef(zprot*15,0,0,1);
glRotatef(pitch,1,0,0);
glEnable(GL_LIGHTING);
glCallList(MODEL); // 绘制飞机模型
glDisable(GL_LIGHTING);
return true;
}
bool CTerrain3DTestView::DrawTexture(GLvoid)
{
DrawTerrain(); // 绘制地形
DrawSky(); // 绘制天空
if(water)
{
DrawWater(); // 绘制水
}
DrawPlane(); // 绘制飞机及其尾焰
DrawSun(); // 绘制太阳
return true;
}
bool CTerrain3DTestView::DrawWater(GLvoid)
{
glEnable(GL_BLEND);
glLoadIdentity();
glTranslatef(0,0,-10);
glRotatef(sceneroty,0,1,0);
glTranslatef(xtrans,ytrans-3.5-ABS(Speed)/5,ztrans);
glBindTexture(GL_TEXTURE_2D, texture[6]);
glColor4f(1,1,1,.35f);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(xtexa2,ytexa2); glVertex3f(xrange2-MAX,-1,zrange2-MAX);
glTexCoord2f(xtexa2,ytexa); glVertex3f(xrange2-MAX,-1,zrange1-MAX);
glTexCoord2f(xtexa,ytexa2); glVertex3f(xrange1-MAX,-1,zrange2-MAX);
glTexCoord2f(xtexa,ytexa); glVertex3f(xrange1-MAX,-1,zrange1-MAX);
glEnd();
glDisable(GL_BLEND);
return true;
}
bool CTerrain3DTestView::DrawSun(GLvoid)
{
float sun_flare_size;
sun_flare_size = 5000;
glColor4f(1,.5f,0,.5f);
glBegin(GL_TRIANGLE_STRIP); // Build Quad From A Triangle Strip
glTexCoord2f(1,1); glVertex3f(MAX/2+sun_flare_size,sun_height+sun_flare_size,sun_zdistance); // Top Right
glTexCoord2f(0,1); glVertex3f(MAX/2-sun_flare_size,sun_height+sun_flare_size,sun_zdistance); // Top Left
glTexCoord2f(1,0); glVertex3f(MAX/2+sun_flare_size,sun_height-sun_flare_size,sun_zdistance); // Bottom Right
glTexCoord2f(0,0); glVertex3f(MAX/2-sun_flare_size,sun_height-sun_flare_size,sun_zdistance); // Bottom Left
glEnd(); // Done Building Triangle Strip
sun_flare_size = 500;
glColor4f(1,.5f,0,1);
glBegin(GL_TRIANGLE_STRIP); // Build Quad From A Triangle Strip
glTexCoord2f(1,1); glVertex3f(MAX/2+sun_flare_size,sun_height+sun_flare_size,sun_zdistance); // Top Right
glTexCoord2f(0,1); glVertex3f(MAX/2-sun_flare_size,sun_height+sun_flare_size,sun_zdistance); // Top Left
glTexCoord2f(1,0); glVertex3f(MAX/2+sun_flare_size,sun_height-sun_flare_size,sun_zdistance); // Bottom Right
glTexCoord2f(0,0); glVertex3f(MAX/2-sun_flare_size,sun_height-sun_flare_size,sun_zdistance); // Bottom Left
glEnd(); // Done Building Triangle Strip
return true;
}
bool CTerrain3DTestView::DrawPlane(GLvoid)
{
glColor4f(1,1,1,1);
glLoadIdentity();
glTranslatef(0,-.5f,-10);
glRotatef(yaw,0,1,0);
glRotatef(zprot*15,0,0,1);
glRotatef(pitch,1,0,0);
glEnable(GL_LIGHTING);
glCallList(MODEL); // 绘制飞机模型
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glEnable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glBindTexture(GL_TEXTURE_2D,texture[5]);
GLfloat exhaust_r, exhaust_g, exhaust_b;
if (Afterburner)
{
exhaust_r = 1;
exhaust_g = .5f;
exhaust_b = 0;
}
else
{
exhaust_r = .5f;
exhaust_g = .5f;
exhaust_b = 1;
}
glowp += .5f-glow;
glow += glowp*(ABS(Throttle)/500);
if (glow > 1) glow = 1;
else if (glow < .25f) glow = .25f;
glColor4f(exhaust_r,exhaust_g,exhaust_b,glow);
float glowsize = 1;
for (float glowpos = 3; glowpos <= 3.25f; glowpos+=.25f)
{
glowsize -= .175f;
glBegin(GL_TRIANGLE_STRIP); // Build Quad From A Triangle Strip
glTexCoord2f(1,1); glVertex3f(.52+glowsize,-.8f+glowsize,glowpos); // Top Right
glTexCoord2f(0,1); glVertex3f(.52-glowsize,-.8f+glowsize,glowpos); // Top Left
glTexCoord2f(1,0); glVertex3f(.52+glowsize,-.8f-glowsize,glowpos); // Bottom Right
glTexCoord2f(0,0); glVertex3f(.52-glowsize,-.8f-glowsize,glowpos); // Bottom Left
glEnd(); // Done Building Triangle Strip
glBegin(GL_TRIANGLE_STRIP); // Build Quad From A Triangle Strip
glTexCoord2f(1,1); glVertex3f(-.52+glowsize,-.8f+glowsize,glowpos); // Top Right
glTexCoord2f(0,1); glVertex3f(-.52-glowsize,-.8f+glowsize,glowpos); // Top Left
glTexCoord2f(1,0); glVertex3f(-.52+glowsize,-.8f-glowsize,glowpos); // Bottom Right
glTexCoord2f(0,0); glVertex3f(-.52-glowsize,-.8f-glowsize,glowpos); // Bottom Left
glEnd(); // Done Building Triangle Strip
}
for (loop=0;loop<MAX_PARTICLES;loop++) // Loop Through All The Particles
{
GLfloat x=particle[loop].x; // Grab Our Particle X Position
GLfloat y=particle[loop].y; // Grab Our Particle Y Position
GLfloat z=particle[loop].z; // Particle Z Pos + Zoom
glColor4f(particle[loop].r,particle[loop].g,particle[loop].b,particle[loop].life/2);
glBegin(GL_TRIANGLE_STRIP); // Build Quad From A Triangle Strip
glTexCoord2f(1,1); glVertex3f(x+0.1f,y+0.1f,z); // Top Right
glTexCoord2f(0,1); glVertex3f(x-0.1f,y+0.1f,z); // Top Left
glTexCoord2f(1,0); glVertex3f(x+0.1f,y-0.1f,z); // Bottom Right
glTexCoord2f(0,0); glVertex3f(x-0.1f,y-0.1f,z); // Bottom Left
glEnd(); // Done Building Triangle Strip
particle[loop].x+=particle[loop].xi/250;// Move On The X Axis By X Speed
particle[loop].y+=particle[loop].yi/250;// Move On The Y Axis By Y Speed
particle[loop].z+=particle[loop].zi/250;// Move On The Z Axis By Z Speed
particle[loop].xi*=.975f;
particle[loop].yi*=.975f;
particle[loop].zi*=.975f;
particle[loop].zi+=particle[loop].zg; // Take Pull On Z Axis Into Account
particle[loop].life-=particle[loop].fade*3; // Reduce Particles Life By 'Fade'
if (particle[loop].life < .5f)
particle[loop].life*=.975;
if (particle[loop].life<0.05f) // If Particle Is Burned Out
{
particle[loop].r=exhaust_r;
particle[loop].g=exhaust_g;
particle[loop].b=exhaust_b;
particle[loop].life=1.0f; // Give It New Life
particle[loop].fade=GLfloat(rand()%100)/2500 + 0.02f; // Random Fade Value
if (loop < MAX_PARTICLES/2)
particle[loop].x= .52f;
else
particle[loop].x= -.52f;
particle[loop].y= -.8f;
particle[loop].z= 3.f;
V = (GLfloat((rand()%5))+2)/5;
Angle = GLfloat(rand()%360);
particle[loop].xi = sin(Angle) * V;
particle[loop].yi = cos(Angle) * V;
particle[loop].zi = ((rand()%10)-5)/5 + Throttle*4;
}
}
glDisable(GL_FOG);
glLoadIdentity();
glRotatef(sceneroty,0,1,0);
return true;
}
bool CTerrain3DTestView::DrawTerrain(GLvoid)
{
int i;
int i2;
int t, t2;
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glColor4f(1,1,1,1);
glBindTexture(GL_TEXTURE_2D, texture[0]);
for (t = xrange1; t < xrange2; t+=quality)
{
for (t2 = zrange1; t2 < zrange2; t2+=quality)
{
i = t;
i2 = t2;
while (i < 0) i += MAX;
while (i > MAX) i -= MAX;
while (i2 < 0) i2 += MAX;
while (i2 > MAX) i2 -= MAX;
xtexa = (GLfloat(i)/MAX)*57;
xtexa2 = (GLfloat(i+quality)/MAX)*57;
ytexa = (GLfloat(i2)/MAX)*57;
ytexa2 = (GLfloat(i2+quality)/MAX)*57;
int coord=t-MAX;
int coord2=t2-MAX;
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(xtexa2,ytexa2); glVertex3f(coord+quality,field[i+quality][i2+quality].y, coord2+quality);
glTexCoord2f(xtexa2,ytexa); glVertex3f(coord+quality,field[i+quality][i2].y,coord2);
glTexCoord2f(xtexa,ytexa2); glVertex3f(coord,field[i][i2+quality].y,coord2+quality);
glTexCoord2f(xtexa,ytexa); glVertex3f(coord,field[i][i2].y,coord2);
glEnd();
}
}
glEnable(GL_BLEND);
glBlendFunc(GL_DST_COLOR, GL_ZERO);
// 第二次绘制地形(多重纹理)
glBindTexture(GL_TEXTURE_2D, texture[2]);
glColor4f(1,1,1,.5f);
for (t = xrange1; t < xrange2; t+=quality)
{
for (t2 = zrange1; t2 < zrange2; t2+=quality)
{
i = t;
i2 = t2;
while (i < 0) i += MAX;
while (i > MAX) i -= MAX;
while (i2 < 0) i2 += MAX;
while (i2 > MAX) i2 -= MAX;
xtexa = (GLfloat(i)/MAX)*1;
xtexa2 = (GLfloat(i+quality)/MAX)*1;
ytexa = (GLfloat(i2)/MAX)*1;
ytexa2 = (GLfloat(i2+quality)/MAX)*1;
int coord=t-MAX;
int coord2=t2-MAX;
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(xtexa2,ytexa2); glVertex3f(coord+quality,field[i+quality][i2+quality].y, coord2+quality);
glTexCoord2f(xtexa2,ytexa); glVertex3f(coord+quality,field[i+quality][i2].y,coord2);
glTexCoord2f(xtexa,ytexa2); glVertex3f(coord,field[i][i2+quality].y,coord2+quality);
glTexCoord2f(xtexa,ytexa); glVertex3f(coord,field[i][i2].y,coord2);
glEnd();
}
}
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_BLEND);
glFrontFace(GL_CW);
glDisable(GL_CULL_FACE);
return true;
}
bool CTerrain3DTestView::DrawSky(GLvoid)
{
glFogf(GL_FOG_START, MAX*2); // 雾的开始深度
glFogf(GL_FOG_END, MAX*15); // 雾的结束深度
glColor4f(1,1,1,1);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTranslatef(-xtrans,-ytrans-MAX*48,-ztrans);
glRotatef(90,1,0,1);
gluSphere(quadratic,MAX*50,20,20);
glFogf(GL_FOG_START, 10.0f); // 雾的开始深度
glFogf(GL_FOG_END, visual_distance); // 雾的结束深度
return true;
}
void CTerrain3DTestView::Caculate(GLvoid)
{
zprot*=0.935f;
heading += zprot/3;
yaw += zprot/5;
yaw*=.95f;
Throttlei += (_Throttle-Throttle)/10;
Throttlei *= .9f;
Throttle += Throttlei/10;
GLfloat MAX_Speed = (sqrt(Throttle+1)) * 10;
Speedi += MAX_Speed-Speed;
Speedi *= .9f;
Speed += Speedi/1000;
XP = -(GLfloat)sin(heading*piover180) * Speed;
YP = -(GLfloat)sin(pitch*piover180) * Speed;
ZP = -(GLfloat)cos(heading*piover180) * Speed;
GLfloat overallspeed = Hypot(Hypot(XP,YP),ZP) / (ABS(Speed)+1);
YP *= overallspeed;
XP *= overallspeed;
ZP *= overallspeed;
XPOS += XP/30;
YPOS += YP/30;
ZPOS += ZP/30;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -