📄 main.cpp
字号:
thisTexture = LoadPCXTexture(filename);
/*
else if ((strcmp(extStr, "TGA") == 0) || (strcmp(extStr, "tga") == 0) )
thisTexture = LoadTGATexture(filename);
//texType = TGA;
*/
return thisTexture;
}
// SetupMD2Texture()
// desc: sets up a texture for use with an MD2 model
void SetupMD2Texture(texture_t *thisTexture)
{
// set the proper parameters for an MD2 texture
glGenTextures(1, &thisTexture->texID);
glBindTexture(GL_TEXTURE_2D, thisTexture->texID);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
switch (thisTexture->textureType)
{
case BMP:
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, thisTexture->width, thisTexture->height,
GL_RGB, GL_UNSIGNED_BYTE, thisTexture->data);
break;
case PCX:
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, thisTexture->width, thisTexture->height,
GL_RGBA, GL_UNSIGNED_BYTE, thisTexture->data);
case TGA:
break;
default:
break;
}
}
// LoadMD2Model()
// desc: loads an MD2 model specified by filename and with the texture
// specified by textureName
modelData_t *LoadMD2Model(char *filename, char *textureName)
{
FILE *filePtr; // file pointer
int fileLen; // length of model file
char *buffer; // file buffer
modelData_t *model; // the model
modelHeader_t *modelHeader; // model header
texture_t *md2Texture; // model texture
stIndex_t *stPtr; // texture data
frame_t *frame; // frame data
vector_t *pointListPtr; // index variable
mesh_t *triIndex, *bufIndexPtr; // index variables
int i, j; // index variables
// open the model file
filePtr = fopen(filename, "rb");
if (filePtr == NULL)
return NULL;
// find length of file
fseek(filePtr, 0, SEEK_END);
fileLen = ftell(filePtr);
fseek(filePtr, 0, SEEK_SET);
// read entire file into buffer
buffer = (char*)malloc(fileLen + 1);
fread(buffer, sizeof(char), fileLen, filePtr);
// extract model file header from buffer
modelHeader = (modelHeader_t*)buffer;
// allocate memory for model data
model = (modelData_t*)malloc(sizeof(modelData_t));
if (model == NULL)
return NULL;
// allocate memory for all vertices used in model, including animations
model->pointList = (vector_t*)malloc(sizeof(vector_t)*modelHeader->numXYZ * modelHeader->numFrames);
// store vital model data
model->numPoints = modelHeader->numXYZ;
model->numFrames = modelHeader->numFrames;
model->frameSize = modelHeader->framesize;
// loop number of frames in model file
for(j = 0; j < modelHeader->numFrames; j++)
{
// offset to the points in this frame
frame = (frame_t*)&buffer[modelHeader->offsetFrames + modelHeader->framesize * j];
// calculate the point positions based on frame details
pointListPtr = (vector_t*)&model->pointList[modelHeader->numXYZ * j];
for(i = 0; i < modelHeader->numXYZ; i++)
{
pointListPtr[i].point[0] = frame->scale[0] * frame->fp[i].v[0] + frame->translate[0];
pointListPtr[i].point[1] = frame->scale[1] * frame->fp[i].v[1] + frame->translate[1];
pointListPtr[i].point[2] = frame->scale[2] * frame->fp[i].v[2] + frame->translate[2];
}
}
// load the model texture
md2Texture = LoadTexture(textureName);
if (md2Texture != NULL)
{
// setup texture for opengl and store it in model data structure
SetupMD2Texture(md2Texture);
model->modelTex = md2Texture;
}
else
return NULL;
// allocate memory for the model texture coordinates
model->st = (texCoord_t*)malloc(sizeof(texCoord_t)*modelHeader->numST);
// store number of texture coordinates
model->numST = modelHeader->numST;
// set texture pointer to texture coordinate offset
stPtr = (stIndex_t*)&buffer[modelHeader->offsetST];
// calculate and store the texture coordinates for the model
for (i = 0; i < modelHeader->numST; i++)
{
model->st[i].s = (float)stPtr[i].s / (float)md2Texture->width;
model->st[i].t = (float)stPtr[i].t / (float)md2Texture->height;
}
// allocate an index of triangles
triIndex = (mesh_t*)malloc(sizeof(mesh_t) * modelHeader->numTris);
// set total number of triangles
model->numTriangles = modelHeader->numTris;
model->triIndex = triIndex;
// point to triangle indexes in buffer
bufIndexPtr = (mesh_t*)&buffer[modelHeader->offsetTris];
// create a mesh (triangle) list
for (j = 0; j < model->numFrames; j++)
{
// for all triangles in each frame
for(i = 0; i < modelHeader->numTris; i++)
{
triIndex[i].meshIndex[0] = bufIndexPtr[i].meshIndex[0];
triIndex[i].meshIndex[1] = bufIndexPtr[i].meshIndex[1];
triIndex[i].meshIndex[2] = bufIndexPtr[i].meshIndex[2];
triIndex[i].stIndex[0] = bufIndexPtr[i].stIndex[0];
triIndex[i].stIndex[1] = bufIndexPtr[i].stIndex[1];
triIndex[i].stIndex[2] = bufIndexPtr[i].stIndex[2];
}
}
// close file and free memory
fclose(filePtr);
free(buffer);
model->currentFrame = 0;
model->nextFrame = 1;
model->interpol = 0.0;
return model;
}
// CalculateNormal()
// desc: given 3 points, calculates the normal to the points
void CalculateNormal( float *p1, float *p2, float *p3 )
{
float a[3], b[3], result[3];
float length;
a[0] = p1[0] - p2[0];
a[1] = p1[1] - p2[1];
a[2] = p1[2] - p2[2];
b[0] = p1[0] - p3[0];
b[1] = p1[1] - p3[1];
b[2] = p1[2] - p3[2];
result[0] = a[1] * b[2] - b[1] * a[2];
result[1] = b[0] * a[2] - a[0] * b[2];
result[2] = a[0] * b[1] - b[0] * a[1];
// calculate the length of the normal
length = (float)sqrt(result[0]*result[0] + result[1]*result[1] + result[2]*result[2]);
// normalize and specify the normal
glNormal3f(result[0]/length, result[1]/length, result[2]/length);
}
// DisplayMD2()
// desc: displays the frameNum frame of an MD2 model
void DisplayMD2(modelData_t *model, int frameNum)
{
vector_t *pointList;
int i;
// create a pointer to the frame we want to show
pointList = &model->pointList[model->numPoints * frameNum];
// set the texture
glBindTexture(GL_TEXTURE_2D, model->modelTex->texID);
// display the textured model with proper lighting normals
glBegin(GL_TRIANGLES);
for(i = 0; i < model->numTriangles; i++)
{
CalculateNormal(pointList[model->triIndex[i].meshIndex[0]].point,
pointList[model->triIndex[i].meshIndex[2]].point,
pointList[model->triIndex[i].meshIndex[1]].point);
glTexCoord2f(model->st[model->triIndex[i].stIndex[0]].s,
model->st[model->triIndex[i].stIndex[0]].t);
glVertex3fv(pointList[model->triIndex[i].meshIndex[0]].point);
glTexCoord2f(model->st[model->triIndex[i].stIndex[2]].s ,
model->st[model->triIndex[i].stIndex[2]].t);
glVertex3fv(pointList[model->triIndex[i].meshIndex[2]].point);
glTexCoord2f(model->st[model->triIndex[i].stIndex[1]].s,
model->st[model->triIndex[i].stIndex[1]].t);
glVertex3fv(pointList[model->triIndex[i].meshIndex[1]].point);
}
glEnd();
}
// DisplayMD2Interpolate()
// desc: displays an animated MD2 model with keyframe interpolation
void DisplayMD2Interpolate(modelData_t *model)
{
vector_t *pointList; // current frame vertices
vector_t *nextPointList; // next frame vertices
int i; // index counter
float x1, y1, z1; // current frame point values
float x2, y2, z2; // next frame point values
vector_t vertex[3];
if (model == NULL)
return;
if (model->interpol >= 1.0)
{
model->interpol = 0.0f;
model->currentFrame++;
if (model->currentFrame >= model->numFrames)
model->currentFrame = 0;
model->nextFrame = model->currentFrame + 1;
if (model->nextFrame >= model->numFrames)
model->nextFrame = 0;
}
pointList = &model->pointList[model->numPoints*model->currentFrame];
nextPointList = &model->pointList[model->numPoints*model->nextFrame];
glBindTexture(GL_TEXTURE_2D, model->modelTex->texID);
glBegin(GL_TRIANGLES);
for (i = 0; i < model->numTriangles; i++)
{
// get first points of each frame
x1 = pointList[model->triIndex[i].meshIndex[0]].point[0];
y1 = pointList[model->triIndex[i].meshIndex[0]].point[1];
z1 = pointList[model->triIndex[i].meshIndex[0]].point[2];
x2 = nextPointList[model->triIndex[i].meshIndex[0]].point[0];
y2 = nextPointList[model->triIndex[i].meshIndex[0]].point[1];
z2 = nextPointList[model->triIndex[i].meshIndex[0]].point[2];
// xi + percentage * (xf - xi)
// store first interpolated vertex of triangle
vertex[0].point[0] = x1 + model->interpol * (x2 - x1);
vertex[0].point[1] = y1 + model->interpol * (y2 - y1);
vertex[0].point[2] = z1 + model->interpol * (z2 - z1);
// get second points of each frame
x1 = pointList[model->triIndex[i].meshIndex[2]].point[0];
y1 = pointList[model->triIndex[i].meshIndex[2]].point[1];
z1 = pointList[model->triIndex[i].meshIndex[2]].point[2];
x2 = nextPointList[model->triIndex[i].meshIndex[2]].point[0];
y2 = nextPointList[model->triIndex[i].meshIndex[2]].point[1];
z2 = nextPointList[model->triIndex[i].meshIndex[2]].point[2];
// store second interpolated vertex of triangle
vertex[2].point[0] = x1 + model->interpol * (x2 - x1);
vertex[2].point[1] = y1 + model->interpol * (y2 - y1);
vertex[2].point[2] = z1 + model->interpol * (z2 - z1);
// get third points of each frame
x1 = pointList[model->triIndex[i].meshIndex[1]].point[0];
y1 = pointList[model->triIndex[i].meshIndex[1]].point[1];
z1 = pointList[model->triIndex[i].meshIndex[1]].point[2];
x2 = nextPointList[model->triIndex[i].meshIndex[1]].point[0];
y2 = nextPointList[model->triIndex[i].meshIndex[1]].point[1];
z2 = nextPointList[model->triIndex[i].meshIndex[1]].point[2];
// store third interpolated vertex of triangle
vertex[1].point[0] = x1 + model->interpol * (x2 - x1);
vertex[1].point[1] = y1 + model->interpol * (y2 - y1);
vertex[1].point[2] = z1 + model->interpol * (z2 - z1);
// calculate the normal of the triangle
CalculateNormal(vertex[0].point, vertex[2].point, vertex[1].point);
// render properly textured triangle
glTexCoord2f(model->st[model->triIndex[i].stIndex[0]].s,
model->st[model->triIndex[i].stIndex[0]].t);
glVertex3fv(vertex[0].point);
glTexCoord2f(model->st[model->triIndex[i].stIndex[2]].s ,
model->st[model->triIndex[i].stIndex[2]].t);
glVertex3fv(vertex[2].point);
glTexCoord2f(model->st[model->triIndex[i].stIndex[1]].s,
model->st[model->triIndex[i].stIndex[1]].t);
glVertex3fv(vertex[1].point);
}
glEnd();
model->interpol += 0.05f; // increase percentage of interpolation between frames
}
// DisplayMD2Interpolate()
// desc: displays a frame of the model between startFrame and endFrame with an interpolation percent
void DisplayMD2Interpolate(modelData_t *model, int startFrame, int endFrame, float percent)
{
vector_t *pointList; // current frame vertices
vector_t *nextPointList; // next frame vertices
int i; // index counter
float x1, y1, z1; // current frame point values
float x2, y2, z2; // next frame point values
vector_t vertex[3];
if (model == NULL)
return;
if ( (startFrame < 0) || (endFrame < 0) )
return;
if ( (startFrame >= model->numFrames) || (endFrame >= model->numFrames) )
return;
if (model->interpol >= 1.0)
{
model->interpol = 0.0f;
model->currentFrame++;
if (model->currentFrame >= endFrame)//model->numFrames)
model->currentFrame = startFrame; //0;
model->nextFrame = model->currentFrame + 1;
if (model->nextFrame >= endFrame)
model->nextFrame = startFrame;
}
pointList = &model->pointList[model->numPoints*model->currentFrame];
nextPointList = &model->pointList[model->numPoints*model->nextFrame];
glBindTexture(GL_TEXTURE_2D, model->modelTex->texID);
glBegin(GL_TRIANGLES);
for (i = 0; i < model->numTriangles; i++)
{
// get first points of each frame
x1 = pointList[model->triIndex[i].meshIndex[0]].point[0];
y1 = pointList[model->triIndex[i].meshIndex[0]].point[1];
z1 = pointList[model->triIndex[i].meshIndex[0]].point[2];
x2 = nextPointList[model->triIndex[i].meshIndex[0]].point[0];
y2 = nextPointList[model->triIndex[i].meshIndex[0]].point[1];
z2 = nextPointList[model->triIndex[i].meshIndex[0]].point[2];
// store first interpolated vertex of triangle
vertex[0].point[0] = x1 + model->interpol * (x2 - x1);
vertex[0].point[1] = y1 + model->interpol * (y2 - y1);
vertex[0].point[2] = z1 + model->interpol * (z2 - z1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -