From b3b2eb42c67e804a444036d7f8f1758158eb5e5b Mon Sep 17 00:00:00 2001 From: Jordon Moss Date: Thu, 14 Jul 2016 12:35:30 -0300 Subject: [PATCH] Added SurfaceSkin MODELDEF property, allows overriding MD3 per-surface skins. --- src/gl/models/gl_models.cpp | 37 ++++++++++++++++++++++++++++++++- src/gl/models/gl_models.h | 8 +++++++ src/gl/models/gl_models_md3.cpp | 16 ++++++++++++-- src/gl/scene/gl_scene.cpp | 1 + 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 7f05ebb2e..3c2eb05c8 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -460,7 +460,7 @@ void gl_InitModels() { int Lump, lastLump; FString path; - int index; + int index, surface; int i; FSpriteModelFrame smf; @@ -696,6 +696,39 @@ void gl_InitModels() } } } + else if (sc.Compare("surfaceskin")) + { + sc.MustGetNumber(); + index = sc.Number; + sc.MustGetNumber(); + surface = sc.Number; + + if (index<0 || index >= MAX_MODELS_PER_FRAME) + { + sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); + } + + if (surface<0 || index >= MD3_MAX_SURFACES) + { + sc.ScriptError("Invalid MD3 Surface %d in %s", MD3_MAX_SURFACES, smf.type->TypeName.GetChars()); + } + + sc.MustGetString(); + FixPathSeperator(sc.String); + if (sc.Compare("")) + { + smf.surfaceskinIDs[index][surface] = FNullTextureID(); + } + else + { + smf.surfaceskinIDs[index][surface] = LoadSkin("", sc.String); + if (!smf.surfaceskinIDs[index][surface].isValid()) + { + Printf("Surface Skin '%s' not found in '%s'\n", + sc.String, smf.type->TypeName.GetChars()); + } + } + } else if (sc.Compare("frameindex") || sc.Compare("frame")) { bool isframe=!!sc.Compare("frame"); @@ -901,6 +934,8 @@ void gl_RenderFrameModels( const FSpriteModelFrame *smf, mdl->BuildVertexBuffer(); gl_RenderState.SetVertexBuffer(mdl->mVBuf); + mdl->PushSpriteFrame(smf, i); + if ( smfNext && smf->modelframes[i] != smfNext->modelframes[i] ) mdl->RenderFrame(tex, smf->modelframes[i], smfNext->modelframes[i], inter, translation); else diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index ab53bd7e4..a75e74305 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -16,9 +16,12 @@ enum { VX, VZ, VY }; #define DMD_MAGIC 0x4D444D44 #define MD3_MAGIC 0x33504449 #define NUMVERTEXNORMALS 162 +#define MD3_MAX_SURFACES 32 FTextureID LoadSkin(const char * path, const char * fn); +// [JM] Necessary forward declaration +typedef struct FSpriteModelFrame FSpriteModelFrame; class FModel { @@ -42,6 +45,10 @@ public: } virtual float getAspectFactor() { return 1.f; } + const FSpriteModelFrame *curSpriteMDLFrame; + int curMDLIndex; + void PushSpriteFrame(const FSpriteModelFrame *smf, int index) { curSpriteMDLFrame = smf; curMDLIndex = index; }; + FModelVertexBuffer *mVBuf; FString mFileName; }; @@ -347,6 +354,7 @@ struct FSpriteModelFrame { int modelIDs[MAX_MODELS_PER_FRAME]; FTextureID skinIDs[MAX_MODELS_PER_FRAME]; + FTextureID surfaceskinIDs[MAX_MODELS_PER_FRAME][MD3_MAX_SURFACES]; int modelframes[MAX_MODELS_PER_FRAME]; float xscale, yscale, zscale; // [BB] Added zoffset, rotation parameters and flags. diff --git a/src/gl/models/gl_models_md3.cpp b/src/gl/models/gl_models_md3.cpp index 267e85c91..b9c0a120a 100644 --- a/src/gl/models/gl_models_md3.cpp +++ b/src/gl/models/gl_models_md3.cpp @@ -319,6 +319,11 @@ void FMD3Model::AddSkins(BYTE *hitlist) { for (int i = 0; i < numSurfaces; i++) { + if (curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid()) + { + hitlist[curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].GetIndex()] |= FTexture::TEX_Flat; + } + MD3Surface * surf = &surfaces[i]; for (int j = 0; j < surf->numSkins; j++) { @@ -365,8 +370,15 @@ void FMD3Model::RenderFrame(FTexture * skin, int frameno, int frameno2, double i FTexture *surfaceSkin = skin; if (!surfaceSkin) { - if (surf->numSkins==0 || !surf->skins[0].isValid()) return; - surfaceSkin = TexMan(surf->skins[0]); + if (curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid()) + { + surfaceSkin = TexMan(curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i]); + } + else if(surf->numSkins > 0 && surf->skins[0].isValid()) + { + surfaceSkin = TexMan(surf->skins[0]); + } + if (!surfaceSkin) return; } diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 6352ca0cd..619b94f84 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -1113,6 +1113,7 @@ void FGLInterface::Precache(BYTE *texhitlist, TMap &actorhit } else if (smf->modelIDs[i] != -1) { + Models[smf->modelIDs[i]]->PushSpriteFrame(smf, i); Models[smf->modelIDs[i]]->AddSkins(texhitlist); } if (smf->modelIDs[i] != -1)