From 93ee242c05da6c2b71a6eaf4e393435988ca6c5a Mon Sep 17 00:00:00 2001 From: havoc Date: Wed, 9 Nov 2011 03:02:20 +0000 Subject: [PATCH] added r_transparent_sortsurfacesbynearest cvar (default 1), this resolves a lot of sorting issues with transparent surfaces added r_transparent_useplanardistance cvar (default 0), the new spherical distance method will not change when the view rotates, mostly a consistency improvement git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11543 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_particles.c | 6 +++--- clvm_cmds.c | 2 +- gl_backend.c | 2 -- gl_rmain.c | 54 ++++++++++++++++++++++++++++++-------------------- gl_rsurf.c | 25 ++++++++++++++++++----- meshqueue.c | 28 ++++++++++++++++++-------- meshqueue.h | 10 +++++++++- r_explosion.c | 2 +- r_lightning.c | 2 +- r_shadow.c | 4 ++-- r_sprites.c | 2 +- render.h | 7 +++++++ 12 files changed, 98 insertions(+), 46 deletions(-) diff --git a/cl_particles.c b/cl_particles.c index b1d891a7..a1167120 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -2498,7 +2498,7 @@ void R_DrawDecals (void) continue; if (DotProduct(r_refdef.view.origin, decal->normal) > DotProduct(decal->org, decal->normal) && VectorDistance2(decal->org, r_refdef.view.origin) < drawdist2 * (decal->size * decal->size)) - R_MeshQueue_AddTransparent(decal->org, R_DrawDecal_TransparentCallback, NULL, i, NULL); + R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, decal->org, R_DrawDecal_TransparentCallback, NULL, i, NULL); continue; killdecal: decal->typeindex = 0; @@ -2977,7 +2977,7 @@ void R_DrawParticles (void) { case pt_beam: // beams have no culling - R_MeshQueue_AddTransparent(p->sortorigin, R_DrawParticle_TransparentCallback, NULL, i, NULL); + R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, p->sortorigin, R_DrawParticle_TransparentCallback, NULL, i, NULL); break; default: if(cl_particles_visculling.integer) @@ -2991,7 +2991,7 @@ void R_DrawParticles (void) } // anything else just has to be in front of the viewer and visible at this distance if (DotProduct(p->org, r_refdef.view.forward) >= minparticledist_start && VectorDistance2(p->org, r_refdef.view.origin) < drawdist2 * (p->size * p->size)) - R_MeshQueue_AddTransparent(p->sortorigin, R_DrawParticle_TransparentCallback, NULL, i, NULL); + R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, p->sortorigin, R_DrawParticle_TransparentCallback, NULL, i, NULL); break; } diff --git a/clvm_cmds.c b/clvm_cmds.c index 1a6204d1..8d571bfc 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -3226,7 +3226,7 @@ void VM_CL_AddPolygonsToMeshQueue (prvm_prog_t *prog) for (i = 0;i < polys->num_triangles;i++) { VectorMAMAM(1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[0], 1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[1], 1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[2], center); - R_MeshQueue_AddTransparent(center, VM_DrawPolygonCallback, (entity_render_t *)polys, i, NULL); + R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, center, VM_DrawPolygonCallback, (entity_render_t *)polys, i, NULL); } /*polys->num_triangles = 0; // now done after rendering the scene, diff --git a/gl_backend.c b/gl_backend.c index c182ad3b..8df14f8e 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -1536,8 +1536,6 @@ static int d3dstencilopforglfunc(int f) } #endif -extern cvar_t r_transparent_alphatocoverage; - static void GL_Backend_ResetState(void) { unsigned int i; diff --git a/gl_rmain.c b/gl_rmain.c index 304c3074..6c26b8de 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -77,6 +77,8 @@ cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip pla cvar_t r_deformvertexes = {0, "r_deformvertexes", "1", "allows use of deformvertexes in shader files (can be turned off to check performance impact)"}; cvar_t r_transparent = {0, "r_transparent", "1", "allows use of transparent surfaces (can be turned off to check performance impact)"}; cvar_t r_transparent_alphatocoverage = {0, "r_transparent_alphatocoverage", "1", "enables GL_ALPHA_TO_COVERAGE antialiasing technique on alphablend and alphatest surfaces when using vid_samples 2 or higher"}; +cvar_t r_transparent_sortsurfacesbynearest = {0, "r_transparent_sortsurfacesbynearest", "1", "sort entity and world surfaces by nearest point on bounding box instead of using the center of the bounding box, usually reduces sorting artifacts"}; +cvar_t r_transparent_useplanardistance = {0, "r_transparent_useplanardistance", "0", "sort transparent meshes by distance from view plane rather than spherical distance to the chosen point"}; cvar_t r_showoverdraw = {0, "r_showoverdraw", "0", "shows overlapping geometry"}; cvar_t r_showbboxes = {0, "r_showbboxes", "0", "shows bounding boxes of server entities, value controls opacity scaling (1 = 10%, 10 = 100%)"}; cvar_t r_showsurfaces = {0, "r_showsurfaces", "0", "1 shows surfaces as different colors, or a value of 2 shows triangle draw order (for analyzing whether meshes are optimized for vertex cache)"}; @@ -4186,6 +4188,8 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_deformvertexes); Cvar_RegisterVariable(&r_transparent); Cvar_RegisterVariable(&r_transparent_alphatocoverage); + Cvar_RegisterVariable(&r_transparent_sortsurfacesbynearest); + Cvar_RegisterVariable(&r_transparent_useplanardistance); Cvar_RegisterVariable(&r_showoverdraw); Cvar_RegisterVariable(&r_showbboxes); Cvar_RegisterVariable(&r_showsurfaces); @@ -7304,7 +7308,7 @@ static void R_DrawEntityBBoxes(void) if(PRVM_serveredictedict(edict, viewmodelforclient) != 0) continue; VectorLerp(edict->priv.server->areamins, 0.5f, edict->priv.server->areamaxs, center); - R_MeshQueue_AddTransparent(center, R_DrawEntityBBoxes_Callback, (entity_render_t *)NULL, i, (rtlight_t *)NULL); + R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, center, R_DrawEntityBBoxes_Callback, (entity_render_t *)NULL, i, (rtlight_t *)NULL); } } @@ -7412,7 +7416,7 @@ void R_DrawNoModel(entity_render_t *ent) vec3_t org; Matrix4x4_OriginFromMatrix(&ent->matrix, org); if ((ent->flags & RENDER_ADDITIVE) || (ent->alpha < 1)) - R_MeshQueue_AddTransparent(ent->flags & RENDER_NODEPTHTEST ? r_refdef.view.origin : org, R_DrawNoModel_TransparentCallback, ent, 0, rsurface.rtlight); + R_MeshQueue_AddTransparent((ent->flags & RENDER_NODEPTHTEST) ? MESHQUEUE_SORT_HUD : MESHQUEUE_SORT_DISTANCE, org, R_DrawNoModel_TransparentCallback, ent, 0, rsurface.rtlight); else R_DrawNoModel_TransparentCallback(ent, rsurface.rtlight, 0, NULL); } @@ -10410,7 +10414,7 @@ static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity } -static void R_ProcessTransparentTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, const entity_render_t *queueentity) +static void R_ProcessTransparentTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist) { // transparent surfaces get pushed off into the transparent queue int surfacelistindex; @@ -10419,17 +10423,26 @@ static void R_ProcessTransparentTextureSurfaceList(int texturenumsurfaces, const for (surfacelistindex = 0;surfacelistindex < texturenumsurfaces;surfacelistindex++) { surface = texturesurfacelist[surfacelistindex]; - tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f; - tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f; - tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f; + if (r_transparent_sortsurfacesbynearest.integer) + { + tempcenter[0] = bound(surface->mins[0], rsurface.localvieworigin[0], surface->maxs[0]); + tempcenter[1] = bound(surface->mins[1], rsurface.localvieworigin[1], surface->maxs[1]); + tempcenter[2] = bound(surface->mins[2], rsurface.localvieworigin[2], surface->maxs[2]); + } + else + { + tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f; + tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f; + tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f; + } Matrix4x4_Transform(&rsurface.matrix, tempcenter, center); - if (queueentity->transparent_offset) // transparent offset + if (rsurface.entity->transparent_offset) // transparent offset { - center[0] += r_refdef.view.forward[0]*queueentity->transparent_offset; - center[1] += r_refdef.view.forward[1]*queueentity->transparent_offset; - center[2] += r_refdef.view.forward[2]*queueentity->transparent_offset; + center[0] += r_refdef.view.forward[0]*rsurface.entity->transparent_offset; + center[1] += r_refdef.view.forward[1]*rsurface.entity->transparent_offset; + center[2] += r_refdef.view.forward[2]*rsurface.entity->transparent_offset; } - R_MeshQueue_AddTransparent(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_refdef.view.origin : center, R_DrawSurface_TransparentCallback, queueentity, surface - rsurface.modelsurfaces, rsurface.rtlight); + R_MeshQueue_AddTransparent((rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST) ? MESHQUEUE_SORT_HUD : ((rsurface.entity->flags & RENDER_WORLDOBJECT) ? MESHQUEUE_SORT_SKY : MESHQUEUE_SORT_DISTANCE), center, R_DrawSurface_TransparentCallback, rsurface.entity, surface - rsurface.modelsurfaces, rsurface.rtlight); } } @@ -10450,7 +10463,6 @@ static void R_DrawTextureSurfaceList_DepthOnly(int texturenumsurfaces, const msu static void R_ProcessWorldTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, qboolean prepass) { - const entity_render_t *queueentity = r_refdef.scene.worldentity; CHECKGLERROR if (depthonly) R_DrawTextureSurfaceList_DepthOnly(texturenumsurfaces, texturesurfacelist); @@ -10459,7 +10471,7 @@ static void R_ProcessWorldTextureSurfaceList(int texturenumsurfaces, const msurf if (!rsurface.texture->currentnumlayers) return; if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) - R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity); + R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist); else R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass); } @@ -10467,11 +10479,11 @@ static void R_ProcessWorldTextureSurfaceList(int texturenumsurfaces, const msurf R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist); else if (!rsurface.texture->currentnumlayers) return; - else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST))) && queueentity) + else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)))) { // in the deferred case, transparent surfaces were queued during prepass if (!r_shadow_usingdeferredprepass) - R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity); + R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist); } else { @@ -10527,7 +10539,7 @@ static void R_QueueWorldSurfaceList(int numsurfaces, const msurface_t **surfacel R_FrameData_ReturnToMark(); } -static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, const entity_render_t *queueentity, qboolean prepass) +static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, qboolean prepass) { CHECKGLERROR if (depthonly) @@ -10537,7 +10549,7 @@ static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurf if (!rsurface.texture->currentnumlayers) return; if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) - R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity); + R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist); else R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass); } @@ -10545,11 +10557,11 @@ static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurf R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist); else if (!rsurface.texture->currentnumlayers) return; - else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST))) && queueentity) + else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)))) { // in the deferred case, transparent surfaces were queued during prepass if (!r_shadow_usingdeferredprepass) - R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity); + R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist); } else { @@ -10600,7 +10612,7 @@ static void R_QueueModelSurfaceList(entity_render_t *ent, int numsurfaces, const ; } // render the range of surfaces - R_ProcessModelTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly, ent, prepass); + R_ProcessModelTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly, prepass); } R_FrameData_ReturnToMark(); } @@ -10677,7 +10689,7 @@ void R_DrawLocs(void) for (loc = cl.locnodes, index = 0;loc;loc = loc->next, index++) { VectorLerp(loc->mins, 0.5f, loc->maxs, center); - R_MeshQueue_AddTransparent(center, R_DrawLoc_Callback, (entity_render_t *)loc, loc == nearestloc ? -1 : index, NULL); + R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, center, R_DrawLoc_Callback, (entity_render_t *)loc, loc == nearestloc ? -1 : index, NULL); } } diff --git a/gl_rsurf.c b/gl_rsurf.c index 4a9c0a84..bc378401 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -393,7 +393,7 @@ void R_DrawPortals(void) VectorAdd(center, portal->points[i].position, center); f = ixtable[portal->numpoints]; VectorScale(center, f, center); - R_MeshQueue_AddTransparent(center, R_DrawPortal_Callback, (entity_render_t *)portal, leafnum, rsurface.rtlight); + R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, center, R_DrawPortal_Callback, (entity_render_t *)portal, leafnum, rsurface.rtlight); } } } @@ -1516,11 +1516,26 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surface for (l = k;l < kend;l++) { surface = batchsurfacelist[l]; - tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f; - tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f; - tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f; + if (r_transparent_sortsurfacesbynearest.integer) + { + tempcenter[0] = bound(surface->mins[0], rsurface.localvieworigin[0], surface->maxs[0]); + tempcenter[1] = bound(surface->mins[1], rsurface.localvieworigin[1], surface->maxs[1]); + tempcenter[2] = bound(surface->mins[2], rsurface.localvieworigin[2], surface->maxs[2]); + } + else + { + tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f; + tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f; + tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f; + } Matrix4x4_Transform(&rsurface.matrix, tempcenter, center); - R_MeshQueue_AddTransparent(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_refdef.view.origin : center, R_Q1BSP_DrawLight_TransparentCallback, ent, surface - rsurface.modelsurfaces, rsurface.rtlight); + if (ent->transparent_offset) // transparent offset + { + center[0] += r_refdef.view.forward[0]*ent->transparent_offset; + center[1] += r_refdef.view.forward[1]*ent->transparent_offset; + center[2] += r_refdef.view.forward[2]*ent->transparent_offset; + } + R_MeshQueue_AddTransparent((rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST) ? MESHQUEUE_SORT_HUD : ((rsurface.entity->flags & RENDER_WORLDOBJECT) ? MESHQUEUE_SORT_SKY : MESHQUEUE_SORT_DISTANCE), center, R_Q1BSP_DrawLight_TransparentCallback, ent, surface - rsurface.modelsurfaces, rsurface.rtlight); } continue; } diff --git a/meshqueue.c b/meshqueue.c index e0e1e8c7..69bb6919 100644 --- a/meshqueue.c +++ b/meshqueue.c @@ -10,15 +10,13 @@ typedef struct meshqueue_s int surfacenumber; const rtlight_t *rtlight; float dist; + meshqueue_sortcategory_t category; } meshqueue_t; int trans_sortarraysize; meshqueue_t **trans_hash = NULL; meshqueue_t ***trans_hashpointer = NULL; -extern cvar_t r_transparent_sortarraysize; -extern cvar_t r_transparent_sortmindist; -extern cvar_t r_transparent_sortmaxdist; float mqt_viewplanedist; float mqt_viewmaxdist; @@ -33,7 +31,7 @@ void R_MeshQueue_BeginScene(void) mqt_viewmaxdist = 0; } -void R_MeshQueue_AddTransparent(const vec3_t center, void (*callback)(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist), const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight) +void R_MeshQueue_AddTransparent(meshqueue_sortcategory_t category, const vec3_t center, void (*callback)(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist), const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight) { meshqueue_t *mq; if (mqt_count >= mqt_total || !mqt_array) @@ -53,10 +51,11 @@ void R_MeshQueue_AddTransparent(const vec3_t center, void (*callback)(const enti mq->ent = ent; mq->surfacenumber = surfacenumber; mq->rtlight = rtlight; - if (ent && (ent->flags & RENDER_WORLDOBJECT)) - mq->dist = mqt_viewmaxdist; - else + mq->category = category; + if (r_transparent_useplanardistance.integer) mq->dist = DotProduct(center, r_refdef.view.forward) - mqt_viewplanedist; + else + mq->dist = VectorDistance(center, r_refdef.view.origin); mq->next = NULL; mqt_viewmaxdist = max(mqt_viewmaxdist, mq->dist); } @@ -102,7 +101,20 @@ void R_MeshQueue_RenderTransparent(void) maxhashindex = trans_sortarraysize - 1; for (i = 0, mqt = mqt_array; i < mqt_count; i++, mqt++) { - hashindex = bound(0, (int)(bound(0, mqt->dist - r_transparent_sortmindist.integer, r_transparent_sortmaxdist.integer) * distscale), maxhashindex); + switch(mqt->category) + { + default: + case MESHQUEUE_SORT_HUD: + hashindex = 0; + break; + case MESHQUEUE_SORT_DISTANCE: + // this could use a reduced range if we need more categories + hashindex = bound(0, (int)(bound(0, mqt->dist - r_transparent_sortmindist.integer, r_transparent_sortmaxdist.integer) * distscale), maxhashindex); + break; + case MESHQUEUE_SORT_SKY: + hashindex = maxhashindex; + break; + } // link to tail of hash chain (to preserve render order) mqt->next = NULL; *trans_hashpointer[hashindex] = mqt; diff --git a/meshqueue.h b/meshqueue.h index f54c4ce3..9a727f30 100644 --- a/meshqueue.h +++ b/meshqueue.h @@ -5,8 +5,16 @@ // VorteX: seems this value is hardcoded in other several defines as it's changing makes mess #define MESHQUEUE_TRANSPARENT_BATCHSIZE 256 +typedef enum meshqueue_sortcategory_e +{ + MESHQUEUE_SORT_SKY, + MESHQUEUE_SORT_DISTANCE, + MESHQUEUE_SORT_HUD, +} +meshqueue_sortcategory_t; + void R_MeshQueue_BeginScene(void); -void R_MeshQueue_AddTransparent(const vec3_t center, void (*callback)(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist), const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight); +void R_MeshQueue_AddTransparent(meshqueue_sortcategory_t category, const vec3_t center, void (*callback)(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist), const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight); void R_MeshQueue_RenderTransparent(void); #endif diff --git a/r_explosion.c b/r_explosion.c index 58f86bc8..b8f8152f 100644 --- a/r_explosion.c +++ b/r_explosion.c @@ -275,7 +275,7 @@ void R_DrawExplosions(void) { R_MoveExplosion(&explosion[i]); if (explosion[i].alpha) - R_MeshQueue_AddTransparent(explosion[i].origin, R_DrawExplosion_TransparentCallback, NULL, i, NULL); + R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, explosion[i].origin, R_DrawExplosion_TransparentCallback, NULL, i, NULL); } } while (numexplosions > 0 && explosion[i-1].alpha <= 0) diff --git a/r_lightning.c b/r_lightning.c index b7975c6c..5ef3ed14 100644 --- a/r_lightning.c +++ b/r_lightning.c @@ -320,7 +320,7 @@ void R_DrawLightningBeams(void) dist = bound(0, dist, 1); VectorLerp(start, dist, end, org); // now we have the nearest point on the line, so sort with it - R_MeshQueue_AddTransparent(org, R_DrawLightningBeam_TransparentCallback, NULL, i, NULL); + R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, org, R_DrawLightningBeam_TransparentCallback, NULL, i, NULL); } } } diff --git a/r_shadow.c b/r_shadow.c index e0b86dda..adec83e1 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -5429,10 +5429,10 @@ void R_Shadow_DrawLightSprites(void) { light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex); if (light) - R_MeshQueue_AddTransparent(light->origin, R_Shadow_DrawLightSprite_TransparentCallback, (entity_render_t *)light, 5, &light->rtlight); + R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, light->origin, R_Shadow_DrawLightSprite_TransparentCallback, (entity_render_t *)light, 5, &light->rtlight); } if (!r_editlights_lockcursor) - R_MeshQueue_AddTransparent(r_editlights_cursorlocation, R_Shadow_DrawCursor_TransparentCallback, NULL, 0, NULL); + R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, r_editlights_cursorlocation, R_Shadow_DrawCursor_TransparentCallback, NULL, 0, NULL); } int R_Shadow_GetRTLightInfo(unsigned int lightindex, float *origin, float *radius, float *color) diff --git a/r_sprites.c b/r_sprites.c index 27338621..9ab013f3 100644 --- a/r_sprites.c +++ b/r_sprites.c @@ -424,6 +424,6 @@ void R_Model_Sprite_Draw(entity_render_t *ent) return; Matrix4x4_OriginFromMatrix(&ent->matrix, org); - R_MeshQueue_AddTransparent(ent->flags & RENDER_NODEPTHTEST ? r_refdef.view.origin : org, R_Model_Sprite_Draw_TransparentCallback, ent, 0, rsurface.rtlight); + R_MeshQueue_AddTransparent((ent->flags & RENDER_NODEPTHTEST) ? MESHQUEUE_SORT_HUD : ((ent->flags & RENDER_WORLDOBJECT) ? MESHQUEUE_SORT_SKY : MESHQUEUE_SORT_DISTANCE), org, R_Model_Sprite_Draw_TransparentCallback, ent, 0, rsurface.rtlight); } diff --git a/render.h b/render.h index e81638ba..c869615a 100644 --- a/render.h +++ b/render.h @@ -534,6 +534,13 @@ extern cvar_t r_shadows_throwdirection; extern cvar_t r_shadows_focus; extern cvar_t r_shadows_shadowmapscale; +extern cvar_t r_transparent_alphatocoverage; +extern cvar_t r_transparent_sortsurfacesbynearest; +extern cvar_t r_transparent_useplanardistance; +extern cvar_t r_transparent_sortarraysize; +extern cvar_t r_transparent_sortmindist; +extern cvar_t r_transparent_sortmaxdist; + void R_Model_Sprite_Draw(entity_render_t *ent); struct prvm_prog_s; -- 2.39.2