From: havoc Date: Wed, 2 May 2018 07:00:12 +0000 (+0000) Subject: Remove shadowvolume rendering entirely, now shadowmaps are the only kind of shadow. X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=4498a86fd5db6f1066559fae990b648ddfe2df22;p=xonotic%2Fdarkplaces.git Remove shadowvolume rendering entirely, now shadowmaps are the only kind of shadow. Also remove R_SetStencilSeparate and corresponding gl bindings since it isn't needed (R_SetStencil could also be removed but it might have uses). git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12414 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/cl_screen.c b/cl_screen.c index 71a74c08..9507b909 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -2058,11 +2058,8 @@ void R_ClearScreen(qboolean fogcolor) VectorCopy(r_refdef.fogcolor, clearcolor); } // clear depth is 1.0 - // LordHavoc: we use a stencil centered around 128 instead of 0, - // to avoid clamping interfering with strange shadow volume - // drawing orders // clear the screen - GL_Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | (vid.stencil ? GL_STENCIL_BUFFER_BIT : 0), clearcolor, 1.0f, 128); + GL_Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | (vid.stencil ? GL_STENCIL_BUFFER_BIT : 0), clearcolor, 1.0f, 0); } int r_stereo_side; diff --git a/client.h b/client.h index 67013ddf..1b2c7112 100644 --- a/client.h +++ b/client.h @@ -271,8 +271,6 @@ rtlight_particle_t; typedef struct rtlight_s { - // shadow volumes are done entirely in model space, so there are no matrices for dealing with them... they just use the origin - // note that the world to light matrices are inversely scaled (divided) by lightradius // core properties @@ -304,7 +302,7 @@ typedef struct rtlight_s int flags; // generated properties - /// used only for shadow volumes + /// used only for casting shadows vec3_t shadoworigin; /// culling vec3_t cullmins; @@ -360,9 +358,7 @@ typedef struct rtlight_s int shadowmapatlasposition[2]; /// size of one side of this light in the shadowmap atlas (for omnidirectional shadowmaps this is the min corner of a 2x3 arrangement, or a 4x3 arrangement in the case of noselfshadow entities being present) int shadowmapatlassidesize; - /// premade shadow volumes to render for world entity - shadowmesh_t *static_meshchain_shadow_zpass; - shadowmesh_t *static_meshchain_shadow_zfail; + /// optimized and culled mesh to render for world entity shadows shadowmesh_t *static_meshchain_shadow_shadowmap; /// used for visibility testing (more exact than bbox) int static_numleafs; @@ -1999,8 +1995,6 @@ typedef struct r_refdef_s // whether to draw world lights realtime, dlights realtime, and their shadows float polygonfactor; float polygonoffset; - float shadowpolygonfactor; - float shadowpolygonoffset; // how long R_RenderView took on the previous frame double lastdrawscreentime; diff --git a/collision.c b/collision.c index e6621710..1eee2c2b 100644 --- a/collision.c +++ b/collision.c @@ -16,7 +16,6 @@ cvar_t collision_extendtraceboxlength = {0, "collision_extendtraceboxlength", "1 cvar_t collision_extendtracelinelength = {0, "collision_extendtracelinelength", "1", "internal bias for traceline() qc builtin to account for collision_impactnudge (this does not alter the final trace length)"}; cvar_t collision_debug_tracelineasbox = {0, "collision_debug_tracelineasbox", "0", "workaround for any bugs in Collision_TraceLineBrushFloat by using Collision_TraceBrushBrushFloat"}; cvar_t collision_cache = {0, "collision_cache", "1", "store results of collision traces for next frame to reuse if possible (optimization)"}; -//cvar_t collision_triangle_neighborsides = {0, "collision_triangle_neighborsides", "1", "override automatic side generation if triangle has neighbors with face planes that form a convex edge (perfect solution, but can not work for all edges)"}; cvar_t collision_triangle_bevelsides = {0, "collision_triangle_bevelsides", "0", "generate sloped edge planes on triangles - if 0, see axialedgeplanes"}; cvar_t collision_triangle_axialsides = {0, "collision_triangle_axialsides", "1", "generate axially-aligned edge planes on triangles - otherwise use perpendicular edge planes"}; cvar_t collision_bih_fullrecursion = { 0, "collision_bih_fullrecursion", "0", "debugging option to disable the bih recursion optimizations by iterating the entire tree" }; @@ -31,7 +30,6 @@ void Collision_Init (void) Cvar_RegisterVariable(&collision_extendtraceboxlength); Cvar_RegisterVariable(&collision_debug_tracelineasbox); Cvar_RegisterVariable(&collision_cache); -// Cvar_RegisterVariable(&collision_triangle_neighborsides); Cvar_RegisterVariable(&collision_triangle_bevelsides); Cvar_RegisterVariable(&collision_triangle_axialsides); Cvar_RegisterVariable(&collision_bih_fullrecursion); diff --git a/gl_backend.c b/gl_backend.c index afaf8b08..4b93ba7a 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -1432,47 +1432,6 @@ void GL_DepthRange(float nearfrac, float farfrac) } } -void R_SetStencilSeparate(qboolean enable, int writemask, int frontfail, int frontzfail, int frontzpass, int backfail, int backzfail, int backzpass, int frontcompare, int backcompare, int comparereference, int comparemask) -{ - switch (vid.renderpath) - { - case RENDERPATH_GL20: - case RENDERPATH_GLES2: - CHECKGLERROR - if (enable) - { - qglEnable(GL_STENCIL_TEST);CHECKGLERROR - } - else - { - qglDisable(GL_STENCIL_TEST);CHECKGLERROR - } - if (vid.support.ati_separate_stencil) - { - qglStencilMask(writemask);CHECKGLERROR - qglStencilOpSeparate(GL_FRONT, frontfail, frontzfail, frontzpass);CHECKGLERROR - qglStencilOpSeparate(GL_BACK, backfail, backzfail, backzpass);CHECKGLERROR - qglStencilFuncSeparate(GL_FRONT, frontcompare, comparereference, comparereference);CHECKGLERROR - qglStencilFuncSeparate(GL_BACK, backcompare, comparereference, comparereference);CHECKGLERROR - } - else if (vid.support.ext_stencil_two_side) - { -#if defined(GL_STENCIL_TEST_TWO_SIDE_EXT) && !defined(USE_GLES2) - qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR - qglActiveStencilFaceEXT(GL_FRONT);CHECKGLERROR - qglStencilMask(writemask);CHECKGLERROR - qglStencilOp(frontfail, frontzfail, frontzpass);CHECKGLERROR - qglStencilFunc(frontcompare, comparereference, comparemask);CHECKGLERROR - qglActiveStencilFaceEXT(GL_BACK);CHECKGLERROR - qglStencilMask(writemask);CHECKGLERROR - qglStencilOp(backfail, backzfail, backzpass);CHECKGLERROR - qglStencilFunc(backcompare, comparereference, comparemask);CHECKGLERROR -#endif - } - break; - } -} - void R_SetStencil(qboolean enable, int writemask, int fail, int zfail, int zpass, int compare, int comparereference, int comparemask) { switch (vid.renderpath) @@ -1488,12 +1447,6 @@ void R_SetStencil(qboolean enable, int writemask, int fail, int zfail, int zpass { qglDisable(GL_STENCIL_TEST);CHECKGLERROR } - if (vid.support.ext_stencil_two_side) - { -#ifdef GL_STENCIL_TEST_TWO_SIDE_EXT - qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR -#endif - } qglStencilMask(writemask);CHECKGLERROR qglStencilOp(fail, zfail, zpass);CHECKGLERROR qglStencilFunc(compare, comparereference, comparemask);CHECKGLERROR diff --git a/gl_backend.h b/gl_backend.h index 60953740..f4324cd2 100644 --- a/gl_backend.h +++ b/gl_backend.h @@ -40,7 +40,6 @@ void GL_DepthMask(int state); void GL_DepthTest(int state); void GL_DepthFunc(int state); void GL_DepthRange(float nearfrac, float farfrac); -void R_SetStencilSeparate(qboolean enable, int writemask, int frontfail, int frontzfail, int frontzpass, int backfail, int backzfail, int backzpass, int frontcompare, int backcompare, int comparereference, int comparemask); void R_SetStencil(qboolean enable, int writemask, int fail, int zfail, int zpass, int compare, int comparereference, int comparemask); void GL_PolygonOffset(float planeoffset, float depthoffset); void GL_CullFace(int state); diff --git a/gl_rmain.c b/gl_rmain.c index b32206dc..08dcf6e7 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -92,7 +92,6 @@ cvar_t r_showsurfaces = {0, "r_showsurfaces", "0", "1 shows surfaces as differen cvar_t r_showtris = {0, "r_showtris", "0", "shows triangle outlines, value controls brightness (can be above 1)"}; cvar_t r_shownormals = {0, "r_shownormals", "0", "shows per-vertex surface normals and tangent vectors for bumpmapped lighting"}; cvar_t r_showlighting = {0, "r_showlighting", "0", "shows areas lit by lights, useful for finding out why some areas of a map render slowly (bright orange = lots of passes = slow), a value of 2 disables depth testing which can be interesting but not very useful"}; -cvar_t r_showshadowvolumes = {0, "r_showshadowvolumes", "0", "shows areas shadowed by lights, useful for finding out why some areas of a map render slowly (bright blue = lots of passes = slow), a value of 2 disables depth testing which can be interesting but not very useful"}; cvar_t r_showcollisionbrushes = {0, "r_showcollisionbrushes", "0", "draws collision brushes in quake3 maps (mode 1), mode 2 disables rendering of world (trippy!)"}; cvar_t r_showcollisionbrushes_polygonfactor = {0, "r_showcollisionbrushes_polygonfactor", "-1", "expands outward the brush polygons a little bit, used to make collision brushes appear infront of walls"}; cvar_t r_showcollisionbrushes_polygonoffset = {0, "r_showcollisionbrushes_polygonoffset", "0", "nudges brush polygon depth in hardware depth units, used to make collision brushes appear infront of walls"}; @@ -3270,7 +3269,6 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_showtris); Cvar_RegisterVariable(&r_shownormals); Cvar_RegisterVariable(&r_showlighting); - Cvar_RegisterVariable(&r_showshadowvolumes); Cvar_RegisterVariable(&r_showcollisionbrushes); Cvar_RegisterVariable(&r_showcollisionbrushes_polygonfactor); Cvar_RegisterVariable(&r_showcollisionbrushes_polygonoffset); @@ -3473,7 +3471,7 @@ void GL_Init (void) #endif // clear to black (loading plaque will be seen over this) - GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 128); + GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 0); } #endif @@ -4605,7 +4603,6 @@ void R_ResetViewRendering2D_Common(int viewfbo, rtexture_t *viewdepthtexture, rt R_EntityMatrix(&identitymatrix); R_Mesh_ResetTextureState(); GL_PolygonOffset(0, 0); - R_SetStencil(false, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_ALWAYS, 128, 255); switch(vid.renderpath) { case RENDERPATH_GL20: @@ -4638,7 +4635,6 @@ void R_ResetViewRendering3D(int viewfbo, rtexture_t *viewdepthtexture, rtexture_ R_EntityMatrix(&identitymatrix); R_Mesh_ResetTextureState(); GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset); - R_SetStencil(false, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_ALWAYS, 128, 255); switch(vid.renderpath) { case RENDERPATH_GL20: @@ -5307,7 +5303,7 @@ static void R_Bloom_MakeTexture(void) x *= 2; r = bound(0, r_bloom_colorexponent.value / x, 1); // always 0.5 to 1 if(x <= 2) - GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 128); + GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 0); GL_BlendFunc(GL_SRC_COLOR, GL_ZERO); // square it GL_Color(1,1,1,1); // no fix factor supported here R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, prev->texcoord2f); @@ -5610,8 +5606,6 @@ void R_UpdateVariables(void) Cvar_SetValueQuick(&r_shadow_frontsidecasting, 1); r_refdef.polygonfactor = 0; r_refdef.polygonoffset = 0; - r_refdef.shadowpolygonfactor = r_refdef.polygonfactor + r_shadow_polygonfactor.value * (r_shadow_frontsidecasting.integer ? 1 : -1); - r_refdef.shadowpolygonoffset = r_refdef.polygonoffset + r_shadow_polygonoffset.value * (r_shadow_frontsidecasting.integer ? 1 : -1); r_refdef.scene.rtworld = r_shadow_realtime_world.integer != 0; r_refdef.scene.rtworldshadows = r_shadow_realtime_world_shadows.integer && vid.stencil; @@ -6045,16 +6039,6 @@ void R_RenderScene(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewco if (r_refdef.scene.extraupdate) S_ExtraUpdate (); - if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && !r_shadows_drawafterrtlighting.integer && r_refdef.scene.lightmapintensity > 0) - { - R_ResetViewRendering3D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); - R_Shadow_DrawModelShadows(); - R_ResetViewRendering3D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); - // don't let sound skip if going slow - if (r_refdef.scene.extraupdate) - S_ExtraUpdate (); - } - if (!r_shadow_usingdeferredprepass) { R_Shadow_DrawLights(); @@ -6066,16 +6050,6 @@ void R_RenderScene(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewco if (r_refdef.scene.extraupdate) S_ExtraUpdate (); - if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && r_shadows_drawafterrtlighting.integer && r_refdef.scene.lightmapintensity > 0) - { - R_ResetViewRendering3D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); - R_Shadow_DrawModelShadows(); - R_ResetViewRendering3D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); - // don't let sound skip if going slow - if (r_refdef.scene.extraupdate) - S_ExtraUpdate (); - } - if (cl.csqc_vidvars.drawworld) { if (cl_decals_newsystem.integer) diff --git a/gl_rsurf.c b/gl_rsurf.c index 3051aa0b..42250c5a 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -1300,80 +1300,6 @@ void R_Q1BSP_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, floa qsort(info.outsurfacelist, info.outnumsurfaces, sizeof(*info.outsurfacelist), R_Q1BSP_GetLightInfo_comparefunc); } -void R_Q1BSP_CompileShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativelightdirection, float lightradius, int numsurfaces, const int *surfacelist) -{ - dp_model_t *model = ent->model; - msurface_t *surface; - int surfacelistindex; - float projectdistance = relativelightdirection ? lightradius : lightradius + model->radius*2 + r_shadow_projectdistance.value; - // if triangle neighbors are disabled, shadowvolumes are disabled - if (!model->brush.shadowmesh->neighbor3i) - return; - r_shadow_compilingrtlight->static_meshchain_shadow_zfail = Mod_ShadowMesh_Begin(r_main_mempool, 32768, 32768, NULL, NULL, NULL, false, false, true); - R_Shadow_PrepareShadowMark(model->brush.shadowmesh->numtriangles); - for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++) - { - surface = model->data_surfaces + surfacelist[surfacelistindex]; - if (surface->texture->basematerialflags & MATERIALFLAG_NOSHADOW) - continue; - R_Shadow_MarkVolumeFromBox(surface->num_firstshadowmeshtriangle, surface->num_triangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, relativelightorigin, relativelightdirection, r_shadow_compilingrtlight->cullmins, r_shadow_compilingrtlight->cullmaxs, surface->mins, surface->maxs); - } - R_Shadow_VolumeFromList(model->brush.shadowmesh->numverts, model->brush.shadowmesh->numtriangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, model->brush.shadowmesh->neighbor3i, relativelightorigin, relativelightdirection, projectdistance, numshadowmark, shadowmarklist, ent->mins, ent->maxs); - r_shadow_compilingrtlight->static_meshchain_shadow_zfail = Mod_ShadowMesh_Finish(r_main_mempool, r_shadow_compilingrtlight->static_meshchain_shadow_zfail, false, false, true); -} - -extern cvar_t r_polygonoffset_submodel_factor; -extern cvar_t r_polygonoffset_submodel_offset; -void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, const vec3_t relativelightorigin, const vec3_t relativelightdirection, float lightradius, int modelnumsurfaces, const int *modelsurfacelist, const vec3_t lightmins, const vec3_t lightmaxs) -{ - dp_model_t *model = ent->model; - const msurface_t *surface; - int modelsurfacelistindex; - float projectdistance = relativelightdirection ? lightradius : lightradius + model->radius*2 + r_shadow_projectdistance.value; - // check the box in modelspace, it was already checked in worldspace - if (!BoxesOverlap(model->normalmins, model->normalmaxs, lightmins, lightmaxs)) - return; - R_FrameData_SetMark(); - 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) - { - // if triangle neighbors are disabled, shadowvolumes are disabled - if (!model->brush.shadowmesh->neighbor3i) - return; - R_Shadow_PrepareShadowMark(model->brush.shadowmesh->numtriangles); - for (modelsurfacelistindex = 0;modelsurfacelistindex < modelnumsurfaces;modelsurfacelistindex++) - { - surface = model->data_surfaces + modelsurfacelist[modelsurfacelistindex]; - if (R_GetCurrentTexture(surface->texture)->currentmaterialflags & MATERIALFLAG_NOSHADOW) - continue; - R_Shadow_MarkVolumeFromBox(surface->num_firstshadowmeshtriangle, surface->num_triangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, relativelightorigin, relativelightdirection, lightmins, lightmaxs, surface->mins, surface->maxs); - } - R_Shadow_VolumeFromList(model->brush.shadowmesh->numverts, model->brush.shadowmesh->numtriangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, model->brush.shadowmesh->neighbor3i, relativelightorigin, relativelightdirection, projectdistance, numshadowmark, shadowmarklist, ent->mins, ent->maxs); - } - else - { - // if triangle neighbors are disabled, shadowvolumes are disabled - if (!model->surfmesh.data_neighbor3i) - return; - projectdistance = lightradius + model->radius*2; - R_Shadow_PrepareShadowMark(model->surfmesh.num_triangles); - // identify lit faces within the bounding box - for (modelsurfacelistindex = 0;modelsurfacelistindex < modelnumsurfaces;modelsurfacelistindex++) - { - surface = model->data_surfaces + modelsurfacelist[modelsurfacelistindex]; - rsurface.texture = R_GetCurrentTexture(surface->texture); - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_NOSHADOW) - continue; - R_Shadow_MarkVolumeFromBox(surface->num_firsttriangle, surface->num_triangles, rsurface.modelvertex3f, rsurface.modelelement3i, relativelightorigin, relativelightdirection, lightmins, lightmaxs, surface->mins, surface->maxs); - } - R_Shadow_VolumeFromList(model->surfmesh.num_vertices, model->surfmesh.num_triangles, rsurface.modelvertex3f, model->surfmesh.data_element3i, model->surfmesh.data_neighbor3i, relativelightorigin, relativelightdirection, projectdistance, numshadowmark, shadowmarklist, ent->mins, ent->maxs); - } - if (ent->model->brush.submodel) - GL_PolygonOffset(r_refdef.shadowpolygonfactor, r_refdef.shadowpolygonoffset); - R_FrameData_ReturnToMark(); -} - void R_Q1BSP_CompileShadowMap(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativelightdirection, float lightradius, int numsurfaces, const int *surfacelist) { dp_model_t *model = ent->model; @@ -1388,7 +1314,7 @@ void R_Q1BSP_CompileShadowMap(entity_render_t *ent, vec3_t relativelightorigin, // exceeding the number of triangles in a single mesh) we have to make sure // that we make only a single mesh - so over-estimate the size of the mesh // to match the model. - r_shadow_compilingrtlight->static_meshchain_shadow_shadowmap = Mod_ShadowMesh_Begin(r_main_mempool, model->surfmesh.num_vertices, model->surfmesh.num_triangles, NULL, NULL, NULL, false, false, true); + r_shadow_compilingrtlight->static_meshchain_shadow_shadowmap = Mod_ShadowMesh_Begin(r_main_mempool, model->surfmesh.num_vertices, model->surfmesh.num_triangles, NULL, NULL, NULL, false, true); R_Shadow_PrepareShadowSides(model->brush.shadowmesh->numtriangles); for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++) { @@ -1396,7 +1322,7 @@ void R_Q1BSP_CompileShadowMap(entity_render_t *ent, vec3_t relativelightorigin, sidemasks |= R_Shadow_ChooseSidesFromBox(surface->num_firstshadowmeshtriangle, surface->num_triangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, &r_shadow_compilingrtlight->matrix_worldtolight, relativelightorigin, relativelightdirection, r_shadow_compilingrtlight->cullmins, r_shadow_compilingrtlight->cullmaxs, surface->mins, surface->maxs, surface->texture->basematerialflags & MATERIALFLAG_NOSHADOW ? NULL : sidetotals); } R_Shadow_ShadowMapFromList(model->brush.shadowmesh->numverts, model->brush.shadowmesh->numtriangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, numshadowsides, sidetotals, shadowsides, shadowsideslist); - r_shadow_compilingrtlight->static_meshchain_shadow_shadowmap = Mod_ShadowMesh_Finish(r_main_mempool, r_shadow_compilingrtlight->static_meshchain_shadow_shadowmap, false, false, true); + r_shadow_compilingrtlight->static_meshchain_shadow_shadowmap = Mod_ShadowMesh_Finish(r_main_mempool, r_shadow_compilingrtlight->static_meshchain_shadow_shadowmap, false, true); r_shadow_compilingrtlight->static_shadowmap_receivers &= sidemasks; for(i = 0;i<6;i++) if(!sidetotals[i]) @@ -1464,7 +1390,7 @@ static void R_Q1BSP_DrawLight_TransparentCallback(const entity_render_t *ent, co // note: in practice this never actually receives batches R_Shadow_RenderMode_Begin(); R_Shadow_RenderMode_ActiveLight(rtlight); - R_Shadow_RenderMode_Lighting(false, true, rtlight->shadowmapatlassidesize != 0, (ent->flags & RENDER_NOSELFSHADOW) != 0); + R_Shadow_RenderMode_Lighting(true, rtlight->shadowmapatlassidesize != 0, (ent->flags & RENDER_NOSELFSHADOW) != 0); R_Shadow_SetupEntityLight(ent); for (i = 0;i < numsurfaces;i = j) { diff --git a/glquake.h b/glquake.h index 914162c6..646c3d36 100644 --- a/glquake.h +++ b/glquake.h @@ -439,21 +439,6 @@ extern void (GLAPIENTRY *qglCopyTexSubImage3D)(GLenum target, GLint level, GLint #define GL_CLAMP_TO_EDGE 0x812F #endif -//GL_ATI_separate_stencil -#ifndef GL_STENCIL_BACK_FUNC -#define GL_STENCIL_BACK_FUNC 0x8800 -#define GL_STENCIL_BACK_FAIL 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 -#endif -extern void (GLAPIENTRY *qglStencilOpSeparate)(GLenum, GLenum, GLenum, GLenum); -extern void (GLAPIENTRY *qglStencilFuncSeparate)(GLenum, GLenum, GLint, GLuint); - -//GL_EXT_stencil_two_side -#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 -#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 -extern void (GLAPIENTRY *qglActiveStencilFaceEXT)(GLenum); - //GL_EXT_blend_minmax #ifndef GL_FUNC_ADD #define GL_FUNC_ADD 0x8006 // also supplied by GL_blend_subtract diff --git a/model_alias.c b/model_alias.c index e6427044..3cd08bec 100644 --- a/model_alias.c +++ b/model_alias.c @@ -1012,8 +1012,6 @@ void Mod_IDP0_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->DrawPrepass = R_Q1BSP_DrawPrepass; loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap; loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap; - loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume; - loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume; loadmodel->DrawLight = R_Q1BSP_DrawLight; loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox; loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine; @@ -1180,13 +1178,7 @@ void Mod_IDP0_Load(dp_model_t *mod, void *buffer, void *bufferend) // load the frames loadmodel->animscenes = (animscene_t *)Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numframes); loadmodel->surfmesh.data_morphmdlvertex = (trivertx_t *)Mem_Alloc(loadmodel->mempool, sizeof(trivertx_t) * loadmodel->surfmesh.num_morphframes * loadmodel->surfmesh.num_vertices); - if (r_enableshadowvolumes.integer) - { - loadmodel->surfmesh.data_neighbor3i = (int *)Mem_Alloc(loadmodel->mempool, loadmodel->surfmesh.num_triangles * sizeof(int[3])); - } Mod_MDL_LoadFrames (startframes, numverts, vertremap); - if (loadmodel->surfmesh.data_neighbor3i) - Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles); loadmodel->surfmesh.isanimated = Mod_Alias_CalculateBoundingBox(); Mod_Alias_MorphMesh_CompileFrames(); @@ -1376,8 +1368,6 @@ void Mod_IDP2_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->DrawPrepass = R_Q1BSP_DrawPrepass; loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap; loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap; - loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume; - loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume; loadmodel->DrawLight = R_Q1BSP_DrawLight; loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox; loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine; @@ -1419,17 +1409,13 @@ void Mod_IDP2_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->num_surfaces = 1; loadmodel->nummodelsurfaces = loadmodel->num_surfaces; - data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->numframes * sizeof(animscene_t) + loadmodel->numframes * sizeof(float[6]) + loadmodel->surfmesh.num_triangles * sizeof(int[3]) + (r_enableshadowvolumes.integer ? loadmodel->surfmesh.num_triangles * sizeof(int[3]) : 0)); + data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->numframes * sizeof(animscene_t) + loadmodel->numframes * sizeof(float[6]) + loadmodel->surfmesh.num_triangles * sizeof(int[3])); loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t); loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int); loadmodel->sortedmodelsurfaces[0] = 0; loadmodel->animscenes = (animscene_t *)data;data += loadmodel->numframes * sizeof(animscene_t); loadmodel->surfmesh.data_morphmd2framesize6f = (float *)data;data += loadmodel->numframes * sizeof(float[6]); loadmodel->surfmesh.data_element3i = (int *)data;data += loadmodel->surfmesh.num_triangles * sizeof(int[3]); - if (r_enableshadowvolumes.integer) - { - loadmodel->surfmesh.data_neighbor3i = (int *)data;data += loadmodel->surfmesh.num_triangles * sizeof(int[3]); - } loadmodel->synctype = ST_RAND; @@ -1573,8 +1559,6 @@ void Mod_IDP2_Load(dp_model_t *mod, void *buffer, void *bufferend) Mem_Free(vertremap); - if (loadmodel->surfmesh.data_neighbor3i) - Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles); loadmodel->surfmesh.isanimated = Mod_Alias_CalculateBoundingBox(); Mod_Alias_MorphMesh_CompileFrames(); if(mod_alias_force_animated.string[0]) @@ -1643,8 +1627,6 @@ void Mod_IDP3_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->DrawPrepass = R_Q1BSP_DrawPrepass; loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap; loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap; - loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume; - loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume; loadmodel->DrawLight = R_Q1BSP_DrawLight; loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox; loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine; @@ -1710,7 +1692,7 @@ void Mod_IDP3_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->nummodelsurfaces = loadmodel->num_surfaces; loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins; loadmodel->num_texturesperskin = loadmodel->num_surfaces; - data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (r_enableshadowvolumes.integer ? meshtriangles * sizeof(int[3]) : 0) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + meshvertices * sizeof(float[2]) + meshvertices * loadmodel->numframes * sizeof(md3vertex_t)); + data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + meshvertices * sizeof(float[2]) + meshvertices * loadmodel->numframes * sizeof(md3vertex_t)); loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t); loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int); loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t); @@ -1719,10 +1701,6 @@ void Mod_IDP3_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->surfmesh.num_morphframes = loadmodel->numframes; // TODO: remove? loadmodel->num_poses = loadmodel->surfmesh.num_morphframes; loadmodel->surfmesh.data_element3i = (int *)data;data += meshtriangles * sizeof(int[3]); - if (r_enableshadowvolumes.integer) - { - loadmodel->surfmesh.data_neighbor3i = (int *)data;data += meshtriangles * sizeof(int[3]); - } loadmodel->surfmesh.data_texcoordtexture2f = (float *)data;data += meshvertices * sizeof(float[2]); loadmodel->surfmesh.data_morphmd3vertex = (md3vertex_t *)data;data += meshvertices * loadmodel->numframes * sizeof(md3vertex_t); if (meshvertices <= 65536) @@ -1774,8 +1752,6 @@ void Mod_IDP3_Load(dp_model_t *mod, void *buffer, void *bufferend) if (loadmodel->surfmesh.data_element3s) for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++) loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i]; - if (loadmodel->surfmesh.data_neighbor3i) - Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles); Mod_Alias_MorphMesh_CompileFrames(); loadmodel->surfmesh.isanimated = Mod_Alias_CalculateBoundingBox(); Mod_FreeSkinFiles(skinfiles); @@ -1884,8 +1860,6 @@ void Mod_ZYMOTICMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->DrawPrepass = R_Q1BSP_DrawPrepass; loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap; loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap; - loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume; - loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume; loadmodel->DrawLight = R_Q1BSP_DrawLight; loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox; loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine; @@ -1983,17 +1957,13 @@ void Mod_ZYMOTICMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->nummodelsurfaces = loadmodel->num_surfaces; loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins; loadmodel->num_texturesperskin = loadmodel->num_surfaces; - data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (r_enableshadowvolumes.integer ? meshtriangles * sizeof(int[3]) : 0) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + meshvertices * (sizeof(float[14]) + sizeof(unsigned short) + sizeof(unsigned char[2][4])) + loadmodel->num_poses * loadmodel->num_bones * sizeof(short[7]) + loadmodel->num_bones * sizeof(float[12])); + data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + meshvertices * (sizeof(float[14]) + sizeof(unsigned short) + sizeof(unsigned char[2][4])) + loadmodel->num_poses * loadmodel->num_bones * sizeof(short[7]) + loadmodel->num_bones * sizeof(float[12])); loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t); loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int); loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t); loadmodel->surfmesh.num_vertices = meshvertices; loadmodel->surfmesh.num_triangles = meshtriangles; loadmodel->surfmesh.data_element3i = (int *)data;data += meshtriangles * sizeof(int[3]); - if (r_enableshadowvolumes.integer) - { - loadmodel->surfmesh.data_neighbor3i = (int *)data;data += meshtriangles * sizeof(int[3]); - } loadmodel->surfmesh.data_vertex3f = (float *)data;data += meshvertices * sizeof(float[3]); loadmodel->surfmesh.data_svector3f = (float *)data;data += meshvertices * sizeof(float[3]); loadmodel->surfmesh.data_tvector3f = (float *)data;data += meshvertices * sizeof(float[3]); @@ -2178,8 +2148,6 @@ void Mod_ZYMOTICMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) Mod_BuildBaseBonePoses(); Mod_BuildNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_normal3f, r_smoothnormals_areaweighting.integer != 0); Mod_BuildTextureVectorsFromNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_normal3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, r_smoothnormals_areaweighting.integer != 0); - if (loadmodel->surfmesh.data_neighbor3i) - Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles); loadmodel->surfmesh.isanimated = Mod_Alias_CalculateBoundingBox(); if(mod_alias_force_animated.string[0]) loadmodel->surfmesh.isanimated = mod_alias_force_animated.integer != 0; @@ -2269,8 +2237,6 @@ void Mod_DARKPLACESMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->DrawPrepass = R_Q1BSP_DrawPrepass; loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap; loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap; - loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume; - loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume; loadmodel->DrawLight = R_Q1BSP_DrawLight; loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox; loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine; @@ -2316,17 +2282,13 @@ void Mod_DARKPLACESMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins; loadmodel->num_texturesperskin = loadmodel->num_surfaces; // do most allocations as one merged chunk - data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + (r_enableshadowvolumes.integer ? meshtriangles * sizeof(int[3]) : 0) + meshvertices * (sizeof(float[14]) + sizeof(unsigned short) + sizeof(unsigned char[2][4])) + loadmodel->num_poses * loadmodel->num_bones * sizeof(short[7]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t)); + data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + meshvertices * (sizeof(float[14]) + sizeof(unsigned short) + sizeof(unsigned char[2][4])) + loadmodel->num_poses * loadmodel->num_bones * sizeof(short[7]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t)); loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t); loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int); loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t); loadmodel->surfmesh.num_vertices = meshvertices; loadmodel->surfmesh.num_triangles = meshtriangles; loadmodel->surfmesh.data_element3i = (int *)data;data += meshtriangles * sizeof(int[3]); - if (r_enableshadowvolumes.integer) - { - loadmodel->surfmesh.data_neighbor3i = (int *)data;data += meshtriangles * sizeof(int[3]); - } loadmodel->surfmesh.data_vertex3f = (float *)data;data += meshvertices * sizeof(float[3]); loadmodel->surfmesh.data_svector3f = (float *)data;data += meshvertices * sizeof(float[3]); loadmodel->surfmesh.data_tvector3f = (float *)data;data += meshvertices * sizeof(float[3]); @@ -2557,8 +2519,6 @@ void Mod_DARKPLACESMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i]; Mod_BuildBaseBonePoses(); Mod_BuildTextureVectorsFromNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_normal3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, r_smoothnormals_areaweighting.integer != 0); - if (loadmodel->surfmesh.data_neighbor3i) - Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles); loadmodel->surfmesh.isanimated = Mod_Alias_CalculateBoundingBox(); if(mod_alias_force_animated.string[0]) loadmodel->surfmesh.isanimated = mod_alias_force_animated.integer != 0; @@ -2623,8 +2583,6 @@ void Mod_PSKMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->DrawPrepass = R_Q1BSP_DrawPrepass; loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap; loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap; - loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume; - loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume; loadmodel->DrawLight = R_Q1BSP_DrawLight; loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox; loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine; @@ -2984,16 +2942,12 @@ void Mod_PSKMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->surfmesh.num_vertices = meshvertices; loadmodel->surfmesh.num_triangles = meshtriangles; // do most allocations as one merged chunk - size = loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + loadmodel->surfmesh.num_triangles * sizeof(int[3]) + (r_enableshadowvolumes.integer ? loadmodel->surfmesh.num_triangles * sizeof(int[3]) : 0) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[2]) + loadmodel->surfmesh.num_vertices * sizeof(unsigned char[4]) + loadmodel->surfmesh.num_vertices * sizeof(unsigned char[4]) + loadmodel->surfmesh.num_vertices * sizeof(unsigned short) + loadmodel->num_poses * loadmodel->num_bones * sizeof(short[7]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t) + ((loadmodel->surfmesh.num_vertices <= 65536) ? (loadmodel->surfmesh.num_triangles * sizeof(unsigned short[3])) : 0); + size = loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + loadmodel->surfmesh.num_triangles * sizeof(int[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[2]) + loadmodel->surfmesh.num_vertices * sizeof(unsigned char[4]) + loadmodel->surfmesh.num_vertices * sizeof(unsigned char[4]) + loadmodel->surfmesh.num_vertices * sizeof(unsigned short) + loadmodel->num_poses * loadmodel->num_bones * sizeof(short[7]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t) + ((loadmodel->surfmesh.num_vertices <= 65536) ? (loadmodel->surfmesh.num_triangles * sizeof(unsigned short[3])) : 0); data = (unsigned char *)Mem_Alloc(loadmodel->mempool, size); loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t); loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int); loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t); loadmodel->surfmesh.data_element3i = (int *)data;data += loadmodel->surfmesh.num_triangles * sizeof(int[3]); - if (r_enableshadowvolumes.integer) - { - loadmodel->surfmesh.data_neighbor3i = (int *)data;data += loadmodel->surfmesh.num_triangles * sizeof(int[3]); - } loadmodel->surfmesh.data_vertex3f = (float *)data;data += loadmodel->surfmesh.num_vertices * sizeof(float[3]); loadmodel->surfmesh.data_svector3f = (float *)data;data += loadmodel->surfmesh.num_vertices * sizeof(float[3]); loadmodel->surfmesh.data_tvector3f = (float *)data;data += loadmodel->surfmesh.num_vertices * sizeof(float[3]); @@ -3236,8 +3190,6 @@ void Mod_PSKMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) Mod_ValidateElements(loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_element3s, loadmodel->surfmesh.num_triangles, 0, loadmodel->surfmesh.num_vertices, __FILE__, __LINE__); Mod_BuildNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_normal3f, r_smoothnormals_areaweighting.integer != 0); Mod_BuildTextureVectorsFromNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_normal3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, r_smoothnormals_areaweighting.integer != 0); - if (loadmodel->surfmesh.data_neighbor3i) - Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles); loadmodel->surfmesh.isanimated = Mod_Alias_CalculateBoundingBox(); if(mod_alias_force_animated.string[0]) loadmodel->surfmesh.isanimated = mod_alias_force_animated.integer != 0; @@ -3274,8 +3226,6 @@ void Mod_INTERQUAKEMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) float biggestorigin; const unsigned int *inelements; int *outelements; - const int *inneighbors; - int *outneighbors; float *outvertex, *outnormal, *outtexcoord, *outsvector, *outtvector, *outcolor; // this pointers into the file data are read only through Little* functions so they can be unaligned memory const float *vnormal = NULL; @@ -3457,8 +3407,6 @@ void Mod_INTERQUAKEMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->DrawPrepass = R_Q1BSP_DrawPrepass; loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap; loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap; - loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume; - loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume; loadmodel->DrawLight = R_Q1BSP_DrawLight; loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox; loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine; @@ -3481,17 +3429,13 @@ void Mod_INTERQUAKEMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) meshtriangles = header.num_triangles; // do most allocations as one merged chunk - data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + (r_enableshadowvolumes.integer ? meshtriangles * sizeof(int[3]) : 0) + meshvertices * (sizeof(float[14]) + (vcolor4f || vcolor4ub ? sizeof(float[4]) : 0)) + (vblendindexes && vblendweights ? meshvertices * (sizeof(unsigned short) + sizeof(unsigned char[2][4])) : 0) + loadmodel->num_poses * loadmodel->num_bones * sizeof(short[7]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t)); + data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + meshvertices * (sizeof(float[14]) + (vcolor4f || vcolor4ub ? sizeof(float[4]) : 0)) + (vblendindexes && vblendweights ? meshvertices * (sizeof(unsigned short) + sizeof(unsigned char[2][4])) : 0) + loadmodel->num_poses * loadmodel->num_bones * sizeof(short[7]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t)); loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t); loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int); loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t); loadmodel->surfmesh.num_vertices = meshvertices; loadmodel->surfmesh.num_triangles = meshtriangles; loadmodel->surfmesh.data_element3i = (int *)data;data += meshtriangles * sizeof(int[3]); - if (r_enableshadowvolumes.integer) - { - loadmodel->surfmesh.data_neighbor3i = (int *)data;data += meshtriangles * sizeof(int[3]); - } loadmodel->surfmesh.data_vertex3f = (float *)data;data += meshvertices * sizeof(float[3]); loadmodel->surfmesh.data_svector3f = (float *)data;data += meshvertices * sizeof(float[3]); loadmodel->surfmesh.data_tvector3f = (float *)data;data += meshvertices * sizeof(float[3]); @@ -3847,21 +3791,6 @@ void Mod_INTERQUAKEMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) } Mod_ValidateElements(loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_element3s, loadmodel->surfmesh.num_triangles, 0, header.num_vertexes, __FILE__, __LINE__); - if (header.ofs_neighbors && loadmodel->surfmesh.data_neighbor3i) - { - // this unaligned memory access is safe (LittleLong reads as bytes) - inneighbors = (const int *)(pbase + header.ofs_neighbors); - outneighbors = loadmodel->surfmesh.data_neighbor3i; - for (i = 0;i < (int)header.num_triangles;i++) - { - outneighbors[0] = LittleLong(inneighbors[0]); - outneighbors[1] = LittleLong(inneighbors[1]); - outneighbors[2] = LittleLong(inneighbors[2]); - outneighbors += 3; - inneighbors += 3; - } - } - // load vertex data // this unaligned memory access is safe (LittleFloat reads as bytes) outvertex = loadmodel->surfmesh.data_vertex3f; @@ -4004,8 +3933,6 @@ void Mod_INTERQUAKEMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) Mod_BuildNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_normal3f, r_smoothnormals_areaweighting.integer != 0); if (!vnormal || !vtangent) Mod_BuildTextureVectorsFromNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_normal3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, r_smoothnormals_areaweighting.integer != 0); - if (!header.ofs_neighbors && loadmodel->surfmesh.data_neighbor3i) - Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles); if (!header.ofs_bounds) Mod_Alias_CalculateBoundingBox(); diff --git a/model_brush.c b/model_brush.c index c355b1a2..0cd1e191 100644 --- a/model_brush.c +++ b/model_brush.c @@ -2587,7 +2587,7 @@ static void Mod_Q1BSP_LoadFaces(sizebuf_t *sb) totaltris += numedges - 2; } - Mod_AllocSurfMesh(loadmodel->mempool, totalverts, totaltris, true, false, false); + Mod_AllocSurfMesh(loadmodel->mempool, totalverts, totaltris, true, false); lightmaptexture = NULL; deluxemaptexture = r_texture_blanknormalmap; @@ -3866,13 +3866,11 @@ static int Mod_Q1BSP_CreateShadowMesh(dp_model_t *mod) surface->num_firstshadowmeshtriangle = numshadowmeshtriangles; numshadowmeshtriangles += surface->num_triangles; } - mod->brush.shadowmesh = Mod_ShadowMesh_Begin(mod->mempool, numshadowmeshtriangles * 3, numshadowmeshtriangles, NULL, NULL, NULL, false, false, true); + mod->brush.shadowmesh = Mod_ShadowMesh_Begin(mod->mempool, numshadowmeshtriangles * 3, numshadowmeshtriangles, NULL, NULL, NULL, false, true); for (j = 0, surface = mod->data_surfaces;j < mod->num_surfaces;j++, surface++) if (surface->num_triangles > 0) Mod_ShadowMesh_AddMesh(mod->mempool, mod->brush.shadowmesh, NULL, NULL, NULL, mod->surfmesh.data_vertex3f, NULL, NULL, NULL, NULL, surface->num_triangles, (mod->surfmesh.data_element3i + 3 * surface->num_firsttriangle)); - mod->brush.shadowmesh = Mod_ShadowMesh_Finish(mod->mempool, mod->brush.shadowmesh, false, r_enableshadowvolumes.integer != 0, false); - if (mod->brush.shadowmesh && mod->brush.shadowmesh->neighbor3i) - Mod_BuildTriangleNeighbors(mod->brush.shadowmesh->neighbor3i, mod->brush.shadowmesh->element3i, mod->brush.shadowmesh->numtriangles); + mod->brush.shadowmesh = Mod_ShadowMesh_Finish(mod->mempool, mod->brush.shadowmesh, false, false); return numshadowmeshtriangles; } @@ -3986,8 +3984,6 @@ void Mod_Q1BSP_Load(dp_model_t *mod, void *buffer, void *bufferend) mod->GetLightInfo = R_Q1BSP_GetLightInfo; mod->CompileShadowMap = R_Q1BSP_CompileShadowMap; mod->DrawShadowMap = R_Q1BSP_DrawShadowMap; - mod->CompileShadowVolume = R_Q1BSP_CompileShadowVolume; - mod->DrawShadowVolume = R_Q1BSP_DrawShadowVolume; mod->DrawLight = R_Q1BSP_DrawLight; // load into heap @@ -4969,8 +4965,6 @@ static void Mod_Q2BSP_Load(dp_model_t *mod, void *buffer, void *bufferend) mod->GetLightInfo = R_Q1BSP_GetLightInfo; mod->CompileShadowMap = R_Q1BSP_CompileShadowMap; mod->DrawShadowMap = R_Q1BSP_DrawShadowMap; - mod->CompileShadowVolume = R_Q1BSP_CompileShadowVolume; - mod->DrawShadowVolume = R_Q1BSP_DrawShadowVolume; mod->DrawLight = R_Q1BSP_DrawLight; // load into heap @@ -5938,7 +5932,6 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l) int i, oldi, j, n, count, invalidelements, patchsize[2], finalwidth, finalheight, xtess, ytess, finalvertices, finaltriangles, firstvertex, firstelement, type, oldnumtriangles, oldnumtriangles2, meshvertices, meshtriangles, collisionvertices, collisiontriangles, numvertices, numtriangles, cxtess, cytess; float lightmaptcbase[2], lightmaptcscale[2]; //int *originalelement3i; - //int *originalneighbor3i; float *originalvertex3f; //float *originalsvector3f; //float *originaltvector3f; @@ -6158,7 +6151,7 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l) i = oldi; in = oldin; out = oldout; - Mod_AllocSurfMesh(loadmodel->mempool, meshvertices, meshtriangles, false, true, false); + Mod_AllocSurfMesh(loadmodel->mempool, meshvertices, meshtriangles, false, true); if (collisiontriangles) { loadmodel->brush.data_collisionvertex3f = (float *)Mem_Alloc(loadmodel->mempool, collisionvertices * sizeof(float[3])); @@ -7925,8 +7918,6 @@ static void Mod_Q3BSP_Load(dp_model_t *mod, void *buffer, void *bufferend) mod->GetLightInfo = R_Q1BSP_GetLightInfo; mod->CompileShadowMap = R_Q1BSP_CompileShadowMap; mod->DrawShadowMap = R_Q1BSP_DrawShadowMap; - mod->CompileShadowVolume = R_Q1BSP_CompileShadowVolume; - mod->DrawShadowVolume = R_Q1BSP_DrawShadowVolume; mod->DrawLight = R_Q1BSP_DrawLight; mod_base = (unsigned char *)header; @@ -8246,8 +8237,6 @@ void Mod_OBJ_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->GetLightInfo = R_Q1BSP_GetLightInfo; loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap; loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap; - loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume; - loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume; loadmodel->DrawLight = R_Q1BSP_DrawLight; skinfiles = Mod_LoadSkinFiles(); @@ -8583,14 +8572,12 @@ void Mod_OBJ_Load(dp_model_t *mod, void *buffer, void *bufferend) // allocate storage for final mesh data loadmodel->num_textures = numtextures * loadmodel->numskins; loadmodel->num_texturesperskin = numtextures; - data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + numtriangles * sizeof(int[3]) + (numvertices <= 65536 ? numtriangles * sizeof(unsigned short[3]) : 0) + (r_enableshadowvolumes.integer ? numtriangles * sizeof(int[3]) : 0) + numvertices * sizeof(float[14]) + loadmodel->brush.numsubmodels * sizeof(dp_model_t *)); + data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + numtriangles * sizeof(int[3]) + (numvertices <= 65536 ? numtriangles * sizeof(unsigned short[3]) : 0) + numvertices * sizeof(float[14]) + loadmodel->brush.numsubmodels * sizeof(dp_model_t *)); loadmodel->brush.submodels = (dp_model_t **)data;data += loadmodel->brush.numsubmodels * sizeof(dp_model_t *); loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int); loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t); loadmodel->surfmesh.num_vertices = numvertices; loadmodel->surfmesh.num_triangles = numtriangles; - if (r_enableshadowvolumes.integer) - loadmodel->surfmesh.data_neighbor3i = (int *)data;data += numtriangles * sizeof(int[3]); loadmodel->surfmesh.data_vertex3f = (float *)data;data += numvertices * sizeof(float[3]); loadmodel->surfmesh.data_svector3f = (float *)data;data += numvertices * sizeof(float[3]); loadmodel->surfmesh.data_tvector3f = (float *)data;data += numvertices * sizeof(float[3]); @@ -8636,8 +8623,6 @@ void Mod_OBJ_Load(dp_model_t *mod, void *buffer, void *bufferend) if (!VectorLength2(loadmodel->surfmesh.data_normal3f)) Mod_BuildNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_normal3f, r_smoothnormals_areaweighting.integer != 0); Mod_BuildTextureVectorsFromNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_normal3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, r_smoothnormals_areaweighting.integer != 0); - if (loadmodel->surfmesh.data_neighbor3i) - Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles); // if this is a worldmodel and has no BSP tree, create a fake one for the purpose loadmodel->brush.num_visleafs = 1; diff --git a/model_shared.c b/model_shared.c index c4a716a7..0ebf4baa 100644 --- a/model_shared.c +++ b/model_shared.c @@ -27,7 +27,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "r_shadow.h" #include "polygon.h" -cvar_t r_enableshadowvolumes = {CVAR_SAVE, "r_enableshadowvolumes", "1", "Enables use of Stencil Shadow Volume shadowing methods, saves some memory if turned off"}; cvar_t r_mipskins = {CVAR_SAVE, "r_mipskins", "0", "mipmaps model skins so they render faster in the distance and do not display noise artifacts, can cause discoloration of skins if they contain undesirable border colors"}; cvar_t r_mipnormalmaps = {CVAR_SAVE, "r_mipnormalmaps", "1", "mipmaps normalmaps (turning it off looks sharper but may have aliasing)"}; cvar_t mod_generatelightmaps_unitspersample = {CVAR_SAVE, "mod_generatelightmaps_unitspersample", "8", "lightmap resolution"}; @@ -162,7 +161,6 @@ void Mod_Init (void) Mod_AliasInit(); Mod_SpriteInit(); - Cvar_RegisterVariable(&r_enableshadowvolumes); Cvar_RegisterVariable(&r_mipskins); Cvar_RegisterVariable(&r_mipnormalmaps); Cvar_RegisterVariable(&mod_generatelightmaps_unitspersample); @@ -703,119 +701,6 @@ int Mod_BuildVertexRemapTableFromElements(int numelements, const int *elements, return count; } -#if 1 -// fast way, using an edge hash -#define TRIANGLEEDGEHASH 8192 -void Mod_BuildTriangleNeighbors(int *neighbors, const int *elements, int numtriangles) -{ - int i, j, p, e1, e2, *n, hashindex, count, match; - const int *e; - typedef struct edgehashentry_s - { - struct edgehashentry_s *next; - int triangle; - int element[2]; - } - edgehashentry_t; - static edgehashentry_t **edgehash; - edgehashentry_t *edgehashentries, *hash; - if (!numtriangles) - return; - edgehash = (edgehashentry_t **)Mem_Alloc(tempmempool, TRIANGLEEDGEHASH * sizeof(*edgehash)); - // if there are too many triangles for the stack array, allocate larger buffer - edgehashentries = (edgehashentry_t *)Mem_Alloc(tempmempool, numtriangles * 3 * sizeof(edgehashentry_t)); - // find neighboring triangles - for (i = 0, e = elements, n = neighbors;i < numtriangles;i++, e += 3, n += 3) - { - for (j = 0, p = 2;j < 3;p = j, j++) - { - e1 = e[p]; - e2 = e[j]; - // this hash index works for both forward and backward edges - hashindex = (unsigned int)(e1 + e2) % TRIANGLEEDGEHASH; - hash = edgehashentries + i * 3 + j; - hash->next = edgehash[hashindex]; - edgehash[hashindex] = hash; - hash->triangle = i; - hash->element[0] = e1; - hash->element[1] = e2; - } - } - for (i = 0, e = elements, n = neighbors;i < numtriangles;i++, e += 3, n += 3) - { - for (j = 0, p = 2;j < 3;p = j, j++) - { - e1 = e[p]; - e2 = e[j]; - // this hash index works for both forward and backward edges - hashindex = (unsigned int)(e1 + e2) % TRIANGLEEDGEHASH; - count = 0; - match = -1; - for (hash = edgehash[hashindex];hash;hash = hash->next) - { - if (hash->element[0] == e2 && hash->element[1] == e1) - { - if (hash->triangle != i) - match = hash->triangle; - count++; - } - else if ((hash->element[0] == e1 && hash->element[1] == e2)) - count++; - } - // detect edges shared by three triangles and make them seams - if (count > 2) - match = -1; - n[p] = match; - } - - // also send a keepalive here (this can take a while too!) - CL_KeepaliveMessage(false); - } - // free the allocated buffer - Mem_Free(edgehashentries); - Mem_Free(edgehash); -} -#else -// very slow but simple way -static int Mod_FindTriangleWithEdge(const int *elements, int numtriangles, int start, int end, int ignore) -{ - int i, match, count; - count = 0; - match = -1; - for (i = 0;i < numtriangles;i++, elements += 3) - { - if ((elements[0] == start && elements[1] == end) - || (elements[1] == start && elements[2] == end) - || (elements[2] == start && elements[0] == end)) - { - if (i != ignore) - match = i; - count++; - } - else if ((elements[1] == start && elements[0] == end) - || (elements[2] == start && elements[1] == end) - || (elements[0] == start && elements[2] == end)) - count++; - } - // detect edges shared by three triangles and make them seams - if (count > 2) - match = -1; - return match; -} - -void Mod_BuildTriangleNeighbors(int *neighbors, const int *elements, int numtriangles) -{ - int i, *n; - const int *e; - for (i = 0, e = elements, n = neighbors;i < numtriangles;i++, e += 3, n += 3) - { - n[0] = Mod_FindTriangleWithEdge(elements, numtriangles, e[1], e[0], i); - n[1] = Mod_FindTriangleWithEdge(elements, numtriangles, e[2], e[1], i); - n[2] = Mod_FindTriangleWithEdge(elements, numtriangles, e[0], e[2], i); - } -} -#endif - qboolean Mod_ValidateElements(int *element3i, unsigned short *element3s, int numtriangles, int firstvertex, int numvertices, const char *filename, int fileline) { int first = firstvertex, last = first + numvertices - 1, numelements = numtriangles * 3; @@ -1051,10 +936,10 @@ void Mod_BuildTextureVectorsFromNormals(int firstvertex, int numvertices, int nu } } -void Mod_AllocSurfMesh(mempool_t *mempool, int numvertices, int numtriangles, qboolean lightmapoffsets, qboolean vertexcolors, qboolean neighbors) +void Mod_AllocSurfMesh(mempool_t *mempool, int numvertices, int numtriangles, qboolean lightmapoffsets, qboolean vertexcolors) { unsigned char *data; - data = (unsigned char *)Mem_Alloc(mempool, numvertices * (3 + 3 + 3 + 3 + 2 + 2 + (vertexcolors ? 4 : 0)) * sizeof(float) + numvertices * (lightmapoffsets ? 1 : 0) * sizeof(int) + numtriangles * (3 + (neighbors ? 3 : 0)) * sizeof(int) + (numvertices <= 65536 ? numtriangles * sizeof(unsigned short[3]) : 0)); + data = (unsigned char *)Mem_Alloc(mempool, numvertices * (3 + 3 + 3 + 3 + 2 + 2 + (vertexcolors ? 4 : 0)) * sizeof(float) + numvertices * (lightmapoffsets ? 1 : 0) * sizeof(int) + numtriangles * sizeof(int[3]) + (numvertices <= 65536 ? numtriangles * sizeof(unsigned short[3]) : 0)); loadmodel->surfmesh.num_vertices = numvertices; loadmodel->surfmesh.num_triangles = numtriangles; if (loadmodel->surfmesh.num_vertices) @@ -1073,14 +958,12 @@ void Mod_AllocSurfMesh(mempool_t *mempool, int numvertices, int numtriangles, qb if (loadmodel->surfmesh.num_triangles) { loadmodel->surfmesh.data_element3i = (int *)data, data += sizeof(int[3]) * loadmodel->surfmesh.num_triangles; - if (neighbors) - loadmodel->surfmesh.data_neighbor3i = (int *)data, data += sizeof(int[3]) * loadmodel->surfmesh.num_triangles; if (loadmodel->surfmesh.num_vertices <= 65536) loadmodel->surfmesh.data_element3s = (unsigned short *)data, data += sizeof(unsigned short[3]) * loadmodel->surfmesh.num_triangles; } } -shadowmesh_t *Mod_ShadowMesh_Alloc(mempool_t *mempool, int maxverts, int maxtriangles, rtexture_t *map_diffuse, rtexture_t *map_specular, rtexture_t *map_normal, int light, int neighbors, int expandable) +shadowmesh_t *Mod_ShadowMesh_Alloc(mempool_t *mempool, int maxverts, int maxtriangles, rtexture_t *map_diffuse, rtexture_t *map_specular, rtexture_t *map_normal, int light, int expandable) { shadowmesh_t *newmesh; unsigned char *data; @@ -1092,8 +975,6 @@ shadowmesh_t *Mod_ShadowMesh_Alloc(mempool_t *mempool, int maxverts, int maxtria size += maxtriangles * sizeof(int[3]); if (maxverts <= 65536) size += maxtriangles * sizeof(unsigned short[3]); - if (neighbors) - size += maxtriangles * sizeof(int[3]); if (expandable) size += SHADOWMESHVERTEXHASH * sizeof(shadowmeshvertexhash_t *) + maxverts * sizeof(shadowmeshvertexhash_t); data = (unsigned char *)Mem_Alloc(mempool, size); @@ -1117,10 +998,6 @@ shadowmesh_t *Mod_ShadowMesh_Alloc(mempool_t *mempool, int maxverts, int maxtria newmesh->texcoord2f = (float *)data;data += maxverts * sizeof(float[2]); } newmesh->element3i = (int *)data;data += maxtriangles * sizeof(int[3]); - if (neighbors) - { - newmesh->neighbor3i = (int *)data;data += maxtriangles * sizeof(int[3]); - } if (expandable) { newmesh->vertexhashtable = (shadowmeshvertexhash_t **)data;data += SHADOWMESHVERTEXHASH * sizeof(shadowmeshvertexhash_t *); @@ -1131,10 +1008,10 @@ shadowmesh_t *Mod_ShadowMesh_Alloc(mempool_t *mempool, int maxverts, int maxtria return newmesh; } -shadowmesh_t *Mod_ShadowMesh_ReAlloc(mempool_t *mempool, shadowmesh_t *oldmesh, int light, int neighbors) +shadowmesh_t *Mod_ShadowMesh_ReAlloc(mempool_t *mempool, shadowmesh_t *oldmesh, int light) { shadowmesh_t *newmesh; - newmesh = Mod_ShadowMesh_Alloc(mempool, oldmesh->numverts, oldmesh->numtriangles, oldmesh->map_diffuse, oldmesh->map_specular, oldmesh->map_normal, light, neighbors, false); + newmesh = Mod_ShadowMesh_Alloc(mempool, oldmesh->numverts, oldmesh->numtriangles, oldmesh->map_diffuse, oldmesh->map_specular, oldmesh->map_normal, light, false); newmesh->numverts = oldmesh->numverts; newmesh->numtriangles = oldmesh->numtriangles; memcpy(newmesh->sideoffsets, oldmesh->sideoffsets, sizeof(oldmesh->sideoffsets)); @@ -1149,8 +1026,6 @@ shadowmesh_t *Mod_ShadowMesh_ReAlloc(mempool_t *mempool, shadowmesh_t *oldmesh, memcpy(newmesh->texcoord2f, oldmesh->texcoord2f, oldmesh->numverts * sizeof(float[2])); } memcpy(newmesh->element3i, oldmesh->element3i, oldmesh->numtriangles * sizeof(int[3])); - if (newmesh->neighbor3i && oldmesh->neighbor3i) - memcpy(newmesh->neighbor3i, oldmesh->neighbor3i, oldmesh->numtriangles * sizeof(int[3])); return newmesh; } @@ -1195,7 +1070,7 @@ void Mod_ShadowMesh_AddTriangle(mempool_t *mempool, shadowmesh_t *mesh, rtexture while (mesh->map_diffuse != map_diffuse || mesh->map_specular != map_specular || mesh->map_normal != map_normal || mesh->numverts + 3 > mesh->maxverts || mesh->numtriangles + 1 > mesh->maxtriangles) { if (mesh->next == NULL) - mesh->next = Mod_ShadowMesh_Alloc(mempool, max(mesh->maxverts, 300), max(mesh->maxtriangles, 100), map_diffuse, map_specular, map_normal, mesh->svector3f != NULL, mesh->neighbor3i != NULL, true); + mesh->next = Mod_ShadowMesh_Alloc(mempool, max(mesh->maxverts, 300), max(mesh->maxtriangles, 100), map_diffuse, map_specular, map_normal, mesh->svector3f != NULL, true); mesh = mesh->next; } mesh->element3i[mesh->numtriangles * 3 + 0] = Mod_ShadowMesh_AddVertex(mesh, vertex14f + 14 * 0); @@ -1251,12 +1126,12 @@ void Mod_ShadowMesh_AddMesh(mempool_t *mempool, shadowmesh_t *mesh, rtexture_t * CL_KeepaliveMessage(false); } -shadowmesh_t *Mod_ShadowMesh_Begin(mempool_t *mempool, int maxverts, int maxtriangles, rtexture_t *map_diffuse, rtexture_t *map_specular, rtexture_t *map_normal, int light, int neighbors, int expandable) +shadowmesh_t *Mod_ShadowMesh_Begin(mempool_t *mempool, int maxverts, int maxtriangles, rtexture_t *map_diffuse, rtexture_t *map_specular, rtexture_t *map_normal, int light, int expandable) { // the preparation before shadow mesh initialization can take a while, so let's do a keepalive here CL_KeepaliveMessage(false); - return Mod_ShadowMesh_Alloc(mempool, maxverts, maxtriangles, map_diffuse, map_specular, map_normal, light, neighbors, expandable); + return Mod_ShadowMesh_Alloc(mempool, maxverts, maxtriangles, map_diffuse, map_specular, map_normal, light, expandable); } static void Mod_ShadowMesh_CreateVBOs(shadowmesh_t *mesh, mempool_t *mempool) @@ -1321,7 +1196,7 @@ static void Mod_ShadowMesh_CreateVBOs(shadowmesh_t *mesh, mempool_t *mempool) } } -shadowmesh_t *Mod_ShadowMesh_Finish(mempool_t *mempool, shadowmesh_t *firstmesh, qboolean light, qboolean neighbors, qboolean createvbo) +shadowmesh_t *Mod_ShadowMesh_Finish(mempool_t *mempool, shadowmesh_t *firstmesh, qboolean light, qboolean createvbo) { shadowmesh_t *mesh, *newmesh, *nextmesh; // reallocate meshs to conserve space @@ -1330,7 +1205,7 @@ shadowmesh_t *Mod_ShadowMesh_Finish(mempool_t *mempool, shadowmesh_t *firstmesh, nextmesh = mesh->next; if (mesh->numverts >= 3 && mesh->numtriangles >= 1) { - newmesh = Mod_ShadowMesh_ReAlloc(mempool, mesh, light, neighbors); + newmesh = Mod_ShadowMesh_ReAlloc(mempool, mesh, light); newmesh->next = firstmesh; firstmesh = newmesh; if (newmesh->element3s) @@ -1441,7 +1316,7 @@ void Mod_CreateCollisionMesh(dp_model_t *mod) continue; numcollisionmeshtriangles += surface->num_triangles; } - mod->brush.collisionmesh = Mod_ShadowMesh_Begin(mempool, numcollisionmeshtriangles * 3, numcollisionmeshtriangles, NULL, NULL, NULL, false, false, true); + mod->brush.collisionmesh = Mod_ShadowMesh_Begin(mempool, numcollisionmeshtriangles * 3, numcollisionmeshtriangles, NULL, NULL, NULL, false, true); if (usesinglecollisionmesh) Mod_ShadowMesh_AddMesh(mempool, mod->brush.collisionmesh, NULL, NULL, NULL, mod->surfmesh.data_vertex3f, NULL, NULL, NULL, NULL, surface->num_triangles, (mod->surfmesh.data_element3i + 3 * surface->num_firsttriangle)); else @@ -1454,7 +1329,7 @@ void Mod_CreateCollisionMesh(dp_model_t *mod) Mod_ShadowMesh_AddMesh(mempool, mod->brush.collisionmesh, NULL, NULL, NULL, mod->surfmesh.data_vertex3f, NULL, NULL, NULL, NULL, surface->num_triangles, (mod->surfmesh.data_element3i + 3 * surface->num_firsttriangle)); } } - mod->brush.collisionmesh = Mod_ShadowMesh_Finish(mempool, mod->brush.collisionmesh, false, false, false); + mod->brush.collisionmesh = Mod_ShadowMesh_Finish(mempool, mod->brush.collisionmesh, false, false); } #if 0 @@ -1498,7 +1373,7 @@ static void Mod_GetTerrainVertexFromBGRA(const unsigned char *imagepixels, int i VectorAdd(normal3f, nl, normal3f); } -static void Mod_ConstructTerrainPatchFromBGRA(const unsigned char *imagepixels, int imagewidth, int imageheight, int x1, int y1, int width, int height, int *element3i, int *neighbor3i, float *vertex3f, float *svector3f, float *tvector3f, float *normal3f, float *texcoord2f, matrix4x4_t *pixelstepmatrix, matrix4x4_t *pixeltexturestepmatrix) +static void Mod_ConstructTerrainPatchFromBGRA(const unsigned char *imagepixels, int imagewidth, int imageheight, int x1, int y1, int width, int height, int *element3i, float *vertex3f, float *svector3f, float *tvector3f, float *normal3f, float *texcoord2f, matrix4x4_t *pixelstepmatrix, matrix4x4_t *pixeltexturestepmatrix) { int x, y, ix, iy, *e; e = element3i; @@ -1515,7 +1390,6 @@ static void Mod_ConstructTerrainPatchFromBGRA(const unsigned char *imagepixels, e += 6; } } - Mod_BuildTriangleNeighbors(neighbor3i, element3i, width*height*2); for (y = 0, iy = y1;y < height + 1;y++, iy++) for (x = 0, ix = x1;x < width + 1;x++, ix++, vertex3f += 3, texcoord2f += 2, svector3f += 3, tvector3f += 3, normal3f += 3) Mod_GetTerrainVertexFromBGRA(imagepixels, imagewidth, imageheight, ix, iy, vertex3f, texcoord2f, svector3f, tvector3f, normal3f, pixelstepmatrix, pixeltexturestepmatrix); @@ -4384,7 +4258,7 @@ static void Mod_GenerateLightmaps_CreateLightmaps(dp_model_t *model) // lightmap coordinates here are in pixels // lightmap projections are snapped to pixel grid explicitly, such // that two neighboring triangles sharing an edge and projection - // axis will have identical sampl espacing along their shared edge + // axis will have identical sample spacing along their shared edge k = 0; for (j = 0;j < 3;j++) { @@ -4650,7 +4524,6 @@ void Mod_Mesh_Create(dp_model_t *mod, const char *name) mod->DrawPrepass = R_Q1BSP_DrawPrepass; mod->GetLightInfo = R_Q1BSP_GetLightInfo; mod->DrawShadowMap = R_Q1BSP_DrawShadowMap; - mod->DrawShadowVolume = R_Q1BSP_DrawShadowVolume; mod->DrawLight = R_Q1BSP_DrawLight; } diff --git a/model_shared.h b/model_shared.h index d83fe2cc..54331d1a 100644 --- a/model_shared.h +++ b/model_shared.h @@ -150,7 +150,6 @@ typedef struct surfmesh_s unsigned short *data_element3s; // unsigned short[tris*3] triangles of the mesh in unsigned short format (NULL if num_vertices > 65536) r_meshbuffer_t *data_element3s_indexbuffer; int data_element3s_bufferoffset; - int *data_neighbor3i; // int[tris*3] neighboring triangle on each edge (-1 if none) // vertex data in system memory int num_vertices; // number of vertices in the mesh float *data_vertex3f; // float[verts*3] vertex locations @@ -239,8 +238,6 @@ typedef struct shadowmesh_s r_vertexmesh_t *vertexmesh; // usually NULL // used for shadow mapping cubemap side partitioning int sideoffsets[6], sidetotals[6]; - // used for shadow mesh (NULL on light mesh) - int *neighbor3i; // these are NULL after Mod_ShadowMesh_Finish is performed, only used // while building meshes shadowmeshvertexhash_t **vertexhashtable, *vertexhashentries; @@ -1098,10 +1095,6 @@ typedef struct model_s void(*DrawShadowMap)(int side, struct entity_render_s *ent, const vec3_t relativelightorigin, const vec3_t relativelightdirection, float lightradius, int numsurfaces, const int *surfacelist, const unsigned char *surfacesides, const vec3_t lightmins, const vec3_t lightmaxs); // gathers info on which clusters and surfaces are lit by light, as well as calculating a bounding box void(*GetLightInfo)(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius, vec3_t outmins, vec3_t outmaxs, int *outleaflist, unsigned char *outleafpvs, int *outnumleafspointer, int *outsurfacelist, unsigned char *outsurfacepvs, int *outnumsurfacespointer, unsigned char *outshadowtrispvs, unsigned char *outlighttrispvs, unsigned char *visitingleafpvs, int numfrustumplanes, const mplane_t *frustumplanes, qboolean noocclusion); - // compile a shadow volume for the model based on light source - void(*CompileShadowVolume)(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativelightdirection, float lightradius, int numsurfaces, const int *surfacelist); - // draw a shadow volume for the model based on light source - void(*DrawShadowVolume)(struct entity_render_s *ent, const vec3_t relativelightorigin, const vec3_t relativelightdirection, float lightradius, int numsurfaces, const int *surfacelist, const vec3_t lightmins, const vec3_t lightmaxs); // draw the lighting on a model (through stencil) void(*DrawLight)(struct entity_render_s *ent, int numsurfaces, const int *surfacelist, const unsigned char *trispvs); // trace a box against this model @@ -1139,7 +1132,6 @@ extern unsigned char *mod_base; //extern cvar_t gl_subdivide_size; // texture fullbrights extern cvar_t r_fullbrights; -extern cvar_t r_enableshadowvolumes; void Mod_Init (void); void Mod_Reload (void); @@ -1156,25 +1148,24 @@ extern dp_model_t *loadmodel; extern char loadname[32]; // for hunk tags int Mod_BuildVertexRemapTableFromElements(int numelements, const int *elements, int numvertices, int *remapvertices); -void Mod_BuildTriangleNeighbors(int *neighbors, const int *elements, int numtriangles); void Mod_BuildNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const int *elements, float *normal3f, qboolean areaweighting); void Mod_BuildTextureVectorsFromNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const float *texcoord2f, const float *normal3f, const int *elements, float *svector3f, float *tvector3f, qboolean areaweighting); qboolean Mod_ValidateElements(int *element3i, unsigned short *element3s, int numtriangles, int firstvertex, int numvertices, const char *filename, int fileline); -void Mod_AllocSurfMesh(mempool_t *mempool, int numvertices, int numtriangles, qboolean lightmapoffsets, qboolean vertexcolors, qboolean neighbors); +void Mod_AllocSurfMesh(mempool_t *mempool, int numvertices, int numtriangles, qboolean lightmapoffsets, qboolean vertexcolors); void Mod_MakeSortedSurfaces(dp_model_t *mod); // called specially by brush model loaders before generating submodels // automatically called after model loader returns void Mod_BuildVBOs(void); -shadowmesh_t *Mod_ShadowMesh_Alloc(mempool_t *mempool, int maxverts, int maxtriangles, rtexture_t *map_diffuse, rtexture_t *map_specular, rtexture_t *map_normal, int light, int neighbors, int expandable); -shadowmesh_t *Mod_ShadowMesh_ReAlloc(mempool_t *mempool, shadowmesh_t *oldmesh, int light, int neighbors); +shadowmesh_t *Mod_ShadowMesh_Alloc(mempool_t *mempool, int maxverts, int maxtriangles, rtexture_t *map_diffuse, rtexture_t *map_specular, rtexture_t *map_normal, int light, int expandable); +shadowmesh_t *Mod_ShadowMesh_ReAlloc(mempool_t *mempool, shadowmesh_t *oldmesh, int light); int Mod_ShadowMesh_AddVertex(shadowmesh_t *mesh, float *vertex14f); void Mod_ShadowMesh_AddTriangle(mempool_t *mempool, shadowmesh_t *mesh, rtexture_t *map_diffuse, rtexture_t *map_specular, rtexture_t *map_normal, float *vertex14f); void Mod_ShadowMesh_AddMesh(mempool_t *mempool, shadowmesh_t *mesh, rtexture_t *map_diffuse, rtexture_t *map_specular, rtexture_t *map_normal, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *texcoord2f, int numtris, const int *element3i); -shadowmesh_t *Mod_ShadowMesh_Begin(mempool_t *mempool, int maxverts, int maxtriangles, rtexture_t *map_diffuse, rtexture_t *map_specular, rtexture_t *map_normal, int light, int neighbors, int expandable); -shadowmesh_t *Mod_ShadowMesh_Finish(mempool_t *mempool, shadowmesh_t *firstmesh, qboolean light, qboolean neighbors, qboolean createvbo); +shadowmesh_t *Mod_ShadowMesh_Begin(mempool_t *mempool, int maxverts, int maxtriangles, rtexture_t *map_diffuse, rtexture_t *map_specular, rtexture_t *map_normal, int light, int expandable); +shadowmesh_t *Mod_ShadowMesh_Finish(mempool_t *mempool, shadowmesh_t *firstmesh, qboolean light, qboolean createvbo); void Mod_ShadowMesh_CalcBBox(shadowmesh_t *firstmesh, vec3_t mins, vec3_t maxs, vec3_t center, float *radius); void Mod_ShadowMesh_Free(shadowmesh_t *mesh); @@ -1259,8 +1250,6 @@ void R_Q1BSP_DrawPrepass(struct entity_render_s *ent); void R_Q1BSP_GetLightInfo(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius, vec3_t outmins, vec3_t outmaxs, int *outleaflist, unsigned char *outleafpvs, int *outnumleafspointer, int *outsurfacelist, unsigned char *outsurfacepvs, int *outnumsurfacespointer, unsigned char *outshadowtrispvs, unsigned char *outlighttrispvs, unsigned char *visitingleafpvs, int numfrustumplanes, const mplane_t *frustumplanes, qboolean noocclusion); void R_Q1BSP_CompileShadowMap(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativelightdirection, float lightradius, int numsurfaces, const int *surfacelist); void R_Q1BSP_DrawShadowMap(int side, struct entity_render_s *ent, const vec3_t relativelightorigin, const vec3_t relativelightdirection, float lightradius, int modelnumsurfaces, const int *modelsurfacelist, const unsigned char *surfacesides, const vec3_t lightmins, const vec3_t lightmaxs); -void R_Q1BSP_CompileShadowVolume(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativelightdirection, float lightradius, int numsurfaces, const int *surfacelist); -void R_Q1BSP_DrawShadowVolume(struct entity_render_s *ent, const vec3_t relativelightorigin, const vec3_t relativelightdirection, float lightradius, int numsurfaces, const int *surfacelist, const vec3_t lightmins, const vec3_t lightmaxs); void R_Q1BSP_DrawLight(struct entity_render_s *ent, int numsurfaces, const int *surfacelist, const unsigned char *trispvs); // dynamic mesh building (every frame) for debugging and other uses diff --git a/model_sprite.c b/model_sprite.c index 12819e40..23604f72 100644 --- a/model_sprite.c +++ b/model_sprite.c @@ -277,8 +277,6 @@ void Mod_IDSP_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->DrawSky = NULL; loadmodel->Draw = R_Model_Sprite_Draw; loadmodel->DrawDepth = NULL; - loadmodel->CompileShadowVolume = NULL; - loadmodel->DrawShadowVolume = NULL; loadmodel->DrawLight = NULL; loadmodel->DrawAddWaterPlanes = NULL; @@ -394,8 +392,6 @@ void Mod_IDS2_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->DrawSky = NULL; loadmodel->Draw = R_Model_Sprite_Draw; loadmodel->DrawDepth = NULL; - loadmodel->CompileShadowVolume = NULL; - loadmodel->DrawShadowVolume = NULL; loadmodel->DrawLight = NULL; loadmodel->DrawAddWaterPlanes = NULL; diff --git a/r_shadow.c b/r_shadow.c index dd7114bf..303322c4 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -1,139 +1,3 @@ - -/* -Terminology: Stencil Shadow Volume (sometimes called Stencil Shadows) -An extrusion of the lit faces, beginning at the original geometry and ending -further from the light source than the original geometry (presumably at least -as far as the light's radius, if the light has a radius at all), capped at -both front and back to avoid any problems (extrusion from dark faces also -works but has a different set of problems) - -This is normally rendered using Carmack's Reverse technique, in which -backfaces behind zbuffer (zfail) increment the stencil, and frontfaces behind -zbuffer (zfail) decrement the stencil, the result is a stencil value of zero -where shadows did not intersect the visible geometry, suitable as a stencil -mask for rendering lighting everywhere but shadow. - -In our case to hopefully avoid the Creative Labs patent, we draw the backfaces -as decrement and the frontfaces as increment, and we redefine the DepthFunc to -GL_LESS (the patent uses GL_GEQUAL) which causes zfail when behind surfaces -and zpass when infront (the patent draws where zpass with a GL_GEQUAL test), -additionally we clear stencil to 128 to avoid the need for the unclamped -incr/decr extension (not related to patent). - -Patent warning: -This algorithm may be covered by Creative's patent (US Patent #6384822), -however that patent is quite specific about increment on backfaces and -decrement on frontfaces where zpass with GL_GEQUAL depth test, which is -opposite this implementation and partially opposite Carmack's Reverse paper -(which uses GL_LESS, but increments on backfaces and decrements on frontfaces). - - - -Terminology: Stencil Light Volume (sometimes called Light Volumes) -Similar to a Stencil Shadow Volume, but inverted; rather than containing the -areas in shadow it contains the areas in light, this can only be built -quickly for certain limited cases (such as portal visibility from a point), -but is quite useful for some effects (sunlight coming from sky polygons is -one possible example, translucent occluders is another example). - - - -Terminology: Optimized Stencil Shadow Volume -A Stencil Shadow Volume that has been processed sufficiently to ensure it has -no duplicate coverage of areas (no need to shadow an area twice), often this -greatly improves performance but is an operation too costly to use on moving -lights (however completely optimal Stencil Light Volumes can be constructed -in some ideal cases). - - - -Terminology: Per Pixel Lighting (sometimes abbreviated PPL) -Per pixel evaluation of lighting equations, at a bare minimum this involves -DOT3 shading of diffuse lighting (per pixel dotproduct of negated incidence -vector and surface normal, using a texture of the surface bumps, called a -NormalMap) if supported by hardware; in our case there is support for cards -which are incapable of DOT3, the quality is quite poor however. Additionally -it is desirable to have specular evaluation per pixel, per vertex -normalization of specular halfangle vectors causes noticable distortion but -is unavoidable on hardware without GL_ARB_fragment_program or -GL_ARB_fragment_shader. - - - -Terminology: Normalization CubeMap -A cubemap containing normalized dot3-encoded (vectors of length 1 or less -encoded as RGB colors) for any possible direction, this technique allows per -pixel calculation of incidence vector for per pixel lighting purposes, which -would not otherwise be possible per pixel without GL_ARB_fragment_program or -GL_ARB_fragment_shader. - - - -Terminology: 2D+1D Attenuation Texturing -A very crude approximation of light attenuation with distance which results -in cylindrical light shapes which fade vertically as a streak (some games -such as Doom3 allow this to be rotated to be less noticable in specific -cases), the technique is simply modulating lighting by two 2D textures (which -can be the same) on different axes of projection (XY and Z, typically), this -is the second best technique available without 3D Attenuation Texturing, -GL_ARB_fragment_program or GL_ARB_fragment_shader technology. - - - -Terminology: 2D+1D Inverse Attenuation Texturing -A clever method described in papers on the Abducted engine, this has a squared -distance texture (bright on the outside, black in the middle), which is used -twice using GL_ADD blending, the result of this is used in an inverse modulate -(GL_ONE_MINUS_DST_ALPHA, GL_ZERO) to implement the equation -lighting*=(1-((X*X+Y*Y)+(Z*Z))) which is spherical (unlike 2D+1D attenuation -texturing). - - - -Terminology: 3D Attenuation Texturing -A slightly crude approximation of light attenuation with distance, its flaws -are limited radius and resolution (performance tradeoffs). - - - -Terminology: 3D Attenuation-Normalization Texturing -A 3D Attenuation Texture merged with a Normalization CubeMap, by making the -vectors shorter the lighting becomes darker, a very effective optimization of -diffuse lighting if 3D Attenuation Textures are already used. - - - -Terminology: Light Cubemap Filtering -A technique for modeling non-uniform light distribution according to -direction, for example a lantern may use a cubemap to describe the light -emission pattern of the cage around the lantern (as well as soot buildup -discoloring the light in certain areas), often also used for softened grate -shadows and light shining through a stained glass window (done crudely by -texturing the lighting with a cubemap), another good example would be a disco -light. This technique is used heavily in many games (Doom3 does not support -this however). - - - -Terminology: Light Projection Filtering -A technique for modeling shadowing of light passing through translucent -surfaces, allowing stained glass windows and other effects to be done more -elegantly than possible with Light Cubemap Filtering by applying an occluder -texture to the lighting combined with a stencil light volume to limit the lit -area, this technique is used by Doom3 for spotlights and flashlights, among -other things, this can also be used more generally to render light passing -through multiple translucent occluders in a scene (using a light volume to -describe the area beyond the occluder, and thus mask off rendering of all -other areas). - - - -Terminology: Doom3 Lighting -A combination of Stencil Shadow Volume, Per Pixel Lighting, Normalization -CubeMap, 2D+1D Attenuation Texturing, and Light Projection Filtering, as -demonstrated by the game Doom3. -*/ - #include "quakedef.h" #include "r_shadow.h" #include "cl_collision.h" @@ -167,8 +31,6 @@ r_shadow_shadowmode_t; r_shadow_rendermode_t r_shadow_rendermode = R_SHADOW_RENDERMODE_NONE; r_shadow_rendermode_t r_shadow_lightingrendermode = R_SHADOW_RENDERMODE_NONE; -r_shadow_rendermode_t r_shadow_shadowingrendermode_zpass = R_SHADOW_RENDERMODE_NONE; -r_shadow_rendermode_t r_shadow_shadowingrendermode_zfail = R_SHADOW_RENDERMODE_NONE; int r_shadow_scenemaxlights; int r_shadow_scenenumlights; rtlight_t **r_shadow_scenelightlist; // includes both static lights and dlights, as filtered by appropriate flags @@ -307,7 +169,7 @@ cvar_t r_shadow_realtime_world_compileshadow = {0, "r_shadow_realtime_world_comp cvar_t r_shadow_realtime_world_compilesvbsp = {0, "r_shadow_realtime_world_compilesvbsp", "1", "enables svbsp optimization during compilation (slower than compileportalculling but more exact)"}; cvar_t r_shadow_realtime_world_compileportalculling = {0, "r_shadow_realtime_world_compileportalculling", "1", "enables portal-based culling optimization during compilation (overrides compilesvbsp)"}; cvar_t r_shadow_scissor = {0, "r_shadow_scissor", "1", "use scissor optimization of light rendering (restricts rendering to the portion of the screen affected by the light)"}; -cvar_t r_shadow_shadowmapping = {CVAR_SAVE, "r_shadow_shadowmapping", "1", "enables use of shadowmapping (depth texture sampling) instead of stencil shadow volumes"}; +cvar_t r_shadow_shadowmapping = {CVAR_SAVE, "r_shadow_shadowmapping", "1", "enables use of shadowmapping (shadow rendering by depth texture sampling)"}; cvar_t r_shadow_shadowmapping_filterquality = {CVAR_SAVE, "r_shadow_shadowmapping_filterquality", "-1", "shadowmap filter modes: -1 = auto-select, 0 = no filtering, 1 = bilinear, 2 = bilinear 2x2 blur (fast), 3 = 3x3 blur (moderate), 4 = 4x4 blur (slow)"}; cvar_t r_shadow_shadowmapping_useshadowsampler = {CVAR_SAVE, "r_shadow_shadowmapping_useshadowsampler", "1", "whether to use sampler2DShadow if available"}; cvar_t r_shadow_shadowmapping_depthbits = {CVAR_SAVE, "r_shadow_shadowmapping_depthbits", "24", "requested minimum shadowmap texture depth bits"}; @@ -324,8 +186,6 @@ cvar_t r_shadow_shadowmapping_bias = {CVAR_SAVE, "r_shadow_shadowmapping_bias", cvar_t r_shadow_shadowmapping_polygonfactor = {CVAR_SAVE, "r_shadow_shadowmapping_polygonfactor", "2", "slope-dependent shadowmapping bias"}; cvar_t r_shadow_shadowmapping_polygonoffset = {CVAR_SAVE, "r_shadow_shadowmapping_polygonoffset", "0", "constant shadowmapping bias"}; cvar_t r_shadow_sortsurfaces = {0, "r_shadow_sortsurfaces", "1", "improve performance by sorting illuminated surfaces by texture"}; -cvar_t r_shadow_polygonfactor = {0, "r_shadow_polygonfactor", "0", "how much to enlarge shadow volume polygons when rendering (should be 0!)"}; -cvar_t r_shadow_polygonoffset = {0, "r_shadow_polygonoffset", "1", "how much to push shadow volumes into the distance when rendering, to reduce chances of zfighting artifacts (should not be less than 0)"}; cvar_t r_shadow_texture3d = {0, "r_shadow_texture3d", "1", "use 3D voxel textures for spherical attenuation rather than cylindrical (does not affect OpenGL 2.0 render path)"}; cvar_t r_shadow_culllights_pvs = {CVAR_SAVE, "r_shadow_culllights_pvs", "1", "check if light overlaps any visible bsp leafs when determining if the light is visible"}; cvar_t r_shadow_culllights_trace = {CVAR_SAVE, "r_shadow_culllights_trace", "1", "use raytraces from the eye to random places within light bounds to determine if the light is visible"}; @@ -376,8 +236,6 @@ cvar_t r_coronas = {CVAR_SAVE, "r_coronas", "0", "brightness of corona flare eff cvar_t r_coronas_occlusionsizescale = {CVAR_SAVE, "r_coronas_occlusionsizescale", "0.1", "size of light source for corona occlusion checksum the proportion of hidden pixels controls corona intensity"}; cvar_t r_coronas_occlusionquery = {CVAR_SAVE, "r_coronas_occlusionquery", "0", "use GL_ARB_occlusion_query extension if supported (fades coronas according to visibility) - bad performance (synchronous rendering) - worse on multi-gpu!"}; cvar_t gl_flashblend = {CVAR_SAVE, "gl_flashblend", "0", "render bright coronas for dynamic lights instead of actual lighting, fast but ugly"}; -cvar_t gl_ext_separatestencil = {0, "gl_ext_separatestencil", "1", "make use of OpenGL 2.0 glStencilOpSeparate or GL_ATI_separate_stencil extension"}; -cvar_t gl_ext_stenciltwoside = {0, "gl_ext_stenciltwoside", "1", "make use of GL_EXT_stenciltwoside extension (NVIDIA only)"}; cvar_t r_editlights = {0, "r_editlights", "0", "enables .rtlights file editing mode"}; cvar_t r_editlights_cursordistance = {0, "r_editlights_cursordistance", "1024", "maximum distance of cursor from eye"}; cvar_t r_editlights_cursorpushback = {0, "r_editlights_cursorpushback", "0", "how far to pull the cursor back toward the eye"}; @@ -783,8 +641,6 @@ void R_Shadow_Init(void) Cvar_RegisterVariable(&r_shadow_shadowmapping_polygonfactor); Cvar_RegisterVariable(&r_shadow_shadowmapping_polygonoffset); Cvar_RegisterVariable(&r_shadow_sortsurfaces); - Cvar_RegisterVariable(&r_shadow_polygonfactor); - Cvar_RegisterVariable(&r_shadow_polygonoffset); Cvar_RegisterVariable(&r_shadow_texture3d); Cvar_RegisterVariable(&r_shadow_culllights_pvs); Cvar_RegisterVariable(&r_shadow_culllights_trace); @@ -835,8 +691,6 @@ void R_Shadow_Init(void) Cvar_RegisterVariable(&r_coronas_occlusionsizescale); Cvar_RegisterVariable(&r_coronas_occlusionquery); Cvar_RegisterVariable(&gl_flashblend); - Cvar_RegisterVariable(&gl_ext_separatestencil); - Cvar_RegisterVariable(&gl_ext_stenciltwoside); R_Shadow_EditLights_Init(); Mem_ExpandableArray_NewArray(&r_shadow_worldlightsarray, r_main_mempool, sizeof(dlight_t), 128); r_shadow_scenemaxlights = 0; @@ -1001,476 +855,6 @@ void R_Shadow_PrepareShadowSides(int numtris) numshadowsides = 0; } -static int R_Shadow_ConstructShadowVolume_ZFail(int innumvertices, int innumtris, const int *inelement3i, const int *inneighbor3i, const float *invertex3f, int *outnumvertices, int *outelement3i, float *outvertex3f, const float *projectorigin, const float *projectdirection, float projectdistance, int numshadowmarktris, const int *shadowmarktris) -{ - int i, j; - int outtriangles = 0, outvertices = 0; - const int *element; - const float *vertex; - float ratio, direction[3], projectvector[3]; - - if (projectdirection) - VectorScale(projectdirection, projectdistance, projectvector); - else - VectorClear(projectvector); - - // create the vertices - if (projectdirection) - { - for (i = 0;i < numshadowmarktris;i++) - { - element = inelement3i + shadowmarktris[i] * 3; - for (j = 0;j < 3;j++) - { - if (vertexupdate[element[j]] != vertexupdatenum) - { - vertexupdate[element[j]] = vertexupdatenum; - vertexremap[element[j]] = outvertices; - vertex = invertex3f + element[j] * 3; - // project one copy of the vertex according to projectvector - VectorCopy(vertex, outvertex3f); - VectorAdd(vertex, projectvector, (outvertex3f + 3)); - outvertex3f += 6; - outvertices += 2; - } - } - } - } - else - { - for (i = 0;i < numshadowmarktris;i++) - { - element = inelement3i + shadowmarktris[i] * 3; - for (j = 0;j < 3;j++) - { - if (vertexupdate[element[j]] != vertexupdatenum) - { - vertexupdate[element[j]] = vertexupdatenum; - vertexremap[element[j]] = outvertices; - vertex = invertex3f + element[j] * 3; - // project one copy of the vertex to the sphere radius of the light - // (FIXME: would projecting it to the light box be better?) - VectorSubtract(vertex, projectorigin, direction); - ratio = projectdistance / VectorLength(direction); - VectorCopy(vertex, outvertex3f); - VectorMA(projectorigin, ratio, direction, (outvertex3f + 3)); - outvertex3f += 6; - outvertices += 2; - } - } - } - } - - if (r_shadow_frontsidecasting.integer) - { - for (i = 0;i < numshadowmarktris;i++) - { - int remappedelement[3]; - int markindex; - const int *neighbortriangle; - - markindex = shadowmarktris[i] * 3; - element = inelement3i + markindex; - neighbortriangle = inneighbor3i + markindex; - // output the front and back triangles - outelement3i[0] = vertexremap[element[0]]; - outelement3i[1] = vertexremap[element[1]]; - outelement3i[2] = vertexremap[element[2]]; - outelement3i[3] = vertexremap[element[2]] + 1; - outelement3i[4] = vertexremap[element[1]] + 1; - outelement3i[5] = vertexremap[element[0]] + 1; - - outelement3i += 6; - outtriangles += 2; - // output the sides (facing outward from this triangle) - if (shadowmark[neighbortriangle[0]] != shadowmarkcount) - { - remappedelement[0] = vertexremap[element[0]]; - remappedelement[1] = vertexremap[element[1]]; - outelement3i[0] = remappedelement[1]; - outelement3i[1] = remappedelement[0]; - outelement3i[2] = remappedelement[0] + 1; - outelement3i[3] = remappedelement[1]; - outelement3i[4] = remappedelement[0] + 1; - outelement3i[5] = remappedelement[1] + 1; - - outelement3i += 6; - outtriangles += 2; - } - if (shadowmark[neighbortriangle[1]] != shadowmarkcount) - { - remappedelement[1] = vertexremap[element[1]]; - remappedelement[2] = vertexremap[element[2]]; - outelement3i[0] = remappedelement[2]; - outelement3i[1] = remappedelement[1]; - outelement3i[2] = remappedelement[1] + 1; - outelement3i[3] = remappedelement[2]; - outelement3i[4] = remappedelement[1] + 1; - outelement3i[5] = remappedelement[2] + 1; - - outelement3i += 6; - outtriangles += 2; - } - if (shadowmark[neighbortriangle[2]] != shadowmarkcount) - { - remappedelement[0] = vertexremap[element[0]]; - remappedelement[2] = vertexremap[element[2]]; - outelement3i[0] = remappedelement[0]; - outelement3i[1] = remappedelement[2]; - outelement3i[2] = remappedelement[2] + 1; - outelement3i[3] = remappedelement[0]; - outelement3i[4] = remappedelement[2] + 1; - outelement3i[5] = remappedelement[0] + 1; - - outelement3i += 6; - outtriangles += 2; - } - } - } - else - { - for (i = 0;i < numshadowmarktris;i++) - { - int remappedelement[3]; - int markindex; - const int *neighbortriangle; - - markindex = shadowmarktris[i] * 3; - element = inelement3i + markindex; - neighbortriangle = inneighbor3i + markindex; - // output the front and back triangles - outelement3i[0] = vertexremap[element[2]]; - outelement3i[1] = vertexremap[element[1]]; - outelement3i[2] = vertexremap[element[0]]; - outelement3i[3] = vertexremap[element[0]] + 1; - outelement3i[4] = vertexremap[element[1]] + 1; - outelement3i[5] = vertexremap[element[2]] + 1; - - outelement3i += 6; - outtriangles += 2; - // output the sides (facing outward from this triangle) - if (shadowmark[neighbortriangle[0]] != shadowmarkcount) - { - remappedelement[0] = vertexremap[element[0]]; - remappedelement[1] = vertexremap[element[1]]; - outelement3i[0] = remappedelement[0]; - outelement3i[1] = remappedelement[1]; - outelement3i[2] = remappedelement[1] + 1; - outelement3i[3] = remappedelement[0]; - outelement3i[4] = remappedelement[1] + 1; - outelement3i[5] = remappedelement[0] + 1; - - outelement3i += 6; - outtriangles += 2; - } - if (shadowmark[neighbortriangle[1]] != shadowmarkcount) - { - remappedelement[1] = vertexremap[element[1]]; - remappedelement[2] = vertexremap[element[2]]; - outelement3i[0] = remappedelement[1]; - outelement3i[1] = remappedelement[2]; - outelement3i[2] = remappedelement[2] + 1; - outelement3i[3] = remappedelement[1]; - outelement3i[4] = remappedelement[2] + 1; - outelement3i[5] = remappedelement[1] + 1; - - outelement3i += 6; - outtriangles += 2; - } - if (shadowmark[neighbortriangle[2]] != shadowmarkcount) - { - remappedelement[0] = vertexremap[element[0]]; - remappedelement[2] = vertexremap[element[2]]; - outelement3i[0] = remappedelement[2]; - outelement3i[1] = remappedelement[0]; - outelement3i[2] = remappedelement[0] + 1; - outelement3i[3] = remappedelement[2]; - outelement3i[4] = remappedelement[0] + 1; - outelement3i[5] = remappedelement[2] + 1; - - outelement3i += 6; - outtriangles += 2; - } - } - } - if (outnumvertices) - *outnumvertices = outvertices; - return outtriangles; -} - -static int R_Shadow_ConstructShadowVolume_ZPass(int innumvertices, int innumtris, const int *inelement3i, const int *inneighbor3i, const float *invertex3f, int *outnumvertices, int *outelement3i, float *outvertex3f, const float *projectorigin, const float *projectdirection, float projectdistance, int numshadowmarktris, const int *shadowmarktris) -{ - int i, j, k; - int outtriangles = 0, outvertices = 0; - const int *element; - const float *vertex; - float ratio, direction[3], projectvector[3]; - qboolean side[4]; - - if (projectdirection) - VectorScale(projectdirection, projectdistance, projectvector); - else - VectorClear(projectvector); - - for (i = 0;i < numshadowmarktris;i++) - { - int remappedelement[3]; - int markindex; - const int *neighbortriangle; - - markindex = shadowmarktris[i] * 3; - neighbortriangle = inneighbor3i + markindex; - side[0] = shadowmark[neighbortriangle[0]] == shadowmarkcount; - side[1] = shadowmark[neighbortriangle[1]] == shadowmarkcount; - side[2] = shadowmark[neighbortriangle[2]] == shadowmarkcount; - if (side[0] + side[1] + side[2] == 0) - continue; - - side[3] = side[0]; - element = inelement3i + markindex; - - // create the vertices - for (j = 0;j < 3;j++) - { - if (side[j] + side[j+1] == 0) - continue; - k = element[j]; - if (vertexupdate[k] != vertexupdatenum) - { - vertexupdate[k] = vertexupdatenum; - vertexremap[k] = outvertices; - vertex = invertex3f + k * 3; - VectorCopy(vertex, outvertex3f); - if (projectdirection) - { - // project one copy of the vertex according to projectvector - VectorAdd(vertex, projectvector, (outvertex3f + 3)); - } - else - { - // project one copy of the vertex to the sphere radius of the light - // (FIXME: would projecting it to the light box be better?) - VectorSubtract(vertex, projectorigin, direction); - ratio = projectdistance / VectorLength(direction); - VectorMA(projectorigin, ratio, direction, (outvertex3f + 3)); - } - outvertex3f += 6; - outvertices += 2; - } - } - - // output the sides (facing outward from this triangle) - if (!side[0]) - { - remappedelement[0] = vertexremap[element[0]]; - remappedelement[1] = vertexremap[element[1]]; - outelement3i[0] = remappedelement[1]; - outelement3i[1] = remappedelement[0]; - outelement3i[2] = remappedelement[0] + 1; - outelement3i[3] = remappedelement[1]; - outelement3i[4] = remappedelement[0] + 1; - outelement3i[5] = remappedelement[1] + 1; - - outelement3i += 6; - outtriangles += 2; - } - if (!side[1]) - { - remappedelement[1] = vertexremap[element[1]]; - remappedelement[2] = vertexremap[element[2]]; - outelement3i[0] = remappedelement[2]; - outelement3i[1] = remappedelement[1]; - outelement3i[2] = remappedelement[1] + 1; - outelement3i[3] = remappedelement[2]; - outelement3i[4] = remappedelement[1] + 1; - outelement3i[5] = remappedelement[2] + 1; - - outelement3i += 6; - outtriangles += 2; - } - if (!side[2]) - { - remappedelement[0] = vertexremap[element[0]]; - remappedelement[2] = vertexremap[element[2]]; - outelement3i[0] = remappedelement[0]; - outelement3i[1] = remappedelement[2]; - outelement3i[2] = remappedelement[2] + 1; - outelement3i[3] = remappedelement[0]; - outelement3i[4] = remappedelement[2] + 1; - outelement3i[5] = remappedelement[0] + 1; - - outelement3i += 6; - outtriangles += 2; - } - } - if (outnumvertices) - *outnumvertices = outvertices; - return outtriangles; -} - -void R_Shadow_MarkVolumeFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const vec3_t projectorigin, const vec3_t projectdirection, const vec3_t lightmins, const vec3_t lightmaxs, const vec3_t surfacemins, const vec3_t surfacemaxs) -{ - int t, tend; - const int *e; - const float *v[3]; - float normal[3]; - if (!BoxesOverlap(lightmins, lightmaxs, surfacemins, surfacemaxs)) - return; - tend = firsttriangle + numtris; - if (BoxInsideBox(surfacemins, surfacemaxs, lightmins, lightmaxs)) - { - // surface box entirely inside light box, no box cull - if (projectdirection) - { - for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3) - { - TriangleNormal(invertex3f + e[0] * 3, invertex3f + e[1] * 3, invertex3f + e[2] * 3, normal); - if (r_shadow_frontsidecasting.integer == (DotProduct(normal, projectdirection) < 0)) - shadowmarklist[numshadowmark++] = t; - } - } - else - { - for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3) - if (r_shadow_frontsidecasting.integer == PointInfrontOfTriangle(projectorigin, invertex3f + e[0] * 3, invertex3f + e[1] * 3, invertex3f + e[2] * 3)) - shadowmarklist[numshadowmark++] = t; - } - } - else - { - // surface box not entirely inside light box, cull each triangle - if (projectdirection) - { - for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3) - { - v[0] = invertex3f + e[0] * 3; - v[1] = invertex3f + e[1] * 3; - v[2] = invertex3f + e[2] * 3; - TriangleNormal(v[0], v[1], v[2], normal); - if (r_shadow_frontsidecasting.integer == (DotProduct(normal, projectdirection) < 0) - && TriangleBBoxOverlapsBox(v[0], v[1], v[2], lightmins, lightmaxs)) - shadowmarklist[numshadowmark++] = t; - } - } - else - { - for (t = firsttriangle, e = elements + t * 3;t < tend;t++, e += 3) - { - v[0] = invertex3f + e[0] * 3; - v[1] = invertex3f + e[1] * 3; - v[2] = invertex3f + e[2] * 3; - if (r_shadow_frontsidecasting.integer == PointInfrontOfTriangle(projectorigin, v[0], v[1], v[2]) - && TriangleBBoxOverlapsBox(v[0], v[1], v[2], lightmins, lightmaxs)) - shadowmarklist[numshadowmark++] = t; - } - } - } -} - -static qboolean R_Shadow_UseZPass(vec3_t mins, vec3_t maxs) -{ -#if 1 - return false; -#else - if (r_shadow_compilingrtlight || !r_shadow_frontsidecasting.integer || !r_shadow_usezpassifpossible.integer) - return false; - // check if the shadow volume intersects the near plane - // - // a ray between the eye and light origin may intersect the caster, - // indicating that the shadow may touch the eye location, however we must - // test the near plane (a polygon), not merely the eye location, so it is - // easiest to enlarge the caster bounding shape slightly for this. - // TODO - return true; -#endif -} - -void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f, const int *elements, const int *neighbors, const vec3_t projectorigin, const vec3_t projectdirection, float projectdistance, int nummarktris, const int *marktris, vec3_t trismins, vec3_t trismaxs) -{ - int i, tris, outverts; - if (projectdistance < 0.1) - { - Con_Printf("R_Shadow_Volume: projectdistance %f\n", projectdistance); - return; - } - if (!numverts || !nummarktris) - return; - // make sure shadowelements is big enough for this volume - if (maxshadowtriangles < nummarktris*8 || maxshadowvertices < numverts*2) - R_Shadow_ResizeShadowArrays(numverts, nummarktris, 2, 8); - - if (maxvertexupdate < numverts) - { - maxvertexupdate = numverts; - if (vertexupdate) - Mem_Free(vertexupdate); - if (vertexremap) - Mem_Free(vertexremap); - vertexupdate = (int *)Mem_Alloc(r_main_mempool, maxvertexupdate * sizeof(int)); - vertexremap = (int *)Mem_Alloc(r_main_mempool, maxvertexupdate * sizeof(int)); - vertexupdatenum = 0; - } - vertexupdatenum++; - if (vertexupdatenum == 0) - { - vertexupdatenum = 1; - memset(vertexupdate, 0, maxvertexupdate * sizeof(int)); - memset(vertexremap, 0, maxvertexupdate * sizeof(int)); - } - - for (i = 0;i < nummarktris;i++) - shadowmark[marktris[i]] = shadowmarkcount; - - if (r_shadow_compilingrtlight) - { - // if we're compiling an rtlight, capture the mesh - //tris = R_Shadow_ConstructShadowVolume_ZPass(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris); - //Mod_ShadowMesh_AddMesh(r_main_mempool, r_shadow_compilingrtlight->static_meshchain_shadow_zpass, NULL, NULL, NULL, shadowvertex3f, NULL, NULL, NULL, NULL, tris, shadowelements); - tris = R_Shadow_ConstructShadowVolume_ZFail(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris); - Mod_ShadowMesh_AddMesh(r_main_mempool, r_shadow_compilingrtlight->static_meshchain_shadow_zfail, NULL, NULL, NULL, shadowvertex3f, NULL, NULL, NULL, NULL, tris, shadowelements); - } - else if (r_shadow_rendermode == R_SHADOW_RENDERMODE_VISIBLEVOLUMES) - { - tris = R_Shadow_ConstructShadowVolume_ZFail(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris); - R_Mesh_PrepareVertices_Vertex3f(outverts, shadowvertex3f, NULL, 0); - R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, NULL, NULL, 0); - } - else - { - // decide which type of shadow to generate and set stencil mode - R_Shadow_RenderMode_StencilShadowVolumes(R_Shadow_UseZPass(trismins, trismaxs)); - // generate the sides or a solid volume, depending on type - if (r_shadow_rendermode >= R_SHADOW_RENDERMODE_ZPASS_STENCIL && r_shadow_rendermode <= R_SHADOW_RENDERMODE_ZPASS_STENCILTWOSIDE) - tris = R_Shadow_ConstructShadowVolume_ZPass(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris); - else - tris = R_Shadow_ConstructShadowVolume_ZFail(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris); - r_refdef.stats[r_stat_lights_dynamicshadowtriangles] += tris; - r_refdef.stats[r_stat_lights_shadowtriangles] += tris; - if (r_shadow_rendermode == R_SHADOW_RENDERMODE_ZPASS_STENCIL) - { - // increment stencil if frontface is infront of depthbuffer - GL_CullFace(r_refdef.view.cullface_front); - R_SetStencil(true, 255, GL_KEEP, GL_KEEP, GL_DECR, GL_ALWAYS, 128, 255); - R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, NULL, NULL, 0); - // decrement stencil if backface is infront of depthbuffer - GL_CullFace(r_refdef.view.cullface_back); - R_SetStencil(true, 255, GL_KEEP, GL_KEEP, GL_INCR, GL_ALWAYS, 128, 255); - } - else if (r_shadow_rendermode == R_SHADOW_RENDERMODE_ZFAIL_STENCIL) - { - // decrement stencil if backface is behind depthbuffer - GL_CullFace(r_refdef.view.cullface_front); - R_SetStencil(true, 255, GL_KEEP, GL_DECR, GL_KEEP, GL_ALWAYS, 128, 255); - R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, NULL, NULL, 0); - // increment stencil if frontface is behind depthbuffer - GL_CullFace(r_refdef.view.cullface_back); - R_SetStencil(true, 255, GL_KEEP, GL_INCR, GL_KEEP, GL_ALWAYS, 128, 255); - } - R_Mesh_PrepareVertices_Vertex3f(outverts, shadowvertex3f, NULL, 0); - R_Mesh_Draw(0, outverts, 0, tris, shadowelements, NULL, 0, NULL, NULL, 0); - } -} - int R_Shadow_CalcTriangleSideMask(const vec3_t p1, const vec3_t p2, const vec3_t p3, float bias) { // p1, p2, p3 are in the cubemap's local coordinate system @@ -1997,10 +1381,6 @@ void R_Shadow_ValidateCvars(void) { if (r_shadow_texture3d.integer && !vid.support.ext_texture_3d) Cvar_SetValueQuick(&r_shadow_texture3d, 0); - if (gl_ext_separatestencil.integer && !vid.support.ati_separate_stencil) - Cvar_SetValueQuick(&gl_ext_separatestencil, 0); - if (gl_ext_stenciltwoside.integer && !vid.support.ext_stencil_two_side) - Cvar_SetValueQuick(&gl_ext_stenciltwoside, 0); } void R_Shadow_RenderMode_Begin(void) @@ -2028,23 +1408,6 @@ void R_Shadow_RenderMode_Begin(void) GL_Scissor(r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height); r_shadow_rendermode = R_SHADOW_RENDERMODE_NONE; - - if (gl_ext_separatestencil.integer && vid.support.ati_separate_stencil) - { - r_shadow_shadowingrendermode_zpass = R_SHADOW_RENDERMODE_ZPASS_SEPARATESTENCIL; - r_shadow_shadowingrendermode_zfail = R_SHADOW_RENDERMODE_ZFAIL_SEPARATESTENCIL; - } - else if (gl_ext_stenciltwoside.integer && vid.support.ext_stencil_two_side) - { - r_shadow_shadowingrendermode_zpass = R_SHADOW_RENDERMODE_ZPASS_STENCILTWOSIDE; - r_shadow_shadowingrendermode_zfail = R_SHADOW_RENDERMODE_ZFAIL_STENCILTWOSIDE; - } - else - { - r_shadow_shadowingrendermode_zpass = R_SHADOW_RENDERMODE_ZPASS_STENCIL; - r_shadow_shadowingrendermode_zfail = R_SHADOW_RENDERMODE_ZFAIL_STENCIL; - } - r_shadow_lightingrendermode = R_SHADOW_RENDERMODE_LIGHT_GLSL; CHECKGLERROR @@ -2082,42 +1445,14 @@ void R_Shadow_RenderMode_Reset(void) GL_BlendFunc(GL_ONE, GL_ZERO); R_SetupShader_Generic_NoTexture(false, false); r_shadow_usingshadowmap2d = false; - R_SetStencil(false, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_ALWAYS, 128, 255); } void R_Shadow_ClearStencil(void) { - GL_Clear(GL_STENCIL_BUFFER_BIT, NULL, 1.0f, 128); + GL_Clear(GL_STENCIL_BUFFER_BIT, NULL, 1.0f, 0); r_refdef.stats[r_stat_lights_clears]++; } -void R_Shadow_RenderMode_StencilShadowVolumes(qboolean zpass) -{ - r_shadow_rendermode_t mode = zpass ? r_shadow_shadowingrendermode_zpass : r_shadow_shadowingrendermode_zfail; - if (r_shadow_rendermode == mode) - return; - R_Shadow_RenderMode_Reset(); - GL_DepthFunc(GL_LESS); - GL_ColorMask(0, 0, 0, 0); - GL_PolygonOffset(r_refdef.shadowpolygonfactor, r_refdef.shadowpolygonoffset);CHECKGLERROR - GL_CullFace(GL_NONE); - R_SetupShader_DepthOrShadow(false, false, false); // FIXME test if we have a skeletal model? - r_shadow_rendermode = mode; - switch(mode) - { - default: - break; - case R_SHADOW_RENDERMODE_ZPASS_STENCILTWOSIDE: - case R_SHADOW_RENDERMODE_ZPASS_SEPARATESTENCIL: - R_SetStencilSeparate(true, 255, GL_KEEP, GL_KEEP, GL_INCR, GL_KEEP, GL_KEEP, GL_DECR, GL_ALWAYS, GL_ALWAYS, 128, 255); - break; - case R_SHADOW_RENDERMODE_ZFAIL_STENCILTWOSIDE: - case R_SHADOW_RENDERMODE_ZFAIL_SEPARATESTENCIL: - R_SetStencilSeparate(true, 255, GL_KEEP, GL_INCR, GL_KEEP, GL_KEEP, GL_DECR, GL_KEEP, GL_ALWAYS, GL_ALWAYS, 128, 255); - break; - } -} - static void R_Shadow_MakeVSDCT(void) { // maps to a 2x3 texture rectangle with normalized coordinates @@ -2282,7 +1617,7 @@ static void R_Shadow_RenderMode_ShadowMap(int side, int size, int x, int y) r_shadow_shadowmapside = side; } -void R_Shadow_RenderMode_Lighting(qboolean stenciltest, qboolean transparent, qboolean shadowmapping, qboolean noselfshadowpass) +void R_Shadow_RenderMode_Lighting(qboolean transparent, qboolean shadowmapping, qboolean noselfshadowpass) { R_Mesh_ResetTextureState(); if (transparent) @@ -2303,12 +1638,6 @@ void R_Shadow_RenderMode_Lighting(qboolean stenciltest, qboolean transparent, qb GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 0); r_shadow_usingshadowmap2d = shadowmapping; r_shadow_rendermode = r_shadow_lightingrendermode; - // only draw light where this geometry was already rendered AND the - // stencil is 128 (values other than this mean shadow) - if (stenciltest) - R_SetStencil(true, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_EQUAL, 128, 255); - else - R_SetStencil(false, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_ALWAYS, 128, 255); } static const unsigned short bboxelements[36] = @@ -2343,7 +1672,6 @@ void R_Shadow_RenderMode_DrawDeferredLight(qboolean shadowmapping) r_shadow_rendermode = r_shadow_lightingrendermode; R_EntityMatrix(&identitymatrix); GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); - R_SetStencil(false, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_EQUAL, 128, 255); if (rsurface.rtlight->specularscale > 0 && r_shadow_gloss.integer > 0) R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusespecularfbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL); else @@ -3561,19 +2889,7 @@ void R_Shadow_UpdateBounceGridTexture(void) } } -void R_Shadow_RenderMode_VisibleShadowVolumes(void) -{ - R_Shadow_RenderMode_Reset(); - GL_BlendFunc(GL_ONE, GL_ONE); - GL_DepthRange(0, 1); - GL_DepthTest(r_showshadowvolumes.integer < 2); - GL_Color(0.0, 0.0125 * r_refdef.view.colorscale, 0.1 * r_refdef.view.colorscale, 1); - GL_PolygonOffset(r_refdef.shadowpolygonfactor, r_refdef.shadowpolygonoffset);CHECKGLERROR - GL_CullFace(GL_NONE); - r_shadow_rendermode = R_SHADOW_RENDERMODE_VISIBLEVOLUMES; -} - -void R_Shadow_RenderMode_VisibleLighting(qboolean stenciltest, qboolean transparent) +void R_Shadow_RenderMode_VisibleLighting(qboolean transparent) { R_Shadow_RenderMode_Reset(); GL_BlendFunc(GL_ONE, GL_ONE); @@ -3582,7 +2898,6 @@ void R_Shadow_RenderMode_VisibleLighting(qboolean stenciltest, qboolean transpar GL_Color(0.1 * r_refdef.view.colorscale, 0.0125 * r_refdef.view.colorscale, 0, 1); if (!transparent) GL_DepthFunc(GL_EQUAL); - R_SetStencil(stenciltest, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_EQUAL, 128, 255); r_shadow_rendermode = R_SHADOW_RENDERMODE_VISIBLELIGHTING; } @@ -3741,11 +3056,10 @@ void R_RTLight_Compile(rtlight_t *rtlight) { int i; int numsurfaces, numleafs, numleafpvsbytes, numshadowtrispvsbytes, numlighttrispvsbytes; - int lighttris, shadowtris, shadowzpasstris, shadowzfailtris; + int lighttris, shadowtris; entity_render_t *ent = r_refdef.scene.worldentity; dp_model_t *model = r_refdef.scene.worldmodel; unsigned char *data; - shadowmesh_t *mesh; // compile the light rtlight->compiled = true; @@ -3767,7 +3081,7 @@ void R_RTLight_Compile(rtlight_t *rtlight) if (model && model->GetLightInfo) { - // this variable must be set for the CompileShadowVolume/CompileShadowMap code + // this variable must be set for the CompileShadowMap code r_shadow_compilingrtlight = rtlight; R_FrameData_SetMark(); model->GetLightInfo(ent, rtlight->shadoworigin, rtlight->radius, rtlight->cullmins, rtlight->cullmaxs, r_shadow_buffer_leaflist, r_shadow_buffer_leafpvs, &numleafs, r_shadow_buffer_surfacelist, r_shadow_buffer_surfacepvs, &numsurfaces, r_shadow_buffer_shadowtrispvs, r_shadow_buffer_lighttrispvs, r_shadow_buffer_visitingleafpvs, 0, NULL, rtlight->shadow == 0); @@ -3797,17 +3111,8 @@ void R_RTLight_Compile(rtlight_t *rtlight) if (rtlight->static_numlighttrispvsbytes) memcpy(rtlight->static_lighttrispvs, r_shadow_buffer_lighttrispvs, rtlight->static_numlighttrispvsbytes); R_FrameData_SetMark(); - switch (rtlight->shadowmode) - { - case R_SHADOW_SHADOWMODE_SHADOWMAP2D: - if (model->CompileShadowMap && rtlight->shadow) - model->CompileShadowMap(ent, rtlight->shadoworigin, NULL, rtlight->radius, numsurfaces, r_shadow_buffer_surfacelist); - break; - default: - if (model->CompileShadowVolume && rtlight->shadow) - model->CompileShadowVolume(ent, rtlight->shadoworigin, NULL, rtlight->radius, numsurfaces, r_shadow_buffer_surfacelist); - break; - } + if (model->CompileShadowMap && rtlight->shadow) + model->CompileShadowMap(ent, rtlight->shadoworigin, NULL, rtlight->radius, numsurfaces, r_shadow_buffer_surfacelist); R_FrameData_ReturnToMark(); // now we're done compiling the rtlight r_shadow_compilingrtlight = NULL; @@ -3818,16 +3123,6 @@ void R_RTLight_Compile(rtlight_t *rtlight) //rtlight->cullradius = RadiusFromBoundsAndOrigin(rtlight->cullmins, rtlight->cullmaxs, rtlight->shadoworigin); //rtlight->cullradius = min(rtlight->cullradius, rtlight->radius); - shadowzpasstris = 0; - if (rtlight->static_meshchain_shadow_zpass) - for (mesh = rtlight->static_meshchain_shadow_zpass;mesh;mesh = mesh->next) - shadowzpasstris += mesh->numtriangles; - - shadowzfailtris = 0; - if (rtlight->static_meshchain_shadow_zfail) - for (mesh = rtlight->static_meshchain_shadow_zfail;mesh;mesh = mesh->next) - shadowzfailtris += mesh->numtriangles; - lighttris = 0; if (rtlight->static_numlighttrispvsbytes) for (i = 0;i < rtlight->static_numlighttrispvsbytes*8;i++) @@ -3841,19 +3136,13 @@ void R_RTLight_Compile(rtlight_t *rtlight) shadowtris++; if (developer_extra.integer) - Con_DPrintf("static light built: %f %f %f : %f %f %f box, %i light triangles, %i shadow triangles, %i zpass/%i zfail compiled shadow volume triangles\n", rtlight->cullmins[0], rtlight->cullmins[1], rtlight->cullmins[2], rtlight->cullmaxs[0], rtlight->cullmaxs[1], rtlight->cullmaxs[2], lighttris, shadowtris, shadowzpasstris, shadowzfailtris); + Con_DPrintf("static light built: %f %f %f : %f %f %f box, %i light triangles, %i shadow triangles\n", rtlight->cullmins[0], rtlight->cullmins[1], rtlight->cullmins[2], rtlight->cullmaxs[0], rtlight->cullmaxs[1], rtlight->cullmaxs[2], lighttris, shadowtris); } void R_RTLight_Uncompile(rtlight_t *rtlight) { if (rtlight->compiled) { - if (rtlight->static_meshchain_shadow_zpass) - Mod_ShadowMesh_Free(rtlight->static_meshchain_shadow_zpass); - rtlight->static_meshchain_shadow_zpass = NULL; - if (rtlight->static_meshchain_shadow_zfail) - Mod_ShadowMesh_Free(rtlight->static_meshchain_shadow_zfail); - rtlight->static_meshchain_shadow_zfail = NULL; if (rtlight->static_meshchain_shadow_shadowmap) Mod_ShadowMesh_Free(rtlight->static_meshchain_shadow_shadowmap); rtlight->static_meshchain_shadow_shadowmap = NULL; @@ -4084,78 +3373,6 @@ static void R_Shadow_DrawWorldShadow_ShadowMap(int numsurfaces, int *surfacelist rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity } -static void R_Shadow_DrawWorldShadow_ShadowVolume(int numsurfaces, int *surfacelist, const unsigned char *trispvs) -{ - qboolean zpass = false; - shadowmesh_t *mesh; - int t, tend; - int surfacelistindex; - msurface_t *surface; - - // if triangle neighbors are disabled, shadowvolumes are disabled - if (r_refdef.scene.worldmodel->brush.shadowmesh ? !r_refdef.scene.worldmodel->brush.shadowmesh->neighbor3i : !r_refdef.scene.worldmodel->surfmesh.data_neighbor3i) - return; - - RSurf_ActiveModelEntity(r_refdef.scene.worldentity, false, false, false); - - if (rsurface.rtlight->compiled && r_shadow_realtime_world_compile.integer && r_shadow_realtime_world_compileshadow.integer) - { - CHECKGLERROR - if (r_shadow_rendermode != R_SHADOW_RENDERMODE_VISIBLEVOLUMES) - { - zpass = R_Shadow_UseZPass(r_refdef.scene.worldmodel->normalmins, r_refdef.scene.worldmodel->normalmaxs); - R_Shadow_RenderMode_StencilShadowVolumes(zpass); - } - mesh = zpass ? rsurface.rtlight->static_meshchain_shadow_zpass : rsurface.rtlight->static_meshchain_shadow_zfail; - for (;mesh;mesh = mesh->next) - { - r_refdef.stats[r_stat_lights_shadowtriangles] += mesh->numtriangles; - R_Mesh_PrepareVertices_Vertex3f(mesh->numverts, mesh->vertex3f, mesh->vbo_vertexbuffer, mesh->vbooffset_vertex3f); - if (r_shadow_rendermode == R_SHADOW_RENDERMODE_ZPASS_STENCIL) - { - // increment stencil if frontface is infront of depthbuffer - GL_CullFace(r_refdef.view.cullface_back); - R_SetStencil(true, 255, GL_KEEP, GL_KEEP, GL_INCR, GL_ALWAYS, 128, 255); - R_Mesh_Draw(0, mesh->numverts, 0, mesh->numtriangles, mesh->element3i, mesh->element3i_indexbuffer, mesh->element3i_bufferoffset, mesh->element3s, mesh->element3s_indexbuffer, mesh->element3s_bufferoffset); - // decrement stencil if backface is infront of depthbuffer - GL_CullFace(r_refdef.view.cullface_front); - R_SetStencil(true, 255, GL_KEEP, GL_KEEP, GL_DECR, GL_ALWAYS, 128, 255); - } - else if (r_shadow_rendermode == R_SHADOW_RENDERMODE_ZFAIL_STENCIL) - { - // decrement stencil if backface is behind depthbuffer - GL_CullFace(r_refdef.view.cullface_front); - R_SetStencil(true, 255, GL_KEEP, GL_DECR, GL_KEEP, GL_ALWAYS, 128, 255); - R_Mesh_Draw(0, mesh->numverts, 0, mesh->numtriangles, mesh->element3i, mesh->element3i_indexbuffer, mesh->element3i_bufferoffset, mesh->element3s, mesh->element3s_indexbuffer, mesh->element3s_bufferoffset); - // increment stencil if frontface is behind depthbuffer - GL_CullFace(r_refdef.view.cullface_back); - R_SetStencil(true, 255, GL_KEEP, GL_INCR, GL_KEEP, GL_ALWAYS, 128, 255); - } - R_Mesh_Draw(0, mesh->numverts, 0, mesh->numtriangles, mesh->element3i, mesh->element3i_indexbuffer, mesh->element3i_bufferoffset, mesh->element3s, mesh->element3s_indexbuffer, mesh->element3s_bufferoffset); - } - CHECKGLERROR - } - else if (numsurfaces && r_refdef.scene.worldmodel->brush.shadowmesh) - { - // use the shadow trispvs calculated earlier by GetLightInfo to cull world triangles on this dynamic light - R_Shadow_PrepareShadowMark(r_refdef.scene.worldmodel->brush.shadowmesh->numtriangles); - for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++) - { - surface = r_refdef.scene.worldmodel->data_surfaces + surfacelist[surfacelistindex]; - for (t = surface->num_firstshadowmeshtriangle, tend = t + surface->num_triangles;t < tend;t++) - if (CHECKPVSBIT(trispvs, t)) - shadowmarklist[numshadowmark++] = t; - } - R_Shadow_VolumeFromList(r_refdef.scene.worldmodel->brush.shadowmesh->numverts, r_refdef.scene.worldmodel->brush.shadowmesh->numtriangles, r_refdef.scene.worldmodel->brush.shadowmesh->vertex3f, r_refdef.scene.worldmodel->brush.shadowmesh->element3i, r_refdef.scene.worldmodel->brush.shadowmesh->neighbor3i, rsurface.rtlight->shadoworigin, NULL, rsurface.rtlight->radius + r_refdef.scene.worldmodel->radius*2 + r_shadow_projectdistance.value, numshadowmark, shadowmarklist, r_refdef.scene.worldmodel->normalmins, r_refdef.scene.worldmodel->normalmaxs); - } - else if (numsurfaces) - { - r_refdef.scene.worldmodel->DrawShadowVolume(r_refdef.scene.worldentity, rsurface.rtlight->shadoworigin, NULL, rsurface.rtlight->radius, numsurfaces, surfacelist, rsurface.rtlight->cached_cullmins, rsurface.rtlight->cached_cullmaxs); - } - - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity -} - static void R_Shadow_DrawEntityShadow(entity_render_t *ent) { vec3_t relativeshadoworigin, relativeshadowmins, relativeshadowmaxs; @@ -4170,15 +3387,7 @@ static void R_Shadow_DrawEntityShadow(entity_render_t *ent) relativeshadowmaxs[0] = relativeshadoworigin[0] + relativeshadowradius; relativeshadowmaxs[1] = relativeshadoworigin[1] + relativeshadowradius; relativeshadowmaxs[2] = relativeshadoworigin[2] + relativeshadowradius; - switch (r_shadow_rendermode) - { - case R_SHADOW_RENDERMODE_SHADOWMAP2D: - ent->model->DrawShadowMap(r_shadow_shadowmapside, ent, relativeshadoworigin, NULL, relativeshadowradius, ent->model->nummodelsurfaces, ent->model->sortedmodelsurfaces, NULL, relativeshadowmins, relativeshadowmaxs); - break; - default: - ent->model->DrawShadowVolume(ent, relativeshadoworigin, NULL, relativeshadowradius, ent->model->nummodelsurfaces, ent->model->sortedmodelsurfaces, relativeshadowmins, relativeshadowmaxs); - break; - } + ent->model->DrawShadowMap(r_shadow_shadowmapside, ent, relativeshadoworigin, NULL, relativeshadowradius, ent->model->nummodelsurfaces, ent->model->sortedmodelsurfaces, NULL, relativeshadowmins, relativeshadowmaxs); rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity } @@ -4412,7 +3621,7 @@ static void R_Shadow_PrepareLight(rtlight_t *rtlight) // since it is lit, it probably also casts a shadow... // about the VectorDistance2 - light emitting entities should not cast their own shadow Matrix4x4_OriginFromMatrix(&ent->matrix, org); - if ((ent->flags & RENDER_SHADOW) && model->DrawShadowVolume && VectorDistance2(org, rtlight->shadoworigin) > 0.1) + if ((ent->flags & RENDER_SHADOW) && model->DrawShadowMap && VectorDistance2(org, rtlight->shadoworigin) > 0.1) { // note: exterior models without the RENDER_NOSELFSHADOW // flag still create a RENDER_NOSELFSHADOW shadow but @@ -4436,7 +3645,7 @@ static void R_Shadow_PrepareLight(rtlight_t *rtlight) continue; // about the VectorDistance2 - light emitting entities should not cast their own shadow Matrix4x4_OriginFromMatrix(&ent->matrix, org); - if ((ent->flags & RENDER_SHADOW) && model->DrawShadowVolume && VectorDistance2(org, rtlight->shadoworigin) > 0.1) + if ((ent->flags & RENDER_SHADOW) && model->DrawShadowMap && VectorDistance2(org, rtlight->shadoworigin) > 0.1) { if (ent->flags & (RENDER_NOSELFSHADOW | RENDER_EXTERIORMODEL)) shadowentities_noselfshadow[numshadowentities_noselfshadow++] = ent; @@ -4717,25 +3926,11 @@ static void R_Shadow_DrawLight(rtlight_t *rtlight) // make this the active rtlight for rendering purposes R_Shadow_RenderMode_ActiveLight(rtlight); - if (r_showshadowvolumes.integer && r_refdef.view.showdebug && numsurfaces + numshadowentities + numshadowentities_noselfshadow && rtlight->shadow && (rtlight->isstatic ? r_refdef.scene.rtworldshadows : r_refdef.scene.rtdlightshadows)) - { - // optionally draw visible shape of the shadow volumes - // for performance analysis by level designers - R_Shadow_RenderMode_VisibleShadowVolumes(); - if (numsurfaces) - R_Shadow_DrawWorldShadow_ShadowVolume(numsurfaces, surfacelist, shadowtrispvs); - for (i = 0;i < numshadowentities;i++) - R_Shadow_DrawEntityShadow(shadowentities[i]); - for (i = 0;i < numshadowentities_noselfshadow;i++) - R_Shadow_DrawEntityShadow(shadowentities_noselfshadow[i]); - R_Shadow_RenderMode_VisibleLighting(false, false); - } - if (r_showlighting.integer && r_refdef.view.showdebug && numsurfaces + numlightentities + numlightentities_noselfshadow) { // optionally draw the illuminated areas // for performance analysis by level designers - R_Shadow_RenderMode_VisibleLighting(false, false); + R_Shadow_RenderMode_VisibleLighting(false); if (numsurfaces) R_Shadow_DrawWorldLight(numsurfaces, surfacelist, lighttrispvs); for (i = 0;i < numlightentities;i++) @@ -4764,7 +3959,7 @@ static void R_Shadow_DrawLight(rtlight_t *rtlight) // draw lighting in the unmasked areas if (numsurfaces + numlightentities) { - R_Shadow_RenderMode_Lighting(false, false, true, false); + R_Shadow_RenderMode_Lighting(false, true, false); // draw lighting in the unmasked areas if (numsurfaces) R_Shadow_DrawWorldLight(numsurfaces, surfacelist, lighttrispvs); @@ -4774,7 +3969,7 @@ static void R_Shadow_DrawLight(rtlight_t *rtlight) // offset to the noselfshadow part of the atlas and draw those too if (numlightentities_noselfshadow) { - R_Shadow_RenderMode_Lighting(false, false, true, true); + R_Shadow_RenderMode_Lighting(false, true, true); for (i = 0; i < numlightentities_noselfshadow; i++) R_Shadow_DrawEntityLight(lightentities_noselfshadow[i]); } @@ -4783,41 +3978,10 @@ static void R_Shadow_DrawLight(rtlight_t *rtlight) if (r_shadow_usingdeferredprepass) R_Shadow_RenderMode_DrawDeferredLight(true); } - else if (castshadows && vid.stencil) - { - // draw stencil shadow volumes to mask off pixels that are in shadow - // so that they won't receive lighting - GL_Scissor(r_shadow_lightscissor[0], r_shadow_lightscissor[1], r_shadow_lightscissor[2], r_shadow_lightscissor[3]); - R_Shadow_ClearStencil(); - - if (numsurfaces) - R_Shadow_DrawWorldShadow_ShadowVolume(numsurfaces, surfacelist, shadowtrispvs); - for (i = 0;i < numshadowentities;i++) - R_Shadow_DrawEntityShadow(shadowentities[i]); - - // draw lighting in the unmasked areas - R_Shadow_RenderMode_Lighting(true, false, false, false); - for (i = 0;i < numlightentities_noselfshadow;i++) - R_Shadow_DrawEntityLight(lightentities_noselfshadow[i]); - - for (i = 0;i < numshadowentities_noselfshadow;i++) - R_Shadow_DrawEntityShadow(shadowentities_noselfshadow[i]); - - // draw lighting in the unmasked areas - R_Shadow_RenderMode_Lighting(true, false, false, false); - if (numsurfaces) - R_Shadow_DrawWorldLight(numsurfaces, surfacelist, lighttrispvs); - for (i = 0;i < numlightentities;i++) - R_Shadow_DrawEntityLight(lightentities[i]); - - // rasterize the box when rendering deferred lighting - the regular surface lighting only applies to transparent surfaces - if (r_shadow_usingdeferredprepass) - R_Shadow_RenderMode_DrawDeferredLight(false); - } else { // draw lighting in the unmasked areas - R_Shadow_RenderMode_Lighting(false, false, false, false); + R_Shadow_RenderMode_Lighting(false, false, false); if (numsurfaces) R_Shadow_DrawWorldLight(numsurfaces, surfacelist, lighttrispvs); for (i = 0;i < numlightentities;i++) @@ -5161,31 +4325,6 @@ void R_Shadow_PrepareModelShadows(void) if (!r_refdef.scene.numentities || r_refdef.scene.lightmapintensity <= 0.0f || r_shadows.integer <= 0) return; - switch (r_shadow_shadowmode) - { - case R_SHADOW_SHADOWMODE_SHADOWMAP2D: - if (r_shadows.integer >= 2) - break; - // fall through - case R_SHADOW_SHADOWMODE_STENCIL: - if (!vid.stencil) - return; - for (i = 0; i < r_refdef.scene.numentities; i++) - { - ent = r_refdef.scene.entities[i]; - if (ent->model && ent->model->DrawShadowVolume != NULL && (!ent->model->brush.submodel || r_shadows_castfrombmodels.integer) && (ent->flags & RENDER_SHADOW)) - { - if (r_shadow_nummodelshadows >= MAX_MODELSHADOWS) - break; - r_shadow_modelshadows[r_shadow_nummodelshadows++] = ent; - R_AnimCache_GetEntity(ent, false, false); - } - } - return; - default: - return; - } - size = r_shadow_shadowmaptexturesize / 4; scale = r_shadow_shadowmapping_precision.value * r_shadows_shadowmapscale.value; radius = 0.5f * size / scale; @@ -5350,97 +4489,6 @@ static void R_Shadow_DrawModelShadowMaps(void) Matrix4x4_Concat(&r_shadow_shadowmapmatrix, &texmatrix, &invmvpmatrix); } -void R_Shadow_DrawModelShadows(void) -{ - int i; - float relativethrowdistance; - entity_render_t *ent; - vec3_t relativelightorigin; - vec3_t relativelightdirection; - vec3_t relativeshadowmins, relativeshadowmaxs; - vec3_t tmp, shadowdir; - prvm_vec3_t prvmshadowdir; - - if (!r_shadow_nummodelshadows || (r_shadow_shadowmode != R_SHADOW_SHADOWMODE_STENCIL && r_shadows.integer != 1)) - return; - - R_ResetViewRendering3D(r_shadow_viewfbo, r_shadow_viewdepthtexture, r_shadow_viewcolortexture, r_shadow_viewx, r_shadow_viewy, r_shadow_viewwidth, r_shadow_viewheight); - //GL_Scissor(r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height); - //GL_Scissor(r_refdef.view.x, vid.height - r_refdef.view.height - r_refdef.view.y, r_refdef.view.width, r_refdef.view.height); - R_Shadow_RenderMode_Begin(); - R_Shadow_RenderMode_ActiveLight(NULL); - r_shadow_lightscissor[0] = r_shadow_viewx; - r_shadow_lightscissor[1] = (r_shadow_viewfbo ? r_shadow_viewheight : vid.height) - r_shadow_viewy - r_shadow_viewheight; - r_shadow_lightscissor[2] = r_shadow_viewwidth; - r_shadow_lightscissor[3] = r_shadow_viewheight; - R_Shadow_RenderMode_StencilShadowVolumes(false); - - // get shadow dir - if (r_shadows.integer == 2) - { - Math_atov(r_shadows_throwdirection.string, prvmshadowdir); - VectorCopy(prvmshadowdir, shadowdir); - VectorNormalize(shadowdir); - } - - R_Shadow_ClearStencil(); - - for (i = 0;i < r_shadow_nummodelshadows;i++) - { - ent = r_shadow_modelshadows[i]; - - // cast shadows from anything of the map (submodels are optional) - relativethrowdistance = r_shadows_throwdistance.value * Matrix4x4_ScaleFromMatrix(&ent->inversematrix); - VectorSet(relativeshadowmins, -relativethrowdistance, -relativethrowdistance, -relativethrowdistance); - VectorSet(relativeshadowmaxs, relativethrowdistance, relativethrowdistance, relativethrowdistance); - if (r_shadows.integer == 2) // 2: simpler mode, throw shadows always in same direction - Matrix4x4_Transform3x3(&ent->inversematrix, shadowdir, relativelightdirection); - else - { - VectorNegate(ent->render_modellight_lightdir, tmp); - Matrix4x4_Transform3x3(&ent->inversematrix, tmp, relativelightdirection); - } - - VectorScale(relativelightdirection, -relativethrowdistance, relativelightorigin); - RSurf_ActiveModelEntity(ent, false, false, false); - ent->model->DrawShadowVolume(ent, relativelightorigin, relativelightdirection, relativethrowdistance, ent->model->nummodelsurfaces, ent->model->sortedmodelsurfaces, relativeshadowmins, relativeshadowmaxs); - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity - } - - // not really the right mode, but this will disable any silly stencil features - R_Shadow_RenderMode_End(); - - // set up ortho view for rendering this pass - //GL_Scissor(r_refdef.view.x, vid.height - r_refdef.view.height - r_refdef.view.y, r_refdef.view.width, r_refdef.view.height); - //GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1); - //GL_ScissorTest(true); - //R_EntityMatrix(&identitymatrix); - //R_Mesh_ResetTextureState(); - R_ResetViewRendering2D(r_shadow_viewfbo, r_shadow_viewdepthtexture, r_shadow_viewcolortexture, r_shadow_viewx, r_shadow_viewy, r_shadow_viewwidth, r_shadow_viewheight); - - // set up a darkening blend on shadowed areas - GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - //GL_DepthRange(0, 1); - //GL_DepthTest(false); - //GL_DepthMask(false); - //GL_PolygonOffset(0, 0);CHECKGLERROR - GL_Color(0, 0, 0, r_shadows_darken.value); - //GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1); - //GL_DepthFunc(GL_ALWAYS); - R_SetStencil(true, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_NOTEQUAL, 128, 255); - - // apply the blend to the shadowed areas - R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, NULL); - R_SetupShader_Generic_NoTexture(false, true); - R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0); - - // restore the viewport - R_SetViewport(&r_refdef.view.viewport); - - // restore other state to normal - //R_Shadow_RenderMode_End(); -} - static void R_BeginCoronaQuery(rtlight_t *rtlight, float scale, qboolean usequery) { float zdist; diff --git a/r_shadow.h b/r_shadow.h index 82f5c88e..048fcc4e 100644 --- a/r_shadow.h +++ b/r_shadow.h @@ -31,11 +31,7 @@ extern cvar_t r_shadow_realtime_world_compileshadow; extern cvar_t r_shadow_realtime_world_compilesvbsp; extern cvar_t r_shadow_realtime_world_compileportalculling; extern cvar_t r_shadow_scissor; -extern cvar_t r_shadow_polygonfactor; -extern cvar_t r_shadow_polygonoffset; extern cvar_t r_shadow_texture3d; -extern cvar_t gl_ext_separatestencil; -extern cvar_t gl_ext_stenciltwoside; // used by shader for bouncegrid feature typedef struct r_shadow_bouncegrid_settings_s @@ -102,9 +98,7 @@ extern r_shadow_bouncegrid_state_t r_shadow_bouncegrid_state; void R_Shadow_Init(void); qboolean R_Shadow_ShadowMappingEnabled(void); -void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f, const int *elements, const int *neighbors, const vec3_t projectorigin, const vec3_t projectdirection, float projectdistance, int nummarktris, const int *marktris, vec3_t trismins, vec3_t trismaxs); void R_Shadow_ShadowMapFromList(int numverts, int numtris, const float *vertex3f, const int *elements, int numsidetris, const int *sidetotals, const unsigned char *sides, const int *sidetris); -void R_Shadow_MarkVolumeFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const vec3_t projectorigin, const vec3_t projectdirection, const vec3_t lightmins, const vec3_t lightmaxs, const vec3_t surfacemins, const vec3_t surfacemaxs); int R_Shadow_CalcTriangleSideMask(const vec3_t p1, const vec3_t p2, const vec3_t p3, float bias); int R_Shadow_CalcSphereSideMask(const vec3_t p1, float radius, float bias); int R_Shadow_ChooseSidesFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const matrix4x4_t *worldtolight, const vec3_t projectorigin, const vec3_t projectdirection, const vec3_t lightmins, const vec3_t lightmaxs, const vec3_t surfacemins, const vec3_t surfacemaxs, int *totals); @@ -112,11 +106,9 @@ void R_Shadow_RenderLighting(int texturenumsurfaces, const msurface_t **textures void R_Shadow_RenderMode_Begin(void); void R_Shadow_RenderMode_ActiveLight(const rtlight_t *rtlight); void R_Shadow_RenderMode_Reset(void); -void R_Shadow_RenderMode_StencilShadowVolumes(qboolean zpass); -void R_Shadow_RenderMode_Lighting(qboolean stenciltest, qboolean transparent, qboolean shadowmapping, qboolean noselfshadowpass); +void R_Shadow_RenderMode_Lighting(qboolean transparent, qboolean shadowmapping, qboolean noselfshadowpass); void R_Shadow_RenderMode_DrawDeferredLight(qboolean shadowmapping); -void R_Shadow_RenderMode_VisibleShadowVolumes(void); -void R_Shadow_RenderMode_VisibleLighting(qboolean stenciltest, qboolean transparent); +void R_Shadow_RenderMode_VisibleLighting(qboolean transparent); void R_Shadow_RenderMode_End(void); void R_Shadow_ClearStencil(void); void R_Shadow_SetupEntityLight(const entity_render_t *ent); @@ -162,6 +154,5 @@ void R_Shadow_PrepareModelShadows(void); void R_CompleteLightPoint(float *ambient, float *diffuse, float *lightdir, const vec3_t p, const int flags, float lightmapintensity, float ambientintensity); void R_Shadow_DrawShadowMaps(void); -void R_Shadow_DrawModelShadows(void); #endif diff --git a/render.h b/render.h index dcacb639..2ae9bc84 100644 --- a/render.h +++ b/render.h @@ -219,7 +219,6 @@ typedef struct rmesh_s int maxtriangles; int numtriangles; int *element3i; - int *neighbor3i; // snapping epsilon float epsilon2; } @@ -243,7 +242,6 @@ extern cvar_t r_showoverdraw; extern cvar_t r_showtris; extern cvar_t r_shownormals; extern cvar_t r_showlighting; -extern cvar_t r_showshadowvolumes; extern cvar_t r_showcollisionbrushes; extern cvar_t r_showcollisionbrushes_polygonfactor; extern cvar_t r_showcollisionbrushes_polygonoffset; diff --git a/vid.h b/vid.h index f5185602..71404c2f 100644 --- a/vid.h +++ b/vid.h @@ -55,14 +55,12 @@ typedef struct viddef_support_s qboolean arb_texture_non_power_of_two; qboolean arb_vertex_buffer_object; qboolean arb_uniform_buffer_object; - qboolean ati_separate_stencil; qboolean ext_blend_minmax; qboolean ext_blend_subtract; qboolean ext_blend_func_separate; qboolean ext_draw_range_elements; qboolean ext_framebuffer_object; qboolean ext_packed_depth_stencil; - qboolean ext_stencil_two_side; qboolean ext_texture_3d; qboolean ext_texture_compression_s3tc; qboolean ext_texture_edge_clamp; diff --git a/vid_sdl.c b/vid_sdl.c index 70032371..dcaeafbb 100644 --- a/vid_sdl.c +++ b/vid_sdl.c @@ -1892,7 +1892,6 @@ void GLES_Init(void) vid.support.arb_texture_gather = false; vid.support.arb_texture_non_power_of_two = strstr(gl_extensions, "GL_OES_texture_npot") != NULL; vid.support.arb_vertex_buffer_object = true; // GLES2 core - vid.support.ati_separate_stencil = false; vid.support.ext_blend_minmax = false; vid.support.ext_blend_subtract = true; // GLES2 core vid.support.ext_blend_func_separate = true; // GLES2 core @@ -1907,7 +1906,6 @@ void GLES_Init(void) vid.support.ext_framebuffer_object = true; vid.support.ext_packed_depth_stencil = false; - vid.support.ext_stencil_two_side = false; vid.support.ext_texture_3d = SDL_GL_ExtensionSupported("GL_OES_texture_3D") != 0; vid.support.ext_texture_compression_s3tc = SDL_GL_ExtensionSupported("GL_EXT_texture_compression_s3tc") != 0; vid.support.ext_texture_edge_clamp = true; // GLES2 core diff --git a/vid_shared.c b/vid_shared.c index 9d7f47c5..b7708cd0 100644 --- a/vid_shared.c +++ b/vid_shared.c @@ -633,26 +633,6 @@ static dllfunction_t texture3dextfuncs[] = {NULL, NULL} }; -static dllfunction_t atiseparatestencilfuncs[] = -{ - {"glStencilOpSeparateATI", (void **) &qglStencilOpSeparate}, - {"glStencilFuncSeparateATI", (void **) &qglStencilFuncSeparate}, - {NULL, NULL} -}; - -static dllfunction_t gl2separatestencilfuncs[] = -{ - {"glStencilOpSeparate", (void **) &qglStencilOpSeparate}, - {"glStencilFuncSeparate", (void **) &qglStencilFuncSeparate}, - {NULL, NULL} -}; - -static dllfunction_t stenciltwosidefuncs[] = -{ - {"glActiveStencilFaceEXT", (void **) &qglActiveStencilFaceEXT}, - {NULL, NULL} -}; - static dllfunction_t blendequationfuncs[] = { {"glBlendEquationEXT", (void **) &qglBlendEquationEXT}, @@ -955,7 +935,6 @@ void VID_CheckExtensions(void) vid.support.arb_texture_non_power_of_two = GL_CheckExtension("GL_ARB_texture_non_power_of_two", NULL, "-notexturenonpoweroftwo", false); vid.support.arb_vertex_buffer_object = GL_CheckExtension("GL_ARB_vertex_buffer_object", vbofuncs, "-novbo", false); vid.support.arb_uniform_buffer_object = GL_CheckExtension("GL_ARB_uniform_buffer_object", ubofuncs, "-noubo", false); - vid.support.ati_separate_stencil = GL_CheckExtension("separatestencil", gl2separatestencilfuncs, "-noseparatestencil", true) || GL_CheckExtension("GL_ATI_separate_stencil", atiseparatestencilfuncs, "-noseparatestencil", false); vid.support.ext_blend_minmax = GL_CheckExtension("GL_EXT_blend_minmax", blendequationfuncs, "-noblendminmax", false); vid.support.ext_blend_subtract = GL_CheckExtension("GL_EXT_blend_subtract", blendequationfuncs, "-noblendsubtract", false); vid.support.ext_blend_func_separate = GL_CheckExtension("GL_EXT_blend_func_separate", blendfuncseparatefuncs, "-noblendfuncseparate", false); @@ -967,7 +946,6 @@ void VID_CheckExtensions(void) vid.support.ext_framebuffer_object = GL_CheckExtension("GL_EXT_framebuffer_object", extfbofuncs, "-nofbo", false); vid.support.ext_packed_depth_stencil = GL_CheckExtension("GL_EXT_packed_depth_stencil", NULL, "-nopackeddepthstencil", false); - vid.support.ext_stencil_two_side = GL_CheckExtension("GL_EXT_stencil_two_side", stenciltwosidefuncs, "-nostenciltwoside", false); vid.support.ext_texture_3d = GL_CheckExtension("GL_EXT_texture3D", texture3dextfuncs, "-notexture3d", false); vid.support.ext_texture_compression_s3tc = GL_CheckExtension("GL_EXT_texture_compression_s3tc", NULL, "-nos3tc", false); vid.support.ext_texture_edge_clamp = GL_CheckExtension("GL_EXT_texture_edge_clamp", NULL, "-noedgeclamp", false) || GL_CheckExtension("GL_SGIS_texture_edge_clamp", NULL, "-noedgeclamp", false); @@ -994,9 +972,7 @@ void VID_CheckExtensions(void) // COMMANDLINEOPTION: GL: -noocclusionquery disables GL_ARB_occlusion_query (which allows coronas to fade according to visibility, and potentially used for rendering optimizations) // COMMANDLINEOPTION: GL: -noquerybuffer disables GL_ARB_query_buffer_object (which allows corona fading without synchronous rendering) // COMMANDLINEOPTION: GL: -nos3tc disables GL_EXT_texture_compression_s3tc (which allows use of .dds texture caching) -// COMMANDLINEOPTION: GL: -noseparatestencil disables use of OpenGL2.0 glStencilOpSeparate and GL_ATI_separate_stencil extensions (which accelerate shadow rendering) // COMMANDLINEOPTION: GL: -noshadow disables use of GL_ARB_shadow (required for hardware shadowmap filtering) -// COMMANDLINEOPTION: GL: -nostenciltwoside disables GL_EXT_stencil_two_side (which accelerate shadow rendering) // COMMANDLINEOPTION: GL: -notexture3d disables GL_EXT_texture3D (required for spherical lights, otherwise they render as a column) // COMMANDLINEOPTION: GL: -notexture4 disables GL_AMD_texture_texture4 (which provides fetch4 sampling) // COMMANDLINEOPTION: GL: -notexturecompression disables GL_ARB_texture_compression (which saves video memory if it is supported, but can also degrade image quality, see gl_texturecompression cvar documentation for more information)