Merge pull request #168 from SHADE-DP/SP3-4-Editor
Added material inspector and setting of materials Fixed imgui breaking in release Added material inspector Allow setting of materials to renderable component
This commit is contained in:
commit
4b09f42adc
|
@ -1,16 +1,16 @@
|
|||
[Window][MainStatusBar]
|
||||
Pos=0,1060
|
||||
Pos=0,1007
|
||||
Size=1920,20
|
||||
Collapsed=0
|
||||
|
||||
[Window][SHEditorMenuBar]
|
||||
Pos=0,48
|
||||
Size=1920,1012
|
||||
Size=1920,959
|
||||
Collapsed=0
|
||||
|
||||
[Window][Hierarchy Panel]
|
||||
Pos=0,197
|
||||
Size=308,863
|
||||
Pos=0,189
|
||||
Size=308,818
|
||||
Collapsed=0
|
||||
DockId=0x00000004,0
|
||||
|
||||
|
@ -21,13 +21,13 @@ Collapsed=0
|
|||
|
||||
[Window][Inspector]
|
||||
Pos=1528,48
|
||||
Size=392,1012
|
||||
Size=392,959
|
||||
Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
[Window][Profiler]
|
||||
Pos=0,48
|
||||
Size=308,147
|
||||
Size=308,139
|
||||
Collapsed=0
|
||||
DockId=0x00000003,0
|
||||
|
||||
|
@ -76,7 +76,7 @@ DockId=0x0000000B,0
|
|||
|
||||
[Window][ Viewport]
|
||||
Pos=310,48
|
||||
Size=1216,715
|
||||
Size=1216,662
|
||||
Collapsed=0
|
||||
DockId=0x0000000B,0
|
||||
|
||||
|
@ -93,13 +93,19 @@ Collapsed=0
|
|||
DockId=0x0000000A,0
|
||||
|
||||
[Window][ Asset Browser]
|
||||
Pos=310,765
|
||||
Pos=310,712
|
||||
Size=1216,295
|
||||
Collapsed=0
|
||||
DockId=0x0000000C,0
|
||||
|
||||
[Window][Material Inspector]
|
||||
Pos=1528,48
|
||||
Size=392,959
|
||||
Collapsed=0
|
||||
DockId=0x00000006,1
|
||||
|
||||
[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=0x00000001 Parent=0x00000005 SizeRef=308,1036 Split=Y 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=0x0000000A Parent=0x00000007 SizeRef=1501,310 Selected=0xD446F7B6
|
||||
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
|
||||
|
||||
|
|
|
@ -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}
|
|
@ -0,0 +1,3 @@
|
|||
Name: TestMat
|
||||
ID: 126974645
|
||||
Type: 7
|
|
@ -43,7 +43,7 @@ void main()
|
|||
{
|
||||
position = In.vertPos;
|
||||
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;
|
||||
lightLayerIndices = In2.lightLayerIndex;
|
||||
|
|
Binary file not shown.
|
@ -157,16 +157,22 @@ namespace SHADE
|
|||
{
|
||||
case AssetType::PREFAB:
|
||||
newPath += PREFAB_FOLDER;
|
||||
newPath += name;
|
||||
newPath += PREFAB_EXTENSION;
|
||||
data = new SHPrefabAsset();
|
||||
break;
|
||||
|
||||
case AssetType::SCENE:
|
||||
newPath += SCENE_FOLDER;
|
||||
newPath += name;
|
||||
newPath += SCENE_EXTENSION;
|
||||
data = new SHSceneAsset();
|
||||
break;
|
||||
|
||||
case AssetType::MATERIAL:
|
||||
newPath += MATERIAL_FOLDER;
|
||||
newPath += name;
|
||||
newPath += MATERIAL_EXTENSION;
|
||||
data = new SHMaterialAsset();
|
||||
break;
|
||||
|
||||
|
|
|
@ -5,15 +5,19 @@
|
|||
#include "Editor/SHImGuiHelpers.hpp"
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
#include <misc/cpp/imgui_stdlib.h>
|
||||
|
||||
#include "Assets/SHAssetManager.h"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Editor/IconsFontAwesome6.h"
|
||||
#include "Editor/SHEditor.h"
|
||||
#include "Editor/DragDrop/SHDragDrop.hpp"
|
||||
#include "Editor/EditorWindow/MaterialInspector/SHMaterialInspector.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
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;
|
||||
if (folder == rootFolder)
|
||||
flags |= ImGuiTreeNodeFlags_DefaultOpen;
|
||||
|
||||
|
||||
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());
|
||||
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.push_back(folder);
|
||||
}
|
||||
|
||||
if (isOpen)
|
||||
{
|
||||
const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark);
|
||||
|
@ -86,6 +109,9 @@ namespace SHADE
|
|||
vertLineEnd.y = midPoint;
|
||||
}
|
||||
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1);
|
||||
if(assetBeingCreated.has_value() && std::get<0>(assetBeingCreated.value()) == folder)
|
||||
DrawAssetBeingCreated();
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
return nodeRect;
|
||||
|
@ -130,7 +156,7 @@ namespace SHADE
|
|||
flags |= ImGuiTreeNodeFlags_Selected;
|
||||
std::string icon{};
|
||||
|
||||
switch(file.assetMeta->type)
|
||||
switch (file.assetMeta->type)
|
||||
{
|
||||
case AssetType::INVALID: 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::MATERIAL: break;
|
||||
case AssetType::MAX_COUNT: break;
|
||||
default: ;
|
||||
default:;
|
||||
}
|
||||
|
||||
ImGui::TreeNodeEx(file.assetMeta, flags, "%s %s", icon.data(), file.assetMeta->name.data());
|
||||
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||
if(SHDragDrop::BeginSource())
|
||||
if (SHDragDrop::BeginSource())
|
||||
{
|
||||
auto id = file.assetMeta->id;
|
||||
ImGui::Text("Moving Asset: %s [%zu]", file.name.data(), file.assetMeta->id);
|
||||
SHDragDrop::SetPayload<AssetID>(SHDragDrop::DRAG_RESOURCE, &id);
|
||||
SHDragDrop::EndSource();
|
||||
}
|
||||
if(ImGui::IsItemClicked())
|
||||
if (ImGui::IsItemClicked())
|
||||
{
|
||||
selectedAssets.clear();
|
||||
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();
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace SHADE
|
|||
class SHAssetBrowser final : public SHEditorWindow
|
||||
{
|
||||
public:
|
||||
using AssetEntry = std::tuple<FolderPointer, AssetType, std::string>;
|
||||
SHAssetBrowser();
|
||||
|
||||
void Init();
|
||||
|
@ -21,11 +22,12 @@ namespace SHADE
|
|||
ImRect RecursivelyDrawTree(FolderPointer folder);
|
||||
void DrawCurrentFolder();
|
||||
ImRect DrawFile(SHFile const& file) noexcept;
|
||||
void DrawAssetBeingCreated() noexcept;
|
||||
|
||||
FolderPointer rootFolder, prevFolder, currentFolder;
|
||||
std::optional<AssetEntry> assetBeingCreated;
|
||||
std::vector<FolderPointer> selectedFolders;
|
||||
std::vector<AssetID> selectedAssets;
|
||||
static constexpr float tileWidth = 50.0f;
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -376,6 +376,7 @@ namespace SHADE
|
|||
{
|
||||
DrawContextMenu(component);
|
||||
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]()
|
||||
{
|
||||
|
@ -387,6 +388,19 @@ namespace SHADE
|
|||
component->SetMesh(SHResourceManager::LoadOrGet<SHMesh>(id));
|
||||
SHResourceManager::FinaliseChanges();
|
||||
}, 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
|
||||
{
|
||||
|
|
|
@ -0,0 +1,257 @@
|
|||
#include "SHpch.h"
|
||||
#include "Serialization/SHSerializationHelper.hpp"
|
||||
#include "SHMaterialInspector.h"
|
||||
#include "Editor/SHImGuiHelpers.hpp"
|
||||
#include <imgui.h>
|
||||
|
||||
#include "Assets/SHAssetManager.h"
|
||||
#include "Editor/IconsMaterialDesign.h"
|
||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||
#include "Editor/SHEditorWidgets.hpp"
|
||||
#include "Resource/SHResourceManager.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
SHMaterialInspector::SHMaterialInspector()
|
||||
:SHEditorWindow("Material Inspector", ImGuiWindowFlags_MenuBar), isDirty(false), isNewMaterial(false), currentViewedMaterial(0)
|
||||
{
|
||||
}
|
||||
|
||||
void SHMaterialInspector::OpenMaterial(AssetID const& assetId, bool isNew) noexcept
|
||||
{
|
||||
//Get mat data
|
||||
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()
|
||||
{
|
||||
SHEditorWindow::Init();
|
||||
}
|
||||
|
||||
void SHMaterialInspector::Update()
|
||||
{
|
||||
SHEditorWindow::Update();
|
||||
|
||||
if (Begin())
|
||||
{
|
||||
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))
|
||||
//{
|
||||
// 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))
|
||||
//{
|
||||
// isDirty = true;
|
||||
// fragShaderHandle = SHResourceManager::LoadOrGet<SHVkShaderModule>(currentMatSpec->fragShader);
|
||||
//}
|
||||
|
||||
DrawShaderProperties(/*fragShaderHandle*/);
|
||||
}
|
||||
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void SHMaterialInspector::Exit()
|
||||
{
|
||||
SHEditorWindow::Exit();
|
||||
}
|
||||
|
||||
void SHMaterialInspector::DrawMenuBar()
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
void SHMaterialInspector::DrawShaderProperties(/*Handle<SHVkShaderModule> shaderModule*/)
|
||||
{
|
||||
/*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());
|
||||
|
||||
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)
|
||||
{
|
||||
case SHShaderBlockInterface::Variable::Type::FLOAT:
|
||||
isDirty |= SHEditorWidgets::DragFloat(VAR_NAME,
|
||||
[&]()
|
||||
{
|
||||
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())
|
||||
{
|
||||
if(AssetID* payload = SHDragDrop::AcceptPayload<AssetID>(SHDragDrop::DRAG_RESOURCE))
|
||||
{
|
||||
currentMatSpec->properties[VAR_NAME] = *payload;
|
||||
isDirty = true;
|
||||
SHDragDrop::EndTarget();
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
#include "Assets/SHAssetMacros.h"
|
||||
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||
#include "Resource/SHHandle.h"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHMaterialInspector final : public SHEditorWindow
|
||||
{
|
||||
public:
|
||||
SHMaterialInspector();
|
||||
~SHMaterialInspector() = default;
|
||||
|
||||
void Init() override;
|
||||
void Update() override;
|
||||
void Exit() override;
|
||||
|
||||
void OpenMaterial(AssetID const& assetId, bool isNew = false) noexcept;
|
||||
private:
|
||||
void DrawMenuBar();
|
||||
void DrawShaderProperties(/*Handle<SHVkShaderModule> shaderModule*/);
|
||||
|
||||
bool isDirty;
|
||||
bool isNewMaterial;
|
||||
AssetID currentViewedMaterial;
|
||||
Handle<SHMaterialSpec> currentMatSpec;
|
||||
Handle<SHMaterial> currentMaterial;
|
||||
Handle<SHVkShaderModule> vertShaderHandle, fragShaderHandle;
|
||||
};
|
||||
}
|
|
@ -19,7 +19,7 @@ namespace SHADE
|
|||
//|| Public Member Functions ||
|
||||
//#==============================================================#
|
||||
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::SetFocusToWindow()
|
||||
{
|
||||
ImGui::SetWindowFocus(windowName.data());
|
||||
}
|
||||
}//namespace SHADE
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace SHADE
|
|||
virtual bool Begin();
|
||||
virtual void OnResize();
|
||||
virtual void OnPosChange();
|
||||
virtual void SetFocusToWindow();
|
||||
|
||||
ImGuiWindowFlags windowFlags = 0;
|
||||
ImGuiIO& io;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#pragma once
|
||||
#include "MenuBar/SHEditorMenuBar.h" //Menu Bar
|
||||
#include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel
|
||||
#include "Inspector/SHEditorInspector.h" //Inspector
|
||||
#include "Profiling/SHEditorProfiler.h" //Profiler
|
||||
#include "ViewportWindow/SHEditorViewport.h" //Editor Viewport
|
||||
#include "AssetBrowser/SHAssetBrowser.h" //Asset Browser
|
||||
#include "MenuBar/SHEditorMenuBar.h" //Menu Bar
|
||||
#include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel
|
||||
#include "Inspector/SHEditorInspector.h" //Inspector
|
||||
#include "Profiling/SHEditorProfiler.h" //Profiler
|
||||
#include "ViewportWindow/SHEditorViewport.h" //Editor Viewport
|
||||
#include "AssetBrowser/SHAssetBrowser.h" //Asset Browser
|
||||
#include "MaterialInspector/SHMaterialInspector.h" //Material Inspector
|
|
@ -93,6 +93,8 @@ namespace SHADE
|
|||
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
|
||||
SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
|
||||
SHEditorWindowManager::CreateEditorWindow<SHAssetBrowser>();
|
||||
SHEditorWindowManager::CreateEditorWindow<SHMaterialInspector>();
|
||||
|
||||
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
|
||||
|
||||
io = &ImGui::GetIO();
|
||||
|
|
|
@ -422,12 +422,13 @@ namespace SHADE
|
|||
ImGui::BeginGroup();
|
||||
ImGui::PushID(label.data());
|
||||
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(T* payload = SHDragDrop::AcceptPayload<T>(dragDropTag))
|
||||
{
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), *payload, set)), false);
|
||||
changed = true;
|
||||
SHDragDrop::EndTarget();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -743,6 +743,11 @@ namespace SHADE
|
|||
graphicsTexCmdBuffer.Free(); graphicsTexCmdBuffer = {};
|
||||
}
|
||||
|
||||
Handle<SHTexture> SHGraphicsSystem::GetTextureHandle(SHTexture::Index textureId) const
|
||||
{
|
||||
return texLibrary.GetTextureHandle(textureId);
|
||||
}
|
||||
|
||||
#pragma endregion ADD_REMOVE
|
||||
|
||||
#pragma region ROUTINES
|
||||
|
|
|
@ -263,6 +263,21 @@ namespace SHADE
|
|||
*/
|
||||
/***************************************************************************/
|
||||
void BuildTextures();
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
*
|
||||
\brief
|
||||
Retrieves the texture handle at the specified texture index.
|
||||
|
||||
\param textureId
|
||||
Index of the texture to look for.
|
||||
|
||||
\returns
|
||||
Handle to the texture
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
Handle<SHTexture> GetTextureHandle(SHTexture::Index textureId) const;
|
||||
|
||||
void PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept;
|
||||
void HandleResize(void) noexcept;
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/************************************************************************************//*!
|
||||
\file SHMaterialSpec.cpp
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Nov 2, 2022
|
||||
\brief Contains the function definitions of SHMaterialSpec.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
#include "SHpch.h"
|
||||
#include "SHMaterialSpec.h"
|
||||
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||
#include "Resource/SHResourceManager.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHMaterialSpec::SHMaterialSpec(const SHMaterial& material)
|
||||
{
|
||||
// Get Shader Handles
|
||||
const auto& SHADERS = material.GetPipeline()->GetPipelineLayout()->GetShaderModules();
|
||||
Handle<SHVkShaderModule> vShaderMod, fShaderMod;
|
||||
for (const auto& shader : SHADERS)
|
||||
{
|
||||
const auto FLAG_BITS = shader->GetShaderStageFlagBits();
|
||||
if (FLAG_BITS & vk::ShaderStageFlagBits::eVertex)
|
||||
vShaderMod = shader;
|
||||
else if (FLAG_BITS & vk::ShaderStageFlagBits::eFragment)
|
||||
fShaderMod = shader;
|
||||
}
|
||||
vertexShader = SHResourceManager::GetAssetID<SHVkShaderModule>(vShaderMod).value_or(0);
|
||||
fragShader = SHResourceManager::GetAssetID<SHVkShaderModule>(fShaderMod).value_or(0);
|
||||
subpassName = material.GetPipeline()->GetPipelineState().GetSubpass()->GetName();
|
||||
|
||||
// Write Properties
|
||||
Handle<SHShaderBlockInterface> pipelineProperties = material.GetShaderBlockInterface();
|
||||
for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i)
|
||||
{
|
||||
const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i);
|
||||
if (!VARIABLE)
|
||||
break;
|
||||
const std::string& VAR_NAME = pipelineProperties->GetVariableName(i);
|
||||
YAML::Node propNode;
|
||||
switch (VARIABLE->type)
|
||||
{
|
||||
case SHADE::SHShaderBlockInterface::Variable::Type::FLOAT:
|
||||
propNode = material.GetProperty<float>(VARIABLE->offset);
|
||||
break;
|
||||
case SHADE::SHShaderBlockInterface::Variable::Type::INT:
|
||||
propNode = material.GetProperty<int>(VARIABLE->offset);
|
||||
break;
|
||||
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
|
||||
propNode = material.GetProperty<SHVec2>(VARIABLE->offset);
|
||||
break;
|
||||
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3:
|
||||
propNode = material.GetProperty<SHVec3>(VARIABLE->offset);
|
||||
break;
|
||||
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4:
|
||||
propNode = material.GetProperty<SHVec4>(VARIABLE->offset);
|
||||
break;
|
||||
case SHADE::SHShaderBlockInterface::Variable::Type::OTHER:
|
||||
default:
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
properties[VAR_NAME.data()] = propNode;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,9 +16,18 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include <utility>
|
||||
// Project Includes
|
||||
#include "Assets/SHAssetMacros.h"
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Forward Declaration */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
class SHMaterial;
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/*************************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
|
@ -32,5 +41,11 @@ namespace SHADE
|
|||
AssetID fragShader;
|
||||
std::string subpassName;
|
||||
YAML::Node properties;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
SHMaterialSpec() = default;
|
||||
explicit SHMaterialSpec(const SHMaterial& material);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -129,6 +129,21 @@ namespace SHADE
|
|||
/* Getter Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
Handle<SHVkDescriptorSetGroup> GetTextureDescriptorSetGroup() const noexcept { return texDescriptors; }
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
*
|
||||
\brief
|
||||
Retrieves the texture handle at the specified texture index.
|
||||
|
||||
\param textureId
|
||||
Index of the texture to look for.
|
||||
|
||||
\returns
|
||||
Handle to the texture
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
Handle<SHTexture> GetTextureHandle(SHTexture::Index textureId) const { return texOrder[textureId]; };
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -70,7 +70,7 @@ namespace SHADE
|
|||
, inputImageDescriptors{ std::move(rhs.inputImageDescriptors) }
|
||||
, inputDescriptorLayout{ rhs.inputDescriptorLayout }
|
||||
, inputSamplers{ rhs.inputSamplers }
|
||||
|
||||
, name { rhs.name }
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -105,6 +105,7 @@ namespace SHADE
|
|||
inputImageDescriptors = std::move(rhs.inputImageDescriptors);
|
||||
inputDescriptorLayout = rhs.inputDescriptorLayout;
|
||||
inputSamplers = rhs.inputSamplers;
|
||||
name = std::move(rhs.name);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
|
@ -54,17 +54,7 @@ namespace SHADE
|
|||
{
|
||||
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
|
||||
{
|
||||
bytesRequired = bytes;
|
||||
|
@ -75,16 +65,4 @@ namespace SHADE
|
|||
{
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -33,7 +33,7 @@ namespace SHADE
|
|||
std::unordered_map<std::string, uint32_t> variableIndexing;
|
||||
|
||||
//! bytes required by the block (includes padding). This variable is required
|
||||
uint32_t bytesRequired;
|
||||
uint32_t bytesRequired = 0;
|
||||
|
||||
public:
|
||||
void AddVariable (std::string name, Variable&& newVariable) noexcept;
|
||||
|
@ -43,13 +43,6 @@ namespace SHADE
|
|||
const std::string& GetVariableName(uint32_t index) 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 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
|
|
@ -13,6 +13,8 @@ of DigiPen Institute of Technology is prohibited.
|
|||
|
||||
// STL Includes
|
||||
#include <unordered_map>
|
||||
|
||||
namespace SHADE { class SHMaterial; }
|
||||
// Project Includes
|
||||
#include "SH_API.h"
|
||||
#include "SHResourceLibrary.h"
|
||||
|
@ -24,6 +26,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||
#include "Assets/Asset Types/SHMaterialAsset.h"
|
||||
|
||||
namespace SHADE
|
||||
|
@ -36,9 +39,9 @@ namespace SHADE
|
|||
template<> struct SHResourceLoader<SHMesh> { using AssetType = SHMeshAsset; };
|
||||
template<> struct SHResourceLoader<SHTexture> { using AssetType = SHTextureAsset; };
|
||||
template<> struct SHResourceLoader<SHVkShaderModule> { using AssetType = SHShaderAsset; };
|
||||
template<> struct SHResourceLoader<SHMaterial> { using AssetType = SHMaterialAsset; };
|
||||
|
||||
/// <summary>
|
||||
template<> struct SHResourceLoader<SHMaterialSpec> { using AssetType = SHMaterialAsset; };
|
||||
template<> struct SHResourceLoader<SHMaterial> { using AssetType = SHMaterialSpec; };
|
||||
/// <summary>
|
||||
/// Static class responsible for loading and caching runtime resources from their
|
||||
/// serialised Asset IDs.
|
||||
/// </summary>
|
||||
|
@ -61,6 +64,8 @@ namespace SHADE
|
|||
/// <returns>Handle to a loaded runtime asset.</returns>
|
||||
template<typename ResourceType>
|
||||
static Handle<ResourceType> LoadOrGet(AssetID assetId);
|
||||
template<>
|
||||
static inline Handle<SHMaterial> LoadOrGet<SHMaterial>(AssetID assetId);
|
||||
/// <summary>
|
||||
/// Unloads an existing loaded asset. Attempting to unload an invalid Handle will
|
||||
/// simply do nothing except emit a warning.
|
||||
|
|
|
@ -24,6 +24,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||
#include "Serialization/SHSerializationHelper.hpp"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -34,7 +35,12 @@ namespace SHADE
|
|||
Handle<ResourceType> SHResourceManager::LoadOrGet(AssetID assetId)
|
||||
{
|
||||
// Check if it is an unsupported type
|
||||
if (!std::is_same_v<ResourceType, SHMesh> && !std::is_same_v<ResourceType, SHTexture>)
|
||||
if (!std::is_same_v<ResourceType, SHMesh> &&
|
||||
!std::is_same_v<ResourceType, SHTexture> &&
|
||||
!std::is_same_v<ResourceType, SHVkShaderModule> &&
|
||||
!std::is_same_v<ResourceType, SHMaterialSpec> &&
|
||||
!std::is_same_v<ResourceType, SHMaterial>
|
||||
)
|
||||
{
|
||||
static_assert(true, "Unsupported Resource Type specified for SHResourceManager.");
|
||||
}
|
||||
|
@ -60,8 +66,35 @@ namespace SHADE
|
|||
return handle;
|
||||
}
|
||||
|
||||
template<>
|
||||
Handle<SHMaterial> SHResourceManager::LoadOrGet<SHMaterial>(AssetID assetId)
|
||||
{
|
||||
/* Attempt to get existing loaded asset */
|
||||
auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap<SHMaterial>();
|
||||
if (typedHandleMap.get().contains(assetId))
|
||||
return Handle<SHMaterial>(typedHandleMap.get()[assetId]);
|
||||
|
||||
/* Otherwise, we need to load it! */
|
||||
// Get system
|
||||
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||
if (gfxSystem == nullptr)
|
||||
throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed.");
|
||||
|
||||
// Get SHMaterialSpec
|
||||
Handle<SHMaterialSpec> matSpec = LoadOrGet<SHMaterialSpec>(assetId);
|
||||
if (!matSpec)
|
||||
return {};
|
||||
|
||||
// Create the material
|
||||
auto handle = load<SHMaterial>(assetId, *matSpec);
|
||||
Handle genericHandle = Handle(handle);
|
||||
typedHandleMap.get().emplace(assetId, genericHandle);
|
||||
typedAssetIdMap.get().emplace(genericHandle, assetId);
|
||||
return handle;
|
||||
}
|
||||
|
||||
template<typename ResourceType>
|
||||
void SHResourceManager::Unload(Handle<ResourceType> assetId)
|
||||
void SHResourceManager::Unload(Handle<ResourceType> asset)
|
||||
{
|
||||
// Check if it is an unsupported type
|
||||
if (!std::is_same_v<ResourceType, SHMesh> && !std::is_same_v<ResourceType, SHTexture>)
|
||||
|
@ -71,14 +104,18 @@ namespace SHADE
|
|||
|
||||
/* Attempt to get existing loaded asset */
|
||||
auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap<ResourceType>();
|
||||
if (typedHandleMap.get().contains(assetId))
|
||||
if (typedHandleMap.get().contains(asset))
|
||||
{
|
||||
// Remove from ResourceHub if SHMaterialSpec
|
||||
if (std::is_same_v<ResourceType, SHMaterialSpec>)
|
||||
resourceHub.Free(asset);
|
||||
|
||||
// Dispose
|
||||
Handle handle = typedHandleMap.get()[assetId];
|
||||
Handle<ResourceType> typedHandle = static_cast<Handle<ResourceType>>(handle);
|
||||
Handle handle = typedHandleMap.get()[asset];
|
||||
auto typedHandle = static_cast<Handle<ResourceType>>(handle);
|
||||
typedHandle.Free();
|
||||
typedAssetIdMap.get().erase(handle);
|
||||
typedHandleMap.get().erase(assetId);
|
||||
typedHandleMap.get().erase(asset);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -181,15 +218,27 @@ namespace SHADE
|
|||
shader->Reflect();
|
||||
return shader;
|
||||
}
|
||||
// Material Spec
|
||||
else if constexpr (std::is_same_v<ResourceType, SHMaterialSpec>)
|
||||
{
|
||||
// Get the data we need to construct
|
||||
auto matSpec = resourceHub.Create<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;
|
||||
}
|
||||
// Materials
|
||||
else if constexpr (std::is_same_v<ResourceType, SHMaterial>)
|
||||
{
|
||||
// Get the data we need to construct
|
||||
SHMaterialSpec matSpec = YAML::Node(assetData.data).as<SHMaterialSpec>();
|
||||
|
||||
// Load shaders
|
||||
auto vertexShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(matSpec.vertexShader);
|
||||
auto fragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(matSpec.fragShader);
|
||||
auto vertexShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(assetData.vertexShader);
|
||||
auto fragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(assetData.fragShader);
|
||||
|
||||
// Ensure that both shaders are present
|
||||
if (!(vertexShader && fragShader))
|
||||
|
@ -205,7 +254,7 @@ namespace SHADE
|
|||
SHLOG_ERROR("[SHResourceManager] Failed to load material as RenderPass could not be found.");
|
||||
return {};
|
||||
}
|
||||
auto subPass = renderPass->GetSubpass(matSpec.subpassName);
|
||||
auto subPass = renderPass->GetSubpass(assetData.subpassName);
|
||||
if (!subPass)
|
||||
{
|
||||
SHLOG_ERROR("[SHResourceManager] Failed to load material as SubPass could not be found.");
|
||||
|
@ -220,8 +269,8 @@ namespace SHADE
|
|||
for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i)
|
||||
{
|
||||
const std::string& PROP_NAME = pipelineProperties->GetVariableName(i);
|
||||
const auto& PROP_NODE = matSpec.properties;
|
||||
if (PROP_NODE)
|
||||
const YAML::Node& PROP_NODE = assetData.properties[PROP_NAME.data()];
|
||||
if (PROP_NODE.IsDefined())
|
||||
{
|
||||
const std::string& VAR_NAME = pipelineProperties->GetVariableName(i);
|
||||
const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i);
|
||||
|
@ -231,7 +280,18 @@ namespace SHADE
|
|||
matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as<float>());
|
||||
break;
|
||||
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;
|
||||
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
|
||||
matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec2>());
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
namespace YAML
|
||||
{
|
||||
using namespace SHADE;
|
||||
using namespace SHADE;
|
||||
|
||||
template<>
|
||||
template<>
|
||||
struct convert<SHVec4>
|
||||
{
|
||||
static constexpr const char* x = "x";
|
||||
|
@ -172,17 +172,17 @@ namespace YAML
|
|||
switch (colliderType)
|
||||
{
|
||||
case SHCollider::Type::BOX:
|
||||
{
|
||||
if(node[HalfExtents].IsDefined())
|
||||
rhs.SetBoundingBox(node[HalfExtents].as<SHVec3>());
|
||||
}
|
||||
break;
|
||||
{
|
||||
if (node[HalfExtents].IsDefined())
|
||||
rhs.SetBoundingBox(node[HalfExtents].as<SHVec3>());
|
||||
}
|
||||
break;
|
||||
case SHCollider::Type::SPHERE:
|
||||
{
|
||||
if(node[Radius].IsDefined())
|
||||
rhs.SetBoundingSphere(node[Radius].as<float>());
|
||||
}
|
||||
break;
|
||||
{
|
||||
if (node[Radius].IsDefined())
|
||||
rhs.SetBoundingSphere(node[Radius].as<float>());
|
||||
}
|
||||
break;
|
||||
case SHCollider::Type::CAPSULE: break;
|
||||
default:;
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ namespace YAML
|
|||
rhs.SetDensity(node[Density].as<float>());
|
||||
if (node[PositionOffset].IsDefined())
|
||||
rhs.SetPositionOffset(node[PositionOffset].as<SHVec3>());
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -231,7 +231,7 @@ namespace YAML
|
|||
const SHCollider::Type colliderType = enumAlign.name_to_value(colliderNode[convert<SHCollider>::Type].as<std::string>()).convert<SHCollider::Type>(&ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
|
||||
switch (colliderType)
|
||||
{
|
||||
case SHCollider::Type::BOX: rhs.AddBoundingBox(); break;
|
||||
|
@ -246,143 +246,80 @@ namespace YAML
|
|||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct convert<SHMaterial>
|
||||
template<>
|
||||
struct convert<SHMaterialSpec>
|
||||
{
|
||||
static constexpr std::string_view VERT_SHADER_YAML_TAG = "VertexShader";
|
||||
static constexpr std::string_view FRAG_SHADER_YAML_TAG = "FragmentShader";
|
||||
static constexpr std::string_view SUBPASS_YAML_TAG = "SubPass";
|
||||
static constexpr std::string_view PROPS_YAML_TAG = "Properties";
|
||||
|
||||
static YAML::Node encode(SHMaterialSpec const& rhs)
|
||||
{
|
||||
static constexpr std::string_view VERT_SHADER_YAML_TAG = "VertexShader";
|
||||
static constexpr std::string_view FRAG_SHADER_YAML_TAG = "FragmentShader";
|
||||
static constexpr std::string_view SUBPASS_YAML_TAG = "SubPass";
|
||||
static constexpr std::string_view PROPS_YAML_TAG = "Properties";
|
||||
YAML::Node node;
|
||||
node[VERT_SHADER_YAML_TAG.data()] = rhs.vertexShader;
|
||||
node[FRAG_SHADER_YAML_TAG.data()] = rhs.fragShader;
|
||||
node[SUBPASS_YAML_TAG.data()] = rhs.subpassName;
|
||||
node[PROPS_YAML_TAG.data()] = rhs.properties;
|
||||
return node;
|
||||
}
|
||||
|
||||
static YAML::Node encode(SHMaterial const& rhs)
|
||||
{
|
||||
// Write Properties
|
||||
YAML::Node propertiesNode;
|
||||
Handle<SHShaderBlockInterface> pipelineProperties = rhs.GetShaderBlockInterface();
|
||||
for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i)
|
||||
{
|
||||
const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i);
|
||||
if (!VARIABLE)
|
||||
break;
|
||||
const std::string& VAR_NAME = pipelineProperties->GetVariableName(i);
|
||||
YAML::Node propNode;
|
||||
switch (VARIABLE->type)
|
||||
{
|
||||
case SHADE::SHShaderBlockInterface::Variable::Type::FLOAT:
|
||||
propNode = rhs.GetProperty<float>(VARIABLE->offset);
|
||||
break;
|
||||
case SHADE::SHShaderBlockInterface::Variable::Type::INT:
|
||||
propNode = rhs.GetProperty<int>(VARIABLE->offset);
|
||||
break;
|
||||
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
|
||||
propNode = rhs.GetProperty<SHVec2>(VARIABLE->offset);
|
||||
break;
|
||||
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3:
|
||||
propNode = rhs.GetProperty<SHVec3>(VARIABLE->offset);
|
||||
break;
|
||||
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4:
|
||||
propNode = rhs.GetProperty<SHVec4>(VARIABLE->offset);
|
||||
break;
|
||||
case SHADE::SHShaderBlockInterface::Variable::Type::OTHER:
|
||||
default:
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
propertiesNode[VAR_NAME.data()] = propNode;
|
||||
}
|
||||
|
||||
// Get Shader Handles
|
||||
const auto& SHADERS = rhs.GetPipeline()->GetPipelineLayout()->GetShaderModules();
|
||||
Handle<SHVkShaderModule> vertexShader, fragShader;
|
||||
for (const auto& shader : SHADERS)
|
||||
{
|
||||
const auto FLAG_BITS = shader->GetShaderStageFlagBits();
|
||||
if (FLAG_BITS & vk::ShaderStageFlagBits::eVertex)
|
||||
vertexShader = shader;
|
||||
else if (FLAG_BITS & vk::ShaderStageFlagBits::eFragment)
|
||||
fragShader = shader;
|
||||
}
|
||||
|
||||
// Write Material
|
||||
YAML::Node node;
|
||||
|
||||
node[VERT_SHADER_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHVkShaderModule>(vertexShader).value_or(0);
|
||||
node[FRAG_SHADER_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHVkShaderModule>(fragShader).value_or(0);
|
||||
node[SUBPASS_YAML_TAG.data()] = rhs.GetPipeline()->GetPipelineState().GetSubpass()->GetName();
|
||||
node[PROPS_YAML_TAG.data()] = propertiesNode;
|
||||
|
||||
return node;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct convert<SHMaterialSpec>
|
||||
static bool decode(YAML::Node const& node, SHMaterialSpec& rhs)
|
||||
{
|
||||
static constexpr std::string_view VERT_SHADER_YAML_TAG = "VertexShader";
|
||||
static constexpr std::string_view FRAG_SHADER_YAML_TAG = "FragmentShader";
|
||||
static constexpr std::string_view SUBPASS_YAML_TAG = "SubPass";
|
||||
static constexpr std::string_view PROPS_YAML_TAG = "Properties";
|
||||
|
||||
static bool decode(YAML::Node const& node, SHMaterialSpec& rhs)
|
||||
{
|
||||
// Retrieve Shader Asset IDs
|
||||
if (!node[VERT_SHADER_YAML_TAG.data()])
|
||||
return false;
|
||||
// Retrieve Shader Asset IDs
|
||||
if (node[VERT_SHADER_YAML_TAG.data()].IsDefined())
|
||||
rhs.vertexShader = node[VERT_SHADER_YAML_TAG.data()].as<AssetID>();
|
||||
if (!node[FRAG_SHADER_YAML_TAG.data()])
|
||||
return false;
|
||||
if (node[FRAG_SHADER_YAML_TAG.data()].IsDefined())
|
||||
rhs.fragShader = node[FRAG_SHADER_YAML_TAG.data()].as<AssetID>();
|
||||
|
||||
// Retrieve Subpass
|
||||
if (!node[SUBPASS_YAML_TAG.data()])
|
||||
return false;
|
||||
// Retrieve Subpass
|
||||
if (node[SUBPASS_YAML_TAG.data()].IsDefined())
|
||||
rhs.subpassName = node[SUBPASS_YAML_TAG.data()].as<std::string>();
|
||||
|
||||
// Retrieve
|
||||
if (!node[PROPS_YAML_TAG.data()])
|
||||
return false;
|
||||
// Retrieve
|
||||
if (node[PROPS_YAML_TAG.data()].IsDefined())
|
||||
rhs.properties = node[PROPS_YAML_TAG.data()];
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct convert<SHRenderable>
|
||||
template<>
|
||||
struct convert<SHRenderable>
|
||||
{
|
||||
static constexpr std::string_view MESH_YAML_TAG = "Mesh";
|
||||
static constexpr std::string_view MAT_YAML_TAG = "Material";
|
||||
|
||||
static YAML::Node encode(SHRenderable const& rhs)
|
||||
{
|
||||
static constexpr std::string_view MESH_YAML_TAG = "Mesh";
|
||||
static constexpr std::string_view MAT_YAML_TAG = "Material";
|
||||
|
||||
static YAML::Node encode(SHRenderable const& rhs)
|
||||
YAML::Node node;
|
||||
node[MESH_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMesh>(rhs.GetMesh()).value_or(0);
|
||||
node[MAT_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMaterial>(rhs.GetMaterial()->GetBaseMaterial()).value_or(0);
|
||||
return node;
|
||||
}
|
||||
static bool decode(YAML::Node const& node, SHRenderable& rhs)
|
||||
{
|
||||
if (node[MESH_YAML_TAG.data()].IsDefined())
|
||||
{
|
||||
rhs.SetMesh(SHResourceManager::LoadOrGet<SHMesh>(node[MESH_YAML_TAG.data()].as<AssetID>()));
|
||||
}
|
||||
if (node[MAT_YAML_TAG.data()].IsDefined())
|
||||
{
|
||||
// Temporarily, use default material
|
||||
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||
if (!gfxSystem)
|
||||
return false;
|
||||
Handle<SHMaterial> baseMat = SHResourceManager::LoadOrGet<SHMaterial>(node[MAT_YAML_TAG.data()].as<AssetID>());
|
||||
if (!baseMat)
|
||||
{
|
||||
YAML::Node node;
|
||||
node[MESH_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMesh>(rhs.GetMesh()).value_or(0);
|
||||
node[MAT_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMaterial>(rhs.GetMaterial()->GetBaseMaterial()).value_or(0);
|
||||
return node;
|
||||
baseMat = gfxSystem->GetDefaultMaterial();
|
||||
SHLog::Warning("[SHSerializationHelper] Unable to load specified material. Falling back to default material.");
|
||||
}
|
||||
static bool decode(YAML::Node const& node, SHRenderable& rhs)
|
||||
{
|
||||
if (node[MESH_YAML_TAG.data()].IsDefined())
|
||||
{
|
||||
rhs.SetMesh(SHResourceManager::LoadOrGet<SHMesh>(node[MESH_YAML_TAG.data()].as<AssetID>()));
|
||||
}
|
||||
if (node[MAT_YAML_TAG.data()].IsDefined())
|
||||
{
|
||||
// Temporarily, use default material
|
||||
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||
if (!gfxSystem)
|
||||
return false;
|
||||
Handle<SHMaterial> baseMat = SHResourceManager::LoadOrGet<SHMaterial>(node[MAT_YAML_TAG.data()].as<AssetID>());
|
||||
if (!baseMat)
|
||||
{
|
||||
baseMat = gfxSystem->GetDefaultMaterial();
|
||||
SHLog::Warning("[SHSerializationHelper] Unable to load specified material. Falling back to default material.");
|
||||
}
|
||||
rhs.SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(baseMat));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
rhs.SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(baseMat));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace SHADE
|
||||
|
@ -550,7 +487,7 @@ namespace SHADE
|
|||
auto properties = propType.get_properties();
|
||||
for (auto const& property : properties)
|
||||
{
|
||||
if(propertyNode[property.get_name().data()].IsDefined())
|
||||
if (propertyNode[property.get_name().data()].IsDefined())
|
||||
InitializeProperty(component, property, propertyNode[property.get_name().data()]);
|
||||
}
|
||||
}
|
||||
|
@ -564,7 +501,7 @@ namespace SHADE
|
|||
return;
|
||||
auto rttrType = rttr::type::get<ComponentType>();
|
||||
auto componentNode = componentsNode[rttrType.get_name().data()];
|
||||
if(!componentNode.IsDefined())
|
||||
if (!componentNode.IsDefined())
|
||||
return;
|
||||
auto properties = rttrType.get_properties();
|
||||
for (auto const& prop : properties)
|
||||
|
|
Loading…
Reference in New Issue