]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_textures.c
restoring scaffolding for cubemap and 2D shadowmaps
[xonotic/darkplaces.git] / gl_textures.c
index 53f34c2d4b429b4de39d323bbc70add23fa5d5cc..1051a7a75490bfcb27b10a826d8bc356e0bf8957 100644 (file)
@@ -60,7 +60,8 @@ static textypeinfo_t textype_bgra                   = {TEXTYPE_BGRA   , 4, 4, 4.
 static textypeinfo_t textype_bgra_alpha             = {TEXTYPE_BGRA   , 4, 4, 4.0f, GL_BGRA   , 4, GL_UNSIGNED_BYTE};
 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_COMPONENT32_ARB, GL_UNSIGNED_INT};
+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
 {
@@ -218,6 +219,8 @@ 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;
@@ -714,7 +717,7 @@ void R_MakeResizeBufferBigger(int size)
        }
 }
 
-static void GL_SetupTextureParameters(int flags, int texturetype)
+static void GL_SetupTextureParameters(int flags, textype_t textype, int texturetype)
 {
        int textureenum = gltexturetypeenums[texturetype];
        int wrapmode = ((flags & TEXF_CLAMP) && gl_support_clamptoedge) ? GL_CLAMP_TO_EDGE : GL_REPEAT;
@@ -780,17 +783,19 @@ static void GL_SetupTextureParameters(int flags, int texturetype)
                qglTexParameteri(textureenum, GL_TEXTURE_MAG_FILTER, gl_filter_mag);CHECKGLERROR
        }
 
-       if (texturetype == TEXTYPE_SHADOWMAP)
+       if (textype == TEXTYPE_SHADOWMAP)
        {
-#if 1
-               qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);CHECKGLERROR
-               qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);CHECKGLERROR
-               qglTexParameteri(textureenum, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);CHECKGLERROR
-#else
-               qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);CHECKGLERROR
-               qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_FUNC_ARB, GL_ALWAYS);CHECKGLERROR
+               if (flags & TEXF_COMPARE)
+               {
+                       qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);CHECKGLERROR
+                       qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);CHECKGLERROR
+               }
+               else
+               {
+                       qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);CHECKGLERROR
+                       qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_FUNC_ARB, GL_ALWAYS);CHECKGLERROR
+               }
                qglTexParameteri(textureenum, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);CHECKGLERROR
-#endif
        }
 
        CHECKGLERROR
@@ -810,7 +815,7 @@ static void R_Upload(gltexture_t *glt, const unsigned char *data, int fragx, int
        qglBindTexture(gltexturetypeenums[glt->texturetype], glt->texnum);CHECKGLERROR
 
        // these are rounded up versions of the size to do better resampling
-       if (gl_support_arb_texture_non_power_of_two)
+       if (gl_support_arb_texture_non_power_of_two || glt->texturetype == GLTEXTURETYPE_RECTANGLE)
        {
                width = glt->inputwidth;
                height = glt->inputheight;
@@ -963,7 +968,7 @@ static void R_Upload(gltexture_t *glt, const unsigned char *data, int fragx, int
                        qglTexImage2D(GL_TEXTURE_RECTANGLE_ARB, mip++, glt->glinternalformat, width, height, 0, glt->glformat, glt->gltype, NULL);CHECKGLERROR
                        break;
                }
-               GL_SetupTextureParameters(glt->flags, glt->texturetype);
+               GL_SetupTextureParameters(glt->flags, glt->textype->textype, glt->texturetype);
        }
        qglBindTexture(gltexturetypeenums[glt->texturetype], oldbindtexnum);CHECKGLERROR
 }
@@ -1059,6 +1064,7 @@ 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");
@@ -1126,24 +1132,53 @@ rtexture_t *R_LoadTextureCubeMap(rtexturepool_t *rtexturepool, const char *ident
        return R_SetupTexture(rtexturepool, identifier, width, width, 1, 6, flags, textype, GLTEXTURETYPE_CUBEMAP, data, palette);
 }
 
-rtexture_t *R_LoadTextureShadowMapRectangle(rtexturepool_t *rtexturepool, const char *identifier, int width, int height)
+rtexture_t *R_LoadTextureShadowMapRectangle(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, qboolean filter)
 {
-       return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, TEXF_ALWAYSPRECACHE | TEXF_FORCENEAREST | TEXF_CLAMP, TEXTYPE_SHADOWMAP, GLTEXTURETYPE_RECTANGLE, NULL, NULL);
+       return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, TEXF_ALWAYSPRECACHE | TEXF_CLAMP | (filter ? TEXF_FORCELINEAR | TEXF_COMPARE : TEXF_FORCENEAREST), TEXTYPE_SHADOWMAP, GLTEXTURETYPE_RECTANGLE, NULL, NULL);
 }
 
-rtexture_t *R_LoadTextureShadowMapCube(rtexturepool_t *rtexturepool, const char *identifier, int width)
+rtexture_t *R_LoadTextureShadowMap2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, qboolean filter)
 {
-       return R_SetupTexture(rtexturepool, identifier, width, width, 1, 6, TEXF_ALWAYSPRECACHE | TEXF_FORCENEAREST | TEXF_CLAMP, TEXTYPE_SHADOWMAP, GLTEXTURETYPE_CUBEMAP, NULL, NULL);
+       return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, TEXF_ALWAYSPRECACHE | TEXF_CLAMP | (filter ? TEXF_FORCELINEAR | TEXF_COMPARE : TEXF_FORCENEAREST), TEXTYPE_SHADOWMAP, GLTEXTURETYPE_2D, NULL, NULL);
 }
 
-rtexture_t *R_LoadTextureShadowMap2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height)
+rtexture_t *R_LoadTextureShadowMapCube(rtexturepool_t *rtexturepool, const char *identifier, int width, qboolean filter)
 {
-       return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, TEXF_ALWAYSPRECACHE | TEXF_FORCENEAREST | TEXF_CLAMP, TEXTYPE_SHADOWMAP, GLTEXTURETYPE_2D, NULL, NULL);
+    return R_SetupTexture(rtexturepool, identifier, width, width, 1, 6, TEXF_ALWAYSPRECACHE | TEXF_CLAMP | TEXF_COMPARE | (filter ? TEXF_FORCELINEAR : TEXF_FORCENEAREST), TEXTYPE_SHADOWMAP, GLTEXTURETYPE_CUBEMAP, NULL, NULL);
 }
 
-rtexture_t *R_LoadTextureCubeProjection(rtexturepool_t *rtexturepool, const char *identifier)
+rtexture_t *R_LoadTextureCubeProjection(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int size, int border)
 {
-       return R_SetupTexture(rtexturepool, identifier, 2, 2, 1, 6, TEXF_ALWAYSPRECACHE | TEXF_FORCENEAREST | TEXF_CLAMP, TEXTYPE_SHADOWMAP, GLTEXTURETYPE_CUBEMAP, NULL, NULL);
+    // 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))/width;
+                               *texel++ = (y + ((2*j + 1)<<stepbits))/height;
+                       }
+               }
+       }
+       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)