[Gameplay] Reduce loom cost
[0ad.git] / source / graphics / TerrainTextureEntry.cpp
blob5bf1a59ce6d151fb1318797b0c73d3fbf3b93c9e
1 /* Copyright (C) 2022 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
18 #include "precompiled.h"
20 #include "TerrainTextureEntry.h"
22 #include "graphics/MaterialManager.h"
23 #include "graphics/Terrain.h"
24 #include "graphics/TerrainProperties.h"
25 #include "graphics/TerrainTextureManager.h"
26 #include "graphics/TextureManager.h"
27 #include "lib/utf8.h"
28 #include "ps/CLogger.h"
29 #include "ps/CStrInternStatic.h"
30 #include "ps/Filesystem.h"
31 #include "ps/XML/Xeromyces.h"
32 #include "renderer/Renderer.h"
33 #include "renderer/SceneRenderer.h"
35 #include <map>
37 CTerrainTextureEntry::CTerrainTextureEntry(CTerrainPropertiesPtr properties, const VfsPath& path):
38 m_pProperties(properties),
39 m_BaseColor(0),
40 m_BaseColorValid(false)
42 ENSURE(properties);
44 CXeromyces XeroFile;
45 if (XeroFile.Load(g_VFS, path, "terrain_texture") != PSRETURN_OK)
47 LOGERROR("Terrain xml not found (%s)", path.string8());
48 return;
51 #define EL(x) int el_##x = XeroFile.GetElementID(#x)
52 #define AT(x) int at_##x = XeroFile.GetAttributeID(#x)
53 EL(tag);
54 EL(terrain);
55 EL(texture);
56 EL(textures);
57 EL(material);
58 EL(props);
59 EL(alphamap);
60 AT(file);
61 AT(name);
62 #undef AT
63 #undef EL
65 XMBElement root = XeroFile.GetRoot();
67 if (root.GetNodeName() != el_terrain)
69 LOGERROR("Invalid terrain format (unrecognised root element '%s')", XeroFile.GetElementString(root.GetNodeName()));
70 return;
73 std::vector<std::pair<CStr, VfsPath> > samplers;
74 VfsPath alphamap("standard");
75 m_Tag = utf8_from_wstring(path.Basename().string());
77 XERO_ITER_EL(root, child)
79 int child_name = child.GetNodeName();
81 if (child_name == el_textures)
83 XERO_ITER_EL(child, textures_element)
85 ENSURE(textures_element.GetNodeName() == el_texture);
87 CStr name;
88 VfsPath terrainTexturePath;
89 XERO_ITER_ATTR(textures_element, relativePath)
91 if (relativePath.Name == at_file)
92 terrainTexturePath = VfsPath("art/textures/terrain") / relativePath.Value.FromUTF8();
93 else if (relativePath.Name == at_name)
94 name = relativePath.Value;
96 samplers.emplace_back(name, terrainTexturePath);
97 if (name == str_baseTex.string())
98 m_DiffuseTexturePath = terrainTexturePath;
102 else if (child_name == el_material)
104 VfsPath mat = VfsPath("art/materials") / child.GetText().FromUTF8();
105 if (CRenderer::IsInitialised())
106 m_Material = g_Renderer.GetSceneRenderer().GetMaterialManager().LoadMaterial(mat);
108 else if (child_name == el_alphamap)
110 alphamap = child.GetText().FromUTF8();
112 else if (child_name == el_props)
114 CTerrainPropertiesPtr ret (new CTerrainProperties(properties));
115 ret->LoadXml(child, &XeroFile, path);
116 if (ret) m_pProperties = ret;
118 else if (child_name == el_tag)
120 m_Tag = child.GetText();
124 for (size_t i = 0; i < samplers.size(); ++i)
126 CTextureProperties texture(samplers[i].second);
127 texture.SetAddressMode(Renderer::Backend::Sampler::AddressMode::REPEAT);
128 texture.SetAnisotropicFilter(true);
130 if (CRenderer::IsInitialised())
132 CTexturePtr texptr = g_Renderer.GetTextureManager().CreateTexture(texture);
133 m_Material.AddSampler(CMaterial::TextureSampler(samplers[i].first, texptr));
137 if (CRenderer::IsInitialised())
138 m_TerrainAlpha = g_TexMan.LoadAlphaMap(alphamap);
140 float texAngle = 0.f;
141 float texSize = 1.f;
143 if (m_pProperties)
145 m_Groups = m_pProperties->GetGroups();
146 texAngle = m_pProperties->GetTextureAngle();
147 texSize = m_pProperties->GetTextureSize();
150 m_TextureMatrix.SetZero();
151 m_TextureMatrix._11 = cosf(texAngle) / texSize;
152 m_TextureMatrix._13 = -sinf(texAngle) / texSize;
153 m_TextureMatrix._21 = -sinf(texAngle) / texSize;
154 m_TextureMatrix._23 = -cosf(texAngle) / texSize;
155 m_TextureMatrix._44 = 1.f;
157 GroupVector::iterator it=m_Groups.begin();
158 for (;it!=m_Groups.end();++it)
159 (*it)->AddTerrain(this);
162 CTerrainTextureEntry::~CTerrainTextureEntry()
164 for (GroupVector::iterator it=m_Groups.begin();it!=m_Groups.end();++it)
165 (*it)->RemoveTerrain(this);
168 // BuildBaseColor: calculate the root color of the texture, used for coloring minimap, and store
169 // in m_BaseColor member
170 void CTerrainTextureEntry::BuildBaseColor()
172 // Use the explicit properties value if possible
173 if (m_pProperties && m_pProperties->HasBaseColor())
175 m_BaseColor=m_pProperties->GetBaseColor();
176 m_BaseColorValid = true;
177 return;
180 // Use the texture color if available
181 if (GetTexture()->TryLoad())
183 m_BaseColor = GetTexture()->GetBaseColor();
184 m_BaseColorValid = true;