diff --git a/source/common/textures/texture.cpp b/source/common/textures/texture.cpp index d958ee265..dc321d04b 100644 --- a/source/common/textures/texture.cpp +++ b/source/common/textures/texture.cpp @@ -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; } diff --git a/source/common/textures/textures.h b/source/common/textures/textures.h index 74473b161..20c9c497f 100644 --- a/source/common/textures/textures.h +++ b/source/common/textures/textures.h @@ -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; }; diff --git a/source/core/textures/buildtiles.cpp b/source/core/textures/buildtiles.cpp index 7392ef603..f808e7690 100644 --- a/source/core/textures/buildtiles.cpp +++ b/source/core/textures/buildtiles.cpp @@ -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 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 FTileTexture::Get8BitPixels(bool alphatex) +TArray FTileTexture::CreatePalettedPixels(int conversion) { TArray buffer(Width * Height, true); auto p = GetRawData(); @@ -106,19 +104,19 @@ TArray FTileTexture::Get8BitPixels(bool alphatex) //========================================================================== // -// Tile textures are owned by their containing file object. +// // //========================================================================== -FArtTile* GetTileTexture(const char* name, const TArray& backingstore, uint32_t offset, int width, int height) +static FTexture* GetTileTexture(const char* name, const TArray& 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(tex); - if (!wtex->Resize(width, height)) return nullptr; + auto wtex = static_cast(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(tex); + auto wtex = static_cast(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(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); diff --git a/source/core/textures/buildtiles.h b/source/core/textures/buildtiles.h index e4d731e17..1251a71d5 100644 --- a/source/core/textures/buildtiles.h +++ b/source/core/textures/buildtiles.h @@ -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 Get8BitPixels(bool alphatex) override; - FBitmap GetBgraBitmap(const PalEntry* remap, int* trans = nullptr) override; - //bool GetTranslucency() override { return false; } + virtual TArray CreatePalettedPixels(int conversion); + virtual int CopyPixels(FBitmap* bmp, int conversion); // This will always ignore 'luminance'. }; //========================================================================== @@ -93,7 +95,8 @@ public: FArtTile(const TArray& 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& 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; diff --git a/source/core/textures/imagetexture.cpp b/source/core/textures/imagetexture.cpp index 9754ff0ea..805cb64ca 100644 --- a/source/core/textures/imagetexture.cpp +++ b/source/core/textures/imagetexture.cpp @@ -88,6 +88,25 @@ TArray 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 {