www.pudn.com > HeightMap.rar > Main.cpp
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glaux.lib")
#include "main.h"
#include "camera.h"
bool g_bFullScreen = true;
HWND g_hWnd;
RECT g_rRect;
HDC g_hDC;
HGLRC g_hRC;
HINSTANCE g_hInstance;
CCamera g_Camera;
BYTE g_HeightMap[MAP_SIZE*MAP_SIZE]; // 保存高程数据
bool g_bRenderMode = true; // 渲染模式
UINT g_Texture[MAX_TEXTURES] = {0};
// 各位置的纹理ID
#define BACK_ID 1
#define FRONT_ID 2
#define BOTTOM_ID 3
#define TOP_ID 4
#define LEFT_ID 5
#define RIGHT_ID 6
// 下面的函数的功能是生成天空
void CreateSkyBox(float x, float y, float z, float width, float height, float length)
{
// 使用纹理
glEnable(GL_TEXTURE_2D);
// 设置BACK纹理参数
glBindTexture(GL_TEXTURE_2D, g_Texture[BACK_ID]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// 天空的位置
x = x - width / 2;
y = y - height / 2;
z = z - length / 2;
// 开始绘制
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x + width, y, z);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x + width, y + height, z);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y + height, z);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x, y, z);
glEnd();
// 设置FRONT部分的纹理参数
glBindTexture(GL_TEXTURE_2D, g_Texture[FRONT_ID]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// 开始绘制
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y, z + length);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y + height, z + length);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x + width, y + height, z + length);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y, z + length);
glEnd();
// 设置BOTTOM部分的纹理参数
glBindTexture(GL_TEXTURE_2D, g_Texture[BOTTOM_ID]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// 开始绘制
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y, z);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y, z + length);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x + width, y, z + length);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y, z);
glEnd();
// 设置TOP部分的纹理参数
glBindTexture(GL_TEXTURE_2D, g_Texture[TOP_ID]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// 开始绘制
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x + width, y + height, z);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y + height, z + length);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y + height, z + length);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y + height, z);
glEnd();
// 设置LEFT部分的纹理参数
glBindTexture(GL_TEXTURE_2D, g_Texture[LEFT_ID]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// 开始绘制
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y + height, z);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y + height, z + length);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x, y, z + length);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y, z);
glEnd();
// 设置RIGHT部分的纹理参数
glBindTexture(GL_TEXTURE_2D, g_Texture[RIGHT_ID]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// 开始绘制
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y, z);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x + width, y, z + length);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x + width, y + height, z + length);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x + width, y + height, z);
glEnd();
}
// 下面的函数功能是初始化地形数据和各种纹理数据
void Init(HWND hWnd)
{
g_hWnd = hWnd;
GetClientRect(g_hWnd, &g_rRect);
InitializeOpenGL(g_rRect.right, g_rRect.bottom);
// 读入"Terrain.raw"文件,作为高程数据
LoadRawFile("Terrain.raw", MAP_SIZE * MAP_SIZE, g_HeightMap);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_CULL_FACE);
// 装入所有的纹理
CreateTexture(g_Texture[0], "Terrain.bmp");
CreateTexture(g_Texture[BACK_ID], "Back.bmp");
CreateTexture(g_Texture[FRONT_ID], "Front.bmp");
CreateTexture(g_Texture[BOTTOM_ID], "Bottom.bmp");
CreateTexture(g_Texture[TOP_ID], "Top.bmp");
CreateTexture(g_Texture[LEFT_ID], "Left.bmp");
CreateTexture(g_Texture[RIGHT_ID], "Right.bmp");
// 设置摄像机的位置
g_Camera.PositionCamera( 280, 35, 225, 281, 35, 225, 0, 1, 0);
}
WPARAM MainLoop()
{
MSG msg;
while(1)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
g_Camera.Update();
RenderScene();
}
}
DeInit();
return(msg.wParam);
}
// 下面的函数功能是绘制场景
void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// 设置摄像机位置和方向
g_Camera.Look();
// 渲染地形
RenderHeightMap(g_HeightMap);
// 绘制天空包围盒
CreateSkyBox(500, 0, 500, 2000, 2000, 2000);
// 获得当前摄像机的位置
CVector3 vPos = g_Camera.Position();
CVector3 vNewPos = vPos;
// 判断摄像机是否低于地平面
if(vPos.y < Height(g_HeightMap, (int)vPos.x, (int)vPos.z ) + 10)
{
// 设置新的位置
vNewPos.y = (float)Height(g_HeightMap, (int)vPos.x, (int)vPos.z ) + 10;
// 获得y方向的差
float temp = vNewPos.y - vPos.y;
// 获得当前摄像机的方向
CVector3 vView = g_Camera.View();
vView.y += temp;
// 设置新的摄像机位置
g_Camera.PositionCamera(vNewPos.x, vNewPos.y, vNewPos.z,
vView.x, vView.y, vView.z, 0, 1, 0);
}
// 交换缓冲区
SwapBuffers(g_hDC);
}
LRESULT CALLBACK WinProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
switch (uMsg)
{
case WM_SIZE:
if(!g_bFullScreen)
{
SizeOpenGLScreen(LOWORD(lParam),HIWORD(lParam));
GetClientRect(hWnd, &g_rRect);
}
break;
case WM_PAINT:
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_LBUTTONDOWN: // 如果按下鼠标左键
g_bRenderMode = !g_bRenderMode;
// 改变渲染模式
if(g_bRenderMode)
{
// 纹理模式
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
else
{
// 线框模式
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
break;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
}
break;
case WM_CLOSE:
PostQuitMessage(0);
break;
}
return DefWindowProc (hWnd, uMsg, wParam, lParam);
}