Skip to content

Commit

Permalink
- did a bit of optimization on FGameTexture.
Browse files Browse the repository at this point in the history
Since all material layers except the brightmaps are relatively rare encounters these were taken out of the main texture object and offloaded to a substructure that is only allocated on demand.
  • Loading branch information
coelckers authored and mjr4077au committed Nov 26, 2022
1 parent 67c4a07 commit b0bac90
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 46 deletions.
41 changes: 35 additions & 6 deletions source/common/textures/gametexture.cpp
Expand Up @@ -140,16 +140,27 @@ void FGameTexture::AddAutoMaterials()
const char* path;
RefCountedPtr<FTexture> FGameTexture::* pointer;
};
struct AutoTextureSearchPath2
{
const char* path;
RefCountedPtr<FTexture> FMaterialLayers::* pointer;
};

static AutoTextureSearchPath autosearchpaths[] =
{
{ "brightmaps/", &FGameTexture::Brightmap }, // For backwards compatibility, only for short names
{ "materials/brightmaps/", &FGameTexture::Brightmap },
{ "materials/normalmaps/", &FGameTexture::Normal },
{ "materials/specular/", &FGameTexture::Specular },
{ "materials/metallic/", &FGameTexture::Metallic },
{ "materials/roughness/", &FGameTexture::Roughness },
{ "materials/ao/", &FGameTexture::AmbientOcclusion }
};

static AutoTextureSearchPath2 autosearchpaths2[] =
{
{ "materials/detailmaps/", &FMaterialLayers::Detailmap },
{ "materials/glowmaps/", &FMaterialLayers::Glowmap },
{ "materials/normalmaps/", &FMaterialLayers::Normal },
{ "materials/specular/", &FMaterialLayers::Specular },
{ "materials/metallic/", &FMaterialLayers::Metallic },
{ "materials/roughness/", &FMaterialLayers::Roughness },
{ "materials/ao/", &FMaterialLayers::AmbientOcclusion }
};

if (flags & GTexf_AutoMaterialsAdded) return; // do this only once
Expand Down Expand Up @@ -181,6 +192,24 @@ void FGameTexture::AddAutoMaterials()
}
}
}
for (size_t i = 0; i < countof(autosearchpaths2); i++)
{
auto& layer = autosearchpaths2[i];
if (!this->Layers || this->Layers.get()->*(layer.pointer) == nullptr) // only if no explicit assignment had been done.
{
FStringf lookup("%s%s%s", layer.path, fullname ? "" : "auto/", searchname.GetChars());
auto lump = fileSystem.CheckNumForFullName(lookup, false, ns_global, true);
if (lump != -1)
{
auto bmtex = TexMan.FindGameTexture(fileSystem.GetFileFullName(lump), ETextureType::Any, FTextureManager::TEXMAN_TryAny);
if (bmtex != nullptr)
{
if (this->Layers == nullptr) this->Layers = std::make_unique<FMaterialLayers>();
this->Layers.get()->* (layer.pointer) = bmtex->GetTexture();
}
}
}
}
flags |= GTexf_AutoMaterialsAdded;
}

Expand Down Expand Up @@ -283,7 +312,7 @@ bool FGameTexture::ShouldExpandSprite()
expandSprite = false;
return false;
}
if (Glowmap != NULL && (Base->GetWidth() != Glowmap->GetWidth() || Base->GetHeight() != Glowmap->GetHeight()))
if (Layers && Layers->Glowmap != NULL && (Base->GetWidth() != Layers->Glowmap->GetWidth() || Base->GetHeight() != Layers->Glowmap->GetHeight()))
{
// same restriction for the glow map
expandSprite = false;
Expand Down
78 changes: 54 additions & 24 deletions source/common/textures/gametexture.h
@@ -1,5 +1,6 @@
#pragma once
#include <stdint.h>
#include <memory>
#include "vectors.h"
#include "floatrect.h"
#include "refcounted.h"
Expand Down Expand Up @@ -62,15 +63,8 @@ enum EGameTexFlags
GTexf_NoTrim = 1024, // Don't perform trimming on this texture.
};

// Refactoring helper to allow piece by piece adjustment of the API
class FGameTexture
struct FMaterialLayers
{
friend class FMaterial;
friend class GLDefsParser; // this needs access to set up the texture properly

// Material layers. These are shared so reference counting is used.
RefCountedPtr<FTexture> Base;
RefCountedPtr<FTexture> Brightmap;
RefCountedPtr<FTexture> Detailmap;
RefCountedPtr<FTexture> Glowmap;
RefCountedPtr<FTexture> Normal; // Normal map texture
Expand All @@ -79,6 +73,18 @@ class FGameTexture
RefCountedPtr<FTexture> Roughness; // Roughness texture for PBR
RefCountedPtr<FTexture> AmbientOcclusion; // Ambient occlusion texture for PBR
RefCountedPtr<FTexture> CustomShaderTextures[MAX_CUSTOM_HW_SHADER_TEXTURES]; // Custom texture maps for custom hardware shaders
};

// Refactoring helper to allow piece by piece adjustment of the API
class FGameTexture
{
friend class FMaterial;
friend class GLDefsParser; // this needs access to set up the texture properly

// Material layers. These are shared so reference counting is used.
RefCountedPtr<FTexture> Base;
RefCountedPtr<FTexture> Brightmap;
std::unique_ptr<FMaterialLayers> Layers;

FString Name;
FTextureID id;
Expand Down Expand Up @@ -204,14 +210,25 @@ class FGameTexture
if (lay.Glossiness > -1000) Glossiness = lay.Glossiness;
if (lay.SpecularLevel > -1000) SpecularLevel = lay.SpecularLevel;
if (lay.Brightmap) Brightmap = lay.Brightmap->GetTexture();
if (lay.Normal) Normal = lay.Normal->GetTexture();
if (lay.Specular) Specular = lay.Specular->GetTexture();
if (lay.Metallic) Metallic = lay.Metallic->GetTexture();
if (lay.Roughness) Roughness = lay.Roughness->GetTexture();
if (lay.AmbientOcclusion) AmbientOcclusion = lay.AmbientOcclusion->GetTexture();
for (int i = 0; i < MAX_CUSTOM_HW_SHADER_TEXTURES; i++)

bool needlayers = (lay.Normal || lay.Specular || lay.Metallic || lay.Roughness || lay.AmbientOcclusion);
for (int i = 0; i < MAX_CUSTOM_HW_SHADER_TEXTURES && !needlayers; i++)
{
if (lay.CustomShaderTextures[i]) needlayers = true;
}
if (needlayers)
{
if (lay.CustomShaderTextures[i]) CustomShaderTextures[i] = lay.CustomShaderTextures[i]->GetTexture();
Layers = std::make_unique<FMaterialLayers>();

if (lay.Normal) Layers->Normal = lay.Normal->GetTexture();
if (lay.Specular) Layers->Specular = lay.Specular->GetTexture();
if (lay.Metallic) Layers->Metallic = lay.Metallic->GetTexture();
if (lay.Roughness) Layers->Roughness = lay.Roughness->GetTexture();
if (lay.AmbientOcclusion) Layers->AmbientOcclusion = lay.AmbientOcclusion->GetTexture();
for (int i = 0; i < MAX_CUSTOM_HW_SHADER_TEXTURES; i++)
{
if (lay.CustomShaderTextures[i]) Layers->CustomShaderTextures[i] = lay.CustomShaderTextures[i]->GetTexture();
}
}
}
float GetGlossiness() const { return Glossiness; }
Expand Down Expand Up @@ -306,13 +323,20 @@ class FGameTexture
void GetLayers(TArray<FTexture*>& layers)
{
layers.Clear();
for (auto tex : { Base.get(), Brightmap.get(), Detailmap.get(), Glowmap.get(), Normal.get(), Specular.get(), Metallic.get(), Roughness.get(), AmbientOcclusion.get() })
for (auto tex : { Base.get(), Brightmap.get() })
{
if (tex != nullptr) layers.Push(tex);
}
for (auto& tex : CustomShaderTextures)
if (Layers)
{
if (tex != nullptr) layers.Push(tex.get());
for (auto tex : { Layers->Detailmap.get(), Layers->Glowmap.get(), Layers->Normal.get(), Layers->Specular.get(), Layers->Metallic.get(), Layers->Roughness.get(), Layers->AmbientOcclusion.get() })
{
if (tex != nullptr) layers.Push(tex);
}
for (auto& tex : Layers->CustomShaderTextures)
{
if (tex != nullptr) layers.Push(tex.get());
}
}
}

Expand All @@ -335,28 +359,34 @@ class FGameTexture
}
FTexture* GetGlowmap()
{
return Glowmap.get();
if (!Layers) return nullptr;
return Layers->Glowmap.get();
}
FTexture* GetDetailmap()
{
return Detailmap.get();
if (!Layers) return nullptr;
return Layers->Detailmap.get();
}

void SetGlowmap(FTexture *T)
{
Glowmap = T;
if (!Layers) Layers = std::make_unique<FMaterialLayers>();
Layers->Glowmap = T;
}
void SetDetailmap(FTexture* T)
{
Detailmap = T;
if (!Layers) Layers = std::make_unique<FMaterialLayers>();
Layers->Detailmap = T;
}
void SetNormalmap(FTexture* T)
{
Normal = T;
if (!Layers) Layers = std::make_unique<FMaterialLayers>();
Layers->Normal = T;
}
void SetSpecularmap(FTexture* T)
{
Specular = T;
if (!Layers) Layers = std::make_unique<FMaterialLayers>();
Layers->Specular = T;
}

};
Expand Down
20 changes: 10 additions & 10 deletions source/common/textures/hw_material.cpp
Expand Up @@ -79,17 +79,17 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
mShaderIndex = tx->isWarped(); // This picks SHADER_Warp1 or SHADER_Warp2
}
// Note that the material takes no ownership of the texture!
else if (tx->Normal.get() && tx->Specular.get())
else if (tx->Layers && tx->Layers->Normal.get() && tx->Layers->Specular.get())
{
for (auto &texture : { tx->Normal.get(), tx->Specular.get() })
for (auto &texture : { tx->Layers->Normal.get(), tx->Layers->Specular.get() })
{
mTextureLayers.Push({ texture, 0, -1 });
}
mShaderIndex = SHADER_Specular;
}
else if (tx->Normal.get() && tx->Metallic.get() && tx->Roughness.get() && tx->AmbientOcclusion.get())
else if (tx->Layers && tx->Layers->Normal.get() && tx->Layers->Metallic.get() && tx->Layers->Roughness.get() && tx->Layers->AmbientOcclusion.get())
{
for (auto &texture : { tx->Normal.get(), tx->Metallic.get(), tx->Roughness.get(), tx->AmbientOcclusion.get() })
for (auto &texture : { tx->Layers->Normal.get(), tx->Layers->Metallic.get(), tx->Layers->Roughness.get(), tx->Layers->AmbientOcclusion.get() })
{
mTextureLayers.Push({ texture, 0, -1 });
}
Expand All @@ -108,18 +108,18 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
{
mTextureLayers.Push({ placeholder->GetTexture(), 0, -1 });
}
if (tx->Detailmap.get())
if (tx->Layers && tx->Layers->Detailmap.get())
{
mTextureLayers.Push({ tx->Detailmap.get(), 0, CLAMP_NONE });
mTextureLayers.Push({ tx->Layers->Detailmap.get(), 0, CLAMP_NONE });
mLayerFlags |= TEXF_Detailmap;
}
else
{
mTextureLayers.Push({ placeholder->GetTexture(), 0, -1 });
}
if (tx->Glowmap.get())
if (tx->Layers && tx->Layers->Glowmap.get())
{
mTextureLayers.Push({ tx->Glowmap.get(), scaleflags, -1 });
mTextureLayers.Push({ tx->Layers->Glowmap.get(), scaleflags, -1 });
mLayerFlags |= TEXF_Glowmap;
}
else
Expand All @@ -133,9 +133,9 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
if (index >= FIRST_USER_SHADER)
{
const UserShaderDesc& usershader = usershaders[index - FIRST_USER_SHADER];
if (usershader.shaderType == mShaderIndex) // Only apply user shader if it matches the expected material
if (tx->Layers && usershader.shaderType == mShaderIndex) // Only apply user shader if it matches the expected material
{
for (auto& texture : tx->CustomShaderTextures)
for (auto& texture : tx->Layers->CustomShaderTextures)
{
if (texture == nullptr) continue;
mTextureLayers.Push({ texture.get(), 0 }); // scalability should be user-definable.
Expand Down
4 changes: 2 additions & 2 deletions source/common/textures/texturemanager.cpp
Expand Up @@ -426,7 +426,7 @@ FTextureID FTextureManager::AddGameTexture (FGameTexture *texture, bool addtohas
hash = -1;
}

TextureHash hasher = { texture, -1, -1, -1, hash };
TextureDescriptor hasher = { texture, -1, -1, -1, hash };
int trans = Textures.Push (hasher);
Translation.Push (trans);
if (bucket >= 0) HashFirst[bucket] = trans;
Expand Down Expand Up @@ -1150,7 +1150,7 @@ void FTextureManager::AddLocalizedVariants()
uint32_t langid = MAKE_ID(lang[0], lang[1], lang[2], 0);
uint64_t comboid = (uint64_t(langid) << 32) | origTex.GetIndex();
LocalizedTextures.Insert(comboid, tex.GetIndex());
Textures[origTex.GetIndex()].HasLocalization = true;
Textures[origTex.GetIndex()].Flags |= TEXFLAG_HASLOCALIZATION;
}
else
{
Expand Down
13 changes: 9 additions & 4 deletions source/common/textures/texturemanager.h
Expand Up @@ -29,7 +29,7 @@ class FTextureManager
{
if ((unsigned)texnum >= Textures.Size()) return -1;
if (animate) texnum = Translation[texnum];
if (localize && Textures[texnum].HasLocalization) texnum = ResolveLocalizedTexture(texnum);
if (localize && Textures[texnum].Flags & TEXFLAG_HASLOCALIZATION) texnum = ResolveLocalizedTexture(texnum);
return texnum;
}

Expand Down Expand Up @@ -183,17 +183,22 @@ class FTextureManager

// Switches

struct TextureHash
struct TextureDescriptor
{
FGameTexture* Texture;
int Paletted; // redirection to paletted variant
int FrontSkyLayer; // and front sky layer,
int RawTexture;
int HashNext;
bool HasLocalization;
uint64_t Flags;
};
enum : uint64_t
{
TEXFLAG_HASLOCALIZATION = 1,
TEXFLAG_FIRSTUSER = 65536, // this leaves 16 flags to the texture manager and 48 flags to the user
};
enum { HASH_END = -1, HASH_SIZE = 1027 };
TArray<TextureHash> Textures;
TArray<TextureDescriptor> Textures;
TMap<uint64_t, int> LocalizedTextures;
int HashFirst[HASH_SIZE];
FTextureID DefaultTexture;
Expand Down

0 comments on commit b0bac90

Please sign in to comment.