<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} p.MsoBodyText, li.MsoBodyText, div.MsoBodyText {margin-top:0cm; margin-right:0cm; margin-bottom:6.0pt; margin-left:0cm; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} p.MsoBodyTextFirstIndent, li.MsoBodyTextFirstIndent, div.MsoBodyTextFirstIndent {mso-style-update:auto; mso-style-parent:正文文本; mso-style-link:" Char Char"; margin:0cm; margin-bottom:.0001pt; text-indent:19.85pt; mso-pagination:none; font-size:10.5pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-ansi-language:ZH-CN;} p.a, li.a, div.a {mso-style-name:正文(首行不缩进); margin:0cm; margin-bottom:.0001pt; line-height:150%; mso-pagination:none; mso-layout-grid-align:none; text-autospace:none; font-size:10.5pt; mso-bidi-font-size:10.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体;} span.CharChar {mso-style-name:" Char Char"; mso-style-locked:yes; mso-style-link:正文首行缩进; mso-ansi-font-size:10.5pt; mso-bidi-font-size:10.5pt; font-family:宋体; mso-fareast-font-family:宋体; mso-ansi-language:ZH-CN; mso-fareast-language:ZH-CN; mso-bidi-language:AR-SA;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} -->
这样我们对 md2文件格式基本上就了解得差不多了, 接下来 再来来看实际上的应用。
#include "md2.h"
CLoadMD2 g_LoadMd2; // 我们的加载MD2 类
Model3D_t g_3DModel; // 3D 模型
#define FILE_NAME "tris.md2" // md2 文件
#define TEXTURE_NAME "rhino.bmp" // 纹理文件
int g_ViewMode=GL_TRIANGLES; // 渲染模式
int glInit(GLvoid)
{
if (!DXInit()) // 初始化DirectInput
{
return FALSE; // 失败,返回
}
glShadeModel(GL_SMOOTH);
glClearColor(1.0f,1.0f,1.0f,0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
// 加载 md2 模型
g_LoadMd2.ImportMD2(&g_3DModel, FILE_NAME, TEXTURE_NAME);
// 加载纹理
for(int i = 0; i < g_3DModel.numOfMaterials; i++)
{
if(strlen(g_3DModel.pMaterials[i].strFile) > 0)
{
g_Texture[i] = CreateTexture(g_3DModel.pMaterials[i].strFile);
}
// 设置材质的纹理ID
g_3DModel.pMaterials[i].texureId = i;
}
glEnable(GL_LIGHTING); // 启用光照
glEnable(GL_LIGHT0);
glEnable(GL_CULL_FACE); // 启用消隐
glCullFace(GL_FRONT); // Quake2 只显示前面可以提高运行速度
// 加载OBJ 模型
g_model = glmReadOBJ(g_model_fn);
if (!g_model) exit(0);
glmUnitize(g_model);
glmScale(g_model,4.0);
glmFacetNormals(g_model);
glmVertexNormals(g_model, 90.0);
g_Camera.PositionCamera(0, 1.5f, 90, 0, 0.5f, 0, 0, 1, 0);
return TRUE;
}
int glMain(GLvoid)
{
HRESULT hr;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// 获取输入设备的数据,保存在buffer 和mouseState 中
hr= g_KDIDev->GetDeviceState(sizeof(buffer), &buffer);
hr= (g_MDIDev->GetDeviceState(sizeof(DIMOUSESTATE),(LPVOID)&mouseState));
if(!KeyPressed())
return FALSE;
gluLookAt(g_Camera.m_vPosition.x, g_Camera.m_vPosition.y, g_Camera.m_vPosition.z,
g_Camera.m_vView.x, g_Camera.m_vView.y, g_Camera.m_vView.z,
g_Camera.m_vUpVector.x, g_Camera.m_vUpVector.y, g_Camera.m_vUpVector.z);
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glDisable(GL_TEXTURE_2D);
// 建立4 个金字塔
CreatePyramid(-60, 6, 60, 1, 10);
CreatePyramid(60, 6, 60, 1, 10);
CreatePyramid(60, 6, -60, 1, 10);
CreatePyramid(-60, 6, -60, 1, 10);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_TEXTURE_2D);
glEnable(GL_CULL_FACE);
// 再一次的确认3D 对象的有效性
if(g_3DModel.pObject.size() <= 0)
return FALSE;
// 获取当前要显示的对象
Object3D_t *pObject = &g_3DModel.pObject[0];
// 根据设置的模式进行渲染
glBegin(g_ViewMode);
// 遍历所有的面
for(int j = 0; j < pObject->numOfFaces; j++)
{
for(int whichVertex = 0; whichVertex < 3; whichVertex++)
{
// 获得三角形中每一个点的索引
int index = pObject->pFaces[j].vertIndex[whichVertex];
// 获取每个纹理坐标的索引
int index2 = pObject->pFaces[j].coordIndex[whichVertex];
// 设置顶点法向量,因为Quake2 多边形的方向和OpenGL 相反,
// 因此这里要用负号变换一下
glNormal3f(-pObject->pNormals[ index ].x, -pObject->pNormals[ index ].y,
-pObject->pNormals[ index ].z);
// 顶点的纹理坐标
if(pObject->pTexVerts)
{
glTexCoord2f(pObject->pTexVerts[ index2 ].x,
pObject->pTexVerts[ index2 ].y);
}
// 顶点坐标
glVertex3f(pObject->pVerts[ index ].x, pObject->pVerts[ index ].y,
pObject->pVerts[ index ].z);
}
}
glEnd(); //md2 模型渲染完毕
// 渲染OBJ 模型Al
CVector3 ObjPosition(0, 2, -50);
glTranslatef(ObjPosition.x, ObjPosition.y, ObjPosition.z);
glDisable(GL_TEXTURE_2D);
glDisable(GL_CULL_FACE);
glmDraw(g_model,GLM_SMOOTH | GLM_MATERIAL | GLM_TEXTURE);
SwapBuffers(g_hDC);
return TRUE;
}