diff --git a/Makefile b/Makefile index 378e2fae..a6c44b1f 100644 --- a/Makefile +++ b/Makefile @@ -997,6 +997,7 @@ REFGL1_OBJS_ := \ src/client/refresh/gl1/gl1_surf.o \ src/client/refresh/gl1/gl1_warp.o \ src/client/refresh/gl1/gl1_sdl.o \ + src/client/refresh/files/light.o \ src/client/refresh/files/surf.o \ src/client/refresh/files/models.o \ src/client/refresh/files/pcx.o \ @@ -1030,6 +1031,7 @@ REFGL3_OBJS_ := \ src/client/refresh/gl3/gl3_surf.o \ src/client/refresh/gl3/gl3_warp.o \ src/client/refresh/gl3/gl3_shaders.o \ + src/client/refresh/files/light.o \ src/client/refresh/files/surf.o \ src/client/refresh/files/models.o \ src/client/refresh/files/pcx.o \ @@ -1069,6 +1071,7 @@ REFGL4_OBJS_ := \ src/client/refresh/gl4/gl4_surf.o \ src/client/refresh/gl4/gl4_warp.o \ src/client/refresh/gl4/gl4_shaders.o \ + src/client/refresh/files/light.o \ src/client/refresh/files/surf.o \ src/client/refresh/files/models.o \ src/client/refresh/files/pcx.o \ @@ -1109,6 +1112,7 @@ REFSOFT_OBJS_ := \ src/client/refresh/soft/sw_scan.o \ src/client/refresh/soft/sw_sprite.o \ src/client/refresh/soft/sw_surf.o \ + src/client/refresh/files/light.o \ src/client/refresh/files/surf.o \ src/client/refresh/files/models.o \ src/client/refresh/files/pcx.o \ @@ -1149,6 +1153,7 @@ REFVK_OBJS_ := \ src/client/refresh/vk/vk_warp.o \ src/client/refresh/vk/vk_util.o \ src/client/refresh/vk/volk/volk.o \ + src/client/refresh/files/light.o \ src/client/refresh/files/surf.o \ src/client/refresh/files/models.o \ src/client/refresh/files/pcx.o \ diff --git a/src/client/refresh/files/light.c b/src/client/refresh/files/light.c new file mode 100644 index 00000000..43501145 --- /dev/null +++ b/src/client/refresh/files/light.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 1997-2001 Id Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * ======================================================================= + * + * Light logic + * + * ======================================================================= + */ + +#include "../ref_shared.h" + +static int +BSPX_LightGridSingleValue(const bspxlightgrid_t *grid, const lightstyle_t *lightstyles, int x, int y, int z, vec3_t res_diffuse) +{ + int i; + unsigned int node; + struct bspxlgsamp_s *samp; + + node = grid->rootnode; + while (!(node & LGNODE_LEAF)) + { + struct bspxlgnode_s *n; + if (node & LGNODE_MISSING) + return 0; //failure + n = grid->nodes + node; + node = n->child[ + ((x>=n->mid[0])<<2)| + ((y>=n->mid[1])<<1)| + ((z>=n->mid[2])<<0)]; + } + + { + struct bspxlgleaf_s *leaf = &grid->leafs[node & ~LGNODE_LEAF]; + x -= leaf->mins[0]; + y -= leaf->mins[1]; + z -= leaf->mins[2]; + if (x >= leaf->size[0] || + y >= leaf->size[1] || + z >= leaf->size[2]) + return 0; //sample we're after is out of bounds... + + i = x + leaf->size[0]*(y + leaf->size[1]*z); + samp = leaf->rgbvalues + i; + + //no hdr support + for (i = 0; i < 4; i++) + { + if (samp->map[i].style == ((byte)(~0u))) + break; //no more + res_diffuse[0] += samp->map[i].rgb[0] * lightstyles[samp->map[i].style].rgb[0] / 255.0; + res_diffuse[1] += samp->map[i].rgb[1] * lightstyles[samp->map[i].style].rgb[1] / 255.0; + res_diffuse[2] += samp->map[i].rgb[2] * lightstyles[samp->map[i].style].rgb[2] / 255.0; + } + } + return 1; +} + +void +BSPX_LightGridValue(const bspxlightgrid_t *grid, const lightstyle_t *lightstyles, const vec3_t point, vec3_t res_diffuse) +{ + int tile[3]; + int i; + int s; + + VectorSet(res_diffuse, 0, 0, 0); //assume worst + + for (i = 0; i < 3; i++) + tile[i] = (point[i] - grid->mins[i]) * grid->gridscale[i]; + + for (i = 0, s = 0; i < 8; i++) + s += BSPX_LightGridSingleValue(grid, lightstyles, + tile[0]+!!(i&1), + tile[1]+!!(i&2), + tile[2]+!!(i&4), res_diffuse); + + VectorScale(res_diffuse, 1.0/s, res_diffuse); //average the successful ones +} diff --git a/src/client/refresh/files/models.c b/src/client/refresh/files/models.c index de1d00df..e43d3ddd 100644 --- a/src/client/refresh/files/models.c +++ b/src/client/refresh/files/models.c @@ -2054,3 +2054,154 @@ Mod_LoadBSPX(int filesize, const byte *mod_base) // success return xheader; } + +/* Need to clean */ +struct rctx_s { + const byte *data; + int ofs, size; +}; + +static byte ReadByte(struct rctx_s *ctx) +{ + if (ctx->ofs >= ctx->size) + { + ctx->ofs++; + return 0; + } + return ctx->data[ctx->ofs++]; +} + +static int ReadInt(struct rctx_s *ctx) +{ + int r = (int)ReadByte(ctx)<<0; + r|= (int)ReadByte(ctx)<<8; + r|= (int)ReadByte(ctx)<<16; + r|= (int)ReadByte(ctx)<<24; + return r; +} + +static float ReadFloat(struct rctx_s *ctx) +{ + union {float f; int i;} u; + u.i = ReadInt(ctx); + return u.f; +} + +bspxlightgrid_t* +BSPX_LightGridLoad(const bspx_header_t *bspx_header, const byte *mod_base) +{ + vec3_t step, mins; + int size[3]; + bspxlightgrid_t *grid; + unsigned int numstyles, numnodes, numleafs, rootnode; + unsigned int nodestart, leafsamps = 0, i, j, k, s; + struct bspxlgsamp_s *samp; + struct rctx_s ctx = {0}; + + ctx.data = Mod_LoadBSPXFindLump(bspx_header, "LIGHTGRID_OCTREE", &ctx.size, mod_base); + if (!ctx.data) + { + return NULL; + } + + for (j = 0; j < 3; j++) + step[j] = ReadFloat(&ctx); + for (j = 0; j < 3; j++) + size[j] = ReadInt(&ctx); + for (j = 0; j < 3; j++) + mins[j] = ReadFloat(&ctx); + + numstyles = ReadByte(&ctx); //urgh, misaligned the entire thing + rootnode = ReadInt(&ctx); + numnodes = ReadInt(&ctx); + nodestart = ctx.ofs; + ctx.ofs += (3+8)*4*numnodes; + numleafs = ReadInt(&ctx); + for (i = 0; i < numleafs; i++) + { + unsigned int lsz[3]; + ctx.ofs += 3*4; + for (j = 0; j < 3; j++) + lsz[j] = ReadInt(&ctx); + j = lsz[0]*lsz[1]*lsz[2]; + leafsamps += j; + while (j --> 0) + { //this loop is annonying, memcpy dreams... + s = ReadByte(&ctx); + if (s == 255) + continue; + ctx.ofs += s*4; + } + } + + grid = Hunk_Alloc(sizeof(*grid) + sizeof(*grid->leafs)*numleafs + sizeof(*grid->nodes)*numnodes + sizeof(struct bspxlgsamp_s)*leafsamps); + memset(grid, 0xcc, sizeof(*grid) + sizeof(*grid->leafs)*numleafs + sizeof(*grid->nodes)*numnodes + sizeof(struct bspxlgsamp_s)*leafsamps); + grid->leafs = (void*)(grid+1); + grid->nodes = (void*)(grid->leafs + numleafs); + samp = (void*)(grid->nodes+numnodes); + + for (j = 0; j < 3; j++) + grid->gridscale[j] = 1/step[j]; //prefer it as a multiply + VectorCopy(mins, grid->mins); + VectorCopy(size, grid->count); + grid->numnodes = numnodes; + grid->numleafs = numleafs; + grid->rootnode = rootnode; + (void)numstyles; + + //rewind to the nodes. *sigh* + ctx.ofs = nodestart; + for (i = 0; i < numnodes; i++) + { + for (j = 0; j < 3; j++) + grid->nodes[i].mid[j] = ReadInt(&ctx); + for (j = 0; j < 8; j++) + grid->nodes[i].child[j] = ReadInt(&ctx); + } + ctx.ofs += 4; + for (i = 0; i < numleafs; i++) + { + for (j = 0; j < 3; j++) + grid->leafs[i].mins[j] = ReadInt(&ctx); + for (j = 0; j < 3; j++) + grid->leafs[i].size[j] = ReadInt(&ctx); + + grid->leafs[i].rgbvalues = samp; + + j = grid->leafs[i].size[0]*grid->leafs[i].size[1]*grid->leafs[i].size[2]; + while (j --> 0) + { + s = ReadByte(&ctx); + if (s == 0xff) + memset(samp, 0xff, sizeof(*samp)); + else + { + for (k = 0; k < s; k++) + { + if (k >= 4) + ReadInt(&ctx); + else + { + samp->map[k].style = ReadByte(&ctx); + samp->map[k].rgb[0] = ReadByte(&ctx); + samp->map[k].rgb[1] = ReadByte(&ctx); + samp->map[k].rgb[2] = ReadByte(&ctx); + } + } + for (; k < 4; k++) + { + samp->map[k].style = (byte)~0u; + samp->map[k].rgb[0] = + samp->map[k].rgb[1] = + samp->map[k].rgb[2] = 0; + } + } + samp++; + } + } + + if (ctx.ofs != ctx.size) + grid = NULL; + + return grid; +} diff --git a/src/client/refresh/gl1/gl1_mesh.c b/src/client/refresh/gl1/gl1_mesh.c index 3eb6611f..3ed04a6b 100644 --- a/src/client/refresh/gl1/gl1_mesh.c +++ b/src/client/refresh/gl1/gl1_mesh.c @@ -29,12 +29,12 @@ #define NUMVERTEXNORMALS 162 #define SHADEDOT_QUANT 16 -float r_avertexnormals[NUMVERTEXNORMALS][3] = { +static float r_avertexnormals[NUMVERTEXNORMALS][3] = { #include "../constants/anorms.h" }; /* precalculated dot products for quantized angles */ -float r_avertexnormal_dots[SHADEDOT_QUANT][256] = { +static float r_avertexnormal_dots[SHADEDOT_QUANT][256] = { #include "../constants/anormtab.h" }; @@ -376,9 +376,9 @@ R_DrawAliasShadowCommand(entity_t *currententity, int *order, int *order_end, point[1] -= shadevector[1] * (point[2] + lheight); point[2] = height; - vtx[index_vtx++] = point [ 0 ]; - vtx[index_vtx++] = point [ 1 ]; - vtx[index_vtx++] = point [ 2 ]; + vtx[index_vtx++] = point[0]; + vtx[index_vtx++] = point[1]; + vtx[index_vtx++] = point[2]; order += 3; } @@ -673,7 +673,8 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel) { if (r_worldmodel->grid) { - BSPX_LightGridValue(r_worldmodel->grid, currententity->origin, shadelight); + BSPX_LightGridValue(r_worldmodel->grid, r_newrefdef.lightstyles, + currententity->origin, shadelight); } else { @@ -732,12 +733,13 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel) { /* bonus items will pulse with time */ float scale; - float min; scale = 0.1 * sin(r_newrefdef.time * 7); for (i = 0; i < 3; i++) { + float min; + min = shadelight[i] * 0.8; shadelight[i] += scale; @@ -951,4 +953,3 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel) glColor4f(1, 1, 1, 1); } - diff --git a/src/client/refresh/gl1/gl1_model.c b/src/client/refresh/gl1/gl1_model.c index d03c83d9..6fd93093 100644 --- a/src/client/refresh/gl1/gl1_model.c +++ b/src/client/refresh/gl1/gl1_model.c @@ -30,7 +30,7 @@ static YQ2_ALIGNAS_TYPE(int) byte mod_novis[MAX_MAP_LEAFS / 8]; #define MAX_MOD_KNOWN 512 static model_t mod_known[MAX_MOD_KNOWN]; -static int mod_numknown; +static int mod_numknown = 0; static int mod_max = 0; int registration_sequence; @@ -1161,7 +1161,7 @@ Mod_ForName(const char *name, model_t *parent_model, qboolean crash) return mod; } -void +static void Mod_Free(model_t *mod) { Hunk_Free(mod->extradata); @@ -1272,220 +1272,3 @@ RI_EndRegistration(void) R_FreeUnusedImages(); } - -/* Need to clean */ -struct rctx_s { - const byte *data; - int ofs, size; -}; - -static byte ReadByte(struct rctx_s *ctx) -{ - if (ctx->ofs >= ctx->size) - { - ctx->ofs++; - return 0; - } - return ctx->data[ctx->ofs++]; -} - -static int ReadInt(struct rctx_s *ctx) -{ - int r = (int)ReadByte(ctx)<<0; - r|= (int)ReadByte(ctx)<<8; - r|= (int)ReadByte(ctx)<<16; - r|= (int)ReadByte(ctx)<<24; - return r; -} - -static float ReadFloat(struct rctx_s *ctx) -{ - union {float f; int i;} u; - u.i = ReadInt(ctx); - return u.f; -} - -bspxlightgrid_t* -BSPX_LightGridLoad(const bspx_header_t *bspx_header, const byte *mod_base) -{ - vec3_t step, mins; - int size[3]; - bspxlightgrid_t *grid; - unsigned int numstyles, numnodes, numleafs, rootnode; - unsigned int nodestart, leafsamps = 0, i, j, k, s; - struct bspxlgsamp_s *samp; - struct rctx_s ctx = {0}; - - ctx.data = Mod_LoadBSPXFindLump(bspx_header, "LIGHTGRID_OCTREE", &ctx.size, mod_base); - if (!ctx.data) - { - return NULL; - } - - for (j = 0; j < 3; j++) - step[j] = ReadFloat(&ctx); - for (j = 0; j < 3; j++) - size[j] = ReadInt(&ctx); - for (j = 0; j < 3; j++) - mins[j] = ReadFloat(&ctx); - - numstyles = ReadByte(&ctx); //urgh, misaligned the entire thing - rootnode = ReadInt(&ctx); - numnodes = ReadInt(&ctx); - nodestart = ctx.ofs; - ctx.ofs += (3+8)*4*numnodes; - numleafs = ReadInt(&ctx); - for (i = 0; i < numleafs; i++) - { - unsigned int lsz[3]; - ctx.ofs += 3*4; - for (j = 0; j < 3; j++) - lsz[j] = ReadInt(&ctx); - j = lsz[0]*lsz[1]*lsz[2]; - leafsamps += j; - while (j --> 0) - { //this loop is annonying, memcpy dreams... - s = ReadByte(&ctx); - if (s == 255) - continue; - ctx.ofs += s*4; - } - } - - grid = Hunk_Alloc(sizeof(*grid) + sizeof(*grid->leafs)*numleafs + sizeof(*grid->nodes)*numnodes + sizeof(struct bspxlgsamp_s)*leafsamps); - memset(grid, 0xcc, sizeof(*grid) + sizeof(*grid->leafs)*numleafs + sizeof(*grid->nodes)*numnodes + sizeof(struct bspxlgsamp_s)*leafsamps); - grid->leafs = (void*)(grid+1); - grid->nodes = (void*)(grid->leafs + numleafs); - samp = (void*)(grid->nodes+numnodes); - - for (j = 0; j < 3; j++) - grid->gridscale[j] = 1/step[j]; //prefer it as a multiply - VectorCopy(mins, grid->mins); - VectorCopy(size, grid->count); - grid->numnodes = numnodes; - grid->numleafs = numleafs; - grid->rootnode = rootnode; - (void)numstyles; - - //rewind to the nodes. *sigh* - ctx.ofs = nodestart; - for (i = 0; i < numnodes; i++) - { - for (j = 0; j < 3; j++) - grid->nodes[i].mid[j] = ReadInt(&ctx); - for (j = 0; j < 8; j++) - grid->nodes[i].child[j] = ReadInt(&ctx); - } - ctx.ofs += 4; - for (i = 0; i < numleafs; i++) - { - for (j = 0; j < 3; j++) - grid->leafs[i].mins[j] = ReadInt(&ctx); - for (j = 0; j < 3; j++) - grid->leafs[i].size[j] = ReadInt(&ctx); - - grid->leafs[i].rgbvalues = samp; - - j = grid->leafs[i].size[0]*grid->leafs[i].size[1]*grid->leafs[i].size[2]; - while (j --> 0) - { - s = ReadByte(&ctx); - if (s == 0xff) - memset(samp, 0xff, sizeof(*samp)); - else - { - for (k = 0; k < s; k++) - { - if (k >= 4) - ReadInt(&ctx); - else - { - samp->map[k].style = ReadByte(&ctx); - samp->map[k].rgb[0] = ReadByte(&ctx); - samp->map[k].rgb[1] = ReadByte(&ctx); - samp->map[k].rgb[2] = ReadByte(&ctx); - } - } - for (; k < 4; k++) - { - samp->map[k].style = (byte)~0u; - samp->map[k].rgb[0] = - samp->map[k].rgb[1] = - samp->map[k].rgb[2] = 0; - } - } - samp++; - } - } - - if (ctx.ofs != ctx.size) - grid = NULL; - - return grid; -} - -static int -BSPX_LightGridSingleValue(bspxlightgrid_t *grid, int x, int y, int z, vec3_t res_diffuse) -{ - int i; - unsigned int node; - struct bspxlgsamp_s *samp; - - node = grid->rootnode; - while (!(node & LGNODE_LEAF)) - { - struct bspxlgnode_s *n; - if (node & LGNODE_MISSING) - return 0; //failure - n = grid->nodes + node; - node = n->child[ - ((x>=n->mid[0])<<2)| - ((y>=n->mid[1])<<1)| - ((z>=n->mid[2])<<0)]; - } - - { - struct bspxlgleaf_s *leaf = &grid->leafs[node & ~LGNODE_LEAF]; - x -= leaf->mins[0]; - y -= leaf->mins[1]; - z -= leaf->mins[2]; - if (x >= leaf->size[0] || - y >= leaf->size[1] || - z >= leaf->size[2]) - return 0; //sample we're after is out of bounds... - - i = x + leaf->size[0]*(y + leaf->size[1]*z); - samp = leaf->rgbvalues + i; - - //no hdr support - for (i = 0; i < 4; i++) - { - if (samp->map[i].style == ((byte)(~0u))) - break; //no more - res_diffuse[0] += samp->map[i].rgb[0] * r_newrefdef.lightstyles[samp->map[i].style].rgb[0] / 255.0; - res_diffuse[1] += samp->map[i].rgb[1] * r_newrefdef.lightstyles[samp->map[i].style].rgb[1] / 255.0; - res_diffuse[2] += samp->map[i].rgb[2] * r_newrefdef.lightstyles[samp->map[i].style].rgb[2] / 255.0; - } - } - return 1; -} - -void -BSPX_LightGridValue(bspxlightgrid_t *grid, const vec3_t point, vec3_t res_diffuse) -{ - int tile[3]; - int i; - int s; - - VectorSet(res_diffuse, 0, 0, 0); //assume worst - - for (i = 0; i < 3; i++) - tile[i] = (point[i] - grid->mins[i]) * grid->gridscale[i]; - - for (i = 0, s = 0; i < 8; i++) - s += BSPX_LightGridSingleValue(grid, tile[0]+!!(i&1), - tile[1]+!!(i&2), - tile[2]+!!(i&4), res_diffuse); - - VectorScale(res_diffuse, 1.0/s, res_diffuse); //average the successful ones -} diff --git a/src/client/refresh/gl1/header/model.h b/src/client/refresh/gl1/header/model.h index 96afa7ee..839ad96b 100644 --- a/src/client/refresh/gl1/header/model.h +++ b/src/client/refresh/gl1/header/model.h @@ -29,41 +29,6 @@ #include "../../ref_model.h" -typedef struct -{ - vec3_t gridscale; - unsigned int count[3]; - vec3_t mins; - unsigned int styles; - - unsigned int rootnode; - - unsigned int numnodes; - struct bspxlgnode_s - { //this uses an octtree to trim samples. - int mid[3]; - unsigned int child[8]; -#define LGNODE_LEAF (1u<<31) -#define LGNODE_MISSING (1u<<30) - } *nodes; - unsigned int numleafs; - struct bspxlgleaf_s - { - int mins[3]; - int size[3]; - struct bspxlgsamp_s - { - struct - { - byte style; - byte rgb[3]; - } map[4]; - } *rgbvalues; - } *leafs; -} bspxlightgrid_t; -bspxlightgrid_t* BSPX_LightGridLoad(const bspx_header_t *bspx_header, const byte *mod_base); -void BSPX_LightGridValue(bspxlightgrid_t *grid, const vec3_t point, vec3_t res_diffuse); - /* Whole model */ typedef struct model_s @@ -149,6 +114,5 @@ int Hunk_End(void); void Hunk_Free(void *base); void Mod_FreeAll(void); -void Mod_Free(model_t *mod); #endif diff --git a/src/client/refresh/ref_shared.h b/src/client/refresh/ref_shared.h index 939f0726..38a53d52 100644 --- a/src/client/refresh/ref_shared.h +++ b/src/client/refresh/ref_shared.h @@ -179,6 +179,50 @@ typedef struct mleaf_s int key; /* BSP sequence number for leaf's contents */ } mleaf_t; +/* BSPX Light octtree */ +#define LGNODE_LEAF (1u<<31) +#define LGNODE_MISSING (1u<<30) + +/* this uses an octtree to trim samples. */ +typedef struct bspxlgnode_s +{ + int mid[3]; + unsigned int child[8]; +} bspxlgnode_t; + +typedef struct bspxlglightstyle_s +{ + byte style; + byte rgb[3]; +} bspxlglightstyle_t; + +typedef struct bspxlgsamp_s +{ + bspxlglightstyle_t map[4]; +} bspxlgsamp_t; + +typedef struct bspxlgleaf_s +{ + int mins[3]; + int size[3]; + bspxlgsamp_t *rgbvalues; +} bspxlgleaf_t; + +typedef struct +{ + vec3_t gridscale; + unsigned int count[3]; + vec3_t mins; + unsigned int styles; + + unsigned int rootnode; + + unsigned int numnodes; + bspxlgnode_t *nodes; + unsigned int numleafs; + bspxlgleaf_t *leafs; +} bspxlightgrid_t; + /* Shared models func */ typedef struct image_s* (*findimage_t)(const char *name, imagetype_t type); extern void *Mod_LoadAliasModel (const char *mod_name, const void *buffer, int modfilelen, @@ -237,4 +281,9 @@ extern void R_SetFrustum(vec3_t vup, vec3_t vpn, vec3_t vright, vec3_t r_origin, float fov_x, float fov_y, cplane_t *frustum); extern void R_BoundPoly(int numverts, float *verts, vec3_t mins, vec3_t maxs); +/* Lights logic */ +extern bspxlightgrid_t *BSPX_LightGridLoad(const bspx_header_t *bspx_header, const byte *mod_base); +extern void BSPX_LightGridValue(const bspxlightgrid_t *grid, const lightstyle_t *lightstyles, + const vec3_t point, vec3_t res_diffuse); + #endif /* SRC_CLIENT_REFRESH_REF_SHARED_H_ */ diff --git a/src/client/refresh/vk/header/model.h b/src/client/refresh/vk/header/model.h index d093e7be..77c56b20 100644 --- a/src/client/refresh/vk/header/model.h +++ b/src/client/refresh/vk/header/model.h @@ -54,91 +54,86 @@ BRUSH MODELS typedef struct model_s { - char name[MAX_QPATH]; + char name[MAX_QPATH]; - int registration_sequence; + int registration_sequence; - modtype_t type; - int numframes; + modtype_t type; + int numframes; - int flags; + int flags; -// -// volume occupied by the model graphics -// - vec3_t mins, maxs; - float radius; + /* volume occupied by the model graphics */ + vec3_t mins, maxs; + float radius; -// -// solid volume for clipping -// - qboolean clipbox; - vec3_t clipmins, clipmaxs; + /* solid volume for clipping */ + qboolean clipbox; + vec3_t clipmins, clipmaxs; -// -// brush model -// - int firstmodelsurface, nummodelsurfaces; - int lightmap; // only for submodels + /* brush model */ + int firstmodelsurface, nummodelsurfaces; + int lightmap; /* only for submodels */ - int numsubmodels; - struct model_s *submodels; + int numsubmodels; + struct model_s *submodels; - int numplanes; - cplane_t *planes; + int numplanes; + cplane_t *planes; - int numleafs; // number of visible leafs, not counting 0 - mleaf_t *leafs; + int numleafs; /* number of visible leafs, not counting 0 */ + mleaf_t *leafs; - int numvertexes; - mvertex_t *vertexes; + int numvertexes; + mvertex_t *vertexes; - int numedges; - medge_t *edges; + int numedges; + medge_t *edges; - int numnodes; - int firstnode; - mnode_t *nodes; + int numnodes; + int firstnode; + mnode_t *nodes; - int numtexinfo; - mtexinfo_t *texinfo; + int numtexinfo; + mtexinfo_t *texinfo; - int numsurfaces; - msurface_t *surfaces; + int numsurfaces; + msurface_t *surfaces; - int numsurfedges; - int *surfedges; + int numsurfedges; + int *surfedges; - int nummarksurfaces; - msurface_t **marksurfaces; + int nummarksurfaces; + msurface_t **marksurfaces; - dvis_t *vis; + dvis_t *vis; - byte *lightdata; + byte *lightdata; - // for alias models and skins - image_t *skins[MAX_MD2SKINS]; + /* for alias models and skins */ + image_t *skins[MAX_MD2SKINS]; - int extradatasize; - void *extradata; + int extradatasize; + void *extradata; // submodules vec3_t origin; // for sounds or lights + + /* octree */ + bspxlightgrid_t *grid; } model_t; -//============================================================================ +void Mod_Init(void); +const byte *Mod_ClusterPVS(int cluster, const model_t *model); -void Mod_Init (void); -const byte *Mod_ClusterPVS (int cluster, const model_t *model); +void Mod_Modellist_f(void); -void Mod_Modellist_f (void); +void *Hunk_Begin(int maxsize); +void *Hunk_Alloc(int size); +int Hunk_End(void); +void Hunk_Free(void *base); -void *Hunk_Begin (int maxsize); -void *Hunk_Alloc (int size); -int Hunk_End (void); -void Hunk_Free (void *base); - -void Mod_FreeAll (void); +void Mod_FreeAll(void); void Mod_FreeModelsKnown (void); #endif diff --git a/src/client/refresh/vk/vk_mesh.c b/src/client/refresh/vk/vk_mesh.c index 028eff0e..12494ca9 100644 --- a/src/client/refresh/vk/vk_mesh.c +++ b/src/client/refresh/vk/vk_mesh.c @@ -20,23 +20,15 @@ * * ======================================================================= * - * Triangle model functions + * Mesh handling * * ======================================================================= - * */ #include "header/local.h" -/* -============================================================= - - ALIAS MODELS - -============================================================= -*/ - -#define NUMVERTEXNORMALS 162 +#define NUMVERTEXNORMALS 162 +#define SHADEDOT_QUANT 16 static float r_avertexnormals[NUMVERTEXNORMALS][3] = { #include "../constants/anorms.h" @@ -64,20 +56,18 @@ polyvert_t *verts_buffer = NULL; lmappolyvert_t *lmappolyverts_buffer = NULL; static drawinfo_t *drawInfo[2] = {NULL, NULL}; static modelvert *vertList[2] = {NULL, NULL}; -static vec4_t *s_lerped = NULL; static vec3_t *shadowverts = NULL; static int verts_count = 0; -vec3_t shadevector; -float shadelight[3]; - -// precalculated dot products for quantized angles -#define SHADEDOT_QUANT 16 +/* precalculated dot products for quantized angles */ static float r_avertexnormal_dots[SHADEDOT_QUANT][256] = { #include "../constants/anormtab.h" }; -float *shadedots = r_avertexnormal_dots[0]; +static vec4_t *s_lerped = NULL; +vec3_t shadevector; +float shadelight[3]; +float *shadedots = r_avertexnormal_dots[0]; // correction matrix with "hacked depth" for models with RF_DEPTHHACK flag set static float r_vulkan_correction_dh[16] = { @@ -244,34 +234,39 @@ void Mesh_Free (void) } -static void Vk_LerpVerts( int nverts, dtrivertx_t *v, dtrivertx_t *ov, dtrivertx_t *verts, +static void +Vk_LerpVerts(int nverts, dtrivertx_t *v, dtrivertx_t *ov, dtrivertx_t *verts, float *lerp, const float move[3], const float frontv[3], const float backv[3], - entity_t *currententity ) + entity_t *currententity) { int i; - //PMM -- added RF_SHELL_DOUBLE, RF_SHELL_HALF_DAM - if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) + if (currententity->flags & + (RF_SHELL_RED | RF_SHELL_GREEN | + RF_SHELL_BLUE | RF_SHELL_DOUBLE | + RF_SHELL_HALF_DAM)) { - for (i=0 ; i < nverts; i++, v++, ov++, lerp+=4 ) + for (i = 0; i < nverts; i++, v++, ov++, lerp += 4) { float *normal = r_avertexnormals[verts[i].lightnormalindex]; - lerp[0] = move[0] + ov->v[0]*backv[0] + v->v[0]*frontv[0] + normal[0] * POWERSUIT_SCALE; - lerp[1] = move[1] + ov->v[1]*backv[1] + v->v[1]*frontv[1] + normal[1] * POWERSUIT_SCALE; - lerp[2] = move[2] + ov->v[2]*backv[2] + v->v[2]*frontv[2] + normal[2] * POWERSUIT_SCALE; + lerp[0] = move[0] + ov->v[0] * backv[0] + v->v[0] * frontv[0] + + normal[0] * POWERSUIT_SCALE; + lerp[1] = move[1] + ov->v[1] * backv[1] + v->v[1] * frontv[1] + + normal[1] * POWERSUIT_SCALE; + lerp[2] = move[2] + ov->v[2] * backv[2] + v->v[2] * frontv[2] + + normal[2] * POWERSUIT_SCALE; } } else { - for (i=0 ; i < nverts; i++, v++, ov++, lerp+=4) + for (i = 0; i < nverts; i++, v++, ov++, lerp += 4) { - lerp[0] = move[0] + ov->v[0]*backv[0] + v->v[0]*frontv[0]; - lerp[1] = move[1] + ov->v[1]*backv[1] + v->v[1]*frontv[1]; - lerp[2] = move[2] + ov->v[2]*backv[2] + v->v[2]*frontv[2]; + lerp[0] = move[0] + ov->v[0] * backv[0] + v->v[0] * frontv[0]; + lerp[1] = move[1] + ov->v[1] * backv[1] + v->v[1] * frontv[1]; + lerp[2] = move[2] + ov->v[2] * backv[2] + v->v[2] * frontv[2]; } } - } static void @@ -298,10 +293,11 @@ Vk_DrawAliasFrameLerpCommands (entity_t *currententity, int *order, int *order_e while (1) { - int count; + int count; - // get the vertex count and primitive type + /* get the vertex count and primitive type */ count = *order++; + if (!count || order >= order_end) { break; /* done */ @@ -325,7 +321,8 @@ Vk_DrawAliasFrameLerpCommands (entity_t *currententity, int *order, int *order_e drawInfo[pipelineIdx][pipeCounters[pipelineIdx]].vertexCount = count; maxTriangleFanIdxCnt = max(maxTriangleFanIdxCnt, ((count - 2) * 3)); - if (currententity->flags & (RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE)) + if (currententity->flags & + (RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE)) { meshUbo.textured = 0; do @@ -469,57 +466,61 @@ FIXME: batch lerp all vertexes ============= */ static void -Vk_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp, image_t *skin, +Vk_DrawAliasFrameLerp(dmdl_t *paliashdr, float backlerp, image_t *skin, float *modelMatrix, int leftHandOffset, int translucentIdx, entity_t *currententity) { - daliasframe_t *frame, *oldframe; - dtrivertx_t *v, *ov, *verts; - int *order; - float frontlerp; - float alpha; - vec3_t move, delta, vectors[3]; - vec3_t frontv, backv; - int i; - float *lerp; + daliasframe_t *frame, *oldframe; + dtrivertx_t *v, *ov, *verts; + int *order; + float frontlerp; + float alpha; + vec3_t move, delta, vectors[3]; + vec3_t frontv, backv; + int i; + float *lerp; int num_mesh_nodes; short *mesh_nodes; frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames - + currententity->frame * paliashdr->framesize); + + currententity->frame * paliashdr->framesize); verts = v = frame->verts; oldframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames - + currententity->oldframe * paliashdr->framesize); + + currententity->oldframe * paliashdr->framesize); ov = oldframe->verts; order = (int *)((byte *)paliashdr + paliashdr->ofs_glcmds); if (currententity->flags & RF_TRANSLUCENT) + { alpha = currententity->alpha; + } else + { alpha = 1.0; + } frontlerp = 1.0 - backlerp; - // move should be the delta back to the previous frame * backlerp + /* move should be the delta back to the previous frame * backlerp */ VectorSubtract(currententity->oldorigin, currententity->origin, delta); - AngleVectors (currententity->angles, vectors[0], vectors[1], vectors[2]); + AngleVectors(currententity->angles, vectors[0], vectors[1], vectors[2]); - move[0] = DotProduct(delta, vectors[0]); // forward - move[1] = -DotProduct(delta, vectors[1]); // left - move[2] = DotProduct(delta, vectors[2]); // up + move[0] = DotProduct(delta, vectors[0]); /* forward */ + move[1] = -DotProduct(delta, vectors[1]); /* left */ + move[2] = DotProduct(delta, vectors[2]); /* up */ - VectorAdd (move, oldframe->translate, move); + VectorAdd(move, oldframe->translate, move); - for (i=0 ; i<3 ; i++) + for (i = 0; i < 3; i++) { - move[i] = backlerp*move[i] + frontlerp*frame->translate[i]; + move[i] = backlerp * move[i] + frontlerp * frame->translate[i]; } - for (i=0 ; i<3 ; i++) + for (i = 0; i < 3; i++) { - frontv[i] = frontlerp*frame->scale[i]; - backv[i] = backlerp*oldframe->scale[i]; + frontv[i] = frontlerp * frame->scale[i]; + backv[i] = backlerp * oldframe->scale[i]; } if (Mesh_VertsRealloc(paliashdr->num_xyz)) @@ -529,7 +530,7 @@ Vk_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp, image_t *skin, lerp = s_lerped[0]; - Vk_LerpVerts( paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv, currententity ); + Vk_LerpVerts(paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv, currententity ); num_mesh_nodes = (paliashdr->ofs_skins - sizeof(dmdl_t)) / sizeof(short) / 2; mesh_nodes = (short *)((char*)paliashdr + sizeof(dmdl_t)); @@ -554,13 +555,8 @@ Vk_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp, image_t *skin, } } - -/* -============= -Vk_DrawAliasShadow -============= -*/ -static void Vk_DrawAliasShadow (int *order, int *order_end, int posenum, +static void +Vk_DrawAliasShadow(int *order, int *order_end, int posenum, float *modelMatrix, entity_t *currententity) { vec3_t point; @@ -579,8 +575,7 @@ static void Vk_DrawAliasShadow (int *order, int *order_end, int posenum, while (1) { - int i; - int count; + int i, count; i = 0; // get the vertex count and primitive type @@ -612,11 +607,11 @@ static void Vk_DrawAliasShadow (int *order, int *order_end, int posenum, ri.Sys_Error(ERR_FATAL, "%s: can't allocate memory", __func__); } - // normals and vertexes come from the frame list - memcpy( point, s_lerped[order[2]], sizeof( point ) ); + /* normals and vertexes come from the frame list */ + memcpy(point, s_lerped[order[2]], sizeof(point)); - point[0] -= shadevector[0]*(point[2]+lheight); - point[1] -= shadevector[1]*(point[2]+lheight); + point[0] -= shadevector[0] * (point[2] + lheight); + point[1] -= shadevector[1] * (point[2] + lheight); point[2] = height; shadowverts[i][0] = point[0]; @@ -625,7 +620,8 @@ static void Vk_DrawAliasShadow (int *order, int *order_end, int posenum, order += 3; i++; - } while (--count); + } + while (--count); if (i > 0) { @@ -653,142 +649,158 @@ static void Vk_DrawAliasShadow (int *order, int *order_end, int posenum, } } - -/* -** R_CullAliasModel -*/ -static qboolean R_CullAliasModel( vec3_t bbox[8], entity_t *e, model_t *currentmodel ) +static qboolean +R_CullAliasModel(vec3_t bbox[8], entity_t *e, model_t *currentmodel ) { int i; - vec3_t mins, maxs; - dmdl_t *paliashdr; - vec3_t vectors[3]; - vec3_t thismins, oldmins, thismaxs, oldmaxs; + vec3_t mins, maxs; + dmdl_t *paliashdr; + vec3_t vectors[3]; + vec3_t thismins, oldmins, thismaxs, oldmaxs; daliasframe_t *pframe, *poldframe; vec3_t angles; paliashdr = (dmdl_t *)currentmodel->extradata; - - if ( ( e->frame >= paliashdr->num_frames ) || ( e->frame < 0 ) ) + if (!paliashdr) { - R_Printf(PRINT_ALL, "%s %s: no such frame %d\n", - __func__, currentmodel->name, e->frame); + R_Printf(PRINT_ALL, "%s %s: Model is not fully loaded\n", + __func__, currentmodel->name); + return true; + } + + if ((e->frame >= paliashdr->num_frames) || (e->frame < 0)) + { + R_Printf(PRINT_DEVELOPER, "%s %s: no such frame %d\n", + __func__, currentmodel->name, e->frame); e->frame = 0; } - if ( ( e->oldframe >= paliashdr->num_frames ) || ( e->oldframe < 0 ) ) + + if ((e->oldframe >= paliashdr->num_frames) || (e->oldframe < 0)) { - R_Printf(PRINT_ALL, "%s %s: no such oldframe %d\n", - __func__, currentmodel->name, e->oldframe); + R_Printf(PRINT_DEVELOPER, "%s %s: no such oldframe %d\n", + __func__, currentmodel->name, e->oldframe); e->oldframe = 0; } - pframe = ( daliasframe_t * ) ( ( byte * ) paliashdr + - paliashdr->ofs_frames + - e->frame * paliashdr->framesize); + pframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames + + e->frame * paliashdr->framesize); - poldframe = ( daliasframe_t * ) ( ( byte * ) paliashdr + - paliashdr->ofs_frames + - e->oldframe * paliashdr->framesize); + poldframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames + + e->oldframe * paliashdr->framesize); - /* - ** compute axially aligned mins and maxs - */ - if ( pframe == poldframe ) + /* compute axially aligned mins and maxs */ + if (pframe == poldframe) { - for ( i = 0; i < 3; i++ ) + for (i = 0; i < 3; i++) { mins[i] = pframe->translate[i]; - maxs[i] = mins[i] + pframe->scale[i]*255; + maxs[i] = mins[i] + pframe->scale[i] * 255; } } else { - for ( i = 0; i < 3; i++ ) + for (i = 0; i < 3; i++) { thismins[i] = pframe->translate[i]; - thismaxs[i] = thismins[i] + pframe->scale[i]*255; + thismaxs[i] = thismins[i] + pframe->scale[i] * 255; - oldmins[i] = poldframe->translate[i]; - oldmaxs[i] = oldmins[i] + poldframe->scale[i]*255; + oldmins[i] = poldframe->translate[i]; + oldmaxs[i] = oldmins[i] + poldframe->scale[i] * 255; - if ( thismins[i] < oldmins[i] ) + if (thismins[i] < oldmins[i]) + { mins[i] = thismins[i]; + } else + { mins[i] = oldmins[i]; + } - if ( thismaxs[i] > oldmaxs[i] ) + if (thismaxs[i] > oldmaxs[i]) + { maxs[i] = thismaxs[i]; + } else + { maxs[i] = oldmaxs[i]; + } } } - /* - ** compute a full bounding box - */ - for ( i = 0; i < 8; i++ ) - { - vec3_t tmp; - - if ( i & 1 ) - tmp[0] = mins[0]; - else - tmp[0] = maxs[0]; - - if ( i & 2 ) - tmp[1] = mins[1]; - else - tmp[1] = maxs[1]; - - if ( i & 4 ) - tmp[2] = mins[2]; - else - tmp[2] = maxs[2]; - - VectorCopy( tmp, bbox[i] ); - } - - /* - ** rotate the bounding box - */ - VectorCopy( e->angles, angles ); - angles[YAW] = -angles[YAW]; - AngleVectors( angles, vectors[0], vectors[1], vectors[2] ); - - for ( i = 0; i < 8; i++ ) + /* compute a full bounding box */ + for (i = 0; i < 8; i++) { vec3_t tmp; - VectorCopy( bbox[i], tmp ); + if (i & 1) + { + tmp[0] = mins[0]; + } + else + { + tmp[0] = maxs[0]; + } - bbox[i][0] = DotProduct( vectors[0], tmp ); - bbox[i][1] = -DotProduct( vectors[1], tmp ); - bbox[i][2] = DotProduct( vectors[2], tmp ); + if (i & 2) + { + tmp[1] = mins[1]; + } + else + { + tmp[1] = maxs[1]; + } - VectorAdd( e->origin, bbox[i], bbox[i] ); + if (i & 4) + { + tmp[2] = mins[2]; + } + else + { + tmp[2] = maxs[2]; + } + + VectorCopy(tmp, bbox[i]); + } + + /* rotate the bounding box */ + VectorCopy(e->angles, angles); + angles[YAW] = -angles[YAW]; + AngleVectors(angles, vectors[0], vectors[1], vectors[2]); + + for (i = 0; i < 8; i++) + { + vec3_t tmp; + + VectorCopy(bbox[i], tmp); + + bbox[i][0] = DotProduct(vectors[0], tmp); + bbox[i][1] = -DotProduct(vectors[1], tmp); + bbox[i][2] = DotProduct(vectors[2], tmp); + + VectorAdd(e->origin, bbox[i], bbox[i]); } { int p, f, aggregatemask = ~0; - for ( p = 0; p < 8; p++ ) + for (p = 0; p < 8; p++) { int mask = 0; - for ( f = 0; f < 4; f++ ) + for (f = 0; f < 4; f++) { float dp = DotProduct( frustum[f].normal, bbox[p] ); - if ( ( dp - frustum[f].dist ) < 0 ) + if ((dp - frustum[f].dist ) < 0) { - mask |= ( 1 << f ); + mask |= (1 << f); } } aggregatemask &= mask; } - if ( aggregatemask ) + if (aggregatemask) { return true; } @@ -797,100 +809,129 @@ static qboolean R_CullAliasModel( vec3_t bbox[8], entity_t *e, model_t *currentm } } -/* -================= -R_DrawAliasModel - -================= -*/ -void R_DrawAliasModel (entity_t *currententity, model_t *currentmodel) +void +R_DrawAliasModel(entity_t *currententity, model_t *currentmodel) { - int i; - int leftHandOffset = 0; - dmdl_t *paliashdr; - float an; - float prev_viewproj[16]; + int i; + int leftHandOffset = 0; + dmdl_t *paliashdr; + float an; + float prev_viewproj[16]; - if ( !( currententity->flags & RF_WEAPONMODEL ) ) + if (!(currententity->flags & RF_WEAPONMODEL)) { - vec3_t bbox[8]; + vec3_t bbox[8]; - if ( R_CullAliasModel( bbox, currententity, currentmodel ) ) + if (R_CullAliasModel( bbox, currententity, currentmodel)) + { return; + } } - if ( currententity->flags & RF_WEAPONMODEL ) + if (currententity->flags & RF_WEAPONMODEL) { - if ( r_lefthand->value == 2 ) + if (r_lefthand->value == 2) + { return; + } } paliashdr = (dmdl_t *)currentmodel->extradata; - // - // get lighting information - // - // PMM - rewrote, reordered to handle new shells & mixing - // PMM - 3.20 code .. replaced with original way of doing it to keep mod authors happy - // - if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE ) ) + /* get lighting information */ + if (currententity->flags & + (RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | + RF_SHELL_BLUE | RF_SHELL_DOUBLE)) { - VectorClear (shadelight); + VectorClear(shadelight); + if (currententity->flags & RF_SHELL_HALF_DAM) { - shadelight[0] = 0.56; - shadelight[1] = 0.59; - shadelight[2] = 0.45; + shadelight[0] = 0.56; + shadelight[1] = 0.59; + shadelight[2] = 0.45; } - if ( currententity->flags & RF_SHELL_DOUBLE ) + + if (currententity->flags & RF_SHELL_DOUBLE) { shadelight[0] = 0.9; shadelight[1] = 0.7; } - if ( currententity->flags & RF_SHELL_RED ) + + if (currententity->flags & RF_SHELL_RED) + { shadelight[0] = 1.0; - if ( currententity->flags & RF_SHELL_GREEN ) + } + + if (currententity->flags & RF_SHELL_GREEN) + { shadelight[1] = 1.0; - if ( currententity->flags & RF_SHELL_BLUE ) + } + + if (currententity->flags & RF_SHELL_BLUE) + { shadelight[2] = 1.0; + } } - else if ( currententity->flags & RF_FULLBRIGHT ) + else if (currententity->flags & RF_FULLBRIGHT) { - for (i=0 ; i<3 ; i++) + for (i = 0; i < 3; i++) + { shadelight[i] = 1.0; + } } else { - R_LightPoint(currententity->origin, shadelight, currententity); - - // player lighting hack for communication back to server - // big hack! - if ( currententity->flags & RF_WEAPONMODEL ) + if (r_worldmodel->grid) { - // pick the greatest component, which should be the same - // as the mono value returned by software + BSPX_LightGridValue(r_worldmodel->grid, r_newrefdef.lightstyles, + currententity->origin, shadelight); + } + else + { + R_LightPoint(currententity->origin, shadelight, currententity); + } + + /* player lighting hack for communication back to server */ + if (currententity->flags & RF_WEAPONMODEL) + { + /* pick the greatest component, which should be + the same as the mono value returned by software */ if (shadelight[0] > shadelight[1]) { if (shadelight[0] > shadelight[2]) - r_lightlevel->value = 150*shadelight[0]; + { + r_lightlevel->value = 150 * shadelight[0]; + } else - r_lightlevel->value = 150*shadelight[2]; + { + r_lightlevel->value = 150 * shadelight[2]; + } } else { if (shadelight[1] > shadelight[2]) - r_lightlevel->value = 150*shadelight[1]; + { + r_lightlevel->value = 150 * shadelight[1]; + } else - r_lightlevel->value = 150*shadelight[2]; + { + r_lightlevel->value = 150 * shadelight[2]; + } } } } - if ( currententity->flags & RF_MINLIGHT ) + if (currententity->flags & RF_MINLIGHT) { - for (i=0 ; i<3 ; i++) + for (i = 0; i < 3; i++) + { if (shadelight[i] > 0.1) + { break; + } + } + if (i == 3) { shadelight[0] = 0.1; @@ -899,50 +940,49 @@ void R_DrawAliasModel (entity_t *currententity, model_t *currentmodel) } } - if ( currententity->flags & RF_GLOW ) - { // bonus items will pulse with time - float scale; + if (currententity->flags & RF_GLOW) + { + /* bonus items will pulse with time */ + float scale; - scale = 0.1 * sin(r_newrefdef.time*7); - for (i=0 ; i<3 ; i++) + scale = 0.1 * sin(r_newrefdef.time * 7); + + for (i = 0; i < 3; i++) { float min; min = shadelight[i] * 0.8; shadelight[i] += scale; + if (shadelight[i] < min) + { shadelight[i] = min; + } } } - // ================= - // PGM ir goggles color override - if ( r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE) + /* ir goggles color override */ + if (r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & + RF_IR_VISIBLE) { shadelight[0] = 1.0; shadelight[1] = 0.0; shadelight[2] = 0.0; } - // PGM - // ================= - shadedots = r_avertexnormal_dots[((int)(currententity->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)]; + shadedots = r_avertexnormal_dots[((int)(currententity->angles[1] * + (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)]; - an = currententity->angles[1]/180*M_PI; + an = currententity->angles[1] / 180 * M_PI; shadevector[0] = cos(-an); shadevector[1] = sin(-an); shadevector[2] = 1; - VectorNormalize (shadevector); - - // - // locate the proper data - // + VectorNormalize(shadevector); + /* locate the proper data */ c_alias_polys += paliashdr->num_tris; - // - // draw all the triangles - // + /* draw all the triangles */ if (currententity->flags & RF_DEPTHHACK || r_newrefdef.rdflags & RDF_NOWORLDMODEL) { // hack the depth range to prevent view model from poking into walls float r_proj_aspect = (float)r_newrefdef.width / r_newrefdef.height; float r_proj_fovy = r_newrefdef.fov_y; diff --git a/src/client/refresh/vk/vk_model.c b/src/client/refresh/vk/vk_model.c index 249ce1c0..edf318b7 100644 --- a/src/client/refresh/vk/vk_model.c +++ b/src/client/refresh/vk/vk_model.c @@ -23,19 +23,18 @@ * Model loading and caching. Includes the .bsp file format * * ======================================================================= - * */ #include "header/local.h" -YQ2_ALIGNAS_TYPE(int) static byte mod_novis[MAX_MAP_LEAFS/8]; +static YQ2_ALIGNAS_TYPE(int) byte mod_novis[MAX_MAP_LEAFS / 8]; -#define MAX_MOD_KNOWN 512 -static model_t *models_known; -static int mod_numknown = 0; -static int mod_loaded = 0; -static int mod_max = 0; -static int models_known_max = 0; +#define MAX_MOD_KNOWN 512 +static model_t *models_known; +static int mod_numknown = 0; +static int mod_max = 0; +static int mod_loaded = 0; +static int models_known_max = 0; int registration_sequence; @@ -160,7 +159,7 @@ Mod_LoadSubmodels(model_t *loadmodel, const byte *mod_base, const lump_t *l) * Fills in s->texturemins[] and s->extents[] */ static void -CalcSurfaceExtents(model_t *loadmodel, msurface_t *s) +Mod_CalcSurfaceExtents(model_t *loadmodel, msurface_t *s) { float mins[2], maxs[2], val; int i; @@ -510,7 +509,7 @@ Mod_LoadFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l, out->lmvlen[0] = 1.0f; out->lmvlen[1] = 1.0f; - CalcSurfaceExtents(loadmodel, out); + Mod_CalcSurfaceExtents(loadmodel, out); lightofs = in->lightofs; } @@ -633,7 +632,7 @@ Mod_LoadQFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l, out->lmvlen[0] = 1.0f; out->lmvlen[1] = 1.0f; - CalcSurfaceExtents(loadmodel, out); + Mod_CalcSurfaceExtents(loadmodel, out); lightofs = in->lightofs; } @@ -900,6 +899,9 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen) ((int *)header)[i] = LittleLong(((int *)header)[i]); } + /* check for BSPX extensions */ + bspx_header = Mod_LoadBSPX(modfilelen, (byte*)header); + // calculate the needed hunksize from the lumps int hunkSize = 0; hunkSize += calcLumpHunkSize(&header->lumps[LUMP_VERTEXES], sizeof(dvertex_t), sizeof(mvertex_t)); @@ -943,8 +945,10 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen) mod->extradata = Hunk_Begin(hunkSize); mod->type = mod_brush; - /* check for BSPX extensions */ - bspx_header = Mod_LoadBSPX(modfilelen, (byte*)header); + if (bspx_header) + { + mod->grid = BSPX_LightGridLoad(bspx_header, mod_base); + } /* load into heap */ Mod_LoadVertexes(mod->name, &mod->vertexes, &mod->numvertexes, mod_base, @@ -996,69 +1000,73 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen) mod->numframes = 2; /* regular and alternate animation */ } -//============================================================================= - /* -================== -Mod_ForName - -Loads in a model for the given name -================== -*/ + * Loads in a model for the given name + */ static model_t * -Mod_ForName (const char *name, model_t *parent_model, qboolean crash) +Mod_ForName(const char *name, model_t *parent_model, qboolean crash) { - model_t *mod; - void *buf; - int i, modfilelen; + model_t *mod; + void *buf; + int i, modfilelen; if (!name[0]) { ri.Sys_Error(ERR_DROP, "%s: NULL name", __func__); } - // - // inline models are grabbed only from worldmodel - // + /* inline models are grabbed only from worldmodel */ if (name[0] == '*' && parent_model) { - i = atoi(name+1); + i = (int)strtol(name + 1, (char **)NULL, 10); + if (i < 1 || i >= parent_model->numsubmodels) - ri.Sys_Error (ERR_DROP, "bad inline model number"); + { + ri.Sys_Error(ERR_DROP, "%s: bad inline model number", + __func__); + } + return &parent_model->submodels[i]; } - // - // search the currently loaded models - // - for (i=0 , mod=models_known ; iname[0]) + { continue; - if (!strcmp (mod->name, name) ) + } + + if (!strcmp(mod->name, name)) + { return mod; + } } - // - // find a free model slot spot - // - for (i=0 , mod=models_known ; iname[0]) - break; // free spot + { + break; /* free spot */ + } } + if (i == mod_numknown) { if (mod_numknown == models_known_max) + { ri.Sys_Error(ERR_DROP, "%s: mod_numknown == models_known_max", __func__); + } + mod_numknown++; } - strcpy (mod->name, name); - // - // load the file - // + strcpy(mod->name, name); + + /* load the file */ modfilelen = Mod_LoadFile (mod->name, &buf); + if (!buf) { if (crash) @@ -1071,7 +1079,8 @@ Mod_ForName (const char *name, model_t *parent_model, qboolean crash) { R_Printf(PRINT_ALL, "%s: Can't load %s\n", __func__, mod->name); } - memset (mod->name, 0, sizeof(mod->name)); + + memset(mod->name, 0, sizeof(mod->name)); return NULL; } @@ -1086,59 +1095,58 @@ Mod_ForName (const char *name, model_t *parent_model, qboolean crash) // fill it in // - // call the apropriate loader - + /* call the apropriate loader */ switch (LittleLong(*(unsigned *)buf)) { - case DKMHEADER: - /* fall through */ - case RAVENFMHEADER: - /* fall through */ - case IDALIASHEADER: - /* fall through */ - case IDMDLHEADER: - { - mod->extradata = Mod_LoadAliasModel(mod->name, buf, modfilelen, - mod->mins, mod->maxs, - (struct image_s **)mod->skins, (findimage_t)Vk_FindImage, - &(mod->type)); - if (!mod->extradata) + case DKMHEADER: + /* fall through */ + case RAVENFMHEADER: + /* fall through */ + case IDALIASHEADER: + /* fall through */ + case IDMDLHEADER: { - ri.Sys_Error(ERR_DROP, "%s: Failed to load %s", - __func__, mod->name); - } - }; - break; + mod->extradata = Mod_LoadAliasModel(mod->name, buf, modfilelen, + mod->mins, mod->maxs, + (struct image_s **)mod->skins, (findimage_t)Vk_FindImage, + &(mod->type)); + if (!mod->extradata) + { + ri.Sys_Error(ERR_DROP, "%s: Failed to load %s", + __func__, mod->name); + } + }; + break; - case IDSPRITEHEADER: - { - mod->extradata = Mod_LoadSP2(mod->name, buf, modfilelen, - (struct image_s **)mod->skins, (findimage_t)Vk_FindImage, - &(mod->type)); - if (!mod->extradata) + case IDSPRITEHEADER: { - ri.Sys_Error(ERR_DROP, "%s: Failed to load %s", - __func__, mod->name); + mod->extradata = Mod_LoadSP2(mod->name, buf, modfilelen, + (struct image_s **)mod->skins, (findimage_t)Vk_FindImage, + &(mod->type)); + if (!mod->extradata) + { + ri.Sys_Error(ERR_DROP, "%s: Failed to load %s", + __func__, mod->name); + } } - } - break; + break; - case IDBSPHEADER: - /* fall through */ - case QBSPHEADER: - Mod_LoadBrushModel(mod, buf, modfilelen); - break; + case IDBSPHEADER: + /* fall through */ + case QBSPHEADER: + Mod_LoadBrushModel(mod, buf, modfilelen); + break; - default: - ri.Sys_Error(ERR_DROP, "%s: unknown fileid for %s", - __func__, mod->name); - break; + default: + ri.Sys_Error(ERR_DROP, "%s: unknown fileid for %s", + __func__, mod->name); + break; } mod->radius = Mod_RadiusFromBounds(mod->mins, mod->maxs); if (mod->extradata) { - mod->extradatasize = Hunk_End (); + mod->extradatasize = Hunk_End(); } else { @@ -1165,8 +1173,8 @@ Mod_Free(model_t *mod) R_Printf(PRINT_ALL, "%s: Unload %s[%d]\n", __func__, mod->name, mod_loaded); } - Hunk_Free (mod->extradata); - memset (mod, 0, sizeof(*mod)); + Hunk_Free(mod->extradata); + memset(mod, 0, sizeof(*mod)); mod_loaded --; if (mod_loaded < 0) { @@ -1175,19 +1183,21 @@ Mod_Free(model_t *mod) } void -Mod_FreeAll (void) +Mod_FreeAll(void) { - int i; + int i; - for (i=0 ; i