mirror of
https://github.com/ZDoom/Raze.git
synced 2025-01-18 14:41:55 +00:00
- transitioned to using GZDoom's texture creation code.
Also added support for creating indexed textures directly into CreateTexBuffer, where this functionality can be shared. As an added plus, brightmaps are working again, this time with less hackery.
This commit is contained in:
parent
66809ca9f4
commit
594ec6626c
9 changed files with 106 additions and 170 deletions
|
@ -302,7 +302,7 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i
|
|||
{
|
||||
int usebright = false;
|
||||
|
||||
bool needmipmap = (clampmode <= CLAMP_XY);
|
||||
bool needmipmap = (clampmode <= CLAMP_XY) && !forcenofilter;
|
||||
|
||||
// Bind it to the system.
|
||||
if (!Bind(texunit, needmipmap))
|
||||
|
@ -331,6 +331,7 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (forcenofilter) clampmode += CLAMP_NOFILTER - CLAMP_NONE;
|
||||
GLRenderer->mSamplerManager->Bind(texunit, clampmode, 255);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -187,7 +187,7 @@ void FGameTexture::AddAutoMaterials()
|
|||
void FGameTexture::CreateDefaultBrightmap()
|
||||
{
|
||||
auto tex = GetTexture();
|
||||
if (flags & GTexf_BrightmapChecked)
|
||||
if (!(flags & GTexf_BrightmapChecked))
|
||||
{
|
||||
flags |= GTexf_BrightmapChecked;
|
||||
// Check for brightmaps
|
||||
|
|
|
@ -305,6 +305,13 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
FTexture* GetBrightmap()
|
||||
{
|
||||
if (Brightmap.get() || (flags & GTexf_BrightmapChecked)) return Brightmap.get();
|
||||
CreateDefaultBrightmap();
|
||||
return Brightmap.get();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
inline FGameTexture* MakeGameTexture(FTexture* tex, const char *name, ETextureType useType)
|
||||
|
|
|
@ -14,6 +14,7 @@ enum ECreateTexBufferFlags
|
|||
CTF_CreateMask = 3, // Flags that are relevant for hardware texture creation.
|
||||
CTF_ProcessData = 4, // run postprocessing on the generated buffer. This is only needed when using the data for a hardware 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_Indexed = 16 // Tell the backend to create an indexed texture.
|
||||
};
|
||||
|
||||
class FHardwareTextureContainer
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "formats/multipatchtexture.h"
|
||||
#include "texturemanager.h"
|
||||
#include "c_cvars.h"
|
||||
#include "imagehelpers.h"
|
||||
|
||||
// Wrappers to keep the definitions of these classes out of here.
|
||||
IHardwareTexture* CreateHardwareTexture(int numchannels);
|
||||
|
@ -323,66 +324,82 @@ bool FTexture::ProcessData(unsigned char* buffer, int w, int h, bool ispatch)
|
|||
FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags)
|
||||
{
|
||||
FTextureBuffer result;
|
||||
|
||||
unsigned char* buffer = nullptr;
|
||||
int W, H;
|
||||
int isTransparent = -1;
|
||||
bool checkonly = !!(flags & CTF_CheckOnly);
|
||||
|
||||
int exx = !!(flags & CTF_Expand);
|
||||
|
||||
W = GetWidth() + 2 * exx;
|
||||
H = GetHeight() + 2 * exx;
|
||||
|
||||
if (!checkonly)
|
||||
if (flags & CTF_Indexed)
|
||||
{
|
||||
buffer = new unsigned char[W * (H + 1) * 4];
|
||||
memset(buffer, 0, W * (H + 1) * 4);
|
||||
// Indexed textures will never be translated and never be scaled.
|
||||
int w = GetWidth(), h = GetHeight();
|
||||
|
||||
auto remap = translation <= 0 ? nullptr : GPalette.TranslationToTable(translation);
|
||||
if (remap) translation = remap->Index;
|
||||
FBitmap bmp(buffer, W * 4, W, H);
|
||||
auto store = Get8BitPixels(false);
|
||||
const uint8_t* p = store.Data();
|
||||
|
||||
int trans;
|
||||
auto Pixels = GetBgraBitmap(remap ? remap->Palette : nullptr, &trans);
|
||||
bmp.Blit(exx, exx, Pixels);
|
||||
result.mBuffer = new uint8_t[w * h];
|
||||
result.mWidth = w;
|
||||
result.mHeight = h;
|
||||
result.mContentId = 0;
|
||||
ImageHelpers::FlipNonSquareBlock(result.mBuffer, p, h, w, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char* buffer = nullptr;
|
||||
int W, H;
|
||||
int isTransparent = -1;
|
||||
bool checkonly = !!(flags & CTF_CheckOnly);
|
||||
|
||||
if (remap == nullptr)
|
||||
int exx = !!(flags & CTF_Expand);
|
||||
|
||||
W = GetWidth() + 2 * exx;
|
||||
H = GetHeight() + 2 * exx;
|
||||
|
||||
if (!checkonly)
|
||||
{
|
||||
CheckTrans(buffer, W * H, trans);
|
||||
isTransparent = bTranslucent;
|
||||
buffer = new unsigned char[W * (H + 1) * 4];
|
||||
memset(buffer, 0, W * (H + 1) * 4);
|
||||
|
||||
auto remap = translation <= 0 ? nullptr : GPalette.TranslationToTable(translation);
|
||||
if (remap) translation = remap->Index;
|
||||
FBitmap bmp(buffer, W * 4, W, H);
|
||||
|
||||
int trans;
|
||||
auto Pixels = GetBgraBitmap(remap ? remap->Palette : nullptr, &trans);
|
||||
bmp.Blit(exx, exx, Pixels);
|
||||
|
||||
if (remap == nullptr)
|
||||
{
|
||||
CheckTrans(buffer, W * H, trans);
|
||||
isTransparent = bTranslucent;
|
||||
}
|
||||
else
|
||||
{
|
||||
isTransparent = 0;
|
||||
// A translated image is not conclusive for setting the texture's transparency info.
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (GetImage())
|
||||
{
|
||||
isTransparent = 0;
|
||||
// A translated image is not conclusive for setting the texture's transparency info.
|
||||
FContentIdBuilder builder;
|
||||
builder.id = 0;
|
||||
builder.imageID = GetImage()->GetId();
|
||||
builder.translation = MAX(0, translation);
|
||||
builder.expand = exx;
|
||||
result.mContentId = builder.id;
|
||||
}
|
||||
else result.mContentId = 0; // for non-image backed textures this has no meaning so leave it at 0.
|
||||
|
||||
result.mBuffer = buffer;
|
||||
result.mWidth = W;
|
||||
result.mHeight = H;
|
||||
|
||||
// Only do postprocessing for image-backed textures. (i.e. not for the burn texture which can also pass through here.)
|
||||
if (GetImage() && flags & CTF_ProcessData)
|
||||
{
|
||||
if (flags & CTF_Upscale) CreateUpsampledTextureBuffer(result, !!isTransparent, checkonly);
|
||||
|
||||
if (!checkonly) ProcessData(result.mBuffer, result.mWidth, result.mHeight, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (GetImage())
|
||||
{
|
||||
FContentIdBuilder builder;
|
||||
builder.id = 0;
|
||||
builder.imageID = GetImage()->GetId();
|
||||
builder.translation = MAX(0, translation);
|
||||
builder.expand = exx;
|
||||
result.mContentId = builder.id;
|
||||
}
|
||||
else result.mContentId = 0; // for non-image backed textures this has no meaning so leave it at 0.
|
||||
|
||||
result.mBuffer = buffer;
|
||||
result.mWidth = W;
|
||||
result.mHeight = H;
|
||||
|
||||
// Only do postprocessing for image-backed textures. (i.e. not for the burn texture which can also pass through here.)
|
||||
if (GetImage() && flags & CTF_ProcessData)
|
||||
{
|
||||
if (flags & CTF_Upscale) CreateUpsampledTextureBuffer(result, !!isTransparent, checkonly);
|
||||
|
||||
if (!checkonly) ProcessData(result.mBuffer, result.mWidth, result.mHeight, false);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -138,7 +138,6 @@ void BuildTiles::Init()
|
|||
tile.picanm = {};
|
||||
tile.RotTile = { -1,-1 };
|
||||
tile.replacement = ReplacementType::Art;
|
||||
tile.NoBrightmapFlag.Zero();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -743,7 +742,7 @@ int BuildTiles::findUnusedTile(void)
|
|||
for (; lastUnusedTile >= 0; --lastUnusedTile)
|
||||
{
|
||||
auto tex = tileGetTexture(lastUnusedTile);
|
||||
if (!tex || tex->GetTexelWidth() <= 0 || tex->GetTexelHeight() <= 0) return lastUnusedTile;
|
||||
if (!tex || !tex->isValid()) return lastUnusedTile;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -265,7 +265,6 @@ struct TileDesc
|
|||
rottile_t RotTile;// = { -1,-1 };
|
||||
TArray<HightileReplacement> Hightiles;
|
||||
ReplacementType replacement;
|
||||
FixedBitArray<256> NoBrightmapFlag;
|
||||
};
|
||||
|
||||
struct BuildTiles
|
||||
|
|
|
@ -43,98 +43,26 @@
|
|||
#include "palettecontainer.h"
|
||||
#include "../../glbackend/glbackend.h"
|
||||
#include "texturemanager.h"
|
||||
#include "v_video.h"
|
||||
|
||||
// Test CVARs.
|
||||
CVAR(Int, fixpalette, -1, 0)
|
||||
CVAR(Int, fixpalswap, -1, 0)
|
||||
|
||||
template<class T>
|
||||
void FlipNonSquareBlock(T* dst, const T* src, int x, int y, int srcpitch)
|
||||
{
|
||||
for (int i = 0; i < x; ++i)
|
||||
{
|
||||
for (int j = 0; j < y; ++j)
|
||||
{
|
||||
dst[i * y + j] = src[i + j * srcpitch];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Create an indexed version of the requested texture
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
OpenGLRenderer::FHardwareTexture* GLInstance::CreateIndexedTexture(FGameTexture* tex)
|
||||
{
|
||||
vec2_t siz = { tex->GetTexelWidth(), tex->GetTexelHeight() };
|
||||
|
||||
auto store = tex->GetTexture()->Get8BitPixels(false);
|
||||
const uint8_t* p = store.Data();
|
||||
|
||||
auto glpic = GLInterface.NewTexture(1);
|
||||
|
||||
TArray<uint8_t> flipped(siz.x * siz.y, true);
|
||||
FlipNonSquareBlock(flipped.Data(), p, siz.y, siz.x, siz.y);
|
||||
glpic->CreateTexture(flipped.Data(), siz.x, siz.y, 15, false, tex->GetName());
|
||||
return glpic;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Create a true color version of the requested tile
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
OpenGLRenderer::FHardwareTexture* GLInstance::CreateTrueColorTexture(FGameTexture* tex, int palid, bool checkfulltransparency, bool rgb8bit)
|
||||
{
|
||||
if (tex == TexMan.GameByIndex(0))
|
||||
return nullptr;
|
||||
auto texbuffer = tex->GetTexture()->CreateTexBuffer(palid, checkfulltransparency? 0: CTF_ProcessData);
|
||||
// Check if the texture is fully transparent. When creating a brightmap such textures can be discarded.
|
||||
if (checkfulltransparency)
|
||||
{
|
||||
int siz = texbuffer.mWidth * texbuffer.mHeight * 4;
|
||||
bool found = false;
|
||||
for (int i = 3; i < siz; i+=4)
|
||||
{
|
||||
if (texbuffer.mBuffer[i] > 0)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) return nullptr;
|
||||
}
|
||||
|
||||
auto glpic = GLInterface.NewTexture(4);
|
||||
glpic->CreateTexture(texbuffer.mBuffer, texbuffer.mWidth, texbuffer.mHeight, 15, true, tex->GetName());
|
||||
return glpic;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Retrieve the texture to be used.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
OpenGLRenderer::FHardwareTexture* GLInstance::LoadTexture(FGameTexture* tex, int textype, int palid)
|
||||
OpenGLRenderer::FHardwareTexture* GLInstance::LoadTexture(FTexture *tex, int textype, int palid)
|
||||
{
|
||||
if (textype == TT_INDEXED) palid = -1;
|
||||
auto phwtex = tex->GetTexture()->SystemTextures.GetHardwareTexture(palid, false);
|
||||
auto phwtex = tex->SystemTextures.GetHardwareTexture(palid, false);
|
||||
if (phwtex) return (OpenGLRenderer::FHardwareTexture*)phwtex;
|
||||
|
||||
OpenGLRenderer::FHardwareTexture *hwtex = nullptr;
|
||||
if (textype == TT_INDEXED)
|
||||
hwtex = CreateIndexedTexture(tex);
|
||||
else if (!tex->GetTexture()->isHardwareCanvas())
|
||||
hwtex = CreateTrueColorTexture(tex, textype == TT_HICREPLACE? -1 : palid, textype == TT_BRIGHTMAP, textype == TT_BRIGHTMAP);
|
||||
else
|
||||
hwtex = nullptr;
|
||||
|
||||
if (hwtex) tex->GetTexture()->SystemTextures.AddHardwareTexture(palid, false, hwtex);
|
||||
auto hwtex = static_cast<OpenGLRenderer::FHardwareTexture*>(screen->CreateHardwareTexture(textype == TT_INDEXED? 1:4));
|
||||
if (hwtex) tex->SystemTextures.AddHardwareTexture(palid, false, hwtex);
|
||||
return hwtex;
|
||||
}
|
||||
|
||||
|
@ -203,7 +131,7 @@ TexturePick PickTexture(int tilenum, int basepal, int palette)
|
|||
|
||||
bool GLInstance::SetTextureInternal(int picnum, FGameTexture* tex, int paletteid, int method, int sampleroverride, FGameTexture *det, float detscale, FGameTexture *glow)
|
||||
{
|
||||
if (tex->GetTexelWidth() <= 0 || tex->GetTexelHeight() <= 0) return false;
|
||||
if (!tex->isValid() || tex->GetTexelWidth() <= 0 || tex->GetTexelHeight() <= 0) return false;
|
||||
int curbasepal = GetTranslationType(paletteid) - Translation_Remap;
|
||||
int palette = GetTranslationIndex(paletteid);
|
||||
int usepalette = fixpalette >= 0 ? fixpalette : curbasepal;
|
||||
|
@ -216,6 +144,7 @@ bool GLInstance::SetTextureInternal(int picnum, FGameTexture* tex, int paletteid
|
|||
TextureType = hw_int_useindexedcolortextures? TT_INDEXED : TT_TRUECOLOR;
|
||||
|
||||
int lookuppal = 0;
|
||||
int bindflags = 0;
|
||||
VSMatrix texmat;
|
||||
|
||||
GLInterface.SetBasepalTint(0xffffff);
|
||||
|
@ -241,6 +170,7 @@ bool GLInstance::SetTextureInternal(int picnum, FGameTexture* tex, int paletteid
|
|||
}
|
||||
if (!rep || rep->palnum != palette || (h.f & HICTINT_APPLYOVERALTPAL)) applytint = true;
|
||||
TextureType = TT_HICREPLACE;
|
||||
bindflags = CTF_Upscale;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -254,7 +184,9 @@ bool GLInstance::SetTextureInternal(int picnum, FGameTexture* tex, int paletteid
|
|||
if (!(h.f & HICTINT_APPLYOVERPALSWAP)) usepalswap = 0;
|
||||
}
|
||||
lookuppal = TRANSLATION(usepalette + Translation_Remap, usepalswap);
|
||||
bindflags = CTF_Upscale;
|
||||
}
|
||||
else bindflags = CTF_Indexed;
|
||||
}
|
||||
|
||||
// This is intentionally the same value for both parameters. The shader does not use the same uniform for modulation and overlay colors.
|
||||
|
@ -264,7 +196,8 @@ bool GLInstance::SetTextureInternal(int picnum, FGameTexture* tex, int paletteid
|
|||
|
||||
|
||||
// Load the main texture
|
||||
auto mtex = LoadTexture(tex, TextureType, lookuppal);
|
||||
|
||||
auto mtex = LoadTexture(tex->GetTexture(), TextureType, lookuppal);
|
||||
if (mtex)
|
||||
{
|
||||
auto sampler = (method & DAMETH_CLAMPED) ? (sampleroverride != -1 ? sampleroverride : SamplerClampXY) : SamplerRepeat;
|
||||
|
@ -280,6 +213,7 @@ bool GLInstance::SetTextureInternal(int picnum, FGameTexture* tex, int paletteid
|
|||
UseGlowMapping(false);
|
||||
UseBrightmaps(false);
|
||||
|
||||
mtex->BindOrCreate(tex->GetTexture(), 0, sampler, lookuppal, bindflags);
|
||||
BindTexture(0, mtex, sampler);
|
||||
// Needs a) testing and b) verification for correctness. This doesn't look like it makes sense.
|
||||
if (rep && (rep->scale.x != 1.0f || rep->scale.y != 1.0f))
|
||||
|
@ -305,8 +239,9 @@ bool GLInstance::SetTextureInternal(int picnum, FGameTexture* tex, int paletteid
|
|||
}
|
||||
if (det)
|
||||
{
|
||||
auto htex = LoadTexture(det, TT_HICREPLACE, 0);
|
||||
auto htex = LoadTexture(det->GetTexture(), TT_HICREPLACE, 0);
|
||||
UseDetailMapping(true);
|
||||
htex->BindOrCreate(det->GetTexture(), 3, CLAMP_NONE, 0, 0);
|
||||
BindTexture(3, htex, SamplerRepeat);
|
||||
texbound[0] = true;
|
||||
|
||||
|
@ -335,44 +270,38 @@ bool GLInstance::SetTextureInternal(int picnum, FGameTexture* tex, int paletteid
|
|||
}
|
||||
if (glow)
|
||||
{
|
||||
auto htex = LoadTexture(glow, TT_HICREPLACE, 0);
|
||||
auto htex = LoadTexture(glow->GetTexture(), TT_HICREPLACE, 0);
|
||||
UseGlowMapping(true);
|
||||
htex->BindOrCreate(glow->GetTexture(), 4, sampler, 0, CTF_Upscale);
|
||||
BindTexture(4, htex, SamplerRepeat);
|
||||
texbound[1] = true;
|
||||
}
|
||||
}
|
||||
#if 1
|
||||
if (picnum > -1 && !(TileFiles.tiledata[picnum].picanm.sf & PICANM_NOFULLBRIGHT_BIT) && !(globalflags & GLOBAL_NO_GL_FULLBRIGHT) && !TileFiles.tiledata[picnum].NoBrightmapFlag[usepalswap])
|
||||
if (picnum > -1 && !(TileFiles.tiledata[picnum].picanm.sf & PICANM_NOFULLBRIGHT_BIT) && !(globalflags & GLOBAL_NO_GL_FULLBRIGHT))
|
||||
{
|
||||
if (TextureType == TT_HICREPLACE)
|
||||
{
|
||||
auto brep = TileFiles.FindReplacement(picnum, BRIGHTPAL);
|
||||
if (brep)
|
||||
{
|
||||
LoadTexture(brep->faces[0], TT_HICREPLACE, 0);
|
||||
auto mtex = LoadTexture(brep->faces[0]->GetTexture(), TT_HICREPLACE, 0);
|
||||
UseBrightmaps(true);
|
||||
mtex->BindOrCreate(brep->faces[0]->GetTexture(), 5, sampler, 0, CTF_Upscale);
|
||||
BindTexture(5, mtex, sampler);
|
||||
texbound[2] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
TileFiles.tiledata[picnum].picanm.sf |= PICANM_NOFULLBRIGHT_BIT;
|
||||
}
|
||||
}
|
||||
else if (TextureType == TT_TRUECOLOR)
|
||||
{
|
||||
lookuppal = -1;// Needs some work on the texture management first. palmanager.LookupPalette(usepalette, usepalswap, true);
|
||||
if (lookuppal >= 0)
|
||||
auto btex = tex->GetBrightmap();
|
||||
if (btex)
|
||||
{
|
||||
auto htex = LoadTexture(tex, TT_BRIGHTMAP, lookuppal);
|
||||
if (htex == nullptr)
|
||||
{
|
||||
// Flag the texture as not being brightmapped for the given palette
|
||||
TileFiles.tiledata[picnum].NoBrightmapFlag.Set(usepalswap);
|
||||
}
|
||||
else
|
||||
auto htex = LoadTexture(btex, TT_BRIGHTMAP, lookuppal);
|
||||
if (htex != nullptr)
|
||||
{
|
||||
UseBrightmaps(true);
|
||||
htex->BindOrCreate(btex, 5, sampler, 0, CTF_Upscale);
|
||||
BindTexture(5, htex, sampler);
|
||||
texbound[2] = true;
|
||||
}
|
||||
|
@ -399,23 +328,10 @@ bool GLInstance::SetTextureInternal(int picnum, FGameTexture* tex, int paletteid
|
|||
|
||||
//===========================================================================
|
||||
//
|
||||
// Sets a named texture for 2D rendering. In this case the palette is
|
||||
// a direct index into the palette map.
|
||||
// stand-ins for the texture system. Nothing of this is used right now, but needs to be present to satisfy the linker
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
bool GLInstance::SetNamedTexture(FGameTexture* tex, int palette, int sampler)
|
||||
{
|
||||
auto mtex = LoadTexture(tex, palette>= 0? TT_TRUECOLOR : TT_HICREPLACE, palette);
|
||||
if (!mtex) return false;
|
||||
|
||||
BindTexture(0, mtex, sampler);
|
||||
GLInterface.SetAlphaThreshold(tex->GetTranslucency()? 0.f : 0.5f);
|
||||
return true;
|
||||
}
|
||||
|
||||
// stand-ins for the texture system. Nothing of this is used right now, but needs to be present to satisfy the linker
|
||||
|
||||
int PalCheck(int tex)
|
||||
{
|
||||
return tex;
|
||||
|
|
|
@ -487,13 +487,9 @@ public:
|
|||
renderState.AlphaThreshold = al;
|
||||
}
|
||||
|
||||
OpenGLRenderer::FHardwareTexture* CreateIndexedTexture(FGameTexture* tex);
|
||||
OpenGLRenderer::FHardwareTexture* CreateTrueColorTexture(FGameTexture* tex, int palid, bool checkfulltransparency = false, bool rgb8bit = false);
|
||||
OpenGLRenderer::FHardwareTexture *LoadTexture(FGameTexture* tex, int texturetype, int palid);
|
||||
OpenGLRenderer::FHardwareTexture *LoadTexture(FTexture* tex, int texturetype, int palid);
|
||||
bool SetTextureInternal(int globalpicnum, FGameTexture* tex, int palette, int method, int sampleroverride, FGameTexture *det, float detscale, FGameTexture *glow);
|
||||
|
||||
bool SetNamedTexture(FGameTexture* tex, int palette, int sampleroverride);
|
||||
|
||||
bool SetTexture(int globalpicnum, FGameTexture* tex, int palette, int method, int sampleroverride)
|
||||
{
|
||||
return SetTextureInternal(globalpicnum, tex, palette, method, sampleroverride, nullptr, 1, nullptr);
|
||||
|
|
Loading…
Reference in a new issue