Merge pull request #742 from 0lvin/benchmark

Update for benchmark mode
This commit is contained in:
Yamagi 2021-10-30 09:39:41 +02:00 committed by GitHub
commit 9a11251740
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 667 additions and 504 deletions

View file

@ -281,7 +281,8 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable`
* **r_retexturing**: If set to `1` (the default) and a retexturing pack
is installed, the high resolution textures are used.
If set to `2` and vulkan render is used, scale up all 8bit textures.
* **r_scale8bittextures**: If set to `1`, scale up all 8bit textures.
* **r_shadows**: Enables rendering of shadows. Quake IIs shadows are
very simple and are prone to render errors.

View file

@ -1422,6 +1422,10 @@ SCR_Framecounter(void) {
static int frametimes[60] = {0};
static long long oldtime;
/* skip statistics without show fps */
if (cl_showfps->value < 1)
return;
newtime = Sys_Microseconds();
frametimes[frame] = (int)(newtime - oldtime);

View file

@ -32,8 +32,8 @@
Mod_DecompressVis
===================
*/
byte *
Mod_DecompressVis(byte *in, int row)
const byte *
Mod_DecompressVis(const byte *in, int row)
{
YQ2_ALIGNAS_TYPE(int) static byte decompressed[MAX_MAP_LEAFS / 8];
int c;

View file

@ -28,6 +28,7 @@
image_t gltextures[MAX_GLTEXTURES];
int numgltextures;
static int image_max = 0;
int base_textureid; /* gltextures[i] = base_textureid+i */
extern qboolean scrap_dirty;
extern byte scrap_texels[MAX_SCRAPS][BLOCK_WIDTH * BLOCK_HEIGHT];
@ -292,9 +293,9 @@ R_TextureSolidMode(char *string)
void
R_ImageList_f(void)
{
int i;
int i, used, texels;
image_t *image;
int texels;
qboolean freeup;
const char *palstrings[2] = {
"RGB",
"PAL"
@ -302,14 +303,23 @@ R_ImageList_f(void)
R_Printf(PRINT_ALL, "------------------\n");
texels = 0;
used = 0;
for (i = 0, image = gltextures; i < numgltextures; i++, image++)
{
char *in_use = "";
if (image->texnum <= 0)
{
continue;
}
if (image->registration_sequence == registration_sequence)
{
in_use = "*";
used++;
}
texels += image->upload_width * image->upload_height;
switch (image->type)
@ -331,14 +341,16 @@ R_ImageList_f(void)
break;
}
R_Printf(PRINT_ALL, " %3i %3i %s: %s\n",
R_Printf(PRINT_ALL, " %3i %3i %s: %s %s\n",
image->upload_width, image->upload_height,
palstrings[image->paletted], image->name);
palstrings[image->paletted], image->name, in_use);
}
R_Printf(PRINT_ALL,
"Total texel count (not counting mipmaps): %i\n",
texels);
freeup = R_ImageHasFreeSpace();
R_Printf(PRINT_ALL, "Used %d of %d images%s.\n", used, image_max, freeup ? ", has free space" : "");
}
/*
@ -761,7 +773,7 @@ R_Upload32(unsigned *data, int width, int height, qboolean mipmap)
qboolean
R_Upload8(byte *data, int width, int height, qboolean mipmap, qboolean is_sky)
{
unsigned trans[512 * 256];
unsigned trans[1024 * 1024];
int i, s;
int p;
@ -769,7 +781,7 @@ R_Upload8(byte *data, int width, int height, qboolean mipmap, qboolean is_sky)
if (s > sizeof(trans) / 4)
{
ri.Sys_Error(ERR_DROP, "R_Upload8: too large");
ri.Sys_Error(ERR_DROP, "%s: too large", __func__);
}
if (gl_config.palettedtexture && is_sky)
@ -926,9 +938,22 @@ R_LoadPic(char *name, byte *pic, int width, int realwidth,
if (bits == 8)
{
image->has_alpha = R_Upload8(pic, width, height,
(image->type != it_pic && image->type != it_sky),
image->type == it_sky);
// resize 8bit images only when we forced such logic
if (r_scale8bittextures->value)
{
byte *image_converted = malloc(width * height * 4);
scale2x(pic, image_converted, width, height);
image->has_alpha = R_Upload8(image_converted, width * 2, height * 2,
(image->type != it_pic && image->type != it_sky),
image->type == it_sky);
free(image_converted);
}
else
{
image->has_alpha = R_Upload8(pic, width, height,
(image->type != it_pic && image->type != it_sky),
image->type == it_sky);
}
}
else
{
@ -1148,7 +1173,7 @@ R_FindImage(char *name, imagetype_t type)
if (strcmp(ext, "pcx") == 0)
{
if (gl_retexturing->value)
if (r_retexturing->value)
{
GetPCXInfo(name, &realwidth, &realheight);
if(realwidth == 0)
@ -1195,7 +1220,7 @@ R_FindImage(char *name, imagetype_t type)
}
else if (strcmp(ext, "wal") == 0 || strcmp(ext, "m8") == 0)
{
if (gl_retexturing->value)
if (r_retexturing->value)
{
/* Get size of the original texture */
if (strcmp(ext, "m8") == 0)
@ -1354,12 +1379,40 @@ R_FreeUnusedImages(void)
}
}
qboolean
R_ImageHasFreeSpace(void)
{
int i, used;
image_t *image;
used = 0;
for (i = 0, image = gltextures; i < numgltextures; i++, image++)
{
if (!image->name[0])
continue;
if (image->registration_sequence == registration_sequence)
{
used ++;
}
}
if (image_max < used)
{
image_max = used;
}
// should same size of free slots as currently used
return (numgltextures + used) < MAX_GLTEXTURES;
}
void
R_InitImages(void)
{
int i, j;
registration_sequence = 1;
image_max = 0;
/* init intensity conversions */
intensity = ri.Cvar_Get("gl1_intensity", "2", CVAR_ARCHIVE);

View file

@ -326,7 +326,7 @@ R_RecursiveLightPoint(mnode_t *node, vec3_t start, vec3_t end)
}
void
R_LightPoint(vec3_t p, vec3_t color)
R_LightPoint(entity_t *currententity, vec3_t p, vec3_t color)
{
vec3_t end;
float r;

View file

@ -137,7 +137,7 @@ LM_AllocBlock(int w, int h, int *x, int *y)
}
void
LM_BuildPolygonFromSurface(msurface_t *fa)
LM_BuildPolygonFromSurface(model_t *currentmodel, msurface_t *fa)
{
int i, lindex, lnumverts;
medge_t *pedges, *r_pedge;

View file

@ -39,9 +39,6 @@ glstate_t gl_state;
image_t *r_notexture; /* use for bad textures */
image_t *r_particletexture; /* little dot for particles */
entity_t *currententity;
model_t *currentmodel;
cplane_t frustum[4];
int r_visframecount; /* bumped when going to a new PVS */
@ -103,7 +100,8 @@ cvar_t *r_fixsurfsky;
cvar_t *r_customwidth;
cvar_t *r_customheight;
cvar_t *gl_retexturing;
cvar_t *r_retexturing;
cvar_t *r_scale8bittextures;
cvar_t *gl_nolerp_list;
@ -176,7 +174,7 @@ R_RotateForEntity(entity_t *e)
}
void
R_DrawSpriteModel(entity_t *e)
R_DrawSpriteModel(entity_t *currententity, const model_t *currentmodel)
{
float alpha = 1.0F;
vec3_t point[4];
@ -188,16 +186,16 @@ R_DrawSpriteModel(entity_t *e)
a single polygon without a surface cache */
psprite = (dsprite_t *)currentmodel->extradata;
e->frame %= psprite->numframes;
frame = &psprite->frames[e->frame];
currententity->frame %= psprite->numframes;
frame = &psprite->frames[currententity->frame];
/* normal sprite */
up = vup;
right = vright;
if (e->flags & RF_TRANSLUCENT)
if (currententity->flags & RF_TRANSLUCENT)
{
alpha = e->alpha;
alpha = currententity->alpha;
}
if (alpha != 1.0F)
@ -207,7 +205,7 @@ R_DrawSpriteModel(entity_t *e)
glColor4f(1, 1, 1, alpha);
R_Bind(currentmodel->skins[e->frame]->texnum);
R_Bind(currentmodel->skins[currententity->frame]->texnum);
R_TexEnv(GL_MODULATE);
@ -227,16 +225,16 @@ R_DrawSpriteModel(entity_t *e)
1, 1
};
VectorMA( e->origin, -frame->origin_y, up, point[0] );
VectorMA( currententity->origin, -frame->origin_y, up, point[0] );
VectorMA( point[0], -frame->origin_x, right, point[0] );
VectorMA( e->origin, frame->height - frame->origin_y, up, point[1] );
VectorMA( currententity->origin, frame->height - frame->origin_y, up, point[1] );
VectorMA( point[1], -frame->origin_x, right, point[1] );
VectorMA( e->origin, frame->height - frame->origin_y, up, point[2] );
VectorMA( currententity->origin, frame->height - frame->origin_y, up, point[2] );
VectorMA( point[2], frame->width - frame->origin_x, right, point[2] );
VectorMA( e->origin, -frame->origin_y, up, point[3] );
VectorMA( currententity->origin, -frame->origin_y, up, point[3] );
VectorMA( point[3], frame->width - frame->origin_x, right, point[3] );
glEnableClientState( GL_VERTEX_ARRAY );
@ -261,7 +259,7 @@ R_DrawSpriteModel(entity_t *e)
}
void
R_DrawNullModel(void)
R_DrawNullModel(entity_t *currententity)
{
vec3_t shadelight;
@ -271,7 +269,7 @@ R_DrawNullModel(void)
}
else
{
R_LightPoint(currententity->origin, shadelight);
R_LightPoint(currententity, currententity->origin, shadelight);
}
glPushMatrix();
@ -330,7 +328,7 @@ R_DrawEntitiesOnList(void)
/* draw non-transparent first */
for (i = 0; i < r_newrefdef.num_entities; i++)
{
currententity = &r_newrefdef.entities[i];
entity_t *currententity = &r_newrefdef.entities[i];
if (currententity->flags & RF_TRANSLUCENT)
{
@ -343,24 +341,24 @@ R_DrawEntitiesOnList(void)
}
else
{
currentmodel = currententity->model;
const model_t *currentmodel = currententity->model;
if (!currentmodel)
{
R_DrawNullModel();
R_DrawNullModel(currententity);
continue;
}
switch (currentmodel->type)
{
case mod_alias:
R_DrawAliasModel(currententity);
R_DrawAliasModel(currententity, currentmodel);
break;
case mod_brush:
R_DrawBrushModel(currententity);
R_DrawBrushModel(currententity, currentmodel);
break;
case mod_sprite:
R_DrawSpriteModel(currententity);
R_DrawSpriteModel(currententity, currentmodel);
break;
default:
ri.Sys_Error(ERR_DROP, "Bad modeltype");
@ -376,7 +374,7 @@ R_DrawEntitiesOnList(void)
for (i = 0; i < r_newrefdef.num_entities; i++)
{
currententity = &r_newrefdef.entities[i];
entity_t *currententity = &r_newrefdef.entities[i];
if (!(currententity->flags & RF_TRANSLUCENT))
{
@ -389,24 +387,24 @@ R_DrawEntitiesOnList(void)
}
else
{
currentmodel = currententity->model;
const model_t *currentmodel = currententity->model;
if (!currentmodel)
{
R_DrawNullModel();
R_DrawNullModel(currententity);
continue;
}
switch (currentmodel->type)
{
case mod_alias:
R_DrawAliasModel(currententity);
R_DrawAliasModel(currententity, currentmodel);
break;
case mod_brush:
R_DrawBrushModel(currententity);
R_DrawBrushModel(currententity, currentmodel);
break;
case mod_sprite:
R_DrawSpriteModel(currententity);
R_DrawSpriteModel(currententity, currentmodel);
break;
default:
ri.Sys_Error(ERR_DROP, "Bad modeltype");
@ -952,7 +950,7 @@ R_SetGL2D(void)
/*
* r_newrefdef must be set before the first call
*/
void
static void
R_RenderView(refdef_t *fd)
{
if ((gl_state.stereo_mode != STEREO_MODE_NONE) && gl_state.camera_separation) {
@ -1073,7 +1071,7 @@ R_RenderView(refdef_t *fd)
if (!r_worldmodel && !(r_newrefdef.rdflags & RDF_NOWORLDMODEL))
{
ri.Sys_Error(ERR_DROP, "R_RenderView: NULL worldmodel");
ri.Sys_Error(ERR_DROP, "%s: NULL worldmodel", __func__);
}
if (r_speeds->value)
@ -1150,8 +1148,8 @@ GL_GetSpecialBufferModeForStereoMode(enum stereo_modes stereo_mode) {
return OPENGL_SPECIAL_BUFFER_MODE_NONE;
}
void
R_SetLightLevel(void)
static void
R_SetLightLevel(entity_t *currententity)
{
vec3_t shadelight;
@ -1161,7 +1159,7 @@ R_SetLightLevel(void)
}
/* save off light value for server to look at */
R_LightPoint(r_newrefdef.vieworg, shadelight);
R_LightPoint(currententity, r_newrefdef.vieworg, shadelight);
/* pick the greatest component, which should be the
* same as the mono value returned by software */
@ -1189,11 +1187,11 @@ R_SetLightLevel(void)
}
}
void
static void
RI_RenderFrame(refdef_t *fd)
{
R_RenderView(fd);
R_SetLightLevel();
R_SetLightLevel (NULL);
R_SetGL2D();
}
@ -1263,7 +1261,8 @@ R_Register(void)
r_customheight = ri.Cvar_Get("r_customheight", "768", CVAR_ARCHIVE);
gl_msaa_samples = ri.Cvar_Get ( "r_msaa_samples", "0", CVAR_ARCHIVE );
gl_retexturing = ri.Cvar_Get("r_retexturing", "1", CVAR_ARCHIVE);
r_retexturing = ri.Cvar_Get("r_retexturing", "1", CVAR_ARCHIVE);
r_scale8bittextures = ri.Cvar_Get("r_scale8bittextures", "0", CVAR_ARCHIVE);
/* don't bilerp characters and crosshairs */
gl_nolerp_list = ri.Cvar_Get("r_nolerp_list", "pics/conchars.pcx pics/ch1.pcx pics/ch2.pcx pics/ch3.pcx", 0);

View file

@ -45,8 +45,8 @@ float shadelight[3];
float *shadedots = r_avertexnormal_dots[0];
extern vec3_t lightspot;
void
R_LerpVerts(int nverts, dtrivertx_t *v, dtrivertx_t *ov,
static void
R_LerpVerts(entity_t *currententity, int nverts, dtrivertx_t *v, dtrivertx_t *ov,
dtrivertx_t *verts, float *lerp, float move[3],
float frontv[3], float backv[3])
{
@ -83,8 +83,8 @@ R_LerpVerts(int nverts, dtrivertx_t *v, dtrivertx_t *ov,
/*
* Interpolates between two frames and origins
*/
void
R_DrawAliasFrameLerp(dmdl_t *paliashdr, float backlerp)
static void
R_DrawAliasFrameLerp(entity_t *currententity, dmdl_t *paliashdr, float backlerp)
{
unsigned short total;
GLenum type;
@ -152,7 +152,7 @@ R_DrawAliasFrameLerp(dmdl_t *paliashdr, float backlerp)
lerp = s_lerped[0];
R_LerpVerts(paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv);
R_LerpVerts(currententity, paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv);
while (1)
{
@ -250,8 +250,8 @@ R_DrawAliasFrameLerp(dmdl_t *paliashdr, float backlerp)
}
}
void
R_DrawAliasShadow(dmdl_t *paliashdr, int posenum)
static void
R_DrawAliasShadow(entity_t *currententity, dmdl_t *paliashdr, int posenum)
{
unsigned short total;
GLenum type;
@ -285,7 +285,7 @@ R_DrawAliasShadow(dmdl_t *paliashdr, int posenum)
if (count < 0)
{
count = -count;
type = GL_TRIANGLE_FAN;
}
else
@ -330,7 +330,7 @@ R_DrawAliasShadow(dmdl_t *paliashdr, int posenum)
}
static qboolean
R_CullAliasModel(vec3_t bbox[8], entity_t *e)
R_CullAliasModel(const model_t *currentmodel, vec3_t bbox[8], entity_t *e)
{
int i;
vec3_t mins, maxs;
@ -482,7 +482,7 @@ R_CullAliasModel(vec3_t bbox[8], entity_t *e)
}
void
R_DrawAliasModel(entity_t *e)
R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
{
int i;
dmdl_t *paliashdr;
@ -490,15 +490,15 @@ R_DrawAliasModel(entity_t *e)
vec3_t bbox[8];
image_t *skin;
if (!(e->flags & RF_WEAPONMODEL))
if (!(currententity->flags & RF_WEAPONMODEL))
{
if (R_CullAliasModel(bbox, e))
if (R_CullAliasModel(currentmodel, bbox, currententity))
{
return;
}
}
if (e->flags & RF_WEAPONMODEL)
if (currententity->flags & RF_WEAPONMODEL)
{
if (gl_lefthand->value == 2)
{
@ -552,7 +552,7 @@ R_DrawAliasModel(entity_t *e)
}
else
{
R_LightPoint(currententity->origin, shadelight);
R_LightPoint(currententity, currententity->origin, shadelight);
/* player lighting hack for communication back to server */
if (currententity->flags & RF_WEAPONMODEL)
@ -631,7 +631,7 @@ R_DrawAliasModel(entity_t *e)
shadelight[i] *= gl1_overbrightbits->value;
}
}
/* ir goggles color override */
@ -695,9 +695,9 @@ R_DrawAliasModel(entity_t *e)
}
glPushMatrix();
e->angles[PITCH] = -e->angles[PITCH];
R_RotateForEntity(e);
e->angles[PITCH] = -e->angles[PITCH];
currententity->angles[PITCH] = -currententity->angles[PITCH];
R_RotateForEntity(currententity);
currententity->angles[PITCH] = -currententity->angles[PITCH];
/* select skin */
if (currententity->skin)
@ -761,7 +761,7 @@ R_DrawAliasModel(entity_t *e)
currententity->backlerp = 0;
}
R_DrawAliasFrameLerp(paliashdr, currententity->backlerp);
R_DrawAliasFrameLerp(currententity, paliashdr, currententity->backlerp);
R_TexEnv(GL_REPLACE);
glShadeModel(GL_FLAT);
@ -811,13 +811,13 @@ R_DrawAliasModel(entity_t *e)
glPushMatrix();
/* don't rotate shadows on ungodly axes */
glTranslatef(e->origin[0], e->origin[1], e->origin[2]);
glRotatef(e->angles[1], 0, 0, 1);
glTranslatef(currententity->origin[0], currententity->origin[1], currententity->origin[2]);
glRotatef(currententity->angles[1], 0, 0, 1);
glDisable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glColor4f(0, 0, 0, 0.5f);
R_DrawAliasShadow(paliashdr, currententity->frame);
R_DrawAliasShadow(currententity, paliashdr, currententity->frame);
glEnable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glPopMatrix();

View file

@ -28,24 +28,49 @@
#define MAX_MOD_KNOWN 512
model_t *loadmodel;
int modfilelen;
YQ2_ALIGNAS_TYPE(int) byte mod_novis[MAX_MAP_LEAFS / 8];
model_t mod_known[MAX_MOD_KNOWN];
int mod_numknown;
static model_t mod_known[MAX_MOD_KNOWN];
static int mod_numknown;
static int mod_max = 0;
int registration_sequence;
byte *mod_base;
void LoadSP2(model_t *mod, void *buffer, int modfilelen);
void Mod_LoadBrushModel(model_t *mod, void *buffer, int modfilelen);
static void Mod_LoadBrushModel(model_t *mod, void *buffer, int modfilelen);
void LoadMD2(model_t *mod, void *buffer, int modfilelen);
void LM_BuildPolygonFromSurface(msurface_t *fa);
void LM_BuildPolygonFromSurface(model_t *currentmodel, msurface_t *fa);
void LM_CreateSurfaceLightmap(msurface_t *surf);
void LM_EndBuildingLightmaps(void);
void LM_BeginBuildingLightmaps(model_t *m);
/* the inline * models from the current map are kept seperate */
model_t mod_inline[MAX_MOD_KNOWN];
//===============================================================================
static qboolean
Mod_HasFreeSpace(void)
{
int i, used;
model_t *mod;
used = 0;
for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++)
{
if (!mod->name[0])
continue;
if (mod->registration_sequence == registration_sequence)
{
used ++;
}
}
if (mod_max < used)
{
mod_max = used;
}
// should same size of free slots as currently used
return (mod_numknown + mod_max) < MAX_MOD_KNOWN;
}
mleaf_t *
Mod_PointInLeaf(vec3_t p, model_t *model)
@ -84,8 +109,8 @@ Mod_PointInLeaf(vec3_t p, model_t *model)
return NULL; /* never reached */
}
byte *
Mod_ClusterPVS(int cluster, model_t *model)
const byte *
Mod_ClusterPVS(int cluster, const model_t *model)
{
if ((cluster == -1) || !model->vis)
{
@ -100,38 +125,52 @@ Mod_ClusterPVS(int cluster, model_t *model)
void
Mod_Modellist_f(void)
{
int i;
int i, total, used;
model_t *mod;
int total;
qboolean freeup;
total = 0;
used = 0;
R_Printf(PRINT_ALL, "Loaded models:\n");
for (i = 0, mod = mod_known; i < mod_numknown; i++, mod++)
{
char *in_use = "";
if (mod->registration_sequence == registration_sequence)
{
in_use = "*";
used ++;
}
if (!mod->name[0])
{
continue;
}
R_Printf(PRINT_ALL, "%8i : %s\n", mod->extradatasize, mod->name);
R_Printf(PRINT_ALL, "%8i : %s %s\n",
mod->extradatasize, mod->name, in_use);
total += mod->extradatasize;
}
R_Printf(PRINT_ALL, "Total resident: %i\n", total);
// update statistics
freeup = Mod_HasFreeSpace();
R_Printf(PRINT_ALL, "Used %d of %d models%s.\n", used, mod_max, freeup ? ", has free space" : "");
}
void
Mod_Init(void)
{
mod_max = 0;
memset(mod_novis, 0xff, sizeof(mod_novis));
}
/*
* Loads in a model for the given name
*/
model_t *
Mod_ForName(char *name, qboolean crash)
static model_t *
Mod_ForName (char *name, model_t *parent_model, qboolean crash)
{
model_t *mod;
unsigned *buf;
@ -143,17 +182,17 @@ Mod_ForName(char *name, qboolean crash)
}
/* inline models are grabbed only from worldmodel */
if (name[0] == '*')
if (name[0] == '*' && parent_model)
{
i = (int)strtol(name + 1, (char **)NULL, 10);
if ((i < 1) || !r_worldmodel || (i >= r_worldmodel->numsubmodels))
if (i < 1 || i >= parent_model->numsubmodels)
{
ri.Sys_Error(ERR_DROP, "%s: bad inline model number",
__func__);
}
return &mod_inline[i];
return &parent_model->submodels[i];
}
/* search the currently loaded models */
@ -206,8 +245,6 @@ Mod_ForName(char *name, qboolean crash)
return NULL;
}
loadmodel = mod;
/* call the apropriate loader */
switch (LittleLong(*(unsigned *)buf))
{
@ -229,15 +266,15 @@ Mod_ForName(char *name, qboolean crash)
break;
}
loadmodel->extradatasize = Hunk_End();
mod->extradatasize = Hunk_End();
ri.FS_FreeFile(buf);
return mod;
}
void
Mod_LoadLighting(lump_t *l)
static void
Mod_LoadLighting(model_t *loadmodel, byte *mod_base, lump_t *l)
{
if (!l->filelen)
{
@ -249,8 +286,8 @@ Mod_LoadLighting(lump_t *l)
memcpy(loadmodel->lightdata, mod_base + l->fileofs, l->filelen);
}
void
Mod_LoadVisibility(lump_t *l)
static void
Mod_LoadVisibility(model_t *loadmodel, byte *mod_base, lump_t *l)
{
int i;
@ -272,8 +309,8 @@ Mod_LoadVisibility(lump_t *l)
}
}
void
Mod_LoadVertexes(lump_t *l)
static void
Mod_LoadVertexes(model_t *loadmodel, byte *mod_base, lump_t *l)
{
dvertex_t *in;
mvertex_t *out;
@ -301,11 +338,11 @@ Mod_LoadVertexes(lump_t *l)
}
}
void
Mod_LoadSubmodels(lump_t *l)
static void
Mod_LoadSubmodels (model_t *loadmodel, byte *mod_base, lump_t *l)
{
dmodel_t *in;
mmodel_t *out;
model_t *out;
int i, j, count;
in = (void *)(mod_base + l->fileofs);
@ -324,6 +361,19 @@ Mod_LoadSubmodels(lump_t *l)
for (i = 0; i < count; i++, in++, out++)
{
if (i == 0)
{
// copy parent as template for first model
memcpy(out, loadmodel, sizeof(*out));
}
else
{
// copy first as template for model
memcpy(out, loadmodel->submodels, sizeof(*out));
}
Com_sprintf (out->name, sizeof(out->name), "*%d", i);
for (j = 0; j < 3; j++)
{
/* spread the mins / maxs by a pixel */
@ -333,14 +383,22 @@ Mod_LoadSubmodels(lump_t *l)
}
out->radius = Mod_RadiusFromBounds(out->mins, out->maxs);
out->headnode = LittleLong(in->headnode);
out->firstface = LittleLong(in->firstface);
out->numfaces = LittleLong(in->numfaces);
out->firstnode = LittleLong (in->headnode);
out->firstmodelsurface = LittleLong (in->firstface);
out->nummodelsurfaces = LittleLong (in->numfaces);
// visleafs
out->numleafs = 0;
// check limits
if (out->firstnode >= loadmodel->numnodes)
{
ri.Sys_Error(ERR_DROP, "%s: Inline model %i has bad firstnode",
__func__, i);
}
}
}
void
Mod_LoadEdges(lump_t *l)
static void
Mod_LoadEdges(model_t *loadmodel, byte *mod_base, lump_t *l)
{
dedge_t *in;
medge_t *out;
@ -367,8 +425,8 @@ Mod_LoadEdges(lump_t *l)
}
}
void
Mod_LoadTexinfo(lump_t *l)
static void
Mod_LoadTexinfo(model_t *loadmodel, byte *mod_base, lump_t *l)
{
texinfo_t *in;
mtexinfo_t *out, *step;
@ -443,8 +501,8 @@ Mod_LoadTexinfo(lump_t *l)
/*
* Fills in s->texturemins[] and s->extents[]
*/
void
Mod_CalcSurfaceExtents(msurface_t *s)
static void
Mod_CalcSurfaceExtents(model_t *loadmodel, msurface_t *s)
{
float mins[2], maxs[2], val;
int i, j, e;
@ -499,7 +557,7 @@ Mod_CalcSurfaceExtents(msurface_t *s)
}
}
static int calcTexinfoAndFacesSize(const lump_t *fl, const lump_t *tl)
static int calcTexinfoAndFacesSize(byte *mod_base, const lump_t *fl, const lump_t *tl)
{
dface_t* face_in = (void *)(mod_base + fl->fileofs);
texinfo_t* texinfo_in = (void *)(mod_base + tl->fileofs);
@ -574,8 +632,8 @@ static int calcTexinfoAndFacesSize(const lump_t *fl, const lump_t *tl)
return ret;
}
void
Mod_LoadFaces(lump_t *l)
static void
Mod_LoadFaces(model_t *loadmodel, byte *mod_base, lump_t *l)
{
dface_t *in;
msurface_t *out;
@ -597,8 +655,6 @@ Mod_LoadFaces(lump_t *l)
loadmodel->surfaces = out;
loadmodel->numsurfaces = count;
currentmodel = loadmodel;
LM_BeginBuildingLightmaps(loadmodel);
for (surfnum = 0; surfnum < count; surfnum++, in++, out++)
@ -628,7 +684,7 @@ Mod_LoadFaces(lump_t *l)
out->texinfo = loadmodel->texinfo + ti;
Mod_CalcSurfaceExtents(out);
Mod_CalcSurfaceExtents(loadmodel, out);
/* lighting info */
for (i = 0; i < MAXLIGHTMAPS; i++)
@ -658,7 +714,7 @@ Mod_LoadFaces(lump_t *l)
out->texturemins[i] = -8192;
}
R_SubdivideSurface(out); /* cut up polygon for warps */
R_SubdivideSurface(loadmodel, out); /* cut up polygon for warps */
}
if (r_fixsurfsky->value)
@ -677,14 +733,14 @@ Mod_LoadFaces(lump_t *l)
if (!(out->texinfo->flags & SURF_WARP))
{
LM_BuildPolygonFromSurface(out);
LM_BuildPolygonFromSurface(loadmodel, out);
}
}
LM_EndBuildingLightmaps();
}
void
static void
Mod_SetParent(mnode_t *node, mnode_t *parent)
{
node->parent = parent;
@ -698,8 +754,8 @@ Mod_SetParent(mnode_t *node, mnode_t *parent)
Mod_SetParent(node->children[1], node);
}
void
Mod_LoadNodes(lump_t *l)
static void
Mod_LoadNodes(model_t *loadmodel, byte *mod_base, lump_t *l)
{
int i, j, count, p;
dnode_t *in;
@ -752,8 +808,8 @@ Mod_LoadNodes(lump_t *l)
Mod_SetParent(loadmodel->nodes, NULL); /* sets nodes and leafs */
}
void
Mod_LoadLeafs(lump_t *l)
static void
Mod_LoadLeafs(model_t *loadmodel, byte *mod_base, lump_t *l)
{
dleaf_t *in;
mleaf_t *out;
@ -802,8 +858,8 @@ Mod_LoadLeafs(lump_t *l)
}
}
void
Mod_LoadMarksurfaces(lump_t *l)
static void
Mod_LoadMarksurfaces(model_t *loadmodel, byte *mod_base, lump_t *l)
{
int i, j, count;
short *in;
@ -837,8 +893,8 @@ Mod_LoadMarksurfaces(lump_t *l)
}
}
void
Mod_LoadSurfedges(lump_t *l)
static void
Mod_LoadSurfedges(model_t *loadmodel, byte *mod_base, lump_t *l)
{
int i, count;
int *in, *out;
@ -870,8 +926,8 @@ Mod_LoadSurfedges(lump_t *l)
}
}
void
Mod_LoadPlanes(lump_t *l)
static void
Mod_LoadPlanes(model_t *loadmodel, byte *mod_base, lump_t *l)
{
int i, j;
cplane_t *out;
@ -933,14 +989,14 @@ static int calcLumpHunkSize(const lump_t *l, int inSize, int outSize)
return size;
}
void
static void
Mod_LoadBrushModel(model_t *mod, void *buffer, int modfilelen)
{
int i;
dheader_t *header;
mmodel_t *bm;
byte *mod_base;
if (loadmodel != mod_known)
if (mod != mod_known)
{
ri.Sys_Error(ERR_DROP, "Loaded a brush model after the world");
}
@ -973,62 +1029,30 @@ Mod_LoadBrushModel(model_t *mod, void *buffer, int modfilelen)
hunkSize += calcLumpHunkSize(&header->lumps[LUMP_SURFEDGES], sizeof(int), sizeof(int));
hunkSize += calcLumpHunkSize(&header->lumps[LUMP_LIGHTING], 1, 1);
hunkSize += calcLumpHunkSize(&header->lumps[LUMP_PLANES], sizeof(dplane_t), sizeof(cplane_t)*2);
hunkSize += calcTexinfoAndFacesSize(&header->lumps[LUMP_FACES], &header->lumps[LUMP_TEXINFO]);
hunkSize += calcTexinfoAndFacesSize(mod_base, &header->lumps[LUMP_FACES], &header->lumps[LUMP_TEXINFO]);
hunkSize += calcLumpHunkSize(&header->lumps[LUMP_LEAFFACES], sizeof(short), sizeof(msurface_t *)); // yes, out is indeeed a pointer!
hunkSize += calcLumpHunkSize(&header->lumps[LUMP_VISIBILITY], 1, 1);
hunkSize += calcLumpHunkSize(&header->lumps[LUMP_LEAFS], sizeof(dleaf_t), sizeof(mleaf_t));
hunkSize += calcLumpHunkSize(&header->lumps[LUMP_NODES], sizeof(dnode_t), sizeof(mnode_t));
hunkSize += calcLumpHunkSize(&header->lumps[LUMP_MODELS], sizeof(dmodel_t), sizeof(mmodel_t));
loadmodel->extradata = Hunk_Begin(hunkSize);
loadmodel->type = mod_brush;
mod->extradata = Hunk_Begin(hunkSize);
mod->type = mod_brush;
/* 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_LoadVertexes(mod, mod_base, &header->lumps[LUMP_VERTEXES]);
Mod_LoadEdges(mod, mod_base, &header->lumps[LUMP_EDGES]);
Mod_LoadSurfedges(mod, mod_base, &header->lumps[LUMP_SURFEDGES]);
Mod_LoadLighting(mod, mod_base, &header->lumps[LUMP_LIGHTING]);
Mod_LoadPlanes(mod, mod_base, &header->lumps[LUMP_PLANES]);
Mod_LoadTexinfo(mod, mod_base, &header->lumps[LUMP_TEXINFO]);
Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES]);
Mod_LoadMarksurfaces(mod, mod_base, &header->lumps[LUMP_LEAFFACES]);
Mod_LoadVisibility(mod, mod_base, &header->lumps[LUMP_VISIBILITY]);
Mod_LoadLeafs(mod, mod_base, &header->lumps[LUMP_LEAFS]);
Mod_LoadNodes(mod, mod_base, &header->lumps[LUMP_NODES]);
Mod_LoadSubmodels (mod, mod_base, &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, "%s: Inline model %i has bad firstnode",
__func__, i);
}
VectorCopy(bm->maxs, starmod->maxs);
VectorCopy(bm->mins, starmod->mins);
starmod->radius = bm->radius;
if (i == 0)
{
*loadmodel = *starmod;
}
starmod->numleafs = bm->visleafs;
}
}
void
@ -1076,7 +1100,7 @@ RI_BeginRegistration(char *model)
Mod_Free(&mod_known[0]);
}
r_worldmodel = Mod_ForName(fullname, true);
r_worldmodel = Mod_ForName(fullname, NULL, true);
r_viewcluster = -1;
}
@ -1089,7 +1113,7 @@ RI_RegisterModel(char *name)
dsprite_t *sprout;
dmdl_t *pheader;
mod = Mod_ForName(name, false);
mod = Mod_ForName(name, r_worldmodel, false);
if (mod)
{
@ -1136,6 +1160,12 @@ RI_EndRegistration(void)
int i;
model_t *mod;
if (Mod_HasFreeSpace() && R_ImageHasFreeSpace())
{
// should be enough space for load next maps
return;
}
for (i = 0, mod = mod_known; i < mod_numknown; i++, mod++)
{
if (!mod->name[0])

View file

@ -45,8 +45,8 @@ void R_BuildLightMap(msurface_t *surf, byte *dest, int stride);
/*
* Returns the proper texture for a given time and base texture
*/
image_t *
R_TextureAnimation(mtexinfo_t *tex)
static image_t *
R_TextureAnimation(entity_t *currententity, mtexinfo_t *tex)
{
int c;
@ -66,7 +66,7 @@ R_TextureAnimation(mtexinfo_t *tex)
return tex->image;
}
void
static void
R_DrawGLPoly(glpoly_t *p)
{
float *v;
@ -84,7 +84,7 @@ R_DrawGLPoly(glpoly_t *p)
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
}
void
static void
R_DrawGLFlowingPoly(msurface_t *fa)
{
int i;
@ -124,7 +124,7 @@ R_DrawGLFlowingPoly(msurface_t *fa)
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
}
void
static void
R_DrawTriangleOutlines(void)
{
int i, j;
@ -179,7 +179,7 @@ R_DrawTriangleOutlines(void)
glEnable(GL_TEXTURE_2D);
}
void
static void
R_DrawGLPolyChain(glpoly_t *p, float soffset, float toffset)
{
if ((soffset == 0) && (toffset == 0))
@ -238,8 +238,8 @@ R_DrawGLPolyChain(glpoly_t *p, float soffset, float toffset)
* This routine takes all the given light mapped surfaces
* in the world and blends them into the framebuffer.
*/
void
R_BlendLightmaps(void)
static void
R_BlendLightmaps(const model_t *currentmodel)
{
int i;
msurface_t *surf, *newdrawsurf = 0;
@ -420,8 +420,8 @@ R_BlendLightmaps(void)
glDepthMask(1);
}
void
R_RenderBrushPoly(msurface_t *fa)
static void
R_RenderBrushPoly(entity_t *currententity, msurface_t *fa)
{
int maps;
image_t *image;
@ -429,7 +429,7 @@ R_RenderBrushPoly(msurface_t *fa)
c_brush_polys++;
image = R_TextureAnimation(fa->texinfo);
image = R_TextureAnimation(currententity, fa->texinfo);
if (fa->flags & SURF_DRAWTURB)
{
@ -604,8 +604,8 @@ R_DrawAlphaSurfaces(void)
r_alpha_surfaces = NULL;
}
void
R_DrawTextureChains(void)
static void
R_DrawTextureChains(entity_t *currententity)
{
int i;
msurface_t *s;
@ -631,7 +631,7 @@ R_DrawTextureChains(void)
for ( ; s; s = s->texturechain)
{
R_RenderBrushPoly(s);
R_RenderBrushPoly(currententity, s);
}
image->texturechain = NULL;
@ -640,8 +640,8 @@ R_DrawTextureChains(void)
R_TexEnv(GL_REPLACE);
}
void
R_DrawInlineBModel(void)
static void
R_DrawInlineBModel(entity_t *currententity, const model_t *currentmodel)
{
int i, k;
cplane_t *pplane;
@ -689,7 +689,7 @@ R_DrawInlineBModel(void)
}
else
{
R_RenderBrushPoly(psurf);
R_RenderBrushPoly(currententity, psurf);
}
}
}
@ -697,7 +697,7 @@ R_DrawInlineBModel(void)
if (!(currententity->flags & RF_TRANSLUCENT))
{
R_BlendLightmaps();
R_BlendLightmaps(currentmodel);
}
else
{
@ -708,7 +708,7 @@ R_DrawInlineBModel(void)
}
void
R_DrawBrushModel(entity_t *e)
R_DrawBrushModel(entity_t *currententity, const model_t *currentmodel)
{
vec3_t mins, maxs;
int i;
@ -719,24 +719,23 @@ R_DrawBrushModel(entity_t *e)
return;
}
currententity = e;
gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;
if (e->angles[0] || e->angles[1] || e->angles[2])
if (currententity->angles[0] || currententity->angles[1] || currententity->angles[2])
{
rotated = true;
for (i = 0; i < 3; i++)
{
mins[i] = e->origin[i] - currentmodel->radius;
maxs[i] = e->origin[i] + currentmodel->radius;
mins[i] = currententity->origin[i] - currentmodel->radius;
maxs[i] = currententity->origin[i] + currentmodel->radius;
}
}
else
{
rotated = false;
VectorAdd(e->origin, currentmodel->mins, mins);
VectorAdd(e->origin, currentmodel->maxs, maxs);
VectorAdd(currententity->origin, currentmodel->mins, mins);
VectorAdd(currententity->origin, currentmodel->maxs, maxs);
}
if (R_CullBox(mins, maxs))
@ -752,7 +751,7 @@ R_DrawBrushModel(entity_t *e)
glColor4f(1, 1, 1, 1);
memset(gl_lms.lightmap_surfaces, 0, sizeof(gl_lms.lightmap_surfaces));
VectorSubtract(r_newrefdef.vieworg, e->origin, modelorg);
VectorSubtract(r_newrefdef.vieworg, currententity->origin, modelorg);
if (rotated)
{
@ -760,18 +759,18 @@ R_DrawBrushModel(entity_t *e)
vec3_t forward, right, up;
VectorCopy(modelorg, temp);
AngleVectors(e->angles, forward, right, up);
AngleVectors(currententity->angles, forward, right, up);
modelorg[0] = DotProduct(temp, forward);
modelorg[1] = -DotProduct(temp, right);
modelorg[2] = DotProduct(temp, up);
}
glPushMatrix();
e->angles[0] = -e->angles[0];
e->angles[2] = -e->angles[2];
R_RotateForEntity(e);
e->angles[0] = -e->angles[0];
e->angles[2] = -e->angles[2];
currententity->angles[0] = -currententity->angles[0];
currententity->angles[2] = -currententity->angles[2];
R_RotateForEntity(currententity);
currententity->angles[0] = -currententity->angles[0];
currententity->angles[2] = -currententity->angles[2];
R_TexEnv(GL_REPLACE);
@ -784,7 +783,7 @@ R_DrawBrushModel(entity_t *e)
R_TexEnv(GL_MODULATE);
}
R_DrawInlineBModel();
R_DrawInlineBModel(currententity, currentmodel);
glPopMatrix();
@ -794,8 +793,8 @@ R_DrawBrushModel(entity_t *e)
}
}
void
R_RecursiveWorldNode(mnode_t *node)
static void
R_RecursiveWorldNode(entity_t *currententity, mnode_t *node)
{
int c, side, sidebit;
cplane_t *plane;
@ -881,7 +880,7 @@ R_RecursiveWorldNode(mnode_t *node)
}
/* recurse down the children, front side first */
R_RecursiveWorldNode(node->children[side]);
R_RecursiveWorldNode(currententity, node->children[side]);
/* draw stuff */
for (c = node->numsurfaces,
@ -908,25 +907,26 @@ R_RecursiveWorldNode(mnode_t *node)
/* add to the translucent chain */
surf->texturechain = r_alpha_surfaces;
r_alpha_surfaces = surf;
r_alpha_surfaces->texinfo->image = R_TextureAnimation(surf->texinfo);
r_alpha_surfaces->texinfo->image = R_TextureAnimation(currententity, surf->texinfo);
}
else
{
/* the polygon is visible, so add it to the texture sorted chain */
image = R_TextureAnimation(surf->texinfo);
image = R_TextureAnimation(currententity, surf->texinfo);
surf->texturechain = image->texturechain;
image->texturechain = surf;
}
}
/* recurse down the back side */
R_RecursiveWorldNode(node->children[!side]);
R_RecursiveWorldNode(currententity, node->children[!side]);
}
void
R_DrawWorld(void)
{
entity_t ent;
const model_t *currentmodel;
if (!r_drawworld->value)
{
@ -945,7 +945,6 @@ R_DrawWorld(void)
/* auto cycle the world frame for texture animation */
memset(&ent, 0, sizeof(ent));
ent.frame = (int)(r_newrefdef.time * 2);
currententity = &ent;
gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;
@ -953,13 +952,11 @@ R_DrawWorld(void)
memset(gl_lms.lightmap_surfaces, 0, sizeof(gl_lms.lightmap_surfaces));
R_ClearSkyBox();
R_RecursiveWorldNode(r_worldmodel->nodes);
R_DrawTextureChains();
R_BlendLightmaps();
R_RecursiveWorldNode(&ent, r_worldmodel->nodes);
R_DrawTextureChains(&ent);
R_BlendLightmaps(currentmodel);
R_DrawSkyBox();
R_DrawTriangleOutlines();
currententity = NULL;
}
/*
@ -969,7 +966,7 @@ R_DrawWorld(void)
void
R_MarkLeaves(void)
{
byte *vis;
const byte *vis;
YQ2_ALIGNAS_TYPE(int) byte fatvis[MAX_MAP_LEAFS / 8];
mnode_t *node;
int i, c;

View file

@ -31,19 +31,18 @@
#define ON_EPSILON 0.1 /* point on plane side epsilon */
#define MAX_CLIP_VERTS 64
extern model_t *loadmodel;
char skyname[MAX_QPATH];
float skyrotate;
vec3_t skyaxis;
image_t *sky_images[6];
msurface_t *warpface;
int skytexorder[6] = {0, 2, 1, 3, 4, 5};
GLfloat vtx_sky[12];
GLfloat tex_sky[8];
unsigned int index_vtx = 0;
unsigned int index_tex = 0;
/* 3dstudio environment map names */
char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
@ -243,7 +242,7 @@ R_SubdividePolygon(int numverts, float *verts)
* can be done reasonably.
*/
void
R_SubdivideSurface(msurface_t *fa)
R_SubdivideSurface(model_t *loadmodel, msurface_t *fa)
{
vec3_t verts[64];
int numverts;

View file

@ -145,8 +145,6 @@ extern int numgltextures;
extern image_t *r_notexture;
extern image_t *r_particletexture;
extern entity_t *currententity;
extern model_t *currentmodel;
extern int r_visframecount;
extern int r_framecount;
extern cplane_t frustum[4];
@ -193,7 +191,8 @@ extern cvar_t *r_mode;
extern cvar_t *r_customwidth;
extern cvar_t *r_customheight;
extern cvar_t *gl_retexturing;
extern cvar_t *r_retexturing;
extern cvar_t *r_scale8bittextures;
extern cvar_t *gl_nolerp_list;
@ -244,7 +243,7 @@ void R_Bind(int texnum);
void R_TexEnv(GLenum value);
void R_LightPoint(vec3_t p, vec3_t color);
void R_LightPoint(entity_t *currententity, vec3_t p, vec3_t color);
void R_PushDlights(void);
extern model_t *r_worldmodel;
@ -253,19 +252,17 @@ extern int registration_sequence;
void V_AddBlend(float r, float g, float b, float a, float *v_blend);
void R_RenderView(refdef_t *fd);
void R_ScreenShot(void);
void R_DrawAliasModel(entity_t *e);
void R_DrawBrushModel(entity_t *e);
void R_DrawSpriteModel(entity_t *e);
void R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel);
void R_DrawBrushModel(entity_t *currententity, const model_t *currentmodel);
void R_DrawSpriteModel(entity_t *currententity, const model_t *currentmodel);
void R_DrawBeam(entity_t *e);
void R_DrawWorld(void);
void R_RenderDlights(void);
void R_DrawAlphaSurfaces(void);
void R_RenderBrushPoly(msurface_t *fa);
void R_InitParticleTexture(void);
void Draw_InitLocal(void);
void R_SubdivideSurface(msurface_t *fa);
void R_SubdivideSurface(model_t *loadmodel, msurface_t *fa);
qboolean R_CullBox(vec3_t mins, vec3_t maxs);
void R_RotateForEntity(entity_t *e);
void R_MarkLeaves(void);
@ -295,6 +292,7 @@ void R_InitImages(void);
void R_ShutdownImages(void);
void R_FreeUnusedImages(void);
qboolean R_ImageHasFreeSpace(void);
void R_TextureAlphaMode(char *string);
void R_TextureSolidMode(char *string);

View file

@ -172,7 +172,7 @@ typedef struct model_s
int lightmap; /* only for submodels */
int numsubmodels;
mmodel_t *submodels;
struct model_s *submodels;
int numplanes;
cplane_t *planes;
@ -211,13 +211,15 @@ typedef struct model_s
int extradatasize;
void *extradata;
// submodules
vec3_t origin; // for sounds or lights
} model_t;
void Mod_Init(void);
void Mod_ClearAll(void);
model_t *Mod_ForName(char *name, qboolean crash);
mleaf_t *Mod_PointInLeaf(vec3_t p, model_t *model);
byte *Mod_ClusterPVS(int cluster, model_t *model);
const byte *Mod_ClusterPVS(int cluster, const model_t *model);
void Mod_Modellist_f(void);

View file

@ -46,7 +46,8 @@ int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST;
int gl_filter_max = GL_LINEAR;
gl3image_t gl3textures[MAX_GL3TEXTURES];
int numgl3textures;
int numgl3textures = 0;
static int image_max = 0;
void
GL3_TextureMode(char *string)
@ -225,7 +226,7 @@ GL3_Upload32(unsigned *data, int width, int height, qboolean mipmap)
qboolean
GL3_Upload8(byte *data, int width, int height, qboolean mipmap, qboolean is_sky)
{
unsigned trans[512 * 256];
unsigned trans[1024 * 1024];
int i, s;
int p;
@ -233,7 +234,7 @@ GL3_Upload8(byte *data, int width, int height, qboolean mipmap, qboolean is_sky)
if (s > sizeof(trans) / 4)
{
ri.Sys_Error(ERR_DROP, "GL3_Upload8: too large");
ri.Sys_Error(ERR_DROP, "%s: too large", __func__);
}
for (i = 0; i < s; i++)
@ -429,9 +430,22 @@ GL3_LoadPic(char *name, byte *pic, int width, int realwidth,
if (bits == 8)
{
image->has_alpha = GL3_Upload8(pic, width, height,
(image->type != it_pic && image->type != it_sky),
image->type == it_sky);
// resize 8bit images only when we forced such logic
if (r_scale8bittextures->value)
{
byte *image_converted = malloc(width * height * 4);
scale2x(pic, image_converted, width, height);
image->has_alpha = GL3_Upload8(image_converted, width * 2, height * 2,
(image->type != it_pic && image->type != it_sky),
image->type == it_sky);
free(image_converted);
}
else
{
image->has_alpha = GL3_Upload8(pic, width, height,
(image->type != it_pic && image->type != it_sky),
image->type == it_sky);
}
}
else
{
@ -732,7 +746,7 @@ GL3_FindImage(char *name, imagetype_t type)
if (strcmp(ext, "pcx") == 0)
{
if (gl_retexturing->value)
if (r_retexturing->value)
{
GetPCXInfo(name, &realwidth, &realheight);
if(realwidth == 0)
@ -779,7 +793,7 @@ GL3_FindImage(char *name, imagetype_t type)
}
else if (strcmp(ext, "wal") == 0 || strcmp(ext, "m8") == 0)
{
if (gl_retexturing->value)
if (r_retexturing->value)
{
/* Get size of the original texture */
if (strcmp(ext, "m8") == 0)
@ -935,6 +949,33 @@ GL3_FreeUnusedImages(void)
}
}
qboolean
GL3_ImageHasFreeSpace(void)
{
int i, used;
gl3image_t *image;
used = 0;
for (i = 0, image = gl3textures; i < numgl3textures; i++, image++)
{
if (!image->name[0])
continue;
if (image->registration_sequence == registration_sequence)
{
used ++;
}
}
if (image_max < used)
{
image_max = used;
}
// should same size of free slots as currently used
return (numgl3textures + used) < MAX_GL3TEXTURES;
}
void
GL3_ShutdownImages(void)
{
@ -973,7 +1014,8 @@ static qboolean IsNPOT(int v)
void
GL3_ImageList_f(void)
{
int i, texels=0;
int i, used, texels;
qboolean freeup;
gl3image_t *image;
const char *formatstrings[2] = {
"RGB ",
@ -985,15 +1027,25 @@ GL3_ImageList_f(void)
};
R_Printf(PRINT_ALL, "------------------\n");
texels = 0;
used = 0;
for (i = 0, image = gl3textures; i < numgl3textures; i++, image++)
{
int w, h;
char *in_use = "";
qboolean isNPOT = false;
if (image->texnum == 0)
{
continue;
}
if (image->registration_sequence == registration_sequence)
{
in_use = "*";
used++;
}
w = image->width;
h = image->height;
@ -1023,9 +1075,11 @@ GL3_ImageList_f(void)
break;
}
R_Printf(PRINT_ALL, " %3i %3i %s %s: %s\n", w, h,
formatstrings[image->has_alpha], potstrings[isNPOT], image->name);
R_Printf(PRINT_ALL, " %3i %3i %s %s: %s %s\n", w, h,
formatstrings[image->has_alpha], potstrings[isNPOT], image->name, in_use);
}
R_Printf(PRINT_ALL, "Total texel count (not counting mipmaps): %i\n", texels);
freeup = GL3_ImageHasFreeSpace();
R_Printf(PRINT_ALL, "Used %d of %d images%s.\n", used, image_max, freeup ? ", has free space" : "");
}

View file

@ -252,7 +252,7 @@ RecursiveLightPoint(mnode_t *node, vec3_t start, vec3_t end)
}
void
GL3_LightPoint(vec3_t p, vec3_t color)
GL3_LightPoint(entity_t *currententity, vec3_t p, vec3_t color)
{
vec3_t end;
float r;

View file

@ -118,7 +118,7 @@ GL3_LM_AllocBlock(int w, int h, int *x, int *y)
}
void
GL3_LM_BuildPolygonFromSurface(msurface_t *fa)
GL3_LM_BuildPolygonFromSurface(gl3model_t *currentmodel, msurface_t *fa)
{
int i, lindex, lnumverts;
medge_t *pedges, *r_pedge;

View file

@ -50,8 +50,6 @@ refdef_t gl3_newrefdef;
viddef_t vid;
gl3model_t *gl3_worldmodel;
gl3model_t *currentmodel;
entity_t *currententity;
float gl3depthmin=0.0f, gl3depthmax=1.0f;
@ -81,7 +79,8 @@ const hmm_mat4 gl3_identityMat4 = {{
cvar_t *gl_msaa_samples;
cvar_t *r_vsync;
cvar_t *gl_retexturing;
cvar_t *r_retexturing;
cvar_t *r_scale8bittextures;
cvar_t *vid_fullscreen;
cvar_t *r_mode;
cvar_t *r_customwidth;
@ -199,7 +198,8 @@ GL3_Register(void)
gl_drawbuffer = ri.Cvar_Get("gl_drawbuffer", "GL_BACK", 0);
r_vsync = ri.Cvar_Get("r_vsync", "1", CVAR_ARCHIVE);
gl_msaa_samples = ri.Cvar_Get ( "r_msaa_samples", "0", CVAR_ARCHIVE );
gl_retexturing = ri.Cvar_Get("r_retexturing", "1", CVAR_ARCHIVE);
r_retexturing = ri.Cvar_Get("r_retexturing", "1", CVAR_ARCHIVE);
r_scale8bittextures = ri.Cvar_Get("r_scale8bittextures", "0", CVAR_ARCHIVE);
gl3_debugcontext = ri.Cvar_Get("gl3_debugcontext", "0", 0);
r_mode = ri.Cvar_Get("r_mode", "4", CVAR_ARCHIVE);
r_customwidth = ri.Cvar_Get("r_customwidth", "1024", CVAR_ARCHIVE);
@ -301,7 +301,7 @@ GL3_Register(void)
//r_customheight = ri.Cvar_Get("r_customheight", "768", CVAR_ARCHIVE);
//gl_msaa_samples = ri.Cvar_Get ( "r_msaa_samples", "0", CVAR_ARCHIVE );
//gl_retexturing = ri.Cvar_Get("r_retexturing", "1", CVAR_ARCHIVE);
//r_retexturing = ri.Cvar_Get("r_retexturing", "1", CVAR_ARCHIVE);
gl1_stereo = ri.Cvar_Get( "gl1_stereo", "0", CVAR_ARCHIVE );
@ -773,7 +773,7 @@ GL3_DrawBeam(entity_t *e)
}
static void
GL3_DrawSpriteModel(entity_t *e)
GL3_DrawSpriteModel(entity_t *e, gl3model_t *currentmodel)
{
float alpha = 1.0F;
gl3_3D_vtx_t verts[4];
@ -852,7 +852,7 @@ GL3_DrawSpriteModel(entity_t *e)
}
static void
GL3_DrawNullModel(void)
GL3_DrawNullModel(entity_t *currententity)
{
vec3_t shadelight;
@ -862,7 +862,7 @@ GL3_DrawNullModel(void)
}
else
{
GL3_LightPoint(currententity->origin, shadelight);
GL3_LightPoint(currententity, currententity->origin, shadelight);
}
hmm_mat4 origModelMat = gl3state.uni3DData.transModelMat4;
@ -977,7 +977,7 @@ GL3_DrawEntitiesOnList(void)
/* draw non-transparent first */
for (i = 0; i < gl3_newrefdef.num_entities; i++)
{
currententity = &gl3_newrefdef.entities[i];
entity_t *currententity = &gl3_newrefdef.entities[i];
if (currententity->flags & RF_TRANSLUCENT)
{
@ -990,11 +990,11 @@ GL3_DrawEntitiesOnList(void)
}
else
{
currentmodel = currententity->model;
gl3model_t *currentmodel = currententity->model;
if (!currentmodel)
{
GL3_DrawNullModel();
GL3_DrawNullModel(currententity);
continue;
}
@ -1004,10 +1004,10 @@ GL3_DrawEntitiesOnList(void)
GL3_DrawAliasModel(currententity);
break;
case mod_brush:
GL3_DrawBrushModel(currententity);
GL3_DrawBrushModel(currententity, currentmodel);
break;
case mod_sprite:
GL3_DrawSpriteModel(currententity);
GL3_DrawSpriteModel(currententity, currentmodel);
break;
default:
ri.Sys_Error(ERR_DROP, "Bad modeltype");
@ -1023,7 +1023,7 @@ GL3_DrawEntitiesOnList(void)
for (i = 0; i < gl3_newrefdef.num_entities; i++)
{
currententity = &gl3_newrefdef.entities[i];
entity_t *currententity = &gl3_newrefdef.entities[i];
if (!(currententity->flags & RF_TRANSLUCENT))
{
@ -1036,11 +1036,11 @@ GL3_DrawEntitiesOnList(void)
}
else
{
currentmodel = currententity->model;
gl3model_t *currentmodel = currententity->model;
if (!currentmodel)
{
GL3_DrawNullModel();
GL3_DrawNullModel(currententity);
continue;
}
@ -1050,10 +1050,10 @@ GL3_DrawEntitiesOnList(void)
GL3_DrawAliasModel(currententity);
break;
case mod_brush:
GL3_DrawBrushModel(currententity);
GL3_DrawBrushModel(currententity, currentmodel);
break;
case mod_sprite:
GL3_DrawSpriteModel(currententity);
GL3_DrawSpriteModel(currententity, currentmodel);
break;
default:
ri.Sys_Error(ERR_DROP, "Bad modeltype");
@ -1580,7 +1580,7 @@ GL3_GetSpecialBufferModeForStereoMode(enum stereo_modes stereo_mode) {
#endif // 0
static void
GL3_SetLightLevel(void)
GL3_SetLightLevel(entity_t *currententity)
{
vec3_t shadelight = {0};
@ -1590,7 +1590,7 @@ GL3_SetLightLevel(void)
}
/* save off light value for server to look at */
GL3_LightPoint(gl3_newrefdef.vieworg, shadelight);
GL3_LightPoint(currententity, gl3_newrefdef.vieworg, shadelight);
/* pick the greatest component, which should be the
* same as the mono value returned by software */
@ -1622,7 +1622,7 @@ static void
GL3_RenderFrame(refdef_t *fd)
{
GL3_RenderView(fd);
GL3_SetLightLevel();
GL3_SetLightLevel(NULL);
GL3_SetGL2D();
if(v_blend[3] != 0.0f)

View file

@ -711,7 +711,7 @@ GL3_DrawAliasModel(entity_t *entity)
}
else
{
GL3_LightPoint(entity->origin, shadelight);
GL3_LightPoint(entity, entity->origin, shadelight);
/* player lighting hack for communication back to server */
if (entity->flags & RF_WEAPONMODEL)

View file

@ -29,15 +29,40 @@
enum { MAX_MOD_KNOWN = 512 };
static gl3model_t *loadmodel;
YQ2_ALIGNAS_TYPE(int) static byte mod_novis[MAX_MAP_LEAFS / 8];
gl3model_t mod_known[MAX_MOD_KNOWN];
static int mod_numknown;
static int mod_max = 0;
int registration_sequence;
static byte *mod_base;
/* the inline * models from the current map are kept seperate */
gl3model_t mod_inline[MAX_MOD_KNOWN];
//===============================================================================
static qboolean
Mod_HasFreeSpace(void)
{
int i, used;
gl3model_t *mod;
used = 0;
for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++)
{
if (!mod->name[0])
continue;
if (mod->registration_sequence == registration_sequence)
{
used ++;
}
}
if (mod_max < used)
{
mod_max = used;
}
// should same size of free slots as currently used
return (mod_numknown + mod_max) < MAX_MOD_KNOWN;
}
mleaf_t *
GL3_Mod_PointInLeaf(vec3_t p, gl3model_t *model)
@ -76,8 +101,8 @@ GL3_Mod_PointInLeaf(vec3_t p, gl3model_t *model)
return NULL; /* never reached */
}
byte*
GL3_Mod_ClusterPVS(int cluster, gl3model_t *model)
const byte*
GL3_Mod_ClusterPVS(int cluster, const gl3model_t *model)
{
if ((cluster == -1) || !model->vis)
{
@ -92,35 +117,49 @@ GL3_Mod_ClusterPVS(int cluster, gl3model_t *model)
void
GL3_Mod_Modellist_f(void)
{
int i;
int i, total, used;
gl3model_t *mod;
int total;
qboolean freeup;
total = 0;
used = 0;
R_Printf(PRINT_ALL, "Loaded models:\n");
for (i = 0, mod = mod_known; i < mod_numknown; i++, mod++)
{
char *in_use = "";
if (mod->registration_sequence == registration_sequence)
{
in_use = "*";
used ++;
}
if (!mod->name[0])
{
continue;
}
R_Printf(PRINT_ALL, "%8i : %s\n", mod->extradatasize, mod->name);
R_Printf(PRINT_ALL, "%8i : %s %s\n",
mod->extradatasize, mod->name, in_use);
total += mod->extradatasize;
}
R_Printf(PRINT_ALL, "Total resident: %i\n", total);
// update statistics
freeup = Mod_HasFreeSpace();
R_Printf(PRINT_ALL, "Used %d of %d models%s.\n", used, mod_max, freeup ? ", has free space" : "");
}
void
GL3_Mod_Init(void)
{
mod_max = 0;
memset(mod_novis, 0xff, sizeof(mod_novis));
}
static void
Mod_LoadLighting(lump_t *l)
Mod_LoadLighting(gl3model_t *loadmodel, byte *mod_base, lump_t *l)
{
if (!l->filelen)
{
@ -133,7 +172,7 @@ Mod_LoadLighting(lump_t *l)
}
static void
Mod_LoadVisibility(lump_t *l)
Mod_LoadVisibility(gl3model_t *loadmodel, byte *mod_base, lump_t *l)
{
int i;
@ -156,7 +195,7 @@ Mod_LoadVisibility(lump_t *l)
}
static void
Mod_LoadVertexes(lump_t *l)
Mod_LoadVertexes(gl3model_t *loadmodel, byte *mod_base, lump_t *l)
{
dvertex_t *in;
mvertex_t *out;
@ -185,10 +224,10 @@ Mod_LoadVertexes(lump_t *l)
}
static void
Mod_LoadSubmodels(lump_t *l)
Mod_LoadSubmodels(gl3model_t *loadmodel, byte *mod_base, lump_t *l)
{
dmodel_t *in;
mmodel_t *out;
gl3model_t *out;
int i, j, count;
in = (void *)(mod_base + l->fileofs);
@ -207,6 +246,19 @@ Mod_LoadSubmodels(lump_t *l)
for (i = 0; i < count; i++, in++, out++)
{
if (i == 0)
{
// copy parent as template for first model
memcpy(out, loadmodel, sizeof(*out));
}
else
{
// copy first as template for model
memcpy(out, loadmodel->submodels, sizeof(*out));
}
Com_sprintf (out->name, sizeof(out->name), "*%d", i);
for (j = 0; j < 3; j++)
{
/* spread the mins / maxs by a pixel */
@ -216,14 +268,22 @@ Mod_LoadSubmodels(lump_t *l)
}
out->radius = Mod_RadiusFromBounds(out->mins, out->maxs);
out->headnode = LittleLong(in->headnode);
out->firstface = LittleLong(in->firstface);
out->numfaces = LittleLong(in->numfaces);
out->firstnode = LittleLong(in->headnode);
out->firstmodelsurface = LittleLong(in->firstface);
out->nummodelsurfaces = LittleLong(in->numfaces);
// visleafs
out->numleafs = 0;
// check limits
if (out->firstnode >= loadmodel->numnodes)
{
ri.Sys_Error(ERR_DROP, "%s: Inline model %i has bad firstnode",
__func__, i);
}
}
}
static void
Mod_LoadEdges(lump_t *l)
Mod_LoadEdges(gl3model_t *loadmodel, byte *mod_base, lump_t *l)
{
dedge_t *in;
medge_t *out;
@ -251,7 +311,7 @@ Mod_LoadEdges(lump_t *l)
}
static void
Mod_LoadTexinfo(lump_t *l)
Mod_LoadTexinfo(gl3model_t *loadmodel, byte *mod_base, lump_t *l)
{
texinfo_t *in;
mtexinfo_t *out, *step;
@ -327,7 +387,7 @@ Mod_LoadTexinfo(lump_t *l)
* Fills in s->texturemins[] and s->extents[]
*/
static void
Mod_CalcSurfaceExtents(msurface_t *s)
Mod_CalcSurfaceExtents(gl3model_t *loadmodel, msurface_t *s)
{
float mins[2], maxs[2], val;
int i, j, e;
@ -385,7 +445,7 @@ Mod_CalcSurfaceExtents(msurface_t *s)
extern void
GL3_SubdivideSurface(msurface_t *fa, gl3model_t* loadmodel);
static int calcTexinfoAndFacesSize(const lump_t *fl, const lump_t *tl)
static int calcTexinfoAndFacesSize(byte *mod_base, const lump_t *fl, const lump_t *tl)
{
dface_t* face_in = (void *)(mod_base + fl->fileofs);
texinfo_t* texinfo_in = (void *)(mod_base + tl->fileofs);
@ -461,7 +521,7 @@ static int calcTexinfoAndFacesSize(const lump_t *fl, const lump_t *tl)
}
static void
Mod_LoadFaces(lump_t *l)
Mod_LoadFaces(gl3model_t *loadmodel, byte *mod_base, lump_t *l)
{
dface_t *in;
msurface_t *out;
@ -483,8 +543,6 @@ Mod_LoadFaces(lump_t *l)
loadmodel->surfaces = out;
loadmodel->numsurfaces = count;
currentmodel = loadmodel;
GL3_LM_BeginBuildingLightmaps(loadmodel);
for (surfnum = 0; surfnum < count; surfnum++, in++, out++)
@ -514,7 +572,7 @@ Mod_LoadFaces(lump_t *l)
out->texinfo = loadmodel->texinfo + ti;
Mod_CalcSurfaceExtents(out);
Mod_CalcSurfaceExtents(loadmodel, out);
/* lighting info */
for (i = 0; i < MAX_LIGHTMAPS_PER_SURFACE; i++)
@ -563,7 +621,7 @@ Mod_LoadFaces(lump_t *l)
if (!(out->texinfo->flags & SURF_WARP))
{
GL3_LM_BuildPolygonFromSurface(out);
GL3_LM_BuildPolygonFromSurface(loadmodel, out);
}
}
@ -585,7 +643,7 @@ Mod_SetParent(mnode_t *node, mnode_t *parent)
}
static void
Mod_LoadNodes(lump_t *l)
Mod_LoadNodes(gl3model_t *loadmodel, byte *mod_base, lump_t *l)
{
int i, j, count, p;
dnode_t *in;
@ -639,7 +697,7 @@ Mod_LoadNodes(lump_t *l)
}
static void
Mod_LoadLeafs(lump_t *l)
Mod_LoadLeafs(gl3model_t *loadmodel, byte *mod_base, lump_t *l)
{
dleaf_t *in;
mleaf_t *out;
@ -689,7 +747,7 @@ Mod_LoadLeafs(lump_t *l)
}
static void
Mod_LoadMarksurfaces(lump_t *l)
Mod_LoadMarksurfaces(gl3model_t *loadmodel, byte *mod_base, lump_t *l)
{
int i, j, count;
short *in;
@ -723,7 +781,7 @@ Mod_LoadMarksurfaces(lump_t *l)
}
static void
Mod_LoadSurfedges(lump_t *l)
Mod_LoadSurfedges(gl3model_t *loadmodel, byte *mod_base, lump_t *l)
{
int i, count;
int *in, *out;
@ -756,7 +814,7 @@ Mod_LoadSurfedges(lump_t *l)
}
static void
Mod_LoadPlanes(lump_t *l)
Mod_LoadPlanes(gl3model_t *loadmodel, byte *mod_base, lump_t *l)
{
int i, j;
cplane_t *out;
@ -823,9 +881,9 @@ Mod_LoadBrushModel(gl3model_t *mod, void *buffer, int modfilelen)
{
int i;
dheader_t *header;
mmodel_t *bm;
byte *mod_base;
if (loadmodel != mod_known)
if (mod != mod_known)
{
ri.Sys_Error(ERR_DROP, "Loaded a brush model after the world");
}
@ -858,62 +916,30 @@ Mod_LoadBrushModel(gl3model_t *mod, void *buffer, int modfilelen)
hunkSize += calcLumpHunkSize(&header->lumps[LUMP_SURFEDGES], sizeof(int), sizeof(int));
hunkSize += calcLumpHunkSize(&header->lumps[LUMP_LIGHTING], 1, 1);
hunkSize += calcLumpHunkSize(&header->lumps[LUMP_PLANES], sizeof(dplane_t), sizeof(cplane_t)*2);
hunkSize += calcTexinfoAndFacesSize(&header->lumps[LUMP_FACES], &header->lumps[LUMP_TEXINFO]);
hunkSize += calcTexinfoAndFacesSize(mod_base, &header->lumps[LUMP_FACES], &header->lumps[LUMP_TEXINFO]);
hunkSize += calcLumpHunkSize(&header->lumps[LUMP_LEAFFACES], sizeof(short), sizeof(msurface_t *)); // yes, out is indeeed a pointer!
hunkSize += calcLumpHunkSize(&header->lumps[LUMP_VISIBILITY], 1, 1);
hunkSize += calcLumpHunkSize(&header->lumps[LUMP_LEAFS], sizeof(dleaf_t), sizeof(mleaf_t));
hunkSize += calcLumpHunkSize(&header->lumps[LUMP_NODES], sizeof(dnode_t), sizeof(mnode_t));
hunkSize += calcLumpHunkSize(&header->lumps[LUMP_MODELS], sizeof(dmodel_t), sizeof(mmodel_t));
loadmodel->extradata = Hunk_Begin(hunkSize);
loadmodel->type = mod_brush;
mod->extradata = Hunk_Begin(hunkSize);
mod->type = mod_brush;
/* 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_LoadVertexes(mod, mod_base, &header->lumps[LUMP_VERTEXES]);
Mod_LoadEdges(mod, mod_base, &header->lumps[LUMP_EDGES]);
Mod_LoadSurfedges(mod, mod_base, &header->lumps[LUMP_SURFEDGES]);
Mod_LoadLighting(mod, mod_base, &header->lumps[LUMP_LIGHTING]);
Mod_LoadPlanes(mod, mod_base, &header->lumps[LUMP_PLANES]);
Mod_LoadTexinfo(mod, mod_base, &header->lumps[LUMP_TEXINFO]);
Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES]);
Mod_LoadMarksurfaces(mod, mod_base, &header->lumps[LUMP_LEAFFACES]);
Mod_LoadVisibility(mod, mod_base, &header->lumps[LUMP_VISIBILITY]);
Mod_LoadLeafs(mod, mod_base, &header->lumps[LUMP_LEAFS]);
Mod_LoadNodes(mod, mod_base, &header->lumps[LUMP_NODES]);
Mod_LoadSubmodels (mod, mod_base, &header->lumps[LUMP_MODELS]);
mod->numframes = 2; /* regular and alternate animation */
/* set up the submodels */
for (i = 0; i < mod->numsubmodels; i++)
{
gl3model_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, "%s: Inline model %i has bad firstnode",
__func__, i);
}
VectorCopy(bm->maxs, starmod->maxs);
VectorCopy(bm->mins, starmod->mins);
starmod->radius = bm->radius;
if (i == 0)
{
*loadmodel = *starmod;
}
starmod->numleafs = bm->visleafs;
}
}
static void
@ -944,7 +970,7 @@ extern void GL3_LoadSP2(gl3model_t *mod, void *buffer, int modfilelen);
* Loads in a model for the given name
*/
static gl3model_t *
Mod_ForName(char *name, qboolean crash)
Mod_ForName (char *name, gl3model_t *parent_model, qboolean crash)
{
gl3model_t *mod;
unsigned *buf;
@ -956,17 +982,17 @@ Mod_ForName(char *name, qboolean crash)
}
/* inline models are grabbed only from worldmodel */
if (name[0] == '*')
if (name[0] == '*' && parent_model)
{
i = (int)strtol(name + 1, (char **)NULL, 10);
if ((i < 1) || !gl3_worldmodel || (i >= gl3_worldmodel->numsubmodels))
if (i < 1 || i >= parent_model->numsubmodels)
{
ri.Sys_Error(ERR_DROP, "%s: bad inline model number",
__func__);
}
return &mod_inline[i];
return &parent_model->submodels[i];
}
/* search the currently loaded models */
@ -1019,8 +1045,6 @@ Mod_ForName(char *name, qboolean crash)
return NULL;
}
loadmodel = mod;
/* call the apropriate loader */
switch (LittleLong(*(unsigned *)buf))
{
@ -1042,7 +1066,7 @@ Mod_ForName(char *name, qboolean crash)
break;
}
loadmodel->extradatasize = Hunk_End();
mod->extradatasize = Hunk_End();
ri.FS_FreeFile(buf);
@ -1075,7 +1099,7 @@ GL3_BeginRegistration(char *model)
Mod_Free(&mod_known[0]);
}
gl3_worldmodel = Mod_ForName(fullname, true);
gl3_worldmodel = Mod_ForName(fullname, NULL, true);
gl3_viewcluster = -1;
}
@ -1088,7 +1112,7 @@ GL3_RegisterModel(char *name)
dsprite_t *sprout;
dmdl_t *pheader;
mod = Mod_ForName(name, false);
mod = Mod_ForName(name, gl3_worldmodel, false);
if (mod)
{
@ -1133,6 +1157,12 @@ GL3_EndRegistration(void)
int i;
gl3model_t *mod;
if (Mod_HasFreeSpace() && GL3_ImageHasFreeSpace())
{
// should be enough space for load next maps
return;
}
for (i = 0, mod = mod_known; i < mod_numknown; i++, mod++)
{
if (!mod->name[0])

View file

@ -159,7 +159,7 @@ CullBox(vec3_t mins, vec3_t maxs)
* Returns the proper texture for a given time and base texture
*/
static gl3image_t *
TextureAnimation(mtexinfo_t *tex)
TextureAnimation(entity_t *currententity, mtexinfo_t *tex)
{
int c;
@ -337,14 +337,14 @@ UpdateLMscales(const hmm_vec4 lmScales[MAX_LIGHTMAPS_PER_SURFACE], gl3ShaderInfo
}
static void
RenderBrushPoly(msurface_t *fa)
RenderBrushPoly(entity_t *currententity, msurface_t *fa)
{
int map;
gl3image_t *image;
c_brush_polys++;
image = TextureAnimation(fa->texinfo);
image = TextureAnimation(currententity, fa->texinfo);
if (fa->flags & SURF_DRAWTURB)
{
@ -449,7 +449,7 @@ GL3_DrawAlphaSurfaces(void)
}
static void
DrawTextureChains(void)
DrawTextureChains(entity_t *currententity)
{
int i;
msurface_t *s;
@ -476,7 +476,7 @@ DrawTextureChains(void)
for ( ; s; s = s->texturechain)
{
SetLightFlags(s);
RenderBrushPoly(s);
RenderBrushPoly(currententity, s);
}
image->texturechain = NULL;
@ -486,10 +486,10 @@ DrawTextureChains(void)
}
static void
RenderLightmappedPoly(msurface_t *surf)
RenderLightmappedPoly(entity_t *currententity, msurface_t *surf)
{
int map;
gl3image_t *image = TextureAnimation(surf->texinfo);
gl3image_t *image = TextureAnimation(currententity, surf->texinfo);
hmm_vec4 lmScales[MAX_LIGHTMAPS_PER_SURFACE] = {0};
lmScales[0] = HMM_Vec4(1.0f, 1.0f, 1.0f, 1.0f);
@ -526,7 +526,7 @@ RenderLightmappedPoly(msurface_t *surf)
}
static void
DrawInlineBModel(void)
DrawInlineBModel(entity_t *currententity, gl3model_t *currentmodel)
{
int i, k;
cplane_t *pplane;
@ -574,11 +574,11 @@ DrawInlineBModel(void)
else if(!(psurf->flags & SURF_DRAWTURB))
{
SetAllLightFlags(psurf);
RenderLightmappedPoly(psurf);
RenderLightmappedPoly(currententity, psurf);
}
else
{
RenderBrushPoly(psurf);
RenderBrushPoly(currententity, psurf);
}
}
}
@ -590,7 +590,7 @@ DrawInlineBModel(void)
}
void
GL3_DrawBrushModel(entity_t *e)
GL3_DrawBrushModel(entity_t *e, gl3model_t *currentmodel)
{
vec3_t mins, maxs;
int i;
@ -601,7 +601,6 @@ GL3_DrawBrushModel(entity_t *e)
return;
}
currententity = e;
gl3state.currenttexture = -1;
if (e->angles[0] || e->angles[1] || e->angles[2])
@ -656,7 +655,7 @@ GL3_DrawBrushModel(entity_t *e)
e->angles[0] = -e->angles[0];
e->angles[2] = -e->angles[2];
DrawInlineBModel();
DrawInlineBModel(e, currentmodel);
// glPopMatrix();
gl3state.uni3DData.transModelMat4 = oldMat;
@ -669,7 +668,7 @@ GL3_DrawBrushModel(entity_t *e)
}
static void
RecursiveWorldNode(mnode_t *node)
RecursiveWorldNode(entity_t *currententity, mnode_t *node)
{
int c, side, sidebit;
cplane_t *plane;
@ -755,7 +754,7 @@ RecursiveWorldNode(mnode_t *node)
}
/* recurse down the children, front side first */
RecursiveWorldNode(node->children[side]);
RecursiveWorldNode(currententity, node->children[side]);
/* draw stuff */
for (c = node->numsurfaces,
@ -782,7 +781,7 @@ RecursiveWorldNode(mnode_t *node)
/* add to the translucent chain */
surf->texturechain = gl3_alpha_surfaces;
gl3_alpha_surfaces = surf;
gl3_alpha_surfaces->texinfo->image = TextureAnimation(surf->texinfo);
gl3_alpha_surfaces->texinfo->image = TextureAnimation(currententity, surf->texinfo);
}
else
{
@ -798,7 +797,7 @@ RecursiveWorldNode(mnode_t *node)
#endif // 0
{
/* the polygon is visible, so add it to the texture sorted chain */
image = TextureAnimation(surf->texinfo);
image = TextureAnimation(currententity, surf->texinfo);
surf->texturechain = image->texturechain;
image->texturechain = surf;
}
@ -806,7 +805,7 @@ RecursiveWorldNode(mnode_t *node)
}
/* recurse down the back side */
RecursiveWorldNode(node->children[!side]);
RecursiveWorldNode(currententity, node->children[!side]);
}
void
@ -824,24 +823,19 @@ GL3_DrawWorld(void)
return;
}
currentmodel = gl3_worldmodel;
VectorCopy(gl3_newrefdef.vieworg, modelorg);
/* auto cycle the world frame for texture animation */
memset(&ent, 0, sizeof(ent));
ent.frame = (int)(gl3_newrefdef.time * 2);
currententity = &ent;
gl3state.currenttexture = -1;
GL3_ClearSkyBox();
RecursiveWorldNode(gl3_worldmodel->nodes);
DrawTextureChains();
RecursiveWorldNode(&ent, gl3_worldmodel->nodes);
DrawTextureChains(&ent);
GL3_DrawSkyBox();
DrawTriangleOutlines();
currententity = NULL;
}
/*
@ -851,7 +845,7 @@ GL3_DrawWorld(void)
void
GL3_MarkLeaves(void)
{
byte *vis;
const byte *vis;
YQ2_ALIGNAS_TYPE(int) byte fatvis[MAX_MAP_LEAFS / 8];
mnode_t *node;
int i, c;

View file

@ -300,8 +300,6 @@ typedef struct
} gl3lightmapstate_t;
extern gl3model_t *gl3_worldmodel;
extern gl3model_t *currentmodel;
extern entity_t *currententity;
extern float gl3depthmin, gl3depthmax;
@ -381,7 +379,7 @@ extern void GL3_BeginRegistration(char *model);
extern struct model_s * GL3_RegisterModel(char *name);
extern void GL3_EndRegistration(void);
extern void GL3_Mod_Modellist_f(void);
extern byte* GL3_Mod_ClusterPVS(int cluster, gl3model_t *model);
extern const byte* GL3_Mod_ClusterPVS(int cluster, const gl3model_t *model);
extern mleaf_t* GL3_Mod_PointInLeaf(vec3_t p, gl3model_t *model);
// gl3_draw.c
@ -421,12 +419,13 @@ extern gl3image_t *GL3_FindImage(char *name, imagetype_t type);
extern gl3image_t *GL3_RegisterSkin(char *name);
extern void GL3_ShutdownImages(void);
extern void GL3_FreeUnusedImages(void);
extern qboolean GL3_ImageHasFreeSpace(void);
extern void GL3_ImageList_f(void);
// gl3_light.c
extern void GL3_MarkLights(dlight_t *light, int bit, mnode_t *node);
extern void GL3_PushDlights(void);
extern void GL3_LightPoint(vec3_t p, vec3_t color);
extern void GL3_LightPoint(entity_t *currententity, vec3_t p, vec3_t color);
extern void GL3_BuildLightMap(msurface_t *surf, int offsetInLMbuf, int stride);
// gl3_lightmap.c
@ -435,7 +434,7 @@ extern void GL3_BuildLightMap(msurface_t *surf, int offsetInLMbuf, int stride);
extern void GL3_LM_InitBlock(void);
extern void GL3_LM_UploadBlock(void);
extern qboolean GL3_LM_AllocBlock(int w, int h, int *x, int *y);
extern void GL3_LM_BuildPolygonFromSurface(msurface_t *fa);
extern void GL3_LM_BuildPolygonFromSurface(gl3model_t *currentmodel, msurface_t *fa);
extern void GL3_LM_CreateSurfaceLightmap(msurface_t *surf);
extern void GL3_LM_BeginBuildingLightmaps(gl3model_t *m);
extern void GL3_LM_EndBuildingLightmaps(void);
@ -457,7 +456,7 @@ extern void GL3_DrawGLPoly(msurface_t *fa);
extern void GL3_DrawGLFlowingPoly(msurface_t *fa);
extern void GL3_DrawTriangleOutlines(void);
extern void GL3_DrawAlphaSurfaces(void);
extern void GL3_DrawBrushModel(entity_t *e);
extern void GL3_DrawBrushModel(entity_t *e, gl3model_t *currentmodel);
extern void GL3_DrawWorld(void);
extern void GL3_MarkLeaves(void);
@ -481,7 +480,8 @@ extern void GL3_UpdateUBOLights(void);
extern cvar_t *gl_msaa_samples;
extern cvar_t *r_vsync;
extern cvar_t *gl_retexturing;
extern cvar_t *r_retexturing;
extern cvar_t *r_scale8bittextures;
extern cvar_t *vid_fullscreen;
extern cvar_t *r_mode;
extern cvar_t *r_customwidth;

View file

@ -195,7 +195,7 @@ typedef struct model_s
int lightmap; /* only for submodels */
int numsubmodels;
mmodel_t *submodels;
struct model_s *submodels;
int numplanes;
cplane_t *planes;
@ -234,6 +234,9 @@ typedef struct model_s
int extradatasize;
void *extradata;
// submodules
vec3_t origin; // for sounds or lights
} gl3model_t;
#endif /* SRC_CLIENT_REFRESH_GL3_HEADER_MODEL_H_ */

View file

@ -74,5 +74,5 @@ extern void GetWalInfo(char *name, int *width, int *height);
extern void GetM8Info(char *name, int *width, int *height);
extern float Mod_RadiusFromBounds(const vec3_t mins, const vec3_t maxs);
extern byte* Mod_DecompressVis(byte *in, int row);
extern const byte* Mod_DecompressVis(const byte *in, int row);
#endif /* SRC_CLIENT_REFRESH_REF_SHARED_H_ */

View file

@ -424,7 +424,8 @@ extern cvar_t *sw_stipplealpha;
extern cvar_t *sw_surfcacheoverride;
extern cvar_t *sw_waterwarp;
extern cvar_t *sw_gunzposition;
extern cvar_t *sw_retexturing;
extern cvar_t *r_retexturing;
extern cvar_t *r_scale8bittextures;
extern cvar_t *r_fullbright;
extern cvar_t *r_lefthand;
@ -443,7 +444,7 @@ extern int *pfrustum_indexes[4];
//=============================================================================
void R_RenderWorld(void);
void R_RenderWorld(entity_t *currententity);
//=============================================================================
@ -451,7 +452,6 @@ extern cplane_t screenedge[4];
extern vec3_t r_origin;
extern entity_t r_worldentity;
extern vec3_t modelorg;
extern vec3_t r_entorigin;
@ -477,7 +477,7 @@ void R_DrawSolidClippedSubmodelPolygons(entity_t *currententity, const model_t *
void R_AliasDrawModel(entity_t *currententity, const model_t *currentmodel);
void R_BeginEdgeFrame(void);
void R_ScanEdges(surf_t *surface);
void R_ScanEdges(entity_t *currententity, surf_t *surface);
void R_PushDlights(const model_t *model);
void R_RotateBmodel(const entity_t *currententity);

View file

@ -222,8 +222,8 @@ typedef struct model_s
void Mod_Init(void);
mleaf_t *Mod_PointInLeaf(vec3_t p, model_t *model);
byte *Mod_ClusterPVS(int cluster, model_t *model);
mleaf_t *Mod_PointInLeaf(vec3_t p, const model_t *model);
const byte *Mod_ClusterPVS(int cluster, const model_t *model);
void Mod_Modellist_f(void);
void Mod_FreeAll(void);

View file

@ -587,7 +587,7 @@ R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnod
{
msurface_t *surf;
surf = r_worldmodel->surfaces + node->firstsurface;
surf = currentmodel->surfaces + node->firstsurface;
if (dot < -BACKFACE_EPSILON)
{
@ -631,7 +631,7 @@ R_RenderWorld
================
*/
void
R_RenderWorld (void)
R_RenderWorld (entity_t *currententity)
{
const model_t *currentmodel = r_worldmodel;
@ -643,10 +643,10 @@ R_RenderWorld (void)
c_drawnode=0;
// auto cycle the world frame for texture animation
r_worldentity.frame = (int)(r_newrefdef.time*2);
currententity->frame = (int)(r_newrefdef.time*2);
VectorCopy (r_origin, modelorg);
r_pcurrentvertbase = currentmodel->vertexes;
R_RecursiveWorldNode (&r_worldentity, currentmodel, currentmodel->nodes, ALIAS_XY_CLIP_MASK, false);
R_RecursiveWorldNode (currententity, currentmodel, currentmodel->nodes, ALIAS_XY_CLIP_MASK, false);
}

View file

@ -339,7 +339,7 @@ RE_Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, byte *data)
// we have only one image size
pic.mip_levels = 1;
if (sw_retexturing->value)
if (r_retexturing->value)
{
if (cols < (w / 3) || rows < (h / 3))
{
@ -373,7 +373,7 @@ RE_Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, byte *data)
RE_Draw_StretchPicImplementation (x, y, w, h, &pic);
if (sw_retexturing->value)
if (r_retexturing->value)
{
free(image_scaled);
}

View file

@ -581,7 +581,7 @@ R_GenerateSpansBackward (void)
R_CleanupSpan ();
}
static void D_DrawSurfaces (surf_t *surface);
static void D_DrawSurfaces (entity_t *currententity, surf_t *surface);
/*
==============
@ -597,7 +597,7 @@ Each surface has a linked list of its visible spans
==============
*/
void
R_ScanEdges (surf_t *surface)
R_ScanEdges (entity_t *currententity, surf_t *surface)
{
shift20_t iv, bottom;
surf_t *s;
@ -672,7 +672,7 @@ R_ScanEdges (surf_t *surface)
if (span_p + r_refdef.vrect.width >= max_span_p)
{
// Draw stuff on screen
D_DrawSurfaces (surface);
D_DrawSurfaces (currententity, surface);
// clear the surface span pointers
for (s = &surfaces[1] ; s<surface ; s++)
@ -707,7 +707,7 @@ R_ScanEdges (surf_t *surface)
(*pdrawfunc) ();
// draw whatever's left in the span list
D_DrawSurfaces (surface);
D_DrawSurfaces (currententity, surface);
}
@ -935,10 +935,8 @@ Normal surface cached, texture mapped surface
==============
*/
static void
D_SolidSurf (surf_t *s)
D_SolidSurf (entity_t *currententity, surf_t *s)
{
entity_t *currententity;
if (s->insubmodel)
{
vec3_t local_modelorg;
@ -952,8 +950,6 @@ D_SolidSurf (surf_t *s)
R_RotateBmodel(currententity); // FIXME: don't mess with the frustum,
// make entity passed in
}
else
currententity = &r_worldentity;
pface = s->msurf;
miplevel = D_MipLevelForScale(s->nearzi * scale_for_mip * pface->texinfo->mipadjust);
@ -1022,7 +1018,7 @@ May be called more than once a frame if the surf list overflows (higher res)
==============
*/
static void
D_DrawSurfaces (surf_t *surface)
D_DrawSurfaces (entity_t *currententity, surf_t *surface)
{
VectorSubtract (r_origin, vec3_origin, modelorg);
TransformVector (modelorg, transformed_modelorg);
@ -1040,7 +1036,7 @@ D_DrawSurfaces (surf_t *surface)
r_drawnpolycount++;
if (! (s->flags & (SURF_DRAWSKYBOX|SURF_DRAWBACKGROUND|SURF_DRAWTURB) ) )
D_SolidSurf (s);
D_SolidSurf (currententity, s);
else if (s->flags & SURF_DRAWSKYBOX)
D_SkySurf (s);
else if (s->flags & SURF_DRAWBACKGROUND)

View file

@ -581,7 +581,7 @@ R_LoadImage(char *name, const char* namewe, const char *ext, imagetype_t type)
image_t *image = NULL;
// with retexturing and not skin
if (sw_retexturing->value)
if (r_retexturing->value)
{
image = R_LoadHiColorImage(name, namewe, ext, type);
}
@ -598,7 +598,7 @@ R_LoadImage(char *name, const char* namewe, const char *ext, imagetype_t type)
if (!pic)
return NULL;
if (sw_retexturing->value == 2 && type == it_pic)
if (r_scale8bittextures->value && type == it_pic)
{
byte *scaled = NULL;
int realwidth, realheight;
@ -810,6 +810,7 @@ R_InitImages (void)
{
unsigned char * table16to8;
registration_sequence = 1;
image_max = 0;
d_16to8table = NULL;
ri.FS_LoadFile("pics/16to8.dat", (void **)&table16to8);

View file

@ -53,8 +53,6 @@ refimport_t ri;
static unsigned d_8to24table[256];
entity_t r_worldentity;
char skyname[MAX_QPATH];
vec3_t skyaxis;
@ -148,7 +146,8 @@ static cvar_t *sw_overbrightbits;
cvar_t *sw_custom_particles;
static cvar_t *sw_anisotropic;
cvar_t *sw_texture_filtering;
cvar_t *sw_retexturing;
cvar_t *r_retexturing;
cvar_t *r_scale8bittextures;
cvar_t *sw_gunzposition;
static cvar_t *sw_partialrefresh;
@ -377,7 +376,8 @@ R_RegisterVariables (void)
sw_custom_particles = ri.Cvar_Get("sw_custom_particles", "0", CVAR_ARCHIVE);
sw_texture_filtering = ri.Cvar_Get("sw_texture_filtering", "0", CVAR_ARCHIVE);
sw_anisotropic = ri.Cvar_Get("r_anisotropic", "0", CVAR_ARCHIVE);
sw_retexturing = ri.Cvar_Get("r_retexturing", "1", CVAR_ARCHIVE);
r_retexturing = ri.Cvar_Get("r_retexturing", "1", CVAR_ARCHIVE);
r_scale8bittextures = ri.Cvar_Get("r_scale8bittextures", "0", CVAR_ARCHIVE);
sw_gunzposition = ri.Cvar_Get("sw_gunzposition", "8", CVAR_ARCHIVE);
// On MacOS texture is cleaned up after render and code have to copy a whole
@ -744,7 +744,7 @@ cluster
static void
R_MarkLeaves (void)
{
byte *vis;
const byte *vis;
mnode_t *node;
int i;
mleaf_t *leaf;
@ -1163,7 +1163,7 @@ Render the map
================
*/
static void
R_EdgeDrawing (void)
R_EdgeDrawing (entity_t *currententity)
{
if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
return;
@ -1181,7 +1181,7 @@ R_EdgeDrawing (void)
// Build the Global Edget Table
// Also populate the surface stack and count # surfaces to render (surf_max is the max)
R_RenderWorld ();
R_RenderWorld (currententity);
if (r_dspeeds->value)
{
@ -1199,7 +1199,7 @@ R_EdgeDrawing (void)
// Use the Global Edge Table to maintin the Active Edge Table: Draw the world as scanlines
// Write the Z-Buffer (but no read)
R_ScanEdges (surface_p);
R_ScanEdges (currententity, surface_p);
}
//=======================================================================
@ -1300,6 +1300,7 @@ static void
RE_RenderFrame (refdef_t *fd)
{
r_newrefdef = *fd;
entity_t ent;
if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
{
@ -1340,9 +1341,14 @@ RE_RenderFrame (refdef_t *fd)
// For each dlight_t* passed via r_newrefdef.dlights, mark polygons affected by a light.
R_PushDlights (r_worldmodel);
// TODO: rearange code same as in GL*_DrawWorld?
/* auto cycle the world frame for texture animation */
memset(&ent, 0, sizeof(ent));
ent.frame = (int)(r_newrefdef.time * 2);
// Build the Global Edge Table and render it via the Active Edge Table
// Render the map
R_EdgeDrawing ();
R_EdgeDrawing (&ent);
if (r_dspeeds->value)
{
@ -1377,10 +1383,10 @@ RE_RenderFrame (refdef_t *fd)
dp_time2 = SDL_GetTicks();
// Perform pixel palette blending ia the pics/colormap.pcx lower part lookup table.
R_DrawAlphaSurfaces(&r_worldentity);
R_DrawAlphaSurfaces(&ent);
// Save off light value for server to look at (BIG HACK!)
R_SetLightLevel (&r_worldentity);
R_SetLightLevel (&ent);
if (r_dowarp)
D_WarpScreen ();

View file

@ -230,7 +230,7 @@ Mod_PointInLeaf
===============
*/
mleaf_t *
Mod_PointInLeaf (vec3_t p, model_t *model)
Mod_PointInLeaf (vec3_t p, const model_t *model)
{
mnode_t *node;
@ -263,8 +263,8 @@ Mod_PointInLeaf (vec3_t p, model_t *model)
Mod_ClusterPVS
==============
*/
byte *
Mod_ClusterPVS (int cluster, model_t *model)
const byte *
Mod_ClusterPVS (int cluster, const model_t *model)
{
if (cluster == -1 || !model->vis)
return mod_novis;
@ -408,25 +408,6 @@ Mod_LoadVertexes (model_t *loadmodel, byte *mod_base, lump_t *l)
}
}
/*
=================
RadiusFromBounds
=================
*/
static float
RadiusFromBounds (vec3_t mins, vec3_t maxs)
{
int i;
vec3_t corner;
for (i=0 ; i<3 ; i++)
{
corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]);
}
return VectorLength (corner);
}
/*
=================
Mod_LoadSubmodels
@ -474,7 +455,7 @@ Mod_LoadSubmodels (model_t *loadmodel, byte *mod_base, lump_t *l)
out->origin[j] = LittleFloat (in->origin[j]);
}
out->radius = RadiusFromBounds (out->mins, out->maxs);
out->radius = Mod_RadiusFromBounds (out->mins, out->maxs);
out->firstnode = LittleLong (in->headnode);
out->firstmodelsurface = LittleLong (in->firstface);
out->nummodelsurfaces = LittleLong (in->numfaces);

View file

@ -541,16 +541,26 @@ GLimp_InitGraphics(int fullscreen, int *pwidth, int *pheight)
{
if((flags & SDL_WINDOW_OPENGL) && gl_msaa_samples->value)
{
int msaa_samples = gl_msaa_samples->value;
if (msaa_samples > 0)
{
msaa_samples /= 2;
}
Com_Printf("SDL SetVideoMode failed: %s\n", SDL_GetError());
Com_Printf("Reverting to %s r_mode %i (%ix%i) without MSAA.\n",
Com_Printf("Reverting to %s r_mode %i (%ix%i) with %dx MSAA.\n",
(flags & fs_flag) ? "fullscreen" : "windowed",
(int) Cvar_VariableValue("r_mode"), width, height);
(int) Cvar_VariableValue("r_mode"), width, height,
msaa_samples);
/* Try to recover */
Cvar_SetValue("r_msaa_samples", 0);
Cvar_SetValue("r_msaa_samples", msaa_samples);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,
msaa_samples > 0 ? 1 : 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,
msaa_samples);
}
else if (width != 640 || height != 480 || (flags & fs_flag))
{

View file

@ -81,6 +81,8 @@ char userGivenGame[MAX_QPATH];
// Hack for the signal handlers.
qboolean quitnextframe;
static void Qcommon_Frame(int usec);
// ----
static void
@ -130,7 +132,7 @@ Qcommon_Buildstring(void)
printf("Architecture: %s\n", YQ2ARCH);
}
void
static void
Qcommon_Mainloop(void)
{
long long newtime;
@ -140,39 +142,46 @@ Qcommon_Mainloop(void)
while (1)
{
#ifndef DEDICATED_ONLY
// Throttle the game a little bit.
if (busywait->value)
if (!cl_timedemo->value)
{
long long spintime = Sys_Microseconds();
while (1)
// Throttle the game a little bit.
if (busywait->value)
{
/* Give the CPU a hint that this is a very tight
spinloop. One PAUSE instruction each loop is
enough to reduce power consumption and head
dispersion a lot, it's 95°C against 67°C on
a Kaby Lake laptop. */
long long spintime = Sys_Microseconds();
while (1)
{
/* Give the CPU a hint that this is a very tight
spinloop. One PAUSE instruction each loop is
enough to reduce power consumption and head
dispersion a lot, it's 95°C against 67°C on
a Kaby Lake laptop. */
#if defined (__GNUC__) && (__i386 || __x86_64__)
asm("pause");
asm("pause");
#elif defined(__aarch64__) || (defined(__ARM_ARCH) && __ARM_ARCH >= 7) || defined(__ARM_ARCH_6K__)
asm("yield");
asm("yield");
#endif
if (Sys_Microseconds() - spintime >= 5)
{
break;
if (Sys_Microseconds() - spintime >= 5)
{
break;
}
}
}
}
else
{
Sys_Nanosleep(5000);
else
{
Sys_Nanosleep(5000);
}
}
#else
Sys_Nanosleep(850000);
#endif
newtime = Sys_Microseconds();
// Save global time for network- und input code.
curtime = (int)(newtime / 1000ll);
Qcommon_Frame(newtime - oldtime);
oldtime = newtime;
}
@ -392,7 +401,7 @@ Qcommon_Init(int argc, char **argv)
}
#ifndef DEDICATED_ONLY
void
static void
Qcommon_Frame(int usec)
{
// Used for the dedicated server console.
@ -523,11 +532,6 @@ Qcommon_Frame(int usec)
Cvar_SetValue("cl_maxfps", 60);
}
// Save global time for network- und input code.
curtime = Sys_Milliseconds();
// Calculate target and renderframerate.
if (R_IsVSyncActive())
{
@ -598,9 +602,15 @@ Qcommon_Frame(int usec)
}
}
}
else if (clienttimedelta < 1000 || servertimedelta < 1000)
else
{
return;
/* minimal frame time in timedemo fps * 5 ~ 5000 */
int minframetime;
minframetime = 1000 * 1000 / 5 / vid_maxfps->value;
if (clienttimedelta < minframetime || servertimedelta < minframetime)
return;
}
@ -668,7 +678,7 @@ Qcommon_Frame(int usec)
}
}
#else
void
static void
Qcommon_Frame(int usec)
{
// For the dedicated server terminal console.
@ -720,10 +730,6 @@ Qcommon_Frame(int usec)
}
// Save global time for network- und input code.
curtime = Sys_Milliseconds();
// Target framerate.
pfps = (int)cl_maxfps->value;

View file

@ -780,7 +780,6 @@ void Z_FreeTags(int tag);
void Qcommon_Init(int argc, char **argv);
void Qcommon_ExecConfigs(qboolean addEarlyCmds);
const char* Qcommon_GetInitialGame(void);
void Qcommon_Frame(int msec);
void Qcommon_Shutdown(void);
#define NUMVERTEXNORMALS 162