/*/
// MD2 Viewer (c) 1999 by Mete Ciragan
//
// file: md2.c
// last modified: Apr 28 1999, Mete Ciragan
// copyright: The programs and associated files contained in this
// distribution were developed by Mete Ciragan. The programs
// are not in the public domain, but they are freely
// distributable without licensing fees. These programs are
// provided without guarantee or warrantee expressed or
// implied.
//
// version: 1.4
//
// email: mete@swissquake.ch
// web: http://www.swissquake.ch/chumbalum-soft/
/*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* memset */
#include <math.h> /* sqrt */
//#include <mx/gl.h>
#include <windows.h>
#include <gl/gl.h>
#include "md2.h"
#define NUMVERTEXNORMALS 162
float avertexnormals[NUMVERTEXNORMALS][3] = {
#include "anorms.h"
};
static int g_glcmds = 1; /* use glcommands */
static int g_interp = 1; /* interpolate frames */
/*
* load model
*/
md2_model_t*
md2_readModel (const char *filename)
{
FILE *file;
md2_model_t *model;
byte buffer[MD2_MAX_FRAMESIZE];
int i;
model = (md2_model_t *) malloc (sizeof (md2_model_t));
if (!model)
return 0;
file = fopen (filename, "rb");
if (!file)
{
free (model);
return 0;
}
/* initialize model and read header */
memset (model, 0, sizeof (md2_model_t));
fread (&model->header, sizeof (md2_header_t), 1, file);
#if 0
printf ("magic:\t\t%d\n", model->header.magic);
printf ("version:\t\t%d\n", model->header.version);
printf ("skinWidth:\t\t%d\n", model->header.skinWidth);
printf ("skinHeight:\t\t%d\n", model->header.skinHeight);
printf ("frameSize:\t\t%d\n", model->header.frameSize);
printf ("numSkins:\t\t%d\n", model->header.numSkins);
printf ("numVertices:\t\t%d\n", model->header.numVertices);
printf ("numTexCoords:\t\t%d\n", model->header.numTexCoords);
printf ("numTriangles:\t\t%d\n", model->header.numTriangles);
printf ("numGlCommands:\t\t%d\n", model->header.numGlCommands);
printf ("numFrames:\t\t%d\n", model->header.numFrames);
printf ("offsetSkins:\t\t%d\n", model->header.offsetSkins);
printf ("offsetTexCoords:\t%d\n", model->header.offsetTexCoords);
printf ("offsetTriangles:\t%d\n", model->header.offsetTriangles);
printf ("offsetFrames:\t\t%d\n", model->header.offsetFrames);
printf ("offsetGlCommands:\t%d\n", model->header.offsetGlCommands);
printf ("offsetEnd:\t\t%d\n", model->header.offsetEnd);
#endif
if (model->header.magic != (int) (('2' << 24) + ('P' << 16) + ('D' << 8) + 'I'))
{
fclose (file);
free (model);
return 0;
}
/* read skins */
fseek (file, model->header.offsetSkins, SEEK_SET);
if (model->header.numSkins > 0)
{
model->skins = (md2_skin_t *) malloc (sizeof (md2_skin_t) * model->header.numSkins);
if (!model->skins)
{
md2_freeModel (model);
return 0;
}
for (i = 0; i < model->header.numSkins; i++)
fread (&model->skins[i], sizeof (md2_skin_t), 1, file);
}
/* read texture coordinates */
fseek (file, model->header.offsetTexCoords, SEEK_SET);
if (model->header.numTexCoords > 0)
{
model->texCoords = (md2_textureCoordinate_t *) malloc (sizeof (md2_textureCoordinate_t) * model->header.numTexCoords);
if (!model->texCoords)
{
md2_freeModel (model);
return 0;
}
for (i = 0; i < model->header.numTexCoords; i++)
fread (&model->texCoords[i], sizeof (md2_textureCoordinate_t), 1, file);
}
/* read triangles */
fseek (file, model->header.offsetTriangles, SEEK_SET);
if (model->header.numTriangles > 0)
{
model->triangles = (md2_triangle_t *) malloc (sizeof (md2_triangle_t) * model->header.numTriangles);
if (!model->triangles)
{
md2_freeModel (model);
return 0;
}
for (i = 0; i < model->header.numTriangles; i++)
fread (&model->triangles[i], sizeof (md2_triangle_t), 1, file);
}
/* read alias frames */
fseek (file, model->header.offsetFrames, SEEK_SET);
if (model->header.numFrames > 0)
{
model->frames = (md2_frame_t *) malloc (sizeof (md2_frame_t) * model->header.numFrames);
if (!model->frames)
{
md2_freeModel (model);
return 0;
}
for (i = 0; i < model->header.numFrames; i++)
{
md2_alias_frame_t *frame = (md2_alias_frame_t *) buffer;
int j;
model->frames[i].vertices = (md2_triangleVertex_t *) malloc (sizeof (md2_triangleVertex_t) * model->header.numVertices);
if (!model->frames[i].vertices)
{
md2_freeModel (model);
return 0;
}
fread (frame, 1, model->header.frameSize, file);
strcpy (model->frames[i].name, frame->name);
for (j = 0; j < model->header.numVertices; j++)
{
model->frames[i].vertices[j].vertex[0] = (float) ((int) frame->alias_vertices[j].vertex[0]) * frame->scale[0] + frame->translate[0];
model->frames[i].vertices[j].vertex[2] = -1* ((float) ((int) frame->alias_vertices[j].vertex[1]) * frame->scale[1] + frame->translate[1]);
model->frames[i].vertices[j].vertex[1] = (float) ((int) frame->alias_vertices[j].vertex[2]) * frame->scale[2] + frame->translate[2];
model->frames[i].vertices[j].normal[0] = avertexnormals[frame->alias_vertices[j].lightNormalIndex][0];
model->frames[i].vertices[j].normal[1] = avertexnormals[frame->alias_vertices[j].lightNormalIndex][1];
model->frames[i].vertices[j].normal[2] = avertexnormals[frame->alias_vertices[j].lightNormalIndex][2];
//model->frames[i].vertices[j].lightNormalIndex = frame->alias_vertices[j].lightNormalIndex;
}
}
}
/* read gl commands */
fseek (file, model->header.offsetGlCommands, SEEK_SET);
if (model->header.numGlCommands)
{
model->glCommandBuffer = (int *) malloc (sizeof (int) * model->header.numGlCommands);
if (!model->glCommandBuffer)
{
md2_freeModel (model);
return 0;
}
fread (model->glCommandBuffer, sizeof (int), model->header.numGlCommands, file);
}
fclose (file);
return model;
}
/*
* free model
*/
void
md2_freeModel (md2_model_t *model)
{
if (model)
{
if (model->skins)
free (model->skins);
if (model->texCoords)
free (model->texCoords);
if (model->triangles)
free (model->triangles);
if (model->frames)
{
int i;
for (i = 0; i < model->header.numFrames; i++)
{
if (model->frames[i].vertices)
free (model->frames[i].vertices);
}
free (model->frames);
}
if (model->glCommandBuffer)
free (model->glCommandBuffer);
free (model);
}
}
/*
* set draw style, either with glcommands, interpolated
*/
void
md2_setStyle (int glcmds, int interp)
{
g_glcmds = glcmds;
g_interp = interp;
}
/*
* center model
*
*/
void
md2_getBoundingBox (md2_model_t *model, float *minmax)
{
int i;
float minx, maxx;
float miny, maxy;
float minz, maxz;
minx = miny = minz = 999999.0f;
maxx = maxy = maxz = -999999.0f;
/* get bounding box */
for (i = 0; i < model->header.numVertices; i++)
{
md2_triangleVertex_t *v = &model->frames[0].vertices[i];
if (v->vertex[0] < minx)
minx = v->vertex[0];
else if (v->vertex[0] > maxx)
maxx = v->vertex[0];
if (v->vertex[1] < miny)
miny = v->vertex[1];
else if (v->vertex[1] > maxy)
maxy = v->vertex[1];
if (v->vertex[2] < minz)
minz = v->vertex[2];
else if (v->vertex[2] > maxz)
maxz = v->vertex[2];
}
minmax[0] = minx;
minmax[1] = maxx;
minmax[2] = miny;
minmax[3] = maxy;
minmax[4] = minz;
minmax[5] = maxz;
}
/*
* draw normal
*
*/
void
_md2_drawModel (md2_model_t *model, int frame)
{
int i;
md2_frame_t *f = &model->frames[frame];
glBegin (GL_TRIANGLES);
for (i = 0; i < model->header.numTriangles; i++)
{
md2_triangle_t *t = &model->triangles[i];
//int lightNormalIndex;
/*
lightNormalInde
- 1
- 2
前往页