t->specularscale = 0;
}
- t->currentpolygonfactor = r_refdef.polygonfactor + t->basepolygonfactor;
- t->currentpolygonoffset = r_refdef.polygonoffset + t->basepolygonoffset;
- // submodels are biased to avoid z-fighting with world surfaces that they
- // may be exactly overlapping (avoids z-fighting artifacts on certain
- // doors and things in Quake maps)
- if (ent->model->brush.submodel)
- {
- t->currentpolygonfactor += r_polygonoffset_submodel_factor.value;
- t->currentpolygonoffset += r_polygonoffset_submodel_offset.value;
- }
-
VectorClear(t->dlightcolor);
t->currentnumlayers = 0;
if (!(t->currentmaterialflags & MATERIALFLAG_NODRAW))
rsurface.frameblend[1] = ent->frameblend[1];
rsurface.frameblend[2] = ent->frameblend[2];
rsurface.frameblend[3] = ent->frameblend[3];
+ rsurface.basepolygonfactor = r_refdef.polygonfactor;
+ rsurface.basepolygonoffset = r_refdef.polygonoffset;
+ if (ent->model->brush.submodel)
+ {
+ rsurface.basepolygonfactor += r_polygonoffset_submodel_factor.value;
+ rsurface.basepolygonoffset += r_polygonoffset_submodel_offset.value;
+ }
if (model->surfmesh.isanimated && (rsurface.frameblend[0].lerp != 1 || rsurface.frameblend[0].frame != 0))
{
if (wanttangents)
RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
}
-static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, msurface_t **texturesurfacelist)
+void RSurf_SetupDepthAndCulling(void)
{
+ // submodels are biased to avoid z-fighting with world surfaces that they
+ // may be exactly overlapping (avoids z-fighting artifacts on certain
+ // doors and things in Quake maps)
GL_DepthRange(0, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SHORTDEPTHRANGE) ? 0.0625 : 1);
- GL_PolygonOffset(rsurface.texture->currentpolygonfactor, rsurface.texture->currentpolygonoffset);
+ GL_PolygonOffset(rsurface.basepolygonfactor + rsurface.texture->biaspolygonfactor, rsurface.basepolygonoffset + rsurface.texture->biaspolygonoffset);
GL_DepthTest(!(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
GL_CullFace((rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : r_view.cullface_back);
+}
+
+static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, msurface_t **texturesurfacelist)
+{
+ RSurf_SetupDepthAndCulling();
if (rsurface.mode != RSURFMODE_SHOWSURFACES)
{
rsurface.mode = RSURFMODE_SHOWSURFACES;
// restore entity matrix
R_Mesh_Matrix(&rsurface.matrix);
}
- GL_DepthRange(0, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SHORTDEPTHRANGE) ? 0.0625 : 1);
- GL_PolygonOffset(rsurface.texture->currentpolygonfactor, rsurface.texture->currentpolygonoffset);
- GL_DepthTest(!(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
- GL_CullFace((rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : r_view.cullface_back);
+ RSurf_SetupDepthAndCulling();
GL_DepthMask(true);
// LordHavoc: HalfLife maps have freaky skypolys so don't use
// skymasking on them, and Quake3 never did sky masking (unlike
GL_ColorMask(0,0,0,0);
GL_Color(1,1,1,1);
}
- GL_DepthRange(0, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SHORTDEPTHRANGE) ? 0.0625 : 1);
- GL_PolygonOffset(rsurface.texture->currentpolygonfactor, rsurface.texture->currentpolygonoffset);
- GL_CullFace((rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : r_view.cullface_back);
+ RSurf_SetupDepthAndCulling();
GL_DepthTest(true);
GL_BlendFunc(GL_ONE, GL_ZERO);
GL_DepthMask(true);
{
if (rsurface.mode != RSURFMODE_MULTIPASS)
rsurface.mode = RSURFMODE_MULTIPASS;
- GL_DepthRange(0, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SHORTDEPTHRANGE) ? 0.0625 : 1);
- GL_PolygonOffset(rsurface.texture->currentpolygonfactor, rsurface.texture->currentpolygonoffset);
+ RSurf_SetupDepthAndCulling();
GL_DepthTest(true);
- GL_CullFace((rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : r_view.cullface_back);
GL_BlendFunc(GL_ONE, GL_ZERO);
GL_DepthMask(writedepth);
GL_Color(1,1,1,1);
// write depth for anything we skipped on the depth-only pass earlier
if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
writedepth = true;
- GL_DepthRange(0, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SHORTDEPTHRANGE) ? 0.0625 : 1);
- GL_PolygonOffset(rsurface.texture->currentpolygonfactor, rsurface.texture->currentpolygonoffset);
- GL_DepthTest(!(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
- GL_CullFace((rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : r_view.cullface_back);
+ RSurf_SetupDepthAndCulling();
GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED));
GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
info.pvs = info.model->brush.GetPVS(info.model, info.relativelightorigin);
else
info.pvs = NULL;
- if (ent != r_refdef.worldentity)
- R_UpdateAllTextureInfo(ent);
+ R_UpdateAllTextureInfo(ent);
if (r_shadow_frontsidecasting.integer && r_shadow_compilingrtlight && r_shadow_realtime_world_compileportalculling.integer)
{
// check the box in modelspace, it was already checked in worldspace
if (!BoxesOverlap(model->normalmins, model->normalmaxs, lightmins, lightmaxs))
return;
- if (ent != r_refdef.worldentity)
- R_UpdateAllTextureInfo(ent);
+ R_UpdateAllTextureInfo(ent);
if (ent->model->brush.submodel)
GL_PolygonOffset(r_refdef.shadowpolygonfactor + r_polygonoffset_submodel_factor.value, r_refdef.shadowpolygonoffset + r_polygonoffset_submodel_offset.value);
if (model->brush.shadowmesh)
R_Shadow_RenderMode_End();
}
-#define RSURF_MAX_BATCHSURFACES 1024
+#define RSURF_MAX_BATCHSURFACES 8192
void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surfacelist, const unsigned char *trispvs)
{
int batchelements[BATCHSIZE*3];
texture_t *tex;
CHECKGLERROR
- if (ent == r_refdef.worldentity)
- RSurf_ActiveWorldEntity();
- else
- {
- RSurf_ActiveModelEntity(ent, true, true);
- R_UpdateAllTextureInfo(ent);
- }
- CHECKGLERROR
culltriangles = r_shadow_culltriangles.integer && !(ent->flags & RENDER_NOSELFSHADOW);
element3i = rsurface.modelelement3i;
// this is a double loop because non-visible surface skipping has to be
if (shader->textureflags & Q3TEXTUREFLAG_TWOSIDED)
texture->basematerialflags |= MATERIALFLAG_NOSHADOW | MATERIALFLAG_NOCULLFACE;
if (shader->textureflags & Q3TEXTUREFLAG_POLYGONOFFSET)
- texture->basepolygonoffset -= 2;
+ texture->biaspolygonoffset -= 2;
if (shader->textureflags & Q3TEXTUREFLAG_REFRACTION)
texture->basematerialflags |= MATERIALFLAG_REFRACTION;
if (shader->textureflags & Q3TEXTUREFLAG_REFLECTION)
// current material flags (updated each bmodel render)
int currentmaterialflags;
- // current PolygonOffset values for rendering this material
- float currentpolygonfactor;
- float currentpolygonoffset;
- float basepolygonfactor;
- float basepolygonoffset;
+ // PolygonOffset values for rendering this material
+ // (these are added to the r_refdef values and submodel values)
+ float biaspolygonfactor;
+ float biaspolygonoffset;
// textures to use when rendering this material
skinframe_t *currentskinframe;
}
if ((ambientscale + diffusescale) * VectorLength2(lightcolorbase) + specularscale * VectorLength2(lightcolorbase) < (1.0f / 1048576.0f))
return;
- GL_DepthRange(0, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SHORTDEPTHRANGE) ? 0.0625 : 1);
- GL_PolygonOffset(rsurface.texture->currentpolygonfactor, rsurface.texture->currentpolygonoffset);
- GL_DepthTest(!(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
- GL_CullFace((rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : r_view.cullface_back);
+ RSurf_SetupDepthAndCulling();
nmap = rsurface.texture->currentskinframe->nmap;
if (gl_lightmaps.integer)
nmap = r_texture_blanknormalmap;
r_refdef.worldmodel->DrawLight(r_refdef.worldentity, numsurfaces, surfacelist, trispvs);
}
-void R_Shadow_DrawEntityLight(entity_render_t *ent, int numsurfaces, int *surfacelist)
+void R_Shadow_DrawEntityLight(entity_render_t *ent)
{
model_t *model = ent->model;
if (!model->DrawLight)
return;
R_Shadow_SetupEntityLight(ent);
+ R_UpdateAllTextureInfo(ent);
model->DrawLight(ent, model->nummodelsurfaces, model->surfacelist, NULL);
}
// draw lighting in the unmasked areas
R_Shadow_RenderMode_Lighting(true, false);
for (i = 0;i < numlightentities_noselfshadow;i++)
- R_Shadow_DrawEntityLight(lightentities_noselfshadow[i], numsurfaces, surfacelist);
+ R_Shadow_DrawEntityLight(lightentities_noselfshadow[i]);
// optionally draw the illuminated areas
// for performance analysis by level designers
{
R_Shadow_RenderMode_VisibleLighting(!r_showdisabledepthtest.integer, false);
for (i = 0;i < numlightentities_noselfshadow;i++)
- R_Shadow_DrawEntityLight(lightentities_noselfshadow[i], numsurfaces, surfacelist);
+ R_Shadow_DrawEntityLight(lightentities_noselfshadow[i]);
}
R_Shadow_RenderMode_StencilShadowVolumes(false);
if (numsurfaces)
R_Shadow_DrawWorldLight(numsurfaces, surfacelist, lighttrispvs);
for (i = 0;i < numlightentities;i++)
- R_Shadow_DrawEntityLight(lightentities[i], numsurfaces, surfacelist);
+ R_Shadow_DrawEntityLight(lightentities[i]);
// optionally draw the illuminated areas
// for performance analysis by level designers
if (numsurfaces)
R_Shadow_DrawWorldLight(numsurfaces, surfacelist, lighttrispvs);
for (i = 0;i < numlightentities;i++)
- R_Shadow_DrawEntityLight(lightentities[i], numsurfaces, surfacelist);
+ R_Shadow_DrawEntityLight(lightentities[i]);
}
}
}
if (numsurfaces)
R_Shadow_DrawWorldLight(numsurfaces, surfacelist, lighttrispvs);
for (i = 0;i < numlightentities;i++)
- R_Shadow_DrawEntityLight(lightentities[i], numsurfaces, surfacelist);
+ R_Shadow_DrawEntityLight(lightentities[i]);
for (i = 0;i < numlightentities_noselfshadow;i++)
- R_Shadow_DrawEntityLight(lightentities_noselfshadow[i], numsurfaces, surfacelist);
+ R_Shadow_DrawEntityLight(lightentities_noselfshadow[i]);
// optionally draw the illuminated areas
// for performance analysis by level designers
if (numsurfaces)
R_Shadow_DrawWorldLight(numsurfaces, surfacelist, lighttrispvs);
for (i = 0;i < numlightentities;i++)
- R_Shadow_DrawEntityLight(lightentities[i], numsurfaces, surfacelist);
+ R_Shadow_DrawEntityLight(lightentities[i]);
for (i = 0;i < numlightentities_noselfshadow;i++)
- R_Shadow_DrawEntityLight(lightentities_noselfshadow[i], numsurfaces, surfacelist);
+ R_Shadow_DrawEntityLight(lightentities_noselfshadow[i]);
}
}
}
vec3_t colormap_shirtcolor;
// view location in model space
vec3_t modelorg; // TODO: rename this
+ // polygon offset data for submodels
+ float basepolygonfactor;
+ float basepolygonoffset;
// current texture in batching code
texture_t *texture;
// whether lightmapping is active on this batch
void RSurf_ActiveWorldEntity(void);
void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents);
void RSurf_CleanUp(void);
+void RSurf_SetupDepthAndCulling(void);
void R_Mesh_ResizeArrays(int newvertices);