]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
added r_transparent_sortsurfacesbynearest cvar (default 1), this
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 9 Nov 2011 03:02:20 +0000 (03:02 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 9 Nov 2011 03:02:20 +0000 (03:02 +0000)
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

12 files changed:
cl_particles.c
clvm_cmds.c
gl_backend.c
gl_rmain.c
gl_rsurf.c
meshqueue.c
meshqueue.h
r_explosion.c
r_lightning.c
r_shadow.c
r_sprites.c
render.h

index b1d891a7df3ed4fd1568684efb95e9eccc476f0b..a11671209ddaa136d9779855aaa6ac588f34acc1 100644 (file)
@@ -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))
                        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;
                continue;
 killdecal:
                decal->typeindex = 0;
@@ -2977,7 +2977,7 @@ void R_DrawParticles (void)
                {
                case pt_beam:
                        // beams have no culling
                {
                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)
                        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))
                                        }
                        // 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;
                }
 
                        break;
                }
 
index 1a6204d17bdbb6b2e65914c5df0d2e745872816e..8d571bfc905437d9f94350600962d7f46aac2b68 100644 (file)
@@ -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);
        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,
        }
 
        /*polys->num_triangles = 0; // now done after rendering the scene,
index c182ad3bb5c305e664b04bd8f00dfebe8d1cb555..8df14f8e1da990268ea13c0e6ca26e9ec5e30ee0 100644 (file)
@@ -1536,8 +1536,6 @@ static int d3dstencilopforglfunc(int f)
 }
 #endif
 
 }
 #endif
 
-extern cvar_t r_transparent_alphatocoverage;
-
 static void GL_Backend_ResetState(void)
 {
        unsigned int i;
 static void GL_Backend_ResetState(void)
 {
        unsigned int i;
index 304c3074169ebbf52faec7934f17dbfe1861421f..6c26b8de7040514c4269c65a585f824a9255e8cf 100644 (file)
@@ -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_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)"};
 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_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);
        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);
                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))
        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);
 }
        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
 }
 
        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;
 {
        // 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];
        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);
                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)
 {
 
 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);
        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)
                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);
        }
                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;
                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)
        {
                // in the deferred case, transparent surfaces were queued during prepass
                if (!r_shadow_usingdeferredprepass)
-                       R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity);
+                       R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist);
        }
        else
        {
        }
        else
        {
@@ -10527,7 +10539,7 @@ static void R_QueueWorldSurfaceList(int numsurfaces, const msurface_t **surfacel
        R_FrameData_ReturnToMark();
 }
 
        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)
 {
        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)
                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);
        }
                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;
                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)
        {
                // in the deferred case, transparent surfaces were queued during prepass
                if (!r_shadow_usingdeferredprepass)
-                       R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity);
+                       R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist);
        }
        else
        {
        }
        else
        {
@@ -10600,7 +10612,7 @@ static void R_QueueModelSurfaceList(entity_render_t *ent, int numsurfaces, const
                                ;
                }
                // render the range of surfaces
                                ;
                }
                // 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();
 }
        }
        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);
        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);
        }
 }
 
        }
 }
 
index 4a9c0a84376978b59d174d435fd593e1f78a6a0f..bc37840189571356248e4155bdcc121cbdcca064 100644 (file)
@@ -393,7 +393,7 @@ void R_DrawPortals(void)
                                                VectorAdd(center, portal->points[i].position, center);
                                        f = ixtable[portal->numpoints];
                                        VectorScale(center, f, center);
                                                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];
                                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);
                                        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;
                        }
                                }
                                continue;
                        }
index e0e1e8c7091c7765783b311010f8da3399a1e3c2..69bb69198e2fcc65406b5e3324f6d855535d831e 100644 (file)
@@ -10,15 +10,13 @@ typedef struct meshqueue_s
        int surfacenumber;
        const rtlight_t *rtlight;
        float dist;
        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;
 }
 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;
 
 float mqt_viewplanedist;
 float mqt_viewmaxdist;
@@ -33,7 +31,7 @@ void R_MeshQueue_BeginScene(void)
        mqt_viewmaxdist = 0;
 }
 
        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)
 {
        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;
        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;
                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);
 }
        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++)
        {
        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;
                // link to tail of hash chain (to preserve render order)
                mqt->next = NULL;
                *trans_hashpointer[hashindex] = mqt;
index f54c4ce39e3e0320d12f2a230ebf4dd38ff39451..9a727f30ff110674d784baa014e11b56a61f4d3f 100644 (file)
@@ -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
 
 // 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_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
 void R_MeshQueue_RenderTransparent(void);
 
 #endif
index 58f86bc83e7797fd1340937494a9538b6fbe605f..b8f8152f89316fd3f2b64708d519130e857a3b96 100644 (file)
@@ -275,7 +275,7 @@ void R_DrawExplosions(void)
                {
                        R_MoveExplosion(&explosion[i]);
                        if (explosion[i].alpha)
                {
                        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)
                }
        }
        while (numexplosions > 0 && explosion[i-1].alpha <= 0)
index b7975c6c01b4281eec6c5d529a418a66e40ebb06..5ef3ed144534841a4e08219a35435f9b65e7175f 100644 (file)
@@ -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
                        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);
                }
        }
 }
                }
        }
 }
index e0b86ddaf8360157f07eca484f7e164ccfc83bcf..adec83e15b337ff8a42e49981fdb8679e53a3be1 100644 (file)
@@ -5429,10 +5429,10 @@ void R_Shadow_DrawLightSprites(void)
        {
                light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
                if (light)
        {
                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)
        }
        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)
 }
 
 int R_Shadow_GetRTLightInfo(unsigned int lightindex, float *origin, float *radius, float *color)
index 27338621ad6199e25e48632356d28bf58745192e..9ab013f31fbd48e2fb8c51a21ea6a5c35803d1cb 100644 (file)
@@ -424,6 +424,6 @@ void R_Model_Sprite_Draw(entity_render_t *ent)
                return;
 
        Matrix4x4_OriginFromMatrix(&ent->matrix, org);
                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);
 }
 
 }
 
index e81638ba88feac71a59c9a91da74f977a598f723..c869615a2fed6362c19e6e2acbe3ce38253bd4c6 100644 (file)
--- 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_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;
 void R_Model_Sprite_Draw(entity_render_t *ent);
 
 struct prvm_prog_s;