2013-06-27 23:05:11 +00:00
|
|
|
|
2014-02-10 10:56:14 +00:00
|
|
|
#include "baselayer.h"
|
2013-05-15 02:17:17 +00:00
|
|
|
#include "build.h"
|
2014-02-10 10:55:49 +00:00
|
|
|
#include "lz4.h"
|
2013-05-15 02:17:17 +00:00
|
|
|
#include "hightile.h"
|
|
|
|
#include "polymost.h"
|
|
|
|
#include "texcache.h"
|
|
|
|
#include "scriptfile.h"
|
2014-03-22 09:26:39 +00:00
|
|
|
#include "xxhash.h"
|
2014-09-30 04:18:43 +00:00
|
|
|
#include "kplib.h"
|
2013-05-15 02:17:17 +00:00
|
|
|
|
2019-03-01 08:51:50 +00:00
|
|
|
#include "vfs.h"
|
2019-10-10 21:29:13 +00:00
|
|
|
#include "textures.h"
|
|
|
|
#include "bitmap.h"
|
|
|
|
#include "../../glbackend/glbackend.h"
|
2019-03-01 08:51:50 +00:00
|
|
|
|
2019-10-17 22:20:27 +00:00
|
|
|
extern int r_detailmapping, r_glowmapping, usehightile, r_useindexedcolortextures;
|
|
|
|
extern int fixpalette, fixpalswap;
|
|
|
|
|
2019-10-17 19:44:34 +00:00
|
|
|
#if 0
|
|
|
|
|
2019-10-10 21:29:13 +00:00
|
|
|
void gltexinvalidate(int32_t dapicnum, int32_t dapalnum, int32_t dameth)
|
|
|
|
{
|
|
|
|
const int32_t pic = (dapicnum & (GLTEXCACHEADSIZ - 1));
|
|
|
|
|
|
|
|
for (pthtyp* pth = texcache.list[pic]; pth; pth = pth->next)
|
|
|
|
if (pth->picnum == dapicnum && pth->palnum == dapalnum)
|
|
|
|
{
|
|
|
|
pth->flags |= PTH_INVALIDATED;
|
|
|
|
if (pth->flags & PTH_HASFULLBRIGHT)
|
|
|
|
pth->ofb->flags |= PTH_INVALIDATED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//Make all textures "dirty" so they reload, but not re-allocate
|
|
|
|
//This should be much faster than polymost_glreset()
|
|
|
|
//Use this for palette effects ... but not ones that change every frame!
|
|
|
|
void gltexinvalidatetype(int32_t type)
|
|
|
|
{
|
2019-10-17 18:29:58 +00:00
|
|
|
#if 0
|
2019-10-10 21:29:13 +00:00
|
|
|
for (bssize_t j = 0; j <= GLTEXCACHEADSIZ - 1; j++)
|
|
|
|
{
|
|
|
|
for (pthtyp* pth = texcache.list[j]; pth; pth = pth->next)
|
|
|
|
{
|
|
|
|
if (type == INVALIDATE_ALL ||
|
|
|
|
(type == INVALIDATE_ALL_NON_INDEXED && !(pth->flags & PTH_INDEXED)) ||
|
|
|
|
(type == INVALIDATE_ART && pth->hicr == NULL) ||
|
|
|
|
(type == INVALIDATE_ART_NON_INDEXED && pth->hicr == NULL && !(pth->flags & PTH_INDEXED)))
|
|
|
|
{
|
|
|
|
pth->flags |= PTH_INVALIDATED;
|
|
|
|
if (pth->flags & PTH_HASFULLBRIGHT)
|
|
|
|
pth->ofb->flags |= PTH_INVALIDATED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-10-17 18:29:58 +00:00
|
|
|
#endif
|
2019-10-10 21:29:13 +00:00
|
|
|
|
|
|
|
clearskins(type);
|
|
|
|
|
|
|
|
#ifdef DEBUGGINGAIDS
|
|
|
|
OSD_Printf("gltexinvalidateall()\n");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cleartexturecache()
|
|
|
|
{
|
|
|
|
for (bssize_t i = 0; i <= GLTEXCACHEADSIZ - 1; i++)
|
|
|
|
{
|
|
|
|
for (pthtyp* pth = texcache.list[i]; pth;)
|
|
|
|
{
|
|
|
|
pthtyp* const next = pth->next;
|
|
|
|
|
|
|
|
if (pth->flags & PTH_HASFULLBRIGHT)
|
|
|
|
{
|
|
|
|
delete pth->ofb->glpic;
|
|
|
|
Xfree(pth->ofb);
|
|
|
|
}
|
|
|
|
|
|
|
|
delete pth->glpic;
|
|
|
|
Xfree(pth);
|
|
|
|
pth = next;
|
|
|
|
}
|
|
|
|
|
|
|
|
texcache.list[i] = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-17 19:44:34 +00:00
|
|
|
static void polymost_setupsampler(FHardwareTexture* tex, const int32_t dameth, int filter)
|
2019-10-10 21:29:13 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
if (!(dameth & DAMETH_CLAMPED))
|
|
|
|
{
|
|
|
|
tex->SetSampler(SamplerRepeat);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// For sprite textures, clamping looks better than wrapping
|
|
|
|
tex->SetSampler(SamplerClampXY);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void gloadtile_art(int32_t dapic, int32_t dameth, pthtyp* pth, int32_t doalloc)
|
|
|
|
{
|
|
|
|
vec2_16_t const& tsizart = tilesiz[dapic];
|
|
|
|
vec2_t siz = { tsizart.x, tsizart.y };
|
|
|
|
vec2_t ssiz = siz;
|
|
|
|
//POGOTODO: npoty
|
|
|
|
char npoty = 0;
|
|
|
|
|
2019-10-15 21:18:52 +00:00
|
|
|
tileLoad(globalpicnum);
|
2019-10-10 21:29:13 +00:00
|
|
|
|
2019-10-11 21:31:59 +00:00
|
|
|
const uint8_t* p = tilePtr(dapic);
|
|
|
|
if (!p)
|
2019-10-10 21:29:13 +00:00
|
|
|
{
|
|
|
|
static uint8_t pix = 255;
|
|
|
|
siz.x = siz.y = 1;
|
|
|
|
|
|
|
|
p = &pix;
|
|
|
|
}
|
|
|
|
{
|
|
|
|
if (doalloc)
|
|
|
|
{
|
|
|
|
assert(pth->glpic == nullptr);
|
|
|
|
pth->glpic = GLInterface.NewTexture();
|
|
|
|
pth->glpic->CreateTexture(siz.x, siz.y, true, false);
|
|
|
|
pth->glpic->SetSampler((dameth & DAMETH_CLAMPED) ? SamplerClampXY : SamplerRepeat);
|
|
|
|
|
2019-10-17 19:44:34 +00:00
|
|
|
polymost_setupsampler(pth->glpic, dameth, 0);
|
2019-10-10 21:29:13 +00:00
|
|
|
}
|
|
|
|
TArray<uint8_t> flipped(siz.x * siz.y, true);
|
|
|
|
FlipNonSquareBlock(flipped.Data(), p, siz.y, siz.x, siz.y);
|
|
|
|
|
|
|
|
pth->glpic->LoadTexture(flipped.Data());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pth->picnum = dapic;
|
|
|
|
pth->palnum = 0;
|
|
|
|
pth->shade = 0;
|
|
|
|
pth->effects = 0;
|
|
|
|
pth->flags = PTH_HASALPHA | PTH_ONEBITALPHA | PTH_INDEXED;
|
2019-10-17 18:29:58 +00:00
|
|
|
//pth->hicr = NULL;
|
2019-10-10 21:29:13 +00:00
|
|
|
pth->siz = ssiz;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-10-17 18:29:58 +00:00
|
|
|
#if 0
|
2019-10-10 21:29:13 +00:00
|
|
|
int32_t gloadtile_hi(int32_t dapic, int32_t dapalnum, int32_t facen, hicreplctyp* hicr,
|
|
|
|
int32_t dameth, pthtyp* pth, int32_t doalloc, polytintflags_t effect)
|
|
|
|
{
|
|
|
|
if (!hicr) return -1;
|
|
|
|
|
|
|
|
char* fn;
|
|
|
|
|
|
|
|
if (facen > 0)
|
|
|
|
{
|
|
|
|
if (!hicr->skybox || facen > 6 || !hicr->skybox->face[facen - 1])
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
fn = hicr->skybox->face[facen - 1];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!hicr->filename)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
fn = hicr->filename;
|
|
|
|
}
|
|
|
|
|
2019-10-16 19:16:40 +00:00
|
|
|
auto texture = TileFiles.GetTexture(fn);
|
2019-10-10 21:29:13 +00:00
|
|
|
|
|
|
|
if (texture == nullptr)
|
|
|
|
{
|
|
|
|
OSD_Printf("hightile: %s (pic %d) not found\n", fn, dapic);
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((doalloc & 3) == 1)
|
|
|
|
{
|
|
|
|
pth->glpic = GLInterface.NewTexture();
|
|
|
|
pth->glpic->CreateTexture(texture->GetWidth(), texture->GetHeight(), false, true);
|
|
|
|
}
|
|
|
|
auto image = texture->GetBgraBitmap(nullptr, nullptr);
|
|
|
|
bool hasalpha = texture->GetTranslucency();
|
|
|
|
bool onebitalpha = texture->isMasked();
|
|
|
|
|
|
|
|
pth->glpic->LoadTexture(image);
|
|
|
|
|
|
|
|
#if 0 // I don't really think this is a good idea. The hightile should look indistinguishable to the game compared to the regular one.
|
|
|
|
vec2_t tsiz = { texture->GetWidth(), texture->GetHeight() };
|
|
|
|
// precalculate scaling parameters for replacement
|
|
|
|
if (facen > 0)
|
|
|
|
pth->scale = { (float)tsiz.x * (1.0f / 64.f), (float)tsiz.y * (1.0f / 64.f) };
|
|
|
|
else
|
|
|
|
pth->scale = { (float)tsiz.x / (float)tilesiz[dapic].x, (float)tsiz.y / (float)tilesiz[dapic].y };
|
|
|
|
#else
|
|
|
|
pth->scale = { 1.f,1.f };
|
|
|
|
#endif
|
|
|
|
|
2019-10-17 19:44:34 +00:00
|
|
|
polymost_setupsampler(pth->glpic, dameth, (hicr->flags & HICR_FORCEFILTER) ? TEXFILTER_ON : -1);
|
2019-10-10 21:29:13 +00:00
|
|
|
|
|
|
|
pth->picnum = dapic;
|
|
|
|
pth->effects = effect;
|
|
|
|
pth->flags = PTH_HIGHTILE | ((facen > 0) * PTH_SKYBOX) |
|
|
|
|
(onebitalpha ? PTH_ONEBITALPHA : 0) |
|
|
|
|
(hasalpha ? PTH_HASALPHA : 0) |
|
|
|
|
((hicr->flags & HICR_FORCEFILTER) ? PTH_FORCEFILTER : 0);
|
|
|
|
pth->skyface = facen;
|
2019-10-17 18:29:58 +00:00
|
|
|
//pth->hicr = hicr;
|
2019-10-10 21:29:13 +00:00
|
|
|
|
|
|
|
if (facen > 0) pth->siz = { 64, 64 }; else pth->siz = { tilesiz[dapic].x, tilesiz[dapic].y };
|
|
|
|
return 0;
|
|
|
|
}
|
2019-10-17 18:29:58 +00:00
|
|
|
#endif
|
2019-03-01 08:51:50 +00:00
|
|
|
|
2019-06-25 11:29:08 +00:00
|
|
|
#define TEXCACHE_FREEBUFS() { Xfree(pic), Xfree(packbuf), Xfree(midbuf); }
|
2013-05-15 02:17:17 +00:00
|
|
|
|
2013-05-17 03:42:37 +00:00
|
|
|
globaltexcache texcache;
|
2013-05-15 02:17:17 +00:00
|
|
|
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2015-03-09 20:32:11 +00:00
|
|
|
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2014-03-30 13:53:08 +00:00
|
|
|
// <dashade>: ignored if not in Polymost+r_usetileshades
|
2013-05-15 02:18:27 +00:00
|
|
|
pthtyp *texcache_fetch(int32_t dapicnum, int32_t dapalnum, int32_t dashade, int32_t dameth)
|
2013-05-15 02:17:17 +00:00
|
|
|
{
|
2019-10-17 18:29:58 +00:00
|
|
|
#if 0
|
2014-11-22 12:34:29 +00:00
|
|
|
const int32_t j = dapicnum & (GLTEXCACHEADSIZ - 1);
|
2019-10-17 18:29:58 +00:00
|
|
|
hicreplctyp *si = usehightile ? hicfindsubst(dapicnum, dapalnum) : NULL;
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2019-10-09 22:07:45 +00:00
|
|
|
if (drawingskybox && usehightile)
|
|
|
|
{
|
|
|
|
auto si = hicfindskybox(dapicnum, dapalnum);
|
|
|
|
if (si == nullptr)
|
|
|
|
return nullptr;
|
|
|
|
}
|
2013-05-15 02:17:17 +00:00
|
|
|
|
|
|
|
if (!si)
|
2019-10-17 18:29:58 +00:00
|
|
|
#endif
|
|
|
|
{
|
2014-11-22 12:34:29 +00:00
|
|
|
return (dapalnum >= (MAXPALOOKUPS - RESERVEDPALS) || hicprecaching) ?
|
|
|
|
NULL : texcache_tryart(dapicnum, dapalnum, dashade, dameth);
|
2013-05-15 02:17:17 +00:00
|
|
|
}
|
2019-10-17 18:29:58 +00:00
|
|
|
#if 0
|
2013-05-15 02:17:17 +00:00
|
|
|
/* if palette > 0 && replacement found
|
|
|
|
* no effects are applied to the texture
|
|
|
|
* else if palette > 0 && no replacement found
|
|
|
|
* effects are applied to the palette 0 texture if it exists
|
|
|
|
*/
|
|
|
|
|
2017-06-21 13:46:50 +00:00
|
|
|
polytintflags_t const tintflags = hictinting[dapalnum].f;
|
|
|
|
|
|
|
|
const int32_t checktintpal = (tintflags & HICTINT_APPLYOVERALTPAL) ? 0 : si->palnum;
|
2018-10-07 05:20:19 +00:00
|
|
|
const int32_t checkcachepal = ((tintflags & HICTINT_IN_MEMORY) || ((tintflags & HICTINT_APPLYOVERALTPAL) && si->palnum > 0)) ? dapalnum : si->palnum;
|
2015-04-14 08:07:23 +00:00
|
|
|
|
2013-05-15 02:17:17 +00:00
|
|
|
// load a replacement
|
2015-03-24 00:40:33 +00:00
|
|
|
for (pthtyp *pth = texcache.list[j]; pth; pth = pth->next)
|
2013-05-15 02:17:17 +00:00
|
|
|
{
|
2017-06-27 02:24:34 +00:00
|
|
|
if (pth->picnum == dapicnum && pth->palnum == checkcachepal && (checktintpal > 0 ? 1 : (pth->effects == tintflags))
|
2019-10-09 22:07:45 +00:00
|
|
|
&& (pth->flags & (PTH_HIGHTILE | PTH_SKYBOX)) == (PTH_HIGHTILE | (drawingskybox > 0) * PTH_SKYBOX)
|
2017-06-27 02:24:34 +00:00
|
|
|
&& (drawingskybox > 0 ? (pth->skyface == drawingskybox) : 1))
|
2013-05-15 02:17:17 +00:00
|
|
|
{
|
2014-05-28 22:40:16 +00:00
|
|
|
if (pth->flags & PTH_INVALIDATED)
|
2013-05-15 02:17:17 +00:00
|
|
|
{
|
2014-05-28 22:40:16 +00:00
|
|
|
pth->flags &= ~PTH_INVALIDATED;
|
|
|
|
|
2019-09-18 18:44:21 +00:00
|
|
|
int32_t tilestat = gloadtile_hi(dapicnum, dapalnum, drawingskybox, si, dameth, pth, 0,
|
2017-06-21 13:46:50 +00:00
|
|
|
(checktintpal > 0) ? 0 : tintflags); // reload tile
|
2014-09-30 04:06:05 +00:00
|
|
|
|
2014-11-22 12:34:29 +00:00
|
|
|
if (!tilestat)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
return (drawingskybox || hicprecaching) ? NULL : texcache_tryart(dapicnum, dapalnum, dashade, dameth);
|
2013-05-15 02:17:17 +00:00
|
|
|
}
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
return pth;
|
2013-05-15 02:17:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-24 00:40:33 +00:00
|
|
|
pthtyp *pth = (pthtyp *)Xcalloc(1, sizeof(pthtyp));
|
2013-05-15 02:17:17 +00:00
|
|
|
|
|
|
|
// possibly fetch an already loaded multitexture :_)
|
2017-06-27 11:01:12 +00:00
|
|
|
if (dapalnum == DETAILPAL && texcache_fetchmulti(pth, si, dapicnum, dameth))
|
2014-09-30 04:06:05 +00:00
|
|
|
return pth;
|
2014-05-30 00:02:14 +00:00
|
|
|
|
2019-09-13 19:43:05 +00:00
|
|
|
int32_t tilestat = gloadtile_hi(dapicnum, dapalnum, drawingskybox, si, dameth, pth, 1, (checktintpal > 0) ? 0 : tintflags);
|
2019-10-09 22:07:45 +00:00
|
|
|
|
|
|
|
if (!tilestat)
|
2013-05-15 02:17:17 +00:00
|
|
|
{
|
2014-11-22 12:34:29 +00:00
|
|
|
pth->next = texcache.list[j];
|
2015-04-14 21:17:36 +00:00
|
|
|
pth->palnum = checkcachepal;
|
2014-11-22 12:34:29 +00:00
|
|
|
texcache.list[j] = pth;
|
|
|
|
return pth;
|
2013-05-15 02:17:17 +00:00
|
|
|
}
|
2019-06-25 11:29:08 +00:00
|
|
|
Xfree(pth);
|
2014-11-22 12:34:29 +00:00
|
|
|
|
|
|
|
return (drawingskybox || hicprecaching) ? NULL : texcache_tryart(dapicnum, dapalnum, dashade, dameth);
|
2019-10-17 18:29:58 +00:00
|
|
|
#endif
|
|
|
|
|
2013-05-15 02:17:17 +00:00
|
|
|
}
|
|
|
|
|
2019-10-17 22:20:27 +00:00
|
|
|
#endif
|
2019-10-17 19:44:34 +00:00
|
|
|
|
|
|
|
|
2019-10-17 22:20:27 +00:00
|
|
|
template<class T>
|
|
|
|
void FlipNonSquareBlock(T* dst, const T* src, int x, int y, int srcpitch)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < x; ++i)
|
2019-10-17 19:44:34 +00:00
|
|
|
{
|
2019-10-17 22:20:27 +00:00
|
|
|
for (int j = 0; j < y; ++j)
|
2019-10-17 19:44:34 +00:00
|
|
|
{
|
2019-10-17 22:20:27 +00:00
|
|
|
dst[i * y + j] = src[i + j * srcpitch];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-10-17 19:44:34 +00:00
|
|
|
|
2017-06-27 02:24:34 +00:00
|
|
|
|
2019-10-17 22:20:27 +00:00
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// Create an indexed version of the requested texture
|
|
|
|
//
|
|
|
|
//===========================================================================
|
2019-10-17 19:44:34 +00:00
|
|
|
|
2019-10-17 22:20:27 +00:00
|
|
|
FHardwareTexture* CreateIndexedTexture(FTexture* tex)
|
|
|
|
{
|
|
|
|
auto siz = tex->GetSize();
|
|
|
|
bool npoty = false;
|
2019-10-17 19:44:34 +00:00
|
|
|
|
2019-10-17 22:20:27 +00:00
|
|
|
const uint8_t* p = tex->Get8BitPixels();
|
|
|
|
TArray<uint8_t> store(siz.x * siz.y, true);
|
|
|
|
if (!p)
|
|
|
|
{
|
|
|
|
tex->Create8BitPixels(store.Data());
|
|
|
|
p = store.Data();
|
2019-10-17 19:44:34 +00:00
|
|
|
}
|
|
|
|
|
2019-10-17 22:20:27 +00:00
|
|
|
auto glpic = GLInterface.NewTexture();
|
|
|
|
glpic->CreateTexture(siz.x, siz.y, true, false);
|
|
|
|
|
|
|
|
TArray<uint8_t> flipped(siz.x * siz.y, true);
|
|
|
|
FlipNonSquareBlock(flipped.Data(), p, siz.y, siz.x, siz.y);
|
|
|
|
glpic->LoadTexture(flipped.Data());
|
|
|
|
return glpic;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// Retrieve the texture to be used.
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
|
|
|
|
FHardwareTexture* GLInstance::LoadTexture(FTexture* tex, int textype, int palid)
|
|
|
|
{
|
|
|
|
if (textype == TT_TRUECOLOR && palid == 0) textype = TT_HICREPLACE; // true color tiles with the base palette won't get processed.
|
|
|
|
if (textype == TT_INDEXED)
|
2019-10-17 19:44:34 +00:00
|
|
|
{
|
2019-10-17 22:20:27 +00:00
|
|
|
auto hwtex = tex->GetHardwareTexture(-1);
|
|
|
|
if (hwtex) return hwtex;
|
|
|
|
else
|
2019-10-17 19:44:34 +00:00
|
|
|
{
|
2019-10-17 22:20:27 +00:00
|
|
|
hwtex = CreateIndexedTexture(tex);
|
|
|
|
tex->SetHardwareTexture(-1, hwtex);
|
|
|
|
return hwtex;
|
2019-10-17 19:44:34 +00:00
|
|
|
}
|
|
|
|
}
|
2019-10-17 22:20:27 +00:00
|
|
|
}
|
2019-10-17 19:44:34 +00:00
|
|
|
|
2019-10-17 22:20:27 +00:00
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// Sets a texture for rendering
|
|
|
|
//
|
|
|
|
//===========================================================================
|
2019-10-17 19:44:34 +00:00
|
|
|
|
2019-10-17 22:20:27 +00:00
|
|
|
bool GLInstance::SetTexture(FTexture* tex, int palette, int method, int sampleroverride)
|
|
|
|
{
|
|
|
|
int usepalette = fixpalette >= 1 ? fixpalette - 1 : curbasepal;
|
|
|
|
int usepalswap = fixpalswap >= 1 ? fixpalswap - 1 : palette;
|
|
|
|
GLInterface.SetPalette(usepalette);
|
|
|
|
GLInterface.SetPalswap(usepalswap);
|
2019-10-17 19:44:34 +00:00
|
|
|
|
2019-10-17 22:20:27 +00:00
|
|
|
TextureType = r_useindexedcolortextures? TT_INDEXED : TT_TRUECOLOR;
|
2019-10-17 19:44:34 +00:00
|
|
|
|
2019-10-17 22:20:27 +00:00
|
|
|
int lookuppal = 0;
|
|
|
|
VSMatrix texmat;
|
2019-10-17 19:44:34 +00:00
|
|
|
|
2019-10-17 22:20:27 +00:00
|
|
|
auto rep = usehightile? currentTexture->FindReplacement(palette) : nullptr;
|
|
|
|
if (rep)
|
|
|
|
{
|
|
|
|
// Hightile replacements have only one texture representation and it is always the base.
|
|
|
|
tex = rep->faces[0];
|
|
|
|
TextureType = TT_HICREPLACE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Only look up the palette if we really want to use it (i.e. when creating a true color texture of an ART tile.)
|
|
|
|
if (!r_useindexedcolortextures) lookuppal = palmanager.LookupPalette(usepalette, usepalswap);
|
|
|
|
}
|
2019-10-17 19:44:34 +00:00
|
|
|
|
2019-10-17 22:20:27 +00:00
|
|
|
// Load the main texture
|
|
|
|
auto mtex = LoadTexture(tex, TextureType, lookuppal);
|
|
|
|
if (mtex)
|
|
|
|
{
|
|
|
|
auto sampler = (method & DAMETH_CLAMPED) ? (sampleroverride != -1 ? sampleroverride : SamplerClampXY) : SamplerRepeat;
|
2019-10-17 19:44:34 +00:00
|
|
|
|
2019-10-17 22:20:27 +00:00
|
|
|
BindTexture(0, mtex, sampler);
|
|
|
|
if (rep && ((rep->scale.x != 1.0f) || (rep->scale.y != 1.0f)))
|
|
|
|
{
|
|
|
|
texmat.loadIdentity();
|
|
|
|
texmat.scale(rep->scale.x, rep->scale.y, 1.0f);
|
|
|
|
GLInterface.SetMatrix(Matrix_Texture, &texmat);
|
|
|
|
MatrixChange |= 1;
|
|
|
|
}
|
2019-10-17 19:44:34 +00:00
|
|
|
|
2019-10-17 22:20:27 +00:00
|
|
|
// Also load additional layers needed for this texture.
|
|
|
|
if (r_detailmapping && usehightile)
|
|
|
|
{
|
|
|
|
auto drep = currentTexture->FindReplacement(DETAILPAL);
|
|
|
|
if (drep)
|
|
|
|
{
|
|
|
|
auto htex = LoadTexture(drep->faces[0], TT_HICREPLACE, 0);
|
|
|
|
UseDetailMapping(true);
|
|
|
|
BindTexture(3, htex, SamplerRepeat);
|
|
|
|
|
|
|
|
texmat.loadIdentity();
|
|
|
|
|
|
|
|
if (rep && ((rep->scale.x != 1.0f) || (rep->scale.y != 1.0f)))
|
|
|
|
{
|
|
|
|
texmat.scale(rep->scale.x, rep->scale.y, 1.0f);
|
|
|
|
MatrixChange |= 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((drep->scale.x != 1.0f) || (drep->scale.y != 1.0f))
|
|
|
|
{
|
|
|
|
texmat.scale(drep->scale.x, drep->scale.y, 1.0f);
|
|
|
|
MatrixChange |= 2;
|
|
|
|
}
|
|
|
|
if (MatrixChange & 2) GLInterface.SetMatrix(Matrix_Detail, &texmat);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (r_glowmapping && usehightile)
|
|
|
|
{
|
|
|
|
auto drep = currentTexture->FindReplacement(GLOWPAL);
|
|
|
|
if (drep)
|
|
|
|
{
|
|
|
|
auto htex = LoadTexture(drep->faces[0], TT_HICREPLACE, 0);
|
|
|
|
UseGlowMapping(true);
|
|
|
|
BindTexture(4, htex, SamplerRepeat);
|
2019-10-17 19:44:34 +00:00
|
|
|
|
2019-10-17 22:20:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
auto brep = currentTexture->FindReplacement(BRIGHTPAL);
|
|
|
|
if (brep)
|
|
|
|
{
|
|
|
|
auto htex = LoadTexture(brep->faces[0], TT_HICREPLACE, 0);
|
|
|
|
BindTexture(5, mtex, sampler);
|
|
|
|
}
|
|
|
|
}
|
2019-10-17 19:44:34 +00:00
|
|
|
|
2019-10-17 22:20:27 +00:00
|
|
|
float al = 0;
|
|
|
|
if (TextureType == TT_HICREPLACE)
|
|
|
|
{
|
|
|
|
al = /*alphahackarray[globalpicnum] != 0 ? alphahackarray[globalpicnum] * (1.f / 255.f) :*/
|
|
|
|
(tex->alphaThreshold >= 0.f ? tex->alphaThreshold : 0.f);
|
|
|
|
}
|
2019-10-17 19:44:34 +00:00
|
|
|
GLInterface.SetAlphaThreshold(al);
|
|
|
|
}
|
2017-06-27 02:24:34 +00:00
|
|
|
|
2013-05-15 02:18:27 +00:00
|
|
|
|
2019-10-17 19:44:34 +00:00
|
|
|
|