diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index cc900649b..f9f8f4f22 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -30,7 +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); + virtual void BuildVertexBuffer(FModelVertexBuffer *buf) = 0; @@ -193,11 +193,15 @@ class FMD3Model : public FModel MD3TexCoord * texcoords; MD3Vertex * vertices; + unsigned int vindex; // contains numframes arrays of vertices + unsigned int iindex; + MD3Surface() { tris=NULL; vertices=NULL; texcoords=NULL; + vindex = iindex = UINT_MAX; } ~MD3Surface() @@ -233,20 +237,13 @@ public: 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); -}; - -class FVoxelVertexBuffer; - -struct FVoxelVertex -{ - float x,y,z; - float u,v; + virtual void BuildVertexBuffer(FModelVertexBuffer *buf); }; struct FVoxelVertexHash { // Returns the hash value for a key. - hash_t Hash(const FVoxelVertex &key) + hash_t Hash(const FModelVertex &key) { int ix = xs_RoundToInt(key.x); int iy = xs_RoundToInt(key.y); @@ -255,7 +252,7 @@ struct FVoxelVertexHash } // Compares two keys, returning zero if they are the same. - int Compare(const FVoxelVertex &left, const FVoxelVertex &right) + int Compare(const FModelVertex &left, const FModelVertex &right) { return left.x != right.x || left.y != right.y || left.z != right.z || left.u != right.u || left.v != right.v; } @@ -269,7 +266,7 @@ struct FIndexInit } }; -typedef TMap FVoxelMap; +typedef TMap FVoxelMap; class FVoxelModel : public FModel @@ -277,13 +274,15 @@ class FVoxelModel : public FModel protected: FVoxel *mVoxel; bool mOwningVoxel; // if created through MODELDEF deleting this object must also delete the voxel object - TArray mVertices; + TArray mVertices; TArray mIndices; FTexture *mPalette; + unsigned int vindex; + unsigned int iindex; 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); - void AddVertex(FVoxelVertex &vert, FVoxelMap &check); + unsigned int AddVertex(FModelVertex &vert, FVoxelMap &check); public: FVoxelModel(FVoxel *voxel, bool owned); @@ -293,6 +292,7 @@ public: virtual int FindFrame(const char * name); virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0); FTexture *GetPaletteTexture() const { return mPalette; } + void BuildVertexBuffer(FModelVertexBuffer *buf); }; diff --git a/src/gl/models/gl_models_md3.cpp b/src/gl/models/gl_models_md3.cpp index 6b380ea29..2c6f39d05 100644 --- a/src/gl/models/gl_models_md3.cpp +++ b/src/gl/models/gl_models_md3.cpp @@ -206,6 +206,37 @@ bool FMD3Model::Load(const char * path, int, const char * buffer, int length) return true; } +void FMD3Model::BuildVertexBuffer(FModelVertexBuffer *buf) +{ + for (int i = 0; i < numSurfaces; i++) + { + MD3Surface * surf = &surfaces[i]; + + surf->vindex = buf->vbo_shadowdata.Size(); + surf->iindex = buf->ibo_shadowdata.Size(); + for (int j = 0; j < numFrames * surf->numVertices; j++) + { + MD3Vertex* vert = surf->vertices + j; + + FModelVertex bvert; + + int tc = j % surf->numVertices; + bvert.Set(vert->x, vert->z, vert->y, surf->texcoords[tc].s, surf->texcoords[tc].t); + bvert.SetNormal(vert->nx, vert->nz, vert->ny); + buf->vbo_shadowdata.Push(bvert); + } + + for (int k = 0; k < surf->numTriangles; k++) + { + for (int l = 0; l < 3; l++) + { + buf->ibo_shadowdata.Push(surf->tris[k].VertIndex[l]); + } + } + } +} + + int FMD3Model::FindFrame(const char * name) { for (int i=0;ivbo_shadowdata.Size(); + iindex = buf->ibo_shadowdata.Size(); + + FModelVertex *mv = &buf->vbo_shadowdata[buf->vbo_shadowdata.Reserve(mVertices.Size())]; + unsigned int *mi = &buf->ibo_shadowdata[buf->ibo_shadowdata.Reserve(mIndices.Size())]; + + memcpy(mv, &mVertices[0], sizeof(FModelVertex)* mVertices.Size()); + memcpy(mi, &mIndices[0], sizeof(unsigned int)* mIndices.Size()); +} + +//=========================================================================== +// +// +// +//=========================================================================== + +unsigned int FVoxelModel::AddVertex(FModelVertex &vert, FVoxelMap &check) { unsigned int index = check[vert]; if (index == 0xffffffff) { index = check[vert] =mVertices.Push(vert); } - mIndices.Push(index); + return index; } //=========================================================================== @@ -257,8 +277,8 @@ void FVoxelModel::AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3 float PivotY = mVoxel->Mips[0].PivotY / 256.f; float PivotZ = mVoxel->Mips[0].PivotZ / 256.f; int h = mVoxel->Mips[0].SizeZ; - FVoxelVertex vert; - + FModelVertex vert; + unsigned int indx[4]; vert.u = (((col & 15) * 255 / 16) + 7) / 255.f; vert.v = (((col / 16) * 255 / 16) + 7) / 255.f; @@ -266,23 +286,29 @@ void FVoxelModel::AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3 vert.x = x1 - PivotX; vert.z = -y1 + PivotY; vert.y = -z1 + PivotZ; - AddVertex(vert, check); + indx[0] = AddVertex(vert, check); vert.x = x2 - PivotX; vert.z = -y2 + PivotY; vert.y = -z2 + PivotZ; - AddVertex(vert, check); + indx[1] = AddVertex(vert, check); vert.x = x4 - PivotX; vert.z = -y4 + PivotY; vert.y = -z4 + PivotZ; - AddVertex(vert, check); + indx[2] = AddVertex(vert, check); vert.x = x3 - PivotX; vert.z = -y3 + PivotY; vert.y = -z3 + PivotZ; - AddVertex(vert, check); + indx[3] = AddVertex(vert, check); + mIndices.Push(indx[0]); + mIndices.Push(indx[1]); + mIndices.Push(indx[2]); + mIndices.Push(indx[1]); + mIndices.Push(indx[3]); + mIndices.Push(indx[2]); } //=========================================================================== @@ -384,7 +410,7 @@ int FVoxelModel::FindFrame(const char * name) //=========================================================================== // -// Voxels never interpolate between frames +// Voxels never interpolate between frames, they only have one. // //=========================================================================== @@ -394,10 +420,10 @@ void FVoxelModel::RenderFrame(FTexture * skin, int frame, int frame2, double int tex->Bind(0, translation); gl_RenderState.Apply(); - glBegin(GL_QUADS); + glBegin(GL_TRIANGLES); for (unsigned i = 0; i < mIndices.Size(); i++) { - FVoxelVertex *vert = &mVertices[mIndices[i]]; + FModelVertex *vert = &mVertices[mIndices[i]]; glTexCoord2fv(&vert->u); glVertex3fv(&vert->x); }