完整版基于OpenGL的飞机3D实时仿真程序代码Word下载.docx
《完整版基于OpenGL的飞机3D实时仿真程序代码Word下载.docx》由会员分享,可在线阅读,更多相关《完整版基于OpenGL的飞机3D实时仿真程序代码Word下载.docx(30页珍藏版)》请在冰豆网上搜索。
//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
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
//对象的名称
CVector3*pVerts;
//对象的顶点
CVector3*pNormals;
//对象的法向量
CVector2*pTexVerts;
//纹理UV坐标
tFace*pFaces;
//对象的面信息
//模型信息结构体
structt3DModel
intnumOfObjects;
//模型中对象的数目
intnumOfMaterials;
//模型中材质的数目
vector<
tMaterialInfo>
pMaterials;
//材质链表信息
t3DObject>
pObject;
//模型中对象链表信息
structtIndices
{
unsignedshorta,b,c,bVisible;
//保存块信息的结构
structtChunk
unsignedshortintID;
//块的ID
unsignedintlength;
//块的长度
unsignedintbytesRead;
//需要读的块数据的字节数
//CLoad3DS类处理所有的装入代码
classCLoad3DS
//可以被该类中的函数、子类的函数、其友元函数访问,也可以由该类的对象访问
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("
strWindowName,dwStyle,0,0,
rWindow.right-rWindow.left,rWindow.bottom-rWindow.top,
NULL,//无父窗口
NULL,//无菜单
hInstance,//实例
NULL);
//不向WM_CREATE传递信息
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);
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)//设置像素格式
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);
intMainLoop()//主循环
MSGmsg;
while
(1)
if(PeekMessage(&
msg,NULL,0,0,PM_REMOVE))//该函数为一个消息检查线程消息队列,并将该消息(如果存在)放于指定的结构。
//PM_REMOVE:
PeekMessage处理后,消息从队列里除掉
if(msg.message==WM_CLOSE)
break;
TranslateMessage(&
msg