1
0
Fork 0
forked from fte/fteqw

finally fix fbsp lightgrid.

fix issue where framegroups with no poses were causing a crash. now causes spam.
implement sneaky trick to munge lightmaps a little, greatly accelerating stuff like sock's map.
fix q3 physics issue (was probably bugging out q2 too).

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4922 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2015-06-28 00:42:00 +00:00
parent d81bf36c68
commit 5ef22569cd
10 changed files with 181 additions and 127 deletions

View file

@ -2735,7 +2735,7 @@ void Surf_BuildModelLightmaps (model_t *m)
{ {
if (lightmap_bgra && lightmap_bytes == 4) if (lightmap_bgra && lightmap_bytes == 4)
{ {
for (j = 0; j < m->lightmaps.width*m->lightmaps.height; j++, dst += 4, src += 3) for (j = min((m->lightdatasize-i*m->lightmaps.width*m->lightmaps.height*3)/3,m->lightmaps.width*m->lightmaps.height); j > 0; j--, dst += 4, src += 3)
{ {
dst[0] = src[2]; dst[0] = src[2];
dst[1] = src[1]; dst[1] = src[1];

View file

@ -1825,6 +1825,8 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in
else else
#endif #endif
{ {
//FIXME: replace most of this logic with Alias_BuildSkelLerps
frame1 = e->framestate.g[FS_REG].frame[0]; frame1 = e->framestate.g[FS_REG].frame[0];
frame2 = e->framestate.g[FS_REG].frame[1]; frame2 = e->framestate.g[FS_REG].frame[1];
lerp = e->framestate.g[FS_REG].lerpweight[1]; //FIXME lerp = e->framestate.g[FS_REG].lerpweight[1]; //FIXME
@ -1860,6 +1862,15 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in
g1 = &inf->ofsanimations[frame1]; g1 = &inf->ofsanimations[frame1];
g2 = &inf->ofsanimations[frame2]; g2 = &inf->ofsanimations[frame2];
if (!inf->numanimations || !g1->numposes || !g2->numposes)
{
Con_Printf("Invalid animation data on entity with model %s\n", e->model->name);
//no animation data. panic!
memset(mesh, 0, sizeof(*mesh));
*vbop = NULL;
return false;
}
if (g1 == g2) //lerping within group is only done if not changing group if (g1 == g2) //lerping within group is only done if not changing group
{ {
lerp = fg1time*g1->rate; lerp = fg1time*g1->rate;

View file

@ -2895,6 +2895,7 @@ qboolean CModQ3_LoadRFaces (model_t *mod, qbyte *mod_base, lump_t *l)
out->lightmaptexturenums[sty] = -1; out->lightmaptexturenums[sty] = -1;
} }
out->lmshift = LMSHIFT_DEFAULT; out->lmshift = LMSHIFT_DEFAULT;
//fixme: determine texturemins from lightmap_origin
out->extents[0] = (LittleLong(in->lightmap_width)-1)<<out->lmshift; out->extents[0] = (LittleLong(in->lightmap_width)-1)<<out->lmshift;
out->extents[1] = (LittleLong(in->lightmap_height)-1)<<out->lmshift; out->extents[1] = (LittleLong(in->lightmap_height)-1)<<out->lmshift;
out->samples=NULL; out->samples=NULL;
@ -3466,6 +3467,7 @@ void CModQ3_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l)
loadmodel->engineflags |= MDLF_RGBLIGHTING; loadmodel->engineflags |= MDLF_RGBLIGHTING;
loadmodel->lightdata = out = ZG_Malloc(&loadmodel->memgroup, samples); loadmodel->lightdata = out = ZG_Malloc(&loadmodel->memgroup, samples);
loadmodel->lightdatasize = samples;
//be careful here, q3bsp deluxemapping is done using interleaving. we want to unoverbright ONLY lightmaps and not deluxemaps. //be careful here, q3bsp deluxemapping is done using interleaving. we want to unoverbright ONLY lightmaps and not deluxemaps.
for (m = 0; m < maps; m++) for (m = 0; m < maps; m++)
@ -4451,23 +4453,19 @@ void CM_InitBoxHull (void)
{ {
side = i&1; side = i&1;
// brush sides //the pointers
s = &box_sides[i]; s = &box_sides[i];
s->plane = box_planes + (i*2+side); p = &box_planes[i];
// brush sides
s->plane = p;
s->surface = &nullsurface; s->surface = &nullsurface;
// planes // planes
p = &box_planes[i*2]; p->type = ((i>=3)?i-3:i);
p->type = i>>1;
p->signbits = 0; p->signbits = 0;
VectorClear (p->normal); VectorClear (p->normal);
p->normal[i>>1] = 1; p->normal[p->type] = ((i>=3)?-1:1);
p = &box_planes[i*2+1];
p->type = 3 + (i>>1);
p->signbits = 0;
VectorClear (p->normal);
p->normal[i>>1] = -1;
} }
} }
@ -4483,17 +4481,11 @@ BSP trees instead of being compared directly.
void CM_SetTempboxSize (vec3_t mins, vec3_t maxs) void CM_SetTempboxSize (vec3_t mins, vec3_t maxs)
{ {
box_planes[0].dist = maxs[0]; box_planes[0].dist = maxs[0];
box_planes[1].dist = -maxs[0]; box_planes[1].dist = maxs[1];
box_planes[2].dist = mins[0]; box_planes[2].dist = maxs[2];
box_planes[3].dist = -mins[0]; box_planes[3].dist = -mins[0];
box_planes[4].dist = maxs[1]; box_planes[4].dist = -mins[1];
box_planes[5].dist = -maxs[1]; box_planes[5].dist = -mins[2];
box_planes[6].dist = mins[1];
box_planes[7].dist = -mins[1];
box_planes[8].dist = maxs[2];
box_planes[9].dist = -maxs[2];
box_planes[10].dist = mins[2];
box_planes[11].dist = -mins[2];
} }
model_t *CM_TempBoxModel(vec3_t mins, vec3_t maxs) model_t *CM_TempBoxModel(vec3_t mins, vec3_t maxs)
@ -5837,6 +5829,12 @@ static qboolean BM_NativeTrace(model_t *model, int forcehullnum, int frame, vec3
if (contents & FTECONTENTS_BODY) if (contents & FTECONTENTS_BODY)
{ {
trace_contents = contents;
VectorCopy (start, trace_start);
VectorCopy (end, trace_end);
VectorCopy (mins, trace_mins);
VectorCopy (maxs, trace_maxs);
if (trace_mins[0] == 0 && trace_mins[1] == 0 && trace_mins[2] == 0 && trace_maxs[0] == 0 && trace_maxs[1] == 0 && trace_maxs[2] == 0) if (trace_mins[0] == 0 && trace_mins[1] == 0 && trace_mins[2] == 0 && trace_maxs[0] == 0 && trace_maxs[1] == 0 && trace_maxs[2] == 0)
trace_shape = shape_ispoint; trace_shape = shape_ispoint;
else if (capsule) else if (capsule)
@ -5844,12 +5842,6 @@ static qboolean BM_NativeTrace(model_t *model, int forcehullnum, int frame, vec3
else else
trace_shape = shape_isbox; trace_shape = shape_isbox;
trace_contents = contents;
VectorCopy (start, trace_start);
VectorCopy (end, trace_end);
VectorCopy (mins, trace_mins);
VectorCopy (maxs, trace_maxs);
CM_ClipBoxToBrush (trace_mins, trace_maxs, trace_start, trace_end, trace, &box_brush); CM_ClipBoxToBrush (trace_mins, trace_maxs, trace_start, trace_end, trace, &box_brush);
} }

View file

@ -1444,6 +1444,11 @@ void R_GAlias_DrawBatch(batch_t *batch)
{ {
/*needrecolour =*/ Alias_GAliasBuildMesh(&mesh, &batch->vbo, inf, surfnum, e, batch->shader->prog && batch->shader->prog->permu[PERMUTATION_SKELETAL].handle.glsl.handle); /*needrecolour =*/ Alias_GAliasBuildMesh(&mesh, &batch->vbo, inf, surfnum, e, batch->shader->prog && batch->shader->prog->permu[PERMUTATION_SKELETAL].handle.glsl.handle);
batch->mesh = &meshl; batch->mesh = &meshl;
if (!mesh.numindexes)
{
batch->meshes = 0; //something went screwy
batch->mesh = NULL;
}
return; return;
} }
} }

View file

@ -3944,6 +3944,14 @@ static void DrawMeshes(void)
shaderstate.pendingvertexvbo = shaderstate.sourcevbo->coord.gl.vbo; shaderstate.pendingvertexvbo = shaderstate.sourcevbo->coord.gl.vbo;
} }
#ifdef _DEBUG
if (!shaderstate.pendingvertexpointer && !shaderstate.pendingvertexvbo)
{
Con_Printf(CON_ERROR "pendingvertexpointer+vbo are both null! shader is %s\n", shaderstate.curshader->name);
return;
}
#endif
#ifdef FTE_TARGET_WEB #ifdef FTE_TARGET_WEB
if (!shaderstate.pendingvertexvbo) if (!shaderstate.pendingvertexvbo)
return; return;
@ -4499,7 +4507,7 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
continue; continue;
} }
if (bs->flags & SHADER_NODRAW) if ((bs->flags & SHADER_NODRAW) || !batch->meshes)
continue; continue;
if (bs->flags & SHADER_NODLIGHT) if (bs->flags & SHADER_NODLIGHT)
if (shaderstate.mode == BEM_LIGHT) if (shaderstate.mode == BEM_LIGHT)

View file

@ -125,7 +125,7 @@ static void Mod_MemList_f(void)
#ifndef SERVERONLY #ifndef SERVERONLY
static void Mod_BatchList_f(void) static void Mod_BatchList_f(void)
{ {
int m, i; int m, i, lm;
model_t *mod; model_t *mod;
batch_t *batch; batch_t *batch;
unsigned int count; unsigned int count;
@ -2663,14 +2663,14 @@ void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, builddata_t *co
} }
#ifndef SERVERONLY #ifndef SERVERONLY
static void Mod_Batches_BuildModelMeshes(model_t *mod, int maxverts, int maxindicies, void (*build)(model_t *mod, msurface_t *surf, builddata_t *bd), builddata_t *bd) static void Mod_Batches_BuildModelMeshes(model_t *mod, int maxverts, int maxindicies, void (*build)(model_t *mod, msurface_t *surf, builddata_t *bd), builddata_t *bd, int lmmerge)
{ {
batch_t *batch; batch_t *batch;
msurface_t *surf; msurface_t *surf;
mesh_t *mesh; mesh_t *mesh;
int numverts = 0; int numverts = 0;
int numindicies = 0; int numindicies = 0;
int j; int j, i;
int sortid; int sortid;
int sty; int sty;
vbo_t vbo; vbo_t vbo;
@ -2749,6 +2749,23 @@ static void Mod_Batches_BuildModelMeshes(model_t *mod, int maxverts, int maxindi
mesh->vbofirstelement = 0; mesh->vbofirstelement = 0;
build(mod, surf, bd); build(mod, surf, bd);
if (lmmerge != 1)
for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
{
if (surf->lightmaptexturenums[sty] >= 0)
{
if (mesh->lmst_array[sty])
{
for (i = 0; i < mesh->numvertexes; i++)
{
mesh->lmst_array[sty][i][1] += surf->lightmaptexturenums[sty] % lmmerge;
mesh->lmst_array[sty][i][1] /= lmmerge;
}
}
surf->lightmaptexturenums[sty] /= lmmerge;
}
}
} }
batch->meshes = 0; batch->meshes = 0;
batch->firstmesh = 0; batch->firstmesh = 0;
@ -2810,10 +2827,11 @@ void Mod_UpdateBatchShader_Q2 (struct batch_s *batch)
batch->shader = base->shader; batch->shader = base->shader;
} }
#define lmmerge(i) ((i>=0)?i/merge:i)
/* /*
batch->firstmesh is set only in and for this function, its cleared out elsewhere batch->firstmesh is set only in and for this function, its cleared out elsewhere
*/ */
static void Mod_Batches_Generate(model_t *mod) static int Mod_Batches_Generate(model_t *mod)
{ {
int i; int i;
msurface_t *surf; msurface_t *surf;
@ -2822,6 +2840,18 @@ static void Mod_Batches_Generate(model_t *mod)
batch_t *batch, *lbatch = NULL; batch_t *batch, *lbatch = NULL;
vec4_t plane; vec4_t plane;
int merge = sh_config.texture_maxsize / mod->lightmaps.height;
while (merge > mod->lightmaps.count)
merge /= 2;
if (merge < 1)//erk?
merge = 1;
mod->lightmaps.count = (mod->lightmaps.count+merge-1) & ~(merge-1);
mod->lightmaps.count /= merge;
mod->lightmaps.height *= merge;
//for each surface, find a suitable batch to insert it into. //for each surface, find a suitable batch to insert it into.
//we use 'firstmesh' to avoid chucking out too many verts in a single vbo (gl2 hardware tends to have a 16bit limit) //we use 'firstmesh' to avoid chucking out too many verts in a single vbo (gl2 hardware tends to have a 16bit limit)
for (i=0; i<mod->nummodelsurfaces; i++) for (i=0; i<mod->nummodelsurfaces; i++)
@ -2862,13 +2892,13 @@ static void Mod_Batches_Generate(model_t *mod)
if (lbatch && ( if (lbatch && (
lbatch->texture == surf->texinfo->texture && lbatch->texture == surf->texinfo->texture &&
lbatch->lightmap[0] == surf->lightmaptexturenums[0] && lbatch->lightmap[0] == lmmerge(surf->lightmaptexturenums[0]) &&
Vector4Compare(plane, lbatch->plane) && Vector4Compare(plane, lbatch->plane) &&
lbatch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES) && lbatch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES) &&
#if MAXRLIGHTMAPS > 1 #if MAXRLIGHTMAPS > 1
lbatch->lightmap[1] == surf->lightmaptexturenums[1] && lbatch->lightmap[1] == lmmerge(surf->lightmaptexturenums[1]) &&
lbatch->lightmap[2] == surf->lightmaptexturenums[2] && lbatch->lightmap[2] == lmmerge(surf->lightmaptexturenums[2]) &&
lbatch->lightmap[3] == surf->lightmaptexturenums[3] && lbatch->lightmap[3] == lmmerge(surf->lightmaptexturenums[3]) &&
#endif #endif
lbatch->fog == surf->fog) lbatch->fog == surf->fog)
batch = lbatch; batch = lbatch;
@ -2878,13 +2908,13 @@ static void Mod_Batches_Generate(model_t *mod)
{ {
if ( if (
batch->texture == surf->texinfo->texture && batch->texture == surf->texinfo->texture &&
batch->lightmap[0] == surf->lightmaptexturenums[0] && batch->lightmap[0] == lmmerge(surf->lightmaptexturenums[0]) &&
Vector4Compare(plane, batch->plane) && Vector4Compare(plane, batch->plane) &&
batch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES && batch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES &&
#if MAXRLIGHTMAPS > 1 #if MAXRLIGHTMAPS > 1
batch->lightmap[1] == surf->lightmaptexturenums[1] && batch->lightmap[1] == lmmerge(surf->lightmaptexturenums[1]) &&
batch->lightmap[2] == surf->lightmaptexturenums[2] && batch->lightmap[2] == lmmerge(surf->lightmaptexturenums[2]) &&
batch->lightmap[3] == surf->lightmaptexturenums[3] && batch->lightmap[3] == lmmerge(surf->lightmaptexturenums[3]) &&
#endif #endif
batch->fog == surf->fog) batch->fog == surf->fog)
break; break;
@ -2893,11 +2923,11 @@ static void Mod_Batches_Generate(model_t *mod)
if (!batch) if (!batch)
{ {
batch = ZG_Malloc(&mod->memgroup, sizeof(*batch)); batch = ZG_Malloc(&mod->memgroup, sizeof(*batch));
batch->lightmap[0] = surf->lightmaptexturenums[0]; batch->lightmap[0] = lmmerge(surf->lightmaptexturenums[0]);
#if MAXRLIGHTMAPS > 1 #if MAXRLIGHTMAPS > 1
batch->lightmap[1] = surf->lightmaptexturenums[1]; batch->lightmap[1] = lmmerge(surf->lightmaptexturenums[1]);
batch->lightmap[2] = surf->lightmaptexturenums[2]; batch->lightmap[2] = lmmerge(surf->lightmaptexturenums[2]);
batch->lightmap[3] = surf->lightmaptexturenums[3]; batch->lightmap[3] = lmmerge(surf->lightmaptexturenums[3]);
#endif #endif
batch->texture = surf->texinfo->texture; batch->texture = surf->texinfo->texture;
batch->shader = surf->texinfo->texture->shader; batch->shader = surf->texinfo->texture->shader;
@ -2922,6 +2952,9 @@ static void Mod_Batches_Generate(model_t *mod)
lbatch = batch; lbatch = batch;
} }
return merge;
#undef lmmerge
} }
void Mod_LightmapAllocInit(lmalloc_t *lmallocator, qboolean hasdeluxe, unsigned int width, unsigned int height, int firstlm) void Mod_LightmapAllocInit(lmalloc_t *lmallocator, qboolean hasdeluxe, unsigned int width, unsigned int height, int firstlm)
@ -2938,7 +2971,7 @@ void Mod_LightmapAllocDone(lmalloc_t *lmallocator, model_t *mod)
{ {
mod->lightmaps.first = lmallocator->firstlm; mod->lightmaps.first = lmallocator->firstlm;
mod->lightmaps.count = (lmallocator->lmnum - lmallocator->firstlm); mod->lightmaps.count = (lmallocator->lmnum - lmallocator->firstlm);
if (lmallocator->allocated[0]) if (lmallocator->allocated[0]) //lmnum was only *COMPLETE* lightmaps that we allocated, and does not include the one we're currently building.
mod->lightmaps.count++; mod->lightmaps.count++;
if (lmallocator->deluxe) if (lmallocator->deluxe)
@ -3015,7 +3048,7 @@ static void Mod_LightmapAllocSurf(lmalloc_t *lmallocator, msurface_t *surf, int
Mod_LightmapAllocBlock (lmallocator, smax, tmax, &surf->light_s[surfstyle], &surf->light_t[surfstyle], &surf->lightmaptexturenums[surfstyle]); Mod_LightmapAllocBlock (lmallocator, smax, tmax, &surf->light_s[surfstyle], &surf->light_t[surfstyle], &surf->lightmaptexturenums[surfstyle]);
} }
static void Mod_Batches_SplitLightmaps(model_t *mod) static void Mod_Batches_SplitLightmaps(model_t *mod, int lmmerge)
{ {
batch_t *batch; batch_t *batch;
batch_t *nb; batch_t *nb;
@ -3023,14 +3056,13 @@ static void Mod_Batches_SplitLightmaps(model_t *mod)
msurface_t *surf; msurface_t *surf;
int sty; int sty;
for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++) for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
for (batch = mod->batches[sortid]; batch != NULL; batch = batch->next) for (batch = mod->batches[sortid]; batch != NULL; batch = batch->next)
{ {
surf = (msurface_t*)batch->mesh[0]; surf = (msurface_t*)batch->mesh[0];
for (sty = 0; sty < MAXRLIGHTMAPS; sty++) for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
{ {
batch->lightmap[sty] = surf->lightmaptexturenums[sty]; batch->lightmap[sty] = (surf->lightmaptexturenums[sty]>=0)?surf->lightmaptexturenums[sty]/lmmerge:surf->lightmaptexturenums[sty];
batch->lmlightstyle[sty] = surf->styles[sty]; batch->lmlightstyle[sty] = surf->styles[sty];
} }
@ -3039,7 +3071,8 @@ static void Mod_Batches_SplitLightmaps(model_t *mod)
surf = (msurface_t*)batch->mesh[j]; surf = (msurface_t*)batch->mesh[j];
for (sty = 0; sty < MAXRLIGHTMAPS; sty++) for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
{ {
if (surf->lightmaptexturenums[sty] != batch->lightmap[sty] || int lm = (surf->lightmaptexturenums[sty]>=0)?surf->lightmaptexturenums[sty]/lmmerge:surf->lightmaptexturenums[sty];
if (lm != batch->lightmap[sty] ||
//fixme: we should merge later (reverted matching) surfaces into the prior batch //fixme: we should merge later (reverted matching) surfaces into the prior batch
surf->styles[sty] != batch->lmlightstyle[sty] || surf->styles[sty] != batch->lmlightstyle[sty] ||
surf->vlstyles[sty] != batch->vtlightstyle[sty]) surf->vlstyles[sty] != batch->vtlightstyle[sty])
@ -3056,7 +3089,8 @@ static void Mod_Batches_SplitLightmaps(model_t *mod)
batch->maxmeshes = j; batch->maxmeshes = j;
for (sty = 0; sty < MAXRLIGHTMAPS; sty++) for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
{ {
nb->lightmap[sty] = surf->lightmaptexturenums[sty]; int lm = (surf->lightmaptexturenums[sty]>=0)?surf->lightmaptexturenums[sty]/lmmerge:surf->lightmaptexturenums[sty];
nb->lightmap[sty] = lm;
nb->lmlightstyle[sty] = surf->styles[sty]; nb->lmlightstyle[sty] = surf->styles[sty];
nb->vtlightstyle[sty] = surf->vlstyles[sty]; nb->vtlightstyle[sty] = surf->vlstyles[sty];
} }
@ -3179,6 +3213,7 @@ static void Mod_Batches_Build(model_t *mod, builddata_t *bd)
int sortid; int sortid;
batch_t *batch; batch_t *batch;
mesh_t *meshlist; mesh_t *meshlist;
int merge = 1;
currentmodel = mod; currentmodel = mod;
@ -3208,7 +3243,7 @@ static void Mod_Batches_Build(model_t *mod, builddata_t *bd)
} }
/*assign each mesh to a batch, generating as needed*/ /*assign each mesh to a batch, generating as needed*/
Mod_Batches_Generate(mod); merge = Mod_Batches_Generate(mod);
bmeshes = ZG_Malloc(&mod->memgroup, sizeof(*bmeshes)*mod->nummodelsurfaces*R_MAX_RECURSE); bmeshes = ZG_Malloc(&mod->memgroup, sizeof(*bmeshes)*mod->nummodelsurfaces*R_MAX_RECURSE);
@ -3227,17 +3262,17 @@ static void Mod_Batches_Build(model_t *mod, builddata_t *bd)
surf->sbatch->mesh[surf->sbatch->meshes++] = (mesh_t*)surf; surf->sbatch->mesh[surf->sbatch->meshes++] = (mesh_t*)surf;
} }
if (bd) //q3 if (bd) //q3
Mod_Batches_SplitLightmaps(mod); Mod_Batches_SplitLightmaps(mod, merge);
else else
Mod_Batches_AllocLightmaps(mod); Mod_Batches_AllocLightmaps(mod);
if (!bd) if (!bd)
{ {
mod->lightmaps.surfstyles = 1; mod->lightmaps.surfstyles = 1;
Mod_Batches_BuildModelMeshes(mod, numverts, numindicies, ModQ1_Batches_BuildQ1Q2Poly, bd); Mod_Batches_BuildModelMeshes(mod, numverts, numindicies, ModQ1_Batches_BuildQ1Q2Poly, bd, merge);
} }
else else
Mod_Batches_BuildModelMeshes(mod, numverts, numindicies, bd->buildfunc, bd); Mod_Batches_BuildModelMeshes(mod, numverts, numindicies, bd->buildfunc, bd, merge);
if (BE_GenBrushModelVBO) if (BE_GenBrushModelVBO)
BE_GenBrushModelVBO(mod); BE_GenBrushModelVBO(mod);

View file

@ -1086,24 +1086,26 @@ LIGHT SAMPLING
mplane_t *lightplane; mplane_t *lightplane;
vec3_t lightspot; vec3_t lightspot;
static void GLQ3_AddLatLong(qbyte latlong[2], vec3_t dir, float mag)
{
float lat = (float)latlong[0] * (2 * M_PI)*(1.0 / 255.0);
float lng = (float)latlong[1] * (2 * M_PI)*(1.0 / 255.0);
dir[0] += mag * cos ( lng ) * sin ( lat );
dir[1] += mag * sin ( lng ) * sin ( lat );
dir[2] += mag * cos ( lat );
}
void GLQ3_LightGrid(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir) void GLQ3_LightGrid(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir)
{ {
q3lightgridinfo_t *lg = (q3lightgridinfo_t *)cl.worldmodel->lightgrid; q3lightgridinfo_t *lg = (q3lightgridinfo_t *)cl.worldmodel->lightgrid;
int index[8]; int index[8];
int vi[3]; int vi[3];
int i, j; int i, j;
float t[8], direction_uv[3]; float t[8];
vec3_t vf, vf2; vec3_t vf, vf2;
vec3_t ambient, diffuse; vec3_t ambient, diffuse, direction;
if (res_dir) if (!lg || (!lg->lightgrid && !lg->rbspelements) || lg->numlightgridelems < 1)
{
res_dir[0] = 1;
res_dir[1] = 1;
res_dir[2] = 0.1;
}
if (!lg || !lg->lightgrid)
{ {
if(res_ambient) if(res_ambient)
{ {
@ -1118,6 +1120,13 @@ void GLQ3_LightGrid(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_a
res_diffuse[1] = 192; res_diffuse[1] = 192;
res_diffuse[2] = 192; res_diffuse[2] = 192;
} }
if (res_dir)
{
res_dir[0] = 1;
res_dir[1] = 1;
res_dir[2] = 0.1;
}
return; return;
} }
@ -1132,73 +1141,64 @@ void GLQ3_LightGrid(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_a
vf2[i] = 1.0f - vf[i]; vf2[i] = 1.0f - vf[i];
} }
index[0] = vi[2]*lg->gridBounds[3] + vi[1]*lg->gridBounds[0] + vi[0];
index[1] = index[0] + lg->gridBounds[0];
index[2] = index[0] + lg->gridBounds[3];
index[3] = index[2] + lg->gridBounds[0];
index[4] = index[0]+(index[0]<(lg->numlightgridelems-1));
index[5] = index[1]+(index[1]<(lg->numlightgridelems-1));
index[6] = index[2]+(index[2]<(lg->numlightgridelems-1));
index[7] = index[3]+(index[3]<(lg->numlightgridelems-1));
for ( i = 0; i < 8; i++ ) for ( i = 0; i < 8; i++ )
{ {
if ( index[i] < 0 || index[i] >= (lg->numlightgridelems) ) //bound it properly
index[i] = bound(0, vi[0]+((i&1)?1:0), lg->gridBounds[0]-1) * 1 +
bound(0, vi[1]+((i&2)?1:0), lg->gridBounds[1]-1) * lg->gridBounds[0] +
bound(0, vi[2]+((i&4)?1:0), lg->gridBounds[2]-1) * lg->gridBounds[3] ;
t[i] = ((i&1)?vf[0]:vf2[0]) *
((i&2)?vf[1]:vf2[1]) *
((i&4)?vf[2]:vf2[2]) ;
}
//rbsp has a separate grid->index lookup for compression.
if (lg->rbspindexes)
{ {
res_ambient[0] = 255; //out of the map for (i = 0; i < 8; i++)
res_ambient[1] = 255; index[i] = lg->rbspindexes[index[i]];
res_ambient[2] = 255; }
if (res_diffuse) VectorClear(ambient);
VectorClear(diffuse);
VectorClear(direction);
if (lg->rbspelements)
{ {
res_diffuse[0] = 255; for (i = 0; i < 8; i++)
res_diffuse[1] = 255; { //rbsp has up to 4 styles per grid element, which needs to be scaled by that style's current value
res_diffuse[2] = 255; float tot = 0;
} for (j = 0; j < countof(lg->rbspelements[index[i]].styles); j++)
return;
}
}
t[0] = vf2[0] * vf2[1] * vf2[2];
t[1] = vf[0] * vf2[1] * vf2[2];
t[2] = vf2[0] * vf[1] * vf2[2];
t[3] = vf[0] * vf[1] * vf2[2];
t[4] = vf2[0] * vf2[1] * vf[2];
t[5] = vf[0] * vf2[1] * vf[2];
t[6] = vf2[0] * vf[1] * vf[2];
t[7] = vf[0] * vf[1] * vf[2];
for ( j = 0; j < 3; j++ )
{ {
ambient[j] = 0; qbyte st = lg->rbspelements[index[i]].styles[j];
diffuse[j] = 0; if (st != 255)
for ( i = 0; i < 4; i++ )
{ {
ambient[j] += t[i*2] * lg->lightgrid[ index[i]].ambient[j]; float mag = d_lightstylevalue[st] * 1.0/255 * t[i];
ambient[j] += t[i*2+1] * lg->lightgrid[ index[i+4]].ambient[j]; //FIXME: cl_lightstyle[st].colours[rgb]
VectorMA (ambient, mag, lg->rbspelements[index[i]].ambient[j], ambient);
diffuse[j] += t[i*2] * lg->lightgrid[ index[i]].diffuse[j]; VectorMA (diffuse, mag, lg->rbspelements[index[i]].diffuse[j], diffuse);
diffuse[j] += t[i*2+1] * lg->lightgrid[ index[i+4]].diffuse[j]; tot += mag;
} }
} }
GLQ3_AddLatLong(lg->rbspelements[index[i]].direction, direction, tot);
for ( j = 0; j < 2; j++ ) }
}
else
{ {
direction_uv[j] = 0; for (i = 0; i < 8; i++)
for ( i = 0; i < 4; i++ )
{ {
direction_uv[j] += t[i*2] * lg->lightgrid[ index[i]].direction[j]; VectorMA (ambient, t[i], lg->lightgrid[index[i]].ambient, ambient);
direction_uv[j] += t[i*2+1] * lg->lightgrid[ index[i+4]].direction[j]; VectorMA (diffuse, t[i], lg->lightgrid[index[i]].diffuse, diffuse);
GLQ3_AddLatLong(lg->lightgrid[index[i]].direction, direction, t[i]);
} }
direction_uv[j] = anglemod ( direction_uv[j] ); VectorScale(ambient, d_lightstylevalue[0]/255.0, ambient);
VectorScale(diffuse, d_lightstylevalue[0]/255.0, diffuse);
//FIXME: cl_lightstyle[0].colours[rgb]
} }
VectorScale(ambient, 4, ambient); //q3bsp has *4 overbrighting.
VectorScale(diffuse, 4, diffuse); // VectorScale(ambient, 4, ambient);
// VectorScale(diffuse, 4, diffuse);
/*ambient is the min level*/ /*ambient is the min level*/
/*diffuse is the max level*/ /*diffuse is the max level*/
@ -1206,11 +1206,7 @@ void GLQ3_LightGrid(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_a
if (res_diffuse) if (res_diffuse)
VectorAdd(diffuse, ambient, res_diffuse); VectorAdd(diffuse, ambient, res_diffuse);
if (res_dir) if (res_dir)
{ VectorCopy(direction, res_dir);
vec3_t right, left;
direction_uv[2] = 0;
AngleVectors(direction_uv, res_dir, right, left);
}
} }
int GLRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) int GLRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)

View file

@ -484,6 +484,9 @@ void GLR_TimeRefresh_f (void)
if (frames < 1) if (frames < 1)
frames = 128; frames = 128;
if (!r_refdef.playerview)
r_refdef.playerview = &cl.playerview[0];
if (finish == 2) if (finish == 2)
{ {
qglFinish (); qglFinish ();

View file

@ -156,14 +156,18 @@ static void Q3G_UnlinkEntity(q3sharedEntity_t *ent)
static model_t *Q3G_GetCModel(unsigned int modelindex) static model_t *Q3G_GetCModel(unsigned int modelindex)
{ {
//0 is world
//1 == *1
//this is not how quake's precaches normally work.
modelindex++;
if ((unsigned int)modelindex < MAX_PRECACHE_MODELS) if ((unsigned int)modelindex < MAX_PRECACHE_MODELS)
{ {
if (!sv.models[modelindex]) if (!sv.models[modelindex])
{ {
if (modelindex == 0) if (modelindex == 1)
sv.models[modelindex] = sv.world.worldmodel; sv.models[modelindex] = sv.world.worldmodel;
else else
sv.models[modelindex] = Mod_ForName(Mod_FixName(va("*%i", modelindex), sv.modelname), MLV_WARN); sv.models[modelindex] = Mod_ForName(Mod_FixName(va("*%i", modelindex-1), sv.modelname), MLV_WARN);
} }
if (sv.models[modelindex]->loadstate == MLS_LOADING) if (sv.models[modelindex]->loadstate == MLS_LOADING)

View file

@ -903,7 +903,7 @@ static int sasl_scramsha1_challenge(jclient_t *jcl, char *in, int inlen, char *o
SHA1_Hi(salted_password, password, strlen(password), &salt, atoi(itr.buf)); SHA1_Hi(salted_password, password, strlen(password), &salt, atoi(itr.buf));
SHA1_HMAC(clientkey, sizeof(clientkey), "Client Key", strlen("Client Key"), salted_password, sizeof(salted_password)); SHA1_HMAC(clientkey, sizeof(clientkey), "Client Key", strlen("Client Key"), salted_password, sizeof(salted_password));
SHA1(storedkey, sizeof(storedkey), clientkey, sizeof(clientkey)); SHA1(storedkey, sizeof(storedkey), clientkey, sizeof(clientkey)); //FIXME: switch the account's plain password to store this digest instead (with salt+itr).
SHA1_HMAC(clientsignature, sizeof(clientsignature), sigkey.buf, sigkey.len, storedkey, sizeof(storedkey)); SHA1_HMAC(clientsignature, sizeof(clientsignature), sigkey.buf, sigkey.len, storedkey, sizeof(storedkey));
for (i = 0; i < sizeof(proof); i++) for (i = 0; i < sizeof(proof); i++)