📄 gl_model.cpp
字号:
for ( i=0 ; i<count ; i++)
out[i] = LittleLong (in[i]);
}
/*
=================
Mod_LoadPlanes
=================
*/
void Mod_LoadPlanes( model_t *loadmodel, lump_t *l )
{
int i, j;
cplane_t *out;
dplane_t *in;
int count;
int bits;
in = (dplane_t *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
engine.Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (cplane_t *)engine.MemAlloc( 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;
}
}
//-----------------------------------------------------------------------------
// Purpose: Loads the vertex index list for all portals
// Input : *loadmodel -
// *l -
//-----------------------------------------------------------------------------
void Mod_LoadPortalVerts( model_t *loadmodel, lump_t *l )
{
int i;
unsigned short *out;
unsigned short *in;
int count;
in = (unsigned short *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
engine.Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (unsigned short *)engine.MemAlloc( count*sizeof(*out) );
loadmodel->portalverts = out;
loadmodel->numportalverts = count;
for ( i = 0; i < count; i++, in++, out++ )
{
*out = (unsigned short)LittleShort( *in );
}
}
//-----------------------------------------------------------------------------
// Purpose: loads the portal index list for all clusters
// Input : *loadmodel -
// *l -
//-----------------------------------------------------------------------------
void Mod_LoadClusterPortals( model_t *loadmodel, lump_t *l )
{
int i;
unsigned short *out;
unsigned short *in;
int count;
in = (unsigned short *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
engine.Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (unsigned short *)engine.MemAlloc( count*sizeof(*out) );
loadmodel->clusterportals = out;
loadmodel->numclusterportals = count;
for ( i = 0; i < count; i++, in++, out++ )
{
*out = (unsigned short)LittleShort( *in );
}
}
//-----------------------------------------------------------------------------
// Purpose: Loads the data for each clusters (points to portal list)
// Input : *loadmodel -
// *l -
//-----------------------------------------------------------------------------
void Mod_LoadClusters( model_t *loadmodel, lump_t *l )
{
int i;
mcluster_t *out;
dcluster_t *in;
int count;
in = (dcluster_t *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
engine.Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (mcluster_t *)engine.MemAlloc( count*sizeof(*out) );
loadmodel->clusters = out;
loadmodel->numclusters = count;
for ( i = 0; i < count; i++, in++, out++ )
{
out->numportals = LittleLong( in->numportals );
out->portalList = loadmodel->clusterportals + LittleLong( in->firstportal );
}
}
void Mod_LoadPortals( model_t *loadmodel, lump_t *l )
{
int i;
mportal_t *out;
dportal_t *in;
int count;
in = (dportal_t *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
engine.Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (mportal_t *)engine.MemAlloc( count*sizeof(*out) );
loadmodel->portals = out;
loadmodel->numportals = count;
for ( i = 0; i < count; i++, in++, out++ )
{
out->cluster[0] = (unsigned short)LittleShort( in->cluster[0] );
out->cluster[1] = (unsigned short)LittleShort( in->cluster[1] );
out->numportalverts = LittleLong( in->numportalverts );
out->plane = loadmodel->planes + LittleLong( in->planenum );
out->vertList = loadmodel->portalverts + LittleLong( in->firstportalvert );
out->visframe = 0;
}
}
model_t *r_worldmodel = NULL;
/*
=================
Mod_LoadMap
=================
*/
void Mod_LoadMap( void *buffer )
{
int i;
dheader_t *header;
model_t *mod = mod_known;
mod->type = mod_brush;
if (mod != mod_known)
engine.Error ("Loaded a brush model after the world");
header = (dheader_t *)buffer;
i = LittleLong (header->version);
if (i != BSPVERSION)
engine.Error ("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
// we don't really load the entities, just parse out the .wads' that are used
// This should go away when shaders are done
Mod_LoadEntities( mod, &header->lumps[LUMP_ENTITIES] );
Mod_LoadVertexes( mod, &header->lumps[LUMP_VERTEXES] );
Mod_LoadEdges( mod, &header->lumps[LUMP_EDGES] );
Mod_LoadSurfedges( mod, &header->lumps[LUMP_SURFEDGES] );
Mod_LoadLighting( mod, &header->lumps[LUMP_LIGHTING] );
Mod_LoadPlanes( mod, &header->lumps[LUMP_PLANES] );
// texdata needs to load before texinfo
Mod_LoadTexdata( mod, &header->lumps[LUMP_TEXDATA] );
Mod_LoadTexinfo( mod, &header->lumps[LUMP_TEXINFO] );
Mod_LoadDispInfo( mod, &header->lumps[LUMP_DISPINFO] );
Mod_LoadFaces( mod, &header->lumps[LUMP_FACES] );
Mod_LoadMarksurfaces( mod, &header->lumps[LUMP_LEAFFACES] );
// UNDONE: Client shouldn't need visibility, use common model
Mod_LoadVisibility( mod, &header->lumps[LUMP_VISIBILITY] );
Mod_LoadLeafs( mod, &header->lumps[LUMP_LEAFS] );
Mod_LoadNodes( mod, &header->lumps[LUMP_NODES] );
// UNDONE: Does the cmodel need worldlights?
Mod_LoadWorldlights( mod, &header->lumps[LUMP_WORLDLIGHTS] );
// load the portal information
Mod_LoadPortalVerts( mod, &header->lumps[LUMP_PORTALVERTS] );
Mod_LoadClusterPortals( mod, &header->lumps[LUMP_CLUSTERPORTALS] );
Mod_LoadClusters( mod, &header->lumps[LUMP_CLUSTERS] );
Mod_LoadPortals( mod, &header->lumps[LUMP_PORTALS] );
// mod->numframes = 2; // regular and alternate animation
Mod_LoadSubmodels( mod, &header->lumps[LUMP_MODELS] );
//
// set up the submodels
//
for (i=0 ; i<mod->numsubmodels ; i++)
{
model_t *starmod;
mmodel_t *bm;
bm = &mod->submodels[i];
starmod = &mod_inline[i];
*starmod = *mod;
starmod->firstmodelsurface = bm->firstface;
starmod->nummodelsurfaces = bm->numfaces;
starmod->firstnode = bm->headnode;
if (starmod->firstnode >= mod->numnodes)
engine.Error ("Inline model %i has bad firstnode", i);
VectorCopy (bm->maxs, starmod->maxs);
VectorCopy (bm->mins, starmod->mins);
starmod->radius = bm->radius;
if (i == 0)
*mod = *starmod;
starmod->numleafs = bm->visleafs;
}
r_worldmodel = mod;
GL_BeginBuildingLightmaps( mod );
for ( i = 0; i < mod->numsurfaces; i++ )
{
GL_CreateSurfaceLightmap( mod->surfaces + i );
}
GL_EndBuildingLightmaps();
}
#if 0
/*
==============================================================================
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)
engine.Error ("%s has wrong version number (%i should be %i)",
mod->name, sprout->version, SPRITE_VERSION);
if (sprout->numframes > MAX_MD2SKINS)
engine.Error ("%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;
}
#endif
#if 0
//=============================================================================
/*
@@@@@@@@@@@@@@@@@@@@@
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);
}
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]);
}
}
#endif
/*
===============
R_MarkLeaves
Mark the leaves and nodes that are in the PVS for the current
cluster
===============
*/
int r_oldviewcluster = -2, r_viewcluster = -2, r_oldviewcluster2 = -2, r_viewcluster2 = -2, r_visframecount = 0;
void R_MarkLeaves( void );
void R_SetupVis( Vector& origin, model_t *worldmodel )
{
mleaf_t *leaf;
r_worldmodel = worldmodel;
leaf = Mod_PointInLeaf( origin, worldmodel );
r_viewcluster = r_viewcluster2 = leaf->cluster;
R_MarkLeaves();
}
void R_MarkLeaves( void )
{
byte *vis;
byte fatvis[MAX_MAP_LEAFS/8];
mnode_t *node;
int i, c;
mleaf_t *leaf;
int cluster;
if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2 && !r_novis->value && r_viewcluster != -1)
return;
// development aid to let you run around and see exactly where
// the pvs ends
if (gl_lockpvs->value)
return;
r_visframecount++;
r_oldviewcluster = r_viewcluster;
r_oldviewcluster2 = r_viewcluster2;
if (r_novis->value || r_viewcluster == -1 || !r_worldmodel->vis)
{
// mark everything
for (i=0 ; i<r_worldmodel->numleafs ; i++)
r_worldmodel->leafs[i].visframe = r_visframecount;
for (i=0 ; i<r_worldmodel->numnodes ; i++)
r_worldmodel->nodes[i].visframe = r_visframecount;
for ( i = 0; i < r_worldmodel->numportals; i++ )
r_worldmodel->portals[i].visframe = r_visframecount;
return;
}
vis = Mod_ClusterPVS (r_viewcluster, r_worldmodel);
// may have to combine two clusters because of solid water boundaries
if (r_viewcluster2 != r_viewcluster)
{
memcpy (fatvis, vis, (r_worldmodel->numleafs+7)/8);
vis = Mod_ClusterPVS (r_viewcluster2, r_worldmodel);
c = (r_worldmodel->numleafs+31)/32;
for (i=0 ; i<c ; i++)
((int *)fatvis)[i] |= ((int *)vis)[i];
vis = fatvis;
}
for (i=0,leaf=r_worldmodel->leafs ; i<r_worldmodel->numleafs ; i++, leaf++)
{
cluster = leaf->cluster;
if (cluster == -1)
continue;
if (vis[cluster>>3] & (1<<(cluster&7)))
{
int j;
unsigned short *start;
if ( r_worldmodel->portals )
{
start = r_worldmodel->clusters[ cluster ].portalList;
for ( j = 0; j < r_worldmodel->clusters[ cluster ].numportals; j++ )
{
r_worldmodel->portals[ *start ].visframe = r_visframecount;
start++;
}
}
node = (mnode_t *)leaf;
do
{
if (node->visframe == r_visframecount)
break;
node->visframe = r_visframecount;
node = node->parent;
} while (node);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -