cvar_t r_shadows_throwdirection = {CVAR_SAVE, "r_shadows_throwdirection", "0 0 -1", "override throwing direction for r_shadows 2"};
cvar_t r_shadows_drawafterrtlighting = {CVAR_SAVE, "r_shadows_drawafterrtlighting", "0", "draw fake shadows AFTER realtime lightning is drawn. May be useful for simulating fast sunlight on large outdoor maps with only one noshadow rtlight. The price is less realistic appearance of dynamic light shadows."};
cvar_t r_shadows_castfrombmodels = {CVAR_SAVE, "r_shadows_castfrombmodels", "0", "do cast shadows from bmodels"};
+cvar_t r_shadows_focus = {CVAR_SAVE, "r_shadows_focus", "0 0 0", "offset the shadowed area focus"};
+cvar_t r_shadows_shadowmapscale = {CVAR_SAVE, "r_shadows_shadowmapscale", "1", "increases shadowmap quality (multiply global shadowmap precision) for fake shadows. Needs shadowmapping ON."};
cvar_t r_q1bsp_skymasking = {0, "r_q1bsp_skymasking", "1", "allows sky polygons in quake1 maps to obscure other geometry"};
cvar_t r_polygonoffset_submodel_factor = {0, "r_polygonoffset_submodel_factor", "0", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"};
cvar_t r_polygonoffset_submodel_offset = {0, "r_polygonoffset_submodel_offset", "14", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"};
"\n"
"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
"# ifdef USESHADOWMAPORTHO\n"
-"# define GetShadowMapTC2D(dir) (min(dir, vec3(ShadowMap_Parameters.zw, 1.0)))\n"
+"# define GetShadowMapTC2D(dir) (min(dir, ShadowMap_Parameters.xyz))\n"
"# else\n"
"# ifdef USESHADOWMAPVSDCT\n"
"vec3 GetShadowMapTC2D(vec3 dir)\n"
"{\n"
-" vec3 adir = abs(dir);\n"
-" vec4 proj = textureCube(Texture_CubeProjection, dir);\n"
-" float ma = max(max(adir.x, adir.y), adir.z);\n"
-" vec3 stc = vec3(mix(dir.xy, dir.zz, proj.xy) * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
-" stc.xy += proj.zw * ShadowMap_Parameters.y;\n"
-" stc.z += ShadowMap_Parameters.z;\n"
-" return stc;\n"
+" vec3 adir = abs(dir);\n"
+" vec2 aparams = ShadowMap_Parameters.xy / max(max(adir.x, adir.y), adir.z);\n"
+" vec4 proj = textureCube(Texture_CubeProjection, dir);\n"
+" return vec3(mix(dir.xy, dir.zz, proj.xy) * aparams.x + proj.zw * ShadowMap_Parameters.z, aparams.y + ShadowMap_Parameters.w);\n"
"}\n"
"# else\n"
"vec3 GetShadowMapTC2D(vec3 dir)\n"
"{\n"
" vec3 adir = abs(dir);\n"
-" vec2 tc;\n"
-" vec2 offset;\n"
-" float ma;\n"
-" if (adir.x > adir.y)\n"
-" {\n"
-" if (adir.x > adir.z) // X\n"
-" {\n"
-" ma = adir.x;\n"
-" tc = dir.zy;\n"
-" offset = vec2(mix(0.5, 1.5, dir.x < 0.0), 0.5);\n"
-" }\n"
-" else // Z\n"
-" {\n"
-" ma = adir.z;\n"
-" tc = dir.xy;\n"
-" offset = vec2(mix(0.5, 1.5, dir.z < 0.0), 2.5);\n"
-" }\n"
-" }\n"
-" else\n"
-" {\n"
-" if (adir.y > adir.z) // Y\n"
-" {\n"
-" ma = adir.y;\n"
-" tc = dir.xz;\n"
-" offset = vec2(mix(0.5, 1.5, dir.y < 0.0), 1.5);\n"
-" }\n"
-" else // Z\n"
-" {\n"
-" ma = adir.z;\n"
-" tc = dir.xy;\n"
-" offset = vec2(mix(0.5, 1.5, dir.z < 0.0), 2.5);\n"
-" }\n"
-" }\n"
-"\n"
-" vec3 stc = vec3(tc * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
-" stc.xy += offset * ShadowMap_Parameters.y;\n"
-" stc.z += ShadowMap_Parameters.z;\n"
-" return stc;\n"
+" float ma = adir.z;\n"
+" vec4 proj = vec4(dir, 2.5);\n"
+" if (adir.x > ma) { ma = adir.x; proj = vec4(dir.zyx, 0.5); }\n"
+" if (adir.y > ma) { ma = adir.y; proj = vec4(dir.xzy, 1.5); }\n"
+" vec2 aparams = ShadowMap_Parameters.xy / ma;\n"
+" return vec3(proj.xy * aparams.x + vec2(proj.z < 0.0 ? 1.5 : 0.5, proj.w) * ShadowMap_Parameters.z, aparams.y + ShadowMap_Parameters.w);\n"
"}\n"
"# endif\n"
"# endif\n"
"\n"
"# endif\n"
"# ifdef USESHADOWMAPORTHO\n"
-" return mix(ShadowMap_Parameters.x, ShadowMap_Parameters.y, f);\n"
+" return mix(ShadowMap_Parameters.w, 1.0, f);\n"
"# else\n"
" return f;\n"
"# endif\n"
"# endif\n"
"# endif\n"
"# ifdef USESHADOWMAPORTHO\n"
-" return mix(ShadowMap_Parameters.x, ShadowMap_Parameters.y, f);\n"
+" return mix(ShadowMap_Parameters.w, 1.0, f);\n"
"# else\n"
" return f;\n"
"# endif\n"
"#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USESHADOWMAPORTHO)\n"
"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
"# ifdef USESHADOWMAPORTHO\n"
-"# define GetShadowMapTC2D(dir, ShadowMap_Parameters) (min(dir, float3(ShadowMap_Parameters.zw, 1.0)))\n"
+"# define GetShadowMapTC2D(dir, ShadowMap_Parameters) (min(dir, ShadowMap_Parameters.xyz))\n"
"# else\n"
"# ifdef USESHADOWMAPVSDCT\n"
"float3 GetShadowMapTC2D(float3 dir, float4 ShadowMap_Parameters, samplerCUBE Texture_CubeProjection)\n"
"{\n"
-" float3 adir = abs(dir);\n"
-" float4 proj = texCUBE(Texture_CubeProjection, dir);\n"
-" float ma = max(max(adir.x, adir.y), adir.z);\n"
-" float3 stc = float3(lerp(dir.xy, dir.zz, proj.xy) * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
-" stc.xy += proj.zw * ShadowMap_Parameters.y;\n"
-" stc.z += ShadowMap_Parameters.z;\n"
-" return stc;\n"
+" float3 adir = abs(dir);\n"
+" float2 aparams = ShadowMap_Parameters.xy / max(max(adir.x, adir.y), adir.z);\n"
+" float4 proj = texCUBEe(Texture_CubeProjection, dir);\n"
+" return float3(mix(dir.xy, dir.zz, proj.xy) * aparams.x + proj.zw * ShadowMap_Parameters.z, aparams.y + ShadowMap_Parameters.w);\n"
"}\n"
"# else\n"
"float3 GetShadowMapTC2D(float3 dir, float4 ShadowMap_Parameters)\n"
"{\n"
" float3 adir = abs(dir);\n"
-" float2 tc;\n"
-" float2 offset;\n"
-" float ma;\n"
-" if (adir.x > adir.y)\n"
-" {\n"
-" if (adir.x > adir.z) // X\n"
-" {\n"
-" ma = adir.x;\n"
-" tc = dir.zy;\n"
-" offset = float2(lerp(0.5, 1.5, dir.x < 0.0), 0.5);\n"
-" }\n"
-" else // Z\n"
-" {\n"
-" ma = adir.z;\n"
-" tc = dir.xy;\n"
-" offset = float2(lerp(0.5, 1.5, dir.z < 0.0), 2.5);\n"
-" }\n"
-" }\n"
-" else\n"
-" {\n"
-" if (adir.y > adir.z) // Y\n"
-" {\n"
-" ma = adir.y;\n"
-" tc = dir.xz;\n"
-" offset = float2(lerp(0.5, 1.5, dir.y < 0.0), 1.5);\n"
-" }\n"
-" else // Z\n"
-" {\n"
-" ma = adir.z;\n"
-" tc = dir.xy;\n"
-" offset = float2(lerp(0.5, 1.5, dir.z < 0.0), 2.5);\n"
-" }\n"
-" }\n"
-"\n"
-" float3 stc = float3(tc * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
-" stc.xy += offset * ShadowMap_Parameters.y;\n"
-" stc.z += ShadowMap_Parameters.z;\n"
-" return stc;\n"
+" float ma = adir.z;\n"
+" float4 proj = float4(dir, 2.5);\n"
+" if (adir.x > ma) { ma = adir.x; proj = float4(dir.zyx, 0.5); }\n"
+" if (adir.y > ma) { ma = adir.y; proj = float4(dir.xzy, 1.5); }\n"
+" float2 aparams = ShadowMap_Parameters.xy / ma;\n"
+" return float3(proj.xy * aparams.x + float2(proj.z < 0.0 ? 1.5 : 0.5, proj.w) * ShadowMap_Parameters.z, aparams.y + ShadowMap_Parameters.w);\n"
"}\n"
"# endif\n"
"# endif\n"
"\n"
"# endif\n"
"# ifdef USESHADOWMAPORTHO\n"
-" return lerp(ShadowMap_Parameters.x, ShadowMap_Parameters.y, f);\n"
+" return lerp(ShadowMap_Parameters.w, 1.0, f);\n"
"# else\n"
" return f;\n"
"# endif\n"
"# endif\n"
"# endif\n"
"# ifdef USESHADOWMAPORTHO\n"
-" return lerp(ShadowMap_Parameters.x, ShadowMap_Parameters.y, f);\n"
+" return lerp(ShadowMap_Parameters.w, 1.0, f);\n"
"# else\n"
" return f;\n"
"# endif\n"
if (p->loc_Texture_Cube >= 0) qglUniform1iARB(p->loc_Texture_Cube , GL20TU_CUBE);
if (p->loc_Texture_Refraction >= 0) qglUniform1iARB(p->loc_Texture_Refraction , GL20TU_REFRACTION);
if (p->loc_Texture_Reflection >= 0) qglUniform1iARB(p->loc_Texture_Reflection , GL20TU_REFLECTION);
- if (p->loc_Texture_ShadowMapRect >= 0) qglUniform1iARB(p->loc_Texture_ShadowMapRect , GL20TU_SHADOWMAPRECT);
+ if (p->loc_Texture_ShadowMapRect >= 0) qglUniform1iARB(p->loc_Texture_ShadowMapRect , permutation & SHADERPERMUTATION_SHADOWMAPORTHO ? GL20TU_SHADOWMAPORTHORECT : GL20TU_SHADOWMAPRECT);
if (p->loc_Texture_ShadowMapCube >= 0) qglUniform1iARB(p->loc_Texture_ShadowMapCube , GL20TU_SHADOWMAPCUBE);
- if (p->loc_Texture_ShadowMap2D >= 0) qglUniform1iARB(p->loc_Texture_ShadowMap2D , GL20TU_SHADOWMAP2D);
+ if (p->loc_Texture_ShadowMap2D >= 0) qglUniform1iARB(p->loc_Texture_ShadowMap2D , permutation & SHADERPERMUTATION_SHADOWMAPORTHO ? GL20TU_SHADOWMAPORTHO2D : GL20TU_SHADOWMAP2D);
if (p->loc_Texture_CubeProjection >= 0) qglUniform1iARB(p->loc_Texture_CubeProjection , GL20TU_CUBEPROJECTION);
if (p->loc_Texture_ScreenDepth >= 0) qglUniform1iARB(p->loc_Texture_ScreenDepth , GL20TU_SCREENDEPTH);
if (p->loc_Texture_ScreenNormalMap >= 0) qglUniform1iARB(p->loc_Texture_ScreenNormalMap, GL20TU_SCREENNORMALMAP);
permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE;
if (rsurface.texture->colormapping)
permutation |= SHADERPERMUTATION_COLORMAPPING;
- if (r_shadow_usingshadowmaportho && (r_shadow_usingshadowmaprect || r_shadow_usingshadowmap2d))
+ if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
{
permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
if (r_shadow_usingshadowmaprect)
permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE;
if (rsurface.texture->colormapping)
permutation |= SHADERPERMUTATION_COLORMAPPING;
- if (r_shadow_usingshadowmaportho && (r_shadow_usingshadowmaprect || r_shadow_usingshadowmap2d))
+ if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
{
permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
if (r_shadow_usingshadowmaprect)
permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE;
if (rsurface.texture->colormapping)
permutation |= SHADERPERMUTATION_COLORMAPPING;
- if (r_shadow_usingshadowmaportho && (r_shadow_usingshadowmaprect || r_shadow_usingshadowmap2d))
+ if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
{
permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
if (r_shadow_usingshadowmaprect)
permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE;
if (rsurface.texture->colormapping)
permutation |= SHADERPERMUTATION_COLORMAPPING;
- if (r_shadow_usingshadowmaportho && (r_shadow_usingshadowmaprect || r_shadow_usingshadowmap2d))
+ if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
{
permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
if (r_shadow_usingshadowmaprect)
if (r_glsl_permutation->loc_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
if (r_glsl_permutation->loc_Texture_ScreenDiffuse >= 0) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE , r_shadow_prepasslightingdiffusetexture );
if (r_glsl_permutation->loc_Texture_ScreenSpecular >= 0) R_Mesh_TexBind(GL20TU_SCREENSPECULAR , r_shadow_prepasslightingspeculartexture );
- if (rsurface.rtlight || r_shadow_usingshadowmaportho)
+ if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
{
- if (r_glsl_permutation->loc_Texture_ShadowMap2D >= 0) R_Mesh_TexBind(GL20TU_SHADOWMAP2D , r_shadow_shadowmap2dtexture );
- if (r_glsl_permutation->loc_Texture_ShadowMapRect >= 0) R_Mesh_TexBind(GL20TU_SHADOWMAPRECT , r_shadow_shadowmaprectangletexture );
+ if (r_glsl_permutation->loc_Texture_ShadowMap2D >= 0) R_Mesh_TexBind(r_shadow_usingshadowmaportho ? GL20TU_SHADOWMAPORTHO2D : GL20TU_SHADOWMAP2D, r_shadow_shadowmap2dtexture );
+ if (r_glsl_permutation->loc_Texture_ShadowMapRect >= 0) R_Mesh_TexBind(r_shadow_usingshadowmaportho ? GL20TU_SHADOWMAPORTHORECT : GL20TU_SHADOWMAPRECT, r_shadow_shadowmaprectangletexture );
if (rsurface.rtlight)
{
if (r_glsl_permutation->loc_Texture_Cube >= 0) R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
if (r_cg_permutation->fp_Texture_ScreenNormalMap) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenNormalMap, r_shadow_prepassgeometrynormalmaptexture );CHECKCGERROR
if (r_cg_permutation->fp_Texture_ScreenDiffuse ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenDiffuse , r_shadow_prepasslightingdiffusetexture );CHECKCGERROR
if (r_cg_permutation->fp_Texture_ScreenSpecular ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenSpecular , r_shadow_prepasslightingspeculartexture );CHECKCGERROR
- if (rsurface.rtlight || r_shadow_usingshadowmaportho)
+ if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
{
if (r_cg_permutation->fp_Texture_ShadowMap2D ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMap2D , r_shadow_shadowmap2dtexture );CHECKCGERROR
if (r_cg_permutation->fp_Texture_ShadowMapRect ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMapRect , r_shadow_shadowmaprectangletexture );CHECKCGERROR
Cvar_RegisterVariable(&r_shadows_castfrombmodels);
Cvar_RegisterVariable(&r_shadows_throwdistance);
Cvar_RegisterVariable(&r_shadows_throwdirection);
+ Cvar_RegisterVariable(&r_shadows_focus);
+ Cvar_RegisterVariable(&r_shadows_shadowmapscale);
Cvar_RegisterVariable(&r_q1bsp_skymasking);
Cvar_RegisterVariable(&r_polygonoffset_submodel_factor);
Cvar_RegisterVariable(&r_polygonoffset_submodel_offset);
for (i = 0;i < r_refdef.scene.numentities;i++)
if (r_refdef.viewcache.entityvisible[i])
R_AnimCache_GetEntity(r_refdef.scene.entities[i], wantnormals, wanttangents);
-
- if (r_shadows.integer)
- for (i = 0;i < r_refdef.scene.numentities;i++)
- if (!r_refdef.viewcache.entityvisible[i])
- R_AnimCache_GetEntity(r_refdef.scene.entities[i], false, false);
}
//==================================================================================
entity_render_t *ent;
vec3_t tempdiffusenormal, avg;
vec_t f, fa, fd, fdd;
+ qboolean skipunseen = r_shadows.integer != 1 || R_Shadow_ShadowMappingEnabled();
for (i = 0;i < r_refdef.scene.numentities;i++)
{
ent = r_refdef.scene.entities[i];
// skip unseen models
- if (!r_refdef.viewcache.entityvisible[i] && r_shadows.integer != 1)
+ if (!r_refdef.viewcache.entityvisible[i] && skipunseen)
continue;
// skip bsp models
int samples;
entity_render_t *ent;
- renderimask = r_refdef.envmap ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL) : ((chase_active.integer || r_waterstate.renderingscene) ? RENDER_VIEWMODEL : RENDER_EXTERIORMODEL);
+ renderimask = r_refdef.envmap ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL)
+ : r_waterstate.renderingrefraction ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL)
+ : (chase_active.integer || r_waterstate.renderingscene) ? RENDER_VIEWMODEL
+ : RENDER_EXTERIORMODEL;
if (!r_drawviewmodel.integer)
renderimask |= RENDER_VIEWMODEL;
if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs)
// (except that a clipping plane should be used to hide everything on one side of the water, and the viewer's weapon model should be omitted)
if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
{
+ r_waterstate.renderingrefraction = true;
r_refdef.view = myview;
r_refdef.view.clipplane = p->plane;
VectorNegate(r_refdef.view.clipplane.normal, r_refdef.view.clipplane.normal);
R_RenderScene();
R_Mesh_CopyToTexture(p->texture_refraction, 0, 0, r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
+ r_waterstate.renderingrefraction = false;
}
}
R_TimeReport("animation");
R_Shadow_PrepareLights();
+ if (r_shadows.integer > 0 && r_refdef.lightmapintensity > 0)
+ R_Shadow_PrepareModelShadows();
if (r_timereport_active)
R_TimeReport("preparelights");
{
CHECKGLERROR
RSurf_SetupDepthAndCulling();
- if (r_showsurfaces.integer == 3 && !prepass && (rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY))
+ if (r_showsurfaces.integer == 3 && !prepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY))
{
R_DrawTextureSurfaceList_ShowSurfaces3(texturenumsurfaces, texturesurfacelist, writedepth);
return;
{
CHECKGLERROR
RSurf_SetupDepthAndCulling();
- if (r_showsurfaces.integer == 3 && !prepass && (rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY))
+ if (r_showsurfaces.integer == 3 && !prepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY))
{
R_DrawTextureSurfaceList_ShowSurfaces3(texturenumsurfaces, texturesurfacelist, writedepth);
return;
VectorCopy(decal->vertex3f[2], v3f + 6);
}
+ if (r_refdef.fogenabled)
+ {
+ alpha = RSurf_FogVertex(v3f);
+ VectorScale(c4f, alpha, c4f);
+ alpha = RSurf_FogVertex(v3f + 3);
+ VectorScale(c4f + 4, alpha, c4f + 4);
+ alpha = RSurf_FogVertex(v3f + 6);
+ VectorScale(c4f + 8, alpha, c4f + 8);
+ }
+
v3f += 9;
c4f += 12;
t2f += 6;
{
r_refdef.stats.drawndecals += numtris;
- if (r_refdef.fogenabled)
- {
- switch(vid.renderpath)
- {
- case RENDERPATH_GL20:
- case RENDERPATH_CGGL:
- case RENDERPATH_GL13:
- case RENDERPATH_GL11:
- for (i = 0, v3f = decalsystem->vertex3f, c4f = decalsystem->color4f;i < numtris*3;i++, v3f += 3, c4f += 4)
- {
- alpha = RSurf_FogVertex(v3f);
- c4f[0] *= alpha;
- c4f[1] *= alpha;
- c4f[2] *= alpha;
- }
- break;
- }
- }
-
// now render the decals all at once
// (this assumes they all use one particle font texture!)
RSurf_ActiveCustomEntity(&rsurface.matrix, &rsurface.inversematrix, rsurface.ent_flags, rsurface.ent_shadertime, 1, 1, 1, 1, numdecals*3, decalsystem->vertex3f, decalsystem->texcoord2f, NULL, NULL, NULL, decalsystem->color4f, numtris, decalsystem->element3i, decalsystem->element3s, false, false);
}
}
+extern cvar_t mod_collision_bih;
void R_DrawDebugModel(void)
{
entity_render_t *ent = rsurface.entity;
int i, j, k, l, flagsmask;
- q3mbrush_t *brush;
const msurface_t *surface;
dp_model_t *model = ent->model;
vec3_t v;
GL_DepthMask(false);
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- if (r_showcollisionbrushes.value > 0 && model->brush.num_brushes)
+ if (r_showcollisionbrushes.value > 0 && model->collision_bih.numleafs && mod_collision_bih.integer)
{
+ int triangleindex;
+ int bihleafindex;
+ qboolean cullbox = ent == r_refdef.scene.worldentity;
+ const q3mbrush_t *brush;
+ const bih_t *bih = &model->collision_bih;
+ const bih_leaf_t *bihleaf;
+ float vertex3f[3][3];
GL_PolygonOffset(r_refdef.polygonfactor + r_showcollisionbrushes_polygonfactor.value, r_refdef.polygonoffset + r_showcollisionbrushes_polygonoffset.value);
- for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++)
- {
- if (brush->colbrushf && brush->colbrushf->numtriangles)
- {
- R_Mesh_VertexPointer(brush->colbrushf->points->v, 0, 0);
- GL_Color((i & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((i >> 5) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((i >> 10) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, r_showcollisionbrushes.value);
- R_Mesh_Draw(0, brush->colbrushf->numpoints, 0, brush->colbrushf->numtriangles, brush->colbrushf->elements, NULL, 0, 0);
- }
- }
- for (i = 0, surface = model->data_surfaces + model->firstmodelsurface;i < model->nummodelsurfaces;i++, surface++)
+ cullbox = false;
+ for (bihleafindex = 0, bihleaf = bih->leafs;bihleafindex < bih->numleafs;bihleafindex++, bihleaf++)
{
- if (surface->num_collisiontriangles)
+ if (cullbox && R_CullBox(bihleaf->mins, bihleaf->maxs))
+ continue;
+ switch (bihleaf->type)
{
- R_Mesh_VertexPointer(surface->data_collisionvertex3f, 0, 0);
- GL_Color((i & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((i >> 5) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((i >> 10) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, r_showcollisionbrushes.value);
- R_Mesh_Draw(0, surface->num_collisionvertices, 0, surface->num_collisiontriangles, surface->data_collisionelement3i, NULL, 0, 0);
+ case BIH_LEAF:
+ // brush
+ brush = model->brush.data_brushes + bihleaf->itemindex;
+ if (brush->colbrushf && brush->colbrushf->numtriangles)
+ {
+ R_Mesh_VertexPointer(brush->colbrushf->points->v, 0, 0);
+ GL_Color((bihleafindex & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((bihleafindex >> 5) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((bihleafindex >> 10) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, r_showcollisionbrushes.value);
+ R_Mesh_Draw(0, brush->colbrushf->numpoints, 0, brush->colbrushf->numtriangles, brush->colbrushf->elements, NULL, 0, 0);
+ }
+ break;
+ case BIH_LEAF + 1:
+ // triangle
+ triangleindex = bihleaf->itemindex;
+ VectorCopy(model->brush.data_collisionvertex3f + 3*model->brush.data_collisionelement3i[triangleindex*3+0], vertex3f[0]);
+ VectorCopy(model->brush.data_collisionvertex3f + 3*model->brush.data_collisionelement3i[triangleindex*3+1], vertex3f[1]);
+ VectorCopy(model->brush.data_collisionvertex3f + 3*model->brush.data_collisionelement3i[triangleindex*3+2], vertex3f[2]);
+ R_Mesh_VertexPointer(vertex3f[0], 0, 0);
+ GL_Color((bihleafindex & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((bihleafindex >> 5) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((bihleafindex >> 10) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, r_showcollisionbrushes.value);
+ R_Mesh_Draw(0, 3, 0, 1, polygonelement3i, polygonelement3s, 0, 0);
+ break;
+ default:
+ break;
}
}
}