📄 md2.cpp
字号:
extreme.y = currPoint.y;
}
if(currPoint.z > extreme.z) {
extreme.z = currPoint.z;
}
}
g_Debug->Log("Extreme x: %f - y: %f - z: %f\n", extreme.x, extreme.y, extreme.z );
SetExtents(extreme);
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////
bool GcMD2::LoadSkin(char *skinName, uint index)
{
// Check to see that the skin is valid and that a texture space for it exist
if((texture == NULL) || (index > numSkins - 1)) {
g_Debug->Log("Failed to load skin %d\n", index);
return false;
}
// Create the skin
texture[index].Create(skinName);
// Calcualte the texutre coords
for(int i = 0; i < numTexCrds; i++)
{
texCrds[i].x /= texture[index].Width();
texCrds[i].y /= texture[index].Height();
}
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////
void GcMD2::SetNumberOfSkins(uint num)
{
// Delete previus textures if needed
if(texture != NULL) {
delete [] texture;
}
// Create new textures
texture = new GcTexture[num];
// Save the number of skins
numSkins = num;
}
////////////////////////////////////////////////////////////////////////////////////////////
bool GcMD2::Animate(int startFrame, int endFrame, float percent)
{
GcPoint3 *currList; // Holds the current frame's vertices
GcPoint3 *nextList; // Holds the next frame's vertices
GcPoint3 currPoint;
GcPoint3 nextPoint;
GcPoint3 vertex[3]; // The vertex's to be rendered
GcVector3 normal; // The vertex normal
if(startFrame > currentFrame) {
currentFrame = startFrame;
}
if((startFrame < 0) || (endFrame < 0)) {
return false;
}
if((startFrame >= numFrames) || (endFrame >= numFrames)) {
return false;
}
if(interpol >= 1.0f)
{
// Re-set the interpolation
interpol = 0.0f;
// Another fram has gone by
currentFrame++;
// Time to start the animation over?
if(currentFrame >= endFrame) {
currentFrame = startFrame;
}
// Set the next frame
nextFrame = currentFrame + 1;
// Time to start the animation over?
if(nextFrame >= endFrame) {
nextFrame = startFrame;
}
}
// Set the pointers to point to this frame's vertices, and the next
currList = &vertexList[numVertices*currentFrame];
nextList = &vertexList[numVertices*nextFrame];
// Bind the texture for the model
if(numSkins > 0) {
texture[activeSkin].Bind();
}
glPushMatrix();
glMultMatrixf(m_worldMatrix);
glBegin(GL_TRIANGLES);
for(int i = 0; i < numTris; i++)
{
// Get the first points from this fram and the next
currPoint.x = currList[triIndex[i].triInd[0]].x;
currPoint.y = currList[triIndex[i].triInd[0]].y;
currPoint.z = currList[triIndex[i].triInd[0]].z;
nextPoint.x = nextList[triIndex[i].triInd[0]].x;
nextPoint.y = nextList[triIndex[i].triInd[0]].y;
nextPoint.z = nextList[triIndex[i].triInd[0]].z;
// Claculate the first interpolated vertex
vertex[0] = (nextPoint - currPoint) * interpol + currPoint;
// Get the first points from this fram and the next
currPoint.x = currList[triIndex[i].triInd[1]].x;
currPoint.y = currList[triIndex[i].triInd[1]].y;
currPoint.z = currList[triIndex[i].triInd[1]].z;
nextPoint.x = nextList[triIndex[i].triInd[1]].x;
nextPoint.y = nextList[triIndex[i].triInd[1]].y;
nextPoint.z = nextList[triIndex[i].triInd[1]].z;
// Claculate the second interpolated vertex
vertex[1] = (nextPoint - currPoint) * interpol + currPoint;
// Get the first points from this fram and the next
currPoint.x = currList[triIndex[i].triInd[2]].x;
currPoint.y = currList[triIndex[i].triInd[2]].y;
currPoint.z = currList[triIndex[i].triInd[2]].z;
nextPoint.x = nextList[triIndex[i].triInd[2]].x;
nextPoint.y = nextList[triIndex[i].triInd[2]].y;
nextPoint.z = nextList[triIndex[i].triInd[2]].z;
// Claculate the first interpolated vertex
vertex[2] = (nextPoint - currPoint) * interpol + currPoint;
// Calculate the normal
normal = GcMath::ClaculateNormal(vertex[0], vertex[1], vertex[3]);
// Give the normal to open gl
glNormal3f(normal.x, normal.y, normal.z);
// Render the triangle
glTexCoord2f(texCrds[triIndex[i].texCrdInd[0]].x,
texCrds[triIndex[i].texCrdInd[0]].y);
glVertex3fv(vertex[0].array);
glTexCoord2f(texCrds[triIndex[i].texCrdInd[2]].x,
texCrds[triIndex[i].texCrdInd[2]].y);
glVertex3fv(vertex[2].array);
glTexCoord2f(texCrds[triIndex[i].texCrdInd[1]].x,
texCrds[triIndex[i].texCrdInd[1]].y);
glVertex3fv(vertex[1].array);
}
glEnd();
interpol += percent;
glPopMatrix();
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
bool GcMD2::RenderKeyFrame(int frame)
{
GcPoint3 *currList; // Holds the current frame's vertices
GcPoint3 vertex[3]; // The vertices to be rendered
GcVector3 normal; // The triangle normal
// Check for a valid frame
if(frame < 0 || frame > numFrames) {
return false;
}
// Set the pointers to point to this frame's vertices
currList = &vertexList[numVertices * frame];
// Bind the texture for the model
if(numSkins > 0) {
texture[activeSkin].Bind();
}
glPushMatrix();
glMultMatrixf(m_worldMatrix);
glBegin(GL_TRIANGLES);
for(int i = 0; i < numTris; i++)
{
// Get the first point from this frame
vertex[0].x = currList[triIndex[i].triInd[0]].x;
vertex[0].y = currList[triIndex[i].triInd[0]].y;
vertex[0].z = currList[triIndex[i].triInd[0]].z;
// Get the second point from this frame
vertex[1].x = currList[triIndex[i].triInd[1]].x;
vertex[1].y = currList[triIndex[i].triInd[1]].y;
vertex[1].z = currList[triIndex[i].triInd[1]].z;
// Get the third point from this frame
vertex[2].x = currList[triIndex[i].triInd[2]].x;
vertex[2].y = currList[triIndex[i].triInd[2]].y;
vertex[2].z = currList[triIndex[i].triInd[2]].z;
// Calculate the normal
normal = GcMath::ClaculateNormal(vertex[0], vertex[1], vertex[3]);
// Give the normal to OpenGL
glNormal3f(normal.x, normal.y, normal.z);
// Render the triangle
glTexCoord2f(texCrds[triIndex[i].texCrdInd[0]].x,
texCrds[triIndex[i].texCrdInd[0]].y);
glVertex3fv(vertex[0].array);
glTexCoord2f(texCrds[triIndex[i].texCrdInd[2]].x,
texCrds[triIndex[i].texCrdInd[2]].y);
glVertex3fv(vertex[2].array);
glTexCoord2f(texCrds[triIndex[i].texCrdInd[1]].x,
texCrds[triIndex[i].texCrdInd[1]].y);
glVertex3fv(vertex[1].array);
}
glEnd();
glPopMatrix();
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
void GcMD2::Destroy()
{
// Clear up the memory
if(triIndex != NULL) {
delete [] triIndex;
triIndex = NULL;
}
if(texCrds != NULL) {
delete [] texCrds;
texCrds = NULL;
}
if(vertexList != NULL) {
delete [] vertexList;
vertexList = NULL;
}
if(texture != NULL) {
delete [] texture;
texture = NULL;
}
}
////////////////////////////////////////////////////////////////////////////////////////////
bool GcMD2::SaveAsGMD(char *fileName)
{
// Open the file for writing
ofstream file(fileName, ios::out | ios::binary);
// Check for success
if(!file.is_open()) {
return false;
}
// Create a GMD header
GMDHeader *header = new GMDHeader;
header->ident = GMD_IDENT;
header->numFrames = numFrames;
header->numTexCoords = numTexCrds;
header->numTris = numTris;
header->numVertices = numVertices;
header->offsetEnd = sizeof(GMDHeader) + sizeof(GcPoint3) * numVertices * numFrames +
sizeof(GcPoint2) * numTexCrds + sizeof(MD2Tri) * numTris;
header->offsetFrames = sizeof(GMDHeader);
header->offsetTexCoords = sizeof(GMDHeader) + sizeof(GcPoint3) * numVertices * numFrames;
header->offsetTris = sizeof(GMDHeader) + sizeof(GcPoint3) * numVertices * numFrames +
sizeof(GcPoint2) * numTexCrds;
// Write the header to the file
file.write((char*)header, sizeof(GMDHeader));
// Write the frames (vertices to the list)
file.write((char*)vertexList, sizeof(GMDVertex) * header->numVertices * header->numFrames);
// Write the texture coordinates to the file
file.write((char*)texCrds, sizeof(GMDTexCoord) * header->numTexCoords);
// Write the trinagle indeices to the file
file.write((char*)triIndex, sizeof(GMDTri) * header->numTris);
// Close the file
file.close();
// Clean up temporary files
delete header;
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -