mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-04 10:03:36 +00:00
Modifications for mip-mapped textures load.
Treat specail case for Southern Swamp grass texture, Zelda MM, #2315
This commit is contained in:
parent
1e915af002
commit
35567da2ad
136
src/Textures.cpp
136
src/Textures.cpp
|
@ -1077,34 +1077,65 @@ void TextureCache::_getTextureDestData(CachedTexture& tmptex,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void doubleTexture(T* pTex, u32 width, u32 height)
|
||||||
|
{
|
||||||
|
std::vector<T> vData(width * height);
|
||||||
|
memcpy(vData.data(), pTex, width * height * sizeof(T));
|
||||||
|
u32 srcIdx = 0;
|
||||||
|
u32 dstIdx = 0;
|
||||||
|
for (u32 y = 0; y < height; ++y) {
|
||||||
|
const u32 srcIdxCur = srcIdx;
|
||||||
|
for (u32 x = 0; x < width; ++x) {
|
||||||
|
pTex[dstIdx++] = vData[srcIdx];
|
||||||
|
pTex[dstIdx++] = vData[srcIdx++];
|
||||||
|
}
|
||||||
|
srcIdx = srcIdxCur;
|
||||||
|
for (u32 x = 0; x < width; ++x) {
|
||||||
|
pTex[dstIdx++] = vData[srcIdx];
|
||||||
|
pTex[dstIdx++] = vData[srcIdx++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
|
void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
|
||||||
{
|
{
|
||||||
u64 ricecrc = 0;
|
u64 ricecrc = 0;
|
||||||
if (_loadHiresTexture(_tile, _pTexture, ricecrc))
|
if (_loadHiresTexture(_tile, _pTexture, ricecrc))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
u16 line;
|
s32 mipLevel = 0;
|
||||||
GetTexelFunc GetTexel;
|
bool force32bitFormat = false;
|
||||||
InternalColorFormatParam glInternalFormat;
|
_pTexture->max_level = 0;
|
||||||
DatatypeParam glType;
|
|
||||||
u32 sizeShift;
|
|
||||||
|
|
||||||
const TextureLoadParameters & loadParams =
|
if (config.generalEmulation.enableLOD != 0 && gSP.texture.level > 1) {
|
||||||
ImageFormat::get().tlp[gDP.otherMode.textureLUT][_pTexture->size][_pTexture->format];
|
if (_tile == 0) {
|
||||||
if (loadParams.autoFormat == internalcolorFormat::RGBA8) {
|
_pTexture->max_level = 0;
|
||||||
sizeShift = 2;
|
} else {
|
||||||
_pTexture->textureBytes = (_pTexture->width * _pTexture->height) << sizeShift;
|
_pTexture->max_level = static_cast<u8>(gSP.texture.level - 1);
|
||||||
GetTexel = loadParams.Get32;
|
const u16 dim = std::max(_pTexture->width, _pTexture->height);
|
||||||
glInternalFormat = loadParams.glInternalFormat32;
|
while (dim < static_cast<u16>(1 << _pTexture->max_level))
|
||||||
glType = loadParams.glType32;
|
--_pTexture->max_level;
|
||||||
} else {
|
|
||||||
sizeShift = 1;
|
auto texFormat = gDP.tiles[gSP.texture.tile + 1].format;
|
||||||
_pTexture->textureBytes = (_pTexture->width * _pTexture->height) << sizeShift;
|
auto texSize = gDP.tiles[gSP.texture.tile + 1].size;
|
||||||
GetTexel = loadParams.Get16;
|
u32 tileMipLevel = gSP.texture.tile + 2;
|
||||||
glInternalFormat = loadParams.glInternalFormat16;
|
while (!force32bitFormat && (tileMipLevel < gSP.texture.tile + gSP.texture.level)) {
|
||||||
glType = loadParams.glType16;
|
gDPTile const& mipTile = gDP.tiles[tileMipLevel++];
|
||||||
|
force32bitFormat = texFormat != mipTile.format || texSize != mipTile.size;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 sizeShift = 1;
|
||||||
|
{
|
||||||
|
const TextureLoadParameters & loadParams =
|
||||||
|
ImageFormat::get().tlp[gDP.otherMode.textureLUT][_pTexture->size][_pTexture->format];
|
||||||
|
if (force32bitFormat || loadParams.autoFormat == internalcolorFormat::RGBA8)
|
||||||
|
sizeShift = 2;
|
||||||
|
}
|
||||||
|
_pTexture->textureBytes = (_pTexture->width * _pTexture->height) << sizeShift;
|
||||||
|
|
||||||
// RAII holder for texture data
|
// RAII holder for texture data
|
||||||
class TexData
|
class TexData
|
||||||
{
|
{
|
||||||
|
@ -1127,29 +1158,54 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
|
||||||
u32 *pData = NULL;
|
u32 *pData = NULL;
|
||||||
} texData(_pTexture->textureBytes);
|
} texData(_pTexture->textureBytes);
|
||||||
|
|
||||||
|
GetTexelFunc GetTexel;
|
||||||
|
InternalColorFormatParam glInternalFormat;
|
||||||
|
DatatypeParam glType;
|
||||||
|
|
||||||
s32 mipLevel = 0;
|
auto getLoadParams = [&](u16 _format, u16 _size)
|
||||||
_pTexture->max_level = 0;
|
{
|
||||||
|
const TextureLoadParameters & loadParams =
|
||||||
if (config.generalEmulation.enableLOD != 0 && gSP.texture.level > 1) {
|
ImageFormat::get().tlp[gDP.otherMode.textureLUT][_size][_format];
|
||||||
if (_tile == 0) {
|
if (force32bitFormat || loadParams.autoFormat == internalcolorFormat::RGBA8) {
|
||||||
_pTexture->max_level = 0;
|
GetTexel = loadParams.Get32;
|
||||||
} else {
|
glInternalFormat = loadParams.glInternalFormat32;
|
||||||
_pTexture->max_level = static_cast<u8>(gSP.texture.level - 1);
|
glType = loadParams.glType32;
|
||||||
const u16 dim = std::max(_pTexture->width, _pTexture->height);
|
|
||||||
while (dim < static_cast<u16>(1 << _pTexture->max_level))
|
|
||||||
--_pTexture->max_level;
|
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
|
GetTexel = loadParams.Get16;
|
||||||
|
glInternalFormat = loadParams.glInternalFormat16;
|
||||||
|
glType = loadParams.glType16;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
ObjectHandle name;
|
CachedTexture tmptex = *_pTexture;
|
||||||
CachedTexture tmptex(name);
|
u16 line = tmptex.line;
|
||||||
memcpy(&tmptex, _pTexture, sizeof(CachedTexture));
|
|
||||||
|
|
||||||
line = tmptex.line;
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
_getTextureDestData(tmptex, texData.get(), glInternalFormat, GetTexel, &line);
|
getLoadParams(tmptex.format, tmptex.size);
|
||||||
|
{
|
||||||
|
const u32 tileMipLevel = gSP.texture.tile + mipLevel + 1;
|
||||||
|
gDPTile & mipTile = gDP.tiles[tileMipLevel];
|
||||||
|
if (tmptex.max_level > 1 &&
|
||||||
|
tmptex.width == (mipTile.lrs - mipTile.uls + 1) * 2 &&
|
||||||
|
tmptex.height == (mipTile.lrt - mipTile.ult + 1) * 2)
|
||||||
|
{
|
||||||
|
// Special case for Southern Swamp grass texture, Zelda MM. See #2315
|
||||||
|
const u16 texWidth = tmptex.width;
|
||||||
|
const u16 texHeight = tmptex.height;
|
||||||
|
tmptex.width = mipTile.lrs - mipTile.uls + 1;
|
||||||
|
tmptex.height = mipTile.lrt - mipTile.ult + 1;
|
||||||
|
_getTextureDestData(tmptex, texData.get(), glInternalFormat, GetTexel, &line);
|
||||||
|
if (sizeShift == 2)
|
||||||
|
doubleTexture<u32>(texData.get(), tmptex.width, tmptex.height);
|
||||||
|
else
|
||||||
|
doubleTexture<u16>((u16*)texData.get(), tmptex.width, tmptex.height);
|
||||||
|
tmptex.width = texWidth;
|
||||||
|
tmptex.height = texHeight;
|
||||||
|
} else {
|
||||||
|
_getTextureDestData(tmptex, texData.get(), glInternalFormat, GetTexel, &line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((config.generalEmulation.hacks&hack_LoadDepthTextures) != 0 && gDP.colorImage.address == gDP.depthImageAddress) {
|
if ((config.generalEmulation.hacks&hack_LoadDepthTextures) != 0 && gDP.colorImage.address == gDP.depthImageAddress) {
|
||||||
_loadDepthTexture(_pTexture, (u16*)texData.get());
|
_loadDepthTexture(_pTexture, (u16*)texData.get());
|
||||||
|
@ -1239,6 +1295,8 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
|
||||||
tmptex.palette = mipTile.palette;
|
tmptex.palette = mipTile.palette;
|
||||||
tmptex.maskS = mipTile.masks;
|
tmptex.maskS = mipTile.masks;
|
||||||
tmptex.maskT = mipTile.maskt;
|
tmptex.maskT = mipTile.maskt;
|
||||||
|
tmptex.format = mipTile.format;
|
||||||
|
tmptex.size = mipTile.size;
|
||||||
TileSizes sizes;
|
TileSizes sizes;
|
||||||
_calcTileSizes(tileMipLevel, sizes, nullptr);
|
_calcTileSizes(tileMipLevel, sizes, nullptr);
|
||||||
tmptex.clampWidth = sizes.clampWidth;
|
tmptex.clampWidth = sizes.clampWidth;
|
||||||
|
@ -1529,6 +1587,7 @@ void TextureCache::update(u32 _t)
|
||||||
TileSizes sizes;
|
TileSizes sizes;
|
||||||
_calcTileSizes(_t, sizes, gDP.loadTile);
|
_calcTileSizes(_t, sizes, gDP.loadTile);
|
||||||
TextureParams params;
|
TextureParams params;
|
||||||
|
const u32 texLevel = _t == 0 ? 0U : gSP.texture.level;
|
||||||
params.flags = pTile->masks |
|
params.flags = pTile->masks |
|
||||||
(pTile->maskt << 4) |
|
(pTile->maskt << 4) |
|
||||||
(pTile->mirrors << 8) |
|
(pTile->mirrors << 8) |
|
||||||
|
@ -1537,7 +1596,8 @@ void TextureCache::update(u32 _t)
|
||||||
(pTile->clampt << 11) |
|
(pTile->clampt << 11) |
|
||||||
(pTile->size << 12) |
|
(pTile->size << 12) |
|
||||||
(pTile->format << 14) |
|
(pTile->format << 14) |
|
||||||
(gDP.otherMode.textureLUT << 17);
|
(gDP.otherMode.textureLUT << 17) |
|
||||||
|
(texLevel << 19);
|
||||||
params.width = sizes.width;
|
params.width = sizes.width;
|
||||||
params.height = sizes.height;
|
params.height = sizes.height;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user