📄 gl_model.c
字号:
{
out->extents[i] = 16384;
out->texturemins[i] = -8192;
}
GL_SubdivideSurface (out); // cut up polygon for warps
}
// create lightmaps and polygons
if ( !(out->texinfo->flags & (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_WARP) ) )
GL_CreateSurfaceLightmap (out);
if (! (out->texinfo->flags & SURF_WARP) )
GL_BuildPolygonFromSurface(out);
}
GL_EndBuildingLightmaps ();
}
/*
=================
Mod_SetParent
=================
*/
void Mod_SetParent (mnode_t *node, mnode_t *parent)
{
node->parent = parent;
if (node->contents != -1)
return;
Mod_SetParent (node->children[0], node);
Mod_SetParent (node->children[1], node);
}
/*
=================
Mod_LoadNodes
=================
*/
void Mod_LoadNodes (lump_t *l)
{
int i, j, count, p;
dnode_t *in;
mnode_t *out;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = Hunk_Alloc ( count*sizeof(*out));
loadmodel->nodes = out;
loadmodel->numnodes = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
for (j=0 ; j<3 ; j++)
{
out->minmaxs[j] = LittleShort (in->mins[j]);
out->minmaxs[3+j] = LittleShort (in->maxs[j]);
}
p = LittleLong(in->planenum);
out->plane = loadmodel->planes + p;
out->firstsurface = LittleShort (in->firstface);
out->numsurfaces = LittleShort (in->numfaces);
out->contents = -1; // differentiate from leafs
for (j=0 ; j<2 ; j++)
{
p = LittleLong (in->children[j]);
if (p >= 0)
out->children[j] = loadmodel->nodes + p;
else
out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p));
}
}
Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs
}
/*
=================
Mod_LoadLeafs
=================
*/
void Mod_LoadLeafs (lump_t *l)
{
dleaf_t *in;
mleaf_t *out;
int i, j, count, p;
// glpoly_t *poly;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = Hunk_Alloc ( count*sizeof(*out));
loadmodel->leafs = out;
loadmodel->numleafs = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
for (j=0 ; j<3 ; j++)
{
out->minmaxs[j] = LittleShort (in->mins[j]);
out->minmaxs[3+j] = LittleShort (in->maxs[j]);
}
p = LittleLong(in->contents);
out->contents = p;
out->cluster = LittleShort(in->cluster);
out->area = LittleShort(in->area);
out->firstmarksurface = loadmodel->marksurfaces +
LittleShort(in->firstleafface);
out->nummarksurfaces = LittleShort(in->numleaffaces);
// gl underwater warp
#if 0
if (out->contents & (CONTENTS_WATER|CONTENTS_SLIME|CONTENTS_LAVA|CONTENTS_THINWATER) )
{
for (j=0 ; j<out->nummarksurfaces ; j++)
{
out->firstmarksurface[j]->flags |= SURF_UNDERWATER;
for (poly = out->firstmarksurface[j]->polys ; poly ; poly=poly->next)
poly->flags |= SURF_UNDERWATER;
}
}
#endif
}
}
/*
=================
Mod_LoadMarksurfaces
=================
*/
void Mod_LoadMarksurfaces (lump_t *l)
{
int i, j, count;
short *in;
msurface_t **out;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = Hunk_Alloc ( count*sizeof(*out));
loadmodel->marksurfaces = out;
loadmodel->nummarksurfaces = count;
for ( i=0 ; i<count ; i++)
{
j = LittleShort(in[i]);
if (j < 0 || j >= loadmodel->numsurfaces)
ri.Sys_Error (ERR_DROP, "Mod_ParseMarksurfaces: bad surface number");
out[i] = loadmodel->surfaces + j;
}
}
/*
=================
Mod_LoadSurfedges
=================
*/
void Mod_LoadSurfedges (lump_t *l)
{
int i, count;
int *in, *out;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
if (count < 1 || count >= MAX_MAP_SURFEDGES)
ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: bad surfedges count in %s: %i",
loadmodel->name, count);
out = Hunk_Alloc ( count*sizeof(*out));
loadmodel->surfedges = out;
loadmodel->numsurfedges = count;
for ( i=0 ; i<count ; i++)
out[i] = LittleLong (in[i]);
}
/*
=================
Mod_LoadPlanes
=================
*/
void Mod_LoadPlanes (lump_t *l)
{
int i, j;
cplane_t *out;
dplane_t *in;
int count;
int bits;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
ri.Sys_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = Hunk_Alloc ( count*2*sizeof(*out));
loadmodel->planes = out;
loadmodel->numplanes = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
bits = 0;
for (j=0 ; j<3 ; j++)
{
out->normal[j] = LittleFloat (in->normal[j]);
if (out->normal[j] < 0)
bits |= 1<<j;
}
out->dist = LittleFloat (in->dist);
out->type = LittleLong (in->type);
out->signbits = bits;
}
}
/*
=================
Mod_LoadBrushModel
=================
*/
void Mod_LoadBrushModel (model_t *mod, void *buffer)
{
int i;
dheader_t *header;
mmodel_t *bm;
loadmodel->type = mod_brush;
if (loadmodel != mod_known)
ri.Sys_Error (ERR_DROP, "Loaded a brush model after the world");
header = (dheader_t *)buffer;
i = LittleLong (header->version);
if (i != BSPVERSION)
ri.Sys_Error (ERR_DROP, "Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION);
// swap all the lumps
mod_base = (byte *)header;
for (i=0 ; i<sizeof(dheader_t)/4 ; i++)
((int *)header)[i] = LittleLong ( ((int *)header)[i]);
// load into heap
Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]);
Mod_LoadEdges (&header->lumps[LUMP_EDGES]);
Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]);
Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]);
Mod_LoadPlanes (&header->lumps[LUMP_PLANES]);
Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]);
Mod_LoadFaces (&header->lumps[LUMP_FACES]);
Mod_LoadMarksurfaces (&header->lumps[LUMP_LEAFFACES]);
Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]);
Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]);
Mod_LoadNodes (&header->lumps[LUMP_NODES]);
Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]);
mod->numframes = 2; // regular and alternate animation
//
// set up the submodels
//
for (i=0 ; i<mod->numsubmodels ; i++)
{
model_t *starmod;
bm = &mod->submodels[i];
starmod = &mod_inline[i];
*starmod = *loadmodel;
starmod->firstmodelsurface = bm->firstface;
starmod->nummodelsurfaces = bm->numfaces;
starmod->firstnode = bm->headnode;
if (starmod->firstnode >= loadmodel->numnodes)
ri.Sys_Error (ERR_DROP, "Inline model %i has bad firstnode", i);
VectorCopy (bm->maxs, starmod->maxs);
VectorCopy (bm->mins, starmod->mins);
starmod->radius = bm->radius;
if (i == 0)
*loadmodel = *starmod;
starmod->numleafs = bm->visleafs;
}
}
/*
==============================================================================
ALIAS MODELS
==============================================================================
*/
/*
=================
Mod_LoadAliasModel
=================
*/
void Mod_LoadAliasModel (model_t *mod, void *buffer)
{
int i, j;
dmdl_t *pinmodel, *pheader;
dstvert_t *pinst, *poutst;
dtriangle_t *pintri, *pouttri;
daliasframe_t *pinframe, *poutframe;
int *pincmd, *poutcmd;
int version;
pinmodel = (dmdl_t *)buffer;
version = LittleLong (pinmodel->version);
if (version != ALIAS_VERSION)
ri.Sys_Error (ERR_DROP, "%s has wrong version number (%i should be %i)",
mod->name, version, ALIAS_VERSION);
pheader = Hunk_Alloc (LittleLong(pinmodel->ofs_end));
// byte swap the header fields and sanity check
for (i=0 ; i<sizeof(dmdl_t)/4 ; i++)
((int *)pheader)[i] = LittleLong (((int *)buffer)[i]);
if (pheader->skinheight > MAX_LBM_HEIGHT)
ri.Sys_Error (ERR_DROP, "model %s has a skin taller than %d", mod->name,
MAX_LBM_HEIGHT);
if (pheader->num_xyz <= 0)
ri.Sys_Error (ERR_DROP, "model %s has no vertices", mod->name);
if (pheader->num_xyz > MAX_VERTS)
ri.Sys_Error (ERR_DROP, "model %s has too many vertices", mod->name);
if (pheader->num_st <= 0)
ri.Sys_Error (ERR_DROP, "model %s has no st vertices", mod->name);
if (pheader->num_tris <= 0)
ri.Sys_Error (ERR_DROP, "model %s has no triangles", mod->name);
if (pheader->num_frames <= 0)
ri.Sys_Error (ERR_DROP, "model %s has no frames", mod->name);
//
// load base s and t vertices (not used in gl version)
//
pinst = (dstvert_t *) ((byte *)pinmodel + pheader->ofs_st);
poutst = (dstvert_t *) ((byte *)pheader + pheader->ofs_st);
for (i=0 ; i<pheader->num_st ; i++)
{
poutst[i].s = LittleShort (pinst[i].s);
poutst[i].t = LittleShort (pinst[i].t);
}
//
// load triangle lists
//
pintri = (dtriangle_t *) ((byte *)pinmodel + pheader->ofs_tris);
pouttri = (dtriangle_t *) ((byte *)pheader + pheader->ofs_tris);
for (i=0 ; i<pheader->num_tris ; i++)
{
for (j=0 ; j<3 ; j++)
{
pouttri[i].index_xyz[j] = LittleShort (pintri[i].index_xyz[j]);
pouttri[i].index_st[j] = LittleShort (pintri[i].index_st[j]);
}
}
//
// load the frames
//
for (i=0 ; i<pheader->num_frames ; i++)
{
pinframe = (daliasframe_t *) ((byte *)pinmodel
+ pheader->ofs_frames + i * pheader->framesize);
poutframe = (daliasframe_t *) ((byte *)pheader
+ pheader->ofs_frames + i * pheader->framesize);
memcpy (poutframe->name, pinframe->name, sizeof(poutframe->name));
for (j=0 ; j<3 ; j++)
{
poutframe->scale[j] = LittleFloat (pinframe->scale[j]);
poutframe->translate[j] = LittleFloat (pinframe->translate[j]);
}
// verts are all 8 bit, so no swapping needed
memcpy (poutframe->verts, pinframe->verts,
pheader->num_xyz*sizeof(dtrivertx_t));
}
mod->type = mod_alias;
//
// load the glcmds
//
pincmd = (int *) ((byte *)pinmodel + pheader->ofs_glcmds);
poutcmd = (int *) ((byte *)pheader + pheader->ofs_glcmds);
for (i=0 ; i<pheader->num_glcmds ; i++)
poutcmd[i] = LittleLong (pincmd[i]);
// register all skins
memcpy ((char *)pheader + pheader->ofs_skins, (char *)pinmodel + pheader->ofs_skins,
pheader->num_skins*MAX_SKINNAME);
for (i=0 ; i<pheader->num_skins ; i++)
{
mod->skins[i] = GL_FindImage ((char *)pheader + pheader->ofs_skins + i*MAX_SKINNAME
, it_skin);
}
mod->mins[0] = -32;
mod->mins[1] = -32;
mod->mins[2] = -32;
mod->maxs[0] = 32;
mod->maxs[1] = 32;
mod->maxs[2] = 32;
}
/*
==============================================================================
SPRITE MODELS
==============================================================================
*/
/*
=================
Mod_LoadSpriteModel
=================
*/
void Mod_LoadSpriteModel (model_t *mod, void *buffer)
{
dsprite_t *sprin, *sprout;
int i;
sprin = (dsprite_t *)buffer;
sprout = Hunk_Alloc (modfilelen);
sprout->ident = LittleLong (sprin->ident);
sprout->version = LittleLong (sprin->version);
sprout->numframes = LittleLong (sprin->numframes);
if (sprout->version != SPRITE_VERSION)
ri.Sys_Error (ERR_DROP, "%s has wrong version number (%i should be %i)",
mod->name, sprout->version, SPRITE_VERSION);
if (sprout->numframes > MAX_MD2SKINS)
ri.Sys_Error (ERR_DROP, "%s has too many frames (%i > %i)",
mod->name, sprout->numframes, MAX_MD2SKINS);
// byte swap everything
for (i=0 ; i<sprout->numframes ; i++)
{
sprout->frames[i].width = LittleLong (sprin->frames[i].width);
sprout->frames[i].height = LittleLong (sprin->frames[i].height);
sprout->frames[i].origin_x = LittleLong (sprin->frames[i].origin_x);
sprout->frames[i].origin_y = LittleLong (sprin->frames[i].origin_y);
memcpy (sprout->frames[i].name, sprin->frames[i].name, MAX_SKINNAME);
mod->skins[i] = GL_FindImage (sprout->frames[i].name,
it_sprite);
}
mod->type = mod_sprite;
}
//=============================================================================
/*
@@@@@@@@@@@@@@@@@@@@@
R_BeginRegistration
Specifies the model that will be used as the world
@@@@@@@@@@@@@@@@@@@@@
*/
void R_BeginRegistration (char *model)
{
char fullname[MAX_QPATH];
cvar_t *flushmap;
registration_sequence++;
r_oldviewcluster = -1; // force markleafs
Com_sprintf (fullname, sizeof(fullname), "maps/%s.bsp", model);
// explicitly free the old map if different
// this guarantees that mod_known[0] is the world map
flushmap = ri.Cvar_Get ("flushmap", "0", 0);
if ( strcmp(mod_known[0].name, fullname) || flushmap->value)
Mod_Free (&mod_known[0]);
r_worldmodel = Mod_ForName(fullname, true);
r_viewcluster = -1;
}
/*
@@@@@@@@@@@@@@@@@@@@@
R_RegisterModel
@@@@@@@@@@@@@@@@@@@@@
*/
struct model_s *R_RegisterModel (char *name)
{
model_t *mod;
int i;
dsprite_t *sprout;
dmdl_t *pheader;
mod = Mod_ForName (name, false);
if (mod)
{
mod->registration_sequence = registration_sequence;
// register any images used by the models
if (mod->type == mod_sprite)
{
sprout = (dsprite_t *)mod->extradata;
for (i=0 ; i<sprout->numframes ; i++)
mod->skins[i] = GL_FindImage (sprout->frames[i].name, it_sprite);
}
else if (mod->type == mod_alias)
{
pheader = (dmdl_t *)mod->extradata;
for (i=0 ; i<pheader->num_skins ; i++)
mod->skins[i] = GL_FindImage ((char *)pheader + pheader->ofs_skins + i*MAX_SKINNAME, it_skin);
//PGM
mod->numframes = pheader->num_frames;
//PGM
}
else if (mod->type == mod_brush)
{
for (i=0 ; i<mod->numtexinfo ; i++)
mod->texinfo[i].image->registration_sequence = registration_sequence;
}
}
return mod;
}
/*
@@@@@@@@@@@@@@@@@@@@@
R_EndRegistration
@@@@@@@@@@@@@@@@@@@@@
*/
void R_EndRegistration (void)
{
int i;
model_t *mod;
for (i=0, mod=mod_known ; i<mod_numknown ; i++, mod++)
{
if (!mod->name[0])
continue;
if (mod->registration_sequence != registration_sequence)
{ // don't need this model
Mod_Free (mod);
}
}
GL_FreeUnusedImages ();
}
//=============================================================================
/*
================
Mod_Free
================
*/
void Mod_Free (model_t *mod)
{
Hunk_Free (mod->extradata);
memset (mod, 0, sizeof(*mod));
}
/*
================
Mod_FreeAll
================
*/
void Mod_FreeAll (void)
{
int i;
for (i=0 ; i<mod_numknown ; i++)
{
if (mod_known[i].extradatasize)
Mod_Free (&mod_known[i]);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -