Fix MD3 model support (esp. on 64bit)

.. but even on 32bit it didn't work reliably due to
an uninitialized value
This commit is contained in:
Daniel Gibson 2023-01-29 01:10:41 +01:00
parent 2de8c22f3b
commit 604dc7c44d
3 changed files with 20 additions and 7 deletions

View file

@ -210,6 +210,8 @@ struct md3Surface_s;
class idRenderModelMD3 : public idRenderModelStatic {
public:
idRenderModelMD3();
virtual void InitFromFile( const char *fileName );
virtual dynamicModel_t IsDynamicModel() const;
virtual idRenderModel * InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel );
@ -220,6 +222,7 @@ private:
int dataSize; // just for listing purposes
struct md3Header_s * md3; // only if type == MOD_MESH
int numLods;
idList<const idMaterial*> shaders; // DG: md3Shader_t::shaderIndex indexes into this array
void LerpMeshVertexes( srfTriangles_t *tri, const struct md3Surface_s *surf, const float backlerp, const int frame, const int oldframe ) const;
};

View file

@ -38,6 +38,10 @@ If you have questions concerning this license or the applicable additional terms
***********************************************************************/
// DG: added constructor to make sure all members are initialized
idRenderModelMD3::idRenderModelMD3() : index(-1), dataSize(0), md3(NULL), numLods(0)
{}
#define LL(x) x=LittleInt(x)
/*
@ -63,7 +67,7 @@ void idRenderModelMD3::InitFromFile( const char *fileName ) {
name = fileName;
size = fileSystem->ReadFile( fileName, &buffer, NULL );
if (!size || size<0 ) {
if ( size <= sizeof(md3Header_t) ) {
return;
}
@ -165,10 +169,10 @@ void idRenderModelMD3::InitFromFile( const char *fileName ) {
// register the shaders
shader = (md3Shader_t *) ( (byte *)surf + surf->ofsShaders );
for ( j = 0 ; j < surf->numShaders ; j++, shader++ ) {
const idMaterial *sh;
sh = declManager->FindMaterial( shader->name );
shader->shader = sh;
const idMaterial *sh = declManager->FindMaterial( shader->name );
// DG: md3Shadder_t must use an index to the material instead of a pointer,
// otherwise the sizes are wrong on 64bit and we get data corruption
shader->shaderIndex = shaders.AddUnique( sh );
}
// swap all the triangles
@ -310,7 +314,10 @@ idRenderModel *idRenderModelMD3::InstantiateDynamicModel( const struct renderEnt
surf.geometry = tri;
md3Shader_t* shaders = (md3Shader_t *) ((byte *)surface + surface->ofsShaders);
surf.shader = shaders->shader;
// FIXME: theoretically there can be multiple shaders?
// DG: turned md3Shader_t::shader (pointer) into an int (index)
int shaderIdx = shaders->shaderIndex;
surf.shader = (shaderIdx >= 0) ? this->shaders[shaderIdx] : NULL;
LerpMeshVertexes( tri, surface, backlerp, frame, oldframe );
@ -332,6 +339,7 @@ idRenderModel *idRenderModelMD3::InstantiateDynamicModel( const struct renderEnt
R_BoundTriSurf( tri );
surf.id = staticModel->NumSurfaces(); // DG: make sure to initialize id; FIXME: or just set id to 0?
staticModel->AddSurface( surf );
staticModel->bounds.AddPoint( surf.geometry->bounds[0] );
staticModel->bounds.AddPoint( surf.geometry->bounds[1] );
@ -362,6 +370,7 @@ idBounds idRenderModelMD3::Bounds(const struct renderEntity_s *ent) const {
}
md3Frame_t *frame = (md3Frame_t *)( (byte *)md3 + md3->ofsFrames );
frame += (int)ent->shaderParms[SHADERPARM_MD3_FRAME]; // DG: use bounds of current frame
ret.AddPoint( frame->bounds[0] );
ret.AddPoint( frame->bounds[1] );

View file

@ -106,7 +106,8 @@ typedef struct md3Surface_s {
typedef struct {
char name[MAX_MD3PATH];
const idMaterial * shader; // for in-game use
//const idMaterial * shader; // for in-game use
int shaderIndex; // DG: can't use a pointer, that breaks on 64bit!
} md3Shader_t;
typedef struct {