better VSDCT transform
authoreihrul <eihrul@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 1 Oct 2009 16:09:44 +0000 (16:09 +0000)
committereihrul <eihrul@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 1 Oct 2009 16:09:44 +0000 (16:09 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9272 d7cf8633-e32d-0410-b094-e92efae38249

gl_backend.c
gl_rmain.c
gl_textures.c
glquake.h
r_shadow.c
r_textures.h

index 78e5642..e4dc975 100644 (file)
@@ -442,42 +442,83 @@ void R_Viewport_InitPerspectiveInfinite(r_viewport_t *v, const matrix4x4_t *came
 
 float cubeviewmatrix[6][16] =
 {
-       {
-                0, 0,-1, 0,
-                0,-1, 0, 0,
-               -1, 0, 0, 0,
-                0, 0, 0, 1,
-       },
-       {
-                0, 0, 1, 0,
-                0,-1, 0, 0,
-                1, 0, 0, 0,
-                0, 0, 0, 1,
-       },
-       {
-                1, 0, 0, 0,
-                0, 0,-1, 0,
-                0, 1, 0, 0,
-                0, 0, 0, 1,
-       },
-       {
-                1, 0, 0, 0,
-                0, 0, 1, 0,
-                0,-1, 0, 0,
-                0, 0, 0, 1,
-       },
-       {
-                1, 0, 0, 0,
-                0,-1, 0, 0,
-                0, 0,-1, 0,
-                0, 0, 0, 1,
-       },
-       {
-               -1, 0, 0, 0,
-                0,-1, 0, 0,
-                0, 0, 1, 0,
-                0, 0, 0, 1,
-       },
+    // standard cubemap projections
+    { // +X
+         0, 0,-1, 0,
+         0,-1, 0, 0,
+        -1, 0, 0, 0,
+         0, 0, 0, 1,
+    },
+    { // -X
+         0, 0, 1, 0,
+         0,-1, 0, 0,
+         1, 0, 0, 0,
+         0, 0, 0, 1,
+    },
+    { // +Y
+         1, 0, 0, 0,
+         0, 0,-1, 0,
+         0, 1, 0, 0,
+         0, 0, 0, 1,
+    },
+    { // -Y
+         1, 0, 0, 0,
+         0, 0, 1, 0,
+         0,-1, 0, 0,
+         0, 0, 0, 1,
+    },
+    { // +Z
+         1, 0, 0, 0,
+         0,-1, 0, 0,
+         0, 0,-1, 0,
+         0, 0, 0, 1,
+    },
+    { // -Z
+        -1, 0, 0, 0,
+         0,-1, 0, 0,
+         0, 0, 1, 0,
+         0, 0, 0, 1,
+    },
+};
+float rectviewmatrix[6][16] =
+{
+    // sign-preserving cubemap projections
+    { // +X
+         0, 0,-1, 0,
+         0, 1, 0, 0,
+         1, 0, 0, 0,
+         0, 0, 0, 1,
+    },
+    { // -X
+         0, 0, 1, 0,
+         0, 1, 0, 0,
+         1, 0, 0, 0,
+         0, 0, 0, 1,
+    },
+    { // +Y
+         1, 0, 0, 0,
+         0, 0,-1, 0,
+         0, 1, 0, 0,
+         0, 0, 0, 1,
+    },
+    { // -Y
+         1, 0, 0, 0,
+         0, 0, 1, 0,
+         0, 1, 0, 0,
+         0, 0, 0, 1,
+    },
+    { // +Z
+         1, 0, 0, 0,
+         0, 1, 0, 0,
+         0, 0,-1, 0,
+         0, 0, 0, 1,
+    },
+    { // -Z
+         1, 0, 0, 0,
+         0, 1, 0, 0,
+         0, 0, 1, 0,
+         0, 0, 0, 1,
+    },
 };
 
 void R_Viewport_InitCubeSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, float nearclip, float farclip, const float *nearplane)
@@ -521,7 +562,7 @@ void R_Viewport_InitRectSideView(r_viewport_t *v, const matrix4x4_t *cameramatri
        v->m[11] = -1;
        v->m[14] = -2 * nearclip * farclip / (farclip - nearclip);
 
-       Matrix4x4_FromArrayFloatGL(&basematrix, cubeviewmatrix[side]);
+       Matrix4x4_FromArrayFloatGL(&basematrix, rectviewmatrix[side]);
        Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix);
        Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
        Matrix4x4_FromArrayDoubleGL(&v->projectmatrix, v->m);
index dfa8a44..2d10139 100644 (file)
@@ -924,40 +924,52 @@ static const char *builtinshaderstring =
 "      float ma;\n"
 "      if (adir.x > adir.y)\n"
 "      {\n"
-"              if (adir.x > adir.z)\n"
+"              if (adir.x > adir.z) // X\n"
 "              {\n"
 "                      ma = adir.x;\n"
-"                      if (dir.x >= 0.0) { tc = vec2(-dir.z, -dir.y); offset = vec2(0.5, 0.5); } // +X\n"
-"                      else              { tc = vec2( dir.z, -dir.y); offset = vec2(1.5, 0.5); } // -X\n"
+"                      tc = dir.zy;\n"
+"                      offset = vec2(mix(0.5, 1.5, dir.x < 0.0), 0.5);\n"
 "              }\n"
-"              else\n"
+"              else // Z\n"
 "              {\n"
 "                      ma = adir.z;\n"
-"                      if (dir.z >= 0.0) { tc = vec2( dir.x, -dir.y); offset = vec2(0.5, 2.5); } // +Z\n"
-"                      else              { tc = vec2(-dir.x, -dir.y); offset = vec2(1.5, 2.5); } // -Z\n"
+"                      tc = dir.xy;\n"
+"                      offset = vec2(mix(0.5, 1.5, dir.z < 0.0), 2.5);\n"
 "              }\n"
 "      }\n"
 "      else\n"
 "      {\n"
-"              if (adir.y > adir.z)\n"
+"              if (adir.y > adir.z) // Y\n"
 "              {\n"
 "                      ma = adir.y;\n"
-"                      if (dir.y >= 0.0) { tc = vec2( dir.x,  dir.z); offset = vec2(0.5, 1.5); } // +Y\n"
-"                      else              { tc = vec2( dir.x, -dir.z); offset = vec2(1.5, 1.5); } // -Y\n"
+"                      tc = dir.xz;\n"
+"                      offset = vec2(mix(0.5, 1.5, dir.y < 0.0), 1.5);\n"
 "              }\n"
-"              else\n"
+"              else // Z\n"
 "              {\n"
 "                      ma = adir.z;\n"
-"                      if (dir.z >= 0.0) { tc = vec2( dir.x, -dir.y); offset = vec2(0.5, 2.5); } // +Z\n"
-"                      else              { tc = vec2(-dir.x, -dir.y); offset = vec2(1.5, 2.5); } // -Z\n"
+"                      tc = dir.xy;\n"
+"                      offset = vec2(mix(0.5, 1.5, dir.z < 0.0), 2.5);\n"
 "              }\n"
 "      }\n"
 "\n"
-"      vec3 stc = vec3(tc * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma + vec3(offset * ShadowMap_Parameters.y, ShadowMap_Parameters.z);\n"
+"      vec3 stc = vec3(tc * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
+"      stc.xy += offset * ShadowMap_Parameters.y;\n"
+"      stc.z += ShadowMap_Parameters.z;\n"
+"#  ifndef USESHADOWMAPRECT\n"
 "      stc.xy *= ShadowMap_TextureScale.xy;\n"
+"#  endif\n"
 "      return stc;\n"
 "# else\n"
-"      return vec3(textureCube(Texture_CubeProjection, dir.xyz).ra * ShadowMap_Parameters.xy, ShadowMap_Parameters.z + ShadowMap_Parameters.w / max(max(adir.x, adir.y), adir.z));\n"
+"      vec4 proj = textureCube(Texture_CubeProjection, dir);\n"
+"      float ma = max(max(adir.x, adir.y), adir.z);\n"
+"      vec3 stc = vec3(mix(dir.xy, dir.zz, proj.xy) * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
+"      stc.xy += proj.zw * ShadowMap_Parameters.y;\n"
+"      stc.z += ShadowMap_Parameters.z;\n"
+"#  ifndef USESHADOWMAPRECT\n"
+"      stc.xy *= ShadowMap_TextureScale.xy;\n"
+"#  endif\n"
+"      return stc;\n"
 "# endif\n"
 "}\n"
 "#endif // defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
index c3cbcf3..e0c9720 100644 (file)
@@ -61,7 +61,6 @@ static textypeinfo_t textype_bgra_alpha             = {TEXTYPE_BGRA   , 4, 4, 4.
 static textypeinfo_t textype_bgra_compress          = {TEXTYPE_BGRA   , 4, 4, 0.5f, GL_BGRA   , GL_COMPRESSED_RGB_ARB, GL_UNSIGNED_BYTE};
 static textypeinfo_t textype_bgra_alpha_compress    = {TEXTYPE_BGRA   , 4, 4, 1.0f, GL_BGRA   , GL_COMPRESSED_RGBA_ARB, GL_UNSIGNED_BYTE};
 static textypeinfo_t textype_shadowmap              = {TEXTYPE_SHADOWMAP,4,4, 4.0f, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24_ARB, GL_UNSIGNED_INT};
-static textypeinfo_t textype_projection             = {TEXTYPE_PROJECTION,4,4,4.0f, GL_LUMINANCE_ALPHA, GL_LUMINANCE16_ALPHA16, GL_UNSIGNED_SHORT};
 
 typedef enum gltexturetype_e
 {
@@ -219,8 +218,6 @@ static textypeinfo_t *R_GetTexTypeInfo(textype_t textype, int flags)
                                return &textype_bgra;
                        case TEXTYPE_SHADOWMAP:
                                return &textype_shadowmap;
-                       case TEXTYPE_PROJECTION:
-                               return &textype_projection;
                        default:
                                Host_Error("R_GetTexTypeInfo: unknown texture format");
                                return NULL;
@@ -1066,7 +1063,6 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden
                }
                break;
        case TEXTYPE_SHADOWMAP:
-       case TEXTYPE_PROJECTION:
                break;
        default:
                Host_Error("R_LoadTexture: unknown texture type");
@@ -1149,40 +1145,6 @@ rtexture_t *R_LoadTextureShadowMapCube(rtexturepool_t *rtexturepool, const char
     return R_SetupTexture(rtexturepool, identifier, width, width, 1, 6, TEXF_ALWAYSPRECACHE | TEXF_CLAMP | (filter ? TEXF_FORCELINEAR | TEXF_COMPARE : TEXF_FORCENEAREST), TEXTYPE_SHADOWMAP, GLTEXTURETYPE_CUBEMAP, NULL, NULL);
 }
 
-rtexture_t *R_LoadTextureCubeProjection(rtexturepool_t *rtexturepool, const char *identifier, int size, int border)
-{
-    // maps to a 2x3 texture rectangle with normalized coordinates (must be scaled by size after lookup)
-    // +-
-    // XX
-    // YY
-    // ZZ
-    rtexture_t *projection;
-       unsigned short *data, *texel;
-       unsigned int sizebits = 0, stepbits = 0, res, i, j, k;
-       while ((1 << sizebits) < size) sizebits++;
-       while ((1 << stepbits) <= border) stepbits++;
-    stepbits = min(stepbits, sizebits);
-       res = size>>stepbits;
-       stepbits += 16 - sizebits - 1;
-       data = (unsigned short *)Mem_Alloc(texturemempool, 2*sizeof(unsigned short)*res*res*6);
-       texel = data;
-       for (i = 0;i < 6;i++) 
-       {
-               unsigned int x = (i%2)<<16, y = (i/2)<<16;
-               for (j = 0;j < res;j++)
-               {
-                       for (k = 0;k < res;k++)
-                       {
-                               *texel++ = (x + ((2*k + 1)<<stepbits))/2;
-                               *texel++ = (y + ((2*j + 1)<<stepbits))/3;
-                       }
-               }
-       }
-       projection = R_SetupTexture(rtexturepool, identifier, res, res, 1, 6, TEXF_ALWAYSPRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, TEXTYPE_PROJECTION, GLTEXTURETYPE_CUBEMAP, (unsigned char *)data, NULL);
-       Mem_Free(data);
-    return projection;
-}
-
 int R_TextureHasAlpha(rtexture_t *rt)
 {
        return rt ? (((gltexture_t *)rt)->flags & TEXF_ALPHA) != 0 : false;
index 301b466..9a749e3 100644 (file)
--- a/glquake.h
+++ b/glquake.h
@@ -953,10 +953,6 @@ extern void (GLAPIENTRY *qglGetQueryObjectuivARB)(GLuint qid, GLenum pname, GLui
 // GL_EXT_bgra
 #define GL_BGRA                                        0x80E1
 
-// GL_EXT_texture
-#define GL_LUMINANCE_ALPHA                0x190A
-#define GL_LUMINANCE16_ALPHA16            0x8048
-
 //GL_AMD_texture_texture4
 extern int gl_support_amd_texture_texture4;
 
index b0c3454..a6f99ec 100644 (file)
@@ -227,7 +227,7 @@ rtexture_t *r_shadow_lightcorona;
 rtexture_t *r_shadow_shadowmaprectangletexture;
 rtexture_t *r_shadow_shadowmap2dtexture;
 rtexture_t *r_shadow_shadowmapcubetexture[R_SHADOW_SHADOWMAP_NUMCUBEMAPS];
-rtexture_t *r_shadow_shadowmapcubeprojectiontexture[R_SHADOW_SHADOWMAP_NUMCUBEMAPS];
+rtexture_t *r_shadow_shadowmapvsdcttexture;
 int r_shadow_shadowmapsize; // changes for each light based on distance
 int r_shadow_shadowmaplod; // changes for each light based on distance
 
@@ -435,10 +435,9 @@ void R_Shadow_FreeShadowMaps(void)
                        R_FreeTexture(r_shadow_shadowmapcubetexture[i]);
        memset(r_shadow_shadowmapcubetexture, 0, sizeof(r_shadow_shadowmapcubetexture));
 
-       for (i = 0;i < R_SHADOW_SHADOWMAP_NUMCUBEMAPS;i++)
-               if (r_shadow_shadowmapcubeprojectiontexture[i])
-                       R_FreeTexture(r_shadow_shadowmapcubeprojectiontexture[i]);
-       memset(r_shadow_shadowmapcubeprojectiontexture, 0, sizeof(r_shadow_shadowmapcubeprojectiontexture));
+       if (r_shadow_shadowmapvsdcttexture)
+               R_FreeTexture(r_shadow_shadowmapvsdcttexture);
+       r_shadow_shadowmapvsdcttexture = NULL;
 
        CHECKGLERROR
 }
@@ -454,7 +453,7 @@ void r_shadow_start(void)
        r_shadow_shadowmaprectangletexture = NULL;
        r_shadow_shadowmap2dtexture = NULL;
        memset(r_shadow_shadowmapcubetexture, 0, sizeof(r_shadow_shadowmapcubetexture));
-       memset(r_shadow_shadowmapcubeprojectiontexture, 0, sizeof(r_shadow_shadowmapcubeprojectiontexture));
+       r_shadow_shadowmapvsdcttexture = NULL;
        r_shadow_shadowmapmaxsize = 0;
        r_shadow_shadowmapsize = 0;
        r_shadow_shadowmaplod = 0;
@@ -1536,6 +1535,26 @@ void R_Shadow_RenderMode_StencilShadowVolumes(qboolean zpass)
        }
 }
 
+static void R_Shadow_MakeVSDCT(void)
+{
+       // maps to a 2x3 texture rectangle with normalized coordinates
+       // +-
+       // XX
+       // YY
+       // ZZ
+       // stores abs(dir.xy), offset.xy/2.5
+       unsigned char data[4*6] =
+       {
+               255, 0, 0x33, 0x33, // +X: <1, 0>, <0.5, 0.5>
+               255, 0, 0x99, 0x33, // -X: <1, 0>, <1.5, 0.5>
+               0, 255, 0x33, 0x99, // +Y: <0, 1>, <0.5, 1.5>
+               0, 255, 0x99, 0x99, // -Y: <0, 1>, <1.5, 1.5>
+               0,   0, 0x33, 0xFF, // +Z: <0, 0>, <0.5, 2.5>
+               0,   0, 0x99, 0xFF, // -Z: <0, 0>, <1.5, 2.5>
+       };
+       r_shadow_shadowmapvsdcttexture = R_LoadTextureCubeMap(r_shadow_texturepool, "shadowmapvsdct", 1, data, TEXTYPE_RGBA, TEXF_ALWAYSPRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALPHA, NULL); 
+}
+
 void R_Shadow_RenderMode_ShadowMap(int side, qboolean clear, int size)
 {
        int i;
@@ -1553,8 +1572,8 @@ void R_Shadow_RenderMode_ShadowMap(int side, qboolean clear, int size)
        if (r_shadow_shadowmode == 1)
        {
                // complex unrolled cube approach (more flexible)
-               if (r_shadow_shadowmapvsdct && !r_shadow_shadowmapcubeprojectiontexture[r_shadow_shadowmaplod])
-                       r_shadow_shadowmapcubeprojectiontexture[r_shadow_shadowmaplod] = R_LoadTextureCubeProjection(r_shadow_texturepool, "shadowmapcubeprojection", size, r_shadow_shadowmapborder);
+               if (r_shadow_shadowmapvsdct && !r_shadow_shadowmapvsdcttexture)
+                       R_Shadow_MakeVSDCT();
                if (!r_shadow_shadowmap2dtexture)
                {
 #if 1
@@ -1586,18 +1605,18 @@ void R_Shadow_RenderMode_ShadowMap(int side, qboolean clear, int size)
                        R_SetupShowDepthShader();
                        qglClearColor(1,1,1,1);CHECKGLERROR
                }
-               R_Viewport_InitRectSideView(&viewport, &rsurface.rtlight->matrix_lighttoworld, side, size, r_shadow_shadowmapping_bordersize.integer, nearclip, farclip, NULL);
+               R_Viewport_InitRectSideView(&viewport, &rsurface.rtlight->matrix_lighttoworld, side, size, r_shadow_shadowmapborder, nearclip, farclip, NULL);
                r_shadow_shadowmap_texturescale[0] = 1.0f / R_TextureWidth(r_shadow_shadowmap2dtexture);
                r_shadow_shadowmap_texturescale[1] = 1.0f / R_TextureHeight(r_shadow_shadowmap2dtexture);
-               r_shadow_shadowmap_parameters[0] = r_shadow_shadowmapvsdct ? 2*size * r_shadow_shadowmap_texturescale[0] : 0.5f * (size - r_shadow_shadowmapborder);
-               r_shadow_shadowmap_parameters[1] = r_shadow_shadowmapvsdct ? 3*size * r_shadow_shadowmap_texturescale[1] : size;
+               r_shadow_shadowmap_parameters[0] = 0.5f * (size - r_shadow_shadowmapborder);
+               r_shadow_shadowmap_parameters[1] = r_shadow_shadowmapvsdct ? 2.5f*size : size;
                r_shadow_rendermode = R_SHADOW_RENDERMODE_SHADOWMAP2D;
        }
        else if (r_shadow_shadowmode == 2)
        {
                // complex unrolled cube approach (more flexible)
-               if (r_shadow_shadowmapvsdct && !r_shadow_shadowmapcubeprojectiontexture[r_shadow_shadowmaplod])
-                       r_shadow_shadowmapcubeprojectiontexture[r_shadow_shadowmaplod] = R_LoadTextureCubeProjection(r_shadow_texturepool, "shadowmapcubeprojection", size, r_shadow_shadowmapborder);
+               if (r_shadow_shadowmapvsdct && !r_shadow_shadowmapvsdcttexture)
+                       R_Shadow_MakeVSDCT();
                if (!r_shadow_shadowmaprectangletexture)
                {
 #if 1
@@ -1631,8 +1650,8 @@ void R_Shadow_RenderMode_ShadowMap(int side, qboolean clear, int size)
                R_Viewport_InitRectSideView(&viewport, &rsurface.rtlight->matrix_lighttoworld, side, size, r_shadow_shadowmapborder, nearclip, farclip, NULL);
                r_shadow_shadowmap_texturescale[0] = 1.0f;
                r_shadow_shadowmap_texturescale[1] = 1.0f;
-               r_shadow_shadowmap_parameters[0] = r_shadow_shadowmapvsdct ? 2*size : 0.5f * (size - r_shadow_shadowmapborder);
-               r_shadow_shadowmap_parameters[1] = r_shadow_shadowmapvsdct ? 3*size : size;
+               r_shadow_shadowmap_parameters[0] = 0.5f * (size - r_shadow_shadowmapborder);
+               r_shadow_shadowmap_parameters[1] = r_shadow_shadowmapvsdct ? 2.5f*size : size;
                r_shadow_rendermode = R_SHADOW_RENDERMODE_SHADOWMAPRECTANGLE;
        }
        else if (r_shadow_shadowmode == 3)
@@ -1740,7 +1759,7 @@ void R_Shadow_RenderMode_Lighting(qboolean stenciltest, qboolean transparent, qb
 
                        if (r_shadow_shadowmapvsdct && (r_shadow_usingshadowmap2d || r_shadow_usingshadowmaprect))
                        {
-                               R_Mesh_TexBindCubeMap(GL20TU_CUBEPROJECTION, R_GetTexture(r_shadow_shadowmapcubeprojectiontexture[r_shadow_shadowmaplod]));
+                               R_Mesh_TexBindCubeMap(GL20TU_CUBEPROJECTION, R_GetTexture(r_shadow_shadowmapvsdcttexture));
                                CHECKGLERROR
                        }
                }
@@ -3778,7 +3797,7 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible)
                        if ((r_shadow_shadowmapping_maxsize.integer >> i) > lodlinear)
                                r_shadow_shadowmaplod = i;
 
-               size = r_shadow_shadowmapvsdct || r_shadow_shadowmode == 3 ? r_shadow_shadowmapping_maxsize.integer >> r_shadow_shadowmaplod : lodlinear;
+               size = r_shadow_shadowmode == 3 ? r_shadow_shadowmapping_maxsize.integer >> r_shadow_shadowmaplod : lodlinear;
                size = bound(1, size, 2048);
 
                //Con_Printf("distance %f lodlinear %i (lod %i) size %i\n", distance, lodlinear, r_shadow_shadowmaplod, size);
index 55adebc..d43be40 100644 (file)
@@ -37,8 +37,6 @@ typedef enum textype_e
        TEXTYPE_BGRA,
        // 32bit S8D24 (24bit depth, 8bit stencil unused)
        TEXTYPE_SHADOWMAP,
-       // 32bit L16A16
-       TEXTYPE_PROJECTION
 }
 textype_t;
 
@@ -86,7 +84,6 @@ rtexture_t *R_LoadTextureCubeMap(rtexturepool_t *rtexturepool, const char *ident
 rtexture_t *R_LoadTextureShadowMapRectangle(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, qboolean filter);
 rtexture_t *R_LoadTextureShadowMap2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, qboolean filter);
 rtexture_t *R_LoadTextureShadowMapCube(rtexturepool_t *rtexturepool, const char *identifier, int width, qboolean filter);
-rtexture_t *R_LoadTextureCubeProjection(rtexturepool_t *rtexturepool, const char *identifier, int size, int border);
 
 // free a texture
 void R_FreeTexture(rtexture_t *rt);