Cogs.Core
MaterialInspector.cpp
1#include "Inspectors.h"
2
3#include "InspectorGuiHelper.h"
4#include "Context.h"
5#include "Resources/MaterialManager.h"
6
7#include "Resources/MaterialInstance.h"
8#include "Resources/Texture.h"
9
10#include "imgui.h"
11
12using namespace Cogs::Core;
13
14namespace {
15 void ShowPropertiy(Material* material, MaterialProperty &prop)
16 {
17 auto& buffer = material->constantBuffers.buffers[prop.buffer];
18 switch (prop.type) {
19 case MaterialDataType::Float:
20 {
21 float value = buffer.getValue<float>(prop.descriptor.offset);
22 if (ImGui::DragFloat(prop.name.c_str(), &value, 0.01f, 0.0f, 1.0f)) {
23 buffer.setValue(prop.descriptor.offset, value);
24 }
25 }
26 break;
27
28 case MaterialDataType::Int:
29 {
30 int32_t value = buffer.getValue<int32_t>(prop.descriptor.offset);
31 if (ImGui::DragInt(prop.name.c_str(), &value, 1.0f, 0, 100)) {
32 buffer.setValue(prop.descriptor.offset, value);
33 }
34 }
35 break;
36
37 case MaterialDataType::Bool:
38 {
39 bool value = buffer.getValue<bool>(prop.descriptor.offset);
40 if (ImGui::Checkbox(prop.name.c_str(), &value)) {
41 buffer.setValue(prop.descriptor.offset, value);
42 }
43 }
44 break;
45
46 case MaterialDataType::Float2:
47 {
48 glm::vec2 value = buffer.getValue<glm::vec2>(prop.descriptor.offset);
49 if (ImGui::DragFloat2(prop.name.c_str(), glm::value_ptr(value))) {
50 buffer.setValue(prop.descriptor.offset, value);
51 }
52 }
53 break;
54
55 case MaterialDataType::Float3:
56 {
57 glm::vec3 value = buffer.getValue<glm::vec3>(prop.descriptor.offset);
58 if (ImGui::DragFloat3(prop.name.c_str(), glm::value_ptr(value))) {
59 buffer.setValue(prop.descriptor.offset, value);
60 }
61 }
62 break;
63
64 case MaterialDataType::Float4:
65 {
66 glm::vec4 value = buffer.getValue<glm::vec4>(prop.descriptor.offset);
67 if (ImGui::DragFloat4(prop.name.c_str(), glm::value_ptr(value))) {
68 buffer.setValue(prop.descriptor.offset, value);
69 }
70 }
71 break;
72
73 case MaterialDataType::Float4x4:
74 {
75 auto value = buffer.getValue<glm::mat4>(prop.descriptor.offset);
76 if (showMatrix(prop.name, value)) {
77 buffer.setValue(prop.descriptor.offset, value);
78 }
79 }
80 break;
81
82 case MaterialDataType::UInt:
83 {
84 int32_t value = (int32_t)buffer.getValue<uint32_t>(prop.descriptor.offset);
85 if (ImGui::DragInt(prop.name.c_str(), &value, 1.0f, 0, 100)) {
86 buffer.setValue(prop.descriptor.offset, (uint32_t)value);
87 }
88 }
89 break;
90
91 default:
92 ImGui::Text("Unsupported: %d", static_cast<int>(prop.type));
93 break;
94 }
95 }
96}
97
98void showMaterial(Context * context, Material * material, const std::string & header)
99{
100 ImGui::PushID(material);
101
102 if (ImGui::TreeNode(header.c_str())) {
103 ScopedIndent si;
104
105 if (!material->constantBuffers.variables.empty()) {
106 if (ImGui::TreeNode("Properties")) {
107 for (auto & prop : material->constantBuffers.variables) {
108 ShowPropertiy(material, prop);
109 }
110 ImGui::TreePop();
111 }
112 } else {
113 ImGui::Text("Properties: Empty");
114 }
115
116 if (!material->textureProperties.empty() && ImGui::TreeNode("Textures")) {
117 ScopedIndent si2;
118 for (auto & prop : material->textureProperties) {
119 if (!prop.texture.handle) {
120 ImGui::Text("%s: Empty", prop.name.c_str());
121 } else {
122 if (ImGui::TreeNode(prop.name.c_str())) {
123 ScopedIndent si3;
124
125 showTexture(context, dynamic_cast<Cogs::Core::Renderer *>(context->renderer), prop.texture.handle.resolve());
126
127 ImGui::TreePop();
128 }
129 }
130 }
131
132 ImGui::TreePop();
133 }
134
135 bool hasSharedVariants = false;
136 if (!material->definition.variants.empty()) {
137 for (const ShaderVariantDefinition& v : material->definition.variants) {
138 if (v.isShared) {
139 hasSharedVariants = true;
140 break;
141 }
142 }
143 }
144 if (hasSharedVariants && ImGui::TreeNode("Variants")) {
145 for (ShaderVariantDefinition& v : material->definition.variants) {
146 if (!v.isShared) continue;
147 size_t value = v.defaultValue;
148
149 switch (v.type) {
150 case ShaderVariantType::Enum:
151 {
152 std::vector<const char*> enumNames(v.values.size());
153
154 for (size_t i = 0; i < v.values.size(); ++i) {
155 enumNames[i] = v.values[i].key.c_str();
156 }
157
158 int currentIndex = static_cast<int>(value);
159 if (ImGui::Combo(v.name.c_str(), &currentIndex, enumNames.data(), static_cast<int>(enumNames.size()))) {
160 // The shared setVariant function is not yet created for enums
161 }
162 }
163 break;
164
165 case ShaderVariantType::Bool:
166 if (bool boolean = value != 0; ImGui::Checkbox(v.name.c_str(), &boolean)) {
167 // The shared setVariant function is not yet created for bools
168 }
169 break;
170
171 case ShaderVariantType::Int:
172 if (int integer = static_cast<int>(value); ImGui::InputInt(v.name.c_str(), &integer, 1)) {
173 material->setVariant(v.name, integer);
174 }
175 break;
176
177 // Don't show: VertexStreamPosition0": { "type": "format", "value" : "BASE_MATERIAL_VERTEX_POSITION0",..
178 case ShaderVariantType::Format:
179 break;
180
181 default:
182 ImGui::Text("Unsupported: %s", v.name.c_str());
183 break;
184 }
185 }
186
187 ImGui::TreePop();
188 }
189
190 if (!material->constantBuffers.buffers.empty()) {
191 if (ImGui::TreeNode("Buffers")) {
192 ScopedIndent si2;
193 for (auto & buffer : material->constantBuffers.buffers) {
194 ImGui::Text("%s", buffer.name.c_str());
195 ImGui::Text(" Size: %zu", buffer.size); ImGui::SameLine();
196 ImGui::Text(" Shared: %s", buffer.isPerInstance ? "false" : "true"); ImGui::SameLine();
197 ImGui::Text(" Gen: %zu", buffer.generation);
198
199 ImGui::PushID(&buffer);
200 if (!material->constantBuffers.variables.empty() && ImGui::TreeNode("Properties")) {
201 for (auto& prop : material->constantBuffers.variables) {
202 if (prop.buffer != buffer.index) continue;
203 ShowPropertiy(material, prop);
204 }
205 ImGui::TreePop();
206 }
207 ImGui::PopID();
208 }
209 ImGui::TreePop();
210 }
211 }
212
213 showMaterialOptions(context, &material->options, "Options");
214
215 ImGui::TreePop();
216 }
217
218 ImGui::PopID();
219}
220
221void Cogs::Core::materialInspector(Context * context, bool * show)
222{
223 if (*show) {
224 ImGui::SetNextWindowSize(ImVec2(600, 1000), ImGuiCond_Once);
225
226 std::vector<Cogs::Core::ResourceBase*> materials = context->materialManager->getAllocatedResources();
227 guiBegin("Materials " + std::to_string(materials.size()), show);
228
229 int id = 0;
230 for (auto & m : materials) {
231 auto material = static_cast<Material *>(m);
232 std::string header = (!material->getName().empty() ? std::string(material->getName()) : "Material " + std::to_string(id++));
233 showMaterial(context, material, header);
234 }
235
236 guiEnd();
237 }
238}
239
240
241void Cogs::Core::materialInstanceInspector(Context* context, bool* show)
242{
243 if (*show) {
244 ImGui::SetNextWindowSize(ImVec2(600, 1000), ImGuiCond_Once);
245
246 std::vector<Cogs::Core::ResourceBase*> materials = context->materialInstanceManager->getAllocatedResources();
247 guiBegin("Material Instances " + std::to_string(materials.size()), show);
248
249 int id = 0;
250 for (auto& m : materials) {
251 auto material = static_cast<MaterialInstance*>(m);
252 std::string header = (!material->getName().empty() ? std::string(material->getName()) : "Material " + std::to_string(id++));
253 showMaterialInstance(context, material, header);
254 }
255
256 guiEnd();
257 }
258}
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
class IRenderer * renderer
Renderer.
Definition: Context.h:228
Core renderer system.
Definition: Renderer.h:28
constexpr bool empty() const noexcept
Check if the string is empty.
Definition: StringView.h:122
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
STL namespace.
std::vector< MaterialPropertyBuffer > buffers
Constant buffer instances.
std::vector< MaterialProperty > variables
Individual variables from all buffer instances.
Material instances represent a specialized Material combined with state for all its buffers and prope...
Defines a single material property.
MaterialPropertyDescriptor descriptor
Property descriptor.
ConstantBufferKey buffer
Key to the buffer the property value is stored in.
PropertyName name
Name of the property, used to reference named uniforms of constant buffer members in shaders.
MaterialDataType type
Type of data held by property.
Material resources define the how of geometry rendering (the what is defined by Mesh and Texture reso...
Definition: Material.h:82
MaterialOptions options
Material rendering options.
Definition: Material.h:383
StringView getName() const
Get the name of the resource.
Definition: ResourceBase.h:307