mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2024-11-09 23:11:39 +00:00
Small speedup...
This commit is contained in:
parent
169c47b30d
commit
3aa4ceb4f4
20 changed files with 1426 additions and 140 deletions
|
@ -239,7 +239,7 @@ typedef struct texinfo_s
|
|||
{
|
||||
float vecs[2][4]; // [s/t][xyz offset]
|
||||
int miptex;
|
||||
int flags;
|
||||
int flags; //TEX_SPECIAL
|
||||
} texinfo_t;
|
||||
#define TEX_SPECIAL 1 // sky or slime, no lightmap or 256 subdivision
|
||||
#define TEX_MISSING 2 // johnfitz -- this texinfo does not have a texture
|
||||
|
|
|
@ -255,7 +255,7 @@ void CL_Record_Prespawn(void)
|
|||
//static ents
|
||||
for (idx = 1; idx < cl.num_statics; idx++)
|
||||
{
|
||||
MSG_WriteStaticOrBaseLine(&net_message, -1, &cl.static_entities[idx]->baseline, cl.protocol_pext2, cl.protocol, cl.protocolflags);
|
||||
MSG_WriteStaticOrBaseLine(&net_message, -1, &cl.static_entities[idx].ent->baseline, cl.protocol_pext2, cl.protocol, cl.protocolflags);
|
||||
|
||||
if (net_message.cursize > 4096)
|
||||
{ //periodically flush so that large maps don't need larger than vanilla limits
|
||||
|
|
|
@ -78,8 +78,8 @@ void CL_ClearTrailStates(void)
|
|||
int i;
|
||||
for (i = 0; i < cl.num_statics; i++)
|
||||
{
|
||||
PScript_DelinkTrailstate(&(cl.static_entities[i]->trailstate));
|
||||
PScript_DelinkTrailstate(&(cl.static_entities[i]->emitstate));
|
||||
PScript_DelinkTrailstate(&(cl.static_entities[i].ent->trailstate));
|
||||
PScript_DelinkTrailstate(&(cl.static_entities[i].ent->emitstate));
|
||||
}
|
||||
for (i = 0; i < cl.max_edicts; i++)
|
||||
{
|
||||
|
@ -147,6 +147,8 @@ void CL_ClearState (void)
|
|||
PScript_Shutdown();
|
||||
#endif
|
||||
|
||||
RSceneCache_Shutdown();
|
||||
|
||||
if (!sv.active)
|
||||
Draw_ReloadTextures(false);
|
||||
}
|
||||
|
@ -1203,10 +1205,10 @@ qboolean CL_CheckDownloads(void)
|
|||
//make sure ents have the correct models, now that they're actually loaded.
|
||||
for (i = 0; i < cl.num_statics; i++)
|
||||
{
|
||||
if (cl.static_entities[i]->model)
|
||||
if (cl.static_entities[i].ent->model)
|
||||
continue;
|
||||
cl.static_entities[i]->model = cl.model_precache[cl.static_entities[i]->netstate.modelindex];
|
||||
R_AddEfrags (cl.static_entities[i]);
|
||||
cl.static_entities[i].ent->model = cl.model_precache[cl.static_entities[i].ent->netstate.modelindex];
|
||||
CL_LinkStaticEnt(&cl.static_entities[i]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -2005,16 +2005,16 @@ static void CL_ParseStatic (int version) //johnfitz -- added a parameter
|
|||
if (i >= cl.max_static_entities)
|
||||
{
|
||||
int ec = 64;
|
||||
entity_t **newstatics = realloc(cl.static_entities, sizeof(*newstatics) * (cl.max_static_entities+ec));
|
||||
struct cl_static_entities_s *newstatics = realloc(cl.static_entities, sizeof(*newstatics) * (cl.max_static_entities+ec));
|
||||
entity_t *newents = Hunk_Alloc(sizeof(*newents) * ec);
|
||||
if (!newstatics || !newents)
|
||||
Host_Error ("Too many static entities");
|
||||
cl.static_entities = newstatics;
|
||||
while (ec--)
|
||||
cl.static_entities[cl.max_static_entities++] = newents++;
|
||||
cl.static_entities[cl.max_static_entities++].ent = newents++;
|
||||
}
|
||||
|
||||
ent = cl.static_entities[i];
|
||||
ent = cl.static_entities[i].ent;
|
||||
cl.num_statics++;
|
||||
CL_ParseBaseline (ent, version); //johnfitz -- added second parameter
|
||||
|
||||
|
@ -2034,8 +2034,7 @@ static void CL_ParseStatic (int version) //johnfitz -- added a parameter
|
|||
ent->alpha = ent->baseline.alpha; //johnfitz -- alpha
|
||||
VectorCopy (ent->baseline.origin, ent->origin);
|
||||
VectorCopy (ent->baseline.angles, ent->angles);
|
||||
if (ent->model)
|
||||
R_AddEfrags (ent);
|
||||
CL_LinkStaticEnt(&cl.static_entities[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -74,7 +74,7 @@ typedef struct
|
|||
{
|
||||
vec3_t origin;
|
||||
float radius;
|
||||
float die; // stop lighting after this time
|
||||
double die; // stop lighting after this time
|
||||
float decay; // drop this each second
|
||||
float minlight; // don't add when contributing less
|
||||
int key;
|
||||
|
@ -249,7 +249,13 @@ typedef struct
|
|||
int max_edicts;
|
||||
int num_entities;
|
||||
|
||||
entity_t **static_entities; //spike -- was static
|
||||
struct cl_static_entities_s
|
||||
{
|
||||
entity_t *ent;
|
||||
unsigned int num_clusters;
|
||||
int clusternums[MAX_ENT_LEAFS];
|
||||
vec3_t absmin, absmax;
|
||||
} *static_entities; //spike -- was static
|
||||
int max_static_entities;
|
||||
int num_statics;
|
||||
|
||||
|
|
|
@ -247,6 +247,7 @@ void Mod_ClearAll (void)
|
|||
mod->needload = true;
|
||||
TexMgr_FreeTexturesForOwner (mod); //johnfitz
|
||||
PScript_ClearSurfaceParticles(mod);
|
||||
RSceneCache_Cleanup(mod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -265,6 +266,7 @@ void Mod_ResetAll (void)
|
|||
{
|
||||
TexMgr_FreeTexturesForOwner (mod);
|
||||
PScript_ClearSurfaceParticles(mod);
|
||||
RSceneCache_Cleanup(mod);
|
||||
}
|
||||
memset(mod, 0, sizeof(qmodel_t));
|
||||
}
|
||||
|
@ -1411,16 +1413,14 @@ static void Mod_LoadTexinfo (lump_t *l)
|
|||
if (miptex >= loadmodel->numtextures-1 || !loadmodel->textures[miptex])
|
||||
{
|
||||
if (out->flags & TEX_SPECIAL)
|
||||
out->texture = loadmodel->textures[loadmodel->numtextures-1];
|
||||
miptex = loadmodel->numtextures-1;
|
||||
else
|
||||
out->texture = loadmodel->textures[loadmodel->numtextures-2];
|
||||
miptex = loadmodel->numtextures-2;
|
||||
out->flags |= TEX_MISSING;
|
||||
missing++;
|
||||
}
|
||||
else
|
||||
{
|
||||
out->texture = loadmodel->textures[miptex];
|
||||
}
|
||||
out->texture = loadmodel->textures[miptex];
|
||||
out->materialidx = miptex;
|
||||
//johnfitz
|
||||
}
|
||||
|
||||
|
@ -2849,6 +2849,8 @@ visdone:
|
|||
// set up the submodels (FIXME: this is confusing)
|
||||
//
|
||||
|
||||
mod->submodelof = loadmodel;
|
||||
|
||||
// johnfitz -- okay, so that i stop getting confused every time i look at this loop, here's how it works:
|
||||
// we're looping through the submodels starting at 0. Submodel 0 is the main model, so we don't have to
|
||||
// worry about clobbering data the first time through, since it's the same data. At the end of the loop,
|
||||
|
@ -2869,6 +2871,8 @@ visdone:
|
|||
|
||||
mod->firstmodelsurface = bm->firstface;
|
||||
mod->nummodelsurfaces = bm->numfaces;
|
||||
mod->submodelof = loadmodel->submodelof;
|
||||
mod->submodelidx = i;
|
||||
|
||||
VectorCopy (bm->maxs, mod->maxs);
|
||||
VectorCopy (bm->mins, mod->mins);
|
||||
|
|
|
@ -115,6 +115,7 @@ typedef struct
|
|||
float vecs[2][4];
|
||||
texture_t *texture;
|
||||
int flags;
|
||||
int materialidx;
|
||||
} mtexinfo_t;
|
||||
|
||||
#define VERTEXSIZE 7
|
||||
|
@ -495,6 +496,8 @@ typedef struct qmodel_s
|
|||
|
||||
int numsubmodels;
|
||||
mmodel_t *submodels;
|
||||
struct qmodel_s *submodelof;
|
||||
unsigned submodelidx;
|
||||
|
||||
int numplanes;
|
||||
mplane_t *planes;
|
||||
|
|
|
@ -165,7 +165,7 @@ void R_CheckEfrags (void)
|
|||
R_AddEfrags
|
||||
===========
|
||||
*/
|
||||
void R_AddEfrags (entity_t *ent)
|
||||
static void R_AddEfrags (entity_t *ent)
|
||||
{
|
||||
qmodel_t *entmodel;
|
||||
float scale;
|
||||
|
@ -266,3 +266,79 @@ void R_StoreEfrags (efrag_t **ppefrag)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void R_FindTouchedLeafs (struct cl_static_entities_s *ent, mnode_t *node)
|
||||
{
|
||||
mplane_t *splitplane;
|
||||
mleaf_t *leaf;
|
||||
int sides;
|
||||
int clusternum;
|
||||
|
||||
if (node->contents == CONTENTS_SOLID)
|
||||
return;
|
||||
|
||||
// add an efrag if the node is a leaf
|
||||
|
||||
if ( node->contents < 0)
|
||||
{
|
||||
if (ent->num_clusters < MAX_ENT_LEAFS)
|
||||
{
|
||||
leaf = (mleaf_t *)node;
|
||||
clusternum = (leaf - cl.worldmodel->leafs) - 1;
|
||||
ent->clusternums[ent->num_clusters] = clusternum;
|
||||
}
|
||||
ent->num_clusters++;
|
||||
return;
|
||||
}
|
||||
|
||||
// NODE_MIXED
|
||||
|
||||
splitplane = node->plane;
|
||||
sides = BOX_ON_PLANE_SIDE(ent->absmin, ent->absmax, splitplane);
|
||||
|
||||
// recurse down the contacted sides
|
||||
if (sides & 1)
|
||||
R_FindTouchedLeafs (ent, node->children[0]);
|
||||
|
||||
if (sides & 2)
|
||||
R_FindTouchedLeafs (ent, node->children[1]);
|
||||
}
|
||||
|
||||
void CL_LinkStaticEnt(struct cl_static_entities_s *ent)
|
||||
{
|
||||
ent->num_clusters = 0;
|
||||
if (!ent->ent->model)
|
||||
return;
|
||||
|
||||
//calc its bbox...
|
||||
if (ent->ent->angles[0] || ent->ent->angles[1] || ent->ent->angles[2])
|
||||
{ // expand for rotation the lame way. hopefully there's an origin brush in there.
|
||||
int i;
|
||||
float v1,v2;
|
||||
vec3_t max;
|
||||
//q2 method
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
v1 = fabs(ent->ent->model->mins[i]);
|
||||
v2 = fabs(ent->ent->model->maxs[i]);
|
||||
max[i] = q_max(v1,v2);
|
||||
}
|
||||
v1 = sqrt(DotProduct(max,max));
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
ent->absmin[i] = ent->ent->origin[i] - v1;
|
||||
ent->absmax[i] = ent->ent->origin[i] + v1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //simple
|
||||
VectorAdd(ent->ent->origin, ent->ent->model->mins, ent->absmin);
|
||||
VectorAdd(ent->ent->origin, ent->ent->model->maxs, ent->absmax);
|
||||
}
|
||||
|
||||
//for scenecache
|
||||
R_FindTouchedLeafs(ent, cl.worldmodel->nodes);
|
||||
|
||||
//legacy bloat for non-scenecache.
|
||||
R_AddEfrags(ent->ent);
|
||||
}
|
||||
|
|
|
@ -23,8 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "quakedef.h"
|
||||
|
||||
int r_dlightframecount;
|
||||
|
||||
extern cvar_t r_flatlightstyles; //johnfitz
|
||||
|
||||
//Spike - made this a general function
|
||||
|
@ -162,8 +160,6 @@ void R_RenderDlights (void)
|
|||
if (!gl_flashblend.value)
|
||||
return;
|
||||
|
||||
r_dlightframecount = r_framecount + 1; // because the count hasn't
|
||||
// advanced yet for this frame
|
||||
glDepthMask (0);
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
glShadeModel (GL_SMOOTH);
|
||||
|
@ -199,7 +195,7 @@ DYNAMIC LIGHTS
|
|||
R_MarkLights -- johnfitz -- rewritten to use LordHavoc's lighting speedup
|
||||
=============
|
||||
*/
|
||||
void R_MarkLights (dlight_t *light, vec3_t lightorg, int num, mnode_t *node)
|
||||
void R_MarkLights (dlight_t *light, vec3_t lightorg, int framecount, int num, mnode_t *node)
|
||||
{
|
||||
mplane_t *splitplane;
|
||||
msurface_t *surf;
|
||||
|
@ -247,10 +243,10 @@ start:
|
|||
// compare to minimum light
|
||||
if ((s*s+t*t+dist*dist) < maxdist)
|
||||
{
|
||||
if (surf->dlightframe != r_dlightframecount) // not dynamic until now
|
||||
if (surf->dlightframe != framecount) // not dynamic until now
|
||||
{
|
||||
surf->dlightbits[num >> 5] = 1U << (num & 31);
|
||||
surf->dlightframe = r_dlightframecount;
|
||||
surf->dlightframe = framecount;
|
||||
}
|
||||
else // already dynamic
|
||||
surf->dlightbits[num >> 5] |= 1U << (num & 31);
|
||||
|
@ -258,9 +254,9 @@ start:
|
|||
}
|
||||
|
||||
if (node->children[0]->contents >= 0)
|
||||
R_MarkLights (light, lightorg, num, node->children[0]);
|
||||
R_MarkLights (light, lightorg, framecount, num, node->children[0]);
|
||||
if (node->children[1]->contents >= 0)
|
||||
R_MarkLights (light, lightorg, num, node->children[1]);
|
||||
R_MarkLights (light, lightorg, framecount, num, node->children[1]);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -275,9 +271,6 @@ void R_PushDlights (void)
|
|||
|
||||
if (gl_flashblend.value)
|
||||
return;
|
||||
|
||||
r_dlightframecount = r_framecount + 1; // because the count hasn't
|
||||
// advanced yet for this frame
|
||||
if (!r_refdef.drawworld)
|
||||
return;
|
||||
l = cl_dlights;
|
||||
|
@ -286,7 +279,7 @@ void R_PushDlights (void)
|
|||
{
|
||||
if (l->die < cl.time || !l->radius)
|
||||
continue;
|
||||
R_MarkLights (l, l->origin, i, cl.worldmodel->nodes);
|
||||
R_MarkLights (l, l->origin, r_framecount, i, cl.worldmodel->nodes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -562,11 +562,11 @@ void R_SetupView (void)
|
|||
int viewcontents; //spike -- rewrote this a little
|
||||
int i;
|
||||
|
||||
// Need to do those early because we now update dynamic light maps during R_MarkSurfaces
|
||||
R_PushDlights ();
|
||||
R_AnimateLight ();
|
||||
r_framecount++;
|
||||
|
||||
// Need to do those early because we now update dynamic light maps during R_MarkSurfaces
|
||||
R_AnimateLight ();
|
||||
|
||||
Fog_SetupFrame (); //johnfitz
|
||||
|
||||
// build the transformation matrix for the given view angles
|
||||
|
@ -993,9 +993,12 @@ void R_RenderScene (void)
|
|||
|
||||
Fog_EnableGFog (); //johnfitz
|
||||
|
||||
Sky_DrawSky (); //johnfitz
|
||||
if (r_refdef.drawworld)
|
||||
{
|
||||
Sky_DrawSky (); //johnfitz
|
||||
|
||||
R_DrawWorld ();
|
||||
R_DrawWorld ();
|
||||
}
|
||||
currententity = NULL;
|
||||
|
||||
S_ExtraUpdate (); // don't let sound get messed up if going slow
|
||||
|
|
|
@ -43,6 +43,7 @@ extern cvar_t r_lerpmove;
|
|||
extern cvar_t r_nolerp_list;
|
||||
extern cvar_t r_noshadow_list;
|
||||
//johnfitz
|
||||
extern cvar_t r_scenecache;
|
||||
extern cvar_t gl_zfix; // QuakeSpasm z-fighting fix
|
||||
cvar_t r_brokenturbbias = {"r_brokenturbbias", "1", CVAR_ARCHIVE}; //replicates QS's bug where it ignores texture coord offsets for water (breaking curved water volumes). we do NOT ignore scales though.
|
||||
|
||||
|
@ -222,6 +223,9 @@ void R_Init (void)
|
|||
Cvar_RegisterVariable (&r_noshadow_list);
|
||||
Cvar_SetCallback (&r_noshadow_list, R_Model_ExtraFlags_List_f);
|
||||
//johnfitz
|
||||
//spike -- new cvars...
|
||||
Cvar_RegisterVariable (&r_scenecache);
|
||||
//spike
|
||||
|
||||
Cvar_RegisterVariable (&gl_zfix); // QuakeSpasm z-fighting fix
|
||||
Cvar_RegisterVariable (&r_lavaalpha);
|
||||
|
|
|
@ -29,6 +29,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
float Fog_GetDensity(void);
|
||||
float *Fog_GetColor(void);
|
||||
|
||||
#ifndef SDL_THREADS_DISABLED
|
||||
qboolean RSceneCache_DrawSkySurfDepth(void); //Draws sky surfaces.
|
||||
#endif
|
||||
|
||||
extern int rs_skypolys; // for r_speeds readout
|
||||
extern int rs_skypasses; // for r_speeds readout
|
||||
|
||||
|
@ -123,7 +127,7 @@ void Sky_LoadTexture (qmodel_t *mod, texture_t *mt, enum srcformat fmt, unsigned
|
|||
memcpy(back_data+bb*i*columns, src+bb*(i*columns*2 + columns), columns*bb);
|
||||
|
||||
q_snprintf(texturename, sizeof(texturename), "%s:%s_back", mod->name, mt->name);
|
||||
solidskytexture = TexMgr_LoadImage (mod, texturename, width, height, fmt, back_data, "", (src_offset_t)back_data, TEXPREF_NONE);
|
||||
mt->gltexture = solidskytexture = TexMgr_LoadImage (mod, texturename, width, height, fmt, back_data, "", (src_offset_t)back_data, TEXPREF_NONE);
|
||||
|
||||
// extract front layer and upload
|
||||
for (i=0 ; i<rows ; i++)
|
||||
|
@ -137,7 +141,7 @@ void Sky_LoadTexture (qmodel_t *mod, texture_t *mt, enum srcformat fmt, unsigned
|
|||
}
|
||||
}
|
||||
q_snprintf(texturename, sizeof(texturename), "%s:%s_front", mod->name, mt->name);
|
||||
alphaskytexture = TexMgr_LoadImage (mod, texturename, width, height, fmt, front_data, "", (src_offset_t)front_data, TEXPREF_ALPHA);
|
||||
mt->fullbright = alphaskytexture = TexMgr_LoadImage (mod, texturename, width, height, fmt, front_data, "", (src_offset_t)front_data, TEXPREF_ALPHA);
|
||||
|
||||
// calculate r_fastsky color based on average of all opaque foreground colors, if we can.
|
||||
r = g = b = count = 0;
|
||||
|
@ -190,7 +194,7 @@ void Sky_LoadTextureQ64 (qmodel_t *mod, texture_t *mt)
|
|||
|
||||
// Normal indexed texture for the back layer
|
||||
q_snprintf(texturename, sizeof(texturename), "%s:%s_back", mod->name, mt->name);
|
||||
solidskytexture = TexMgr_LoadImage (mod, texturename, mt->width, halfheight, SRC_INDEXED, back, "", (src_offset_t)back, TEXPREF_NONE);
|
||||
mt->gltexture = solidskytexture = TexMgr_LoadImage (mod, texturename, mt->width, halfheight, SRC_INDEXED, back, "", (src_offset_t)back, TEXPREF_NONE);
|
||||
|
||||
// front layer, convert to RGBA and upload
|
||||
p = r = g = b = count = 0;
|
||||
|
@ -214,7 +218,7 @@ void Sky_LoadTextureQ64 (qmodel_t *mod, texture_t *mt)
|
|||
}
|
||||
|
||||
q_snprintf(texturename, sizeof(texturename), "%s:%s_front", mod->name, mt->name);
|
||||
alphaskytexture = TexMgr_LoadImage (mod, texturename, mt->width, halfheight, SRC_RGBA, front_rgba, "", (src_offset_t)front_rgba, TEXPREF_ALPHA);
|
||||
mt->fullbright = alphaskytexture = TexMgr_LoadImage (mod, texturename, mt->width, halfheight, SRC_RGBA, front_rgba, "", (src_offset_t)front_rgba, TEXPREF_ALPHA);
|
||||
|
||||
// calculate r_fastsky color based on average of all opaque foreground colors
|
||||
skyflatcolor[0] = (float)r/(count*255);
|
||||
|
@ -736,6 +740,11 @@ void Sky_ProcessEntities (void)
|
|||
if (!e->model || e->model->needload || e->model->type != mod_brush)
|
||||
continue;
|
||||
|
||||
if (e->model->submodelof == cl.worldmodel &&
|
||||
skipsubmodels &&
|
||||
skipsubmodels[e->model->submodelidx>>3]&(1u<<(e->model->submodelidx&7)))
|
||||
return; //its in the scenecache that we're drawing. don't draw it twice (and certainly not the slow way).
|
||||
|
||||
if (R_CullModelForEntity(e))
|
||||
continue;
|
||||
|
||||
|
@ -1189,7 +1198,18 @@ void Sky_DrawSky (void)
|
|||
glColor3fv (Fog_GetColor());
|
||||
else
|
||||
glColor3fv (skyflatcolor);
|
||||
Sky_ProcessTextureChains ();
|
||||
#ifndef SDL_THREADS_DISABLED
|
||||
if (skybox_name[0] && !r_fastsky.value && RSceneCache_DrawSkySurfDepth())
|
||||
{ //we have no surfaces to process... fill all sides. its probably still faster.
|
||||
for (i=0 ; i<6 ; i++)
|
||||
{
|
||||
skymins[0][i] = skymins[1][i] = -FLT_MAX;
|
||||
skymaxs[0][i] = skymaxs[1][i] = FLT_MAX;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
Sky_ProcessTextureChains ();
|
||||
Sky_ProcessEntities ();
|
||||
glColor3f (1, 1, 1);
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
|
|
|
@ -31,7 +31,6 @@ static cvar_t gl_texturemode = {"gl_texturemode", "", CVAR_ARCHIVE};
|
|||
static cvar_t gl_texture_anisotropy = {"gl_texture_anisotropy", "1", CVAR_ARCHIVE};
|
||||
static cvar_t gl_max_size = {"gl_max_size", "0", CVAR_NONE};
|
||||
static cvar_t gl_picmip = {"gl_picmip", "0", CVAR_NONE};
|
||||
static GLint gl_hardware_maxsize;
|
||||
|
||||
static int numgltextures;
|
||||
static gltexture_t *active_gltextures, *free_gltextures;
|
||||
|
@ -705,9 +704,6 @@ void TexMgr_Init (void)
|
|||
Cmd_AddCommand ("imagelist", &TexMgr_Imagelist_f);
|
||||
Cmd_AddCommand ("imagedump", &TexMgr_Imagedump_f);
|
||||
|
||||
// poll max size from hardware
|
||||
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &gl_hardware_maxsize);
|
||||
|
||||
// load notexture images
|
||||
notexture = TexMgr_LoadImage (NULL, "notexture", 2, 2, SRC_RGBA, notexture_data, "", (src_offset_t)notexture_data, TEXPREF_NEAREST | TEXPREF_PERSIST | TEXPREF_NOPICMIP);
|
||||
nulltexture = TexMgr_LoadImage (NULL, "nulltexture", 2, 2, SRC_RGBA, nulltexture_data, "", (src_offset_t)nulltexture_data, TEXPREF_NEAREST | TEXPREF_PERSIST | TEXPREF_NOPICMIP);
|
||||
|
@ -1507,7 +1503,7 @@ gltexture_t *TexMgr_LoadImage (qmodel_t *owner, const char *name, int width, int
|
|||
return NULL;
|
||||
|
||||
// cache check
|
||||
if (format == SRC_EXTERNAL)
|
||||
if (format == SRC_EXTERNAL || format == SRC_LIGHTMAP)
|
||||
crc = 0;
|
||||
else
|
||||
crc = CRC_Block(data, TexMgr_ImageSize(width, height, format));
|
||||
|
|
|
@ -112,6 +112,7 @@ qboolean gl_glsl_gamma_able = false; //ericw
|
|||
qboolean gl_glsl_alias_able = false; //ericw
|
||||
qboolean gl_glsl_water_able = false; //Spoike
|
||||
int gl_stencilbits;
|
||||
GLint gl_hardware_maxsize;
|
||||
|
||||
PFNGLMULTITEXCOORD2FARBPROC GL_MTexCoord2fFunc = NULL; //johnfitz
|
||||
PFNGLACTIVETEXTUREARBPROC GL_SelectTextureFunc = NULL; //johnfitz
|
||||
|
@ -121,6 +122,10 @@ PFNGLBUFFERDATAARBPROC GL_BufferDataFunc = NULL; //ericw
|
|||
PFNGLBUFFERSUBDATAARBPROC GL_BufferSubDataFunc = NULL; //ericw
|
||||
PFNGLDELETEBUFFERSARBPROC GL_DeleteBuffersFunc = NULL; //ericw
|
||||
PFNGLGENBUFFERSARBPROC GL_GenBuffersFunc = NULL; //ericw
|
||||
PFNGLMAPBUFFERARBPROC GL_MapBufferFunc = NULL; //spike
|
||||
PFNGLUNMAPBUFFERARBPROC GL_UnmapBufferFunc = NULL; //spike
|
||||
PFNGLMAPBUFFERRANGEPROC GL_MapBufferRangeFunc = NULL; //spike
|
||||
PFNGLBUFFERSTORAGEPROC GL_BufferStorageFunc = NULL; //spike
|
||||
|
||||
QS_PFNGLCREATESHADERPROC GL_CreateShaderFunc = NULL; //ericw
|
||||
QS_PFNGLDELETESHADERPROC GL_DeleteShaderFunc = NULL; //ericw
|
||||
|
@ -814,6 +819,7 @@ static void VID_Restart (void)
|
|||
// one of the new objects could be given the same ID as an invalid handle
|
||||
// which is later deleted.
|
||||
|
||||
RSceneCache_Shutdown();
|
||||
TexMgr_DeleteTextureObjects ();
|
||||
GLSLGamma_DeleteTexture ();
|
||||
R_ScaleView_DeleteTexture ();
|
||||
|
@ -993,6 +999,8 @@ static void GL_CheckExtensions (void)
|
|||
GL_BufferSubDataFunc = (PFNGLBUFFERSUBDATAARBPROC) SDL_GL_GetProcAddress("glBufferSubDataARB");
|
||||
GL_DeleteBuffersFunc = (PFNGLDELETEBUFFERSARBPROC) SDL_GL_GetProcAddress("glDeleteBuffersARB");
|
||||
GL_GenBuffersFunc = (PFNGLGENBUFFERSARBPROC) SDL_GL_GetProcAddress("glGenBuffersARB");
|
||||
GL_MapBufferFunc = (PFNGLMAPBUFFERARBPROC) SDL_GL_GetProcAddress("glMapBufferARB"); //spike -- grab these too.
|
||||
GL_UnmapBufferFunc = (PFNGLUNMAPBUFFERARBPROC) SDL_GL_GetProcAddress("glUnmapBufferARB");
|
||||
if (GL_BindBufferFunc && GL_BufferDataFunc && GL_BufferSubDataFunc && GL_DeleteBuffersFunc && GL_GenBuffersFunc)
|
||||
{
|
||||
Con_Printf("FOUND: ARB_vertex_buffer_object\n");
|
||||
|
@ -1004,6 +1012,21 @@ static void GL_CheckExtensions (void)
|
|||
}
|
||||
}
|
||||
|
||||
if (gl_version_major > 4 || (gl_version_major == 4 && gl_version_minor >= 4) || GL_ParseExtensionList(gl_extensions, "GL_ARB_buffer_storage"))
|
||||
{
|
||||
GL_MapBufferRangeFunc = (PFNGLMAPBUFFERRANGEPROC) SDL_GL_GetProcAddress("glMapBufferRange");
|
||||
GL_BufferStorageFunc = (PFNGLBUFFERSTORAGEPROC) SDL_GL_GetProcAddress("glBufferStorage");
|
||||
if (gl_vbo_able && GL_MapBufferRangeFunc && GL_BufferStorageFunc)
|
||||
Con_Printf("FOUND: GL_ARB_buffer_storage\n");
|
||||
else
|
||||
Con_Warning ("GL_ARB_buffer_storage not available\n"); //doesn't really warrent a warning, but when in rome...
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_MapBufferRangeFunc = NULL;
|
||||
GL_BufferStorageFunc = NULL;
|
||||
}
|
||||
|
||||
// multitexture
|
||||
//
|
||||
if (COM_CheckParm("-nomtex"))
|
||||
|
@ -1349,6 +1372,11 @@ static void GL_Init (void)
|
|||
}
|
||||
//johnfitz
|
||||
|
||||
// query max size from hardware
|
||||
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &gl_hardware_maxsize);
|
||||
LMBLOCK_WIDTH = q_min(gl_hardware_maxsize, 512); //keeping this small potentially allows for more efficient texsubimage calls.
|
||||
LMBLOCK_HEIGHT = q_min(gl_hardware_maxsize, 16384);
|
||||
|
||||
GLAlias_CreateShaders ();
|
||||
GLWorld_CreateShaders ();
|
||||
GL_ClearBufferBindings ();
|
||||
|
|
|
@ -190,6 +190,8 @@ extern float load_subdivide_size; //johnfitz -- remember what subdivide_size val
|
|||
|
||||
extern int gl_stencilbits;
|
||||
|
||||
extern GLint gl_hardware_maxsize;
|
||||
|
||||
// Multitexture
|
||||
extern qboolean mtexenabled;
|
||||
extern qboolean gl_mtexable;
|
||||
|
@ -210,8 +212,12 @@ extern PFNGLBUFFERDATAARBPROC GL_BufferDataFunc;
|
|||
extern PFNGLBUFFERSUBDATAARBPROC GL_BufferSubDataFunc;
|
||||
extern PFNGLDELETEBUFFERSARBPROC GL_DeleteBuffersFunc;
|
||||
extern PFNGLGENBUFFERSARBPROC GL_GenBuffersFunc;
|
||||
extern PFNGLMAPBUFFERARBPROC GL_MapBufferFunc;
|
||||
extern PFNGLUNMAPBUFFERARBPROC GL_UnmapBufferFunc;
|
||||
extern qboolean gl_vbo_able;
|
||||
//ericw
|
||||
extern PFNGLMAPBUFFERRANGEPROC GL_MapBufferRangeFunc;
|
||||
extern PFNGLBUFFERSTORAGEPROC GL_BufferStorageFunc;
|
||||
|
||||
//ericw -- GLSL
|
||||
|
||||
|
@ -335,9 +341,7 @@ extern overflowtimes_t dev_overflows; //this stores the last time overflow messa
|
|||
//johnfitz -- moved here from r_brush.c
|
||||
extern int gl_lightmap_format, lightmap_bytes;
|
||||
extern qboolean lightmaps_latecached; //we need to rebuild lightmaps and model vbos before rendering.
|
||||
|
||||
#define LMBLOCK_WIDTH 256 //FIXME: make dynamic. if we have a decent card there's no real reason not to use 4k or 16k (assuming there's no lightstyles/dynamics that need uploading...)
|
||||
#define LMBLOCK_HEIGHT 256 //Alternatively, use texture arrays, which would avoid the need to switch textures as often.
|
||||
extern int LMBLOCK_WIDTH, LMBLOCK_HEIGHT; //FIXME: use texture arrays.
|
||||
|
||||
typedef struct glRect_s {
|
||||
unsigned short l,t,w,h;
|
||||
|
@ -349,9 +353,10 @@ struct lightmap_s
|
|||
qboolean modified;
|
||||
glRect_t rectchange;
|
||||
|
||||
// the lightmap texture data needs to be kept in
|
||||
// main memory so texsubimage can update properly
|
||||
byte *data;//[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT];
|
||||
// PBO use allows us to simply copy the lightmap data into a texture on-gpu, reducing stutters. It'll be writethrough though, so we need to keep things cache-friendly.
|
||||
//the data ptr points to a persistently mapped buffer so we can paint it from other threads while the main thread is doing other work so other than creation+upload we can just treat it like regular memory with slightly different cache properties.
|
||||
GLuint pbohandle;
|
||||
byte *pbodata;//[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT];
|
||||
};
|
||||
extern struct lightmap_s *lightmaps;
|
||||
extern int lightmap_count; //allocated lightmaps
|
||||
|
@ -389,7 +394,7 @@ qboolean R_CullBox (vec3_t emins, vec3_t emaxs);
|
|||
void R_StoreEfrags (efrag_t **ppefrag);
|
||||
qboolean R_CullModelForEntity (entity_t *e);
|
||||
void R_RotateForEntity (vec3_t origin, vec3_t angles, unsigned char scale);
|
||||
void R_MarkLights (dlight_t *light, vec3_t lightorg, int num, mnode_t *node);
|
||||
void R_MarkLights (dlight_t *light, vec3_t lightorg, int framecount, int num, mnode_t *node);
|
||||
|
||||
void R_InitParticles (void);
|
||||
void R_DrawParticles (void);
|
||||
|
@ -420,7 +425,7 @@ void R_RebuildAllLightmaps (void);
|
|||
int R_LightPoint (vec3_t p);
|
||||
|
||||
void GL_SubdivideSurface (msurface_t *fa);
|
||||
void R_BuildLightMap (qmodel_t *model, msurface_t *surf, byte *dest, int stride);
|
||||
void R_BuildLightMap (qmodel_t *model, msurface_t *surf, byte *dest, int stride, entity_t *currentent, int framecount, dlight_t *lights);
|
||||
void R_RenderDynamicLightmaps (qmodel_t *model, msurface_t *fa);
|
||||
void R_UploadLightmaps (void);
|
||||
|
||||
|
@ -459,6 +464,9 @@ void R_ClearTextureChains (qmodel_t *mod, texchain_t chain);
|
|||
void R_ChainSurface (msurface_t *surf, texchain_t chain);
|
||||
void R_DrawTextureChains (qmodel_t *model, entity_t *ent, texchain_t chain);
|
||||
void R_DrawWorld_Water (void);
|
||||
void RSceneCache_Cleanup(qmodel_t *mod);
|
||||
void RSceneCache_Shutdown(void);
|
||||
extern byte *skipsubmodels;
|
||||
|
||||
void GL_BindBuffer (GLenum target, GLuint buffer);
|
||||
void GL_ClearBufferBindings ();
|
||||
|
|
|
@ -2096,16 +2096,16 @@ static void PF_cl_makestatic (void)
|
|||
if (i >= cl.max_static_entities)
|
||||
{
|
||||
int ec = 64;
|
||||
entity_t **newstatics = realloc(cl.static_entities, sizeof(*newstatics) * (cl.max_static_entities+ec));
|
||||
struct cl_static_entities_s *newstatics = realloc(cl.static_entities, sizeof(*newstatics) * (cl.max_static_entities+ec));
|
||||
entity_t *newents = Hunk_Alloc(sizeof(*newents) * ec);
|
||||
if (!newstatics || !newents)
|
||||
Host_Error ("Too many static entities");
|
||||
cl.static_entities = newstatics;
|
||||
while (ec--)
|
||||
cl.static_entities[cl.max_static_entities++] = newents++;
|
||||
cl.static_entities[cl.max_static_entities++].ent = newents++;
|
||||
}
|
||||
|
||||
stat = cl.static_entities[i];
|
||||
stat = cl.static_entities[i].ent;
|
||||
cl.num_statics++;
|
||||
|
||||
SV_BuildEntityState(NULL, ent, &stat->baseline);
|
||||
|
@ -2127,8 +2127,7 @@ static void PF_cl_makestatic (void)
|
|||
|
||||
VectorCopy (ent->baseline.origin, stat->origin);
|
||||
VectorCopy (ent->baseline.angles, stat->angles);
|
||||
if (stat->model)
|
||||
R_AddEfrags (stat);
|
||||
CL_LinkStaticEnt(&cl.static_entities[i]);
|
||||
|
||||
// throw the entity away now
|
||||
ED_Free (ent);
|
||||
|
|
|
@ -295,13 +295,16 @@ typedef struct
|
|||
#if defined(USE_SDL2)
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_opengl.h>
|
||||
#include <SDL2/SDL_opengl_glext.h>
|
||||
#else
|
||||
#include <SDL/SDL.h>
|
||||
#include <SDL/SDL_opengl.h>
|
||||
#include <SDL/SDL_opengl_glext.h>
|
||||
#endif
|
||||
#else
|
||||
#include "SDL.h"
|
||||
#include "SDL_opengl.h"
|
||||
#include "SDL_opengl_glext.h"
|
||||
#endif
|
||||
#ifndef APIENTRY
|
||||
#define APIENTRY
|
||||
|
|
188
Quake/r_brush.c
188
Quake/r_brush.c
|
@ -31,14 +31,14 @@ extern cvar_t gl_zfix; // QuakeSpasm z-fighting fix
|
|||
int gl_lightmap_format;
|
||||
int lightmap_bytes;
|
||||
qboolean lightmaps_latecached;
|
||||
qboolean lightmaps_skipupdates;
|
||||
|
||||
#define MAX_SANITY_LIGHTMAPS (1u<<20)
|
||||
struct lightmap_s *lightmaps;
|
||||
int lightmap_count;
|
||||
int last_lightmap_allocated;
|
||||
int allocated[LMBLOCK_WIDTH];
|
||||
|
||||
unsigned blocklights[LMBLOCK_WIDTH*LMBLOCK_HEIGHT*3]; //johnfitz -- was 18*18, added lit support (*3) and loosened surface extents maximum (LMBLOCK_WIDTH*LMBLOCK_HEIGHT)
|
||||
static int last_lightmap_allocated;
|
||||
static int *allocated;
|
||||
int LMBLOCK_WIDTH, LMBLOCK_HEIGHT;
|
||||
|
||||
|
||||
/*
|
||||
|
@ -510,6 +510,12 @@ void R_DrawBrushModel (entity_t *e)
|
|||
mplane_t *pplane;
|
||||
qmodel_t *clmodel;
|
||||
vec3_t lightorg;
|
||||
extern byte *skipsubmodels;
|
||||
|
||||
if (e->model->submodelof == cl.worldmodel &&
|
||||
skipsubmodels &&
|
||||
skipsubmodels[e->model->submodelidx>>3]&(1u<<(e->model->submodelidx&7)))
|
||||
return; //its in the scenecache that we're drawing. don't draw it twice (and certainly not the slow way).
|
||||
|
||||
if (R_CullModelForEntity(e))
|
||||
return;
|
||||
|
@ -535,6 +541,7 @@ void R_DrawBrushModel (entity_t *e)
|
|||
// calculate dynamic lighting for bmodel if it's not an
|
||||
// instanced model
|
||||
if (clmodel->firstmodelsurface != 0 && !gl_flashblend.value)
|
||||
if (e->model->submodelof == cl.worldmodel) //R_MarkLights has a hacky assumption about cl.worldmodel that could crash if we imported some other model.
|
||||
{
|
||||
for (k=0 ; k<MAX_DLIGHTS ; k++)
|
||||
{
|
||||
|
@ -543,7 +550,7 @@ void R_DrawBrushModel (entity_t *e)
|
|||
continue;
|
||||
|
||||
VectorSubtract(cl_dlights[k].origin, e->origin, lightorg);
|
||||
R_MarkLights (&cl_dlights[k], lightorg, k,
|
||||
R_MarkLights (&cl_dlights[k], lightorg, r_framecount, k,
|
||||
clmodel->nodes + clmodel->hulls[0].firstclipnode);
|
||||
}
|
||||
}
|
||||
|
@ -704,9 +711,9 @@ dynamic:
|
|||
theRect->w = (fa->light_s-theRect->l)+smax;
|
||||
if ((theRect->h + theRect->t) < (fa->light_t + tmax))
|
||||
theRect->h = (fa->light_t-theRect->t)+tmax;
|
||||
base = lm->data;
|
||||
base = lm->pbodata;
|
||||
base += fa->light_t * LMBLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes;
|
||||
R_BuildLightMap (model, fa, base, LMBLOCK_WIDTH*lightmap_bytes);
|
||||
R_BuildLightMap (model, fa, base, LMBLOCK_WIDTH*lightmap_bytes, currententity, r_framecount, cl_dlights);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -734,9 +741,18 @@ int AllocBlock (int w, int h, int *x, int *y)
|
|||
lightmap_count++;
|
||||
lightmaps = (struct lightmap_s *) realloc(lightmaps, sizeof(*lightmaps)*lightmap_count);
|
||||
memset(&lightmaps[texnum], 0, sizeof(lightmaps[texnum]));
|
||||
lightmaps[texnum].data = (byte *) calloc(1, 4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT);
|
||||
if (GL_BufferStorageFunc)
|
||||
{ //if we have bufferstorage then we have mapbufferrange+persistent+coherent
|
||||
GL_GenBuffersFunc(1, &lightmaps[texnum].pbohandle);
|
||||
GL_BindBufferFunc(GL_PIXEL_UNPACK_BUFFER_ARB, lightmaps[texnum].pbohandle);
|
||||
GL_BufferStorageFunc(GL_PIXEL_UNPACK_BUFFER_ARB, 4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT, NULL, GL_MAP_WRITE_BIT|GL_MAP_PERSISTENT_BIT|GL_MAP_COHERENT_BIT|GL_CLIENT_STORAGE_BIT);
|
||||
lightmaps[texnum].pbodata = GL_MapBufferRangeFunc(GL_PIXEL_UNPACK_BUFFER_ARB, 0, 4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT, GL_MAP_WRITE_BIT|GL_MAP_PERSISTENT_BIT|GL_MAP_COHERENT_BIT);
|
||||
GL_BindBufferFunc(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
|
||||
}
|
||||
else
|
||||
lightmaps[texnum].pbodata = (byte *) calloc(1, 4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT);
|
||||
//as we're only tracking one texture, we don't need multiple copies of allocated any more.
|
||||
memset(allocated, 0, sizeof(allocated));
|
||||
memset(allocated, 0, sizeof(*allocated)*LMBLOCK_WIDTH);
|
||||
|
||||
lightmaps[texnum].modified = true;
|
||||
lightmaps[texnum].rectchange.l = 0;
|
||||
|
@ -804,9 +820,9 @@ void GL_CreateSurfaceLightmap (qmodel_t *model, msurface_t *surf)
|
|||
tmax = surf->extents[1]+1;
|
||||
|
||||
surf->lightmaptexturenum = AllocBlock (smax, tmax, &surf->light_s, &surf->light_t);
|
||||
base = lightmaps[surf->lightmaptexturenum].data;
|
||||
base = lightmaps[surf->lightmaptexturenum].pbodata;
|
||||
base += (surf->light_t * LMBLOCK_WIDTH + surf->light_s) * lightmap_bytes;
|
||||
R_BuildLightMap (model, surf, base, LMBLOCK_WIDTH*lightmap_bytes);
|
||||
R_BuildLightMap (model, surf, base, LMBLOCK_WIDTH*lightmap_bytes, currententity, r_framecount, cl_dlights);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -936,6 +952,8 @@ void GL_BuildLightmaps (void)
|
|||
struct lightmap_s *lm;
|
||||
qmodel_t *m;
|
||||
|
||||
RSceneCache_Shutdown(); //make sure there's nothing poking them off-thread.
|
||||
|
||||
r_framecount = 1; // no dlightcache
|
||||
|
||||
//Spike -- wipe out all the lightmap data (johnfitz -- the gltexture objects were already freed by Mod_ClearAll)
|
||||
|
@ -943,12 +961,21 @@ void GL_BuildLightmaps (void)
|
|||
{
|
||||
if (lightmaps[i].texture)
|
||||
TexMgr_FreeTexture(lightmaps[i].texture);
|
||||
free(lightmaps[i].data);
|
||||
if (lightmaps[i].pbohandle)
|
||||
{
|
||||
GL_BindBufferFunc(GL_PIXEL_UNPACK_BUFFER_ARB, lightmaps[i].pbohandle);
|
||||
GL_UnmapBufferFunc(GL_PIXEL_UNPACK_BUFFER_ARB);
|
||||
GL_BindBufferFunc(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
|
||||
GL_DeleteBuffersFunc(1, &lightmaps[i].pbohandle);
|
||||
}
|
||||
else
|
||||
free(lightmaps[i].pbodata);
|
||||
}
|
||||
free(lightmaps);
|
||||
lightmaps = NULL;
|
||||
last_lightmap_allocated = 0;
|
||||
lightmap_count = 0;
|
||||
allocated = realloc(allocated, sizeof(*allocated)*LMBLOCK_WIDTH);
|
||||
|
||||
if (gl_texture_e5bgr9)// && cl.worldmodel && (cl.worldmodel->flags&MOD_HDRLIGHTING))
|
||||
gl_lightmap_format = GL_RGB9_E5; //requires gl3, allowing for hdr lighting.
|
||||
|
@ -999,8 +1026,19 @@ void GL_BuildLightmaps (void)
|
|||
|
||||
//johnfitz -- use texture manager
|
||||
sprintf(name, "lightmap%07i",i);
|
||||
lm->texture = TexMgr_LoadImage (NULL, name, LMBLOCK_WIDTH, LMBLOCK_HEIGHT,
|
||||
SRC_LIGHTMAP, lm->data, "", (src_offset_t)lm->data, TEXPREF_LINEAR | TEXPREF_NOPICMIP | TEXPREF_PERSIST);
|
||||
|
||||
if (lm->pbohandle)
|
||||
{
|
||||
GL_BindBufferFunc(GL_PIXEL_UNPACK_BUFFER_ARB, lm->pbohandle);
|
||||
lm->texture = TexMgr_LoadImage (NULL, name, LMBLOCK_WIDTH, LMBLOCK_HEIGHT,
|
||||
SRC_LIGHTMAP, NULL, "", (src_offset_t)lm->pbodata, TEXPREF_LINEAR | TEXPREF_NOPICMIP | TEXPREF_PERSIST);
|
||||
GL_BindBufferFunc(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
lm->texture = TexMgr_LoadImage (NULL, name, LMBLOCK_WIDTH, LMBLOCK_HEIGHT,
|
||||
SRC_LIGHTMAP, lm->pbodata, "", (src_offset_t)lm->pbodata, TEXPREF_LINEAR | TEXPREF_NOPICMIP | TEXPREF_PERSIST);
|
||||
}
|
||||
//johnfitz
|
||||
}
|
||||
|
||||
|
@ -1129,7 +1167,7 @@ void GL_BuildBModelVertexBuffer (void)
|
|||
R_AddDynamicLights
|
||||
===============
|
||||
*/
|
||||
void R_AddDynamicLights (msurface_t *surf)
|
||||
static void R_AddDynamicLights (msurface_t *surf, unsigned *blocklights, entity_t *currentent, dlight_t *lights)
|
||||
{
|
||||
int lnum;
|
||||
int sd, td;
|
||||
|
@ -1152,11 +1190,21 @@ void R_AddDynamicLights (msurface_t *surf)
|
|||
if (! (surf->dlightbits[lnum >> 5] & (1U << (lnum & 31))))
|
||||
continue; // not lit by this light
|
||||
|
||||
rad = cl_dlights[lnum].radius;
|
||||
VectorSubtract(cl_dlights[lnum].origin, currententity->origin, lightofs);
|
||||
rad = lights[lnum].radius;
|
||||
if (currentent->currentangles[0] || currentent->currentangles[1] || currentent->currentangles[2])
|
||||
{
|
||||
vec3_t temp, axis[3];
|
||||
VectorSubtract(lights[lnum].origin, currentent->origin, temp);
|
||||
AngleVectors(currentent->currentangles, axis[0], axis[1], axis[2]);
|
||||
lightofs[0] = +DotProduct(temp, axis[0]);
|
||||
lightofs[1] = -DotProduct(temp, axis[1]);
|
||||
lightofs[2] = +DotProduct(temp, axis[2]);
|
||||
}
|
||||
else
|
||||
VectorSubtract(lights[lnum].origin, currentent->origin, lightofs);
|
||||
dist = DotProduct (lightofs, surf->plane->normal) - surf->plane->dist;
|
||||
rad -= fabs(dist);
|
||||
minlight = cl_dlights[lnum].minlight;
|
||||
minlight = lights[lnum].minlight;
|
||||
if (rad < minlight)
|
||||
continue;
|
||||
minlight = rad - minlight;
|
||||
|
@ -1172,9 +1220,9 @@ void R_AddDynamicLights (msurface_t *surf)
|
|||
|
||||
//johnfitz -- lit support via lordhavoc
|
||||
bl = blocklights;
|
||||
cred = cl_dlights[lnum].color[0] * 256.0f;
|
||||
cgreen = cl_dlights[lnum].color[1] * 256.0f;
|
||||
cblue = cl_dlights[lnum].color[2] * 256.0f;
|
||||
cred = lights[lnum].color[0] * 256.0f;
|
||||
cgreen = lights[lnum].color[1] * 256.0f;
|
||||
cblue = lights[lnum].color[2] * 256.0f;
|
||||
//johnfitz
|
||||
for (t = 0 ; t<tmax ; t++)
|
||||
{
|
||||
|
@ -1213,7 +1261,7 @@ R_BuildLightMap -- johnfitz -- revised for lit support via lordhavoc
|
|||
Combine and scale multiple lightmaps into the 8.8 format in blocklights
|
||||
===============
|
||||
*/
|
||||
void R_BuildLightMap (qmodel_t *model, msurface_t *surf, byte *dest, int stride)
|
||||
void R_BuildLightMap (qmodel_t *model, msurface_t *surf, byte *dest, int stride, entity_t *currentent, int framecount, dlight_t *lights)
|
||||
{
|
||||
int smax, tmax;
|
||||
int r,g,b;
|
||||
|
@ -1221,13 +1269,16 @@ void R_BuildLightMap (qmodel_t *model, msurface_t *surf, byte *dest, int stride)
|
|||
unsigned scale;
|
||||
int maps;
|
||||
unsigned *bl;
|
||||
unsigned *blocklights; //moved this to stack, so workers working on the worldmodel won't fight the main thread processing the submodels.
|
||||
|
||||
surf->cached_dlight = (surf->dlightframe == r_framecount);
|
||||
surf->cached_dlight = (surf->dlightframe == framecount);
|
||||
|
||||
smax = surf->extents[0]+1;
|
||||
tmax = surf->extents[1]+1;
|
||||
size = smax*tmax;
|
||||
|
||||
blocklights = alloca(size*3*sizeof(*blocklights)); //alloca is unsafe, but at least we memset it... should probably memset in stack order in the hopes of getting a standard stack-overflow-segfault instead of poking completely outside what the system thinks is the stack in the case of massive surfs...
|
||||
|
||||
if (model->lightdata)
|
||||
{
|
||||
// clear to no light
|
||||
|
@ -1283,13 +1334,14 @@ void R_BuildLightMap (qmodel_t *model, msurface_t *surf, byte *dest, int stride)
|
|||
}
|
||||
|
||||
// add all the dynamic lights
|
||||
if (surf->dlightframe == r_framecount)
|
||||
R_AddDynamicLights (surf);
|
||||
if (surf->dlightframe == framecount)
|
||||
R_AddDynamicLights (surf, blocklights, currentent, lights);
|
||||
}
|
||||
else
|
||||
{
|
||||
// set to full bright if no light data
|
||||
memset (&blocklights[0], 255, size * 3 * sizeof (unsigned int)); //johnfitz -- lit support via lordhavoc
|
||||
for (i=0 ; i<size ; i++)
|
||||
blocklights[i] = 0xffff; //don't use memset, it oversaturates FAR too much with hdr...
|
||||
}
|
||||
|
||||
// bound, invert, and shift
|
||||
|
@ -1404,12 +1456,26 @@ static void R_UploadLightmap(int lmap)
|
|||
|
||||
lm->modified = false;
|
||||
|
||||
if (gl_lightmap_format == GL_RGB9_E5)
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, lm->rectchange.t, LMBLOCK_WIDTH, lm->rectchange.h, GL_RGB,
|
||||
GL_UNSIGNED_INT_5_9_9_9_REV, lm->data+lm->rectchange.t*LMBLOCK_WIDTH*lightmap_bytes);
|
||||
if (lm->pbohandle)
|
||||
{
|
||||
GL_BindBufferFunc(GL_PIXEL_UNPACK_BUFFER_ARB, lm->pbohandle);
|
||||
if (gl_lightmap_format == GL_RGB9_E5)
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, lm->rectchange.t, LMBLOCK_WIDTH, lm->rectchange.h, GL_RGB,
|
||||
GL_UNSIGNED_INT_5_9_9_9_REV, (byte*)NULL+lm->rectchange.t*LMBLOCK_WIDTH*lightmap_bytes);
|
||||
else
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, lm->rectchange.t, LMBLOCK_WIDTH, lm->rectchange.h, gl_lightmap_format,
|
||||
GL_UNSIGNED_BYTE, (byte*)NULL+lm->rectchange.t*LMBLOCK_WIDTH*lightmap_bytes);
|
||||
GL_BindBufferFunc(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
|
||||
}
|
||||
else
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, lm->rectchange.t, LMBLOCK_WIDTH, lm->rectchange.h, gl_lightmap_format,
|
||||
GL_UNSIGNED_BYTE, lm->data+lm->rectchange.t*LMBLOCK_WIDTH*lightmap_bytes);
|
||||
{
|
||||
if (gl_lightmap_format == GL_RGB9_E5)
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, lm->rectchange.t, LMBLOCK_WIDTH, lm->rectchange.h, GL_RGB,
|
||||
GL_UNSIGNED_INT_5_9_9_9_REV, lm->pbodata+lm->rectchange.t*LMBLOCK_WIDTH*lightmap_bytes);
|
||||
else
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, lm->rectchange.t, LMBLOCK_WIDTH, lm->rectchange.h, gl_lightmap_format,
|
||||
GL_UNSIGNED_BYTE, lm->pbodata+lm->rectchange.t*LMBLOCK_WIDTH*lightmap_bytes);
|
||||
}
|
||||
lm->rectchange.l = LMBLOCK_WIDTH;
|
||||
lm->rectchange.t = LMBLOCK_HEIGHT;
|
||||
lm->rectchange.h = 0;
|
||||
|
@ -1429,6 +1495,9 @@ void R_UploadLightmaps (void)
|
|||
lightmaps_latecached=false;
|
||||
}
|
||||
|
||||
if (lightmaps_skipupdates)
|
||||
return;
|
||||
|
||||
for (lmap = 0; lmap < lightmap_count; lmap++)
|
||||
{
|
||||
if (!lightmaps[lmap].modified)
|
||||
|
@ -1438,9 +1507,18 @@ void R_UploadLightmaps (void)
|
|||
{
|
||||
char name[24];
|
||||
sprintf(name, "lightmap%07i",lmap);
|
||||
lightmaps[lmap].texture = TexMgr_LoadImage (NULL, name, LMBLOCK_WIDTH, LMBLOCK_HEIGHT,
|
||||
SRC_LIGHTMAP, lightmaps[lmap].data, "", (src_offset_t)lightmaps[lmap].data, TEXPREF_LINEAR | TEXPREF_NOPICMIP | TEXPREF_PERSIST);
|
||||
|
||||
if (lightmaps[lmap].pbohandle)
|
||||
{
|
||||
GL_BindBufferFunc(GL_PIXEL_UNPACK_BUFFER_ARB, lightmaps[lmap].pbohandle);
|
||||
lightmaps[lmap].texture = TexMgr_LoadImage (NULL, name, LMBLOCK_WIDTH, LMBLOCK_HEIGHT,
|
||||
SRC_LIGHTMAP, NULL, "", (src_offset_t)lightmaps[lmap].pbodata, TEXPREF_LINEAR | TEXPREF_NOPICMIP | TEXPREF_PERSIST);
|
||||
GL_BindBufferFunc(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
lightmaps[lmap].texture = TexMgr_LoadImage (NULL, name, LMBLOCK_WIDTH, LMBLOCK_HEIGHT,
|
||||
SRC_LIGHTMAP, lightmaps[lmap].pbodata, "", (src_offset_t)lightmaps[lmap].pbodata, TEXPREF_LINEAR | TEXPREF_NOPICMIP | TEXPREF_PERSIST);
|
||||
}
|
||||
lightmaps[lmap].modified = false;
|
||||
lightmaps[lmap].rectchange.l = LMBLOCK_WIDTH;
|
||||
lightmaps[lmap].rectchange.t = LMBLOCK_HEIGHT;
|
||||
|
@ -1480,9 +1558,9 @@ void R_RebuildAllLightmaps (void)
|
|||
{
|
||||
if (fa->flags & SURF_DRAWTILED)
|
||||
continue;
|
||||
base = lightmaps[fa->lightmaptexturenum].data;
|
||||
base = lightmaps[fa->lightmaptexturenum].pbodata;
|
||||
base += fa->light_t * LMBLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes;
|
||||
R_BuildLightMap (mod, fa, base, LMBLOCK_WIDTH*lightmap_bytes);
|
||||
R_BuildLightMap (mod, fa, base, LMBLOCK_WIDTH*lightmap_bytes, currententity, r_framecount, cl_dlights);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1493,18 +1571,42 @@ void R_RebuildAllLightmaps (void)
|
|||
{
|
||||
char name[24];
|
||||
sprintf(name, "lightmap%07i",i);
|
||||
lightmaps[i].texture = TexMgr_LoadImage (NULL, name, LMBLOCK_WIDTH, LMBLOCK_HEIGHT,
|
||||
SRC_LIGHTMAP, lightmaps[i].data, "", (src_offset_t)lightmaps[i].data, TEXPREF_LINEAR | TEXPREF_NOPICMIP | TEXPREF_PERSIST);
|
||||
if (lightmaps[i].pbohandle)
|
||||
{
|
||||
GL_BindBufferFunc(GL_PIXEL_UNPACK_BUFFER_ARB, lightmaps[i].pbohandle);
|
||||
lightmaps[i].texture = TexMgr_LoadImage (NULL, name, LMBLOCK_WIDTH, LMBLOCK_HEIGHT,
|
||||
SRC_LIGHTMAP, NULL, "", (src_offset_t)lightmaps[i].pbodata, TEXPREF_LINEAR | TEXPREF_NOPICMIP | TEXPREF_PERSIST);
|
||||
GL_BindBufferFunc(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
lightmaps[i].texture = TexMgr_LoadImage (NULL, name, LMBLOCK_WIDTH, LMBLOCK_HEIGHT,
|
||||
SRC_LIGHTMAP, lightmaps[i].pbodata, "", (src_offset_t)lightmaps[i].pbodata, TEXPREF_LINEAR | TEXPREF_NOPICMIP | TEXPREF_PERSIST);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_Bind (lightmaps[i].texture);
|
||||
if (gl_lightmap_format == GL_RGB9_E5)
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, LMBLOCK_WIDTH, LMBLOCK_HEIGHT, GL_RGB,
|
||||
GL_UNSIGNED_INT_5_9_9_9_REV, lightmaps[i].data);
|
||||
if (lightmaps[i].pbohandle)
|
||||
{
|
||||
GL_BindBufferFunc(GL_PIXEL_UNPACK_BUFFER_ARB, lightmaps[i].pbohandle);
|
||||
if (gl_lightmap_format == GL_RGB9_E5)
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, LMBLOCK_WIDTH, LMBLOCK_HEIGHT, GL_RGB,
|
||||
GL_UNSIGNED_INT_5_9_9_9_REV, NULL);
|
||||
else
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, LMBLOCK_WIDTH, LMBLOCK_HEIGHT, gl_lightmap_format,
|
||||
GL_UNSIGNED_BYTE, NULL);
|
||||
GL_BindBufferFunc(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
|
||||
}
|
||||
else
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, LMBLOCK_WIDTH, LMBLOCK_HEIGHT, gl_lightmap_format,
|
||||
GL_UNSIGNED_BYTE, lightmaps[i].data);
|
||||
{
|
||||
if (gl_lightmap_format == GL_RGB9_E5)
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, LMBLOCK_WIDTH, LMBLOCK_HEIGHT, GL_RGB,
|
||||
GL_UNSIGNED_INT_5_9_9_9_REV, lightmaps[i].pbodata);
|
||||
else
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, LMBLOCK_WIDTH, LMBLOCK_HEIGHT, gl_lightmap_format,
|
||||
GL_UNSIGNED_BYTE, lightmaps[i].pbodata);
|
||||
}
|
||||
}
|
||||
|
||||
lightmaps[i].modified = false;
|
||||
|
|
1106
Quake/r_world.c
1106
Quake/r_world.c
File diff suppressed because it is too large
Load diff
|
@ -163,7 +163,9 @@ void R_ViewChanged (vrect_t *pvrect, int lineadj, float aspect);
|
|||
//void R_InitSky (struct texture_s *mt); // called at level load
|
||||
|
||||
void R_CheckEfrags (void); //johnfitz
|
||||
void R_AddEfrags (entity_t *ent);
|
||||
//void R_AddEfrags (entity_t *ent);
|
||||
struct cl_static_entities_s;
|
||||
void CL_LinkStaticEnt(struct cl_static_entities_s *ent);
|
||||
|
||||
void R_NewMap (void);
|
||||
|
||||
|
|
Loading…
Reference in a new issue