⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 model.cpp

📁 c++程序
💻 CPP
字号:
// Model.cpp: Implementierung der Klasse CModel.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Model.h"

//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////

CModel::CModel()
{

}

CModel::~CModel()
{
	m_MD2.Destroy ();
}

bool CModel::LoadMD2Model(char sMD2Filename[], char sPCXFilename[])
{
	// Load the passed MD2 model and render it into a display list
	
	// Erase the old one
	m_MD2.Destroy();
	
	// Success ?
	if (!m_MD2.Read(sMD2Filename))
		return FALSE;

	// Load skin
	m_Texture.LoadBMP(sPCXFilename);
	
	// Use only 1 frame
	int frame = 0;

	// Generate a displaylist index
	m_DisplayListID = glGenLists(1);

	// Render model into a display list
	glNewList(m_DisplayListID, GL_COMPILE);

		// Use skin
		m_Texture.Use();

		// Base color
		glColor3f(1.0f, 1.0f, 1.0f);

		// Calculate the centerpoint of the model
		float fCenterPoint[3];
		CalcModelCenter(fCenterPoint, &m_MD2);
		fCenterPoint[2] = 0.0f; // Produces more realistic lighting

		// Model consits of triangles
		glBegin(GL_TRIANGLES);

			for (int i = 0; i < m_MD2.getnumberTriangles(); i++) 
			{
				// Build a Traingle object from the current Triangle

				CTriangle cTriangle;

				cTriangle.m_Vertices[0][0] = m_MD2.m_frame_list[frame].vertex[m_MD2.m_index_list[i].a].x;
				cTriangle.m_Vertices[0][1] = m_MD2.m_frame_list[frame].vertex[m_MD2.m_index_list[i].a].y;
				cTriangle.m_Vertices[0][2] = m_MD2.m_frame_list[frame].vertex[m_MD2.m_index_list[i].a].z;

				cTriangle.m_Vertices[1][0] = m_MD2.m_frame_list[frame].vertex[m_MD2.m_index_list[i].b].x;
				cTriangle.m_Vertices[1][1] = m_MD2.m_frame_list[frame].vertex[m_MD2.m_index_list[i].b].y;
				cTriangle.m_Vertices[1][2] = m_MD2.m_frame_list[frame].vertex[m_MD2.m_index_list[i].b].z;
							
				cTriangle.m_Vertices[2][0] = m_MD2.m_frame_list[frame].vertex[m_MD2.m_index_list[i].c].x;
				cTriangle.m_Vertices[2][1] = m_MD2.m_frame_list[frame].vertex[m_MD2.m_index_list[i].c].y;
				cTriangle.m_Vertices[2][2] = m_MD2.m_frame_list[frame].vertex[m_MD2.m_index_list[i].c].z;
				
				// Use line from the model's center point to the current vertex as normal
				float fNormal[3];

				// Pass normals, texture coordinates and vertices

				glTexCoord2f((m_MD2.m_index_list[i].a_s) / (float) m_Texture.GetWidth(), 
					(m_MD2.m_index_list[i].a_t) / (float) m_Texture.GetHeight());
				fNormal[0] = fCenterPoint[0] - cTriangle.m_Vertices[0][0];
				fNormal[1] = fCenterPoint[1] - cTriangle.m_Vertices[0][1];
				fNormal[2] = fCenterPoint[2] - cTriangle.m_Vertices[0][2];
				ReduceToUnit(fNormal);
				glNormal3fv(fNormal);
				glVertex3fv(cTriangle.m_Vertices[0]);

				glTexCoord2f((m_MD2.m_index_list[i].b_s) / (float) m_Texture.GetWidth(),
					(m_MD2.m_index_list[i].b_t) / (float) m_Texture.GetHeight());
				fNormal[0] = fCenterPoint[0] - cTriangle.m_Vertices[1][0];
				fNormal[1] = fCenterPoint[1] - cTriangle.m_Vertices[1][1];
				fNormal[2] = fCenterPoint[2] - cTriangle.m_Vertices[1][2];
				ReduceToUnit(fNormal);
				glNormal3fv(fNormal);
				glVertex3fv(cTriangle.m_Vertices[1]);

				glTexCoord2f((m_MD2.m_index_list[i].c_s) / (float) m_Texture.GetWidth(),
					(m_MD2.m_index_list[i].c_t) / (float) m_Texture.GetHeight());
				fNormal[0] = fCenterPoint[0] - cTriangle.m_Vertices[2][0];
				fNormal[1] = fCenterPoint[1] - cTriangle.m_Vertices[2][1];
				fNormal[2] = fCenterPoint[2] - cTriangle.m_Vertices[2][2];
				ReduceToUnit(fNormal);
				glNormal3fv(fNormal);
				glVertex3fv(cTriangle.m_Vertices[2]);
			}

		glEnd();

	glEndList();

	return TRUE;
}

void CModel::DrawMD2Model()
{
	// Draw the current MD2 model

	glCallList(m_DisplayListID);
}

void CModel::ReduceToUnit(float vector[])
{
	// Reduces a normal vector specified as a set of three coordinates,
	// to a unit normal vector of length one.

	// Calculate the length of the vector		
	float length = (float) sqrt(( vector[0] * vector[0]) + 
						        ( vector[1] * vector[1]) +
						        ( vector[2] * vector[2]) );

	// Keep the program from blowing up by providing an exceptable
	// value for vectors that may calculated too close to zero.
	if(length == 0.0f)
		length = 1.0f;

	// Dividing each element by the length will result in a
	// unit normal vector.
	vector[0] /= length;
	vector[1] /= length;
	vector[2] /= length;
}

void CModel::CalcModelCenter(float fCenter[3], CMD2 *cModel)
{
	// Calcuate the center point of a model through averaging all of its vertices

	fCenter[0] = 0.0f;
	fCenter[1] = 0.0f;
	fCenter[2] = 0.0f;

	// Use only 1 frame
	int frame = 0;

	// Loop trough all triangles and add all vertices together
	for (int iCurTriangle=0; iCurTriangle<cModel->getnumberTriangles(); iCurTriangle++) 
	{
		fCenter[0] += cModel->m_frame_list[frame].vertex[cModel->m_index_list[iCurTriangle].a].x;
		fCenter[1] += cModel->m_frame_list[frame].vertex[cModel->m_index_list[iCurTriangle].a].y;
		fCenter[2] += cModel->m_frame_list[frame].vertex[cModel->m_index_list[iCurTriangle].a].z;

		fCenter[0] += cModel->m_frame_list[frame].vertex[cModel->m_index_list[iCurTriangle].b].x;
		fCenter[1] += cModel->m_frame_list[frame].vertex[cModel->m_index_list[iCurTriangle].b].y;
		fCenter[2] += cModel->m_frame_list[frame].vertex[cModel->m_index_list[iCurTriangle].b].z;
							
		fCenter[0] += cModel->m_frame_list[frame].vertex[cModel->m_index_list[iCurTriangle].c].x;
		fCenter[1] += cModel->m_frame_list[frame].vertex[cModel->m_index_list[iCurTriangle].c].y;
		fCenter[2] += cModel->m_frame_list[frame].vertex[cModel->m_index_list[iCurTriangle].c].z;
	}

	// Divide the sum of all vertices trough the number of vertices
	fCenter[0] /= cModel->getnumberTriangles() * 3.0f;
	fCenter[1] /= cModel->getnumberTriangles() * 3.0f;
	fCenter[2] /= cModel->getnumberTriangles() * 3.0f;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -