mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-15 08:51:24 +00:00
- did a bit of optimization on FGameTexture.
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.
This commit is contained in:
parent
52e5e2f59a
commit
10c552fb66
5 changed files with 110 additions and 46 deletions
|
@ -140,16 +140,27 @@ void FGameTexture::AddAutoMaterials()
|
||||||
const char* path;
|
const char* path;
|
||||||
RefCountedPtr<FTexture> FGameTexture::* pointer;
|
RefCountedPtr<FTexture> FGameTexture::* pointer;
|
||||||
};
|
};
|
||||||
|
struct AutoTextureSearchPath2
|
||||||
|
{
|
||||||
|
const char* path;
|
||||||
|
RefCountedPtr<FTexture> FMaterialLayers::* pointer;
|
||||||
|
};
|
||||||
|
|
||||||
static AutoTextureSearchPath autosearchpaths[] =
|
static AutoTextureSearchPath autosearchpaths[] =
|
||||||
{
|
{
|
||||||
{ "brightmaps/", &FGameTexture::Brightmap }, // For backwards compatibility, only for short names
|
{ "brightmaps/", &FGameTexture::Brightmap }, // For backwards compatibility, only for short names
|
||||||
{ "materials/brightmaps/", &FGameTexture::Brightmap },
|
{ "materials/brightmaps/", &FGameTexture::Brightmap },
|
||||||
{ "materials/normalmaps/", &FGameTexture::Normal },
|
};
|
||||||
{ "materials/specular/", &FGameTexture::Specular },
|
|
||||||
{ "materials/metallic/", &FGameTexture::Metallic },
|
static AutoTextureSearchPath2 autosearchpaths2[] =
|
||||||
{ "materials/roughness/", &FGameTexture::Roughness },
|
{
|
||||||
{ "materials/ao/", &FGameTexture::AmbientOcclusion }
|
{ "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
|
if (flags & GTexf_AutoMaterialsAdded) return; // do this only once
|
||||||
|
@ -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;
|
flags |= GTexf_AutoMaterialsAdded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,7 +312,7 @@ bool FGameTexture::ShouldExpandSprite()
|
||||||
expandSprite = false;
|
expandSprite = false;
|
||||||
return 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
|
// same restriction for the glow map
|
||||||
expandSprite = false;
|
expandSprite = false;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <memory>
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
#include "floatrect.h"
|
#include "floatrect.h"
|
||||||
#include "refcounted.h"
|
#include "refcounted.h"
|
||||||
|
@ -62,6 +63,18 @@ enum EGameTexFlags
|
||||||
GTexf_NoTrim = 1024, // Don't perform trimming on this texture.
|
GTexf_NoTrim = 1024, // Don't perform trimming on this texture.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FMaterialLayers
|
||||||
|
{
|
||||||
|
RefCountedPtr<FTexture> Detailmap;
|
||||||
|
RefCountedPtr<FTexture> Glowmap;
|
||||||
|
RefCountedPtr<FTexture> Normal; // Normal map texture
|
||||||
|
RefCountedPtr<FTexture> Specular; // Specular light texture for the diffuse+normal+specular light model
|
||||||
|
RefCountedPtr<FTexture> Metallic; // Metalness texture for the physically based rendering (PBR) light model
|
||||||
|
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
|
// Refactoring helper to allow piece by piece adjustment of the API
|
||||||
class FGameTexture
|
class FGameTexture
|
||||||
{
|
{
|
||||||
|
@ -71,14 +84,7 @@ class FGameTexture
|
||||||
// Material layers. These are shared so reference counting is used.
|
// Material layers. These are shared so reference counting is used.
|
||||||
RefCountedPtr<FTexture> Base;
|
RefCountedPtr<FTexture> Base;
|
||||||
RefCountedPtr<FTexture> Brightmap;
|
RefCountedPtr<FTexture> Brightmap;
|
||||||
RefCountedPtr<FTexture> Detailmap;
|
std::unique_ptr<FMaterialLayers> Layers;
|
||||||
RefCountedPtr<FTexture> Glowmap;
|
|
||||||
RefCountedPtr<FTexture> Normal; // Normal map texture
|
|
||||||
RefCountedPtr<FTexture> Specular; // Specular light texture for the diffuse+normal+specular light model
|
|
||||||
RefCountedPtr<FTexture> Metallic; // Metalness texture for the physically based rendering (PBR) light model
|
|
||||||
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
|
|
||||||
|
|
||||||
FString Name;
|
FString Name;
|
||||||
FTextureID id;
|
FTextureID id;
|
||||||
|
@ -204,14 +210,25 @@ public:
|
||||||
if (lay.Glossiness > -1000) Glossiness = lay.Glossiness;
|
if (lay.Glossiness > -1000) Glossiness = lay.Glossiness;
|
||||||
if (lay.SpecularLevel > -1000) SpecularLevel = lay.SpecularLevel;
|
if (lay.SpecularLevel > -1000) SpecularLevel = lay.SpecularLevel;
|
||||||
if (lay.Brightmap) Brightmap = lay.Brightmap->GetTexture();
|
if (lay.Brightmap) Brightmap = lay.Brightmap->GetTexture();
|
||||||
if (lay.Normal) Normal = lay.Normal->GetTexture();
|
|
||||||
if (lay.Specular) Specular = lay.Specular->GetTexture();
|
bool needlayers = (lay.Normal || lay.Specular || lay.Metallic || lay.Roughness || lay.AmbientOcclusion);
|
||||||
if (lay.Metallic) Metallic = lay.Metallic->GetTexture();
|
for (int i = 0; i < MAX_CUSTOM_HW_SHADER_TEXTURES && !needlayers; i++)
|
||||||
if (lay.Roughness) Roughness = lay.Roughness->GetTexture();
|
{
|
||||||
if (lay.AmbientOcclusion) AmbientOcclusion = lay.AmbientOcclusion->GetTexture();
|
if (lay.CustomShaderTextures[i]) needlayers = true;
|
||||||
|
}
|
||||||
|
if (needlayers)
|
||||||
|
{
|
||||||
|
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++)
|
for (int i = 0; i < MAX_CUSTOM_HW_SHADER_TEXTURES; i++)
|
||||||
{
|
{
|
||||||
if (lay.CustomShaderTextures[i]) CustomShaderTextures[i] = lay.CustomShaderTextures[i]->GetTexture();
|
if (lay.CustomShaderTextures[i]) Layers->CustomShaderTextures[i] = lay.CustomShaderTextures[i]->GetTexture();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float GetGlossiness() const { return Glossiness; }
|
float GetGlossiness() const { return Glossiness; }
|
||||||
|
@ -306,15 +323,22 @@ public:
|
||||||
void GetLayers(TArray<FTexture*>& layers)
|
void GetLayers(TArray<FTexture*>& layers)
|
||||||
{
|
{
|
||||||
layers.Clear();
|
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);
|
if (tex != nullptr) layers.Push(tex);
|
||||||
}
|
}
|
||||||
for (auto& tex : CustomShaderTextures)
|
if (Layers)
|
||||||
|
{
|
||||||
|
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());
|
if (tex != nullptr) layers.Push(tex.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FVector2 GetDetailScale() const
|
FVector2 GetDetailScale() const
|
||||||
{
|
{
|
||||||
|
@ -335,28 +359,34 @@ public:
|
||||||
}
|
}
|
||||||
FTexture* GetGlowmap()
|
FTexture* GetGlowmap()
|
||||||
{
|
{
|
||||||
return Glowmap.get();
|
if (!Layers) return nullptr;
|
||||||
|
return Layers->Glowmap.get();
|
||||||
}
|
}
|
||||||
FTexture* GetDetailmap()
|
FTexture* GetDetailmap()
|
||||||
{
|
{
|
||||||
return Detailmap.get();
|
if (!Layers) return nullptr;
|
||||||
|
return Layers->Detailmap.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetGlowmap(FTexture *T)
|
void SetGlowmap(FTexture *T)
|
||||||
{
|
{
|
||||||
Glowmap = T;
|
if (!Layers) Layers = std::make_unique<FMaterialLayers>();
|
||||||
|
Layers->Glowmap = T;
|
||||||
}
|
}
|
||||||
void SetDetailmap(FTexture* T)
|
void SetDetailmap(FTexture* T)
|
||||||
{
|
{
|
||||||
Detailmap = T;
|
if (!Layers) Layers = std::make_unique<FMaterialLayers>();
|
||||||
|
Layers->Detailmap = T;
|
||||||
}
|
}
|
||||||
void SetNormalmap(FTexture* T)
|
void SetNormalmap(FTexture* T)
|
||||||
{
|
{
|
||||||
Normal = T;
|
if (!Layers) Layers = std::make_unique<FMaterialLayers>();
|
||||||
|
Layers->Normal = T;
|
||||||
}
|
}
|
||||||
void SetSpecularmap(FTexture* T)
|
void SetSpecularmap(FTexture* T)
|
||||||
{
|
{
|
||||||
Specular = T;
|
if (!Layers) Layers = std::make_unique<FMaterialLayers>();
|
||||||
|
Layers->Specular = T;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -79,17 +79,17 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
|
||||||
mShaderIndex = tx->isWarped(); // This picks SHADER_Warp1 or SHADER_Warp2
|
mShaderIndex = tx->isWarped(); // This picks SHADER_Warp1 or SHADER_Warp2
|
||||||
}
|
}
|
||||||
// Note that the material takes no ownership of the texture!
|
// 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 });
|
mTextureLayers.Push({ texture, 0, -1 });
|
||||||
}
|
}
|
||||||
mShaderIndex = SHADER_Specular;
|
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 });
|
mTextureLayers.Push({ texture, 0, -1 });
|
||||||
}
|
}
|
||||||
|
@ -108,18 +108,18 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
|
||||||
{
|
{
|
||||||
mTextureLayers.Push({ placeholder->GetTexture(), 0, -1 });
|
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;
|
mLayerFlags |= TEXF_Detailmap;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mTextureLayers.Push({ placeholder->GetTexture(), 0, -1 });
|
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;
|
mLayerFlags |= TEXF_Glowmap;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -133,9 +133,9 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
|
||||||
if (index >= FIRST_USER_SHADER)
|
if (index >= FIRST_USER_SHADER)
|
||||||
{
|
{
|
||||||
const UserShaderDesc& usershader = usershaders[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;
|
if (texture == nullptr) continue;
|
||||||
mTextureLayers.Push({ texture.get(), 0 }); // scalability should be user-definable.
|
mTextureLayers.Push({ texture.get(), 0 }); // scalability should be user-definable.
|
||||||
|
|
|
@ -426,7 +426,7 @@ FTextureID FTextureManager::AddGameTexture (FGameTexture *texture, bool addtohas
|
||||||
hash = -1;
|
hash = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureHash hasher = { texture, -1, -1, -1, hash };
|
TextureDescriptor hasher = { texture, -1, -1, -1, hash };
|
||||||
int trans = Textures.Push (hasher);
|
int trans = Textures.Push (hasher);
|
||||||
Translation.Push (trans);
|
Translation.Push (trans);
|
||||||
if (bucket >= 0) HashFirst[bucket] = trans;
|
if (bucket >= 0) HashFirst[bucket] = trans;
|
||||||
|
@ -1150,7 +1150,7 @@ void FTextureManager::AddLocalizedVariants()
|
||||||
uint32_t langid = MAKE_ID(lang[0], lang[1], lang[2], 0);
|
uint32_t langid = MAKE_ID(lang[0], lang[1], lang[2], 0);
|
||||||
uint64_t comboid = (uint64_t(langid) << 32) | origTex.GetIndex();
|
uint64_t comboid = (uint64_t(langid) << 32) | origTex.GetIndex();
|
||||||
LocalizedTextures.Insert(comboid, tex.GetIndex());
|
LocalizedTextures.Insert(comboid, tex.GetIndex());
|
||||||
Textures[origTex.GetIndex()].HasLocalization = true;
|
Textures[origTex.GetIndex()].Flags |= TEXFLAG_HASLOCALIZATION;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,7 +29,7 @@ private:
|
||||||
{
|
{
|
||||||
if ((unsigned)texnum >= Textures.Size()) return -1;
|
if ((unsigned)texnum >= Textures.Size()) return -1;
|
||||||
if (animate) texnum = Translation[texnum];
|
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;
|
return texnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,17 +183,22 @@ private:
|
||||||
|
|
||||||
// Switches
|
// Switches
|
||||||
|
|
||||||
struct TextureHash
|
struct TextureDescriptor
|
||||||
{
|
{
|
||||||
FGameTexture* Texture;
|
FGameTexture* Texture;
|
||||||
int Paletted; // redirection to paletted variant
|
int Paletted; // redirection to paletted variant
|
||||||
int FrontSkyLayer; // and front sky layer,
|
int FrontSkyLayer; // and front sky layer,
|
||||||
int RawTexture;
|
int RawTexture;
|
||||||
int HashNext;
|
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 };
|
enum { HASH_END = -1, HASH_SIZE = 1027 };
|
||||||
TArray<TextureHash> Textures;
|
TArray<TextureDescriptor> Textures;
|
||||||
TMap<uint64_t, int> LocalizedTextures;
|
TMap<uint64_t, int> LocalizedTextures;
|
||||||
int HashFirst[HASH_SIZE];
|
int HashFirst[HASH_SIZE];
|
||||||
FTextureID DefaultTexture;
|
FTextureID DefaultTexture;
|
||||||
|
|
Loading…
Reference in a new issue