From 23265ad2132b1b6834a9e66baea152911a3302b9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 18 Oct 2019 14:04:32 +0200 Subject: [PATCH] - rework of texture management for models Voxels yet to do. This also removes the redundant texture matrix for the glow texture. --- source/build/include/mdsprite.h | 60 ++-- source/build/include/polymost.h | 39 +-- source/build/src/mdsprite.cpp | 271 +++--------------- source/build/src/polymost.cpp | 16 +- source/build/src/texcache.cpp | 52 ++-- source/glbackend/gl_shader.cpp | 2 - source/glbackend/gl_shader.h | 1 - source/glbackend/glbackend.cpp | 4 - source/glbackend/glbackend.h | 16 +- .../demolition/shaders/glsl/polymost.fp | 3 +- .../demolition/shaders/glsl/polymost.vp | 3 - 11 files changed, 122 insertions(+), 345 deletions(-) diff --git a/source/build/include/mdsprite.h b/source/build/include/mdsprite.h index 3a3a67537..8718efa2b 100644 --- a/source/build/include/mdsprite.h +++ b/source/build/include/mdsprite.h @@ -6,26 +6,28 @@ #define SHIFTMOD32(a) ((a)&31) -#define SHARED_MODEL_DATA int32_t mdnum, shadeoff; \ - float scale, bscale, zadd, yoffset; \ - FHardwareTexture **texid; \ - int32_t flags; - -#define IDMODEL_SHARED_DATA int32_t numframes, cframe, nframe, fpssc, usesalpha; \ - float oldtime, curtime, interpol; \ - mdanim_t *animations; \ - mdskinmap_t *skinmap; \ - int32_t numskins, skinloaded; - #define IDP2_MAGIC 0x32504449 #define IDP3_MAGIC 0x33504449 -class FHardwareTexture; +class FTexture; -typedef struct +struct mdmodel_t { - SHARED_MODEL_DATA; -} mdmodel_t; + int32_t mdnum, shadeoff; + float scale, bscale, zadd, yoffset; + FTexture **textures; + + int32_t flags; +}; + +struct idmodel_t : public mdmodel_t +{ + int32_t numframes, cframe, nframe, fpssc, usesalpha; + float oldtime, curtime, interpol; + mdanim_t *animations; + mdskinmap_t *skinmap; + int32_t numskins, skinloaded; +}; typedef struct _mdanim_t { @@ -41,8 +43,7 @@ typedef struct _mdskinmap_t { uint8_t palette, flags, filler[2]; // Build palette number, flags the same as hightiles int32_t skinnum, surfnum; // Skin identifier, surface number - char *fn; // Skin filename - FHardwareTexture *texid[HICTINT_MEMORY_COMBINATIONS]; // OpenGL texture numbers for effect variations + FTexture *texture; struct _mdskinmap_t *next; float param, specpower, specfactor; } mdskinmap_t; @@ -76,11 +77,8 @@ typedef struct uint16_t u[3]; } md2tri_t; -typedef struct +struct md2model_t : public idmodel_t { - SHARED_MODEL_DATA; - IDMODEL_SHARED_DATA; - //MD2 specific stuff: int32_t numverts, numglcmds, framebytes, *glcmds; char *frames; @@ -88,7 +86,7 @@ typedef struct char *skinfn; // pointer to first of numskins 64-char strings md2uv_t *uv; md2tri_t* tris; -} md2model_t; +}; typedef struct { char nam[64]; int32_t i; } md3shader_t; //ascz path of shader, shader index @@ -152,10 +150,8 @@ typedef struct #define SIZEOF_MD3HEAD_T (sizeof(md3head_t)-3*sizeof(void*)) -typedef struct +struct md3model_t : public idmodel_t { - SHARED_MODEL_DATA; - IDMODEL_SHARED_DATA; //MD3 specific md3head_t head; @@ -171,7 +167,7 @@ typedef struct GLuint *texcoords; GLuint *geometry; */ -} md3model_t; +}; #define VOXBORDWIDTH 1 //use 0 to save memory, but has texture artifacts; 1 looks better... #define VOXUSECHAR 0 @@ -184,15 +180,8 @@ typedef struct { uint16_t x, y, z, u, v; } vert_t; typedef struct { vert_t v[4]; } voxrect_t; -typedef struct +struct voxmodel_t : public mdmodel_t { - //WARNING: This top block is a union of md2model,md3model,voxmodel: Make sure it matches! - int32_t mdnum; //VOX=1, MD2=2, MD3=3. NOTE: must be first in structure! - int32_t shadeoff; - float scale, bscale, zadd; - FHardwareTexture **texid; // skins for palettes - int32_t flags; - //VOX specific stuff: voxrect_t *quad; int32_t qcnt, qfacind[7]; int32_t *mytex, mytexx, mytexy; @@ -205,10 +194,9 @@ typedef struct EXTERN mdmodel_t **models; void updateanimation(md2model_t *m, tspriteptr_t tspr, uint8_t lpal); -FHardwareTexture *mdloadskin(md2model_t *m, int32_t number, int32_t pal, int32_t surf); +FTexture *mdloadskin(idmodel_t *m, int32_t number, int32_t pal, int32_t surf, bool *exact) void mdinit(void); void freeallmodels(void); -void clearskins(int32_t type); int32_t polymost_mddraw(tspriteptr_t tspr); EXTERN void md3_vox_calcmat_common(tspriteptr_t tspr, const vec3f_t *a0, float f, float mat[16]); diff --git a/source/build/include/polymost.h b/source/build/include/polymost.h index cc10bb610..f244247ff 100644 --- a/source/build/include/polymost.h +++ b/source/build/include/polymost.h @@ -8,7 +8,6 @@ void Polymost_CacheHitList(uint8_t* hash); - class FHardwareTexture; typedef struct { uint8_t r, g, b, a; } coltype; typedef struct { float r, g, b, a; } coltypef; @@ -33,7 +32,6 @@ extern void Polymost_prepare_loadboard(void); void polymost_outputGLDebugMessage(uint8_t severity, const char* format, ...); //void phex(char v, char *s); -void uploadtexture(FHardwareTexture *tex, int32_t doalloc, vec2_t siz, int32_t texfmt, coltype *pic, vec2_t tsiz, int32_t dameth); void uploadbasepalette(int32_t basepalnum, bool transient = false); void uploadpalswaps(int count, int32_t *palookupnum); void polymost_drawsprite(int32_t snum); @@ -117,6 +115,7 @@ enum { DAMETH_MASKPROPS = 3, DAMETH_CLAMPED = 4, + DAMETH_MODEL = 8, DAMETH_WALL = 32, // signals a texture for a wall (for r_npotwallmode) @@ -127,42 +126,6 @@ enum { #define DAMETH_NARROW_MASKPROPS(dameth) (((dameth)&(~DAMETH_TRANS1))|(((dameth)&DAMETH_TRANS1)>>1)) EDUKE32_STATIC_ASSERT(DAMETH_NARROW_MASKPROPS(DAMETH_MASKPROPS) == DAMETH_MASK); -// pthtyp pth->flags bits -enum pthtyp_flags { - PTH_HIGHTILE = 2, - PTH_SKYBOX = 4, - PTH_HASALPHA = 8, - PTH_HASFULLBRIGHT = 16, - PTH_NPOTWALL = DAMETH_WALL, // r_npotwallmode=1 generated texture - PTH_FORCEFILTER = 64, - - PTH_INVALIDATED = 128, - - PTH_INDEXED = 512, - PTH_ONEBITALPHA = 1024, -}; - -typedef struct pthtyp_t -{ - struct pthtyp_t *next; - struct pthtyp_t *ofb; // fullbright pixels - // *hicr; - - FHardwareTexture * glpic; - vec2f_t scale; - vec2_t siz; - int16_t picnum; - - uint16_t flags; // see pthtyp_flags - polytintflags_t effects; - char palnum; - char shade; - char skyface; -} pthtyp; - -void gloadtile_art(int32_t dapic, int32_t dameth, pthtyp* pth, int32_t doalloc); -extern int32_t gloadtile_hi(int32_t,int32_t,int32_t, int32_t,pthtyp *,int32_t, polytintflags_t); - extern int32_t globalnoeffect; extern int32_t drawingskybox; extern int32_t hicprecaching; diff --git a/source/build/src/mdsprite.cpp b/source/build/src/mdsprite.cpp index fc3ec3bd3..051890421 100644 --- a/source/build/src/mdsprite.cpp +++ b/source/build/src/mdsprite.cpp @@ -122,96 +122,6 @@ void freeallmodels() #endif } - -// Skin texture names can be aliased! This is ugly, but at least correct. -static void nullskintexids(FHardwareTexture *texid) -{ - int32_t i, j; - - for (i=0; imdnum == 2 || m->mdnum == 3) - { - mdskinmap_t *sk; - md2model_t *m2 = (md2model_t *)m; - - for (j=0; j < m2->numskins * HICTINT_MEMORY_COMBINATIONS; j++) - if (m2->texid[j] == texid) - m2->texid[j] = nullptr; - - for (sk=m2->skinmap; sk; sk=sk->next) - for (j=0; j < HICTINT_MEMORY_COMBINATIONS; j++) - if (sk->texid[j] == texid) - sk->texid[j] = nullptr; - } - } -} - -void clearskins(int32_t type) -{ - int32_t i, j; - - for (i=0; imdnum == 1) - { - voxmodel_t *v = (voxmodel_t *)m; - - for (j=0; jtexid[j]) - { - delete v->texid[j]; - v->texid[j] = nullptr; - } - } - else if ((m->mdnum == 2 || m->mdnum == 3) && type == INVALIDATE_ALL) - { - mdskinmap_t *sk; - md2model_t *m2 = (md2model_t *)m; - - for (j=0; j < m2->numskins * HICTINT_MEMORY_COMBINATIONS; j++) - if (m2->texid[j]) - { - auto otexid = m2->texid[j]; - - delete m2->texid[j]; - m2->texid[j] = nullptr; - - nullskintexids(otexid); - } - - for (sk=m2->skinmap; sk; sk=sk->next) - for (j=0; j < HICTINT_MEMORY_COMBINATIONS; j++) - if (sk->texid[j]) - { - auto otexid = sk->texid[j]; - - delete sk->texid[j]; - sk->texid[j] = nullptr; - - nullskintexids(otexid); - } - } - } - - for (i=0; itexid[j]) - { - delete v->texid[j]; - v->texid[j] = nullptr; - } - } -} - void mdinit() { freeallmodels(); @@ -478,7 +388,6 @@ int32_t md_defineskin(int32_t modelid, const char *skinfn, int32_t palnum, int32 if (!skl) m->skinmap = sk; else skl->next = sk; } - else Xfree(sk->fn); sk->palette = (uint8_t)palnum; sk->flags = (uint8_t)flags; @@ -487,7 +396,11 @@ int32_t md_defineskin(int32_t modelid, const char *skinfn, int32_t palnum, int32 sk->param = param; sk->specpower = specpower; sk->specfactor = specfactor; - sk->fn = Xstrdup(skinfn); + sk->texture = TileFiles.GetTexture(skinfn); + if (!sk->texture) + { + initprintf("Unable to load %s as model skin\n", skinfn); + } return 0; } @@ -557,28 +470,11 @@ static inline int32_t hicfxid(size_t pal) return globalnoeffect ? 0 : ((hictinting[pal].f & (HICTINT_GRAYSCALE|HICTINT_INVERT|HICTINT_COLORIZE)) | ((hictinting[pal].f & HICTINT_BLENDMASK)<<3)); } -static FHardwareTexture *mdloadskin_notfound(char * const skinfile, char const * const fn) -{ - OSD_Printf("Skin \"%s\" not found.\n", fn); - - skinfile[0] = 0; - return nullptr; -} - -static FHardwareTexture *mdloadskin_failed(char * const skinfile, char const * const fn) -{ - OSD_Printf("Failed loading skin file \"%s\".\n", fn); - - skinfile[0] = 0; - return nullptr; -} //Note: even though it says md2model, it works for both md2model&md3model -FHardwareTexture *mdloadskin(md2model_t *m, int32_t number, int32_t pal, int32_t surf) +FTexture *mdloadskin(idmodel_t *m, int32_t number, int32_t pal, int32_t surf, bool *exact) { int32_t i; - char *skinfile = NULL, fn[BMAX_PATH]; - FHardwareTexture **texidx = NULL; mdskinmap_t *sk, *skzero = NULL; int32_t doalloc = 1; @@ -593,11 +489,9 @@ FHardwareTexture *mdloadskin(md2model_t *m, int32_t number, int32_t pal, int32_t { if (sk->palette == pal && sk->skinnum == number && sk->surfnum == surf) { - skinfile = sk->fn; - texidx = &sk->texid[hicfxid(pal)]; - Bstrncpyz(fn, skinfile, BMAX_PATH); + if (exact) *exact = true; //OSD_Printf("Using exact match skin (pal=%d,skinnum=%d,surfnum=%d) %s\n",pal,number,surf,skinfile); - break; + return sk->texture; } //If no match, give highest priority to number, then pal.. (Parkar's request, 02/27/2005) else if ((sk->palette == 0) && (sk->skinnum == number) && (sk->surfnum == surf) && (i < 5)) { i = 5; skzero = sk; } @@ -608,74 +502,18 @@ FHardwareTexture *mdloadskin(md2model_t *m, int32_t number, int32_t pal, int32_t else if ((sk->palette == 0) && (sk->skinnum == 0) && (i < 0)) { i = 0; skzero = sk; } } - if (!sk) - { - if (pal >= (MAXPALOOKUPS - RESERVEDPALS)) - return 0; + // Special palettes do not get replacements + if (pal >= (MAXPALOOKUPS - RESERVEDPALS)) + return 0; - if (skzero) - { - skinfile = skzero->fn; - texidx = &skzero->texid[hicfxid(pal)]; - Bstrncpyz(fn, skinfile, BMAX_PATH); - //OSD_Printf("Using def skin 0,0 as fallback, pal=%d\n", pal); - } - else - return 0; - } - - if (skinfile == NULL || !skinfile[0]) - return 0; - - if (*texidx) - return *texidx; - - // possibly fetch an already loaded multitexture :_) - if (pal >= (MAXPALOOKUPS - RESERVEDPALS)) - for (i=0; iskinmap; skzero && sk; skzero = skzero->next) - if (!Bstrcasecmp(skzero->fn, sk->fn) && skzero->texid[hicfxid(pal)]) - { - size_t f = hicfxid(pal); - - sk->texid[f] = skzero->texid[f]; - return sk->texid[f]; - } - - // for sk->flags below - if (!sk) - sk = skzero; - - *texidx = 0; - - auto texture = TileFiles.GetTexture(fn); - - if (texture == nullptr) + if (skzero) { - return mdloadskin_notfound(skinfile, fn); + //OSD_Printf("Using def skin 0,0 as fallback, pal=%d\n", pal); + if (exact) *exact = false; + return skzero->texture; } - - if ((doalloc & 3) == 1) - { - *texidx = GLInterface.NewTexture(); - } - - auto glpic = *texidx; - glpic->CreateTexture(texture->GetWidth(), texture->GetHeight(), false, true); - auto image = texture->GetBgraBitmap(nullptr, nullptr); - bool hasalpha = texture->GetTranslucency(); - bool onebitalpha = texture->isMasked(); - glpic->LoadTexture(image); - if (!m->skinloaded) - { - m->skinloaded = 1+number; - } - - if (*texidx) - { - (*texidx)->SetSampler(SamplerRepeat); - } - return (*texidx); + else + return nullptr; } //Note: even though it says md2model, it works for both md2model&md3model @@ -959,8 +797,6 @@ static md2model_t *md2load(buildvfs_kfd fil, const char *filnam) { Xfree(m->glcmds); Xfree(m->frames); Xfree(m); return 0; } } - m->texid = (FHardwareTexture **)Xcalloc(ournumskins, sizeof(FHardwareTexture*) * HICTINT_MEMORY_COMBINATIONS); - maxmodelverts = max(maxmodelverts, m->numverts); maxmodeltris = max(maxmodeltris, head.numtris); @@ -969,7 +805,7 @@ static md2model_t *md2load(buildvfs_kfd fil, const char *filnam) // the MD2 is now loaded internally - let's begin the MD3 conversion process //OSD_Printf("Beginning md3 conversion.\n"); m3 = (md3model_t *)Xcalloc(1, sizeof(md3model_t)); - m3->mdnum = 3; m3->texid = nullptr; m3->scale = m->scale; + m3->mdnum = 3; m3->texture = nullptr m3->scale = m->scale; m3->head.id = IDP3_MAGIC; m3->head.vers = 15; m3->head.flags = 0; @@ -1071,9 +907,12 @@ static md2model_t *md2load(buildvfs_kfd fil, const char *filnam) if (m->numskins > 0) { - sk->fn = (char *)Xmalloc(strlen(m->basepath)+strlen(m->skinfn)+1); - Bstrcpy(sk->fn, m->basepath); - Bstrcat(sk->fn, m->skinfn); + FStringf fn("%s%s", m->basepath, m->skinfn); + sk->texture = TileFiles.GetTexture(fn); + if (!sk->texture) + { + initprintf("Unable to load %s as model skin\n", skinfn); + } } m3->skinmap = sk; } @@ -1083,7 +922,7 @@ static md2model_t *md2load(buildvfs_kfd fil, const char *filnam) m3->maxdepths = (float *)Xmalloc(sizeof(float) * s->numtris); // die MD2 ! DIE ! - Xfree(m->texid); Xfree(m->skinfn); Xfree(m->basepath); Xfree(m->uv); Xfree(m->tris); Xfree(m->glcmds); Xfree(m->frames); Xfree(m); + Xfree(m->skinfn); Xfree(m->basepath); Xfree(m->uv); Xfree(m->tris); Xfree(m->glcmds); Xfree(m->frames); Xfree(m); return ((md2model_t *)m3); } @@ -1136,7 +975,7 @@ static md3model_t *md3load(buildvfs_kfd fil) md3surf_t *s; m = (md3model_t *)Xcalloc(1,sizeof(md3model_t)); - m->mdnum = 3; m->texid = 0; m->scale = .01f; + m->mdnum = 3; m->texture = nullptr; m->scale = .01f; m->muladdframes = NULL; @@ -1890,11 +1729,27 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr) GLInterface.SetMatrix(Matrix_ModelView, mat); // PLAG: End - auto tex = mdloadskin((md2model_t *)m,tile2model[Ptile2tile(tspr->picnum,lpal)].skinnum,globalpal,surfi); + bool exact = false; + auto tex = mdloadskin((md2model_t *)m,tile2model[Ptile2tile(tspr->picnum,lpal)].skinnum,globalpal,surfi, &exact); if (!tex) continue; - //i = mdloadskin((md2model *)m,tile2model[Ptile2tile(tspr->picnum,lpal)].skinnum,surfi); //hack for testing multiple surfaces per MD3 - GLInterface.BindTexture(0, tex); + + FTexture *det = nullptr, *glow = nullptr; + float detscale = 1.f; + + // The data lookup here is one incredible mess. Thanks to whoever cooked this up... :( + if (!(tspr->extra&TSPR_EXTRA_MDHACK)) + { + det = tex = r_detailmapping ? mdloadskin((md2model_t *) m, tile2model[Ptile2tile(tspr->picnum, lpal)].skinnum, DETAILPAL, surfi, nullptr) : nullptr; + if (det) + { + for (sk = m->skinmap; sk; sk = sk->next) + if ((int32_t) sk->palette == DETAILPAL && sk->skinnum == tile2model[Ptile2tile(tspr->picnum, lpal)].skinnum && sk->surfnum == surfi) + detscale = sk->param; + } + glow = r_glowmapping ? mdloadskin((md2model_t *) m, tile2model[Ptile2tile(tspr->picnum, lpal)].skinnum, GLOWPAL, surfi, nullptr) : 0; + } + GLInterface.SetModelTexture(tex, globalpal, xpanning, ypanning, det, detscale, glow); VSMatrix texmat(0); texmat.translate(xpanning, ypanning, 1.0f); @@ -1902,38 +1757,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr) if (!(tspr->extra&TSPR_EXTRA_MDHACK)) { //POGOTODO: if we add support for palette indexing on model skins, the texture for the palswap could be setup here -#if 0 // FIXME: This shouls use the HightileReplacement structure inside the texture so that it can use the same code as world textures. - tex = r_detailmapping ? mdloadskin((md2model_t *) m, tile2model[Ptile2tile(tspr->picnum, lpal)].skinnum, DETAILPAL, surfi) : nullptr; - if (tex) - { - mdskinmap_t *sk; - - GLInterface.UseDetailMapping(true); - //polymost_setupdetailtexture(3, tex); - - for (sk = m->skinmap; sk; sk = sk->next) - if ((int32_t) sk->palette == DETAILPAL && sk->skinnum == tile2model[Ptile2tile(tspr->picnum, lpal)].skinnum && sk->surfnum == surfi) - f = sk->param; - - texmat.loadIdentity(); - texmat.translate(xpanning, ypanning, 1.0f); - texmat.scale(f, f, 1.0f); - GLInterface.SetMatrix(Matrix_Detail, &texmat); - } - - tex = r_glowmapping ? mdloadskin((md2model_t *) m, tile2model[Ptile2tile(tspr->picnum, lpal)].skinnum, GLOWPAL, surfi) : 0; - - if (i) - { - GLInterface.UseGlowMapping(true); - //polymost_setupglowtexture(4, tex); - - texmat.loadIdentity(); - texmat.translate(xpanning, ypanning, 1.0f); - GLInterface.SetMatrix(Matrix_Glow, &texmat); - } -#endif indexhandle = m->vindexes; //PLAG: delayed polygon-level sorted rendering @@ -2020,7 +1844,6 @@ static void md3free(md3model_t *m) for (sk=m->skinmap; sk; sk=nsk) { nsk = sk->next; - Xfree(sk->fn); Xfree(sk); } @@ -2036,9 +1859,7 @@ static void md3free(md3model_t *m) } Xfree(m->head.tags); Xfree(m->head.frames); - - Xfree(m->texid); - + Xfree(m->muladdframes); Xfree(m->indexes); diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index 6cc597dc3..234d0a0da 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -121,11 +121,7 @@ int32_t r_yshearing = 0; static float fogresult, fogresult2; coltypef fogcol, fogtable[MAXPALOOKUPS]; -static GLuint quadVertsID = 0; - - int32_t r_useindexedcolortextures = -1; -static FHardwareTexture *palswapTextureID = nullptr; static inline float float_trans(uint32_t maskprops, uint8_t blend) { @@ -295,7 +291,6 @@ void polymost_glinit() { uploadbasepalette(basepalnum); } - palswapTextureID = 0; for (int palookupnum = 0; palookupnum < MAXPALOOKUPS; ++palookupnum) { GLInterface.SetPalswapData(palookupnum, (uint8_t*)palookup[palookupnum], numshades+1); @@ -434,12 +429,6 @@ static void resizeglcheck(void) } } - -void uploadtexture(FHardwareTexture *tex, coltype* pic) -{ - tex->LoadTexture((uint8_t *)pic); -} - void uploadbasepalette(int32_t basepalnum, bool transient) // transient palettes are used by movies and should not affect the engine state. All other palettes only get set at game startup. { if (!basepaltable[basepalnum]) @@ -5610,7 +5599,10 @@ void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype) int const surfaces = (models[mid]->mdnum == 3) ? ((md3model_t *)models[mid])->head.numsurfs : 0; for (int i = 0; i <= surfaces; i++) - mdloadskin((md2model_t *)models[mid], 0, dapalnum, i); + { + auto tex = mdloadskin((md2model_t *)models[mid], 0, dapalnum, i); + if (tex) GLInterface.SetTexture(tex, dapalnum, 0); + } } void PrecacheHardwareTextures(int nTile) diff --git a/source/build/src/texcache.cpp b/source/build/src/texcache.cpp index bd4787c48..01e46a29c 100644 --- a/source/build/src/texcache.cpp +++ b/source/build/src/texcache.cpp @@ -119,11 +119,11 @@ FHardwareTexture* GLInstance::LoadTexture(FTexture* tex, int textype, int palid) //=========================================================================== // -// Sets a texture for rendering +// Sets a texture for rendering. This should be the ONLY place to bind in-game textures // //=========================================================================== -bool GLInstance::SetTexture(FTexture* tex, int palette, int method, int sampleroverride) +bool GLInstance::SetTextureInternal(FTexture* tex, int palette, int method, int sampleroverride, float xpanning, float ypanning, FTexture *det, float detscale, FTexture *glow) { int usepalette = fixpalette >= 1 ? fixpalette - 1 : curbasepal; int usepalswap = fixpalswap >= 1 ? fixpalswap - 1 : palette; @@ -155,9 +155,10 @@ bool GLInstance::SetTexture(FTexture* tex, int palette, int method, int samplero auto sampler = (method & DAMETH_CLAMPED) ? (sampleroverride != -1 ? sampleroverride : SamplerClampXY) : SamplerRepeat; BindTexture(0, mtex, sampler); - if (rep && ((rep->scale.x != 1.0f) || (rep->scale.y != 1.0f))) + if (rep && (rep->scale.x != 1.0f || rep->scale.y != 1.0f || xpanning != 0 || ypanning != 0)) { texmat.loadIdentity(); + texmat.translate(xpanning, ypanning, 0); texmat.scale(rep->scale.x, rep->scale.y, 1.0f); GLInterface.SetMatrix(Matrix_Texture, &texmat); MatrixChange |= 1; @@ -166,24 +167,30 @@ bool GLInstance::SetTexture(FTexture* tex, int palette, int method, int samplero // Also load additional layers needed for this texture. if (r_detailmapping && usehightile) { - auto drep = currentTexture->FindReplacement(DETAILPAL); - if (drep) + float detscalex = detscale, detscaley = detscale; + if (!(method & DAMETH_MODEL)) { - auto htex = LoadTexture(drep->faces[0], TT_HICREPLACE, 0); + auto drep = currentTexture->FindReplacement(DETAILPAL); + if (drep) + { + det = drep->faces[0]; + detscalex = drep->scale.x; + detscaley = drep->scale.y; + } + } + if (det) + { + auto htex = LoadTexture(det, TT_HICREPLACE, 0); UseDetailMapping(true); BindTexture(3, htex, SamplerRepeat); - texmat.loadIdentity(); + // Q: Pass the scale factor as a separate uniform to get rid of the additional matrix? + if (MatrixChange & 1) MatrixChange |= 2; + else texmat.loadIdentity(); - if (rep && ((rep->scale.x != 1.0f) || (rep->scale.y != 1.0f))) + if ((detscalex != 1.0f) || (detscaley != 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); + texmat.scale(detscalex, detscaley, 1.0f); MatrixChange |= 2; } if (MatrixChange & 2) GLInterface.SetMatrix(Matrix_Detail, &texmat); @@ -191,13 +198,19 @@ bool GLInstance::SetTexture(FTexture* tex, int palette, int method, int samplero } if (r_glowmapping && usehightile) { - auto drep = currentTexture->FindReplacement(GLOWPAL); - if (drep) + if (!(method & DAMETH_MODEL)) { - auto htex = LoadTexture(drep->faces[0], TT_HICREPLACE, 0); + auto drep = currentTexture->FindReplacement(DETAILPAL); + if (drep) + { + glow = drep->faces[0]; + } + } + if (glow) + { + auto htex = LoadTexture(glow, TT_HICREPLACE, 0); UseGlowMapping(true); BindTexture(4, htex, SamplerRepeat); - } } if (!(tex->PicAnim.sf & PICANM_NOFULLBRIGHT_BIT) && !(globalflags & GLOBAL_NO_GL_FULLBRIGHT)) @@ -235,4 +248,3 @@ bool GLInstance::SetTexture(FTexture* tex, int palette, int method, int samplero } - diff --git a/source/glbackend/gl_shader.cpp b/source/glbackend/gl_shader.cpp index b3a6888d0..a87955231 100644 --- a/source/glbackend/gl_shader.cpp +++ b/source/glbackend/gl_shader.cpp @@ -156,7 +156,6 @@ bool PolymostShader::Load(const char * name, const char * vert_prog, const char ModelMatrix.Init(hShader, "u_modelMatrix"); ProjectionMatrix.Init(hShader, "u_projectionMatrix"); DetailMatrix.Init(hShader, "u_detailMatrix"); - GlowMatrix.Init(hShader, "u_glowMatrix"); TextureMatrix.Init(hShader, "u_textureMatrix"); @@ -166,7 +165,6 @@ bool PolymostShader::Load(const char * name, const char * vert_prog, const char VSMatrix identity(0); TextureMatrix.Set(identity.get()); DetailMatrix.Set(identity.get()); - GlowMatrix.Set(identity.get()); int SamplerLoc; SamplerLoc = glGetUniformLocation(hShader, "s_texture"); diff --git a/source/glbackend/gl_shader.h b/source/glbackend/gl_shader.h index e08abc78a..30863a9c8 100644 --- a/source/glbackend/gl_shader.h +++ b/source/glbackend/gl_shader.h @@ -56,7 +56,6 @@ public: FUniformMatrix4f ModelMatrix; FUniformMatrix4f ProjectionMatrix; FUniformMatrix4f DetailMatrix; - FUniformMatrix4f GlowMatrix; FUniformMatrix4f TextureMatrix; public: diff --git a/source/glbackend/glbackend.cpp b/source/glbackend/glbackend.cpp index 184fa1f9b..ce81b80af 100644 --- a/source/glbackend/glbackend.cpp +++ b/source/glbackend/glbackend.cpp @@ -334,10 +334,6 @@ void GLInstance::SetMatrix(int num, const VSMatrix *mat) polymostShader->DetailMatrix.Set(mat->get()); break; - case Matrix_Glow: - polymostShader->GlowMatrix.Set(mat->get()); - break; - case Matrix_Texture: polymostShader->TextureMatrix.Set(mat->get()); break; diff --git a/source/glbackend/glbackend.h b/source/glbackend/glbackend.h index 5eaa95efe..f1e91c87d 100644 --- a/source/glbackend/glbackend.h +++ b/source/glbackend/glbackend.h @@ -141,7 +141,6 @@ enum EMatrixType Matrix_Projection, Matrix_ModelView, Matrix_Detail, - Matrix_Glow, Matrix_Texture, // These are the only ones being used. NUMMATRICES @@ -382,7 +381,20 @@ public: FHardwareTexture* CreateIndexedTexture(FTexture* tex); FHardwareTexture* CreateTrueColorTexture(FTexture* tex, int palid, bool checkfulltransparency = false); FHardwareTexture *LoadTexture(FTexture* tex, int texturetype, int palid); - bool SetTexture(FTexture* tex, int palette, int method, int sampleroverride = -1); + bool SetTextureInternal(FTexture* tex, int palette, int method, int sampleroverride, float xpanning, float ypanning, FTexture *det, float detscale, FTexture *glow); + + + bool SetTexture(FTexture* tex, int palette, int method, int sampleroverride) + { + return SetTextureInternal(tex, palette, method, sampleroverride, 0, 0, nullptr, 1, nullptr); + } + + bool SetModelTexture(FTexture *tex, int palette, float xpanning, float ypanning, FTexture *det, float detscale, FTexture *glow) + { + return SetTextureInternal(tex, palette, DAMETH_MODEL, -1, xpanning, ypanning, det, detscale, glow); + } + +) }; extern GLInstance GLInterface; diff --git a/wadsrc/static/demolition/shaders/glsl/polymost.fp b/wadsrc/static/demolition/shaders/glsl/polymost.fp index 8d06596be..e87cf5b73 100644 --- a/wadsrc/static/demolition/shaders/glsl/polymost.fp +++ b/wadsrc/static/demolition/shaders/glsl/polymost.fp @@ -37,7 +37,6 @@ in vec4 v_color; in float v_distance; in vec4 v_texCoord; in vec4 v_detailCoord; -in vec4 v_glowCoord; in float v_fogCoord; const float c_basepalScale = 255.0/256.0; @@ -210,7 +209,7 @@ void main() if (u_useGlowMapping != 0.0 && u_useColorOnly == 0.0) { - vec4 glowColor = texture2D(s_glow, v_glowCoord.xy); + vec4 glowColor = texture2D(s_glow, v_texCoord.xy); color.rgb = mix(color.rgb, glowColor.rgb, glowColor.a); } diff --git a/wadsrc/static/demolition/shaders/glsl/polymost.vp b/wadsrc/static/demolition/shaders/glsl/polymost.vp index a46ca3a1a..18d65d413 100644 --- a/wadsrc/static/demolition/shaders/glsl/polymost.vp +++ b/wadsrc/static/demolition/shaders/glsl/polymost.vp @@ -4,7 +4,6 @@ out vec4 v_color; out float v_distance; out vec4 v_texCoord; out vec4 v_detailCoord; -out vec4 v_glowCoord; out float v_fogCoord; uniform float u_usePalette; @@ -12,7 +11,6 @@ uniform mat4 u_rotMatrix; uniform mat4 u_modelMatrix; uniform mat4 u_projectionMatrix; uniform mat4 u_detailMatrix; -uniform mat4 u_glowMatrix; uniform mat4 u_textureMatrix; in vec4 i_vertPos; @@ -33,7 +31,6 @@ void main() v_texCoord = u_textureMatrix * i_texCoord; v_detailCoord = u_detailMatrix * i_texCoord; - v_glowCoord = u_glowMatrix * i_texCoord; v_fogCoord = abs(eyeCoordPosition.z);