完整版基于OpenGL的飞机3D实时仿真程序代码.docx
《完整版基于OpenGL的飞机3D实时仿真程序代码.docx》由会员分享,可在线阅读,更多相关《完整版基于OpenGL的飞机3D实时仿真程序代码.docx(30页珍藏版)》请在冰豆网上搜索。
完整版基于OpenGL的飞机3D实时仿真程序代码
#include"total.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#defineGLUT_DISABLE_ATEXIT_HACK
#defineFILE_NAME"feiji.3DS"//指定对应的FILENAME
#defineSCREEN_WIDTH800
#defineSCREEN_HEIGHT600
#defineSCREEN_DEPTH16
#defineMAX_TEXTURES100//最大的纹理数目
#definePRIMARY0x4D4D//基本块(PrimaryChunk),位于文件的开始
//主块(MainChunks)
#defineOBJECTINFO0x3D3D//网格对象的版本号
#defineVERSION0x0002//.3ds文件的版本
#defineEDITKEYFRAME0xB000//所有关键帧信息的头部
//对象的次级定义(包括对象的材质和对象)
#defineMATERIAL0xAFFF//保存纹理信息
#defineOBJECT0x4000//保存对象的面、顶点等信息
//材质的次级定义
#defineMATNAME0xA000//保存材质名称
#defineMATDIFFUSE0xA020//对象/材质的颜色
#defineMATMAP0xA200//新材质的头部
#defineMATMAPFILE0xA300//保存纹理的文件名
#defineOBJECT_MESH0x4100//新的网格对象
//OBJECT_MESH的次级定义
#defineOBJECT_VERTICES0x4110//对象顶点
#defineOBJECT_FACES0x4120//对象的面
#defineOBJECT_MATERIAL0x4130//对象的材质
#defineOBJECT_UV0x4140//对象的UV纹理坐标
intg_ViewMode=GL_TRIANGLES;
boolg_bLighting=true;
floatg_Rotatex=0;
floatg_Rotatey=0;
floatg_Rotatez=0;
floatg_x=0;
floatg_y=0;
floatg_z=0;
//。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
定义需要导入的数据
floatRotatex;
floatRotatey;
floatRotatez;
floatx;
floaty;
floatz;
doublegl_x;doublegl_y;doublegl_z;doublegl_pitch;doublegl_roll;doublegl_yaw;
doublegl_wcpitch;doublegl_wcroll;doublegl_wcyaw;
usingnamespacestd;
UINTg_Texture[MAX_TEXTURES]={0};
HWNDg_hWnd;
RECTg_rRect;
HDCg_hDC;
HGLRCg_hRC;
HINSTANCEg_hInstance;
HINSTANCEhInstance;
MMRESULTidtimer_Opengl;
HWNDCreateMyWindow(LPSTRstrWindowName,intwidth,intheight,DWORDdwStyle,HINSTANCEhInstance);//生成用户窗口
LRESULTCALLBACKWinProc(HWNDgl_hwnd,UINTmessage,WPARAMwParam,LPARAMlParam);//消息响应
voidInit(HWNDgl_hWnd);//初始化整个程序
voidInitializeOpenGL(intwidth,intheight);//初始化OpenGL
boolbSetupPixelFormat(HDChdc);//设置像素格式
voidSizeOpenGLScreen(intwidth,intheight);//初始化投影变换
intMainLoop();//主循环
voidRenderScene(doublegl_x,doublegl_y,doublegl_z,doublegl_roll,doublegl_pitch,doublegl_yaw);
voidDeInit();//释放程序占用的内存空间
voidmyDisplaycube();//绘制外框架
voidglprintf();//输出文字
//----------------定义结构变量-----------------------------------------------------------------------------
//定义3D点的类,用于保存模型中的顶点
classCVector3
{
public:
floatx,y,z;
};
//定义2D点类,用于保存模型的UV纹理坐标
classCVector2
{
public:
floatx,y;
};
//面的结构定义
structtFace
{
intvertIndex[3];//顶点索引
intcoordIndex[3];//纹理坐标索引
};
//材质信息结构体
structtMaterialInfo
{
charstrName[255];//纹理名称
charstrFile[255];//如果存在纹理映射,则表示纹理文件名称
BYTEcolor[3];//对象的RGB颜色
inttexureId;//纹理ID
floatuTile;//u重复
floatvTile;//v重复
floatuOffset;//u纹理偏移
floatvOffset;//v纹理偏移
};
//对象信息结构体
structt3DObject
{
intnumOfVerts;//模型中顶点的数目
intnumOfFaces;//模型中面的数目
intnumTexVertex;//模型中纹理坐标的数目
intmaterialID;//纹理ID
charstrName[255];//对象的名称
CVector3*pVerts;//对象的顶点
CVector3*pNormals;//对象的法向量
CVector2*pTexVerts;//纹理UV坐标
tFace*pFaces;//对象的面信息
};
//模型信息结构体
structt3DModel
{
intnumOfObjects;//模型中对象的数目
intnumOfMaterials;//模型中材质的数目
vectorpMaterials;//材质链表信息
vectorpObject;//模型中对象链表信息
};
structtIndices
{
unsignedshorta,b,c,bVisible;
};
//保存块信息的结构
structtChunk
{
unsignedshortintID;//块的ID
unsignedintlength;//块的长度
unsignedintbytesRead;//需要读的块数据的字节数
};
//CLoad3DS类处理所有的装入代码
classCLoad3DS
{
public:
//可以被该类中的函数、子类的函数、其友元函数访问,也可以由该类的对象访问
CLoad3DS();//初始化数据成员
//装入3ds文件到模型结构中
boolImport3DS(t3DModel*pModel,char*strFileName);
//只能由该类中的函数、其友元函数访问,不能被任何其他访问,该类的对象也不能访问
//读一个字符串
intGetString(char*);
//读下一个块
voidReadChunk(tChunk*);
//读下一个块
voidProcessNextChunk(t3DModel*pModel,tChunk*);
//读下一个对象块
voidProcessNextObjectChunk(t3DModel*pModel,t3DObject*pObject,tChunk*);
//读下一个材质块
voidProcessNextMaterialChunk(t3DModel*pModel,tChunk*);
//读对象颜色的RGB值
voidReadColorChunk(tMaterialInfo*pMaterial,tChunk*pChunk);
//读对象的顶点
voidReadVertices(t3DObject*pObject,tChunk*);
//读对象的面信息
voidReadVertexIndices(t3DObject*pObject,tChunk*);
//读对象的纹理坐标
voidReadUVCoordinates(t3DObject*pObject,tChunk*);
//读赋予对象的材质名称
voidReadObjectMaterial(t3DModel*pModel,t3DObject*pObject,tChunk*pPreviousChunk);
//计算对象顶点的法向量
voidComputeNormals(t3DModel*pModel);
//关闭文件,释放内存空间
voidCleanUp();
//文件指针
FILE*m_FilePointer;
tChunk*m_CurrentChunk;//当前块
tChunk*m_TempChunk;//下一个块
};
CLoad3DSg_Load3ds;
t3DModelg_3DModel;
//.........................程序函数............................................................................
intOpenGL_Main()//入口程序
{
gl_hWnd=CreateMyWindow("飞机动态飞行模拟",SCREEN_WIDTH,SCREEN_HEIGHT,0,hInstance);
if(gl_hWnd==NULL)returntrue;
Init(gl_hWnd);//初始化整个程序
MainLoop();
return0;}
//创建窗口
HWNDCreateMyWindow(LPSTRstrWindowName,intwidth,intheight,DWORDdwStyle,HINSTANCEhInstance)
{
HWNDgl_hWnd;
WNDCLASSwndclass;/*wndclass用来保存我们的窗口类的结构。
窗口类结构中保存着我们的窗口信息。
通过改变类的不同字段我们可以改变窗口的外观和行为。
每个窗口都属于一个窗口类。
当您创建窗口时,您必须为窗口注册类。
*/
memset(&wndclass,0,sizeof(WNDCLASS));
wndclass.style=CS_HREDRAW|CS_VREDRAW;//设置窗口风格
wndclass.lpfnWndProc=WinProc;//WndProc处理消息其实就是键盘响应
wndclass.hInstance=hInstance;//设置实例
wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);//装入缺省图标要使用windows预定义的图标,这时hInstance必须设置成NULL
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);//装入鼠标指针
wndclass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);//设置opengl的背景色
wndclass.lpszClassName="opengl";//只是设定一个类型名
RegisterClass(&wndclass);//注册窗口的
if(!
dwStyle)
dwStyle=WS_OVERLAPPEDWINDOW|WS_CLIPSIBLINGS|WS_CLIPCHILDREN;//拓展窗口风格的
/*WS_CLIPCHILDREN裁剪子窗口。
。
。
就是不绘制与子窗口重合的父窗口部分子窗口间相互裁减。
当两个窗口相互重叠时,设置了WS_CLIPSIBLINGS样式的子窗口重绘时不能绘制被重叠的部分。
WS_OVERLAPPEDWINDOW可以创建一个拥有各种窗口风格的窗体,包括标题,系统菜单,边框,最小化和最大化按钮等*/
g_hInstance=hInstance;
RECTrWindow;//取得矩形的左上角和右下角的坐标值
rWindow.left=0;//将Left设为0
rWindow.right=width;//宽度
rWindow.top=0;
rWindow.bottom=height;//高度
AdjustWindowRect(&rWindow,dwStyle,false);//该函数依据所需计算需要的窗口矩形的大小随后传递给CreateWindow函数,用于创建一个客户区所需大小的窗口。
gl_hWnd=CreateWindow("opengl",strWindowName,dwStyle,0,0,
rWindow.right-rWindow.left,rWindow.bottom-rWindow.top,
NULL,//无父窗口
NULL,//无菜单
hInstance,//实例
NULL);//不向WM_CREATE传递信息
if(!
gl_hWnd)returnNULL;
ShowWindow(gl_hWnd,SW_SHOWNORMAL);//该函数设置指定窗口的显示状态SW_SHOWNORMAL运行时正常大小显示
UpdateWindow(gl_hWnd);//指定客户区
SetFocus(gl_hWnd);//设置键盘焦点
returngl_hWnd;
}
LRESULTCALLBACKWinProc(HWNDgl_hWnd,UINTuMsg,WPARAMwParam,LPARAMlParam)//窗口响应
{
staticintcxClient,cyClient;
LONGlRet=0;
switch(uMsg)
{
caseWM_SIZE:
//用于控制窗口的形状变化
cxClient=LOWORD(lParam);
cyClient=HIWORD(lParam);
return0;
caseWM_CLOSE:
//关闭窗口的响应
ShowWindow(gl_hWnd,SW_HIDE);//隐藏窗口
break;
default:
lRet=DefWindowProc(gl_hWnd,uMsg,wParam,lParam);//处理无关消息
break;
}
returnlRet;
}
voidInit(HWNDgl_hWnd)//初始化整个窗口
{
g_hWnd=gl_hWnd;
GetClientRect(g_hWnd,&g_rRect);//该函数获取窗口客户区的坐标。
InitializeOpenGL(g_rRect.right,g_rRect.bottom);//以hWnd代表的客户区的矩形的宽和高为变量初始化opengl
g_Load3ds.Import3DS(&g_3DModel,FILE_NAME);//将3ds文件装入到模型结构体中
glEnable(GL_LIGHT0);//使用默认的0号灯
glEnable(GL_LIGHTING);//使用灯光
glEnable(GL_COLOR_MATERIAL);//使用颜色材质
}
voidInitializeOpenGL(intwidth,intheight)//初始化OpenGL
{
g_hDC=GetDC(g_hWnd);
if(!
bSetupPixelFormat(g_hDC))
PostQuitMessage(0);
g_hRC=wglCreateContext(g_hDC);//函数建立一个适合在指定hdc上绘制的RC,RC与DC有相同的像素格式
wglMakeCurrent(g_hDC,g_hRC);
glEnable(GL_TEXTURE_2D);//开启2D纹理贴图功能
glEnable(GL_DEPTH_TEST);//开启深度测试
SizeOpenGLScreen(width,height);
}
boolbSetupPixelFormat(HDChdc)//设置设置像素格式
{
PIXELFORMATDESCRIPTORpfd;
intpixelformat;
pfd.nSize=sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion=1;
pfd.dwFlags=PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER;
pfd.dwLayerMask=PFD_MAIN_PLANE;
pfd.iPixelType=PFD_TYPE_RGBA;
pfd.cColorBits=SCREEN_DEPTH;
pfd.cDepthBits=SCREEN_DEPTH;
pfd.cAccumBits=0;
pfd.cStencilBits=0;
if((pixelformat=ChoosePixelFormat(hdc,&pfd))==FALSE)//获取opengl最佳像素
{
returnFALSE;
}
if(SetPixelFormat(hdc,pixelformat,&pfd)==FALSE)//设置像素格式
{
returnFALSE;
}
returnTRUE;
}
voidSizeOpenGLScreen(intwidth,intheight)//初始化投影变换
{
if(height==0)
{
height=1;
}
glViewport(0,0,width,height);//设置实际图像映射的像素矩形
glMatrixMode(GL_PROJECTION);//指定当前矩阵
glLoadIdentity();//变成单位矩阵
gluPerspective(45.0f,////角度
(GLfloat)width/(GLfloat)height,//视景体的宽高比
.5f,//沿z轴方向的两裁面之间的距离的近处
150.0f//沿z轴方向的两裁面之间的距离的远处
);//设置透视投影矩阵
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
intMainLoop()//主循环
{
MSGmsg;
while
(1)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))//该函数为一个消息检查线程消息队列,并将该消息(如果存在)放于指定的结构。
//PM_REMOVE:
PeekMessage处理后,消息从队列里除掉
{
if(msg.message==WM_CLOSE)
break;
TranslateMessage(&msg