mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-04-21 09:41:00 +00:00
Merge branch 'mipmapfix' into 'next'
Manual mipmapping + Texture padding See merge request STJr/SRB2!2657
This commit is contained in:
commit
edd69bd194
1 changed files with 139 additions and 0 deletions
|
@ -1486,6 +1486,114 @@ static void AllocTextureBuffer(GLMipmap_t *pTexInfo)
|
|||
}
|
||||
}
|
||||
|
||||
#define PADDING_CHECK(offset, alphaCheck) { from = to + (offset); if ((alphaCheck)) from = NULL; else goto foundFrom; }
|
||||
|
||||
static void PadRGBABitmap(RGBA_t *tex, UINT16 w, UINT16 h)
|
||||
{
|
||||
INT32 i;
|
||||
boolean notLeft, notRight, notTop, notBottom;
|
||||
RGBA_t *to = tex - 1, *from;
|
||||
|
||||
for (i = 0; i < w * h; i++)
|
||||
{
|
||||
to++;
|
||||
if (to->rgba != 0)
|
||||
continue;
|
||||
from = NULL;
|
||||
|
||||
notLeft = i % w != 0;
|
||||
notRight = i % w != w - 1;
|
||||
notTop = i / w != 0;
|
||||
notBottom = i / w != h - 1;
|
||||
|
||||
if (notRight) PADDING_CHECK(1, from->s.alpha == 0) // Check +X
|
||||
if (notBottom) PADDING_CHECK(w, from->s.alpha == 0) // Check +Y
|
||||
if (notLeft) PADDING_CHECK(-1, from->s.alpha == 0) // Check -X
|
||||
if (notTop) PADDING_CHECK(-w, from->s.alpha == 0) // Check -Y
|
||||
if (notRight && notBottom) PADDING_CHECK(1 + w, from->s.alpha == 0) // Check +X+Y
|
||||
if (notLeft && notBottom) PADDING_CHECK(-1 + w, from->s.alpha == 0) // Check -X+Y
|
||||
if (notLeft && notTop) PADDING_CHECK(-1 - w, from->s.alpha == 0) // Check -X-Y
|
||||
if (notRight && notTop) PADDING_CHECK(1 - w, from->s.alpha == 0) // Check +X-Y
|
||||
|
||||
foundFrom:
|
||||
if (from != NULL)
|
||||
{
|
||||
*to = *from;
|
||||
to->s.alpha = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef PADDING_CHECK
|
||||
|
||||
static void GenerateMipmaps(INT32 w, INT32 h, RGBA_t *tex, INT32 maxLOD)
|
||||
{
|
||||
if (tex == NULL)
|
||||
{
|
||||
GL_MSG_Warning("GenerateMipmaps: attempted to generate mipmaps without texture data");
|
||||
return;
|
||||
}
|
||||
|
||||
RGBA_t samplePoint[4];
|
||||
boolean padTexture;
|
||||
INT32 pointsSampled = 0;
|
||||
INT32 m, j, i, p;
|
||||
UINT16 sumR, sumG, sumB, sumA;
|
||||
|
||||
for (m = 0; m < maxLOD; m++)
|
||||
{
|
||||
if (w <= 1 || h <= 1)
|
||||
return;
|
||||
|
||||
padTexture = false;
|
||||
|
||||
for (j = 0; j < h / 2; j++)
|
||||
{
|
||||
for (i = 0; i < w / 2; i++)
|
||||
{
|
||||
samplePoint[0] = tex[w*j*2 + i*2];
|
||||
samplePoint[1] = tex[w*j*2 + i*2+1];
|
||||
samplePoint[2] = tex[w*(j*2+1) + i*2];
|
||||
samplePoint[3] = tex[w*(j*2+1) + i*2+1];
|
||||
|
||||
pointsSampled = sumR = sumG = sumB = sumA = 0;
|
||||
|
||||
for (p = 0; p < 4; p++)
|
||||
{
|
||||
if (samplePoint[p].s.alpha == 0)
|
||||
continue;
|
||||
sumR += samplePoint[p].s.red;
|
||||
sumG += samplePoint[p].s.green;
|
||||
sumB += samplePoint[p].s.blue;
|
||||
sumA += samplePoint[p].s.alpha;
|
||||
pointsSampled++;
|
||||
}
|
||||
|
||||
if (pointsSampled > 0)
|
||||
{
|
||||
tex[(w/2)*j+i].s.red = sumR / pointsSampled;
|
||||
tex[(w/2)*j+i].s.green = sumG / pointsSampled;
|
||||
tex[(w/2)*j+i].s.blue = sumB / pointsSampled;
|
||||
tex[(w/2)*j+i].s.alpha = sumA / pointsSampled;
|
||||
}
|
||||
else
|
||||
{
|
||||
tex[(w/2)*j+i].rgba = 0;
|
||||
padTexture = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
w /= 2;
|
||||
h /= 2;
|
||||
|
||||
if (padTexture)
|
||||
PadRGBABitmap(tex, w, h);
|
||||
|
||||
pglTexSubImage2D(GL_TEXTURE_2D, m + 1, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, tex);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------+
|
||||
// UpdateTexture : Updates texture data.
|
||||
// -----------------+
|
||||
|
@ -1494,6 +1602,7 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
|
|||
// Upload a texture
|
||||
GLuint num = pTexInfo->downloaded;
|
||||
boolean update = true;
|
||||
const boolean applyPadding = mag_filter == GL_LINEAR || min_filter == GL_LINEAR;
|
||||
|
||||
INT32 w = pTexInfo->width, h = pTexInfo->height;
|
||||
INT32 i, j;
|
||||
|
@ -1548,11 +1657,26 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (applyPadding)
|
||||
PadRGBABitmap(tex, w, h);
|
||||
}
|
||||
else if (pTexInfo->format == GL_TEXFMT_RGBA)
|
||||
{
|
||||
// Directly upload the texture data without any kind of conversion.
|
||||
ptex = pImgData;
|
||||
|
||||
// However, it does need to be copied to a buffer for generating mipmaps and padding
|
||||
if (MipMap || applyPadding)
|
||||
{
|
||||
AllocTextureBuffer(pTexInfo);
|
||||
tex = textureBuffer;
|
||||
memcpy(tex, ptex, w * h * 4);
|
||||
ptex = tex;
|
||||
|
||||
if (applyPadding)
|
||||
PadRGBABitmap(tex, w, h);
|
||||
}
|
||||
}
|
||||
else if (pTexInfo->format == GL_TEXFMT_ALPHA_INTENSITY_88)
|
||||
{
|
||||
|
@ -1616,9 +1740,14 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
|
|||
pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0);
|
||||
if (pTexInfo->flags & TF_TRANSPARENT)
|
||||
{
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff
|
||||
}
|
||||
else
|
||||
{
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4);
|
||||
GenerateMipmaps(w, h, tex, 4);
|
||||
}
|
||||
//pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR);
|
||||
}
|
||||
else
|
||||
|
@ -1638,9 +1767,14 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
|
|||
pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex);
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0);
|
||||
if (pTexInfo->flags & TF_TRANSPARENT)
|
||||
{
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff
|
||||
}
|
||||
else
|
||||
{
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4);
|
||||
GenerateMipmaps(w, h, tex, 4);
|
||||
}
|
||||
//pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR);
|
||||
}
|
||||
else
|
||||
|
@ -1660,9 +1794,14 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
|
|||
// Control the mipmap level of detail
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); // the lower the number, the higer the detail
|
||||
if (pTexInfo->flags & TF_TRANSPARENT)
|
||||
{
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff
|
||||
}
|
||||
else
|
||||
{
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 5);
|
||||
GenerateMipmaps(w, h, tex, 5);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue