- cleanup of texture creation code.

There were several mostly pointless options complicating all of this.
This commit is contained in:
Christoph Oelckers 2019-10-10 00:07:45 +02:00
parent eca099681a
commit 1fee7a5f01
7 changed files with 53 additions and 165 deletions

View file

@ -1252,4 +1252,4 @@ source_group("Game Frontends\\EDuke32\\Sources" REGULAR_EXPRESSION "^${CMAKE_CUR
source_group("Game Frontends\\RedNukem\\Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/rr/.+")
#source_group("Game Frontends\\NBlood\\Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/blood/.h")
source_group("Game Frontends\\NBlood\\Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/blood/.+")
source_group("Game Frontends\\Shadow Warrior\\Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sw/.+")

View file

@ -164,41 +164,10 @@ enum {
// used internally by polymost_domost
DAMETH_BACKFACECULL = -1,
// used internally by uploadtexture
DAMETH_NODOWNSIZE = 4096,
DAMETH_HI = 8192,
DAMETH_NOFIX = 16384,
DAMETH_NOTEXCOMPRESS = 32768,
DAMETH_HASALPHA = 65536,
DAMETH_ONEBITALPHA = 131072,
DAMETH_ARTIMMUNITY = 262144,
DAMETH_HASFULLBRIGHT = 524288,
DAMETH_NPOTWALL = 1048576,
DAMETH_UPLOADTEXTURE_MASK =
DAMETH_HI |
DAMETH_NODOWNSIZE |
DAMETH_NOFIX |
DAMETH_NOTEXCOMPRESS |
DAMETH_HASALPHA |
DAMETH_ONEBITALPHA |
DAMETH_ARTIMMUNITY |
DAMETH_HASFULLBRIGHT |
DAMETH_NPOTWALL,
};
#define DAMETH_NARROW_MASKPROPS(dameth) (((dameth)&(~DAMETH_TRANS1))|(((dameth)&DAMETH_TRANS1)>>1))
EDUKE32_STATIC_ASSERT(DAMETH_NARROW_MASKPROPS(DAMETH_MASKPROPS) == DAMETH_MASK);
EDUKE32_STATIC_ASSERT(DAMETH_NARROW_MASKPROPS(DAMETH_CLAMPED) == DAMETH_CLAMPED);
#define TO_DAMETH_NODOWNSIZE(hicr_flags) (((hicr_flags)&HICR_NODOWNSIZE)<<8)
EDUKE32_STATIC_ASSERT(TO_DAMETH_NODOWNSIZE(HICR_NODOWNSIZE) == DAMETH_NODOWNSIZE);
#define TO_DAMETH_NOTEXCOMPRESS(hicr_flags) (((hicr_flags)&HICR_NOTEXCOMPRESS)<<15)
EDUKE32_STATIC_ASSERT(TO_DAMETH_NOTEXCOMPRESS(HICR_NOTEXCOMPRESS) == DAMETH_NOTEXCOMPRESS);
#define TO_DAMETH_ARTIMMUNITY(hicr_flags) (((hicr_flags)&HICR_ARTIMMUNITY)<<13)
EDUKE32_STATIC_ASSERT(TO_DAMETH_ARTIMMUNITY(HICR_ARTIMMUNITY) == DAMETH_ARTIMMUNITY);
// Do we want a NPOT-y-as-classic texture for this <dameth> and <ysiz>?
static FORCE_INLINE int polymost_want_npotytex(int32_t dameth, int32_t ysiz)
@ -208,7 +177,6 @@ static FORCE_INLINE int polymost_want_npotytex(int32_t dameth, int32_t ysiz)
// pthtyp pth->flags bits
enum pthtyp_flags {
PTH_CLAMPED = 1,
PTH_HIGHTILE = 2,
PTH_SKYBOX = 4,
PTH_HASALPHA = 8,
@ -218,8 +186,6 @@ enum pthtyp_flags {
PTH_INVALIDATED = 128,
PTH_NOTRANSFIX = 256, // fixtransparency() bypassed
PTH_INDEXED = 512,
PTH_ONEBITALPHA = 1024,
};
@ -242,15 +208,6 @@ typedef struct pthtyp_t
char skyface;
} pthtyp;
// DAMETH -> PTH conversions
#define TO_PTH_CLAMPED(dameth) (((dameth)&DAMETH_CLAMPED)>>2)
EDUKE32_STATIC_ASSERT(TO_PTH_CLAMPED(DAMETH_CLAMPED) == PTH_CLAMPED);
#define TO_PTH_NOTRANSFIX(dameth) ((((~(dameth))&DAMETH_MASK)<<8)&(((~(dameth))&DAMETH_TRANS1)<<7))
EDUKE32_STATIC_ASSERT(TO_PTH_NOTRANSFIX(DAMETH_NOMASK) == PTH_NOTRANSFIX);
EDUKE32_STATIC_ASSERT(TO_PTH_NOTRANSFIX(DAMETH_MASK) == 0);
EDUKE32_STATIC_ASSERT(TO_PTH_NOTRANSFIX(DAMETH_TRANS1) == 0);
EDUKE32_STATIC_ASSERT(TO_PTH_NOTRANSFIX(DAMETH_MASKPROPS) == 0);
extern void gloadtile_art(int32_t,int32_t,int32_t,int32_t,int32_t,pthtyp *,int32_t);
extern int32_t gloadtile_hi(int32_t,int32_t,int32_t,hicreplctyp *,int32_t,pthtyp *,int32_t, polytintflags_t);

View file

@ -1780,13 +1780,15 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr)
// tinting
pc[0] = pc[1] = pc[2] = ((float)numshades - min(max((globalshade * shadescale) + m->shadeoff, 0.f), (float)numshades)) / (float)numshades;
polytintflags_t const tintflags = hictinting[globalpal].f;
auto& h = hictinting[globalpal];
polytintflags_t const tintflags = h.f;
if (!(tintflags & HICTINT_PRECOMPUTED))
{
if (!(m->flags&1))
hictinting_apply(pc, globalpal);
else globalnoeffect=1;
}
GLInterface.SetTinting(tintflags, PalEntry(h.sr, h.sg, h.sb));
// global tinting
if (have_basepal_tint())
@ -2008,6 +2010,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr)
VSMatrix identity(0);
GLInterface.SetMatrix(Matrix_ModelView, &identity);
GLInterface.SetTinting(0, 0);
GLInterface.SetClamp(prevClamp);
GLInterface.UsePaletteIndexing(true);
GLInterface.SetPolymostShader();

View file

@ -179,8 +179,7 @@ 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_CLAMPED) == TO_PTH_CLAMPED(dameth))
if (pth->picnum == dapicnum && pth->palnum == dapalnum)
{
pth->flags |= PTH_INVALIDATED;
if (pth->flags & PTH_HASFULLBRIGHT)
@ -614,55 +613,8 @@ static void resizeglcheck(void)
}
}
static void fixtransparency(coltype *dapic, vec2_t dasiz, vec2_t dasiz2, int32_t dameth)
{
if (!(dameth & DAMETH_MASKPROPS))
return;
vec2_t doxy = { dasiz2.x-1, dasiz2.y-1 };
if (dameth & DAMETH_CLAMPED)
doxy = { min(doxy.x, dasiz.x), min(doxy.y, dasiz.y) };
else dasiz = dasiz2; //Make repeating textures duplicate top/left parts
dasiz.x--; dasiz.y--; //Hacks for optimization inside loop
int32_t const naxsiz2 = -dasiz2.x;
//Set transparent pixels to average color of neighboring opaque pixels
//Doing this makes bilinear filtering look much better for masked textures (I.E. sprites)
for (bssize_t y=doxy.y; y>=0; y--)
{
coltype * wpptr = &dapic[y*dasiz2.x+doxy.x];
for (bssize_t x=doxy.x; x>=0; x--,wpptr--)
{
if (wpptr->a) continue;
int r = 0, g = 0, b = 0, j = 0;
if ((x> 0) && (wpptr[ -1].a)) { r += wpptr[ -1].r; g += wpptr[ -1].g; b += wpptr[ -1].b; j++; }
if ((x<dasiz.x) && (wpptr[ +1].a)) { r += wpptr[ +1].r; g += wpptr[ +1].g; b += wpptr[ +1].b; j++; }
if ((y> 0) && (wpptr[naxsiz2].a)) { r += wpptr[naxsiz2].r; g += wpptr[naxsiz2].g; b += wpptr[naxsiz2].b; j++; }
if ((y<dasiz.y) && (wpptr[dasiz2.x].a)) { r += wpptr[dasiz2.x].r; g += wpptr[dasiz2.x].g; b += wpptr[dasiz2.x].b; j++; }
switch (j)
{
case 1:
wpptr->r = r ; wpptr->g = g ; wpptr->b = b ; break;
case 2:
wpptr->r = ((r + 1)>>1); wpptr->g = ((g + 1)>>1); wpptr->b = ((b + 1)>>1); break;
case 3:
wpptr->r = ((r*85+128)>>8); wpptr->g = ((g*85+128)>>8); wpptr->b = ((b*85+128)>>8); break;
case 4:
wpptr->r = ((r + 2)>>2); wpptr->g = ((g + 2)>>2); wpptr->b = ((b + 2)>>2); break;
}
}
}
}
void uploadtexture(FHardwareTexture *tex, int32_t doalloc, vec2_t siz, int32_t texfmt,
coltype* pic, vec2_t tsiz, int32_t dameth)
void uploadtexture(FHardwareTexture *tex, coltype* pic)
{
tex->LoadTexture((uint8_t *)pic);
}
@ -761,7 +713,7 @@ static void gloadtile_art_indexed(int32_t dapic, int32_t dameth, pthtyp* pth, in
pth->palnum = 0;
pth->shade = 0;
pth->effects = 0;
pth->flags = TO_PTH_CLAMPED(dameth) | TO_PTH_NOTRANSFIX(dameth) | (PTH_HASALPHA|PTH_ONEBITALPHA) | (npoty*PTH_NPOTWALL) | PTH_INDEXED;
pth->flags = (PTH_HASALPHA|PTH_ONEBITALPHA) | (npoty*PTH_NPOTWALL) | PTH_INDEXED;
pth->hicr = NULL;
pth->siz = siz;
}
@ -809,12 +761,6 @@ void gloadtile_art(int32_t dapic, int32_t dapal, int32_t tintpalnum, int32_t das
int32_t dacol;
int32_t x2 = (x < tsiz.x) ? x : x-tsiz.x;
if ((dameth & DAMETH_CLAMPED) && (x >= tsiz.x || y >= tsiz.y)) //Clamp texture
{
wpptr->r = wpptr->g = wpptr->b = wpptr->a = 0;
continue;
}
dacol = *(char *)(waloff[dapic]+x2*tsiz.y+y2);
if (dacol == 255)
@ -909,8 +855,6 @@ void gloadtile_art(int32_t dapic, int32_t dapal, int32_t tintpalnum, int32_t das
pth->glpic->CreateTexture(siz.x, siz.y, false, true);
}
fixtransparency(pic,tsiz,siz,dameth);
if (polymost_want_npotytex(dameth, siz.y) && tsiz.x == siz.x && tsiz.y == siz.y) // XXX
{
const int32_t nextpoty = 1 << ((picsiz[dapic] >> 4) + 1);
@ -943,12 +887,7 @@ void gloadtile_art(int32_t dapic, int32_t dapal, int32_t tintpalnum, int32_t das
doalloc = true;
}
}
uploadtexture(pth->glpic, doalloc, siz, 1, pic, tsiz,
dameth | DAMETH_ARTIMMUNITY |
(dapic >= MAXUSERTILES ? (DAMETH_NOTEXCOMPRESS|DAMETH_NODOWNSIZE) : 0) | /* never process these short-lived tiles */
(hasfullbright ? DAMETH_HASFULLBRIGHT : 0) |
(npoty ? DAMETH_NPOTWALL : 0) |
(hasalpha ? (DAMETH_HASALPHA|DAMETH_ONEBITALPHA) : 0));
uploadtexture(pth->glpic, pic);
Xfree(pic);
}
@ -959,7 +898,7 @@ void gloadtile_art(int32_t dapic, int32_t dapal, int32_t tintpalnum, int32_t das
pth->palnum = dapal;
pth->shade = dashade;
pth->effects = 0;
pth->flags = TO_PTH_CLAMPED(dameth) | TO_PTH_NOTRANSFIX(dameth) | (hasalpha*(PTH_HASALPHA|PTH_ONEBITALPHA)) | (npoty*PTH_NPOTWALL);
pth->flags = (hasalpha*(PTH_HASALPHA|PTH_ONEBITALPHA)) | (npoty*PTH_NPOTWALL);
pth->hicr = NULL;
pth->siz = tsiz;
@ -1020,21 +959,25 @@ int32_t gloadtile_hi(int32_t dapic,int32_t dapalnum, int32_t facen, hicreplctyp
bool onebitalpha = texture->isMasked();
pth->glpic->LoadTexture(image);
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 };
polymost_setuptexture(pth->glpic, dameth, (hicr->flags & HICR_FORCEFILTER) ? TEXFILTER_ON : -1);
pth->picnum = dapic;
pth->effects = effect;
pth->flags = TO_PTH_CLAMPED(dameth) | TO_PTH_NOTRANSFIX(dameth) |
PTH_HIGHTILE | ((facen>0) * PTH_SKYBOX) |
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;
pth->hicr = hicr;
pth->siz = tsiz;
// pretend to the higher level code that this texture is not scaled.
pth->scale = { 1.f, 1.f };
if (facen > 0) pth->siz = { 64, 64 }; else pth->siz = { tilesiz[dapic].x, tilesiz[dapic].y };
return 0;
}
@ -1101,7 +1044,7 @@ int32_t polymost_spriteHasTranslucency(uspritetype const * const tspr)
if (palookup[pal] == NULL)
pal = 0;
pthtyp* pth = texcache_fetch(tspr->picnum, pal, 0, DAMETH_MASK | DAMETH_CLAMPED);
pthtyp* pth = texcache_fetch(tspr->picnum, pal, 0, DAMETH_MASK);
return pth && (pth->flags & PTH_HASALPHA) && !(pth->flags & PTH_ONEBITALPHA);
}
@ -1420,7 +1363,8 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
pc[3] = float_trans(method & DAMETH_MASKPROPS, drawpoly_blend) * (1.f - drawpoly_alpha);
// tinting
polytintflags_t const tintflags = hictinting[globalpal].f;
auto& h = hictinting[globalpal];
polytintflags_t const tintflags = h.f;
if (!(tintflags & HICTINT_PRECOMPUTED))
{
if (pth->flags & PTH_HIGHTILE)
@ -1431,6 +1375,7 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
else if (tintflags & (HICTINT_USEONART|HICTINT_ALWAYSUSEART))
hictinting_apply(pc, globalpal);
}
GLInterface.SetTinting(tintflags, PalEntry(h.sr, h.sg, h.sb));
// global tinting
if ((pth->flags & PTH_HIGHTILE) && have_basepal_tint())
@ -1600,6 +1545,7 @@ do
GLInterface.Draw(DT_TRIANGLE_FAN, data.first, npoints);
}
GLInterface.SetTinting(0,0);
GLInterface.UseDetailMapping(false);
GLInterface.UseGlowMapping(false);
GLInterface.SetNpotEmulation(false, 1.f, 0.f);
@ -6779,7 +6725,7 @@ void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype)
//OSD_Printf("precached %d %d type %d\n", dapicnum, dapalnum, datype);
hicprecaching = 1;
texcache_fetch(dapicnum, dapalnum, 0, (datype & 1)*(DAMETH_CLAMPED|DAMETH_MASK));
texcache_fetch(dapicnum, dapalnum, 0, (datype & 1)*(DAMETH_MASK));
hicprecaching = 0;
if (datype == 0 || !usemodels) return;

View file

@ -28,45 +28,31 @@ static pthtyp *texcache_tryart(int32_t const dapicnum, int32_t const dapalnum, i
if (tintflags & (HICTINT_USEONART|HICTINT_ALWAYSUSEART))
{
tintpalnum = dapalnum;
dameth &= ~PTH_INDEXED;
if (!(tintflags & HICTINT_APPLYOVERPALSWAP))
searchpalnum = 0;
}
// load from art
for (pth=texcache.list[j]; pth; pth=pth->next)
if (pth->picnum == dapicnum &&
(dameth & PTH_INDEXED ? (pth->flags & PTH_INDEXED) &&
(pth->flags & PTH_CLAMPED) == TO_PTH_CLAMPED(dameth) :
(pth->palnum == dapalnum && pth->shade == dashade &&
!(pth->flags & PTH_INDEXED) &&
(pth->flags & (PTH_CLAMPED | PTH_HIGHTILE | PTH_NOTRANSFIX)) ==
(TO_PTH_CLAMPED(dameth) | TO_PTH_NOTRANSFIX(dameth)) &&
polymost_want_npotytex(dameth, tilesiz[dapicnum].y) == !!(pth->flags&PTH_NPOTWALL))))
{
if (pth->flags & PTH_INVALIDATED)
{
pth->flags &= ~PTH_INVALIDATED;
gloadtile_art(dapicnum, searchpalnum, tintpalnum, dashade, dameth, pth, 0);
pth->palnum = dapalnum;
}
if (pth->picnum == dapicnum &&
(pth->flags & PTH_INDEXED) &&
(pth->flags & (PTH_HIGHTILE)) == 0 &&
polymost_want_npotytex(dameth, tilesiz[dapicnum].y) == !!(pth->flags & PTH_NPOTWALL))
{
if (pth->flags & PTH_INVALIDATED)
{
pth->flags &= ~PTH_INVALIDATED;
gloadtile_art(dapicnum, searchpalnum, tintpalnum, dashade, dameth, pth, 0);
pth->palnum = dapalnum;
}
return pth;
}
return pth;
}
pth = (pthtyp *)Xcalloc(1,sizeof(pthtyp));
#ifdef TIMING
cycle_t clock;
clock.Reset();
clock.Clock();
#endif
gloadtile_art(dapicnum, searchpalnum, tintpalnum, dashade, dameth, pth, 1);
//thl.AddToCache(dapicnum, dapalnum, dameth);
#ifdef TIMING
clock.Unclock();
OSD_Printf("Loaded texture %d, palnum %d, meth %d -> %2.3f\n", dapicnum, dapalnum, dameth, clock.TimeMS());
#endif
pth->palnum = dapalnum;
pth->next = texcache.list[j];
@ -90,8 +76,7 @@ pthtyp *texcache_fetchmulti(pthtyp *pth, hicreplctyp *si, int32_t dapicnum, int3
{
Bmemcpy(pth, pth2, sizeof(pthtyp));
pth->picnum = dapicnum;
pth->flags = TO_PTH_CLAMPED(dameth) | TO_PTH_NOTRANSFIX(dameth) |
PTH_HIGHTILE | (drawingskybox>0)*PTH_SKYBOX;
pth->flags = PTH_HIGHTILE | (drawingskybox>0)*PTH_SKYBOX;
if (pth2->flags & PTH_HASALPHA)
pth->flags |= PTH_HASALPHA;
pth->hicr = si;
@ -113,12 +98,12 @@ pthtyp *texcache_fetch(int32_t dapicnum, int32_t dapalnum, int32_t dashade, int3
const int32_t j = dapicnum & (GLTEXCACHEADSIZ - 1);
hicreplctyp *si = usehightile ? hicfindsubst(dapicnum, dapalnum, hictinting[dapalnum].f & HICTINT_ALWAYSUSEART) : NULL;
if (drawingskybox && usehightile)
if ((si = hicfindskybox(dapicnum, dapalnum)) == NULL)
return NULL;
if ((globalflags & GLOBAL_NO_GL_TILESHADES) || videoGetRenderMode() != REND_POLYMOST)
dashade = 0;
if (drawingskybox && usehightile)
{
auto si = hicfindskybox(dapicnum, dapalnum);
if (si == nullptr)
return nullptr;
}
if (!si)
{
@ -141,8 +126,7 @@ pthtyp *texcache_fetch(int32_t dapicnum, int32_t dapalnum, int32_t dashade, int3
for (pthtyp *pth = texcache.list[j]; pth; pth = pth->next)
{
if (pth->picnum == dapicnum && pth->palnum == checkcachepal && (checktintpal > 0 ? 1 : (pth->effects == tintflags))
&& (pth->flags & (PTH_CLAMPED | PTH_HIGHTILE | PTH_SKYBOX | PTH_NOTRANSFIX))
== (TO_PTH_CLAMPED(dameth) | TO_PTH_NOTRANSFIX(dameth) | PTH_HIGHTILE | (drawingskybox > 0) * PTH_SKYBOX)
&& (pth->flags & (PTH_HIGHTILE | PTH_SKYBOX)) == (PTH_HIGHTILE | (drawingskybox > 0) * PTH_SKYBOX)
&& (drawingskybox > 0 ? (pth->skyface == drawingskybox) : 1))
{
if (pth->flags & PTH_INVALIDATED)
@ -171,17 +155,9 @@ pthtyp *texcache_fetch(int32_t dapicnum, int32_t dapalnum, int32_t dashade, int3
if (dapalnum == DETAILPAL && texcache_fetchmulti(pth, si, dapicnum, dameth))
return pth;
#ifdef TIMING
cycle_t clock;
clock.Reset();
clock.Clock();
#endif
int32_t tilestat = gloadtile_hi(dapicnum, dapalnum, drawingskybox, si, dameth, pth, 1, (checktintpal > 0) ? 0 : tintflags);
#ifdef TIMING
clock.Unclock();
OSD_Printf("Loaded texture %d, palnum %d, meth %d -> %2.3f\n", dapicnum, dapalnum, dameth, clock.TimeMS());
#endif
if (!tilestat)
if (!tilestat)
{
pth->next = texcache.list[j];
pth->palnum = checkcachepal;

View file

@ -178,6 +178,8 @@ static GLint primtypes[] =
void GLInstance::Draw(EDrawType type, size_t start, size_t count)
{
// Todo: Based on the current tinting flags and the texture type (indexed texture and APPLYOVERPALSWAP not set) this may have to reset the palette for the draw call / texture creation.
if (activeShader == polymostShader) renderState.Apply(polymostShader);
glBegin(primtypes[type]);
auto p = &Buffer[start];

View file

@ -355,6 +355,10 @@ public:
renderState.Brightness = 8.f / (brightness + 8.f);
}
void SetTinting(int flags, PalEntry color)
{
// not yet implemented.
}
FTexture *GetTexture(const char *filename);
};