Material Inspector

Can set material
This commit is contained in:
Sri Sham Haran 2022-11-02 21:31:27 +08:00
parent c68c5adc0d
commit e609b5634a
23 changed files with 380 additions and 134 deletions

View File

@ -1,16 +1,16 @@
[Window][MainStatusBar] [Window][MainStatusBar]
Pos=0,1060 Pos=0,1007
Size=1920,20 Size=1920,20
Collapsed=0 Collapsed=0
[Window][SHEditorMenuBar] [Window][SHEditorMenuBar]
Pos=0,48 Pos=0,48
Size=1920,1012 Size=1920,959
Collapsed=0 Collapsed=0
[Window][Hierarchy Panel] [Window][Hierarchy Panel]
Pos=0,197 Pos=0,189
Size=308,863 Size=308,818
Collapsed=0 Collapsed=0
DockId=0x00000004,0 DockId=0x00000004,0
@ -21,13 +21,13 @@ Collapsed=0
[Window][Inspector] [Window][Inspector]
Pos=1528,48 Pos=1528,48
Size=392,1012 Size=392,959
Collapsed=0 Collapsed=0
DockId=0x00000006,0 DockId=0x00000006,0
[Window][Profiler] [Window][Profiler]
Pos=0,48 Pos=0,48
Size=308,147 Size=308,139
Collapsed=0 Collapsed=0
DockId=0x00000003,0 DockId=0x00000003,0
@ -76,7 +76,7 @@ DockId=0x0000000B,0
[Window][ Viewport] [Window][ Viewport]
Pos=310,48 Pos=310,48
Size=1216,715 Size=1216,662
Collapsed=0 Collapsed=0
DockId=0x0000000B,0 DockId=0x0000000B,0
@ -93,13 +93,19 @@ Collapsed=0
DockId=0x0000000A,0 DockId=0x0000000A,0
[Window][ Asset Browser] [Window][ Asset Browser]
Pos=310,765 Pos=310,712
Size=1216,295 Size=1216,295
Collapsed=0 Collapsed=0
DockId=0x0000000C,0 DockId=0x0000000C,0
[Window][Material Inspector]
Pos=1528,48
Size=392,959
Collapsed=0
DockId=0x00000006,1
[Docking][Data] [Docking][Data]
DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=0,71 Size=1920,959 Split=X
DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1526,1036 Split=X DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1526,1036 Split=X
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=308,1036 Split=Y Selected=0x1E6EB881 DockNode ID=0x00000001 Parent=0x00000005 SizeRef=308,1036 Split=Y Selected=0x1E6EB881
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,147 Selected=0x1E6EB881 DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,147 Selected=0x1E6EB881
@ -111,5 +117,5 @@ DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Spli
DockNode ID=0x0000000C Parent=0x00000009 SizeRef=1501,295 Selected=0xB128252A DockNode ID=0x0000000C Parent=0x00000009 SizeRef=1501,295 Selected=0xB128252A
DockNode ID=0x0000000A Parent=0x00000007 SizeRef=1501,310 Selected=0xD446F7B6 DockNode ID=0x0000000A Parent=0x00000007 SizeRef=1501,310 Selected=0xD446F7B6
DockNode ID=0x00000008 Parent=0x00000002 SizeRef=1501,338 Selected=0xD9F31532 DockNode ID=0x00000008 Parent=0x00000002 SizeRef=1501,338 Selected=0xD9F31532
DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=392,1036 Selected=0xE7039252 DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=392,1036 Selected=0xD3697FB6

View File

@ -0,0 +1,8 @@
- VertexShader: 39210065
FragmentShader: 46377769
SubPass: G-Buffer Write
Properties:
data.color: {x: 1, y: 0.200000003, z: 0.100000001, w: 1}
data.textureIndex: 64651793
data.alpha: 0
data.beta: {x: 1, y: 1, z: 1}

View File

@ -0,0 +1,3 @@
Name: TestMat
ID: 126974645
Type: 7

View File

@ -43,7 +43,7 @@ void main()
{ {
position = In.vertPos; position = In.vertPos;
normals = In.normal; normals = In.normal;
albedo = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) + MatProp.data[In2.materialIndex].color / MatProp.data[In2.materialIndex].alpha; albedo = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv);
outEntityID = In2.eid; outEntityID = In2.eid;
lightLayerIndices = In2.lightLayerIndex; lightLayerIndices = In2.lightLayerIndex;

Binary file not shown.

View File

@ -157,16 +157,22 @@ namespace SHADE
{ {
case AssetType::PREFAB: case AssetType::PREFAB:
newPath += PREFAB_FOLDER; newPath += PREFAB_FOLDER;
newPath += name;
newPath += PREFAB_EXTENSION;
data = new SHPrefabAsset(); data = new SHPrefabAsset();
break; break;
case AssetType::SCENE: case AssetType::SCENE:
newPath += SCENE_FOLDER; newPath += SCENE_FOLDER;
newPath += name;
newPath += SCENE_EXTENSION;
data = new SHSceneAsset(); data = new SHSceneAsset();
break; break;
case AssetType::MATERIAL: case AssetType::MATERIAL:
newPath += MATERIAL_FOLDER; newPath += MATERIAL_FOLDER;
newPath += name;
newPath += MATERIAL_EXTENSION;
data = new SHMaterialAsset(); data = new SHMaterialAsset();
break; break;

View File

@ -5,15 +5,19 @@
#include "Editor/SHImGuiHelpers.hpp" #include "Editor/SHImGuiHelpers.hpp"
#include <imgui.h> #include <imgui.h>
#include <imgui_internal.h> #include <imgui_internal.h>
#include <misc/cpp/imgui_stdlib.h>
#include "Assets/SHAssetManager.h" #include "Assets/SHAssetManager.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/IconsFontAwesome6.h" #include "Editor/IconsFontAwesome6.h"
#include "Editor/SHEditor.h"
#include "Editor/DragDrop/SHDragDrop.hpp" #include "Editor/DragDrop/SHDragDrop.hpp"
#include "Editor/EditorWindow/MaterialInspector/SHMaterialInspector.h"
namespace SHADE namespace SHADE
{ {
SHAssetBrowser::SHAssetBrowser() SHAssetBrowser::SHAssetBrowser()
:SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder) :SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder), assetBeingCreated(std::nullopt)
{ {
} }
@ -53,14 +57,33 @@ namespace SHADE
flags |= ImGuiTreeNodeFlags_Selected; flags |= ImGuiTreeNodeFlags_Selected;
if (folder == rootFolder) if (folder == rootFolder)
flags |= ImGuiTreeNodeFlags_DefaultOpen; flags |= ImGuiTreeNodeFlags_DefaultOpen;
bool isOpen = ImGui::TreeNodeEx(folder, flags, "%s %s", ICON_MD_FOLDER, folder->name.data()); bool isOpen = ImGui::TreeNodeEx(folder, flags, "%s %s", ICON_MD_FOLDER, folder->name.data());
ImGuiID folderID = ImGui::GetItemID();
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
if(ImGui::IsItemClicked())
if (ImGui::BeginPopupContextItem())
{
if (ImGui::BeginMenu("Create Asset"))
{
//TODO: Change to rttr type enum align
if (ImGui::Selectable("Material"))
{
assetBeingCreated = { folder, AssetType::MATERIAL, "New Material" };
ImGui::TreeNodeSetOpen(folderID, true);
isOpen = true;
}
ImGui::EndMenu();
}
ImGui::EndPopup();
}
if (ImGui::IsItemClicked())
{ {
selectedFolders.clear(); selectedFolders.clear();
selectedFolders.push_back(folder); selectedFolders.push_back(folder);
} }
if (isOpen) if (isOpen)
{ {
const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark); const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark);
@ -86,6 +109,9 @@ namespace SHADE
vertLineEnd.y = midPoint; vertLineEnd.y = midPoint;
} }
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1); drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1);
if(assetBeingCreated.has_value() && std::get<0>(assetBeingCreated.value()) == folder)
DrawAssetBeingCreated();
ImGui::TreePop(); ImGui::TreePop();
} }
return nodeRect; return nodeRect;
@ -130,7 +156,7 @@ namespace SHADE
flags |= ImGuiTreeNodeFlags_Selected; flags |= ImGuiTreeNodeFlags_Selected;
std::string icon{}; std::string icon{};
switch(file.assetMeta->type) switch (file.assetMeta->type)
{ {
case AssetType::INVALID: break; case AssetType::INVALID: break;
case AssetType::SHADER: icon = ICON_FA_FILE_CODE; break; case AssetType::SHADER: icon = ICON_FA_FILE_CODE; break;
@ -141,24 +167,64 @@ namespace SHADE
case AssetType::PREFAB: icon = ICON_FA_BOX_OPEN; break; case AssetType::PREFAB: icon = ICON_FA_BOX_OPEN; break;
case AssetType::MATERIAL: break; case AssetType::MATERIAL: break;
case AssetType::MAX_COUNT: break; case AssetType::MAX_COUNT: break;
default: ; default:;
} }
ImGui::TreeNodeEx(file.assetMeta, flags, "%s %s", icon.data(), file.assetMeta->name.data()); ImGui::TreeNodeEx(file.assetMeta, flags, "%s %s", icon.data(), file.assetMeta->name.data());
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
if(SHDragDrop::BeginSource()) if (SHDragDrop::BeginSource())
{ {
auto id = file.assetMeta->id; auto id = file.assetMeta->id;
ImGui::Text("Moving Asset: %s [%zu]", file.name.data(), file.assetMeta->id); ImGui::Text("Moving Asset: %s [%zu]", file.name.data(), file.assetMeta->id);
SHDragDrop::SetPayload<AssetID>(SHDragDrop::DRAG_RESOURCE, &id); SHDragDrop::SetPayload<AssetID>(SHDragDrop::DRAG_RESOURCE, &id);
SHDragDrop::EndSource(); SHDragDrop::EndSource();
} }
if(ImGui::IsItemClicked()) if (ImGui::IsItemClicked())
{ {
selectedAssets.clear(); selectedAssets.clear();
selectedAssets.push_back(file.assetMeta->id); selectedAssets.push_back(file.assetMeta->id);
} }
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
{
switch (file.assetMeta->type)
{
case AssetType::INVALID: break;
case AssetType::SHADER: icon = ICON_FA_FILE_CODE; break;
case AssetType::SHADER_BUILT_IN: icon = ICON_FA_FILE_CODE; break;
case AssetType::TEXTURE: icon = ICON_FA_IMAGES; break;
case AssetType::MESH: icon = ICON_FA_CUBES; break;
case AssetType::SCENE: icon = ICON_MD_IMAGE; break;
case AssetType::PREFAB: icon = ICON_FA_BOX_OPEN; break;
case AssetType::MATERIAL:
if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
{
matInspector->OpenMaterial(file.assetMeta->id);
}
break;
case AssetType::MAX_COUNT: break;
default:;
}
}
ImGui::TreePop(); ImGui::TreePop();
return nodeRect; return nodeRect;
} }
void SHAssetBrowser::DrawAssetBeingCreated() noexcept
{
if (!assetBeingCreated.has_value())
return;
auto& path = std::get<0>(assetBeingCreated.value());
auto& type = std::get<1>(assetBeingCreated.value());
auto& assetName = std::get<2>(assetBeingCreated.value());
if (ImGui::InputText("##newAssetname", &assetName, ImGuiInputTextFlags_EnterReturnsTrue))
{
AssetID assetId = SHAssetManager::CreateNewAsset(type, assetName);
if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
{
matInspector->OpenMaterial(assetId, true);
}
assetBeingCreated.reset();
}
}
} }

View File

@ -10,6 +10,7 @@ namespace SHADE
class SHAssetBrowser final : public SHEditorWindow class SHAssetBrowser final : public SHEditorWindow
{ {
public: public:
using AssetEntry = std::tuple<FolderPointer, AssetType, std::string>;
SHAssetBrowser(); SHAssetBrowser();
void Init(); void Init();
@ -21,11 +22,12 @@ namespace SHADE
ImRect RecursivelyDrawTree(FolderPointer folder); ImRect RecursivelyDrawTree(FolderPointer folder);
void DrawCurrentFolder(); void DrawCurrentFolder();
ImRect DrawFile(SHFile const& file) noexcept; ImRect DrawFile(SHFile const& file) noexcept;
void DrawAssetBeingCreated() noexcept;
FolderPointer rootFolder, prevFolder, currentFolder; FolderPointer rootFolder, prevFolder, currentFolder;
std::optional<AssetEntry> assetBeingCreated;
std::vector<FolderPointer> selectedFolders; std::vector<FolderPointer> selectedFolders;
std::vector<AssetID> selectedAssets; std::vector<AssetID> selectedAssets;
static constexpr float tileWidth = 50.0f; static constexpr float tileWidth = 50.0f;
}; };
} }

View File

@ -349,6 +349,7 @@ namespace SHADE
{ {
DrawContextMenu(component); DrawContextMenu(component);
Handle<SHMesh> const& mesh = component->GetMesh(); Handle<SHMesh> const& mesh = component->GetMesh();
Handle<SHMaterialInstance> const& mat = component->GetMaterial();
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Mesh", std::to_string(SHResourceManager::GetAssetID<SHMesh>(mesh).value_or(0)).data(), [component]() SHEditorWidgets::DragDropReadOnlyField<AssetID>("Mesh", std::to_string(SHResourceManager::GetAssetID<SHMesh>(mesh).value_or(0)).data(), [component]()
{ {
@ -359,6 +360,19 @@ namespace SHADE
{ {
component->SetMesh(SHResourceManager::LoadOrGet<SHMesh>(id)); component->SetMesh(SHResourceManager::LoadOrGet<SHMesh>(id));
}, SHDragDrop::DRAG_RESOURCE); }, SHDragDrop::DRAG_RESOURCE);
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Material", mat ? std::to_string(SHResourceManager::GetAssetID<SHMaterial>(mat->GetBaseMaterial()).value_or(0)).data() : "", [component]()
{
Handle<SHMaterialInstance> const& mat = component->GetMaterial();
if(!mat)
return static_cast<AssetID>(0);
return SHResourceManager::GetAssetID<SHMaterial>(mat->GetBaseMaterial()).value_or(0);
},
[component](AssetID const& id)
{
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
component->SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(SHResourceManager::LoadOrGet<SHMaterial>(id)));
}, SHDragDrop::DRAG_RESOURCE);
} }
else else
{ {

View File

@ -1,9 +1,11 @@
#include "SHpch.h" #include "SHpch.h"
#include "Serialization/SHSerializationHelper.hpp"
#include "SHMaterialInspector.h" #include "SHMaterialInspector.h"
#include "Editor/SHImGuiHelpers.hpp" #include "Editor/SHImGuiHelpers.hpp"
#include <imgui.h> #include <imgui.h>
#include "Assets/SHAssetManager.h" #include "Assets/SHAssetManager.h"
#include "Editor/IconsMaterialDesign.h"
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h" #include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
#include "Editor/SHEditorWidgets.hpp" #include "Editor/SHEditorWidgets.hpp"
#include "Resource/SHResourceManager.h" #include "Resource/SHResourceManager.h"
@ -11,14 +13,24 @@
namespace SHADE namespace SHADE
{ {
SHMaterialInspector::SHMaterialInspector() SHMaterialInspector::SHMaterialInspector()
:SHEditorWindow("Material Inspector", ImGuiWindowFlags_MenuBar), isNewMaterial(false), currentViewedMaterial(0) :SHEditorWindow("Material Inspector", ImGuiWindowFlags_MenuBar), isDirty(false), isNewMaterial(false), currentViewedMaterial(0)
{ {
} }
void SHMaterialInspector::OpenMaterial(AssetID const& assetId) noexcept void SHMaterialInspector::OpenMaterial(AssetID const& assetId, bool isNew) noexcept
{ {
//Get mat data //Get mat data
isNewMaterial = false; if(isDirty)
return;
isDirty = isNew;
isOpen = true;
SetFocusToWindow();
currentViewedMaterial = assetId;
//currentMatSpec = //Get mat spec
currentMatSpec = SHResourceManager::LoadOrGet<SHMaterialSpec>(assetId);
currentMaterial = SHResourceManager::LoadOrGet<SHMaterial>(assetId);
} }
void SHMaterialInspector::Init() void SHMaterialInspector::Init()
@ -30,18 +42,26 @@ namespace SHADE
{ {
SHEditorWindow::Update(); SHEditorWindow::Update();
if(Begin()) if (Begin())
{ {
DrawMenuBar(); if(currentViewedMaterial)
{
DrawMenuBar();
if(SHEditorWidgets::DragDropReadOnlyField<AssetID>("Vertex Shader", std::to_string(currentMatSpec.vertexShader), [&](){return currentMatSpec.vertexShader;}, [&](AssetID const& id){currentMatSpec.vertexShader = id;}, SHDragDrop::DRAG_RESOURCE)) //if (SHEditorWidgets::DragDropReadOnlyField<AssetID>("Vertex Shader", std::to_string(currentMatSpec->vertexShader), [&]() {return currentMatSpec->vertexShader; }, [&](AssetID const& id) {currentMatSpec->vertexShader = id; }, SHDragDrop::DRAG_RESOURCE))
{ //{
vertShaderHandle = SHResourceManager::LoadOrGet<SHVkShaderModule>(currentMatSpec.vertexShader); // isDirty = true;
} // vertShaderHandle = SHResourceManager::LoadOrGet<SHVkShaderModule>(currentMatSpec->vertexShader);
if(SHEditorWidgets::DragDropReadOnlyField<AssetID>("Fragment Shader", std::to_string(currentMatSpec.fragShader), [&](){return currentMatSpec.fragShader;}, [&](AssetID const& id){currentMatSpec.fragShader = id;}, SHDragDrop::DRAG_RESOURCE)) //}
{ //if (SHEditorWidgets::DragDropReadOnlyField<AssetID>("Fragment Shader", std::to_string(currentMatSpec->fragShader), [&]() {return currentMatSpec->fragShader; }, [&](AssetID const& id) {currentMatSpec->fragShader = id; }, SHDragDrop::DRAG_RESOURCE))
fragShaderHandle = SHResourceManager::LoadOrGet<SHVkShaderModule>(currentMatSpec.fragShader); //{
// isDirty = true;
// fragShaderHandle = SHResourceManager::LoadOrGet<SHVkShaderModule>(currentMatSpec->fragShader);
//}
DrawShaderProperties(/*fragShaderHandle*/);
} }
} }
ImGui::End(); ImGui::End();
} }
@ -51,67 +71,187 @@ namespace SHADE
SHEditorWindow::Exit(); SHEditorWindow::Exit();
} }
void SHMaterialInspector::CreateNewMaterial()
{
isNewMaterial = true;
//prompt for a name
currentViewedMaterial = SHAssetManager::CreateNewAsset(AssetType::MATERIAL, "NewMaterial");
currentMatSpec = {};
vertShaderHandle = {};
fragShaderHandle = {};
}
void SHMaterialInspector::DrawMenuBar() void SHMaterialInspector::DrawMenuBar()
{ {
if(ImGui::BeginMenuBar()) if (ImGui::BeginMenuBar())
{ {
ImGui::BeginDisabled(!isDirty);
if(ImGui::Button(std::format("{} Save", ICON_MD_SAVE).data()))
{
//save
if(auto matAsset = SHAssetManager::GetData<SHMaterialAsset>(currentViewedMaterial))
{
YAML::Emitter out;
out << YAML::BeginSeq;
out << YAML::convert<SHMaterialSpec>::encode(*currentMatSpec);
out << YAML::EndSeq;
matAsset->data = out.c_str();
Handle<SHShaderBlockInterface> pipelineProperties = currentMaterial->GetShaderBlockInterface();
for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i)
{
const std::string& PROP_NAME = pipelineProperties->GetVariableName(i);
const YAML::Node& PROP_NODE = currentMatSpec->properties[PROP_NAME.data()];
if (PROP_NODE.IsDefined())
{
const std::string& VAR_NAME = pipelineProperties->GetVariableName(i);
const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i);
switch (VARIABLE->type)
{
case SHADE::SHShaderBlockInterface::Variable::Type::FLOAT:
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<float>());
break;
case SHADE::SHShaderBlockInterface::Variable::Type::INT:
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<int>());
break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec2>());
break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3:
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec3>());
break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4:
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec4>());
break;
case SHADE::SHShaderBlockInterface::Variable::Type::OTHER:
default:
continue;
break;
}
}
}
if(SHAssetManager::SaveAsset(currentViewedMaterial))
{
isDirty = false;
}
}
}
ImGui::EndDisabled();
ImGui::EndMenuBar(); ImGui::EndMenuBar();
} }
} }
void SHMaterialInspector::DrawShaderProperties(Handle<SHVkShaderModule> shaderModule) void SHMaterialInspector::DrawShaderProperties(/*Handle<SHVkShaderModule> shaderModule*/)
{ {
auto interface = shaderModule->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA); /*if(!shaderModule)
return;*/
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
auto interface = gfxSystem->GetDefaultMaterialInstance()->GetBaseMaterial()->GetShaderBlockInterface();
//auto interface = shaderModule->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA);
int const varCount = static_cast<int>(interface->GetVariableCount()); int const varCount = static_cast<int>(interface->GetVariableCount());
for(int i = 0; i < varCount; ++i) for (int i = 0; i < varCount; ++i)
{
auto variable = interface->GetVariable(i);
const std::string& VAR_NAME = interface->GetVariableName(i);
if(VAR_NAME.empty())
continue;
switch (variable->type)
{ {
auto variable = interface->GetVariable(i); case SHShaderBlockInterface::Variable::Type::FLOAT:
const std::string& VAR_NAME = interface->GetVariableName(i); isDirty |= SHEditorWidgets::DragFloat(VAR_NAME,
switch (variable->type) [&]()
{
if (currentMatSpec->properties[VAR_NAME].IsDefined())
return currentMatSpec->properties[VAR_NAME].as<float>();
else
return 0.0f;
},
[&](float const& value)
{
currentMatSpec->properties[VAR_NAME] = value;
}
);
break;
case SHShaderBlockInterface::Variable::Type::INT:
isDirty |= SHEditorWidgets::DragInt(VAR_NAME,
[&]()
{
if (currentMatSpec->properties[VAR_NAME].IsDefined())
return currentMatSpec->properties[VAR_NAME].as<int>();
else
return 0;
},
[&](int const& value)
{
currentMatSpec->properties[VAR_NAME] = value;
}
);
if(SHDragDrop::BeginTarget())
{ {
case SHShaderBlockInterface::Variable::Type::FLOAT: if(AssetID* payload = SHDragDrop::AcceptPayload<AssetID>(SHDragDrop::DRAG_RESOURCE))
SHEditorWidgets::DragFloat(VAR_NAME, [&]() {
{ currentMatSpec->properties[VAR_NAME] = *payload;
if(currentMatSpec.properties[VAR_NAME].IsDefined()) isDirty = true;
return currentMatSpec.properties[VAR_NAME].as<float>(); SHDragDrop::EndTarget();
else }
return 0.0f;
},
[&](float const& value)
{
currentMatSpec.properties[VAR_NAME] = value;
}
);
break;
case SHShaderBlockInterface::Variable::Type::INT:
break;
case SHShaderBlockInterface::Variable::Type::VECTOR2:
break;
case SHShaderBlockInterface::Variable::Type::VECTOR3:
break;
case SHShaderBlockInterface::Variable::Type::VECTOR4:
break;
case SHShaderBlockInterface::Variable::Type::OTHER:
default:
continue;
break;
} }
break;
case SHShaderBlockInterface::Variable::Type::VECTOR2:
isDirty |= SHEditorWidgets::DragVec2(VAR_NAME, { "X", "Y" },
[&]()
{
if (currentMatSpec->properties[VAR_NAME].IsDefined())
return currentMatSpec->properties[VAR_NAME].as<SHVec2>();
else
return SHVec2::Zero;
},
[&](SHVec2 const& value)
{
currentMatSpec->properties[VAR_NAME] = value;
}
);
break;
case SHShaderBlockInterface::Variable::Type::VECTOR3:
isDirty |= SHEditorWidgets::DragVec3(VAR_NAME, { "X", "Y", "Z" },
[&]()
{
if (currentMatSpec->properties[VAR_NAME].IsDefined())
return currentMatSpec->properties[VAR_NAME].as<SHVec3>();
else
return SHVec3::Zero;
},
[&](SHVec3 const& value)
{
currentMatSpec->properties[VAR_NAME] = value;
}
);
break;
case SHShaderBlockInterface::Variable::Type::VECTOR4:
isDirty |= SHEditorWidgets::DragVec4(VAR_NAME, { "X", "Y", "Z", "W" },
[&]()
{
if (currentMatSpec->properties[VAR_NAME].IsDefined())
return currentMatSpec->properties[VAR_NAME].as<SHVec4>();
else
return SHVec4::Zero;
},
[&](SHVec4 const& value)
{
currentMatSpec->properties[VAR_NAME] = value;
}
);
break;
case SHShaderBlockInterface::Variable::Type::OTHER:
isDirty |= SHEditorWidgets::InputText(VAR_NAME,
[&]()
{
if (currentMatSpec->properties[VAR_NAME].IsDefined())
return currentMatSpec->properties[VAR_NAME].as<std::string>();
else
return std::string();
},
[&](std::string const& value)
{
currentMatSpec->properties[VAR_NAME] = value;
}
);
default:
continue;
break;
} }
}
} }
} }

View File

@ -18,15 +18,16 @@ namespace SHADE
void Update() override; void Update() override;
void Exit() override; void Exit() override;
void CreateNewMaterial(); void OpenMaterial(AssetID const& assetId, bool isNew = false) noexcept;
void OpenMaterial(AssetID const& assetId) noexcept;
private: private:
void DrawMenuBar(); void DrawMenuBar();
void DrawShaderProperties(Handle<SHVkShaderModule> shaderModule); void DrawShaderProperties(/*Handle<SHVkShaderModule> shaderModule*/);
bool isDirty;
bool isNewMaterial; bool isNewMaterial;
AssetID currentViewedMaterial; AssetID currentViewedMaterial;
SHMaterialSpec currentMatSpec; Handle<SHMaterialSpec> currentMatSpec;
Handle<SHMaterial> currentMaterial;
Handle<SHVkShaderModule> vertShaderHandle, fragShaderHandle; Handle<SHVkShaderModule> vertShaderHandle, fragShaderHandle;
}; };
} }

View File

@ -19,7 +19,7 @@ namespace SHADE
//|| Public Member Functions || //|| Public Member Functions ||
//#==============================================================# //#==============================================================#
SHEditorWindow::SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags) SHEditorWindow::SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags)
: windowName(name), windowFlags(inFlags), io(ImGui::GetIO()) :isOpen(true), isWindowHovered(false), windowName(name), windowFlags(inFlags), io(ImGui::GetIO())
{ {
} }
@ -68,5 +68,10 @@ namespace SHADE
void SHEditorWindow::OnPosChange() void SHEditorWindow::OnPosChange()
{ {
} }
void SHEditorWindow::SetFocusToWindow()
{
ImGui::SetWindowFocus(windowName.data());
}
}//namespace SHADE }//namespace SHADE

View File

@ -34,6 +34,7 @@ namespace SHADE
virtual bool Begin(); virtual bool Begin();
virtual void OnResize(); virtual void OnResize();
virtual void OnPosChange(); virtual void OnPosChange();
virtual void SetFocusToWindow();
ImGuiWindowFlags windowFlags = 0; ImGuiWindowFlags windowFlags = 0;
ImGuiIO& io; ImGuiIO& io;

View File

@ -1,7 +1,8 @@
#pragma once #pragma once
#include "MenuBar/SHEditorMenuBar.h" //Menu Bar #include "MenuBar/SHEditorMenuBar.h" //Menu Bar
#include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel #include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel
#include "Inspector/SHEditorInspector.h" //Inspector #include "Inspector/SHEditorInspector.h" //Inspector
#include "Profiling/SHEditorProfiler.h" //Profiler #include "Profiling/SHEditorProfiler.h" //Profiler
#include "ViewportWindow/SHEditorViewport.h" //Editor Viewport #include "ViewportWindow/SHEditorViewport.h" //Editor Viewport
#include "AssetBrowser/SHAssetBrowser.h" //Asset Browser #include "AssetBrowser/SHAssetBrowser.h" //Asset Browser
#include "MaterialInspector/SHMaterialInspector.h" //Material Inspector

View File

@ -93,6 +93,8 @@ namespace SHADE
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>(); SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>(); SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
SHEditorWindowManager::CreateEditorWindow<SHAssetBrowser>(); SHEditorWindowManager::CreateEditorWindow<SHAssetBrowser>();
SHEditorWindowManager::CreateEditorWindow<SHMaterialInspector>();
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>(); SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
io = &ImGui::GetIO(); io = &ImGui::GetIO();

View File

@ -422,12 +422,13 @@ namespace SHADE
ImGui::BeginGroup(); ImGui::BeginGroup();
ImGui::PushID(label.data()); ImGui::PushID(label.data());
TextLabel(label); TextLabel(label);
bool const changed = ImGui::InputText("##", &text, ImGuiInputTextFlags_ReadOnly, nullptr, nullptr); bool changed = ImGui::InputText("##", &text, ImGuiInputTextFlags_ReadOnly, nullptr, nullptr);
if(SHDragDrop::BeginTarget()) if(SHDragDrop::BeginTarget())
{ {
if(T* payload = SHDragDrop::AcceptPayload<T>(dragDropTag)) if(T* payload = SHDragDrop::AcceptPayload<T>(dragDropTag))
{ {
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), *payload, set)), false); SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), *payload, set)), false);
changed = true;
SHDragDrop::EndTarget(); SHDragDrop::EndTarget();
} }
} }

View File

@ -34,7 +34,7 @@ namespace SHADE
fShaderMod = shader; fShaderMod = shader;
} }
vertexShader = SHResourceManager::GetAssetID<SHVkShaderModule>(vShaderMod).value_or(0); vertexShader = SHResourceManager::GetAssetID<SHVkShaderModule>(vShaderMod).value_or(0);
fragShader = SHResourceManager::GetAssetID<SHVkShaderModule>(vShaderMod).value_or(0); fragShader = SHResourceManager::GetAssetID<SHVkShaderModule>(fShaderMod).value_or(0);
subpassName = material.GetPipeline()->GetPipelineState().GetSubpass()->GetName(); subpassName = material.GetPipeline()->GetPipelineState().GetSubpass()->GetName();
// Write Properties // Write Properties

View File

@ -46,6 +46,6 @@ namespace SHADE
/* Constructors */ /* Constructors */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHMaterialSpec() = default; SHMaterialSpec() = default;
SHMaterialSpec(const SHMaterial& material); explicit SHMaterialSpec(const SHMaterial& material);
}; };
} }

View File

@ -70,7 +70,7 @@ namespace SHADE
, inputImageDescriptors{ std::move(rhs.inputImageDescriptors) } , inputImageDescriptors{ std::move(rhs.inputImageDescriptors) }
, inputDescriptorLayout{ rhs.inputDescriptorLayout } , inputDescriptorLayout{ rhs.inputDescriptorLayout }
, inputSamplers{ rhs.inputSamplers } , inputSamplers{ rhs.inputSamplers }
, name { rhs.name }
{ {
} }
@ -105,6 +105,7 @@ namespace SHADE
inputImageDescriptors = std::move(rhs.inputImageDescriptors); inputImageDescriptors = std::move(rhs.inputImageDescriptors);
inputDescriptorLayout = rhs.inputDescriptorLayout; inputDescriptorLayout = rhs.inputDescriptorLayout;
inputSamplers = rhs.inputSamplers; inputSamplers = rhs.inputSamplers;
name = std::move(rhs.name);
return *this; return *this;
} }

View File

@ -54,17 +54,7 @@ namespace SHADE
{ {
return variables.size(); return variables.size();
} }
SHShaderBlockInterface::SHShaderBlockInterface(void) noexcept
: bytesRequired{ 0 }
{}
SHShaderBlockInterface::SHShaderBlockInterface(SHShaderBlockInterface&& rhs) noexcept
: variables { std::move(rhs.variables) }
, variableIndexing { std::move(rhs.variableIndexing) }
, bytesRequired { rhs.bytesRequired }
{}
void SHShaderBlockInterface::SetBytesRequired(uint32_t bytes) noexcept void SHShaderBlockInterface::SetBytesRequired(uint32_t bytes) noexcept
{ {
bytesRequired = bytes; bytesRequired = bytes;
@ -75,16 +65,4 @@ namespace SHADE
{ {
return bytesRequired; return bytesRequired;
} }
SHADE::SHShaderBlockInterface& SHShaderBlockInterface::operator=(SHShaderBlockInterface&& rhs) noexcept
{
if (&rhs == this)
return *this;
variables = std::move(rhs.variables);
variableIndexing = std::move(rhs.variableIndexing);
bytesRequired = rhs.bytesRequired;
return *this;
}
} }

View File

@ -33,7 +33,7 @@ namespace SHADE
std::unordered_map<std::string, uint32_t> variableIndexing; std::unordered_map<std::string, uint32_t> variableIndexing;
//! bytes required by the block (includes padding). This variable is required //! bytes required by the block (includes padding). This variable is required
uint32_t bytesRequired; uint32_t bytesRequired = 0;
public: public:
void AddVariable (std::string name, Variable&& newVariable) noexcept; void AddVariable (std::string name, Variable&& newVariable) noexcept;
@ -43,13 +43,6 @@ namespace SHADE
const std::string& GetVariableName(uint32_t index) const noexcept; const std::string& GetVariableName(uint32_t index) const noexcept;
size_t GetVariableCount() const noexcept; size_t GetVariableCount() const noexcept;
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/
SHShaderBlockInterface(void) noexcept;
SHShaderBlockInterface(SHShaderBlockInterface&& rhs) noexcept;
SHShaderBlockInterface& operator=(SHShaderBlockInterface&& rhs) noexcept;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */ /* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/

View File

@ -221,7 +221,14 @@ namespace SHADE
{ {
// Get the data we need to construct // Get the data we need to construct
auto matSpec = resourceHub.Create<SHMaterialSpec>(); auto matSpec = resourceHub.Create<SHMaterialSpec>();
*matSpec = YAML::Node(assetData.data).as<SHMaterialSpec>(); YAML::convert<SHMaterialSpec>::decode(*YAML::Load(assetData.data).begin(), *matSpec);
// Failed to load
if (matSpec->subpassName == "")
{
// Use default material
*matSpec = SHMaterialSpec(*gfxSystem->GetDefaultMaterial());
}
return matSpec; return matSpec;
} }
// Materials // Materials
@ -260,8 +267,8 @@ namespace SHADE
for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i) for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i)
{ {
const std::string& PROP_NAME = pipelineProperties->GetVariableName(i); const std::string& PROP_NAME = pipelineProperties->GetVariableName(i);
const auto& PROP_NODE = assetData.properties; const YAML::Node& PROP_NODE = assetData.properties[PROP_NAME.data()];
if (PROP_NODE) if (PROP_NODE.IsDefined())
{ {
const std::string& VAR_NAME = pipelineProperties->GetVariableName(i); const std::string& VAR_NAME = pipelineProperties->GetVariableName(i);
const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i); const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i);
@ -271,7 +278,18 @@ namespace SHADE
matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as<float>()); matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as<float>());
break; break;
case SHADE::SHShaderBlockInterface::Variable::Type::INT: case SHADE::SHShaderBlockInterface::Variable::Type::INT:
matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as<int>()); {
Handle<SHTexture> texture = LoadOrGet<SHTexture>(PROP_NODE.as<int>());
if (texture)
{
matHandle->SetProperty(VARIABLE->offset, texture->TextureArrayIndex);
}
else
{
SHLOG_WARNING("[] Attempted to load invalid texture! Setting to 0.");
matHandle->SetProperty(VARIABLE->offset, 0);
}
}
break; break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2: case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec2>()); matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec2>());

View File

@ -267,17 +267,17 @@ namespace YAML
static bool decode(YAML::Node const& node, SHMaterialSpec& rhs) static bool decode(YAML::Node const& node, SHMaterialSpec& rhs)
{ {
// Retrieve Shader Asset IDs // Retrieve Shader Asset IDs
if (node[VERT_SHADER_YAML_TAG.data()]) if (node[VERT_SHADER_YAML_TAG.data()].IsDefined())
rhs.vertexShader = node[VERT_SHADER_YAML_TAG.data()].as<AssetID>(); rhs.vertexShader = node[VERT_SHADER_YAML_TAG.data()].as<AssetID>();
if (node[FRAG_SHADER_YAML_TAG.data()]) if (node[FRAG_SHADER_YAML_TAG.data()].IsDefined())
rhs.fragShader = node[FRAG_SHADER_YAML_TAG.data()].as<AssetID>(); rhs.fragShader = node[FRAG_SHADER_YAML_TAG.data()].as<AssetID>();
// Retrieve Subpass // Retrieve Subpass
if (node[SUBPASS_YAML_TAG.data()]) if (node[SUBPASS_YAML_TAG.data()].IsDefined())
rhs.subpassName = node[SUBPASS_YAML_TAG.data()].as<std::string>(); rhs.subpassName = node[SUBPASS_YAML_TAG.data()].as<std::string>();
// Retrieve // Retrieve
if (node[PROPS_YAML_TAG.data()]) if (node[PROPS_YAML_TAG.data()].IsDefined())
rhs.properties = node[PROPS_YAML_TAG.data()]; rhs.properties = node[PROPS_YAML_TAG.data()];
return true; return true;