]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - r_shadow.c
merged q1bsp and q3bsp surface rendering
[xonotic/darkplaces.git] / r_shadow.c
index 8a82f06411c73ad8e78c3f84dfbf5f9a9c68680b..ee083d246e3d0cf1b8087695f3520796a50febd7 100644 (file)
@@ -154,11 +154,7 @@ rtexturepool_t *r_shadow_texturepool;
 rtexture_t *r_shadow_normalcubetexture;
 rtexture_t *r_shadow_attenuation2dtexture;
 rtexture_t *r_shadow_attenuation3dtexture;
-rtexture_t *r_shadow_blankbumptexture;
-rtexture_t *r_shadow_blankglosstexture;
-rtexture_t *r_shadow_blankwhitetexture;
 rtexture_t *r_shadow_blankwhitecubetexture;
-rtexture_t *r_shadow_blankblacktexture;
 
 // lights are reloaded when this changes
 char r_shadow_mapname[MAX_QPATH];
@@ -394,11 +390,7 @@ void r_shadow_start(void)
        r_shadow_normalcubetexture = NULL;
        r_shadow_attenuation2dtexture = NULL;
        r_shadow_attenuation3dtexture = NULL;
-       r_shadow_blankbumptexture = NULL;
-       r_shadow_blankglosstexture = NULL;
-       r_shadow_blankwhitetexture = NULL;
        r_shadow_blankwhitecubetexture = NULL;
-       r_shadow_blankblacktexture = NULL;
        r_shadow_texturepool = NULL;
        r_shadow_filters_texturepool = NULL;
        R_Shadow_ValidateCvars();
@@ -503,11 +495,7 @@ void r_shadow_shutdown(void)
        r_shadow_normalcubetexture = NULL;
        r_shadow_attenuation2dtexture = NULL;
        r_shadow_attenuation3dtexture = NULL;
-       r_shadow_blankbumptexture = NULL;
-       r_shadow_blankglosstexture = NULL;
-       r_shadow_blankwhitetexture = NULL;
        r_shadow_blankwhitecubetexture = NULL;
-       r_shadow_blankblacktexture = NULL;
        R_FreeTexturePool(&r_shadow_texturepool);
        R_FreeTexturePool(&r_shadow_filters_texturepool);
        maxshadowelements = 0;
@@ -738,10 +726,10 @@ void R_Shadow_PrepareShadowMark(int numtris)
 
 int R_Shadow_ConstructShadowVolume(int innumvertices, int innumtris, const int *inelement3i, const int *inneighbor3i, const float *invertex3f, int *outnumvertices, int *outelement3i, float *outvertex3f, const float *projectorigin, float projectdistance, int numshadowmarktris, const int *shadowmarktris)
 {
-       int i, j, tris = 0, vr[3], t, outvertices = 0;
-       float f, temp[3];
-       const int *e, *n;
-       const float *v;
+       int i, j;
+       int outtriangles = 0, outvertices = 0;
+       const int *element;
+       const float *vertex;
 
        if (maxvertexupdate < innumvertices)
        {
@@ -767,22 +755,22 @@ int R_Shadow_ConstructShadowVolume(int innumvertices, int innumtris, const int *
 
        for (i = 0;i < numshadowmarktris;i++)
        {
-               t = shadowmarktris[i];
-               e = inelement3i + t * 3;
+               element = inelement3i + shadowmarktris[i] * 3;
                // make sure the vertices are created
                for (j = 0;j < 3;j++)
                {
-                       if (vertexupdate[e[j]] != vertexupdatenum)
+                       if (vertexupdate[element[j]] != vertexupdatenum)
                        {
-                               vertexupdate[e[j]] = vertexupdatenum;
-                               vertexremap[e[j]] = outvertices;
-                               v = invertex3f + e[j] * 3;
+                               float ratio, direction[3];
+                               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(v, projectorigin, temp);
-                               f = projectdistance / VectorLength(temp);
-                               VectorCopy(v, outvertex3f);
-                               VectorMA(projectorigin, f, temp, (outvertex3f + 3));
+                               VectorSubtract(vertex, projectorigin, direction);
+                               ratio = projectdistance / VectorLength(direction);
+                               VectorCopy(vertex, outvertex3f);
+                               VectorMA(projectorigin, ratio, direction, (outvertex3f + 3));
                                outvertex3f += 6;
                                outvertices += 2;
                        }
@@ -791,62 +779,70 @@ int R_Shadow_ConstructShadowVolume(int innumvertices, int innumtris, const int *
 
        for (i = 0;i < numshadowmarktris;i++)
        {
-               t = shadowmarktris[i];
-               e = inelement3i + t * 3;
-               n = inneighbor3i + t * 3;
+               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[e[0]];
-               outelement3i[1] = vertexremap[e[1]];
-               outelement3i[2] = vertexremap[e[2]];
-               outelement3i[3] = vertexremap[e[2]] + 1;
-               outelement3i[4] = vertexremap[e[1]] + 1;
-               outelement3i[5] = vertexremap[e[0]] + 1;
+               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;
-               tris += 2;
+               outtriangles += 2;
                // output the sides (facing outward from this triangle)
-               if (shadowmark[n[0]] != shadowmarkcount)
+               if (shadowmark[neighbortriangle[0]] != shadowmarkcount)
                {
-                       vr[0] = vertexremap[e[0]];
-                       vr[1] = vertexremap[e[1]];
-                       outelement3i[0] = vr[1];
-                       outelement3i[1] = vr[0];
-                       outelement3i[2] = vr[0] + 1;
-                       outelement3i[3] = vr[1];
-                       outelement3i[4] = vr[0] + 1;
-                       outelement3i[5] = vr[1] + 1;
+                       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;
-                       tris += 2;
+                       outtriangles += 2;
                }
-               if (shadowmark[n[1]] != shadowmarkcount)
+               if (shadowmark[neighbortriangle[1]] != shadowmarkcount)
                {
-                       vr[1] = vertexremap[e[1]];
-                       vr[2] = vertexremap[e[2]];
-                       outelement3i[0] = vr[2];
-                       outelement3i[1] = vr[1];
-                       outelement3i[2] = vr[1] + 1;
-                       outelement3i[3] = vr[2];
-                       outelement3i[4] = vr[1] + 1;
-                       outelement3i[5] = vr[2] + 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;
-                       tris += 2;
+                       outtriangles += 2;
                }
-               if (shadowmark[n[2]] != shadowmarkcount)
+               if (shadowmark[neighbortriangle[2]] != shadowmarkcount)
                {
-                       vr[0] = vertexremap[e[0]];
-                       vr[2] = vertexremap[e[2]];
-                       outelement3i[0] = vr[0];
-                       outelement3i[1] = vr[2];
-                       outelement3i[2] = vr[2] + 1;
-                       outelement3i[3] = vr[0];
-                       outelement3i[4] = vr[2] + 1;
-                       outelement3i[5] = vr[0] + 1;
+                       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;
-                       tris += 2;
+                       outtriangles += 2;
                }
        }
        if (outnumvertices)
                *outnumvertices = outvertices;
-       return tris;
+       return outtriangles;
 }
 
 void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f, const int *elements, const int *neighbors, const vec3_t projectorigin, float projectdistance, int nummarktris, const int *marktris)
@@ -866,7 +862,7 @@ void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f,
        R_Shadow_RenderVolume(outverts, tris, varray_vertex3f2, shadowelements);
 }
 
-void R_Shadow_MarkVolumeFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const vec3_t projectorigin, vec3_t lightmins, vec3_t lightmaxs, vec3_t surfacemins, vec3_t surfacemaxs)
+void R_Shadow_MarkVolumeFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const vec3_t projectorigin, const vec3_t lightmins, const vec3_t lightmaxs, const vec3_t surfacemins, const vec3_t surfacemaxs)
 {
        int t, tend;
        const int *e;
@@ -947,26 +943,6 @@ static void R_Shadow_MakeTextures(void)
 #define ATTEN2DSIZE 64
 #define ATTEN3DSIZE 32
        data = Mem_Alloc(tempmempool, max(6*NORMSIZE*NORMSIZE*4, max(ATTEN3DSIZE*ATTEN3DSIZE*ATTEN3DSIZE*4, ATTEN2DSIZE*ATTEN2DSIZE*4)));
-       data[0] = 128; // normal X
-       data[1] = 128; // normal Y
-       data[2] = 255; // normal Z
-       data[3] = 128; // height
-       r_shadow_blankbumptexture = R_LoadTexture2D(r_shadow_texturepool, "blankbump", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
-       data[0] = 255;
-       data[1] = 255;
-       data[2] = 255;
-       data[3] = 255;
-       r_shadow_blankglosstexture = R_LoadTexture2D(r_shadow_texturepool, "blankgloss", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
-       data[0] = 255;
-       data[1] = 255;
-       data[2] = 255;
-       data[3] = 255;
-       r_shadow_blankwhitetexture = R_LoadTexture2D(r_shadow_texturepool, "blankwhite", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
-       data[0] = 0;
-       data[1] = 0;
-       data[2] = 0;
-       data[3] = 255;
-       r_shadow_blankblacktexture = R_LoadTexture2D(r_shadow_texturepool, "blankblack", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
        r_shadow_blankwhitecubetexture = NULL;
        r_shadow_normalcubetexture = NULL;
        if (gl_texturecubemap)
@@ -1585,18 +1561,18 @@ void R_Shadow_RenderLighting(int numverts, int numtriangles, const int *elements
        GL_DepthMask(false);
        GL_DepthTest(true);
        if (!bumptexture)
-               bumptexture = r_shadow_blankbumptexture;
+               bumptexture = r_texture_blanknormalmap;
        specularscale *= r_shadow_glossintensity.value;
        if (!glosstexture)
        {
                if (r_shadow_gloss.integer >= 2)
                {
-                       glosstexture = r_shadow_blankglosstexture;
+                       glosstexture = r_texture_white;
                        specularscale *= r_shadow_gloss2intensity.value;
                }
                else
                {
-                       glosstexture = r_shadow_blankblacktexture;
+                       glosstexture = r_texture_black;
                        specularscale = 0;
                }
        }
@@ -1621,7 +1597,7 @@ void R_Shadow_RenderLighting(int numverts, int numtriangles, const int *elements
                m.tex[2] = R_GetTexture(glosstexture);
                m.texcubemap[3] = R_GetTexture(lightcubemap);
                // TODO: support fog (after renderer is converted to texture fog)
-               m.tex[4] = R_GetTexture(r_shadow_blankwhitetexture);
+               m.tex[4] = R_GetTexture(r_texture_white);
                m.texmatrix[3] = *matrix_modeltolight;
                R_Mesh_State(&m);
                GL_BlendFunc(GL_ONE, GL_ONE);
@@ -1679,9 +1655,9 @@ void R_Shadow_RenderLighting(int numverts, int numtriangles, const int *elements
        else if (gl_dot3arb && gl_texturecubemap && gl_combine.integer && gl_stencil)
        {
                if (!bumptexture)
-                       bumptexture = r_shadow_blankbumptexture;
+                       bumptexture = r_texture_blanknormalmap;
                if (!glosstexture)
-                       glosstexture = r_shadow_blankglosstexture;
+                       glosstexture = r_texture_white;
                if (ambientscale)
                {
                        GL_Color(1,1,1,1);
@@ -2137,7 +2113,7 @@ void R_Shadow_RenderLighting(int numverts, int numtriangles, const int *elements
                        }
                        GL_LockArrays(0, 0);
                }
-               if (specularscale && glosstexture != r_shadow_blankblacktexture)
+               if (specularscale && glosstexture != r_texture_black)
                {
                        // FIXME: detect blendsquare!
                        //if (gl_support_blendsquare)
@@ -2533,8 +2509,8 @@ void R_RTLight_UpdateFromDLight(rtlight_t *rtlight, const dlight_t *light, int i
 void R_RTLight_Compile(rtlight_t *rtlight)
 {
        int shadowmeshes, shadowtris, lightmeshes, lighttris, numclusters, numsurfaces;
-       entity_render_t *ent = &cl_entities[0].render;
-       model_t *model = ent->model;
+       entity_render_t *ent = r_refdef.worldentity;
+       model_t *model = r_refdef.worldmodel;
 
        // compile the light
        rtlight->compiled = true;
@@ -2568,7 +2544,7 @@ void R_RTLight_Compile(rtlight_t *rtlight)
                if (model->DrawShadowVolume && rtlight->shadow)
                {
                        rtlight->static_meshchain_shadow = Mod_ShadowMesh_Begin(r_shadow_mempool, 32768, 32768, NULL, NULL, NULL, false, false, true);
-                       model->DrawShadowVolume(ent, rtlight->shadoworigin, rtlight->radius, numsurfaces, r_shadow_buffer_surfacelist);
+                       model->DrawShadowVolume(ent, rtlight->shadoworigin, rtlight->radius, numsurfaces, r_shadow_buffer_surfacelist, rtlight->cullmins, rtlight->cullmaxs);
                        rtlight->static_meshchain_shadow = Mod_ShadowMesh_Finish(r_shadow_mempool, rtlight->static_meshchain_shadow, false, false);
                }
                if (model->DrawLight)
@@ -2653,7 +2629,7 @@ void R_DrawRTLight(rtlight_t *rtlight, int visiblevolumes)
        int numclusters, numsurfaces;
        int *clusterlist, *surfacelist;
        qbyte *clusterpvs;
-       vec3_t cullmins, cullmaxs;
+       vec3_t cullmins, cullmaxs, relativelightmins, relativelightmaxs;
        shadowmesh_t *mesh;
        rmeshstate_t m;
 
@@ -2727,7 +2703,7 @@ void R_DrawRTLight(rtlight_t *rtlight, int visiblevolumes)
        if (numclusters)
        {
                for (i = 0;i < numclusters;i++)
-                       if (r_worldleafvisible[clusterlist[i]])
+                       if (CHECKPVSBIT(r_pvsbits, clusterlist[i]))
                                break;
                if (i == numclusters)
                        return;
@@ -2777,7 +2753,7 @@ void R_DrawRTLight(rtlight_t *rtlight, int visiblevolumes)
                else if (numsurfaces)
                {
                        Matrix4x4_Transform(&ent->inversematrix, rtlight->shadoworigin, relativelightorigin);
-                       ent->model->DrawShadowVolume(ent, relativelightorigin, rtlight->radius, numsurfaces, surfacelist);
+                       ent->model->DrawShadowVolume(ent, relativelightorigin, rtlight->radius, numsurfaces, surfacelist, rtlight->cullmins, rtlight->cullmaxs);
                }
                if (r_drawentities.integer)
                {
@@ -2798,7 +2774,13 @@ void R_DrawRTLight(rtlight_t *rtlight, int visiblevolumes)
                                // light emitting entities should not cast their own shadow
                                if (VectorLength2(relativelightorigin) < 0.1)
                                        continue;
-                               ent->model->DrawShadowVolume(ent, relativelightorigin, rtlight->radius, ent->model->nummodelsurfaces, ent->model->surfacelist);
+                               relativelightmins[0] = relativelightorigin[0] - rtlight->radius;
+                               relativelightmins[1] = relativelightorigin[1] - rtlight->radius;
+                               relativelightmins[2] = relativelightorigin[2] - rtlight->radius;
+                               relativelightmaxs[0] = relativelightorigin[0] + rtlight->radius;
+                               relativelightmaxs[1] = relativelightorigin[1] + rtlight->radius;
+                               relativelightmaxs[2] = relativelightorigin[2] + rtlight->radius;
+                               ent->model->DrawShadowVolume(ent, relativelightorigin, rtlight->radius, ent->model->nummodelsurfaces, ent->model->surfacelist, relativelightmins, relativelightmaxs);
                        }
                }
        }