]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - r_shadow.c
patch from VorteX that makes GAME_DELUXEQUAKE mode reset a cvar in the
[xonotic/darkplaces.git] / r_shadow.c
index 03fa453dd9b7690c0709bd2b2961ff209aab9d7b..ff0816091d9033f816298a50c6997312327fc9b3 100644 (file)
@@ -895,11 +895,11 @@ void R_Shadow_RenderVolume(int numvertices, int numtriangles, const float *verte
        if (r_shadow_rendermode == R_SHADOW_RENDERMODE_STENCIL)
        {
                // decrement stencil if backface is behind depthbuffer
-               GL_CullFace(GL_BACK); // quake is backwards, this culls front faces
+               GL_CullFace(r_view.cullface_front);
                qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);CHECKGLERROR
                R_Mesh_Draw(0, numvertices, numtriangles, element3i, 0, 0);
                // increment stencil if frontface is behind depthbuffer
-               GL_CullFace(GL_FRONT); // quake is backwards, this culls back faces
+               GL_CullFace(r_view.cullface_back);
                qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR
        }
        R_Mesh_Draw(0, numvertices, numtriangles, element3i, 0, 0);
@@ -907,27 +907,24 @@ void R_Shadow_RenderVolume(int numvertices, int numtriangles, const float *verte
        CHECKGLERROR
 }
 
-static unsigned char R_Shadow_MakeTextures_SamplePoint(float x, float y, float z)
+static unsigned int R_Shadow_MakeTextures_SamplePoint(float x, float y, float z)
 {
        float dist = sqrt(x*x+y*y+z*z);
        float intensity = dist < 1 ? ((1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist)) : 0;
-       return (unsigned char)bound(0, intensity * 256.0f, 255);
+       // note this code could suffer byte order issues except that it is multiplying by an integer that reads the same both ways
+       return (unsigned char)bound(0, intensity * 256.0f, 255) * 0x01010101;
 }
 
 static void R_Shadow_MakeTextures(void)
 {
        int x, y, z;
        float intensity, dist;
-       unsigned char *data;
-       unsigned int palette[256];
+       unsigned int *data;
        R_FreeTexturePool(&r_shadow_texturepool);
        r_shadow_texturepool = R_AllocTexturePool();
        r_shadow_attenlinearscale = r_shadow_lightattenuationlinearscale.value;
        r_shadow_attendividebias = r_shadow_lightattenuationdividebias.value;
-       // note this code could suffer byte order issues except that it is multiplying by an integer that reads the same both ways
-       for (x = 0;x < 256;x++)
-               palette[x] = x * 0x01010101;
-       data = (unsigned char *)Mem_Alloc(tempmempool, max(max(ATTEN3DSIZE*ATTEN3DSIZE*ATTEN3DSIZE, ATTEN2DSIZE*ATTEN2DSIZE), ATTEN1DSIZE));
+       data = (unsigned int *)Mem_Alloc(tempmempool, max(max(ATTEN3DSIZE*ATTEN3DSIZE*ATTEN3DSIZE, ATTEN2DSIZE*ATTEN2DSIZE), ATTEN1DSIZE) * 4);
        // the table includes one additional value to avoid the need to clamp indexing due to minor math errors
        for (x = 0;x <= ATTENTABLESIZE;x++)
        {
@@ -938,12 +935,12 @@ static void R_Shadow_MakeTextures(void)
        // 1D gradient texture
        for (x = 0;x < ATTEN1DSIZE;x++)
                data[x] = R_Shadow_MakeTextures_SamplePoint((x + 0.5f) * (1.0f / ATTEN1DSIZE) * (1.0f / 0.9375), 0, 0);
-       r_shadow_attenuationgradienttexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation1d", ATTEN1DSIZE, 1, data, TEXTYPE_PALETTE, TEXF_PRECACHE | TEXF_CLAMP | TEXF_ALPHA, palette);
+       r_shadow_attenuationgradienttexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation1d", ATTEN1DSIZE, 1, (unsigned char *)data, TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_CLAMP | TEXF_ALPHA, NULL);
        // 2D circle texture
        for (y = 0;y < ATTEN2DSIZE;y++)
                for (x = 0;x < ATTEN2DSIZE;x++)
                        data[y*ATTEN2DSIZE+x] = R_Shadow_MakeTextures_SamplePoint(((x + 0.5f) * (2.0f / ATTEN2DSIZE) - 1.0f) * (1.0f / 0.9375), ((y + 0.5f) * (2.0f / ATTEN2DSIZE) - 1.0f) * (1.0f / 0.9375), 0);
-       r_shadow_attenuation2dtexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation2d", ATTEN2DSIZE, ATTEN2DSIZE, data, TEXTYPE_PALETTE, TEXF_PRECACHE | TEXF_CLAMP | TEXF_ALPHA, palette);
+       r_shadow_attenuation2dtexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation2d", ATTEN2DSIZE, ATTEN2DSIZE, (unsigned char *)data, TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_CLAMP | TEXF_ALPHA, NULL);
        // 3D sphere texture
        if (r_shadow_texture3d.integer && gl_texture3d)
        {
@@ -951,7 +948,7 @@ static void R_Shadow_MakeTextures(void)
                        for (y = 0;y < ATTEN3DSIZE;y++)
                                for (x = 0;x < ATTEN3DSIZE;x++)
                                        data[(z*ATTEN3DSIZE+y)*ATTEN3DSIZE+x] = R_Shadow_MakeTextures_SamplePoint(((x + 0.5f) * (2.0f / ATTEN3DSIZE) - 1.0f) * (1.0f / 0.9375), ((y + 0.5f) * (2.0f / ATTEN3DSIZE) - 1.0f) * (1.0f / 0.9375), ((z + 0.5f) * (2.0f / ATTEN3DSIZE) - 1.0f) * (1.0f / 0.9375));
-               r_shadow_attenuation3dtexture = R_LoadTexture3D(r_shadow_texturepool, "attenuation3d", ATTEN3DSIZE, ATTEN3DSIZE, ATTEN3DSIZE, data, TEXTYPE_PALETTE, TEXF_PRECACHE | TEXF_CLAMP | TEXF_ALPHA, palette);
+               r_shadow_attenuation3dtexture = R_LoadTexture3D(r_shadow_texturepool, "attenuation3d", ATTEN3DSIZE, ATTEN3DSIZE, ATTEN3DSIZE, (unsigned char *)data, TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_CLAMP | TEXF_ALPHA, NULL);
        }
        else
                r_shadow_attenuation3dtexture = NULL;
@@ -1033,7 +1030,7 @@ void R_Shadow_RenderMode_Reset(void)
        qglStencilMask(~0);CHECKGLERROR
        qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);CHECKGLERROR
        qglStencilFunc(GL_ALWAYS, 128, ~0);CHECKGLERROR
-       GL_CullFace(GL_FRONT); // quake is backwards, this culls back faces
+       GL_CullFace(r_view.cullface_back);
        GL_Color(1, 1, 1, 1);
        GL_ColorMask(r_view.colormask[0], r_view.colormask[1], r_view.colormask[2], 1);
        GL_BlendFunc(GL_ONE, GL_ZERO);
@@ -1051,17 +1048,17 @@ void R_Shadow_RenderMode_StencilShadowVolumes(qboolean clearstencil)
        if (r_shadow_rendermode == R_SHADOW_RENDERMODE_SEPARATESTENCIL)
        {
                GL_CullFace(GL_NONE);
-               qglStencilOpSeparate(GL_BACK, GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR // quake is backwards, this is front faces
-               qglStencilOpSeparate(GL_FRONT, GL_KEEP, GL_DECR, GL_KEEP);CHECKGLERROR // quake is backwards, this is back faces
+               qglStencilOpSeparate(r_view.cullface_front, GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR
+               qglStencilOpSeparate(r_view.cullface_back, GL_KEEP, GL_DECR, GL_KEEP);CHECKGLERROR
        }
        else if (r_shadow_rendermode == R_SHADOW_RENDERMODE_STENCILTWOSIDE)
        {
                GL_CullFace(GL_NONE);
                qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR
-               qglActiveStencilFaceEXT(GL_BACK);CHECKGLERROR // quake is backwards, this is front faces
+               qglActiveStencilFaceEXT(r_view.cullface_front);CHECKGLERROR
                qglStencilMask(~0);CHECKGLERROR
                qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR
-               qglActiveStencilFaceEXT(GL_FRONT);CHECKGLERROR // quake is backwards, this is back faces
+               qglActiveStencilFaceEXT(r_view.cullface_back);CHECKGLERROR
                qglStencilMask(~0);CHECKGLERROR
                qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);CHECKGLERROR
        }
@@ -1463,7 +1460,16 @@ static void R_Shadow_RenderLighting_VisibleLighting(int firstvertex, int numvert
 static void R_Shadow_RenderLighting_Light_GLSL(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
 {
        // ARB2 GLSL shader path (GFFX5200, Radeon 9500)
-       R_SetupSurfaceShader(lightcolorbase, false, ambientscale, diffusescale, specularscale);
+       R_SetupSurfaceShader(lightcolorbase, false, ambientscale, diffusescale, specularscale, RSURFPASS_RTLIGHT);
+       R_Mesh_TexMatrix(0, &rsurface.texture->currenttexmatrix);
+       R_Mesh_TexBind(0, R_GetTexture(rsurface.texture->currentskinframe->nmap));
+       R_Mesh_TexBind(1, R_GetTexture(rsurface.texture->basetexture));
+       R_Mesh_TexBind(2, R_GetTexture(rsurface.texture->glosstexture));
+       R_Mesh_TexBindCubeMap(3, R_GetTexture(rsurface.rtlight->currentcubemap));
+       R_Mesh_TexBind(4, R_GetTexture(r_texture_fogattenuation));
+       R_Mesh_TexBind(5, R_GetTexture(rsurface.texture->currentskinframe->pants));
+       R_Mesh_TexBind(6, R_GetTexture(rsurface.texture->currentskinframe->shirt));
+       R_Mesh_TexBind(10, R_GetTexture(r_shadow_attenuationgradienttexture));
        R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset);
        R_Mesh_TexCoordPointer(1, 3, rsurface.svector3f, rsurface.svector3f_bufferobject, rsurface.svector3f_bufferoffset);
        R_Mesh_TexCoordPointer(2, 3, rsurface.tvector3f, rsurface.tvector3f_bufferobject, rsurface.tvector3f_bufferoffset);
@@ -2244,7 +2250,7 @@ void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles,
        GL_DepthRange(0, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SHORTDEPTHRANGE) ? 0.0625 : 1);
        GL_PolygonOffset(rsurface.texture->currentpolygonfactor, rsurface.texture->currentpolygonoffset);
        GL_DepthTest(!(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
-       GL_CullFace((rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : GL_FRONT); // quake is backwards, this culls back faces
+       GL_CullFace((rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : r_view.cullface_back);
        nmap = rsurface.texture->currentskinframe->nmap;
        if (gl_lightmaps.integer)
                nmap = r_texture_blanknormalmap;
@@ -2660,11 +2666,11 @@ void R_Shadow_DrawWorldShadow(int numsurfaces, int *surfacelist, const unsigned
                        if (r_shadow_rendermode == R_SHADOW_RENDERMODE_STENCIL)
                        {
                                // decrement stencil if backface is behind depthbuffer
-                               GL_CullFace(GL_BACK); // quake is backwards, this culls front faces
+                               GL_CullFace(r_view.cullface_front);
                                qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);CHECKGLERROR
                                R_Mesh_Draw(0, mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->ebo, 0);
                                // increment stencil if frontface is behind depthbuffer
-                               GL_CullFace(GL_FRONT); // quake is backwards, this culls back faces
+                               GL_CullFace(r_view.cullface_back);
                                qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR
                        }
                        R_Mesh_Draw(0, mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->ebo, 0);
@@ -2936,7 +2942,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
        // count this light in the r_speeds
        r_refdef.stats.lights++;
 
-       if (r_showshadowvolumes.integer && numsurfaces + numshadowentities + numshadowentities_noselfshadow && rtlight->shadow && (rtlight->isstatic ? r_refdef.rtworldshadows : r_refdef.rtdlightshadows))
+       if (r_showshadowvolumes.integer && r_view.showdebug && numsurfaces + numshadowentities + numshadowentities_noselfshadow && rtlight->shadow && (rtlight->isstatic ? r_refdef.rtworldshadows : r_refdef.rtdlightshadows))
        {
                // optionally draw visible shape of the shadow volumes
                // for performance analysis by level designers
@@ -2967,7 +2973,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
 
                        // optionally draw the illuminated areas
                        // for performance analysis by level designers
-                       if (r_showlighting.integer)
+                       if (r_showlighting.integer && r_view.showdebug)
                        {
                                R_Shadow_RenderMode_VisibleLighting(!r_showdisabledepthtest.integer, false);
                                for (i = 0;i < numlightentities_noselfshadow;i++)
@@ -2990,7 +2996,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
 
                        // optionally draw the illuminated areas
                        // for performance analysis by level designers
-                       if (r_showlighting.integer)
+                       if (r_showlighting.integer && r_view.showdebug)
                        {
                                R_Shadow_RenderMode_VisibleLighting(!r_showdisabledepthtest.integer, false);
                                if (numsurfaces)
@@ -3015,7 +3021,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
 
                        // optionally draw the illuminated areas
                        // for performance analysis by level designers
-                       if (r_showlighting.integer)
+                       if (r_showlighting.integer && r_view.showdebug)
                        {
                                R_Shadow_RenderMode_VisibleLighting(false, false);
                                if (numsurfaces)
@@ -3061,7 +3067,7 @@ void R_ShadowVolumeLighting(qboolean visible)
        R_Shadow_RenderMode_End();
 }
 
-extern void R_SetupView(const matrix4x4_t *matrix);
+extern void R_SetupView(void);
 extern cvar_t r_shadows_throwdistance;
 void R_DrawModelShadows(void)
 {
@@ -3143,7 +3149,7 @@ void R_DrawModelShadows(void)
        R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
 
        // restoring the perspective view is done by R_RenderScene
-       //R_SetupView(&r_view.matrix);
+       //R_SetupView();
 
        // restore other state to normal
        R_Shadow_RenderMode_End();
@@ -3190,7 +3196,7 @@ static int componentorder[4] = {0, 1, 2, 3};
 rtexture_t *R_Shadow_LoadCubemap(const char *basename)
 {
        int i, j, cubemapsize;
-       unsigned char *cubemappixels, *image_rgba;
+       unsigned char *cubemappixels, *image_buffer;
        rtexture_t *cubemaptexture;
        char name[256];
        // must start 0 so the first loadimagepixels has no requested width/height
@@ -3206,10 +3212,10 @@ rtexture_t *R_Shadow_LoadCubemap(const char *basename)
                        // generate an image name based on the base and and suffix
                        dpsnprintf(name, sizeof(name), "%s%s", basename, suffix[j][i].suffix);
                        // load it
-                       if ((image_rgba = loadimagepixels(name, false, cubemapsize, cubemapsize)))
+                       if ((image_buffer = loadimagepixelsbgra(name, false, false)))
                        {
                                // an image loaded, make sure width and height are equal
-                               if (image_width == image_height)
+                               if (image_width == image_height && (!cubemappixels || image_width == cubemapsize))
                                {
                                        // if this is the first image to load successfully, allocate the cubemap memory
                                        if (!cubemappixels && image_width >= 1)
@@ -3220,12 +3226,12 @@ rtexture_t *R_Shadow_LoadCubemap(const char *basename)
                                        }
                                        // copy the image with any flipping needed by the suffix (px and posx types don't need flipping)
                                        if (cubemappixels)
-                                               Image_CopyMux(cubemappixels+i*cubemapsize*cubemapsize*4, image_rgba, cubemapsize, cubemapsize, suffix[j][i].flipx, suffix[j][i].flipy, suffix[j][i].flipdiagonal, 4, 4, componentorder);
+                                               Image_CopyMux(cubemappixels+i*cubemapsize*cubemapsize*4, image_buffer, cubemapsize, cubemapsize, suffix[j][i].flipx, suffix[j][i].flipy, suffix[j][i].flipdiagonal, 4, 4, componentorder);
                                }
                                else
                                        Con_Printf("Cubemap image \"%s\" (%ix%i) is not square, OpenGL requires square cubemaps.\n", name, image_width, image_height);
                                // free the image
-                               Mem_Free(image_rgba);
+                               Mem_Free(image_buffer);
                        }
                }
        }
@@ -3234,7 +3240,7 @@ rtexture_t *R_Shadow_LoadCubemap(const char *basename)
        {
                if (!r_shadow_filters_texturepool)
                        r_shadow_filters_texturepool = R_AllocTexturePool();
-               cubemaptexture = R_LoadTextureCubeMap(r_shadow_filters_texturepool, basename, cubemapsize, cubemappixels, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
+               cubemaptexture = R_LoadTextureCubeMap(r_shadow_filters_texturepool, basename, cubemapsize, cubemappixels, TEXTYPE_BGRA, TEXF_PRECACHE | (gl_texturecompression_lightcubemaps.integer ? TEXF_COMPRESS : 0), NULL);
                Mem_Free(cubemappixels);
        }
        else
@@ -3614,7 +3620,7 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void)
                data = r_refdef.worldmodel->brush.entities;
        if (!data)
                return;
-       for (entnum = 0;COM_ParseToken_Simple(&data, false) && com_token[0] == '{';entnum++)
+       for (entnum = 0;COM_ParseToken_Simple(&data, false, false) && com_token[0] == '{';entnum++)
        {
                type = LIGHTTYPE_MINUSX;
                origin[0] = origin[1] = origin[2] = 0;
@@ -3632,7 +3638,7 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void)
                islight = false;
                while (1)
                {
-                       if (!COM_ParseToken_Simple(&data, false))
+                       if (!COM_ParseToken_Simple(&data, false, false))
                                break; // error
                        if (com_token[0] == '}')
                                break; // end of entity
@@ -3642,7 +3648,7 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void)
                                strlcpy(key, com_token, sizeof(key));
                        while (key[strlen(key)-1] == ' ') // remove trailing spaces
                                key[strlen(key)-1] = 0;
-                       if (!COM_ParseToken_Simple(&data, false))
+                       if (!COM_ParseToken_Simple(&data, false, false))
                                break; // error
                        strlcpy(value, com_token, sizeof(value));