- create vertex buffer data for MD2/DMD models.

This commit is contained in:
Christoph Oelckers 2014-06-19 17:06:26 +02:00
parent 3e9b9c280b
commit 5944894138
3 changed files with 111 additions and 9 deletions

View file

@ -182,6 +182,11 @@ struct FModelVertex
u = uu;
v = vv;
}
void SetNormal(float nx, float ny, float nz)
{
// GZDoom currently doesn't use normals. This function is so that the high level code can pretend it does.
}
};
@ -190,7 +195,9 @@ class FModelVertexBuffer : public FVertexBuffer
int mIndexFrame[2];
public:
// these are public because it's the models having to fill them in.
TArray<FModelVertex> vbo_shadowdata; // this is kept around for interpolating on GL 2.0
TArray<unsigned int> ibo_shadowdata; // this is kept around for interpolating on GL 2.0
FModelVertexBuffer();
~FModelVertexBuffer();

View file

@ -30,6 +30,7 @@ public:
virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length) = 0;
virtual int FindFrame(const char * name) = 0;
virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0) = 0;
virtual void BuildVertexBuffer(FModelVertexBuffer *buf);
@ -54,7 +55,7 @@ protected:
int flags;
};
struct FModelVertex
struct DMDModelVertex
{
float xyz[3];
};
@ -90,8 +91,9 @@ protected:
struct ModelFrame
{
char name[16];
FModelVertex *vertices;
FModelVertex *normals;
DMDModelVertex *vertices;
DMDModelVertex *normals;
unsigned int vindex;
};
struct DMDLoDInfo
@ -114,6 +116,9 @@ protected:
DMDInfo info;
FTexture ** skins;
FTexCoord * texCoords;
unsigned int ib_index;
unsigned int ib_count;
ModelFrame * frames;
DMDLoDInfo lodInfo[MAX_LODS];
@ -121,7 +126,7 @@ protected:
char *vertexUsage; // Bitfield for each vertex.
bool allowTexComp; // Allow texture compression with this.
static void RenderGLCommands(void *glCommands, unsigned int numVertices,FModelVertex * vertices, FModelVertex *vertices2, double inter);
static void RenderGLCommands(void *glCommands, unsigned int numVertices,DMDModelVertex * vertices, DMDModelVertex *vertices2, double inter);
public:
FDMDModel()
@ -131,12 +136,14 @@ public:
skins = NULL;
lods[0].glCommands = NULL;
info.numLODs = 0;
ib_count = 0;
}
virtual ~FDMDModel();
virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length);
virtual int FindFrame(const char * name);
virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0);
virtual void BuildVertexBuffer(FModelVertexBuffer *buf);
};

View file

@ -163,6 +163,7 @@ bool FDMDModel::Load(const char * path, int, const char * buffer, int length)
temp = (char*)buffer + info.offsetFrames;
frames = new ModelFrame[info.numFrames];
ib_count = 0;
for(i = 0, frame = frames; i < info.numFrames; i++, frame++)
{
@ -170,8 +171,9 @@ bool FDMDModel::Load(const char * path, int, const char * buffer, int length)
dmd_packedVertex_t *pVtx;
memcpy(frame->name, pfr->name, sizeof(pfr->name));
frame->vertices = new FModelVertex[info.numVertices];
frame->normals = new FModelVertex[info.numVertices];
frame->vertices = new DMDModelVertex[info.numVertices];
frame->normals = new DMDModelVertex[info.numVertices];
frame->vindex = UINT_MAX;
// Translate each vertex.
for(k = 0, pVtx = pfr->vertices; k < info.numVertices; k++, pVtx++)
@ -244,6 +246,91 @@ FDMDModel::~FDMDModel()
if (vertexUsage != NULL) delete [] vertexUsage;
}
void FDMDModel::BuildVertexBuffer(FModelVertexBuffer *buf)
{
for (int i = 0; i < info.numFrames; i++)
{
ModelFrame *frame = &frames[i];
DMDModelVertex *vert = frame->vertices;
DMDModelVertex *norm = frame->normals;
void *glCommands = lods[0].glCommands;
frame->vindex = buf->vbo_shadowdata.Size();
for (char *pos = (char*)glCommands; *pos;)
{
int count = *(int *)pos;
pos += 4;
// The type of primitive depends on the sign.
int primtype = count > 0 ? GL_TRIANGLE_STRIP : GL_TRIANGLE_FAN;
count = abs(count);
if (i == 0)
{
// build the index buffer - we'll use the same buffer for all frames so only create it once
unsigned int bufindex = buf->vbo_shadowdata.Size() - frame->vindex;
unsigned int bufp = bufindex;
if (primtype == GL_TRIANGLE_STRIP)
{
for (int t = 0; t < count - 2; t++)
{
unsigned int *p = &buf->ibo_shadowdata[buf->ibo_shadowdata.Reserve(3)];
if ((t & 1) == 0)
{
p[0] = bufp;
p[1] = bufp + 1;
p[2] = bufp + 2;
}
else
{
p[0] = bufp;
p[2] = bufp + 2;
p[1] = bufp + 1;
}
bufp++;
}
}
else
{
bufp++;
for (int t = 0; t < count - 2; t++)
{
unsigned int *p = &buf->ibo_shadowdata[buf->ibo_shadowdata.Reserve(3)];
p[0] = bufindex;
p[1] = bufp;
p[2] = bufp + 1;
bufp++;
}
}
}
while (count--)
{
FModelVertex bvert;
FGLCommandVertex * v = (FGLCommandVertex *)pos;
pos += sizeof(FGLCommandVertex);
bvert.Set(vert[v->index].xyz[0], vert[v->index].xyz[1], vert[v->index].xyz[2], v->s, v->t);
bvert.SetNormal(norm[v->index].xyz[0], norm[v->index].xyz[1], norm[v->index].xyz[2]);
buf->vbo_shadowdata.Push(bvert);
}
}
}
}
//===========================================================================
//
// FDMDModel::FindFrame
@ -264,7 +351,7 @@ int FDMDModel::FindFrame(const char * name)
//
//===========================================================================
void FDMDModel::RenderGLCommands(void *glCommands, unsigned int numVertices, FModelVertex * vertices, FModelVertex *vertices2, double inter)
void FDMDModel::RenderGLCommands(void *glCommands, unsigned int numVertices, DMDModelVertex * vertices, DMDModelVertex *vertices2, double inter)
{
char *pos;
FGLCommandVertex * v;
@ -418,8 +505,9 @@ bool FMD2Model::Load(const char * path, int, const char * buffer, int length)
md2_triangleVertex_t *pVtx;
memcpy(frame->name, pfr->name, sizeof(pfr->name));
frame->vertices = new FModelVertex[info.numVertices];
frame->normals = new FModelVertex[info.numVertices];
frame->vertices = new DMDModelVertex[info.numVertices];
frame->normals = new DMDModelVertex[info.numVertices];
frame->vindex = UINT_MAX;
// Translate each vertex.
for(k = 0, pVtx = pfr->vertices; k < info.numVertices; k++, pVtx++)