mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-10 07:12:07 +00:00
models: add md5 support
Has:
* no hacks for replace md2 with md5 automatically(TODO),
* no logic for merge anim and mesh content as required by loader(TODO),
* automaticlly converted md5 to md2 like internal format.
Part of https://github.com/yquake2/yquake2remaster/issues/4
Based on:
* http://tfc.duke.free.fr/coding/md5-specs-en.html
* https://github.com/Shpoike/Quakespasm/blob/qsrebase/Quake/gl_model.c (Normals code)
Also looked to:
* https://github.com/Novum/vkQuake/blob/master/Quake/gl_model.c#L4181
* https://github.com/fte-team/fteqw/blob/master/engine/common/com_mesh.c
* 1b42134e11
This commit is contained in:
parent
ab198a962e
commit
8d0261c6a0
6 changed files with 1223 additions and 36 deletions
5
Makefile
5
Makefile
|
@ -1042,6 +1042,7 @@ REFGL1_OBJS_ := \
|
||||||
src/client/refresh/files/surf.o \
|
src/client/refresh/files/surf.o \
|
||||||
src/client/refresh/files/maps.o \
|
src/client/refresh/files/maps.o \
|
||||||
src/client/refresh/files/models.o \
|
src/client/refresh/files/models.o \
|
||||||
|
src/client/refresh/files/models_md5.o \
|
||||||
src/client/refresh/files/pcx.o \
|
src/client/refresh/files/pcx.o \
|
||||||
src/client/refresh/files/stb.o \
|
src/client/refresh/files/stb.o \
|
||||||
src/client/refresh/files/wal.o \
|
src/client/refresh/files/wal.o \
|
||||||
|
@ -1080,6 +1081,7 @@ REFGL3_OBJS_ := \
|
||||||
src/client/refresh/files/surf.o \
|
src/client/refresh/files/surf.o \
|
||||||
src/client/refresh/files/maps.o \
|
src/client/refresh/files/maps.o \
|
||||||
src/client/refresh/files/models.o \
|
src/client/refresh/files/models.o \
|
||||||
|
src/client/refresh/files/models_md5.o \
|
||||||
src/client/refresh/files/pcx.o \
|
src/client/refresh/files/pcx.o \
|
||||||
src/client/refresh/files/stb.o \
|
src/client/refresh/files/stb.o \
|
||||||
src/client/refresh/files/wal.o \
|
src/client/refresh/files/wal.o \
|
||||||
|
@ -1124,6 +1126,7 @@ REFGL4_OBJS_ := \
|
||||||
src/client/refresh/files/surf.o \
|
src/client/refresh/files/surf.o \
|
||||||
src/client/refresh/files/maps.o \
|
src/client/refresh/files/maps.o \
|
||||||
src/client/refresh/files/models.o \
|
src/client/refresh/files/models.o \
|
||||||
|
src/client/refresh/files/models_md5.o \
|
||||||
src/client/refresh/files/pcx.o \
|
src/client/refresh/files/pcx.o \
|
||||||
src/client/refresh/files/stb.o \
|
src/client/refresh/files/stb.o \
|
||||||
src/client/refresh/files/wal.o \
|
src/client/refresh/files/wal.o \
|
||||||
|
@ -1170,6 +1173,7 @@ REFSOFT_OBJS_ := \
|
||||||
src/client/refresh/files/surf.o \
|
src/client/refresh/files/surf.o \
|
||||||
src/client/refresh/files/maps.o \
|
src/client/refresh/files/maps.o \
|
||||||
src/client/refresh/files/models.o \
|
src/client/refresh/files/models.o \
|
||||||
|
src/client/refresh/files/models_md5.o \
|
||||||
src/client/refresh/files/pcx.o \
|
src/client/refresh/files/pcx.o \
|
||||||
src/client/refresh/files/stb.o \
|
src/client/refresh/files/stb.o \
|
||||||
src/client/refresh/files/wal.o \
|
src/client/refresh/files/wal.o \
|
||||||
|
@ -1215,6 +1219,7 @@ REFVK_OBJS_ := \
|
||||||
src/client/refresh/files/surf.o \
|
src/client/refresh/files/surf.o \
|
||||||
src/client/refresh/files/maps.o \
|
src/client/refresh/files/maps.o \
|
||||||
src/client/refresh/files/models.o \
|
src/client/refresh/files/models.o \
|
||||||
|
src/client/refresh/files/models_md5.o \
|
||||||
src/client/refresh/files/pcx.o \
|
src/client/refresh/files/pcx.o \
|
||||||
src/client/refresh/files/stb.o \
|
src/client/refresh/files/stb.o \
|
||||||
src/client/refresh/files/wal.o \
|
src/client/refresh/files/wal.o \
|
||||||
|
|
18
README.md
18
README.md
|
@ -37,18 +37,24 @@ Goals (finished):
|
||||||
* FM/Heretic 2 model format support,
|
* FM/Heretic 2 model format support,
|
||||||
* Cinematic videos support in smk, mpeg, ogv format,
|
* Cinematic videos support in smk, mpeg, ogv format,
|
||||||
* Use ffmpeg for load any video,
|
* Use ffmpeg for load any video,
|
||||||
|
* MDL/Quake1 model format support,
|
||||||
|
* Daikatana model/wal/map format support,
|
||||||
|
* MD5 model support,
|
||||||
|
* Add debug progress loading code for maps.
|
||||||
|
|
||||||
Goals (none of it finished):
|
Goals (none of it finished):
|
||||||
* Single player support,
|
* Single player support,
|
||||||
* MD5 model support,
|
* modified ReRelease game code support with removed KEX only related code.
|
||||||
* modified ReRelease game code support with removed KEX only related code,
|
|
||||||
|
|
||||||
Bonus goals:
|
Bonus goals:
|
||||||
* MDL/Quake1 model format support,
|
|
||||||
* Daikatana model/wal/map format support,
|
|
||||||
* Load colormap as 24bit color,
|
|
||||||
* Use shared model cache in client code insted reimplemnet in each render,
|
* Use shared model cache in client code insted reimplemnet in each render,
|
||||||
* Add debug progress loading code.
|
* Check load soft colormap as 24bit color,
|
||||||
|
* Use separete texture hi-color buffer for ui in soft render,
|
||||||
|
* Convert map surface flag by game type,
|
||||||
|
* Cleanup function declarations in game save code,
|
||||||
|
* Support scalled textures for models and walls in soft render and fix
|
||||||
|
|
||||||
|
lighting with remastered maps.
|
||||||
|
|
||||||
Not a goal:
|
Not a goal:
|
||||||
* multiplayer protocol support with KEX engine,
|
* multiplayer protocol support with KEX engine,
|
||||||
|
|
|
@ -40,12 +40,12 @@ Mod_LoadSTvertList(dmdx_t *pheader, dstvert_t *pinst)
|
||||||
dstvert_t *poutst;
|
dstvert_t *poutst;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
poutst = (dstvert_t *) ((byte *)pheader + pheader->ofs_st);
|
poutst = (dstvert_t *)((byte *)pheader + pheader->ofs_st);
|
||||||
|
|
||||||
for (i=0 ; i<pheader->num_st ; i++)
|
for (i = 0; i < pheader->num_st; i++)
|
||||||
{
|
{
|
||||||
poutst[i].s = LittleShort (pinst[i].s);
|
poutst[i].s = LittleShort(pinst[i].s);
|
||||||
poutst[i].t = LittleShort (pinst[i].t);
|
poutst[i].t = LittleShort(pinst[i].t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,11 +97,11 @@ Mod_LoadFrames_MD2(dmdx_t *pheader, byte *src, size_t inframesize, vec3_t transl
|
||||||
poutframe = (daliasxframe_t *) ((byte *)pheader
|
poutframe = (daliasxframe_t *) ((byte *)pheader
|
||||||
+ pheader->ofs_frames + i * pheader->framesize);
|
+ pheader->ofs_frames + i * pheader->framesize);
|
||||||
|
|
||||||
memcpy (poutframe->name, pinframe->name, sizeof(poutframe->name));
|
memcpy(poutframe->name, pinframe->name, sizeof(poutframe->name));
|
||||||
for (j=0 ; j<3 ; j++)
|
for (j=0 ; j<3 ; j++)
|
||||||
{
|
{
|
||||||
poutframe->scale[j] = LittleFloat (pinframe->scale[j]) / 0xFF;
|
poutframe->scale[j] = LittleFloat(pinframe->scale[j]) / 0xFF;
|
||||||
poutframe->translate[j] = LittleFloat (pinframe->translate[j]);
|
poutframe->translate[j] = LittleFloat(pinframe->translate[j]);
|
||||||
poutframe->translate[j] += translate[j];
|
poutframe->translate[j] += translate[j];
|
||||||
}
|
}
|
||||||
// verts are all 8 bit, so no swapping needed
|
// verts are all 8 bit, so no swapping needed
|
||||||
|
@ -140,8 +140,8 @@ Mod_LoadDTriangleList(dmdx_t *pheader, dtriangle_t *pintri)
|
||||||
|
|
||||||
for (j=0 ; j<3 ; j++)
|
for (j=0 ; j<3 ; j++)
|
||||||
{
|
{
|
||||||
pouttri[i].index_xyz[j] = LittleShort (pintri[i].index_xyz[j]);
|
pouttri[i].index_xyz[j] = LittleShort(pintri[i].index_xyz[j]);
|
||||||
pouttri[i].index_st[j] = LittleShort (pintri[i].index_st[j]);
|
pouttri[i].index_st[j] = LittleShort(pintri[i].index_st[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,14 +161,14 @@ Mod_LoadDkmTriangleList(dmdx_t *pheader, dkmtriangle_t *pintri)
|
||||||
|
|
||||||
pouttri = (dtriangle_t *) ((char *)pheader + pheader->ofs_tris);
|
pouttri = (dtriangle_t *) ((char *)pheader + pheader->ofs_tris);
|
||||||
|
|
||||||
for (i=0 ; i<pheader->num_tris ; i++)
|
for (i = 0; i < pheader->num_tris; i++)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
for (j=0 ; j<3 ; j++)
|
for (j = 0; j < 3; j++)
|
||||||
{
|
{
|
||||||
pouttri[i].index_xyz[j] = LittleShort (pintri[i].index_xyz[j]);
|
pouttri[i].index_xyz[j] = LittleShort(pintri[i].index_xyz[j]);
|
||||||
pouttri[i].index_st[j] = LittleShort (pintri[i].index_st[j]);
|
pouttri[i].index_st[j] = LittleShort(pintri[i].index_st[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,6 +223,7 @@ Mod_LoadDKMCmdList(const char *mod_name, dmdx_t *pheader, int *pincmd)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memset (poutcmd, 0, (pendcmd - poutcmd) * sizeof(int));
|
memset (poutcmd, 0, (pendcmd - poutcmd) * sizeof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,15 +249,15 @@ Mod_LoadFrames_DKM2(dmdx_t *pheader, const byte *src, size_t inframesize, vec3_t
|
||||||
dxtrivertx_t *outverts;
|
dxtrivertx_t *outverts;
|
||||||
byte *inverts;
|
byte *inverts;
|
||||||
|
|
||||||
pinframe = (daliasframe_t *) (src + i * inframesize);
|
pinframe = (daliasframe_t *)(src + i * inframesize);
|
||||||
poutframe = (daliasxframe_t *) ((byte *)pheader
|
poutframe = (daliasxframe_t *)((byte *)pheader
|
||||||
+ pheader->ofs_frames + i * outframesize);
|
+ pheader->ofs_frames + i * outframesize);
|
||||||
|
|
||||||
memcpy (poutframe->name, pinframe->name, sizeof(poutframe->name));
|
memcpy(poutframe->name, pinframe->name, sizeof(poutframe->name));
|
||||||
for (j=0 ; j<3 ; j++)
|
for (j = 0; j < 3; j++)
|
||||||
{
|
{
|
||||||
poutframe->scale[j] = LittleFloat (pinframe->scale[j]);
|
poutframe->scale[j] = LittleFloat(pinframe->scale[j]);
|
||||||
poutframe->translate[j] = LittleFloat (pinframe->translate[j]);
|
poutframe->translate[j] = LittleFloat(pinframe->translate[j]);
|
||||||
poutframe->translate[j] += translate[j];
|
poutframe->translate[j] += translate[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,6 +267,7 @@ Mod_LoadFrames_DKM2(dmdx_t *pheader, const byte *src, size_t inframesize, vec3_t
|
||||||
|
|
||||||
inverts = (byte *)&pinframe->verts;
|
inverts = (byte *)&pinframe->verts;
|
||||||
outverts = poutframe->verts;
|
outverts = poutframe->verts;
|
||||||
|
|
||||||
/* dkm vert version 2 has unalligned by int size struct */
|
/* dkm vert version 2 has unalligned by int size struct */
|
||||||
for(j=0; j < pheader->num_xyz; j++)
|
for(j=0; j < pheader->num_xyz; j++)
|
||||||
{
|
{
|
||||||
|
@ -540,13 +542,13 @@ Mod_LoadModel_MDL(const char *mod_name, const void *buffer, int modfilelen,
|
||||||
|
|
||||||
|
|
||||||
frame = (daliasframe_t *) ((byte *)pheader + ofs_frames + i * framesize);
|
frame = (daliasframe_t *) ((byte *)pheader + ofs_frames + i * framesize);
|
||||||
frame->scale[0] = LittleFloat (pinmodel->scale[0]) / 0xFF;
|
frame->scale[0] = LittleFloat(pinmodel->scale[0]) / 0xFF;
|
||||||
frame->scale[1] = LittleFloat (pinmodel->scale[1]) / 0xFF;
|
frame->scale[1] = LittleFloat(pinmodel->scale[1]) / 0xFF;
|
||||||
frame->scale[2] = LittleFloat (pinmodel->scale[2]) / 0xFF;
|
frame->scale[2] = LittleFloat(pinmodel->scale[2]) / 0xFF;
|
||||||
|
|
||||||
frame->translate[0] = LittleFloat (pinmodel->translate[0]);
|
frame->translate[0] = LittleFloat(pinmodel->translate[0]);
|
||||||
frame->translate[1] = LittleFloat (pinmodel->translate[1]);
|
frame->translate[1] = LittleFloat(pinmodel->translate[1]);
|
||||||
frame->translate[2] = LittleFloat (pinmodel->translate[2]);
|
frame->translate[2] = LittleFloat(pinmodel->translate[2]);
|
||||||
|
|
||||||
/* Read frame data */
|
/* Read frame data */
|
||||||
/* skip type / int */
|
/* skip type / int */
|
||||||
|
@ -946,7 +948,7 @@ Mod_LoadModel_Flex(const char *mod_name, const void *buffer, int modfilelen,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mod_LoadSTvertList (pheader, (dstvert_t *)src);
|
Mod_LoadSTvertList(pheader, (dstvert_t *)src);
|
||||||
}
|
}
|
||||||
else if (Q_strncasecmp(blockname, "tris", sizeof(blockname)) == 0)
|
else if (Q_strncasecmp(blockname, "tris", sizeof(blockname)) == 0)
|
||||||
{
|
{
|
||||||
|
@ -1178,11 +1180,11 @@ Mod_LoadModel_DKM(const char *mod_name, const void *buffer, int modfilelen,
|
||||||
mesh_nodes[0].start = 0;
|
mesh_nodes[0].start = 0;
|
||||||
mesh_nodes[0].num = pheader->num_glcmds;
|
mesh_nodes[0].num = pheader->num_glcmds;
|
||||||
|
|
||||||
memcpy ((byte*)pheader + pheader->ofs_skins, (byte *)buffer + header.ofs_skins,
|
memcpy((byte*)pheader + pheader->ofs_skins, (byte *)buffer + header.ofs_skins,
|
||||||
pheader->num_skins * MAX_SKINNAME);
|
pheader->num_skins * MAX_SKINNAME);
|
||||||
Mod_LoadSTvertList (pheader,
|
Mod_LoadSTvertList(pheader,
|
||||||
(dstvert_t *)((byte *)buffer + header.ofs_st));
|
(dstvert_t *)((byte *)buffer + header.ofs_st));
|
||||||
Mod_LoadDKMCmdList (mod_name, pheader,
|
Mod_LoadDKMCmdList(mod_name, pheader,
|
||||||
(int *)((byte *)buffer + header.ofs_glcmds));
|
(int *)((byte *)buffer + header.ofs_glcmds));
|
||||||
if (header.version == DKM1_VERSION)
|
if (header.version == DKM1_VERSION)
|
||||||
{
|
{
|
||||||
|
@ -1195,7 +1197,7 @@ Mod_LoadModel_DKM(const char *mod_name, const void *buffer, int modfilelen,
|
||||||
header.framesize, header.translate);
|
header.framesize, header.translate);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mod_LoadDkmTriangleList (pheader,
|
Mod_LoadDkmTriangleList(pheader,
|
||||||
(dkmtriangle_t *)((byte *)buffer + header.ofs_tris));
|
(dkmtriangle_t *)((byte *)buffer + header.ofs_tris));
|
||||||
|
|
||||||
for (i = 0; i < pheader->num_skins; i++)
|
for (i = 0; i < pheader->num_skins; i++)
|
||||||
|
@ -1392,6 +1394,11 @@ Mod_LoadModel(const char *mod_name, const void *buffer, int modfilelen,
|
||||||
skins, numskins, type);
|
skins, numskins, type);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IDMD5HEADER:
|
||||||
|
extradata = Mod_LoadModel_MD5(mod_name, buffer, modfilelen,
|
||||||
|
skins, numskins, type);
|
||||||
|
break;
|
||||||
|
|
||||||
case IDSPRITEHEADER:
|
case IDSPRITEHEADER:
|
||||||
extradata = Mod_LoadSprite_SP2(mod_name, buffer, modfilelen,
|
extradata = Mod_LoadSprite_SP2(mod_name, buffer, modfilelen,
|
||||||
skins, numskins, type);
|
skins, numskins, type);
|
||||||
|
|
1165
src/client/refresh/files/models_md5.c
Normal file
1165
src/client/refresh/files/models_md5.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -322,6 +322,8 @@ typedef struct
|
||||||
|
|
||||||
/* Shared models func */
|
/* Shared models func */
|
||||||
typedef struct image_s* (*findimage_t)(const char *name, imagetype_t type);
|
typedef struct image_s* (*findimage_t)(const char *name, imagetype_t type);
|
||||||
|
extern void *Mod_LoadModel_MD5(const char *mod_name, const void *buffer, int modfilelen,
|
||||||
|
struct image_s ***skins, int *numskins, modtype_t *type);
|
||||||
extern void *Mod_LoadModel(const char *mod_name, const void *buffer, int modfilelen,
|
extern void *Mod_LoadModel(const char *mod_name, const void *buffer, int modfilelen,
|
||||||
vec3_t mins, vec3_t maxs, struct image_s ***skins, int *numskins,
|
vec3_t mins, vec3_t maxs, struct image_s ***skins, int *numskins,
|
||||||
findimage_t find_image, loadimage_t load_image, modtype_t *type);
|
findimage_t find_image, loadimage_t load_image, modtype_t *type);
|
||||||
|
|
|
@ -212,7 +212,9 @@ typedef enum
|
||||||
* ==============================================================
|
* ==============================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Vectors */
|
||||||
typedef float vec_t;
|
typedef float vec_t;
|
||||||
|
typedef vec_t vec2_t[2];
|
||||||
typedef vec_t vec3_t[3];
|
typedef vec_t vec3_t[3];
|
||||||
typedef vec_t vec4_t[4];
|
typedef vec_t vec4_t[4];
|
||||||
typedef vec_t vec5_t[5];
|
typedef vec_t vec5_t[5];
|
||||||
|
|
Loading…
Reference in a new issue