- use image sources, not textures to manage Build tiles.

The font manager and texture compositor need this - they cannot work off non-image-backed textures.
This commit is contained in:
Christoph Oelckers 2020-04-10 18:17:26 +02:00
parent a223535f86
commit 0179029ed1
5 changed files with 92 additions and 54 deletions

View file

@ -721,19 +721,16 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags)
//
//===========================================================================
bool FTexture::GetTranslucency()
bool FTexture::DetermineTranslucency()
{
if (bTranslucent == -1)
if (!bHasCanvas)
{
if (!bHasCanvas)
{
// This will calculate all we need, so just discard the result.
CreateTexBuffer(0);
}
else
{
bTranslucent = 0;
}
// This will calculate all we need, so just discard the result.
CreateTexBuffer(0);
}
else
{
bTranslucent = 0;
}
return !!bTranslucent;
}

View file

@ -438,7 +438,12 @@ protected:
public:
FTextureBuffer CreateTexBuffer(int translation, int flags = 0);
FTextureBuffer CreateTexBuffer(const PalEntry* translation, int flags = 0);
bool GetTranslucency();
virtual bool DetermineTranslucency();
bool GetTranslucency()
{
return bTranslucent != -1 ? bTranslucent : DetermineTranslucency();
}
FMaterial* GetMaterial(int num)
{
return Material[num];
@ -535,6 +540,7 @@ public:
FImageSource* GetImage() const override { return mImage; }
FBitmap GetBgraBitmap(const PalEntry* p, int* trans) override;
bool DetermineTranslucency() override;
};

View file

@ -81,21 +81,19 @@ picanm_t tileConvertAnimFormat(int32_t const picanimraw, int* lo, int* to)
//
//==========================================================================
FBitmap FTileTexture::GetBgraBitmap(const PalEntry* remap, int* ptrans)
int FTileTexture::CopyPixels(FBitmap* bmp, int conversion)
{
FBitmap bmp;
TArray<uint8_t> buffer;
bmp.Create(Width, Height);
bmp->Create(Width, Height);
auto ppix = GetRawData();
if (ppix)
{
if (remap == nullptr) remap = GPalette.BaseColors;
bmp.CopyPixelData(0, 0, ppix, Width, Height, Height, 1, 0, remap);
bmp->CopyPixelData(0, 0, ppix, Width, Height, Height, 1, 0, GPalette.BaseColors);
}
return bmp;
return 0;
}
TArray<uint8_t> FTileTexture::Get8BitPixels(bool alphatex)
TArray<uint8_t> FTileTexture::CreatePalettedPixels(int conversion)
{
TArray<uint8_t> buffer(Width * Height, true);
auto p = GetRawData();
@ -106,19 +104,19 @@ TArray<uint8_t> FTileTexture::Get8BitPixels(bool alphatex)
//==========================================================================
//
// Tile textures are owned by their containing file object.
//
//
//==========================================================================
FArtTile* GetTileTexture(const char* name, const TArray<uint8_t>& backingstore, uint32_t offset, int width, int height)
static FTexture* GetTileTexture(const char* name, const TArray<uint8_t>& backingstore, uint32_t offset, int width, int height)
{
auto tex = new FArtTile(backingstore, offset, width, height);
if (tex)
{
tex->SetName(name);
return new FImageTexture(tex, name);
}
return tex;
return nullptr;
}
//==========================================================================
@ -453,7 +451,7 @@ FTexture* BuildTiles::ValidateCustomTile(int tilenum, ReplacementType type)
// view tilting in the software renderer (this should just use a local buffer instead of relying on the texture manager.)
// Movie playback (like thumbnails this should bypass the texture manager entirely.)
// Blood's 'lens' effect (apparently MP only) - combination of a camera texture with a distortion map - should be made a shader effect to be applied to the camera texture.
replacement = new FWritableTile;
replacement = new FImageTexture(new FWritableTile);
}
else if (type == ReplacementType::Restorable)
{
@ -465,7 +463,7 @@ FTexture* BuildTiles::ValidateCustomTile(int tilenum, ReplacementType type)
// All of these effects should probably be redone without actual texture hacking...
if (tile->GetTexelWidth() == 0 || tile->GetTexelHeight() == 0) return nullptr; // The base must have a size for this to work.
// todo: invalidate hardware textures for tile.
replacement = new FRestorableTile(tile);
replacement = new FImageTexture(new FRestorableTile(tile->GetImage()));
}
else if (type == ReplacementType::Canvas)
{
@ -500,8 +498,9 @@ uint8_t* BuildTiles::tileCreate(int tilenum, int width, int height)
if (width <= 0 || height <= 0) return nullptr;
auto tex = ValidateCustomTile(tilenum, ReplacementType::Writable);
if (tex == nullptr) return nullptr;
auto wtex = static_cast<FWritableTile*>(tex);
if (!wtex->Resize(width, height)) return nullptr;
auto wtex = static_cast<FWritableTile*>(tex->GetImage());
if (!wtex->ResizeImage(width, height)) return nullptr;
tex->SetSize(width, height);
return wtex->GetRawData();
}
@ -515,7 +514,7 @@ uint8_t* BuildTiles::tileCreate(int tilenum, int width, int height)
uint8_t* BuildTiles::tileMakeWritable(int num)
{
auto tex = ValidateCustomTile(num, ReplacementType::Restorable);
auto wtex = static_cast<FWritableTile*>(tex);
auto wtex = static_cast<FWritableTile*>(tex->GetImage());
return wtex ? wtex->GetRawData() : nullptr;
}
@ -528,13 +527,14 @@ uint8_t* BuildTiles::tileMakeWritable(int num)
int32_t tileGetCRC32(int tileNum)
{
if ((unsigned)tileNum >= (unsigned)MAXTILES) return 0;
auto tile = tileGetTexture(tileNum);
if (!tile || TileFiles.tiledata[tileNum].replacement != ReplacementType::Art) return 0; // only consider original ART tiles.
auto pixels = tile->Get8BitPixels(false);
if (!pixels.Size()) return 0;
int size = tile->GetTexelWidth() * tile->GetTexelHeight();
auto tile = dynamic_cast<FArtTile*>(TileFiles.tiledata[tileNum].texture->GetImage()); // only consider original ART tiles.
if (!tile) return 0;
auto pixels = tile->GetRawData();
if (!pixels) return 0;
auto size = tile->GetWidth() * tile->GetHeight();
if (size == 0) return 0;
return crc32(0, (const Bytef*)pixels.Data(), size);
return crc32(0, (const Bytef*)pixels, size);
}
@ -612,7 +612,7 @@ void tileCopy(int tile, int source, int pal, int xoffset, int yoffset, int flags
pixel = remap[pixel];
}
}
tex = new FLooseTile(buffer, tex->GetTexelWidth(), tex->GetTexelHeight());
tex = new FImageTexture(new FLooseTile(buffer, tex->GetTexelWidth(), tex->GetTexelHeight()));
picanm = &TileFiles.tiledata[tile].picanm;
TileFiles.AddTile(tile, tex);
}
@ -709,7 +709,7 @@ void tileSetDummy(int tile, int width, int height)
}
else if (width > 0 && height > 0)
{
auto dtile = new FDummyTile(width, height);
auto dtile = new FImageTexture(new FDummyTile(width, height));
TileFiles.AddTile(tile, dtile);
}
}
@ -732,6 +732,15 @@ int BuildTiles::findUnusedTile(void)
return -1;
}
//==========================================================================
//
// fixme: This *really* needs to be done by rotating the texture coordinates,
// not by creating an entirely new texture.
// Unfortunately it's in all the wrong place in the rendering code so it
// has to wait for later.
//
//==========================================================================
int BuildTiles::tileCreateRotated(int tileNum)
{
if ((unsigned)tileNum >= MAXTILES) return tileNum;
@ -754,7 +763,7 @@ int BuildTiles::tileCreateRotated(int tileNum)
*(dst + y * width + xofs) = *(src + y + yofs);
}
auto dtex = new FLooseTile(dbuffer, tex->GetTexelHeight(), tex->GetTexelWidth());
auto dtex = new FImageTexture(new FLooseTile(dbuffer, tex->GetTexelHeight(), tex->GetTexelWidth()));
int index = findUnusedTile();
bool mapart = TileFiles.tiledata[tileNum].texture != TileFiles.tiledata[tileNum].backup;
TileFiles.AddTile(index, dtex, mapart);

View file

@ -1,6 +1,7 @@
#pragma once
#include "textures.h"
#include "image.h"
#include "i_time.h"
#include "compat.h"
@ -67,16 +68,17 @@ struct HightileReplacement
uint16_t palnum, flags;
};
class FTileTexture : public FTexture
class FTileTexture : public FImageSource
{
public:
FTileTexture()
{}
{
bUseGamePalette = true;
bTranslucent = false;
}
virtual uint8_t* GetRawData() = 0;
void SetName(const char* name) { Name = name; }
TArray<uint8_t> Get8BitPixels(bool alphatex) override;
FBitmap GetBgraBitmap(const PalEntry* remap, int* trans = nullptr) override;
//bool GetTranslucency() override { return false; }
virtual TArray<uint8_t> CreatePalettedPixels(int conversion);
virtual int CopyPixels(FBitmap* bmp, int conversion); // This will always ignore 'luminance'.
};
//==========================================================================
@ -93,7 +95,8 @@ public:
FArtTile(const TArray<uint8_t>& backingstore, uint32_t offset, int width, int height)
: RawPixels(backingstore), Offset(offset)
{
SetSize(width, height);
Width = width;
Height = height;
}
uint8_t* GetRawData() override final
{
@ -114,7 +117,8 @@ public:
FLooseTile(TArray<uint8_t>& store, int width, int height)
{
RawPixels = std::move(store);
SetSize(width, height);
Width = width;
Height = height;
}
uint8_t* GetRawData() override
@ -135,7 +139,8 @@ class FDummyTile : public FTileTexture
public:
FDummyTile(int width, int height)
{
SetSize(width, height);
Width = width;
Height = height;
}
uint8_t* GetRawData() override
@ -166,7 +171,7 @@ public:
return buffer.Data();
}
bool Resize(int w, int h)
bool ResizeImage(int w, int h)
{
if (w <= 0 || h <= 0)
{
@ -175,7 +180,8 @@ public:
}
else
{
SetSize(w, h);
Width = w;
Height = h;
buffer.Resize(w * h);
return true;
}
@ -191,20 +197,21 @@ public:
class FRestorableTile : public FWritableTile
{
FTexture* Base;
FImageSource* Base;
public:
FRestorableTile(FTexture* base)
FRestorableTile(FImageSource* base)
{
Base = base;
CopySize(base);
Resize(GetTexelWidth(), GetTexelHeight());
CopySize(*base);
ResizeImage(Width, Height);
Reload();
}
void Reload()
{
buffer = std::move(Base->Get8BitPixels(false));
buffer = std::move(Base->GetPalettedPixels(0));
}
};
@ -274,7 +281,7 @@ struct BuildTiles
BuildTiles()
{
Placeholder = new FDummyTile(0, 0);
Placeholder = new FImageTexture(new FDummyTile(0, 0));
for (auto& tile : tiledata)
{
tile.backup = tile.texture = Placeholder;

View file

@ -88,6 +88,25 @@ TArray<uint8_t> FImageTexture::Get8BitPixels(bool alpha)
return mImage->GetPalettedPixels(alpha ? alpha : bNoRemap0 ? FImageSource::noremap0 : FImageSource::normal);
}
//===========================================================================
//
// use the already known state of the underlying image to save time.
//
//===========================================================================
bool FImageTexture::DetermineTranslucency()
{
if (mImage->bTranslucent != -1)
{
bTranslucent = mImage->bTranslucent;
return !!bTranslucent;
}
else
{
return FTexture::DetermineTranslucency();
}
}
FTexture* CreateImageTexture(FImageSource* img, const char* name) noexcept
{