Native mipmap support to FTexture
This commit is contained in:
parent
d15af1524c
commit
c235de5c22
9 changed files with 171 additions and 196 deletions
|
|
@ -3672,106 +3672,6 @@ void ApplySpecialColormapRGBACommand::Execute(DrawerThread *thread)
|
|||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <map>
|
||||
|
||||
class MipmappedTexture
|
||||
{
|
||||
public:
|
||||
MipmappedTexture(FTexture *texture)
|
||||
{
|
||||
const uint32_t *base_texture = texture->GetPixelsBgra();
|
||||
Width = texture->GetWidth();
|
||||
Height = texture->GetHeight();
|
||||
Levels = MAX(texture->WidthBits, texture->HeightBits);
|
||||
|
||||
// I bet there is a better way to calculate this..
|
||||
int buffersize = 0;
|
||||
for (int i = 0; i < Levels; i++)
|
||||
{
|
||||
int w = MAX(Width >> i, 2); // 2 instead of 1 because we texelGather in 2x2 blocks
|
||||
int h = MAX(Height >> i, 2);
|
||||
buffersize += w * h;
|
||||
}
|
||||
Pixels.resize(buffersize);
|
||||
|
||||
// Base level:
|
||||
memcpy(Pixels.data(), base_texture, Width * Height * 4);
|
||||
|
||||
// Mipmap levels:
|
||||
uint32_t *src = Pixels.data();
|
||||
uint32_t *dest = src + Width * Height;
|
||||
for (int i = 1; i < Levels; i++)
|
||||
{
|
||||
int srch = MAX(Height >> (i - 1), 2);
|
||||
int w = MAX(Width >> i, 2);
|
||||
int h = MAX(Height >> i, 2);
|
||||
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
uint32_t src00 = src[y * 2 + x * 2 * srch];
|
||||
uint32_t src01 = src[y * 2 + 1 + x * 2 * srch];
|
||||
uint32_t src10 = src[y * 2 + (x * 2 + 1) * srch];
|
||||
uint32_t src11 = src[y * 2 + 1 + (x * 2 + 1) * srch];
|
||||
|
||||
uint32_t alpha = (APART(src00) + APART(src01) + APART(src10) + APART(src11) + 2) / 4;
|
||||
uint32_t red = (RPART(src00) + RPART(src01) + RPART(src10) + RPART(src11) + 2) / 4;
|
||||
uint32_t green = (GPART(src00) + GPART(src01) + GPART(src10) + GPART(src11) + 2) / 4;
|
||||
uint32_t blue = (BPART(src00) + BPART(src01) + BPART(src10) + BPART(src11) + 2) / 4;
|
||||
|
||||
dest[y + x * h] = (alpha << 24) | (red << 16) | (green << 8) | blue;
|
||||
}
|
||||
}
|
||||
|
||||
src = dest;
|
||||
dest += w * h;
|
||||
}
|
||||
}
|
||||
|
||||
int Width = 0;
|
||||
int Height = 0;
|
||||
int Levels = 0;
|
||||
std::vector<uint32_t> Pixels;
|
||||
};
|
||||
|
||||
class TextureMipmapper
|
||||
{
|
||||
public:
|
||||
static std::map<FTexture*, std::shared_ptr<MipmappedTexture>> &Textures()
|
||||
{
|
||||
static std::map<FTexture*, std::shared_ptr<MipmappedTexture>> textures;
|
||||
return textures;
|
||||
}
|
||||
};
|
||||
|
||||
void R_SetMipmappedSpanSource(FTexture *tex)
|
||||
{
|
||||
if (r_swtruecolor)
|
||||
{
|
||||
if (r_mipmap)
|
||||
{
|
||||
auto &mipmap = TextureMipmapper::Textures()[tex];
|
||||
if (!mipmap)
|
||||
mipmap = std::make_shared<MipmappedTexture>(tex);
|
||||
ds_source = (const BYTE*)mipmap->Pixels.data();
|
||||
}
|
||||
else
|
||||
{
|
||||
ds_source = (const BYTE*)tex->GetPixelsBgra();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ds_source = tex->GetPixels();
|
||||
}
|
||||
}
|
||||
|
||||
void R_ClearMipmapCache()
|
||||
{
|
||||
TextureMipmapper::Textures().clear();
|
||||
}
|
||||
|
||||
void R_BeginDrawerCommands()
|
||||
{
|
||||
DrawerCommandQueue::Begin();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue