关键词不能为空

当前您在: 主页 > 英语 >

基于OpenGL的飞机3D实时仿真_程序代码

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-02-01 21:30
tags:

-

2021年2月1日发(作者:引爆)


#include


#include


#include


#include


#include


#include


#include


#include


#include


#include


#include


#include


#include


#include


#include



#define GLUT_DISABLE_ATEXIT_HACK



#define FILE_NAME




//


指定对 应的



FILE NAME



#define SCREEN_WIDTH 800










#define SCREEN_HEIGHT 600










#define SCREEN_DEPTH 16











#define MAX_TEXTURES 100



//


最大的纹理数目



#define PRIMARY








0x4D4D//



基本块


(Primary Chunk)


,位于文件的开始



//



主块


(Main Chunks)


#define OBJECTINFO





0x3D3D





//


网格对象的版本号



#define VERSION








0x0002





// .3ds


文件的版本



#define EDITKEYFRAME



0xB000





//


所有关键帧信息的头部



//



对象的次级定义


(

< br>包括对象的材质和对象)



#define MATERIAL




0xAFFF





//


保存纹理信息



#define OBJECT





0x4000





//


保存对象的面、顶点等信息



//



材质的次级定义



#define MATNAME








0xA000





//


保存材质名称



#define MATDIFFUSE





0xA020





//


对象


/


材质的颜色



#define MATMAP









0xA200





//


新材质的头部



#define MATMAPFILE





0xA300





//


保存纹理的文件名



#define OBJECT_MESH




0x4100





//


新的网格对象



//



OBJECT_MESH


的次级定义



#define OBJECT_VERTICES






0x4110




//


对象顶点



#define OBJECT_FACES



0x4120




//


对象的面



#define OBJECT_MATERIAL



0x4130




//


对象的材质



#define OBJECT_UV




0x4140




//


对象的


UV


纹理坐标





int




g_ViewMode



= GL_TRIANGLES;


bool



g_bLighting






= true;




float g_Rotatex





= 0;


float g_Rotatey








= 0;


float g_Rotatez








= 0;




float g_x
















=0;


float g_y
















=0;


float g_z
















=0;


//





















。定义需要导入的数据



float Rotatex




;


float Rotatey








;


float Rotatez










;




float x
















;


float y
















;


float z
















;


double gl_x; double gl_y; double gl_z;




double gl_pitch; double gl_roll; double gl_yaw;


double gl_wcpitch;double gl_wcroll;double gl_wcyaw;



using namespace std;


UINT g_Texture[MAX_TEXTURES] = {0};








HWND



g_hWnd;












RECT



g_rRect;













HDC




g_hDC;













HGLRC g_hRC;













HINSTANCE g_hInstance;


HINSTANCE




hInstance;


MMRESULT idtimer_Opengl;





HWND


CreateMyWindow(LPSTR


strWindowName,


int


width,


int


height,


DWORD


dwStyle,



HINSTANCE hInstance);//


生成用户窗口



LRESULT


CALLBACK


WinProc(HWND


gl_hwnd,


UINT


message,


WPARAM


wParam,


LPARAM lParam);//


消息响应



void Init(HWND gl_hWnd);//


初始化整个程序



void InitializeOpenGL(int width, int height);//


初始化


OpenGL


bool bSetupPixelFormat(HDC hdc);//


设置像素格式



void SizeOpenGLScreen(int width, int height);//


初始化投影变换



int MainLoop();//


主循环



void


RenderScene(double


gl_x,


double


gl_y,


double


gl_z,




double


gl_roll,


double


gl_pitch,


double gl_yaw)


void DeInit();//


释放程序占用的内存空间



void myDisplaycube();//


绘制外框架



void glprintf();//


输出文字





//------------- ---


定义结构变量


------------------- -------------------------------------------------- --------


//


定义


3D< /p>


点的类,用于保存模型中的顶点



class CVector3



{


public:



float x, y, z;


};



//


定义


2D


点类,用于保存模型的


UV


纹理坐标



class CVector2



{


public:



float x, y;


};



//



面的结构定义



struct tFace


{



int vertIndex[3];




int coordIndex[3];



};



//



材质信息结构体



struct tMaterialInfo


{



char



strName[255];



char



strFile[255];



BYTE



color[3];




int




texureId;




float uTile;





float vTile;





float uOffset;





float vOffset;




}



//



对象信息结构体



struct t3DObject



{



int



numOfVerts;




int



numOfFaces;




int



numTexVertex;



int



materialID;




char strName[255];



CVector3



*pVerts;


//


顶点索引



//


纹理坐标索引




//


纹理名称



//


如果存在纹理映射,则表示纹理文件名称




//


对象的


RGB


颜色




//


纹理


ID


// u


重复



// v


重复



// u


纹理偏移



// v


纹理偏移



//


模型中顶点的数目



//


模型中面的数目




//


模型中纹理坐标的数目



//


纹理


ID


//


对象的名称




//


对象的顶点























CVector3



*pNormals;



//


对象的法向量




CVector2



*pTexVerts;



//


纹理


UV


坐标




tFace *pFaces;





//


对象的面信息



};



//



模型信息结构体



struct t3DModel



{



int numOfObjects;






//


模型中对象的数目




int numOfMaterials;






//


模型中材质的数目




vector pMaterials; //


材质链表信息




vector pObject;




//


模型中对象链表信息



};


struct tIndices



{










unsigned short a, b, c, bVisible;



};



//


保存块信息的结构



struct tChunk


{



unsigned short int ID;






//


块的


ID





unsigned int length;






//


块的长度




unsigned int bytesRead;






//


需要读的块数据的字节数



};



// CLoad3DS


类处理所有的装入代码



class CLoad3DS


{


public://


可以被该类中的函数、子类的函数、其友元函数访问


,


也可以由该类的对象访问





CLoad3DS();









//


初始化数据成员




//


装入


3ds

文件到模型结构中




bool Import3DS(t3DModel *pModel, char *strFileName);



//


只能由该类中的函数、其友元函 数访问


,


不能被任何其他访问,该类的对象也不能访问




//


读一个字符串




int GetString(char *);



//


读下一个块




void ReadChunk(tChunk *);



//


读下一个块




void ProcessNextChunk(t3DModel *pModel, tChunk *);



//


读下一个对象块




void ProcessNextObjectChunk(t3DModel *pModel, t3DObject *pObject, tChunk *);



//


读下一个材质块




void ProcessNextMaterialChunk(t3DModel *pModel, tChunk *);



//


读对象颜色的


RGB





void ReadColorChunk(tMaterialInfo *pMaterial, tChunk *pChunk);



//


读对象的顶点




void ReadVertices(t3DObject *pObject, tChunk *);



//


读对象的面信息




void ReadVertexIndices(t3DObject *pObject, tChunk *);



//


读对象的纹理坐标




void ReadUVCoordinates(t3DObject *pObject, tChunk *);



//


读赋予对象的材质名称




void


ReadObjectMaterial(t3DModel


*pModel,


t3DObject


*pObject,


tChunk


*pPreviousChunk);



//


计算对象顶点的法向量




void ComputeNormals(t3DModel *pModel);



//


关闭文件,释放内存空间




void CleanUp();



//


文件指针




FILE *m_FilePointer;




tChunk *m_CurrentChunk;//


当前块




tChunk *m_TempChunk;//


下一个块



};



CLoad3DS g_Load3ds;











t3DModel g_3DModel;







//............. ............


程序函数


............ .................................................. ..............




int OpenGL_Main()//


入口程序



{




< /p>


gl_hWnd=CreateMyWindow(


飞机动态飞行 模拟



0,



hInstance);



if(gl_hWnd == NULL) return true;






Init(gl_hWnd);//


初始化整个程序







MainLoop();






return 0;}








//


创建窗口



HWND


CreateMyWindow(LPSTR


strWindowName,


int


width,


int


height,


DWORD


dwStyle,


HINSTANCE hInstance)


{



HWND gl_hWnd;



WNDCLASS


wndclass;/*wndclass


用来保存我们的窗口类的结构。窗口类结构中保存着


我们的窗口 信息。























通过改变类的不同字段我们可以改变窗口的外观和行为。























每个窗口都属于一个窗口类。当您创建窗口时,您必须为窗口注


册类 。


*/





memset(&wndclass, 0, sizeof(WNDCLASS));






= CS_HREDRAW | CS_VREDRAW;//


设置窗口风格





dProc = WinProc;


// WndProc


处理消息



其实就是键盘响应







nce = hInstance;



//


设置实例







=


LoadIcon(NULL,


IDI_APPLICATION);//










使



windows


预定义的图标


,


这时


hInstance


必须设置成


NULL




r = LoadCursor(NULL, IDC_ARROW);


//


装入鼠标指针




kground = (HBRUSH) (COLOR_W INDOW+1);//


设置


opengl

的背景色




assName =


//


只是设定一个类型名





RegisterClass(& wndclass);//


注册窗口的













if(!dwStyle)











dwStyle


=


WS_OVERLAPPEDWINDOW


|


WS_CLIPSIBLINGS


|


WS_CLIPCHILDREN;//


拓展窗口风格的


< /p>


/*WS_CLIPCHILDREN


裁剪子窗口。



。就是不绘制与子窗口重合的父窗口部分子窗口间相


互裁减。



当两个窗口相互重叠时,设置了

< br>WS_CLIPSIBLINGS


样式的子窗口重绘时不能绘制被重叠

< p>
的部分。



WS_OVERLAPPEDWIND OW


可以创建一个拥有各种窗口风格的窗体,包括标题,系统菜


单,边框,最小化和最大化按钮等


*/



g_hInstance = hInstance;









RECT rWindow;//


取得矩形的左上角和右下角的坐标值





= 0;



//



Left




设为



0




= width;


//


宽度










= 0;









= height;//


高度









AdjustWindowRect( &rWindow, dwStyle, false);//


该函数依据所需计算需要的窗口矩形的


大小随后传递给


CreateWindow


函数 ,用于创建一个客户区所需大小的窗口。









gl_hWnd = CreateWindow(










- , - ,









NULL, //


无父窗口









NULL,//


无菜单










hInstance,//


实例









NULL);//


不向


WM_CREATE


传递信息




if(!gl_hWnd) return NULL








ShowWindow(gl_hWnd, SW_SHOWNORMAL);


//


该函数设置指定窗口的显示状态




SW_SHOWNORMAL


运行时 正常大小显示




< br>UpdateWindow(gl_hWnd);//


指定客户区









Set Focus(gl_hWnd);//


设置键盘焦点




return gl_hWnd;


}


LRESULT CALLBACK WinProc(HWND gl_hWnd,UINT uMsg, WPARAM wParam, LPARAM


lParam)//


窗口响应



{





static int cxClient,cyClient;






LONG





lRet = 0;







switch (uMsg)



{











case WM_SIZE://


用于控制窗口的形状变化











cxClient = LOWORD(lParam);










cyClient = HIWORD(lParam);










return 0;










case WM_CLOSE:









//


关闭



窗口的响应








ShowWindow(gl_hWnd,SW_HIDE)


//


隐藏窗口









break;














default:




















lRet = DefWindowProc (gl_hWnd, uMsg, wParam, lParam); //


处理无关消息











break;







}











return lRet;












}















void Init(HWND gl_hWnd)//


初始化整个窗口



{



g_hWnd = gl_hWnd;













GetClientRect(g_hWnd, &g_rRect);//


该函数获取窗口客户区的坐标。









InitializeOpenGL(g_, g_);//



hWnd


代表的客户区的矩形的宽和高


为变量初始化


opengl



g_3DS(&g_3DModel, FILE_NAME);



//



3 ds


文件装入到模型


结构体中




glEnable(GL_LIGHT0); //


使用默认的


0


号灯











glEnable(GL_LIGHTING);



//


使用灯光










glEnable(GL_COLOR_MA


TERIAL);



//


使用颜色材质







}



void InitializeOpenGL(int width, int height) //


初始化


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);



}



bool bSetupPixelFormat(HDC hdc) //


设置设置像素格式



{







PIXELFORMATDESCRIPTOR pfd;







int pixelformat;







= sizeof(PIXELFORMATDESCRIPTOR);









on = 1;


























s


=


PFD_DRAW_TO_WINDOW


|


PFD_SUPPORT_OPENGL


|


PFD_DOUBLEBUFFER;







rMask = PFD_MAIN_PLANE;









Type = PFD_TYPE_RGBA;










Bits = SCREEN_DEPTH;










Bits = SCREEN_DEPTH;










Bits = 0;












ilBits = 0;











if ( (pixelformat = ChoosePixelFormat(hdc, &pfd)) == FALSE ) //


获取


opengl


最佳像素







{





















return FALSE;







}









if (SetPixelFormat(hdc, pixelformat, &pfd) == FALSE) //


设置像素格式







{




















return FALSE;







}







return TRUE;









}



void SizeOpenGLScreen(int width, int height)//


初始化投影变换





{



if (height==0)












{




height=1;












}




glViewport(0,0,width,height);//


设置实际图像映射的像素矩形









glMatrixMode(GL_PROJECTION) ;//


指定当前矩阵






glLoadIdentity( );//


变成单位矩阵










gluPerspective( 45.0f,////


角度





(GLfloat)width/(GLfloat)hei ght,//


视景体的宽高比





.5f ,//


沿

< br>z


轴方向的两裁面之间的距离的近处





150.0f//


沿


z


轴方向的两裁面之间的距离的远处





);//


设置透视投影矩阵





glMatrixMode(GL_MODELVIEW);









glLoadIdentity();











}





int MainLoop()//


主循环



{






MSG msg;












while(1)














{





if


(PeekMessage(&msg,


NULL,


0,


0,


PM_REMOVE))


//


该函数为一个消息检查线程


消息队 列,并将该消息(如果存在)放于指定的结构。
























































//PM_REMOVE



PeekMes sage


处理后,消息从队列里除掉











{






if(e == WM_CLOSE)










break;














TranslateMessage(&msg);


//


键盘码的转化




















DispatchMessage(&msg);


//


分发消息到回调函数,系统通过调用回调函数实

现在窗体中实现对应操作













}




else













{













glprintf();//


输出状 态文字









gl_x=0;gl_y=0;gl_z=0;




gl_wcpitch=;gl_wcroll=;gl_wcyaw=;




gl_pitch=gl_wcp itch;gl_roll=gl_wcroll;gl_yaw=gl_wcyaw;




RenderScene(gl_ x,gl_y,gl_z,gl_roll,gl_pitch,gl_yaw);//


控制飞机的姿态和观察角度并


且对应的在


opengl


中绘制


3ds


模型












}



}







for(int i = 0; i < g_bjects; i++)//


清空图形的相关变量




{




//


删除所有的变量





delete [] g_t[i].pFaces;//


对象的面





delete [] g_t[i].pNormals;//


给出法向量





delete [] g_t[i].pVerts; //


对象的顶点





delete [] g_t[i].pTexVerts;//


纹理


UV


坐标




}



DeInit();


//


释放程序占用的内存空间




return();



}



void DeInit()//


释放程序占用的内存空间



{



if (g_hRC)














{




wglMakeCurrent(NULL, NULL);


//






opengl










--------------------


渲染上下文句柄 为


null


时才有这个功能










wgl DeleteContext(g_hRC);//


删除渲染内容的句柄










}





if (g_hDC)




ReleaseDC(g_hWnd, g_hDC);//


函 数释放设备上下文环境(


DC


)供其他应用程序使用

< p>









UnregisterClass(


//


该 函数注销一个窗口类,一类释放所需的内





PostQuitMessage (0);


}



//


文字显示



void glprintf()


{




char str0[100];


sprintf(str0,


char str_pitch[] =


俯仰角度:


strcat(str_pitch, str0);


SetBkColor(g_hDC,NULL);


Text Out(g_hDC,5,5,str_pitch,strlen(str_pitch));


SetTextColor(g_hDC,RGB(0,200,0));



char str1[100];


sprintf(str1,


char str_roll[] =


滚转角度:



strcat(str_roll, str1);


SetBkColor(g_hDC,NULL);


Text Out(g_hDC,5,20,str_roll,strlen(str_roll));


SetTextColor(g_hDC,RGB(0,200,0));



char str2[100];


sprintf(str2,


char str_yaw[] =


偏航角度:



strcat(str _yaw, str2);


SetBkColor(g_hDC,NULL);


TextOut(g_hDC,5,35,str_yaw,strlen(str_yaw ));


SetTextColor(g_hDC,RGB(0,200,0));



char str3[100];


sprintf(str3,


char str_x[] =


轴位移:





strcat(str_x, str3);


SetBkColor(g_hDC,NULL);


Text Out(g_hDC,5,60,str_x,strlen(str_x));


SetTextColor(g_hDC,RGB(0,200,0));



char str4[100];


sprintf(str4,


char str_y[] =


轴位移:





strcat(str_y, str4);


SetBkColor(g_hDC,NULL);


Text Out(g_hDC,5,75,str_y,strlen(str_y));


SetTextColor(g_hDC,RGB(0,200,0));




char str5[100];


sprintf(str5,


char str_z[] =


轴位移:





strcat(str_z, str5);


SetBkColor(g_hDC,NULL);


Text Out(g_hDC,5,90,str_z,strlen(str_z));


SetTextColor(g_hDC,RGB(0,200,0));



}


void


RenderScene(double


gl_x,


double


gl_y,


double


gl_z,




double


gl_roll,


double


gl_pitch,


double gl_yaw)



{








glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //




颜色


缓冲以



深度 缓冲




glLoadIdentit y();//


设置为单位矩阵




gluLookAt(1.2,1.2,-1.2,


0, 0, 0,


-1,-1,-1);//


设置观察坐标,视点坐 标,视线朝向




glPushMatrix();


myDisplaycub e();glPopMatrix();//


绘制外部正方体框架








g_x=gl_x;



g_y=gl_y; g_z=gl_z;



g_Rotatex=gl_roll;g_Rotatey= gl_pitch;g_Rotatez=gl_yaw;






glTranslatef(g_ x,g_y,g_z);//


机翼是


y


方向从机头前方看右侧有正,机身前后方向是


x



头方向为正方向



,机身垂直是

z


向下为正方向




glRotatef(g_Rotatex,1.0f,



0, 0);//


是飞机


roll


的角度





glRotatef(g_Rotatey, 0, 1.0f, 0);//pitch


的角度








glRotatef(g_Rotatez,



0, 0,1.0f);//yaw


的角度




glPushMatrix();



//


将当前变换矩阵


(


单位阵


)


压入堆栈







glPopMatrix();













//


遍历模型中所有的对象(将显示列表里的信息显示出来)




for(int i = 0; i < g_bjects; i++)



{




//


如果模型中没有对应的对象,则退出





if(g_() <= 0) break;




//


获得当前显示的对象





t3DObject *pObject = &g_t[i];




glBegin(g_ViewMode);//


开始以


g_ViewMode


模式绘制







-


-


-


-


-


-


-


-



本文更新与2021-02-01 21:30,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/595213.html

基于OpenGL的飞机3D实时仿真_程序代码的相关文章