📄 gl_model.pas
字号:
_in, _out: PInteger;
begin
_in := Pointer(Cardinal(mod_base) + l^.fileofs);
if (l.filelen mod sizeof(_in^)) <> 0 then
ri.Sys_Error(ERR_DROP, 'MOD_LoadBmodel: funny lump size in %s', loadmodel.name);
count := l.filelen div sizeof(_in^);
if (count < 1) or (count >= MAX_MAP_SURFEDGES) then
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 to count - 1 do
PIntegerArray(_out)^[i] := LittleLong(PIntegerArray(_in)^[i]);
end;
{*
=================
Mod_LoadPlanes
=================
*}
procedure Mod_LoadPlanes(l: lump_p);
var
i, j: integer;
_out: cplane_p;
_in: dplane_p;
count,
bits: integer;
begin
_in := Pointer(Cardinal(mod_base) + l^.fileofs);
if (l.filelen mod sizeof(_in^)) <> 0 then
ri.Sys_Error(ERR_DROP, 'MOD_LoadBmodel: funny lump size in %s', loadmodel.name);
count := l.filelen div sizeof(_in^);
_out := Hunk_Alloc(count * 2 * sizeof(_out^));
loadmodel.planes := _out;
loadmodel.numplanes := count;
for i := 0 to count - 1 do
begin
bits := 0;
for j := 0 to 2 do
begin
_out.normal[j] := LittleFloat(_in.normal[j]);
if (_out.normal[j] < 0) then
bits := bits or (1 shl j);
end;
_out.dist := LittleFloat(_in.dist);
_out._type := LittleLong(_in._type);
_out.signbits := bits;
Inc(_in);
Inc(_out);
end;
end;
{*
=================
Mod_LoadBrushModel
=================
*}
procedure Mod_LoadBrushModel(_mod: model_p; buffer: pointer);
var
i: integer;
header: dheader_p;
bm: mmodel_p;
starmod: model_p;
begin
loadmodel._type := mod_brush;
if (loadmodel <> @mod_known) then
ri.Sys_Error(ERR_DROP, 'Loaded a brush model after the world', []);
header := buffer;
i := LittleLong(header^.version);
if (i <> BSPVERSION) then
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 := PByte(header);
for i := 0 to sizeof(dheader_t) div 4 - 1 do
PIntegerArray(header)^[i] := LittleLong(PIntegerArray(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 to _mod.numsubmodels - 1 do
begin
bm := @mModel_arrp(_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) then
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) then
loadmodel^ := starmod^;
starmod.numleafs := bm.visleafs;
end;
end;
{*
==============================================================================
ALIAS MODELS
==============================================================================
*}
{*
=================
Mod_LoadAliasModel
=================
*}
procedure Mod_LoadAliasModel(_mod: model_p; buffer: pointer);
var
i, j: integer;
pinmodel,
pheader: dmdl_p;
pinst,
poutst: dstvert_p;
pintri,
pouttri: dtriangle_p;
pinframe, poutframe: daliasframe_p;
pincmd, poutcmd: PInteger;
version: integer;
begin
pinmodel := dmdl_p(buffer);
version := LittleLong(pinmodel.version);
if (version <> ALIAS_VERSION) then
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 to sizeof(dmdl_t) div 4 - 1 do
PIntegerArray(pheader)^[i] := LittleLong(PIntegerArray(buffer)^[i]);
if (pheader.skinheight > MAX_LBM_HEIGHT) then
ri.Sys_Error(ERR_DROP, 'model %s has a skin taller than %d',
_mod.name, MAX_LBM_HEIGHT);
if (pheader.num_xyz <= 0) then
ri.Sys_Error(ERR_DROP, 'model %s has no vertices', _mod.name);
if (pheader.num_xyz > MAX_VERTS) then
ri.Sys_Error(ERR_DROP, 'model %s has too many vertices', _mod.name);
if (pheader.num_st <= 0) then
ri.Sys_Error(ERR_DROP, 'model %s has no st vertices', _mod.name);
if (pheader.num_tris <= 0) then
ri.Sys_Error(ERR_DROP, 'model %s has no triangles', _mod.name);
if (pheader.num_frames <= 0) then
ri.Sys_Error(ERR_DROP, 'model %s has no frames', _mod.name);
//
// load base s and t vertices (not used in gl version)
//
pinst := Pointer(Cardinal(pinmodel) + pheader^.ofs_st);
poutst := Pointer(Cardinal(pheader) + pheader^.ofs_st);
for i := 0 to pheader.num_st - 1 do
begin
dstvert_a(poutst)^[i].s := LittleShort(dstvert_a(pinst)^[i].s);
dstvert_a(poutst)^[i].t := LittleShort(dstvert_a(pinst)^[i].t);
end;
//
// load triangle lists
//
pintri := Pointer(Cardinal(pinmodel) + pheader^.ofs_tris);
pouttri := Pointer(Cardinal(pheader) + pheader^.ofs_tris);
for i := 0 to pheader.num_tris - 1 do
for j := 0 to 2 do
begin
dtriangle_a(pouttri)^[i].index_xyz[j] := LittleShort(dtriangle_a(pintri)^[i].index_xyz[j]);
dtriangle_a(pouttri)^[i].index_st[j] := LittleShort(dtriangle_a(pintri)^[i].index_st[j]);
end;
//
// load the frames
//
for i := 0 to pheader.num_frames - 1 do
begin
pinframe := Pointer(Cardinal(pinmodel)
+ pheader^.ofs_frames + i * pheader^.framesize);
poutframe := Pointer(Cardinal(pheader)
+ pheader^.ofs_frames + i * pheader^.framesize);
memcpy(@poutframe^.name, @pinframe^.name, sizeof(poutframe^.name));
for j := 0 to 2 do
begin
poutframe^.scale[j] := LittleFloat(pinframe^.scale[j]);
poutframe^.translate[j] := LittleFloat(pinframe^.translate[j]);
end;
// verts are all 8 bit, so no swapping needed
memcpy(@poutframe^.verts, @pinframe^.verts,
pheader^.num_xyz * sizeof(dtrivertx_t));
end;
_mod._type := mod_alias;
//
// load the glcmds
//
pincmd := Pointer(Cardinal(pinmodel) + pheader^.ofs_glcmds);
poutcmd := Pointer(Cardinal(pheader) + pheader^.ofs_glcmds);
for i := 0 to pheader^.num_glcmds - 1 do
PIntegerArray(poutcmd)^[i] := LittleLong(PIntegerArray(pincmd)^[i]);
// register all skins
memcpy(Pointer(Cardinal(pheader) + pheader^.ofs_skins), Pointer(Cardinal(pinmodel) + pheader^.ofs_skins),
pheader^.num_skins * MAX_SKINNAME);
for i := 0 to pheader.num_skins - 1 do
_mod.skins[i] := GL_FindImage(Pointer(Cardinal(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;
end;
{*
==============================================================================
SPRITE MODELS
==============================================================================
*}
{*
=================
Mod_LoadSpriteModel
=================
*}
procedure Mod_LoadSpriteModel(_mod: model_p; buffer: pointer);
var
sprin,
sprout: dsprite_p;
i: integer;
begin
sprin := 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) then
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) then
ri.Sys_Error(ERR_DROP, '%s has too many frames (%i > %i)',
_mod.name, sprout.numframes, MAX_MD2SKINS);
// byte swap everything
for i := 0 to sprout.numframes - 1 do
begin
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);
end;
_mod._type := mod_sprite;
end;
//=============================================================================
{*
@@@@@@@@@@@@@@@@@@@@@
R_BeginRegistration
Specifies the model that will be used as the world
@@@@@@@@@@@@@@@@@@@@@
*}
procedure R_BeginRegistration(model: PChar); cdecl; //for gl_rmain
var
fullname: array[0..MAX_QPATH - 1] of char;
flushmap: cvar_p;
begin
Inc(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) <> 0) or (flushmap^.Value <> 0) then
Mod_Free(@mod_known[0]);
r_worldmodel := Mod_ForName(fullname, true);
r_viewcluster := -1;
end;
{*
@@@@@@@@@@@@@@@@@@@@@
R_RegisterModel
@@@@@@@@@@@@@@@@@@@@@
*}
//struct model_s *R_RegisterModel (char *name)
function R_RegisterModel(name: PChar): pointer; cdecl; //for gl_rmain
var
_mod: model_p;
i: integer;
sprout: dsprite_p;
pheader: dmdl_p;
begin
_mod := Mod_ForName(name, false);
if Assigned(_mod) then
begin
_mod.registration_sequence := registration_sequence;
// register any images used by the models
if (_mod._type = mod_sprite) then
begin
sprout := {(dsprite_t * )} _mod.extradata;
for i := 0 to sprout.numframes - 1 do
_mod.skins[i] := GL_FindImage(sprout.frames[i].name, it_sprite);
end
else
if (_mod._type = mod_alias) then
begin
pheader := {(dmdl_t * )} _mod.extradata;
for i := 0 to pheader.num_skins - 1 do
_mod.skins[i] := GL_FindImage(Pointer(Cardinal(pheader) + pheader^.ofs_skins + i * MAX_SKINNAME), it_skin);
//PGM
_mod.numframes := pheader.num_frames;
//PGM
end
else
if (_mod._type = mod_brush) then
for i := 0 to _mod.numtexinfo - 1 do
mTexInfo_arrp(_mod.texinfo)^[i].image.registration_sequence := registration_sequence;
end;
Result := _mod;
end;
{*
@@@@@@@@@@@@@@@@@@@@@
R_EndRegistration
@@@@@@@@@@@@@@@@@@@@@
*}
procedure R_EndRegistration; cdecl; //gl_rmain
var
i: integer;
_mod: model_p;
begin
_mod := @mod_known[0];
for i := 0 to mod_numknown - 1 do
begin
if _mod^.name[0] = #0 then
begin
Inc(_mod);
continue;
end;
if _mod^.registration_sequence <> registration_sequence then
Mod_Free(_mod);
Inc(_mod);
end;
GL_FreeUnusedImages();
end;
//=============================================================================
{*
================
Mod_Free
================
*}
procedure Mod_Free(_mod: model_p);
begin
Hunk_Free(_mod.extradata);
memset(_mod, 0, sizeof(_mod^));
end;
{*
================
Mod_FreeAll
================
*}
procedure Mod_FreeAll;
var
i: integer;
begin
for i := 0 to mod_numknown - 1 do
if (mod_known[i].extradatasize <> 0) then
Mod_Free(@mod_known[i]);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -