]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rsurf.c
reworked transparent sorting of MATERIALFLAG_BLENDED to not sort water
[xonotic/darkplaces.git] / gl_rsurf.c
index b333d16f4a70361b9ad3cf7dd063df6f92a2f676..3dad14f3aefc2cc9e29bc85d6917f6255c87b202 100644 (file)
@@ -88,7 +88,7 @@ void R_BuildLightMap (const entity_render_t *ent, msurface_t *surface)
 // add all the lightmaps
                if (lightmap)
                        for (maps = 0;maps < MAXLIGHTMAPS && surface->lightmapinfo->styles[maps] != 255;maps++, lightmap += size3)
-                               for (scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[maps]], i = 0;i < size3;i++)
+                               for (scale = r_refdef.scene.lightstylevalue[surface->lightmapinfo->styles[maps]], i = 0;i < size3;i++)
                                        bl[i] += lightmap[i] * scale;
        }
 
@@ -123,7 +123,7 @@ void R_BuildLightMap (const entity_render_t *ent, msurface_t *surface)
                {
                        for (maps = 0;maps < MAXLIGHTMAPS && surface->lightmapinfo->styles[maps] != 255;maps++, lightmap += size3, normalmap += size3)
                        {
-                               for (scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[maps]], i = 0;i < size;i++)
+                               for (scale = r_refdef.scene.lightstylevalue[surface->lightmapinfo->styles[maps]], i = 0;i < size;i++)
                                {
                                        // add the normalmap with weighting proportional to the style's lightmap intensity
                                        l = (int)(VectorLength(lightmap + i*3) * scale);
@@ -278,7 +278,7 @@ void R_Stain (const vec3_t origin, float radius, int cr1, int cg1, int cb1, int
        entity_render_t *ent;
        model_t *model;
        vec3_t org;
-       if (r_refdef.worldmodel == NULL || !r_refdef.worldmodel->brush.data_nodes || !r_refdef.worldmodel->brushq1.lightdata)
+       if (r_refdef.scene.worldmodel == NULL || !r_refdef.scene.worldmodel->brush.data_nodes || !r_refdef.scene.worldmodel->brushq1.lightdata)
                return;
        fcolor[0] = cr1;
        fcolor[1] = cg1;
@@ -289,7 +289,7 @@ void R_Stain (const vec3_t origin, float radius, int cr1, int cg1, int cb1, int
        fcolor[6] = cb2 - cb1;
        fcolor[7] = (ca2 - ca1) * (1.0f / 64.0f);
 
-       R_StainNode(r_refdef.worldmodel->brush.data_nodes + r_refdef.worldmodel->brushq1.hulls[0].firstclipnode, r_refdef.worldmodel, origin, radius, fcolor);
+       R_StainNode(r_refdef.scene.worldmodel->brush.data_nodes + r_refdef.scene.worldmodel->brushq1.hulls[0].firstclipnode, r_refdef.scene.worldmodel, origin, radius, fcolor);
 
        // look for embedded bmodels
        for (n = 0;n < cl.num_brushmodel_entities;n++)
@@ -341,9 +341,9 @@ static void R_DrawPortal_Callback(const entity_render_t *ent, const rtlight_t *r
        R_Mesh_ResetTextureState();
 
        i = surfacelist[0];
-       GL_Color(((i & 0x0007) >> 0) * (1.0f / 7.0f) * r_view.colorscale,
-                        ((i & 0x0038) >> 3) * (1.0f / 7.0f) * r_view.colorscale,
-                        ((i & 0x01C0) >> 6) * (1.0f / 7.0f) * r_view.colorscale,
+       GL_Color(((i & 0x0007) >> 0) * (1.0f / 7.0f) * r_refdef.view.colorscale,
+                        ((i & 0x0038) >> 3) * (1.0f / 7.0f) * r_refdef.view.colorscale,
+                        ((i & 0x01C0) >> 6) * (1.0f / 7.0f) * r_refdef.view.colorscale,
                         0.125f);
        for (i = 0, v = vertex3f;i < numpoints;i++, v += 3)
                VectorCopy(portal->points[i].position, v);
@@ -356,15 +356,15 @@ void R_DrawPortals(void)
        int i, leafnum;
        mportal_t *portal;
        float center[3], f;
-       model_t *model = r_refdef.worldmodel;
+       model_t *model = r_refdef.scene.worldmodel;
        if (model == NULL)
                return;
-       for (leafnum = 0;leafnum < r_refdef.worldmodel->brush.num_leafs;leafnum++)
+       for (leafnum = 0;leafnum < r_refdef.scene.worldmodel->brush.num_leafs;leafnum++)
        {
-               if (r_viewcache.world_leafvisible[leafnum])
+               if (r_refdef.viewcache.world_leafvisible[leafnum])
                {
                        //for (portalnum = 0, portal = model->brush.data_portals;portalnum < model->brush.num_portals;portalnum++, portal++)
-                       for (portal = r_refdef.worldmodel->brush.data_leafs[leafnum].portals;portal;portal = portal->next)
+                       for (portal = r_refdef.scene.worldmodel->brush.data_leafs[leafnum].portals;portal;portal = portal->next)
                        {
                                if (portal->numpoints <= POLYGONELEMENTS_MAXPOINTS)
                                if (!R_CullBox(portal->mins, portal->maxs))
@@ -386,47 +386,47 @@ void R_View_WorldVisibility(qboolean forcenovis)
        int i, j, *mark;
        mleaf_t *leaf;
        mleaf_t *viewleaf;
-       model_t *model = r_refdef.worldmodel;
+       model_t *model = r_refdef.scene.worldmodel;
 
        if (!model)
                return;
 
-       if (r_view.usecustompvs)
+       if (r_refdef.view.usecustompvs)
        {
                // clear the visible surface and leaf flags arrays
-               memset(r_viewcache.world_surfacevisible, 0, model->num_surfaces);
-               memset(r_viewcache.world_leafvisible, 0, model->brush.num_leafs);
-               r_viewcache.world_novis = false;
+               memset(r_refdef.viewcache.world_surfacevisible, 0, model->num_surfaces);
+               memset(r_refdef.viewcache.world_leafvisible, 0, model->brush.num_leafs);
+               r_refdef.viewcache.world_novis = false;
 
                // simply cull each marked leaf to the frustum (view pyramid)
                for (j = 0, leaf = model->brush.data_leafs;j < model->brush.num_leafs;j++, leaf++)
                {
                        // if leaf is in current pvs and on the screen, mark its surfaces
-                       if (CHECKPVSBIT(r_viewcache.world_pvsbits, leaf->clusterindex) && !R_CullBox(leaf->mins, leaf->maxs))
+                       if (CHECKPVSBIT(r_refdef.viewcache.world_pvsbits, leaf->clusterindex) && !R_CullBox(leaf->mins, leaf->maxs))
                        {
                                r_refdef.stats.world_leafs++;
-                               r_viewcache.world_leafvisible[j] = true;
+                               r_refdef.viewcache.world_leafvisible[j] = true;
                                if (leaf->numleafsurfaces)
                                        for (i = 0, mark = leaf->firstleafsurface;i < leaf->numleafsurfaces;i++, mark++)
-                                               r_viewcache.world_surfacevisible[*mark] = true;
+                                               r_refdef.viewcache.world_surfacevisible[*mark] = true;
                        }
                }
                return;
        }
 
        // if possible find the leaf the view origin is in
-       viewleaf = model->brush.PointInLeaf ? model->brush.PointInLeaf(model, r_view.origin) : NULL;
+       viewleaf = model->brush.PointInLeaf ? model->brush.PointInLeaf(model, r_refdef.view.origin) : NULL;
        // if possible fetch the visible cluster bits
        if (!r_lockpvs.integer && model->brush.FatPVS)
-               model->brush.FatPVS(model, r_view.origin, 2, r_viewcache.world_pvsbits, sizeof(r_viewcache.world_pvsbits), false);
+               model->brush.FatPVS(model, r_refdef.view.origin, 2, r_refdef.viewcache.world_pvsbits, sizeof(r_refdef.viewcache.world_pvsbits), false);
 
        if (!r_lockvisibility.integer)
        {
                // clear the visible surface and leaf flags arrays
-               memset(r_viewcache.world_surfacevisible, 0, model->num_surfaces);
-               memset(r_viewcache.world_leafvisible, 0, model->brush.num_leafs);
+               memset(r_refdef.viewcache.world_surfacevisible, 0, model->num_surfaces);
+               memset(r_refdef.viewcache.world_leafvisible, 0, model->brush.num_leafs);
 
-               r_viewcache.world_novis = false;
+               r_refdef.viewcache.world_novis = false;
 
                // if floating around in the void (no pvs data available, and no
                // portals available), simply use all on-screen leafs.
@@ -435,17 +435,17 @@ void R_View_WorldVisibility(qboolean forcenovis)
                        // no visibility method: (used when floating around in the void)
                        // simply cull each leaf to the frustum (view pyramid)
                        // similar to quake's RecursiveWorldNode but without cache misses
-                       r_viewcache.world_novis = true;
+                       r_refdef.viewcache.world_novis = true;
                        for (j = 0, leaf = model->brush.data_leafs;j < model->brush.num_leafs;j++, leaf++)
                        {
                                // if leaf is in current pvs and on the screen, mark its surfaces
                                if (!R_CullBox(leaf->mins, leaf->maxs))
                                {
                                        r_refdef.stats.world_leafs++;
-                                       r_viewcache.world_leafvisible[j] = true;
+                                       r_refdef.viewcache.world_leafvisible[j] = true;
                                        if (leaf->numleafsurfaces)
                                                for (i = 0, mark = leaf->firstleafsurface;i < leaf->numleafsurfaces;i++, mark++)
-                                                       r_viewcache.world_surfacevisible[*mark] = true;
+                                                       r_refdef.viewcache.world_surfacevisible[*mark] = true;
                                }
                        }
                }
@@ -460,13 +460,13 @@ void R_View_WorldVisibility(qboolean forcenovis)
                        for (j = 0, leaf = model->brush.data_leafs;j < model->brush.num_leafs;j++, leaf++)
                        {
                                // if leaf is in current pvs and on the screen, mark its surfaces
-                               if (CHECKPVSBIT(r_viewcache.world_pvsbits, leaf->clusterindex) && !R_CullBox(leaf->mins, leaf->maxs))
+                               if (CHECKPVSBIT(r_refdef.viewcache.world_pvsbits, leaf->clusterindex) && !R_CullBox(leaf->mins, leaf->maxs))
                                {
                                        r_refdef.stats.world_leafs++;
-                                       r_viewcache.world_leafvisible[j] = true;
+                                       r_refdef.viewcache.world_leafvisible[j] = true;
                                        if (leaf->numleafsurfaces)
                                                for (i = 0, mark = leaf->firstleafsurface;i < leaf->numleafsurfaces;i++, mark++)
-                                                       r_viewcache.world_surfacevisible[*mark] = true;
+                                                       r_refdef.viewcache.world_surfacevisible[*mark] = true;
                                }
                        }
                }
@@ -489,14 +489,14 @@ void R_View_WorldVisibility(qboolean forcenovis)
                        while (leafstackpos)
                        {
                                leaf = leafstack[--leafstackpos];
-                               if (r_viewcache.world_leafvisible[leaf - model->brush.data_leafs])
+                               if (r_refdef.viewcache.world_leafvisible[leaf - model->brush.data_leafs])
                                        continue;
                                r_refdef.stats.world_leafs++;
-                               r_viewcache.world_leafvisible[leaf - model->brush.data_leafs] = true;
+                               r_refdef.viewcache.world_leafvisible[leaf - model->brush.data_leafs] = true;
                                // mark any surfaces bounding this leaf
                                if (leaf->numleafsurfaces)
                                        for (i = 0, mark = leaf->firstleafsurface;i < leaf->numleafsurfaces;i++, mark++)
-                                               r_viewcache.world_surfacevisible[*mark] = true;
+                                               r_refdef.viewcache.world_surfacevisible[*mark] = true;
                                // follow portals into other leafs
                                // the checks are:
                                // if viewer is behind portal (portal faces outward into the scene)
@@ -507,9 +507,9 @@ void R_View_WorldVisibility(qboolean forcenovis)
                                for (p = leaf->portals;p;p = p->next)
                                {
                                        r_refdef.stats.world_portals++;
-                                       if (DotProduct(r_view.origin, p->plane.normal) < (p->plane.dist + 1)
-                                        && !r_viewcache.world_leafvisible[p->past - model->brush.data_leafs]
-                                        && CHECKPVSBIT(r_viewcache.world_pvsbits, p->past->clusterindex)
+                                       if (DotProduct(r_refdef.view.origin, p->plane.normal) < (p->plane.dist + 1)
+                                        && !r_refdef.viewcache.world_leafvisible[p->past - model->brush.data_leafs]
+                                        && CHECKPVSBIT(r_refdef.viewcache.world_pvsbits, p->past->clusterindex)
                                         && !R_CullBox(p->mins, p->maxs)
                                         && leafstackpos < (int)(sizeof(leafstack) / sizeof(leafstack[0])))
                                                leafstack[leafstackpos++] = p->past;
@@ -523,7 +523,7 @@ void R_Q1BSP_DrawSky(entity_render_t *ent)
 {
        if (ent->model == NULL)
                return;
-       if (ent == r_refdef.worldentity)
+       if (ent == r_refdef.scene.worldentity)
                R_DrawWorldSurfaces(true, true, false, false, false);
        else
                R_DrawModelSurfaces(ent, true, true, false, false, false);
@@ -534,7 +534,7 @@ void R_Q1BSP_DrawAddWaterPlanes(entity_render_t *ent)
        model_t *model = ent->model;
        if (model == NULL)
                return;
-       if (ent == r_refdef.worldentity)
+       if (ent == r_refdef.scene.worldentity)
                R_DrawWorldSurfaces(false, false, false, true, false);
        else
                R_DrawModelSurfaces(ent, false, false, false, true, false);
@@ -545,7 +545,7 @@ void R_Q1BSP_Draw(entity_render_t *ent)
        model_t *model = ent->model;
        if (model == NULL)
                return;
-       if (ent == r_refdef.worldentity)
+       if (ent == r_refdef.scene.worldentity)
                R_DrawWorldSurfaces(false, true, false, false, false);
        else
                R_DrawModelSurfaces(ent, false, true, false, false, false);
@@ -556,7 +556,7 @@ void R_Q1BSP_DrawDepth(entity_render_t *ent)
        model_t *model = ent->model;
        if (model == NULL)
                return;
-       if (ent == r_refdef.worldentity)
+       if (ent == r_refdef.scene.worldentity)
                R_DrawWorldSurfaces(false, false, true, false, false);
        else
                R_DrawModelSurfaces(ent, false, false, true, false, false);
@@ -566,7 +566,7 @@ void R_Q1BSP_DrawDebug(entity_render_t *ent)
 {
        if (ent->model == NULL)
                return;
-       if (ent == r_refdef.worldentity)
+       if (ent == r_refdef.scene.worldentity)
                R_DrawWorldSurfaces(false, false, false, false, true);
        else
                R_DrawModelSurfaces(ent, false, false, false, false, true);
@@ -1029,7 +1029,7 @@ static void R_Q1BSP_DrawLight_TransparentCallback(const entity_render_t *ent, co
        R_Shadow_RenderMode_End();
 }
 
-#define RSURF_MAX_BATCHSURFACES 1024
+#define RSURF_MAX_BATCHSURFACES 8192
 
 void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surfacelist, const unsigned char *trispvs)
 {
@@ -1042,9 +1042,7 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surface
        int batchelements[BATCHSIZE*3];
        texture_t *tex;
        CHECKGLERROR
-       RSurf_ActiveModelEntity(ent, true, true);
        R_UpdateAllTextureInfo(ent);
-       CHECKGLERROR
        culltriangles = r_shadow_culltriangles.integer && !(ent->flags & RENDER_NOSELFSHADOW);
        element3i = rsurface.modelelement3i;
        // this is a double loop because non-visible surface skipping has to be
@@ -1055,10 +1053,10 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surface
        {
                batchnumsurfaces = 0;
                endsurface = min(i + RSURF_MAX_BATCHSURFACES, numsurfaces);
-               if (ent == r_refdef.worldentity)
+               if (ent == r_refdef.scene.worldentity)
                {
                        for (;i < endsurface;i++)
-                               if (r_viewcache.world_surfacevisible[surfacelist[i]])
+                               if (r_refdef.viewcache.world_surfacevisible[surfacelist[i]])
                                        batchsurfacelist[batchnumsurfaces++] = model->data_surfaces + surfacelist[i];
                }
                else
@@ -1079,7 +1077,7 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surface
                        // now figure out what to do with this particular range of surfaces
                        if (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WALL | MATERIALFLAG_WATER))
                        {
-                               if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
+                               if (rsurface.texture->currentmaterialflags & MATERIALFLAG_SORTTRANSPARENT)
                                {
                                        vec3_t tempcenter, center;
                                        for (l = k;l < kend;l++)
@@ -1089,7 +1087,7 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surface
                                                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_view.origin : center, R_Q1BSP_DrawLight_TransparentCallback, ent, surface - rsurface.modelsurfaces, rsurface.rtlight);
+                                               R_MeshQueue_AddTransparent(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_refdef.view.origin : center, R_Q1BSP_DrawLight_TransparentCallback, ent, surface - rsurface.modelsurfaces, rsurface.rtlight);
                                        }
                                }
                                else
@@ -1161,12 +1159,12 @@ void R_ReplaceWorldTexture (void)
        int                     i;
        const char      *r, *newt;
        skinframe_t *skinframe;
-       if (!r_refdef.worldmodel)
+       if (!r_refdef.scene.worldmodel)
        {
                Con_Printf("There is no worldmodel\n");
                return;
        }
-       m = r_refdef.worldmodel;
+       m = r_refdef.scene.worldmodel;
 
        if(Cmd_Argc() < 2)
        {
@@ -1209,12 +1207,12 @@ void R_ListWorldTextures (void)
        model_t         *m;
        texture_t       *t;
        int                     i;
-       if (!r_refdef.worldmodel)
+       if (!r_refdef.scene.worldmodel)
        {
                Con_Printf("There is no worldmodel\n");
                return;
        }
-       m = r_refdef.worldmodel;
+       m = r_refdef.scene.worldmodel;
 
        Con_Print("Worldmodel textures :\n");
        for(i=0,t=m->data_textures;i<m->num_textures;i++,t++)