diff --git a/neo/renderer/Model_local.h b/neo/renderer/Model_local.h index c25e423d..cb5eead0 100644 --- a/neo/renderer/Model_local.h +++ b/neo/renderer/Model_local.h @@ -271,6 +271,8 @@ struct md3Surface_s; class idRenderModelMD3 : public idRenderModelStatic { public: + idRenderModelMD3(); + virtual void InitFromFile( const char* fileName, const idImportOptions* options ); virtual bool SupportsBinaryModel() { @@ -285,6 +287,7 @@ private: int dataSize; // just for listing purposes struct md3Header_s* md3; // only if type == MOD_MESH int numLods; + idList 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; }; diff --git a/neo/renderer/Model_md3.cpp b/neo/renderer/Model_md3.cpp index acaffc00..17d45bfd 100644 --- a/neo/renderer/Model_md3.cpp +++ b/neo/renderer/Model_md3.cpp @@ -39,6 +39,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=LittleLong(x) /* @@ -65,7 +69,7 @@ void idRenderModelMD3::InitFromFile( const char* fileName, const idImportOptions name = fileName; size = fileSystem->ReadFile( fileName, &buffer, NULL ); - if( !size || size < 0 ) + if( !buffer || size < 0 ) { return; } @@ -180,10 +184,10 @@ void idRenderModelMD3::InitFromFile( const char* fileName, const idImportOptions 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 = ( sh != NULL ) ? shaders.AddUnique( sh ) : -1; } // swap all the triangles @@ -307,6 +311,11 @@ idRenderModel* idRenderModelMD3::InstantiateDynamicModel( const struct renderEnt int frame, oldframe; idRenderModelStatic* staticModel; + if( md3 == NULL ) + { + return NULL; + } + if( cachedModel ) { delete cachedModel; @@ -336,7 +345,9 @@ idRenderModel* idRenderModelMD3::InstantiateDynamicModel( const struct renderEnt surf.geometry = tri; md3Shader_t* shaders = ( md3Shader_t* )( ( byte* )surface + surface->ofsShaders ); - surf.shader = shaders->shader; + // 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 ); @@ -358,6 +369,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] ); @@ -390,6 +402,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] ); diff --git a/neo/renderer/Model_md3.h b/neo/renderer/Model_md3.h index 5a35ce56..a38b47fb 100644 --- a/neo/renderer/Model_md3.h +++ b/neo/renderer/Model_md3.h @@ -110,7 +110,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