Cogs.Core
BasicTerrainComponent.cpp
1#include "BasicTerrainComponent.h"
2
3#include "Types.h"
4#include "Context.h"
5
6#include "Resources/MaterialManager.h"
7#include "Resources/TextureManager.h"
8#include "Resources/Texture.h"
9
10#include "Systems/Geometry/AdaptivePlanarGridSystem.h"
11
12#include "Foundation/ComponentModel/Attributes.h"
13
14#include <cassert>
15
16namespace {
17 using namespace Cogs::Core;
18
19 void initMaterialInstanceCallback(MaterialInstance* instance, Cogs::ComponentModel::Entity* /*container*/, void* data)
20 {
21 auto* terrainComp = static_cast<const BasicTerrainComponent*>(data);
22 instance->setVariant("HasNoData", terrainComp->noDataEnabled);
23 switch (terrainComp->elevationChannel) {
24 case BasicTerrainElevationChannel::Red:
25 instance->setVariant("ElevationChannel", "Red");
26 break;
27 case BasicTerrainElevationChannel::Alpha:
28 instance->setVariant("ElevationChannel", "Alpha");
29 break;
30 case BasicTerrainElevationChannel::RedGreenBlue:
31 instance->setVariant("ElevationChannel", "RedGreenBlue");
32 break;
33 default:
34 assert(false && "Unhandled case.");
35 }
36 if (terrainComp->colorMap) {
37 switch (terrainComp->transparencyMode) {
38 case BasicTerrainTransparencyMode::None:
39 instance->setOpaque();
40 instance->setVariant("Color", "TextureRGB");
41 instance->options.blendMode = BlendMode::None;
42 break;
43 case BasicTerrainTransparencyMode::Regular:
44 instance->options.blendMode = BlendMode::None;
45 instance->setTransparent();
46 instance->setVariant("Color", "TextureRGBA");
47 break;
48 case BasicTerrainTransparencyMode::BlendWithZWrite:
49 instance->setOpaque();
50 instance->setVariant("Color", "TextureRGBA");
51 instance->options.blendMode = BlendMode::Blend;
52 break;
53 default:
54 assert(false && "Unhandled case.");
55 }
56 }
57 else {
58 instance->setVariant("Color", "Solid");
59 }
60 instance->setVariant("ElevationToAlpha", terrainComp->elevationToAlpha);
61
62 instance->setVec4Property(terrainComp->elevationTransformKey, terrainComp->elevationTransform);
63 instance->setVec2Property(terrainComp->normalTransformKey, terrainComp->normalTransform);
64 instance->setVec3Property(terrainComp->elevationToAlphaTransformKey, terrainComp->elevationToAlphaTransform);
65 instance->setTextureProperty(terrainComp->elevationTexKey, terrainComp->elevationMap);
66 instance->setTextureAddressMode(terrainComp->elevationTexKey, Cogs::SamplerState::AddressMode::Clamp);
67 instance->setTextureProperty(terrainComp->colorTexKey, terrainComp->colorMap);
68 instance->setTextureAddressMode(terrainComp->colorTexKey, Cogs::SamplerState::AddressMode::Clamp);
69 instance->setVec4Property(terrainComp->diffuseColorKey, terrainComp->diffuseColor);
70 instance->setFloatProperty(terrainComp->noDataValueKey, terrainComp->noDataValue);
71 instance->setFloatProperty(terrainComp->vibranceKey, glm::clamp(2.f-terrainComp->vibrance, 0.001f, 2.f));
72 }
73
74}
75
76using namespace Cogs::Reflection;
77
78void Cogs::Core::BasicTerrainComponent::registerType()
79{
80 {
81 static constexpr EnumeratorDef enumerators[] = {
85 };
86 TypeDatabase::createType<BasicTerrainElevationChannel>().setEnumerators(enumerators);
87 }
88 {
89 static constexpr EnumeratorDef enumerators[] = {
93 };
94 TypeDatabase::createType<BasicTerrainTransparencyMode>().setEnumerators(enumerators);
95 }
96
97 Field fields[] = {
98 Field(Name("elevationChannel"), &BasicTerrainComponent::elevationChannel),
99 Field(Name("elevationMap"), &BasicTerrainComponent::elevationMap),
101 Field(Name("colorMap"), &BasicTerrainComponent::colorMap),
103 .add(RangeAttribute(0.0f, 2.f)),
112 Field(Name("elevationMapNormalized"), &BasicTerrainComponent::elevationMapNormalized),
113 Field(Name("elevationToAlpha"), &BasicTerrainComponent::elevationToAlpha),
114 Field(Name("elevationToAlphaMin"), &BasicTerrainComponent::elevationToAlphaMin),
115 Field(Name("elevationToAlphaMax"), &BasicTerrainComponent::elevationToAlphaMax),
116 Field(Name("elevationToAlphaPower"), &BasicTerrainComponent::elevationToAlphaPower)
117 .add(RangeAttribute(0.0f, 2.f)),
118 Field(Name("cullMode"), &BasicTerrainComponent::cullMode)
119 };
120
121 Method methods[] = {
122 Method(Name("initialize"), &BasicTerrainComponent::initialize),
123 Method(Name("update"), &BasicTerrainComponent::update),
124 };
125
126 DynamicComponent::registerDerivedType<BasicTerrainComponent>()
127 .setFields(fields)
128 .setMethods(methods);
129}
130
131void Cogs::Core::BasicTerrainComponent::initialize(Context * context)
132{
133 this->context = context;
134
135 material = context->materialManager->loadMaterial("BasicTerrainMaterial.material");
136
137 context->materialManager->processLoading();
138
139 elevationTexKey = material->getTextureKey("Elevation");
140 colorTexKey = material->getTextureKey("Color");
141 diffuseColorKey = material->getVec4Key("diffuseColor");
142 elevationTransformKey = material->getVec2Key("elevationTransform");
143 normalTransformKey = material->getVec2Key("normalTransform");
144 noDataValueKey = material->getFloatKey("noDataValue");
145 vibranceKey = material->getFloatKey("vibrance");
146 elevationToAlphaTransformKey = material->getFloatKey("elevationToAlphaTransform");
147
148 auto gridComp = getComponent<AdaptivePlanarGridComponent>();
149
150 context->adaptivePlanarGridSystem->registerMaterial(gridComp, material, nullptr, nullptr);
151
152 gridComp->setChanged();
153}
154
155void Cogs::Core::BasicTerrainComponent::update()
156{
157 auto * gridComp = getComponent<AdaptivePlanarGridComponent>();
158 if (!gridComp) return;
159
160 if (hasChanged() || gridComp->hasChanged()) {
161 forceUpdate = true;
162 }
163
164 if (elevationMap) {
165 if (auto flags = elevationMap->getFlags(); elevationFlags != flags) {
166 elevationFlags = flags;
167 forceUpdate = true;
168 }
169 }
170
171 if (forceUpdate && elevationMap) {
172 forceUpdate = false;
173
174 material->options.cullMode = cullMode;
175
176 glm::vec2 extent = glm::vec2(gridComp->extentMax - gridComp->extentMin);
177 if (elevationMapNormalized) {
178 float scale_z = elevationMax - elevationMin;
179 elevationTransform = glm::vec4(scale_z,
180 elevationMin,
181 1.f / elevationMap->description.width,
182 1.f / elevationMap->description.height);
183 normalTransform = glm::vec2(2.f * extent.x / (elevationMap->description.width * scale_z),
184 2.f * extent.y / (elevationMap->description.height * scale_z));
185 elevationToAlphaTransform = glm::vec3((elevationToAlphaMin - elevationMin) / scale_z,
186 scale_z / (elevationToAlphaMax - elevationToAlphaMin),
187 elevationToAlphaPower);
188 }
189 else {
190 elevationTransform = glm::vec4(elevationScale,
191 elevationBias,
192 1.f / elevationMap->description.width,
193 1.f / elevationMap->description.height);
194 normalTransform = glm::vec2(2.f * extent.x / (elevationMap->description.width * elevationScale),
195 2.f * extent.y / (elevationMap->description.height * elevationScale));
196 elevationToAlphaTransform = glm::vec3((elevationToAlphaMin - elevationBias) / elevationScale,
197 elevationScale / (elevationToAlphaMax - elevationToAlphaMin),
198 elevationToAlphaPower);
199 }
200 gridComp->displaceMin = glm::vec3(0.f, 0.f, elevationMin);
201 gridComp->displaceMax = glm::vec3(0.f, 0.f, elevationMax);
202 context->adaptivePlanarGridSystem->registerMaterial(gridComp, material, initMaterialInstanceCallback, this);
203 gridComp->setChanged();
204 }
205}
Container for components, providing composition of dynamic entities.
Definition: Entity.h:18
BasicTerrainTransparencyMode transparencyMode
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
Field definition describing a single data member of a data structure.
Definition: Field.h:68
Field & add(T attribute)
Adds the given attribute.
Definition: Field.h:177
Simple method definition.
Definition: Method.h:72
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
@ None
No transparency, it is safe to store elevation in colormap's alpha channel.
@ BlendWithZWrite
Treat terrain as opaque, but enable blending with colormap's alpha channel.
@ Regular
Regular transparency, use colormap's alpha channel.
@ RedGreenBlue
Concatenate bits from red, green and blue channels.
@ Alpha
Fetch elevation from alpha channel of elevation texture.
@ Red
Fetch elevation from red channel of elevation texture.
Contains reflection support.
Definition: Component.h:11
Tags an object as being able to represent a color.
Definition: Attributes.h:122
Adds range information to an object.
Definition: Attributes.h:38
Material instances represent a specialized Material combined with state for all its buffers and prope...
void setFloatProperty(const VariableKey key, float value)
Set the float property with the given key to value.
void setTransparent()
Set the material instance to transparent, indicating to the renderer that blending should be enabled ...
void setVec3Property(const VariableKey key, glm::vec3 value)
Set the vec3 property with the given key to value.
void setTextureAddressMode(const StringView &key, const StringView &addressMode)
Set texture address mode with textual name.
void setTextureProperty(const StringView &key, TextureHandle value)
Set the texture property with the given key to the texture resource held by value.
void setVec2Property(const VariableKey key, glm::vec2 value)
Set the vec2 property with the given key to value.
MaterialOptions options
Material rendering options used by this instance.
void setVec4Property(const VariableKey key, glm::vec4 value)
Set the vec4 property with the given key to value.
void setOpaque()
Set the material instance to opaque, indicating to the renderer that blending should be disabled for ...
BlendMode blendMode
Blend mode to use when rendering geometry with the material instance.
Represents an unique name.
Definition: Name.h:70
@ Clamp
Texture coordinates are clamped to the [0, 1] range.
Definition: SamplerState.h:17