diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 7b5b7cc1e..73cb8fac7 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -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/.+") - \ No newline at end of file +source_group("Game Frontends\\Shadow Warrior\\Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sw/.+") diff --git a/source/build/include/polymost.h b/source/build/include/polymost.h index 9132d9bbb..c627f5f48 100644 --- a/source/build/include/polymost.h +++ b/source/build/include/polymost.h @@ -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 and ? 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); diff --git a/source/build/src/mdsprite.cpp b/source/build/src/mdsprite.cpp index baffe2f42..0703b9341 100644 --- a/source/build/src/mdsprite.cpp +++ b/source/build/src/mdsprite.cpp @@ -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(); diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index ecbae34e6..107bf8326 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -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 0) && (wpptr[naxsiz2].a)) { r += wpptr[naxsiz2].r; g += wpptr[naxsiz2].g; b += wpptr[naxsiz2].b; j++; } - if ((yr = 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; diff --git a/source/build/src/texcache.cpp b/source/build/src/texcache.cpp index 249be4703..f1514292b 100644 --- a/source/build/src/texcache.cpp +++ b/source/build/src/texcache.cpp @@ -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; diff --git a/source/glbackend/glbackend.cpp b/source/glbackend/glbackend.cpp index d30bfb745..aa1b446cd 100644 --- a/source/glbackend/glbackend.cpp +++ b/source/glbackend/glbackend.cpp @@ -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]; diff --git a/source/glbackend/glbackend.h b/source/glbackend/glbackend.h index 4037cbcba..4bf06c8c4 100644 --- a/source/glbackend/glbackend.h +++ b/source/glbackend/glbackend.h @@ -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); };