mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-27 14:32:26 +00:00
175 lines
4.1 KiB
C++
175 lines
4.1 KiB
C++
#pragma once
|
|
|
|
#include "tarray.h"
|
|
#include "hw_ihwtexture.h"
|
|
#include "palettecontainer.h"
|
|
|
|
struct FTextureBuffer;
|
|
class IHardwareTexture;
|
|
|
|
enum ECreateTexBufferFlags
|
|
{
|
|
CTF_Expand = 1, // create buffer with a one-pixel wide border
|
|
CTF_Upscale = 2, // Upscale the texture
|
|
CTF_CreateMask = 3, // Flags that are relevant for hardware texture creation.
|
|
CTF_Indexed = 4, // Tell the backend to create an indexed texture.
|
|
CTF_CheckOnly = 8, // Only runs the code to get a content ID but does not create a texture. Can be used to access a caching system for the hardware textures.
|
|
CTF_ProcessData = 16, // run postprocessing on the generated buffer. This is only needed when using the data for a hardware texture.
|
|
};
|
|
|
|
class FHardwareTextureContainer
|
|
{
|
|
public:
|
|
enum
|
|
{
|
|
MAX_TEXTURES = 16
|
|
};
|
|
|
|
private:
|
|
struct TranslatedTexture
|
|
{
|
|
IHardwareTexture *hwTexture = nullptr;
|
|
int translation = 0;
|
|
bool precacheMarker; // This is used to check whether a texture has been hit by the precacher, so that the cleanup code can delete the unneeded ones.
|
|
|
|
void Delete()
|
|
{
|
|
if (hwTexture) delete hwTexture;
|
|
hwTexture = nullptr;
|
|
}
|
|
|
|
~TranslatedTexture()
|
|
{
|
|
Delete();
|
|
}
|
|
|
|
void MarkForPrecache(bool on)
|
|
{
|
|
precacheMarker = on;
|
|
}
|
|
|
|
bool isMarkedForPreache() const
|
|
{
|
|
return precacheMarker;
|
|
}
|
|
};
|
|
|
|
private:
|
|
|
|
TranslatedTexture hwDefTex[4];
|
|
TArray<TranslatedTexture> hwTex_Translated;
|
|
|
|
TranslatedTexture * GetTexID(int translation, int scaleflags)
|
|
{
|
|
// Allow negative indices to pass through unchanged.
|
|
// This is needed for allowing the client to allocate slots that aren't matched to a palette, e.g. Build's indexed variants.
|
|
if (translation >= 0)
|
|
{
|
|
if (!IsLuminosityTranslation(translation))
|
|
{
|
|
auto remap = GPalette.TranslationToTable(translation);
|
|
translation = remap == nullptr ? 0 : remap->Index;
|
|
}
|
|
else
|
|
{
|
|
// only needs to preserve the color range plus an identifier for marking this a luminosity translation.
|
|
translation = ((translation >> 16) & 0x3fff) | 0xff0000;
|
|
}
|
|
}
|
|
else translation &= ~0x7fffffff;
|
|
|
|
if (translation == 0 && !(scaleflags & CTF_Upscale))
|
|
{
|
|
return &hwDefTex[scaleflags];
|
|
}
|
|
|
|
translation |= (scaleflags << 24);
|
|
// normally there aren't more than very few different
|
|
// translations here so this isn't performance critical.
|
|
unsigned index = hwTex_Translated.FindEx([=](auto &element)
|
|
{
|
|
return element.translation == translation;
|
|
});
|
|
if (index < hwTex_Translated.Size())
|
|
{
|
|
return &hwTex_Translated[index];
|
|
}
|
|
|
|
int add = hwTex_Translated.Reserve(1);
|
|
auto item = &hwTex_Translated[add];
|
|
item->translation = translation;
|
|
return item;
|
|
}
|
|
|
|
public:
|
|
void Clean()
|
|
{
|
|
hwDefTex[0].Delete();
|
|
hwDefTex[1].Delete();
|
|
hwTex_Translated.Clear();
|
|
}
|
|
|
|
IHardwareTexture * GetHardwareTexture(int translation, int scaleflags)
|
|
{
|
|
auto tt = GetTexID(translation, scaleflags);
|
|
return tt->hwTexture;
|
|
}
|
|
|
|
void AddHardwareTexture(int translation, int scaleflags, IHardwareTexture *tex)
|
|
{
|
|
auto tt = GetTexID(translation, scaleflags);
|
|
tt->Delete();
|
|
tt->hwTexture =tex;
|
|
}
|
|
|
|
//===========================================================================
|
|
//
|
|
// Deletes all allocated resources and considers translations
|
|
//
|
|
//===========================================================================
|
|
|
|
void CleanUnused()
|
|
{
|
|
for (auto& tt : hwDefTex)
|
|
{
|
|
if (!tt.isMarkedForPreache()) tt.Delete();
|
|
}
|
|
for (int i = hwTex_Translated.Size()-1; i>= 0; i--)
|
|
{
|
|
auto& tt = hwTex_Translated[i];
|
|
if (!tt.isMarkedForPreache())
|
|
{
|
|
hwTex_Translated.Delete(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
void UnmarkAll()
|
|
{
|
|
for (auto& tt : hwDefTex)
|
|
{
|
|
if (!tt.isMarkedForPreache()) tt.MarkForPrecache(false);
|
|
}
|
|
for (auto& tt : hwTex_Translated)
|
|
{
|
|
if (!tt.isMarkedForPreache()) tt.MarkForPrecache(false);
|
|
}
|
|
}
|
|
|
|
void MarkForPrecache(int translation, int scaleflags)
|
|
{
|
|
auto tt = GetTexID(translation, scaleflags);
|
|
tt->MarkForPrecache(true);
|
|
}
|
|
|
|
|
|
template<class T>
|
|
void Iterate(T callback)
|
|
{
|
|
for (auto & t : hwDefTex) if (t.hwTexture) callback(t.hwTexture);
|
|
for (auto & t : hwTex_Translated) if (t.hwTexture) callback(t.hwTexture);
|
|
}
|
|
|
|
|
|
};
|
|
|