2013-06-23 07:49:34 +00:00
|
|
|
#ifndef __GL_MODELS_H_
|
|
|
|
#define __GL_MODELS_H_
|
|
|
|
|
2016-05-03 13:45:21 +00:00
|
|
|
#include "tarray.h"
|
2013-06-23 07:49:34 +00:00
|
|
|
#include "gl/utility/gl_geometric.h"
|
2014-06-15 19:56:37 +00:00
|
|
|
#include "gl/data/gl_vertexbuffer.h"
|
2013-06-23 07:49:34 +00:00
|
|
|
#include "p_pspr.h"
|
|
|
|
#include "r_data/voxels.h"
|
|
|
|
|
2014-06-15 19:56:37 +00:00
|
|
|
|
2013-06-23 07:49:34 +00:00
|
|
|
#define MAX_LODS 4
|
|
|
|
|
|
|
|
enum { VX, VZ, VY };
|
|
|
|
|
|
|
|
#define MD2_MAGIC 0x32504449
|
|
|
|
#define DMD_MAGIC 0x4D444D44
|
|
|
|
#define MD3_MAGIC 0x33504449
|
|
|
|
#define NUMVERTEXNORMALS 162
|
|
|
|
|
2016-05-03 13:45:21 +00:00
|
|
|
FTextureID LoadSkin(const char * path, const char * fn);
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
class FModel
|
|
|
|
{
|
|
|
|
public:
|
2014-10-24 09:43:25 +00:00
|
|
|
|
|
|
|
FModel()
|
|
|
|
{
|
|
|
|
mVBuf = NULL;
|
|
|
|
}
|
|
|
|
virtual ~FModel();
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length) = 0;
|
|
|
|
virtual int FindFrame(const char * name) = 0;
|
2014-06-19 11:58:49 +00:00
|
|
|
virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0) = 0;
|
2014-10-24 09:43:25 +00:00
|
|
|
virtual void BuildVertexBuffer() = 0;
|
2016-05-03 16:14:16 +00:00
|
|
|
virtual void AddSkins(BYTE *hitlist) = 0;
|
2015-04-12 16:26:52 +00:00
|
|
|
void DestroyVertexBuffer()
|
|
|
|
{
|
|
|
|
delete mVBuf;
|
|
|
|
mVBuf = NULL;
|
|
|
|
}
|
2014-12-31 11:53:29 +00:00
|
|
|
virtual float getAspectFactor() { return 1.f; }
|
2013-06-23 07:49:34 +00:00
|
|
|
|
2014-10-24 09:43:25 +00:00
|
|
|
FModelVertexBuffer *mVBuf;
|
2013-06-23 07:49:34 +00:00
|
|
|
FString mFileName;
|
|
|
|
};
|
|
|
|
|
|
|
|
class FDMDModel : public FModel
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
|
|
|
|
struct FTriangle
|
|
|
|
{
|
2015-05-07 09:36:31 +00:00
|
|
|
unsigned short vertexIndices[3];
|
|
|
|
unsigned short textureIndices[3];
|
2013-06-23 07:49:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct DMDHeader
|
|
|
|
{
|
|
|
|
int magic;
|
|
|
|
int version;
|
|
|
|
int flags;
|
|
|
|
};
|
|
|
|
|
2014-06-19 15:06:26 +00:00
|
|
|
struct DMDModelVertex
|
2013-06-23 07:49:34 +00:00
|
|
|
{
|
|
|
|
float xyz[3];
|
|
|
|
};
|
|
|
|
|
|
|
|
struct FTexCoord
|
|
|
|
{
|
|
|
|
short s, t;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct FGLCommandVertex
|
|
|
|
{
|
|
|
|
float s, t;
|
|
|
|
int index;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct DMDInfo
|
|
|
|
{
|
|
|
|
int skinWidth;
|
|
|
|
int skinHeight;
|
|
|
|
int frameSize;
|
|
|
|
int numSkins;
|
|
|
|
int numVertices;
|
|
|
|
int numTexCoords;
|
|
|
|
int numFrames;
|
|
|
|
int numLODs;
|
|
|
|
int offsetSkins;
|
|
|
|
int offsetTexCoords;
|
|
|
|
int offsetFrames;
|
|
|
|
int offsetLODs;
|
|
|
|
int offsetEnd;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ModelFrame
|
|
|
|
{
|
|
|
|
char name[16];
|
2015-04-12 16:26:52 +00:00
|
|
|
unsigned int vindex;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ModelFrameVertexData
|
|
|
|
{
|
2014-06-19 15:06:26 +00:00
|
|
|
DMDModelVertex *vertices;
|
|
|
|
DMDModelVertex *normals;
|
2013-06-23 07:49:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct DMDLoDInfo
|
|
|
|
{
|
|
|
|
int numTriangles;
|
|
|
|
int numGlCommands;
|
|
|
|
int offsetTriangles;
|
|
|
|
int offsetGlCommands;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct DMDLoD
|
|
|
|
{
|
|
|
|
FTriangle * triangles;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-12 16:26:52 +00:00
|
|
|
int mLumpNum;
|
2013-06-23 07:49:34 +00:00
|
|
|
DMDHeader header;
|
|
|
|
DMDInfo info;
|
2016-05-03 13:45:21 +00:00
|
|
|
FTextureID * skins;
|
2013-06-23 07:49:34 +00:00
|
|
|
ModelFrame * frames;
|
2015-04-12 16:26:52 +00:00
|
|
|
bool allowTexComp; // Allow texture compression with this.
|
|
|
|
|
|
|
|
// Temp data only needed for buffer construction
|
|
|
|
FTexCoord * texCoords;
|
|
|
|
ModelFrameVertexData *framevtx;
|
2013-06-23 07:49:34 +00:00
|
|
|
DMDLoDInfo lodInfo[MAX_LODS];
|
|
|
|
DMDLoD lods[MAX_LODS];
|
|
|
|
|
|
|
|
public:
|
|
|
|
FDMDModel()
|
|
|
|
{
|
2015-04-12 16:26:52 +00:00
|
|
|
mLumpNum = -1;
|
2013-06-23 07:49:34 +00:00
|
|
|
frames = NULL;
|
|
|
|
skins = NULL;
|
2014-06-29 21:24:16 +00:00
|
|
|
for (int i = 0; i < MAX_LODS; i++)
|
|
|
|
{
|
|
|
|
lods[i].triangles = NULL;
|
|
|
|
}
|
2013-06-23 07:49:34 +00:00
|
|
|
info.numLODs = 0;
|
2014-06-29 21:24:16 +00:00
|
|
|
texCoords = NULL;
|
2015-04-12 16:26:52 +00:00
|
|
|
framevtx = NULL;
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
virtual ~FDMDModel();
|
|
|
|
|
|
|
|
virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length);
|
|
|
|
virtual int FindFrame(const char * name);
|
2014-06-19 11:58:49 +00:00
|
|
|
virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0);
|
2015-04-12 16:26:52 +00:00
|
|
|
virtual void LoadGeometry();
|
2016-05-03 16:14:16 +00:00
|
|
|
virtual void AddSkins(BYTE *hitlist);
|
|
|
|
|
2015-04-12 16:26:52 +00:00
|
|
|
void UnloadGeometry();
|
2014-10-24 09:43:25 +00:00
|
|
|
void BuildVertexBuffer();
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
// This uses the same internal representation as DMD
|
|
|
|
class FMD2Model : public FDMDModel
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
FMD2Model() {}
|
|
|
|
virtual ~FMD2Model();
|
|
|
|
|
|
|
|
virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length);
|
2015-04-12 16:26:52 +00:00
|
|
|
virtual void LoadGeometry();
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class FMD3Model : public FModel
|
|
|
|
{
|
|
|
|
struct MD3Tag
|
|
|
|
{
|
|
|
|
// Currently I have no use for this
|
|
|
|
};
|
|
|
|
|
|
|
|
struct MD3TexCoord
|
|
|
|
{
|
|
|
|
float s,t;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct MD3Vertex
|
|
|
|
{
|
|
|
|
float x,y,z;
|
|
|
|
float nx,ny,nz;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct MD3Triangle
|
|
|
|
{
|
|
|
|
int VertIndex[3];
|
|
|
|
};
|
|
|
|
|
|
|
|
struct MD3Surface
|
|
|
|
{
|
|
|
|
int numVertices;
|
|
|
|
int numTriangles;
|
|
|
|
int numSkins;
|
|
|
|
|
2016-05-03 13:45:21 +00:00
|
|
|
FTextureID * skins;
|
2013-06-23 07:49:34 +00:00
|
|
|
MD3Triangle * tris;
|
|
|
|
MD3TexCoord * texcoords;
|
|
|
|
MD3Vertex * vertices;
|
|
|
|
|
2014-06-19 20:24:33 +00:00
|
|
|
unsigned int vindex; // contains numframes arrays of vertices
|
|
|
|
unsigned int iindex;
|
|
|
|
|
2013-06-23 07:49:34 +00:00
|
|
|
MD3Surface()
|
|
|
|
{
|
|
|
|
tris=NULL;
|
|
|
|
vertices=NULL;
|
|
|
|
texcoords=NULL;
|
2014-06-19 20:24:33 +00:00
|
|
|
vindex = iindex = UINT_MAX;
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
~MD3Surface()
|
2014-10-24 09:43:25 +00:00
|
|
|
{
|
|
|
|
if (skins) delete [] skins;
|
2015-04-12 17:42:03 +00:00
|
|
|
UnloadGeometry();
|
2014-10-24 09:43:25 +00:00
|
|
|
}
|
|
|
|
|
2015-04-12 17:42:03 +00:00
|
|
|
void UnloadGeometry()
|
2013-06-23 07:49:34 +00:00
|
|
|
{
|
|
|
|
if (tris) delete [] tris;
|
|
|
|
if (vertices) delete [] vertices;
|
|
|
|
if (texcoords) delete [] texcoords;
|
2014-10-24 09:43:25 +00:00
|
|
|
tris = NULL;
|
|
|
|
vertices = NULL;
|
|
|
|
texcoords = NULL;
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct MD3Frame
|
|
|
|
{
|
|
|
|
// The bounding box information is of no use in the Doom engine
|
|
|
|
// That will still be done with the actor's size information.
|
|
|
|
char Name[16];
|
|
|
|
float origin[3];
|
|
|
|
};
|
|
|
|
|
|
|
|
int numFrames;
|
|
|
|
int numTags;
|
|
|
|
int numSurfaces;
|
2015-04-12 17:42:03 +00:00
|
|
|
int mLumpNum;
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
MD3Frame * frames;
|
|
|
|
MD3Surface * surfaces;
|
|
|
|
|
|
|
|
public:
|
|
|
|
FMD3Model() { }
|
|
|
|
virtual ~FMD3Model();
|
|
|
|
|
|
|
|
virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length);
|
|
|
|
virtual int FindFrame(const char * name);
|
2014-06-19 11:58:49 +00:00
|
|
|
virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0);
|
2015-04-12 17:42:03 +00:00
|
|
|
void LoadGeometry();
|
2014-10-24 09:43:25 +00:00
|
|
|
void BuildVertexBuffer();
|
2016-05-03 16:14:16 +00:00
|
|
|
virtual void AddSkins(BYTE *hitlist);
|
2013-06-23 07:49:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct FVoxelVertexHash
|
|
|
|
{
|
|
|
|
// Returns the hash value for a key.
|
2014-06-19 20:24:33 +00:00
|
|
|
hash_t Hash(const FModelVertex &key)
|
2013-06-23 07:49:34 +00:00
|
|
|
{
|
|
|
|
int ix = xs_RoundToInt(key.x);
|
|
|
|
int iy = xs_RoundToInt(key.y);
|
|
|
|
int iz = xs_RoundToInt(key.z);
|
|
|
|
return (hash_t)(ix + (iy<<9) + (iz<<18));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Compares two keys, returning zero if they are the same.
|
2014-06-19 20:24:33 +00:00
|
|
|
int Compare(const FModelVertex &left, const FModelVertex &right)
|
2013-06-23 07:49:34 +00:00
|
|
|
{
|
|
|
|
return left.x != right.x || left.y != right.y || left.z != right.z || left.u != right.u || left.v != right.v;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct FIndexInit
|
|
|
|
{
|
|
|
|
void Init(unsigned int &value)
|
|
|
|
{
|
|
|
|
value = 0xffffffff;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-06-19 20:24:33 +00:00
|
|
|
typedef TMap<FModelVertex, unsigned int, FVoxelVertexHash, FIndexInit> FVoxelMap;
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
class FVoxelModel : public FModel
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
FVoxel *mVoxel;
|
|
|
|
bool mOwningVoxel; // if created through MODELDEF deleting this object must also delete the voxel object
|
2016-05-03 13:45:21 +00:00
|
|
|
FTextureID mPalette;
|
2014-10-24 09:43:25 +00:00
|
|
|
unsigned int mNumIndices;
|
2014-06-19 20:24:33 +00:00
|
|
|
TArray<FModelVertex> mVertices;
|
2013-06-23 07:49:34 +00:00
|
|
|
TArray<unsigned int> mIndices;
|
|
|
|
|
|
|
|
void MakeSlabPolys(int x, int y, kvxslab_t *voxptr, FVoxelMap &check);
|
|
|
|
void AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3, int x4, int y4, int z4, BYTE color, FVoxelMap &check);
|
2014-06-19 20:24:33 +00:00
|
|
|
unsigned int AddVertex(FModelVertex &vert, FVoxelMap &check);
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
FVoxelModel(FVoxel *voxel, bool owned);
|
|
|
|
~FVoxelModel();
|
|
|
|
bool Load(const char * fn, int lumpnum, const char * buffer, int length);
|
|
|
|
void Initialize();
|
|
|
|
virtual int FindFrame(const char * name);
|
2014-06-19 11:58:49 +00:00
|
|
|
virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0);
|
2016-05-03 16:14:16 +00:00
|
|
|
virtual void AddSkins(BYTE *hitlist);
|
2016-05-03 13:45:21 +00:00
|
|
|
FTextureID GetPaletteTexture() const { return mPalette; }
|
2014-10-24 09:43:25 +00:00
|
|
|
void BuildVertexBuffer();
|
2014-12-31 11:53:29 +00:00
|
|
|
float getAspectFactor();
|
2013-06-23 07:49:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define MAX_MODELS_PER_FRAME 4
|
|
|
|
|
|
|
|
//
|
|
|
|
// [BB] Model rendering flags.
|
|
|
|
//
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
// [BB] Color translations for the model skin are ignored. This is
|
|
|
|
// useful if the skin texture is not using the game palette.
|
|
|
|
MDL_IGNORETRANSLATION = 1,
|
|
|
|
MDL_PITCHFROMMOMENTUM = 2,
|
|
|
|
MDL_ROTATING = 4,
|
|
|
|
MDL_INTERPOLATEDOUBLEDFRAMES = 8,
|
|
|
|
MDL_NOINTERPOLATION = 16,
|
|
|
|
MDL_INHERITACTORPITCH = 32,
|
|
|
|
MDL_INHERITACTORROLL = 64, // useless for now
|
|
|
|
};
|
|
|
|
|
|
|
|
struct FSpriteModelFrame
|
|
|
|
{
|
2016-05-03 13:45:21 +00:00
|
|
|
int modelIDs[MAX_MODELS_PER_FRAME];
|
|
|
|
FTextureID skinIDs[MAX_MODELS_PER_FRAME];
|
2013-06-23 07:49:34 +00:00
|
|
|
int modelframes[MAX_MODELS_PER_FRAME];
|
|
|
|
float xscale, yscale, zscale;
|
|
|
|
// [BB] Added zoffset, rotation parameters and flags.
|
|
|
|
// Added xoffset, yoffset
|
|
|
|
float xoffset, yoffset, zoffset;
|
|
|
|
float xrotate, yrotate, zrotate;
|
|
|
|
float rotationCenterX, rotationCenterY, rotationCenterZ;
|
|
|
|
float rotationSpeed;
|
|
|
|
unsigned int flags;
|
|
|
|
const PClass * type;
|
|
|
|
short sprite;
|
|
|
|
short frame;
|
|
|
|
FState * state; // for later!
|
|
|
|
int hashnext;
|
2016-03-24 15:10:17 +00:00
|
|
|
float angleoffset;
|
2013-06-23 07:49:34 +00:00
|
|
|
// added pithoffset, rolloffset.
|
|
|
|
float pitchoffset, rolloffset; // I don't want to bother with type transformations, so I made this variables float.
|
|
|
|
};
|
|
|
|
|
|
|
|
class GLSprite;
|
|
|
|
|
|
|
|
FSpriteModelFrame * gl_FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped);
|
|
|
|
|
2014-05-11 19:47:54 +00:00
|
|
|
void gl_RenderModel(GLSprite * spr);
|
2013-06-23 07:49:34 +00:00
|
|
|
// [BB] HUD weapon model rendering functions.
|
2016-06-17 15:21:42 +00:00
|
|
|
void gl_RenderHUDModel(DPSprite *psp, float ofsx, float ofsy);
|
2013-06-23 07:49:34 +00:00
|
|
|
bool gl_IsHUDModelForPlayerAvailable (player_t * player);
|
|
|
|
|
2016-05-03 13:45:21 +00:00
|
|
|
|
|
|
|
class DeletingModelArray : public TArray<FModel *>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
~DeletingModelArray()
|
|
|
|
{
|
|
|
|
for (unsigned i = 0; i<Size(); i++)
|
|
|
|
{
|
|
|
|
delete (*this)[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
extern DeletingModelArray Models;
|
|
|
|
|
2013-06-23 07:49:34 +00:00
|
|
|
#endif
|