From 10a7fbb00ab6d3880b1c22d83f4eed012b514991 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 27 Aug 2000 06:55:07 +0000 Subject: [PATCH] port over the interesting bits of gl_model.c from newtree --- source/gl_model.c | 309 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 217 insertions(+), 92 deletions(-) diff --git a/source/gl_model.c b/source/gl_model.c index d1b3b2e..678192d 100644 --- a/source/gl_model.c +++ b/source/gl_model.c @@ -1,7 +1,7 @@ /* gl_model.c - @description@ + model loading and caching Copyright (C) 1996-1997 Id Software, Inc. @@ -26,18 +26,41 @@ $Id$ */ +// models are the only shared resource between a client and server running +// on the same machine. + #ifdef HAVE_CONFIG_H -# include "config.h" +# include #endif - +#include #include +#include -#include "model.h" -#include "sys.h" #include "qendian.h" -#include "quakefs.h" -#include "glquake.h" +#include "msg.h" +#include "bspfile.h" // needed by: glquake.h +#include "vid.h" +#include "sys.h" +#include "mathlib.h" // needed by: protocol.h, render.h, client.h, + // modelgen.h, glmodel.h +#include "wad.h" +#include "draw.h" +#include "cvar.h" +#include "crc.h" +#include "net.h" // needed by: client.h +#include "protocol.h" // needed by: client.h +#include "cmd.h" +#include "sbar.h" +#include "render.h" // needed by: client.h, gl_model.h, glquake.h +#include "client.h" // need cls in this file +#include "model.h" // needed by: glquake.h #include "console.h" +#include "glquake.h" +#include "quakefs.h" + +void Sys_Error (char *error, ...); + +extern int texture_mode; model_t *loadmodel; char loadname[32]; // for hunk tags @@ -46,6 +69,9 @@ void Mod_LoadSpriteModel (model_t *mod, void *buffer); void Mod_LoadBrushModel (model_t *mod, void *buffer); void Mod_LoadAliasModel (model_t *mod, void *buffer); model_t *Mod_LoadModel (model_t *mod, qboolean crash); +void R_InitSky(struct texture_s *mt); +void GL_SubdivideSurface (msurface_t *fa); +void Mod_LoadMMNearest(miptex_t *mx, texture_t *tx); byte mod_novis[MAX_MAP_LEAFS/8]; @@ -53,6 +79,8 @@ byte mod_novis[MAX_MAP_LEAFS/8]; model_t mod_known[MAX_MOD_KNOWN]; int mod_numknown; +unsigned *model_checksum; +texture_t *r_notexture_mip; cvar_t *gl_subdivide_size; /* @@ -66,28 +94,6 @@ void Mod_Init (void) memset (mod_novis, 0xff, sizeof(mod_novis)); } -/* -=============== -Mod_Init - -Caches the data if needed -=============== -*/ -void *Mod_Extradata (model_t *mod) -{ - void *r; - - r = Cache_Check (&mod->cache); - if (r) - return r; - - Mod_LoadModel (mod, true); - - if (!mod->cache.data) - Sys_Error ("Mod_Extradata: caching failed"); - return mod->cache.data; -} - /* =============== Mod_PointInLeaf @@ -223,25 +229,6 @@ model_t *Mod_FindName (char *name) return mod; } -/* -================== -Mod_TouchModel - -================== -*/ -void Mod_TouchModel (char *name) -{ - model_t *mod; - - mod = Mod_FindName (name); - - if (!mod->needload) - { - if (mod->type == mod_alias) - Cache_Check (&mod->cache); - } -} - /* ================== Mod_LoadModel @@ -266,14 +253,6 @@ model_t *Mod_LoadModel (model_t *mod, qboolean crash) else return mod; // not cached at all } - -// -// because the world is so huge, load it one piece at a time -// - if (!crash) - { - - } // // load the file @@ -299,6 +278,7 @@ model_t *Mod_LoadModel (model_t *mod, qboolean crash) // call the apropriate loader mod->needload = false; + mod->hasfullbrights = false; switch (LittleLong(*(unsigned *)buf)) { @@ -396,15 +376,12 @@ void Mod_LoadTextures (lump_t *l) tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t); // the pixels immediately follow the structures memcpy ( tx+1, mt+1, pixels); - if (!strncmp(mt->name,"sky",3)) R_InitSky (tx); else { - texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; - tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false, 1); - texture_mode = GL_LINEAR; + Mod_LoadMMNearest(mt, tx); } } @@ -502,6 +479,8 @@ void Mod_LoadTextures (lump_t *l) } } +extern byte *COM_LoadFile (char *path, int usehunk); + /* ================= Mod_LoadLighting @@ -509,13 +488,36 @@ Mod_LoadLighting */ void Mod_LoadLighting (lump_t *l) { + int i; + byte *in, *out; + byte d; + char litfilename[1024]; + if (!l->filelen) { loadmodel->lightdata = NULL; return; } - loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname); - memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen); + + strcpy(litfilename, loadmodel->name); + COM_StripExtension(litfilename, litfilename); + strcat(litfilename, ".lit"); + + loadmodel->lightdata = (byte*) COM_LoadHunkFile (litfilename); + if (!loadmodel->lightdata) // expand the white lighting data + { + loadmodel->lightdata = Hunk_AllocName ( l->filelen*3, litfilename); + in = loadmodel->lightdata + l->filelen*2; // place the file at the end, so it will not be overwritten until the very last write + out = loadmodel->lightdata; + memcpy (in, mod_base + l->fileofs, l->filelen); + for (i = 0;i < l->filelen;i++) + { + d = *in++; + *out++ = d; + *out++ = d; + *out++ = d; + } + } } @@ -668,10 +670,13 @@ void Mod_LoadTexinfo (lump_t *l) for ( i=0 ; ivecs[0][j] = LittleFloat (in->vecs[0][j]); + out->vecs[1][j] = LittleFloat (in->vecs[1][j]); + } len1 = Length (out->vecs[0]); len2 = Length (out->vecs[1]); + len1 = (len1 + len2)/2; if (len1 < 0.32) out->mipadjust = 4; @@ -681,12 +686,6 @@ void Mod_LoadTexinfo (lump_t *l) out->mipadjust = 2; else out->mipadjust = 1; -#if 0 - if (len1 + len2 < 0.001) - out->mipadjust = 1; // don't crash - else - out->mipadjust = 1 / floor( (len1+len2)/2 + 0.1 ); -#endif miptex = LittleLong (in->miptex); out->flags = LittleLong (in->flags); @@ -810,7 +809,7 @@ void Mod_LoadFaces (lump_t *l) if (i == -1) out->samples = NULL; else - out->samples = loadmodel->lightdata + i; + out->samples = loadmodel->lightdata + (i * 3); // set the drawing flags flag @@ -834,7 +833,6 @@ void Mod_LoadFaces (lump_t *l) GL_SubdivideSurface (out); // cut up polygon for warps continue; } - } } @@ -910,6 +908,8 @@ void Mod_LoadLeafs (lump_t *l) dleaf_t *in; mleaf_t *out; int i, j, count, p; + //char s[80]; + qboolean isnotmap = true; in = (void *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) @@ -919,7 +919,9 @@ void Mod_LoadLeafs (lump_t *l) loadmodel->leafs = out; loadmodel->numleafs = count; - + //sprintf(s, "maps/%s.bsp", Info_ValueForKey(cl.serverinfo,"map")); + if (!strncmp("maps/", loadmodel->name,5)) + isnotmap = false; for ( i=0 ; inummarksurfaces ; j++) out->firstmarksurface[j]->flags |= SURF_UNDERWATER; } + if (isnotmap) + { + for (j=0 ; jnummarksurfaces ; j++) + out->firstmarksurface[j]->flags |= SURF_DONTWARP; + } } } @@ -1097,7 +1104,6 @@ void Mod_LoadSurfedges (lump_t *l) out[i] = LittleLong (in[i]); } - /* ================= Mod_LoadPlanes @@ -1154,6 +1160,8 @@ float RadiusFromBounds (vec3_t mins, vec3_t maxs) return Length (corner); } +unsigned Com_BlockChecksum (void *buffer, int length); + /* ================= Mod_LoadBrushModel @@ -1179,6 +1187,22 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) for (i=0 ; ichecksum = 0; + mod->checksum2 = 0; + + for (i = 0; i < HEADER_LUMPS; i++) { + if (i == LUMP_ENTITIES) + continue; + mod->checksum ^= LittleLong(Com_BlockChecksum(mod_base + header->lumps[i].fileofs, + header->lumps[i].filelen)); + + if (i == LUMP_VISIBILITY || i == LUMP_LEAFS || i == LUMP_NODES) + continue; + mod->checksum2 ^= LittleLong(Com_BlockChecksum(mod_base + header->lumps[i].fileofs, + header->lumps[i].filelen)); + } + // load into heap Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]); @@ -1229,7 +1253,7 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) { // duplicate the basic information char name[10]; - sprintf (name, "*%i", i+1); + snprintf (name, sizeof(name), "*%i", i+1); loadmodel = Mod_FindName (name); *loadmodel = *mod; strcpy (loadmodel->name, name); @@ -1238,6 +1262,67 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) } } +void Sys_Error (char *error, ...); + +extern char loadname[]; // for hunk tags +extern model_t *loadmodel; +extern model_t mod_known[]; +extern int mod_numknown; + +void Mod_LoadSpriteModel (model_t *mod, void *buffer); +void Mod_LoadAliasModel (model_t *mod, void *buffer); +model_t *Mod_LoadModel (model_t *mod, qboolean crash); +model_t *Mod_FindName (char *name); + +/* +=============== +Mod_Init + +Caches the data if needed +=============== +*/ +void *Mod_Extradata (model_t *mod) +{ + void *r; + + r = Cache_Check (&mod->cache); + if (r) + return r; + + Mod_LoadModel (mod, true); + + if (!mod->cache.data) + Sys_Error ("Mod_Extradata: caching failed"); + return mod->cache.data; +} + +/* +================== +Mod_TouchModel + +================== +*/ +void Mod_TouchModel (char *name) +{ + model_t *mod; + + mod = Mod_FindName (name); + + if (!mod->needload) + { + if (mod->type == mod_alias) + Cache_Check (&mod->cache); + } +} + +void +Mod_LoadMMNearest(miptex_t *mt, texture_t *tx) +{ + texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; + tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false, 1); + texture_mode = GL_LINEAR; +} + /* ============================================================================== @@ -1256,8 +1341,7 @@ mtriangle_t triangles[MAXALIASTRIS]; trivertx_t *poseverts[MAXALIASFRAMES]; int posenum; -byte **player_8bit_texels_tbl; -byte *player_8bit_texels; +byte player_8bit_texels[320*200]; /* ================= @@ -1429,7 +1513,6 @@ void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype) char name[32]; int s; byte *skin; - byte *texels; daliasskingroup_t *pinskingroup; int groupskins; daliasskininterval_t *pinskinintervals; @@ -1447,21 +1530,67 @@ void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype) Mod_FloodFillSkin( skin, pheader->skinwidth, pheader->skinheight ); // save 8 bit texels for the player model to remap - // if (!strcmp(loadmodel->name,"progs/player.mdl")) { - texels = Hunk_AllocName(s, loadname); - pheader->texels[i] = texels - (byte *)pheader; - memcpy (texels, (byte *)(pskintype + 1), s); - // } - sprintf (name, "%s_%i", loadmodel->name, i); + if (!strcmp(loadmodel->name,"progs/player.mdl")) + { + if (s > sizeof(player_8bit_texels)) + Sys_Error ("Player skin too large"); + memcpy (player_8bit_texels, (byte *)(pskintype + 1), s); + } + + // This block is GL fullbright support for objects... + { + int pixels; + byte *ptexel; + + // Check for fullbright pixels.. + pixels = pheader->skinwidth * pheader->skinheight; + ptexel = (byte *)(pskintype + 1); + + for (j=0 ; j= 256-32) { + loadmodel->hasfullbrights = true; + break; + } + } + + if (loadmodel->hasfullbrights) { + byte *ptexels; + + //ptexels = Hunk_Alloc(s); + ptexels = malloc(pixels); + + snprintf(name, sizeof(name), "fb_%s_%i", loadmodel->name,i); + Con_DPrintf("FB Model ID: '%s'\n", name); + for (j=0 ; j= 256-32) { + ptexels[j] = ptexel[j]; + } else { + ptexels[j] = 255; + } + } + pheader->gl_fb_texturenum[i][0] = + pheader->gl_fb_texturenum[i][1] = + pheader->gl_fb_texturenum[i][2] = + pheader->gl_fb_texturenum[i][3] = + GL_LoadTexture (name, pheader->skinwidth, + pheader->skinheight, ptexels, true, true, 1); + + free(ptexels); + } + } + + + snprintf (name, sizeof(name), "%s_%i", loadmodel->name, i); pheader->gl_texturenum[i][0] = pheader->gl_texturenum[i][1] = pheader->gl_texturenum[i][2] = pheader->gl_texturenum[i][3] = GL_LoadTexture (name, pheader->skinwidth, - pheader->skinheight, (byte *)(pskintype + 1), true, false, 1); + pheader->skinheight, (byte *)(pskintype + 1), true, true, 1); pskintype = (daliasskintype_t *)((byte *)(pskintype+1) + s); } else { // animating skin group. yuck. + Con_Printf("Animating Skin Group, if you get this message please notify warp@debian.org\n"); pskintype++; pinskingroup = (daliasskingroup_t *)pskintype; groupskins = LittleLong (pinskingroup->numskins); @@ -1472,12 +1601,7 @@ void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype) for (j=0 ; jskinwidth, pheader->skinheight ); - if (j == 0) { - texels = Hunk_AllocName(s, loadname); - pheader->texels[i] = texels - (byte *)pheader; - memcpy (texels, (byte *)(pskintype), s); - } - sprintf (name, "%s_%i_%i", loadmodel->name, i,j); + snprintf (name, sizeof(name), "%s_%i_%i", loadmodel->name, i,j); pheader->gl_texturenum[i][j&3] = GL_LoadTexture (name, pheader->skinwidth, pheader->skinheight, (byte *)(pskintype), true, false, 1); @@ -1493,6 +1617,7 @@ void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype) return (void *)pskintype; } + //========================================================================= /* @@ -1511,7 +1636,7 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer) daliasframetype_t *pframetype; daliasskintype_t *pskintype; int start, end, total; - + start = Hunk_LowMark (); pinmodel = (mdl_t *)buffer; @@ -1695,7 +1820,7 @@ void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum) pspriteframe->left = origin[0]; pspriteframe->right = width + origin[0]; - sprintf (name, "%s_%i", loadmodel->name, framenum); + snprintf (name, sizeof(name), "%s_%i", loadmodel->name, framenum); pspriteframe->gl_texturenum = GL_LoadTexture (name, width, height, (byte *)(pinframe + 1), true, true, 1); return (void *)((byte *)pinframe + sizeof (dspriteframe_t) + size);