diff --git a/src/common/fonts/font.cpp b/src/common/fonts/font.cpp index f690c94e40..16cbd07d7d 100644 --- a/src/common/fonts/font.cpp +++ b/src/common/fonts/font.cpp @@ -411,13 +411,11 @@ void FFont::ReadSheetFont(TArray &folderdata, int width, int height part[0].Image = tex->GetTexture()->GetImage(); FMultiPatchTexture *image = new FMultiPatchTexture(width, height, part, false, false); FImageTexture *tex = new FImageTexture(image); - tex->bMultiPatch = true; + auto gtex = MakeGameTexture(tex, nullptr, ETextureType::FontChar); tex->bMasked = true; tex->bTranslucent = -1; - tex->bWorldPanning = true; - tex->bNoDecals = false; tex->SourceLump = -1; // We do not really care. - auto gtex = MakeGameTexture(tex, nullptr, ETextureType::FontChar); + gtex->SetWorldPanning(true); gtex->SetOffsets(0, 0, 0); gtex->SetOffsets(1, 0, 0); gtex->SetScale((float)Scale.X, (float)Scale.Y); diff --git a/src/common/textures/formats/multipatchtexture.h b/src/common/textures/formats/multipatchtexture.h index 657576c7c3..63899808eb 100644 --- a/src/common/textures/formats/multipatchtexture.h +++ b/src/common/textures/formats/multipatchtexture.h @@ -140,6 +140,7 @@ class FMultipatchTextureBuilder { FTextureManager &TexMan; TArray BuiltTextures; + TMap complex; void(*progressFunc)(); void(*checkForHacks)(BuildInfo&); diff --git a/src/common/textures/multipatchtexturebuilder.cpp b/src/common/textures/multipatchtexturebuilder.cpp index ea55239d73..c4d8151a67 100644 --- a/src/common/textures/multipatchtexturebuilder.cpp +++ b/src/common/textures/multipatchtexturebuilder.cpp @@ -138,11 +138,9 @@ struct FPatchLookup void FMultipatchTextureBuilder::MakeTexture(BuildInfo &buildinfo, ETextureType usetype) { FImageTexture *tex = new FImageTexture(nullptr); - tex->bMultiPatch = true; tex->SetSize(buildinfo.Width, buildinfo.Height); tex->bMasked = true; // we do not really know yet. tex->bTranslucent = -1; - tex->bNoDecals = buildinfo.bNoDecals; tex->SourceLump = buildinfo.DefinitionLump; buildinfo.itex = tex; buildinfo.texture = MakeGameTexture(tex, buildinfo.Name, usetype); @@ -150,6 +148,7 @@ void FMultipatchTextureBuilder::MakeTexture(BuildInfo &buildinfo, ETextureType u buildinfo.texture->SetOffsets(1, buildinfo.LeftOffset[1], buildinfo.TopOffset[1]); buildinfo.texture->SetScale((float)buildinfo.Scale.X, (float)buildinfo.Scale.X); buildinfo.texture->SetWorldPanning(buildinfo.bWorldPanning); + buildinfo.texture->SetNoDecals(buildinfo.bNoDecals); TexMan.AddGameTexture(buildinfo.texture); } @@ -778,9 +777,13 @@ void FMultipatchTextureBuilder::ResolvePatches(BuildInfo &buildinfo) TexMan.ListTextures(buildinfo.Inits[i].TexName, list, true); for (int i = list.Size() - 1; i >= 0; i--) { - if (list[i] != buildinfo.texture->GetID() && !TexMan.GetGameTexture(list[i])->isMultiPatch() ) + if (list[i] != buildinfo.texture->GetID()) { - texno = list[i]; + auto gtex = TexMan.GetGameTexture(list[i]); + if (gtex && !dynamic_cast(gtex->GetTexture())) + { + texno = list[i]; + } break; } } @@ -813,8 +816,9 @@ void FMultipatchTextureBuilder::ResolvePatches(BuildInfo &buildinfo) { //We cannot set the image source yet. First all textures need to be resolved. buildinfo.Inits[i].Texture = tex->GetTexture(); - buildinfo.itex->bComplex |= tex->GetTexture()->bComplex; // this one's NOT a material property! It must remain on the texture image. - buildinfo.bComplex |= tex->GetTexture()->bComplex; + bool iscomplex = !!complex.CheckKey(tex->GetTexture()); + if (iscomplex) complex.Insert(buildinfo.itex, true); + buildinfo.bComplex |= iscomplex; if (buildinfo.Inits[i].UseOffsets) { buildinfo.Parts[i].OriginX -= tex->GetTexelLeftOffset(0); diff --git a/src/common/textures/texture.cpp b/src/common/textures/texture.cpp index e2dc6ee834..fbbc251330 100644 --- a/src/common/textures/texture.cpp +++ b/src/common/textures/texture.cpp @@ -91,15 +91,10 @@ FTexture * FTexture::CreateTexture(int lumpnum, bool allowflats) FTexture::FTexture (int lumpnum) : SourceLump(lumpnum), - bNoDecals(false), bNoRemap0(false), bWorldPanning(false), - bMasked(true), bAlphaTexture(false), bHasCanvas(false), bWarped(0), bComplex(false), bMultiPatch(false), bFullNameTexture(false), + bNoRemap0(false), bMasked(true), bAlphaTexture(false), bHasCanvas(false), Rotations(0xFFFF), SkyOffset(0), Width(0), Height(0) { bBrightmapChecked = false; - bGlowing = false; - bAutoGlowing = false; - bFullbright = false; - bDisableFullbright = false; bSkybox = false; bNoCompress = false; bTranslucent = -1; @@ -177,10 +172,10 @@ void FGameTexture::AddAutoMaterials() }; - int startindex = Base->bFullNameTexture ? 1 : 0; + bool fullname = !!(flags & GTexf_FullNameTexture); FString searchname = GetName(); - if (Base->bFullNameTexture) + if (fullname) { auto dot = searchname.LastIndexOf('.'); auto slash = searchname.LastIndexOf('/'); @@ -192,7 +187,7 @@ void FGameTexture::AddAutoMaterials() auto &layer = autosearchpaths[i]; if (this->*(layer.pointer) == nullptr) // only if no explicit assignment had been done. { - FStringf lookup("%s%s%s", layer.path, Base->bFullNameTexture ? "" : "auto/", searchname.GetChars()); + FStringf lookup("%s%s%s", layer.path, fullname ? "" : "auto/", searchname.GetChars()); auto lump = fileSystem.CheckNumForFullName(lookup, false, ns_global, true); if (lump != -1) { @@ -258,19 +253,19 @@ void FGameTexture::CreateDefaultBrightmap() // //========================================================================== -void FTexture::GetGlowColor(float *data) +void FGameTexture::GetGlowColor(float *data) { - if (bGlowing && GlowColor == 0) + if (isGlowing() && GlowColor == 0) { - auto buffer = GetBgraBitmap(nullptr); + auto buffer = Base->GetBgraBitmap(nullptr); GlowColor = averageColor((uint32_t*)buffer.GetPixels(), buffer.GetWidth() * buffer.GetHeight(), 153); // Black glow equals nothing so switch glowing off - if (GlowColor == 0) bGlowing = false; + if (GlowColor == 0) flags &= ~GTexf_Glowing; } - data[0] = GlowColor.r / 255.0f; - data[1] = GlowColor.g / 255.0f; - data[2] = GlowColor.b / 255.0f; + data[0] = GlowColor.r * (1/255.0f); + data[1] = GlowColor.g * (1/255.0f); + data[2] = GlowColor.b * (1/255.0f); } //=========================================================================== @@ -614,19 +609,26 @@ TArray FTexture::Get8BitPixels(bool alphatex) bool FGameTexture::ShouldExpandSprite() { - if (Base->bExpandSprite != -1) return Base->bExpandSprite; - if (isWarped() || isHardwareCanvas() || GetShaderIndex() != SHADER_Default) + if (expandSprite != -1) return expandSprite; + // Only applicable to image textures with no shader effect. + if (GetShaderIndex() != SHADER_Default || !dynamic_cast(Base.get())) { - Base->bExpandSprite = false; + expandSprite = false; return false; } if (Brightmap != NULL && (Base->GetWidth() != Brightmap->GetWidth() || Base->GetHeight() != Brightmap->GetHeight())) { - // do not expand if the brightmap's size differs. - Base->bExpandSprite = false; + // do not expand if the brightmap's physical size differs from the base. + expandSprite = false; return false; } - Base->bExpandSprite = true; + if (Glowmap != NULL && (Base->GetWidth() != Glowmap->GetWidth() || Base->GetHeight() != Glowmap->GetHeight())) + { + // same restriction for the glow map + expandSprite = false; + return false; + } + expandSprite = true; return true; } diff --git a/src/common/textures/textures.h b/src/common/textures/textures.h index d73fdf28c3..62f70f8523 100644 --- a/src/common/textures/textures.h +++ b/src/common/textures/textures.h @@ -251,38 +251,22 @@ protected: int SourceLump; FHardwareTextureContainer SystemTextures; - uint8_t bNoDecals : 1; // Decals should not stick to texture uint8_t bNoRemap0 : 1; // Do not remap color 0 (used by front layer of parallax skies) - uint8_t bWorldPanning : 1; // Texture is panned in world units rather than texels + uint8_t bNoCompress : 1; + uint8_t bMasked : 1; // Texture (might) have holes uint8_t bAlphaTexture : 1; // Texture is an alpha channel without color information uint8_t bHasCanvas : 1; // Texture is based off FCanvasTexture - uint8_t bWarped : 2; // This is a warped texture. Used to avoid multiple warps on one texture - uint8_t bComplex : 1; // Will be used to mark extended MultipatchTextures that have to be - // fully composited before subjected to any kind of postprocessing instead of - // doing it per patch. - uint8_t bMultiPatch : 2; // This is a multipatch texture (we really could use real type info for textures...) - uint8_t bFullNameTexture : 1; uint8_t bBrightmapChecked : 1; // Set to 1 if brightmap has been checked - uint8_t bGlowing : 1; // Texture glow color - uint8_t bAutoGlowing : 1; // Glow info is determined from texture image. - uint8_t bFullbright : 1; // always draw fullbright - uint8_t bDisableFullbright : 1; // This texture will not be displayed as fullbright sprite - uint8_t bSkybox : 1; // is a cubic skybox - uint8_t bNoCompress : 1; int8_t bTranslucent : 2; - int8_t bExpandSprite = -1; uint16_t Rotations; int16_t SkyOffset; FloatRect* areas = nullptr; int areacount = 0; - int GlowHeight = 128; - PalEntry GlowColor = 0; - public: IHardwareTexture* GetHardwareTexture(int translation, int scaleflags); @@ -296,29 +280,17 @@ public: int GetHeight() { return Height; } bool isSkybox() const { return bSkybox; } - bool isFullbrightDisabled() const { return bDisableFullbright; } bool isHardwareCanvas() const { return bHasCanvas; } // There's two here so that this can deal with software canvases in the hardware renderer later. bool isCanvas() const { return bHasCanvas; } - int isWarped() const { return bWarped; } int GetRotations() const { return Rotations; } void SetRotations(int rot) { Rotations = int16_t(rot); } - void SetNoDecals(bool on) { bNoDecals = on; } - void SetWarpStyle(int style) { bWarped = style; } - bool allowNoDecals() const { return bNoDecals; } bool isMasked() const { return bMasked; } void SetSkyOffset(int offs) { SkyOffset = offs; } int GetSkyOffset() const { return SkyOffset; } virtual int GetSourceLump() { return SourceLump; } // needed by the scripted GetName method. - void GetGlowColor(float *data); - bool isGlowing() const { return bGlowing; } - bool isAutoGlowing() const { return bAutoGlowing; } - int GetGlowHeight() const { return GlowHeight; } - bool isFullbright() const { return bFullbright; } bool FindHoles(const unsigned char * buffer, int w, int h); int GetSourceLump() const { return SourceLump; } - bool UseWorldPanning() const { return bWorldPanning; } - void SetWorldPanning(bool on) { bWorldPanning = on; } void CopySize(FTexture* BaseTexture) @@ -380,7 +352,6 @@ public: bMasked = false; bHasCanvas = true; bTranslucent = false; - bExpandSprite = false; aspectRatio = (float)width / height; } @@ -508,6 +479,17 @@ public: } }; +enum EGameTexFlags +{ + GTexf_NoDecals = 1, // Decals should not stick to texture + GTexf_WorldPanning = 2, // Texture is panned in world units rather than texels + GTexf_FullNameTexture = 4, // Name is taken from the file system. + GTexf_Glowing = 8, // Texture emits a glow + GTexf_AutoGlowing = 16, // Glow info is determined from texture image. + GTexf_RenderFullbright = 32, // always draw fullbright + Gtexf_DisableFullbrightSprites = 64, // This texture will not be displayed as fullbright sprite +}; + // Refactoring helper to allow piece by piece adjustment of the API class FGameTexture { @@ -546,6 +528,11 @@ class FGameTexture float shaderspeed = 1.f; int shaderindex = 0; + int flags = 0; + uint8_t warped = 0, expandSprite = -1; + uint16_t GlowHeight; + PalEntry GlowColor = 0; + public: FGameTexture(FTexture* wrap, const char *name); ~FGameTexture(); @@ -580,22 +567,23 @@ public: float GetDisplayLeftOffset(int adjusted = 0) const { return LeftOffset[adjusted] / ScaleX; } float GetDisplayTopOffset(int adjusted = 0) const { return TopOffset[adjusted] / ScaleY; } + bool isMiscPatch() const { return GetUseType() == ETextureType::MiscPatch; } // only used by the intermission screen to decide whether to tile the background image or not. + bool isFullbrightDisabled() const { return !!(flags & Gtexf_DisableFullbrightSprites); } + bool isFullbright() const { return !!(flags & GTexf_RenderFullbright); } + bool isFullNameTexture() const { return !!(flags & GTexf_FullNameTexture); } + bool expandSprites() const { return !!expandSprite; } + bool useWorldPanning() const { return !!(flags & GTexf_WorldPanning); } + void SetWorldPanning(bool on) { if (on) flags |= GTexf_WorldPanning; else flags &= ~GTexf_WorldPanning; } + bool allowNoDecals() const { return !!(flags & GTexf_NoDecals); } + void SetNoDecals(bool on) { if (on) flags |= GTexf_NoDecals; else flags &= ~GTexf_NoDecals; } + bool isValid() const { return UseType != ETextureType::Null; } - int isWarped() { return Base->isWarped(); } - void SetWarpStyle(int style) { Base->bWarped = style; } + int isWarped() { return warped; } + void SetWarpStyle(int style) { warped = style; } bool isMasked() { return Base->isMasked(); } bool isHardwareCanvas() const { return Base->isHardwareCanvas(); } // There's two here so that this can deal with software canvases in the hardware renderer later. bool isSoftwareCanvas() const { return Base->isCanvas(); } - bool isMiscPatch() const { return GetUseType() == ETextureType::MiscPatch; } // only used by the intermission screen to decide whether to tile the background image or not. - bool isMultiPatch() const { return Base->bMultiPatch; } - bool isFullbrightDisabled() const { return Base->isFullbrightDisabled(); } - bool isFullbright() const { return Base->isFullbright(); } - bool isFullNameTexture() const { return Base->bFullNameTexture; } - bool expandSprites() const { return Base->bExpandSprite; } - bool useWorldPanning() const { return Base->UseWorldPanning(); } - void SetWorldPanning(bool on) { Base->SetWorldPanning(on); } - bool allowNoDecals() const { return Base->allowNoDecals(); } - void SetNoDecals(bool on) { Base->bNoDecals = on; } + void SetTranslucent(bool on) { Base->bTranslucent = on; } void SetUseType(ETextureType type) { UseType = type; } uint16_t GetRotations() const { return Base->GetRotations(); } @@ -646,15 +634,15 @@ public: } // Glowing is a pure material property that should not filter down to the actual texture objects. - void GetGlowColor(float* data) { Base->GetGlowColor(data); } - bool isGlowing() const { return Base->isGlowing(); } - bool isAutoGlowing() const { return Base->isAutoGlowing(); } - int GetGlowHeight() const { return Base->GetGlowHeight(); } - void SetAutoGlowing() { auto tex = GetTexture(); tex->bAutoGlowing = tex->bGlowing = tex->bFullbright = true; } - void SetGlowHeight(int v) { Base->GlowHeight = v; } - void SetFullbright() { Base->bFullbright = true; } - void SetDisableFullbright(bool on) { Base->bDisableFullbright = on; } - void SetGlowing(PalEntry color) { auto tex = GetTexture(); tex->bAutoGlowing = false; tex->bGlowing = true; tex->GlowColor = color; } + void GetGlowColor(float* data); + bool isGlowing() const { return !!(flags & GTexf_Glowing); } + bool isAutoGlowing() const { return !!(flags & GTexf_AutoGlowing); } + int GetGlowHeight() const { return GlowHeight; } + void SetAutoGlowing() { flags |= (GTexf_AutoGlowing | GTexf_Glowing | GTexf_RenderFullbright); } + void SetGlowHeight(int v) { GlowHeight = v; } + void SetFullbright() { flags |= GTexf_RenderFullbright; } + void SetDisableFullbright(bool on) { if (on) flags |= Gtexf_DisableFullbrightSprites; else flags &= ~Gtexf_DisableFullbrightSprites; } + void SetGlowing(PalEntry color) { flags = (flags & ~GTexf_AutoGlowing) | GTexf_Glowing; GlowColor = color; } bool isUserContent() const; int CheckRealHeight() { return xs_RoundToInt(Base->CheckRealHeight() / ScaleY); }