From 0ce0099e29d8de6f546ff68563531ebaabe5f37c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 14 Apr 2020 23:19:11 +0200 Subject: [PATCH] - moved the sprite positioning info out of FMaterial back into FTexture. This cleans out half of FMaterial and brings it closer to being a texture binding descriptor, which is all it really should be. --- src/common/textures/hw_material.cpp | 252 +----------------- src/common/textures/hw_material.h | 20 -- src/common/textures/texture.cpp | 232 +++++++++++++++- src/common/textures/textures.h | 35 ++- src/rendering/hwrenderer/scene/hw_sprites.cpp | 39 +-- src/rendering/hwrenderer/scene/hw_walls.cpp | 2 +- src/rendering/hwrenderer/scene/hw_weapon.cpp | 29 +- 7 files changed, 309 insertions(+), 300 deletions(-) diff --git a/src/common/textures/hw_material.cpp b/src/common/textures/hw_material.cpp index bb39cef7be..34f60af794 100644 --- a/src/common/textures/hw_material.cpp +++ b/src/common/textures/hw_material.cpp @@ -30,21 +30,6 @@ IHardwareTexture* CreateHardwareTexture(); -// We really do not need to create more than one hardware texture per image source. -// However, the internal handling depends on FTexture for everything so this array maps each all textures sharing the same master texture that gets used in the layer array. -static TMap imageToMasterTexture; - -static FTexture* GetMasterTexture(FTexture* tx) -{ - if (tx->GetUseType() == ETextureType::Null) return tx; // Null textures never get redirected - auto img = tx->GetImage(); - if (!img) return tx; // this is not an image texture and represents itself. - auto find = imageToMasterTexture.CheckKey(img); - if (find) return *find; // already got a master texture for this. Return it. - imageToMasterTexture.Insert(img, tx); - return tx; // this is a newly added master texture. -} - //=========================================================================== // // Constructor @@ -55,7 +40,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) { mShaderIndex = SHADER_Default; sourcetex = tx; - imgtex = GetMasterTexture(tx); + imgtex = tx; if (tx->UseType == ETextureType::SWCanvas && static_cast(tx)->GetColorFormat() == 0) { @@ -79,7 +64,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) { for (auto &texture : { tx->Normal, tx->Specular }) { - mTextureLayers.Push(GetMasterTexture(texture)); + mTextureLayers.Push(texture); } mShaderIndex = SHADER_Specular; } @@ -87,7 +72,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) { for (auto &texture : { tx->Normal, tx->Metallic, tx->Roughness, tx->AmbientOcclusion }) { - mTextureLayers.Push(GetMasterTexture(texture)); + mTextureLayers.Push(texture); } mShaderIndex = SHADER_PBR; } @@ -96,7 +81,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) tx->CreateDefaultBrightmap(); if (tx->Brightmap) { - mTextureLayers.Push(GetMasterTexture(tx->Brightmap)); + mTextureLayers.Push(tx->Brightmap); mLayerFlags |= TEXF_Brightmap; } else @@ -105,7 +90,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) } if (tx->Detailmap) { - mTextureLayers.Push(GetMasterTexture(tx->Detailmap)); + mTextureLayers.Push(tx->Detailmap); mLayerFlags |= TEXF_Detailmap; } else @@ -114,7 +99,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) } if (tx->Glowmap) { - mTextureLayers.Push(GetMasterTexture(tx->Glowmap)); + mTextureLayers.Push(tx->Glowmap); mLayerFlags |= TEXF_Glowmap; } else @@ -130,7 +115,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) for (auto &texture : tx->CustomShaderTextures) { if (texture == nullptr) continue; - mTextureLayers.Push(GetMasterTexture(texture)); + mTextureLayers.Push(texture); } mShaderIndex = tx->shaderindex; } @@ -142,23 +127,8 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) mTopOffset = tx->GetTopOffset(0); mRenderWidth = tx->GetScaledWidth(); mRenderHeight = tx->GetScaledHeight(); - mSpriteU[0] = mSpriteV[0] = 0.f; - mSpriteU[1] = mSpriteV[1] = 1.f; mExpanded = expanded; - if (expanded) - { - int oldwidth = mWidth; - int oldheight = mHeight; - - mTrimResult = TrimBorders(trim); // get the trim size before adding the empty frame - mWidth += 2; - mHeight += 2; - mRenderWidth = mRenderWidth * mWidth / oldwidth; - mRenderHeight = mRenderHeight * mHeight / oldheight; - - } - SetSpriteRect(); mTextureLayers.ShrinkToFit(); tx->Material[expanded] = this; @@ -175,149 +145,6 @@ FMaterial::~FMaterial() { } -//=========================================================================== -// -// Set the sprite rectangle -// -//=========================================================================== - -void FMaterial::SetSpriteRect() -{ - auto leftOffset = sourcetex->GetLeftOffsetHW(); - auto topOffset = sourcetex->GetTopOffsetHW(); - - float fxScale = (float)sourcetex->Scale.X; - float fyScale = (float)sourcetex->Scale.Y; - - // mSpriteRect is for positioning the sprite in the scene. - mSpriteRect.left = -leftOffset / fxScale; - mSpriteRect.top = -topOffset / fyScale; - mSpriteRect.width = mWidth / fxScale; - mSpriteRect.height = mHeight / fyScale; - - if (mExpanded) - { - // a little adjustment to make sprites look better with texture filtering: - // create a 1 pixel wide empty frame around them. - - int oldwidth = mWidth - 2; - int oldheight = mHeight - 2; - - leftOffset += 1; - topOffset += 1; - - // Reposition the sprite with the frame considered - mSpriteRect.left = -leftOffset / fxScale; - mSpriteRect.top = -topOffset / fyScale; - mSpriteRect.width = mWidth / fxScale; - mSpriteRect.height = mHeight / fyScale; - - if (mTrimResult) - { - mSpriteRect.left += trim[0] / fxScale; - mSpriteRect.top += trim[1] / fyScale; - - mSpriteRect.width -= (oldwidth - trim[2]) / fxScale; - mSpriteRect.height -= (oldheight - trim[3]) / fyScale; - - mSpriteU[0] = trim[0] / (float)mWidth; - mSpriteV[0] = trim[1] / (float)mHeight; - mSpriteU[1] -= (oldwidth - trim[0] - trim[2]) / (float)mWidth; - mSpriteV[1] -= (oldheight - trim[1] - trim[3]) / (float)mHeight; - } - } -} - - -//=========================================================================== -// -// Finds empty space around the texture. -// Used for sprites that got placed into a huge empty frame. -// -//=========================================================================== - -bool FMaterial::TrimBorders(uint16_t *rect) -{ - - auto texbuffer = sourcetex->CreateTexBuffer(0); - int w = texbuffer.mWidth; - int h = texbuffer.mHeight; - auto Buffer = texbuffer.mBuffer; - - if (texbuffer.mBuffer == nullptr) - { - return false; - } - if (w != mWidth || h != mHeight) - { - // external Hires replacements cannot be trimmed. - return false; - } - - int size = w*h; - if (size == 1) - { - // nothing to be done here. - rect[0] = 0; - rect[1] = 0; - rect[2] = 1; - rect[3] = 1; - return true; - } - int first, last; - - for(first = 0; first < size; first++) - { - if (Buffer[first*4+3] != 0) break; - } - if (first >= size) - { - // completely empty - rect[0] = 0; - rect[1] = 0; - rect[2] = 1; - rect[3] = 1; - return true; - } - - for(last = size-1; last >= first; last--) - { - if (Buffer[last*4+3] != 0) break; - } - - rect[1] = first / w; - rect[3] = 1 + last/w - rect[1]; - - rect[0] = 0; - rect[2] = w; - - unsigned char *bufferoff = Buffer + (rect[1] * w * 4); - h = rect[3]; - - for(int x = 0; x < w; x++) - { - for(int y = 0; y < h; y++) - { - if (bufferoff[(x+y*w)*4+3] != 0) goto outl; - } - rect[0]++; - } -outl: - rect[2] -= rect[0]; - - for(int x = w-1; rect[2] > 1; x--) - { - for(int y = 0; y < h; y++) - { - if (bufferoff[(x+y*w)*4+3] != 0) - { - return true; - } - } - rect[2]--; - } - return true; -} //=========================================================================== // @@ -343,25 +170,6 @@ IHardwareTexture *FMaterial::GetLayer(int i, int translation, FTexture **pLayer) return nullptr; } -//=========================================================================== -// -// -// -//=========================================================================== - -int FMaterial::GetAreas(FloatRect **pAreas) const -{ - if (mShaderIndex == SHADER_Default) // texture splitting can only be done if there's no attached effects - { - *pAreas = sourcetex->areas; - return sourcetex->areacount; - } - else - { - return 0; - } -} - //========================================================================== // // Gets a texture from the texture manager and checks its validity for @@ -371,31 +179,13 @@ int FMaterial::GetAreas(FloatRect **pAreas) const FMaterial * FMaterial::ValidateTexture(FTexture * tex, bool expand, bool create) { -again: if (tex && tex->isValid()) { - if (tex->bNoExpand) expand = false; + if (!tex->ShouldExpandSprite()) expand = false; FMaterial *hwtex = tex->Material[expand]; if (hwtex == NULL && create) { - if (expand) - { - if (tex->isWarped() || tex->isHardwareCanvas() || tex->shaderindex >= FIRST_USER_SHADER || tex->shaderindex == SHADER_Specular || tex->shaderindex == SHADER_PBR) - { - tex->bNoExpand = true; - goto again; - } - if (tex->Brightmap != NULL && - (tex->GetTexelWidth() != tex->Brightmap->GetTexelWidth() || - tex->GetTexelHeight() != tex->Brightmap->GetTexelHeight()) - ) - { - // do not expand if the brightmap's size differs. - tex->bNoExpand = true; - goto again; - } - } hwtex = new FMaterial(tex, expand); } return hwtex; @@ -415,29 +205,3 @@ void DeleteMaterial(FMaterial* mat) } -//----------------------------------------------------------------------------- -// -// Make sprite offset adjustment user-configurable per renderer. -// -//----------------------------------------------------------------------------- - -extern int r_spriteadjustSW, r_spriteadjustHW; - -CUSTOM_CVAR(Int, r_spriteadjust, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -{ - r_spriteadjustHW = !!(self & 2); - r_spriteadjustSW = !!(self & 1); - for (int i = 0; i < TexMan.NumTextures(); i++) - { - auto tex = TexMan.GetTexture(FSetTextureID(i)); - if (tex->GetTexelLeftOffset(0) != tex->GetTexelLeftOffset(1) || tex->GetTexelTopOffset(0) != tex->GetTexelTopOffset(1)) - { - for (int i = 0; i < 2; i++) - { - auto mat = tex->GetMaterial(i); - if (mat != nullptr) mat->SetSpriteRect(); - } - } - - } -} diff --git a/src/common/textures/hw_material.h b/src/common/textures/hw_material.h index 11cbc58b4c..a280ac6fb1 100644 --- a/src/common/textures/hw_material.h +++ b/src/common/textures/hw_material.h @@ -40,13 +40,6 @@ class FMaterial short mRenderWidth; short mRenderHeight; bool mExpanded; - bool mTrimResult; - uint16_t trim[4]; - - float mSpriteU[2], mSpriteV[2]; - FloatRect mSpriteRect; - - bool TrimBorders(uint16_t *rect); public: FTexture *sourcetex; // the owning texture. @@ -108,17 +101,10 @@ public: // Patch drawing utilities - void GetSpriteRect(FloatRect * r) const - { - *r = mSpriteRect; - } - // This is scaled size in integer units as needed by walls and flats int TextureHeight() const { return mRenderHeight; } int TextureWidth() const { return mRenderWidth; } - int GetAreas(FloatRect **pAreas) const; - int GetWidth() const { return mWidth; @@ -147,12 +133,6 @@ public: float GetU(float upix) const { return upix/(float)mWidth; } float GetV(float vpix) const { return vpix/(float)mHeight; } - float GetSpriteUL() const { return mSpriteU[0]; } - float GetSpriteVT() const { return mSpriteV[0]; } - float GetSpriteUR() const { return mSpriteU[1]; } - float GetSpriteVB() const { return mSpriteV[1]; } - - static FMaterial *ValidateTexture(FTexture * tex, bool expand, bool create = true); static FMaterial *ValidateTexture(FTextureID no, bool expand, bool trans, bool create = true); const TArray &GetLayerArray() const diff --git a/src/common/textures/texture.cpp b/src/common/textures/texture.cpp index 57ee44c57e..bd97b23505 100644 --- a/src/common/textures/texture.cpp +++ b/src/common/textures/texture.cpp @@ -47,6 +47,7 @@ #include "image.h" #include "formats/multipatchtexture.h" #include "texturemanager.h" +#include "c_cvars.h" // Wrappers to keep the definitions of these classes out of here. void DeleteMaterial(FMaterial* mat); @@ -125,7 +126,6 @@ FTexture::FTexture (const char *name, int lumpnum) bDisableFullbright = false; bSkybox = false; bNoCompress = false; - bNoExpand = false; bTranslucent = -1; @@ -461,6 +461,25 @@ void FTexture::GetGlowColor(float *data) data[2] = GlowColor.b / 255.0f; } +//=========================================================================== +// +// +// +//=========================================================================== + +int FTexture::GetAreas(FloatRect** pAreas) const +{ + if (shaderindex == SHADER_Default) // texture splitting can only be done if there's no attached effects + { + *pAreas = areas; + return areacount; + } + else + { + return 0; + } +} + //=========================================================================== // // Finds gaps in the texture which can be skipped by the renderer @@ -776,6 +795,197 @@ TArray FTexture::Get8BitPixels(bool alphatex) return Pixels; } +//=========================================================================== +// +// Sets up the sprite positioning data for this texture +// +//=========================================================================== + +void FTexture::SetupSpriteData() +{ + spi.mSpriteU[0] = spi.mSpriteV[0] = 0.f; + spi.mSpriteU[1] = spi.mSpriteV[1] = 1.f; + spi.spriteWidth = GetTexelWidth(); + spi.spriteHeight = GetTexelHeight(); + + if (ShouldExpandSprite()) + { + if (mTrimResult == -1) mTrimResult = !!TrimBorders(spi.trim); // get the trim size before adding the empty frame + spi.spriteWidth += 2; + spi.spriteHeight += 2; + } + else mTrimResult = 0; + SetSpriteRect(); +} + +//=========================================================================== +// +// Checks if a sprite may be expanded with an empty frame +// +//=========================================================================== + +bool FTexture::ShouldExpandSprite() +{ + if (bExpandSprite != -1) return bExpandSprite; + if (isWarped() || isHardwareCanvas() || shaderindex != SHADER_Default) + { + bExpandSprite = false; + return false; + } + if (Brightmap != NULL && (GetTexelWidth() != Brightmap->GetTexelWidth() || GetTexelHeight() != Brightmap->GetTexelHeight())) + { + // do not expand if the brightmap's size differs. + bExpandSprite = false; + return false; + } + bExpandSprite = true; + return true; +} + +//=========================================================================== +// +// Finds empty space around the texture. +// Used for sprites that got placed into a huge empty frame. +// +//=========================================================================== + +bool FTexture::TrimBorders(uint16_t* rect) +{ + + auto texbuffer = CreateTexBuffer(0); + int w = texbuffer.mWidth; + int h = texbuffer.mHeight; + auto Buffer = texbuffer.mBuffer; + + if (texbuffer.mBuffer == nullptr) + { + return false; + } + if (w != Width || h != Height) + { + // external Hires replacements cannot be trimmed. + return false; + } + + int size = w * h; + if (size == 1) + { + // nothing to be done here. + rect[0] = 0; + rect[1] = 0; + rect[2] = 1; + rect[3] = 1; + return true; + } + int first, last; + + for (first = 0; first < size; first++) + { + if (Buffer[first * 4 + 3] != 0) break; + } + if (first >= size) + { + // completely empty + rect[0] = 0; + rect[1] = 0; + rect[2] = 1; + rect[3] = 1; + return true; + } + + for (last = size - 1; last >= first; last--) + { + if (Buffer[last * 4 + 3] != 0) break; + } + + rect[1] = first / w; + rect[3] = 1 + last / w - rect[1]; + + rect[0] = 0; + rect[2] = w; + + unsigned char* bufferoff = Buffer + (rect[1] * w * 4); + h = rect[3]; + + for (int x = 0; x < w; x++) + { + for (int y = 0; y < h; y++) + { + if (bufferoff[(x + y * w) * 4 + 3] != 0) goto outl; + } + rect[0]++; + } +outl: + rect[2] -= rect[0]; + + for (int x = w - 1; rect[2] > 1; x--) + { + for (int y = 0; y < h; y++) + { + if (bufferoff[(x + y * w) * 4 + 3] != 0) + { + return true; + } + } + rect[2]--; + } + return true; +} + +//=========================================================================== +// +// Set the sprite rectangle +// +//=========================================================================== + +void FTexture::SetSpriteRect() +{ + auto leftOffset = GetLeftOffsetHW(); + auto topOffset = GetTopOffsetHW(); + + float fxScale = (float)Scale.X; + float fyScale = (float)Scale.Y; + + // mSpriteRect is for positioning the sprite in the scene. + spi.mSpriteRect.left = -leftOffset / fxScale; + spi.mSpriteRect.top = -topOffset / fyScale; + spi.mSpriteRect.width = spi.spriteWidth / fxScale; + spi.mSpriteRect.height = spi.spriteHeight / fyScale; + + if (bExpandSprite) + { + // a little adjustment to make sprites look better with texture filtering: + // create a 1 pixel wide empty frame around them. + + int oldwidth = spi.spriteWidth - 2; + int oldheight = spi.spriteHeight - 2; + + leftOffset += 1; + topOffset += 1; + + // Reposition the sprite with the frame considered + spi.mSpriteRect.left = -leftOffset / fxScale; + spi.mSpriteRect.top = -topOffset / fyScale; + spi.mSpriteRect.width = spi.spriteWidth / fxScale; + spi.mSpriteRect.height = spi.spriteHeight / fyScale; + + if (mTrimResult > 0) + { + spi.mSpriteRect.left += spi.trim[0] / fxScale; + spi.mSpriteRect.top += spi.trim[1] / fyScale; + + spi.mSpriteRect.width -= (oldwidth - spi.trim[2]) / fxScale; + spi.mSpriteRect.height -= (oldheight - spi.trim[3]) / fyScale; + + spi.mSpriteU[0] = spi.trim[0] / spi.spriteWidth; + spi.mSpriteV[0] = spi.trim[1] / spi.spriteHeight; + spi.mSpriteU[1] -= (oldwidth - spi.trim[0] - spi.trim[2]) / spi.spriteWidth; + spi.mSpriteV[1] -= (oldheight - spi.trim[1] - spi.trim[3]) / spi.spriteHeight; + } + } +} + + //=========================================================================== // // Coordinate helper. @@ -904,3 +1114,23 @@ bool FGameTexture::isUserContent() const return (filenum > fileSystem.GetMaxIwadNum()); } + +//----------------------------------------------------------------------------- +// +// Make sprite offset adjustment user-configurable per renderer. +// +//----------------------------------------------------------------------------- + +CUSTOM_CVAR(Int, r_spriteadjust, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + r_spriteadjustHW = !!(self & 2); + r_spriteadjustSW = !!(self & 1); + for (int i = 0; i < TexMan.NumTextures(); i++) + { + auto tex = TexMan.GetGameTexture(FSetTextureID(i)); + if (tex->GetTexelLeftOffset(0) != tex->GetTexelLeftOffset(1) || tex->GetTexelTopOffset(0) != tex->GetTexelTopOffset(1)) + { + tex->SetSpriteRect(); + } + } +} diff --git a/src/common/textures/textures.h b/src/common/textures/textures.h index efa45ec753..487d041d01 100644 --- a/src/common/textures/textures.h +++ b/src/common/textures/textures.h @@ -222,6 +222,25 @@ struct FTextureBuffer }; +struct SpritePositioningInfo +{ + uint16_t trim[4]; + int spriteWidth, spriteHeight; + float mSpriteU[2], mSpriteV[2]; + FloatRect mSpriteRect; + + float GetSpriteUL() const { return mSpriteU[0]; } + float GetSpriteVT() const { return mSpriteV[0]; } + float GetSpriteUR() const { return mSpriteU[1]; } + float GetSpriteVB() const { return mSpriteV[1]; } + + const FloatRect &GetSpriteRect() const + { + return mSpriteRect; + } + +}; + // Base texture class class FTexture { @@ -249,6 +268,10 @@ class FTexture public: + + SpritePositioningInfo spi; + int8_t mTrimResult = -1; + static FTexture *CreateTexture(const char *name, int lumpnum, ETextureType usetype); virtual ~FTexture (); virtual FImageSource *GetImage() const { return nullptr; } @@ -331,6 +354,11 @@ public: Height = h; } + bool TrimBorders(uint16_t* rect); + void SetSpriteRect(); + bool ShouldExpandSprite(); + void SetupSpriteData(); + int GetAreas(FloatRect** pAreas) const; // Returns the whole texture, stored in column-major order virtual TArray Get8BitPixels(bool alphatex); @@ -409,8 +437,8 @@ protected: protected: uint8_t bSkybox : 1; // is a cubic skybox uint8_t bNoCompress : 1; - uint8_t bNoExpand : 1; int8_t bTranslucent : 2; + int8_t bExpandSprite = -1; bool bHiresHasColorKey = false; // Support for old color-keyed Doomsday textures uint16_t Rotations; @@ -507,7 +535,7 @@ public: bMasked = false; bHasCanvas = true; bTranslucent = false; - bNoExpand = true; + bExpandSprite = false; UseType = ETextureType::Wall; } @@ -680,6 +708,9 @@ public: bool isSkybox() const { return wrapped.isSkybox(); } void SetSize(int x, int y) { wrapped.SetSize(x, y); } + void SetSpriteRect() { wrapped.SetSpriteRect(); } + const SpritePositioningInfo& GetSpritePositioning() { if (wrapped.mTrimResult == -1) wrapped.SetupSpriteData(); return wrapped.spi; } + }; diff --git a/src/rendering/hwrenderer/scene/hw_sprites.cpp b/src/rendering/hwrenderer/scene/hw_sprites.cpp index 4d6a2bc1ec..035b031f69 100644 --- a/src/rendering/hwrenderer/scene/hw_sprites.cpp +++ b/src/rendering/hwrenderer/scene/hw_sprites.cpp @@ -755,8 +755,6 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t else Angles = thing->Angles; - FloatRect r; - if (sector->sectornum != thing->Sector->sectornum && !thruportal) { // This cannot create a copy in the fake sector cache because it'd interfere with the main thread, so provide a local buffer for the copy. @@ -818,15 +816,15 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t if (!patch.isValid()) return; int type = thing->renderflags & RF_SPRITETYPEMASK; - gltexture = FMaterial::ValidateTexture(patch, (type == RF_FACESPRITE), false); - if (!gltexture) - return; + auto tex = TexMan.GetGameTexture(patch, false); + if (!tex || !tex->isValid()) return; + auto& spi = tex->GetSpritePositioning(); - vt = gltexture->GetSpriteVT(); - vb = gltexture->GetSpriteVB(); + vt = spi.GetSpriteVT(); + vb = spi.GetSpriteVB(); if (thing->renderflags & RF_YFLIP) std::swap(vt, vb); - gltexture->GetSpriteRect(&r); + auto r = spi.GetSpriteRect(); // [SP] SpriteFlip if (thing->renderflags & RF_SPRITEFLIP) @@ -835,15 +833,19 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t if (mirror ^ !!(thing->renderflags & RF_XFLIP)) { r.left = -r.width - r.left; // mirror the sprite's x-offset - ul = gltexture->GetSpriteUL(); - ur = gltexture->GetSpriteUR(); + ul = spi.GetSpriteUL(); + ur = spi.GetSpriteUR(); } else { - ul = gltexture->GetSpriteUR(); - ur = gltexture->GetSpriteUL(); + ul = spi.GetSpriteUR(); + ur = spi.GetSpriteUL(); } + gltexture = FMaterial::ValidateTexture(patch, (type == RF_FACESPRITE), false); + if (!gltexture) + return; + if (thing->renderflags & RF_SPRITEFLIP) // [SP] Flip back thing->renderflags ^= RF_XFLIP; @@ -1182,15 +1184,14 @@ void HWSprite::ProcessParticle (HWDrawInfo *di, particle_t *particle, sector_t * if (lump.isValid()) { - gltexture = FMaterial::ValidateTexture(lump, true, false); translation = 0; + //auto tex = TexMan.GetGameTexture(lump, false); - ul = gltexture->GetUL(); - ur = gltexture->GetUR(); - vt = gltexture->GetVT(); - vb = gltexture->GetVB(); - FloatRect r; - gltexture->GetSpriteRect(&r); + ul = 0; + ur = 1; + vt = 0; + vb = 1; + gltexture = FMaterial::ValidateTexture(lump, true, false); } } diff --git a/src/rendering/hwrenderer/scene/hw_walls.cpp b/src/rendering/hwrenderer/scene/hw_walls.cpp index 9b0a5f1779..cab8ca6ef7 100644 --- a/src/rendering/hwrenderer/scene/hw_walls.cpp +++ b/src/rendering/hwrenderer/scene/hw_walls.cpp @@ -1431,7 +1431,7 @@ void HWWall::DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary, // // FloatRect *splitrect; - int v = gltexture->GetAreas(&splitrect); + int v = gltexture->sourcetex->GetAreas(&splitrect); if (seg->frontsector == seg->backsector) flags |= HWF_NOSPLIT; // we don't need to do vertex splits if a line has both sides in the same sector if (v>0 && !drawfogboundary && !(seg->linedef->flags&ML_WRAP_MIDTEX)) { diff --git a/src/rendering/hwrenderer/scene/hw_weapon.cpp b/src/rendering/hwrenderer/scene/hw_weapon.cpp index d8cabda51b..6cd2313764 100644 --- a/src/rendering/hwrenderer/scene/hw_weapon.cpp +++ b/src/rendering/hwrenderer/scene/hw_weapon.cpp @@ -417,14 +417,14 @@ bool HUDSprite::GetWeaponRect(HWDrawInfo *di, DPSprite *psp, float sx, float sy, FTextureID lump = sprites[psp->GetSprite()].GetSpriteFrame(psp->GetFrame(), 0, 0., &mirror); if (!lump.isValid()) return false; - FMaterial * tex = FMaterial::ValidateTexture(lump, true, false); - if (!tex) return false; + auto tex = TexMan.GetGameTexture(lump, false); + if (!tex || !tex->isValid()) return false; + auto& spi = tex->GetSpritePositioning(); float vw = (float)viewwidth; float vh = (float)viewheight; - FloatRect r; - tex->GetSpriteRect(&r); + FloatRect r = spi.GetSpriteRect(); // calculate edges of the shape scalex = (320.0f / (240.0f * r_viewwindow.WidescreenRatio)) * vw / 320; @@ -452,17 +452,17 @@ bool HUDSprite::GetWeaponRect(HWDrawInfo *di, DPSprite *psp, float sx, float sy, if (!(mirror) != !(psp->Flags & (PSPF_FLIP))) { - u2 = tex->GetSpriteUL(); - v1 = tex->GetSpriteVT(); - u1 = tex->GetSpriteUR(); - v2 = tex->GetSpriteVB(); + u2 = spi.GetSpriteUL(); + v1 = spi.GetSpriteVT(); + u1 = spi.GetSpriteUR(); + v2 = spi.GetSpriteVB(); } else { - u1 = tex->GetSpriteUL(); - v1 = tex->GetSpriteVT(); - u2 = tex->GetSpriteUR(); - v2 = tex->GetSpriteVB(); + u1 = spi.GetSpriteUL(); + v1 = spi.GetSpriteVT(); + u2 = spi.GetSpriteUR(); + v2 = spi.GetSpriteVB(); } auto verts = screen->mVertexData->AllocVertices(4); @@ -473,7 +473,10 @@ bool HUDSprite::GetWeaponRect(HWDrawInfo *di, DPSprite *psp, float sx, float sy, verts.first[2].Set(x2, y1, 0, u2, v1); verts.first[3].Set(x2, y2, 0, u2, v2); - this->tex = tex; + FMaterial* mat = FMaterial::ValidateTexture(lump, true, false); + if (!mat) return false; + + this->tex = mat; return true; }