Skip to content

Commit

Permalink
merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
roeas committed Sep 19, 2023
2 parents 099e885 + fd37097 commit 6b0fd02
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 79 deletions.
5 changes: 5 additions & 0 deletions Engine/Source/Editor/EditorApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,11 @@ void EditorApp::InitEngineRenderers()
auto pBlitRTRenderPass = std::make_unique<engine::BlitRenderTargetPass>(m_pRenderContext->CreateView(), pSceneRenderTarget);
AddEngineRenderer(cd::MoveTemp(pBlitRTRenderPass));

auto pBloomRenderer = std::make_unique<engine::BloomRenderer>(m_pRenderContext->CreateView(), pSceneRenderTarget);
pBloomRenderer->SetSceneWorld(m_pSceneWorld.get());
pBloomRenderer->SetEnable(false);
AddEngineRenderer(cd::MoveTemp(pBloomRenderer));

// We can debug vertex/material/texture information by just output that to screen as fragmentColor.
// But postprocess will bring unnecessary confusion.
auto pPostProcessRenderer = std::make_unique<engine::PostProcessRenderer>(m_pRenderContext->CreateView(), pSceneRenderTarget);
Expand Down
183 changes: 122 additions & 61 deletions Engine/Source/Editor/UILayers/Inspector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,23 @@ void UpdateComponentWidget<engine::MaterialComponent>(engine::SceneWorld* pScene

// Parameters
ImGui::Separator();
ImGuiUtils::ColorPickerProperty("AlbedoColor", pMaterialComponent->GetAlbedoColor());
ImGuiUtils::ImGuiFloatProperty("MetallicFactor", pMaterialComponent->GetMetallicFactor(), cd::Unit::None, 0.0f, 1.0f);
ImGuiUtils::ImGuiFloatProperty("RoughnessFactor", pMaterialComponent->GetRoughnessFactor(), cd::Unit::None, 0.0f, 1.0f);
ImGuiUtils::ColorPickerProperty("EmissiveColor", pMaterialComponent->GetEmissiveColor());
ImGuiUtils::ImGuiBoolProperty("TwoSided", pMaterialComponent->GetTwoSided());
ImGuiUtils::ImGuiStringProperty("BlendMode", nameof::nameof_enum(pMaterialComponent->GetBlendMode()).data());

{
bool isOpen = ImGui::CollapsingHeader("Render States", ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_DefaultOpen);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2, 2));
ImGui::Separator();

if (isOpen)
{
// TODO : generic cull mode.
ImGuiUtils::ImGuiBoolProperty("TwoSided", pMaterialComponent->GetTwoSided());
ImGuiUtils::ImGuiStringProperty("BlendMode", nameof::nameof_enum(pMaterialComponent->GetBlendMode()).data());
}

ImGui::Separator();
ImGui::PopStyleVar();
}

if (cd::BlendMode::Mask == pMaterialComponent->GetBlendMode())
{
ImGuiUtils::ImGuiFloatProperty("AlphaCutOff", pMaterialComponent->GetAlphaCutOff(), cd::Unit::None, 0.0f, 1.0f);
Expand All @@ -161,17 +172,58 @@ void UpdateComponentWidget<engine::MaterialComponent>(engine::SceneWorld* pScene
// Textures
for (int textureTypeValue = 0; textureTypeValue < static_cast<int>(cd::MaterialTextureType::Count); ++textureTypeValue)
{
if (engine::MaterialComponent::TextureInfo* pTextureInfo = pMaterialComponent->GetTextureInfo(static_cast<cd::MaterialPropertyGroup>(textureTypeValue)))
auto textureType = static_cast<cd::MaterialTextureType>(textureTypeValue);
bool allowNoTextures = textureType == cd::MaterialTextureType::BaseColor ||
textureType == cd::MaterialTextureType::Emissive ||
textureType == cd::MaterialTextureType::Metallic ||
textureType == cd::MaterialTextureType::Roughness;

engine::MaterialComponent::TextureInfo* pTextureInfo = pMaterialComponent->GetTextureInfo(textureType);
bool canCreateTextureParameters = pTextureInfo || allowNoTextures;
if (canCreateTextureParameters)
{
const char* title = nameof::nameof_enum(static_cast<cd::MaterialPropertyGroup>(textureTypeValue)).data();
bool isOpen = ImGui::CollapsingHeader(title, ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_DefaultOpen);
const char* pTextureType = nameof::nameof_enum(static_cast<cd::MaterialTextureType>(textureTypeValue)).data();
bool isOpen = ImGui::CollapsingHeader(pTextureType, ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_DefaultOpen);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2, 2));
ImGui::Separator();

if (isOpen)
{
ImGuiUtils::ImGuiVectorProperty("UVOffset", pTextureInfo->GetUVOffset());
ImGuiUtils::ImGuiVectorProperty("UVScale", pTextureInfo->GetUVScale());
ImGui::PushID(textureTypeValue);

if (cd::MaterialTextureType::BaseColor == textureType)
{
ImGuiUtils::ColorPickerProperty("AlbedoColor", pMaterialComponent->GetAlbedoColor());
}
else if (cd::MaterialTextureType::Metallic == textureType)
{
ImGuiUtils::ImGuiFloatProperty("Metalness", pMaterialComponent->GetMetallicFactor(), cd::Unit::None, 0.0f, 1.0f, false, 0.01f);
}
else if (cd::MaterialTextureType::Roughness == textureType)
{
ImGuiUtils::ImGuiFloatProperty("Roughness", pMaterialComponent->GetRoughnessFactor(), cd::Unit::None, 0.0f, 1.0f, false, 0.01f);
}
else if (cd::MaterialTextureType::Emissive == textureType)
{
float emissiveStrength = pMaterialComponent->GetEmissiveColor().x();
if (ImGuiUtils::ImGuiFloatProperty("Emissive Strength", emissiveStrength, cd::Unit::None, 0.0f, 1000.0f, false, 0.1f))
{
pMaterialComponent->SetEmissiveColor(cd::Vec3f(emissiveStrength));
}
}

if (pTextureInfo)
{
if (pTextureInfo->textureHandle != bgfx::kInvalidHandle)
{
ImGui::Image(reinterpret_cast<ImTextureID>(pTextureInfo->textureHandle), ImVec2(64, 64));
}

ImGuiUtils::ImGuiVectorProperty("UV Offset", pTextureInfo->GetUVOffset(), cd::Unit::None, cd::Vec2f(0.0f), cd::Vec2f(1.0f), false, 0.01f);
ImGuiUtils::ImGuiVectorProperty("UV Scale", pTextureInfo->GetUVScale());
}

ImGui::PopID();
}

ImGui::Separator();
Expand All @@ -180,38 +232,39 @@ void UpdateComponentWidget<engine::MaterialComponent>(engine::SceneWorld* pScene
}

// Shaders
const char* title = "Shader";
bool isOpen = ImGui::CollapsingHeader(title, ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_DefaultOpen);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2, 2));
ImGui::Separator();

if (isOpen)
{
ImGuiUtils::ImGuiStringProperty("Vertex Shader", pMaterialComponent->GetVertexShaderName());
ImGuiUtils::ImGuiStringProperty("Fragment Shader", pMaterialComponent->GetFragmentShaderName());
bool isOpen = ImGui::CollapsingHeader("Shader", ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_DefaultOpen);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2, 2));
ImGui::Separator();

std::vector<const char*> activeShaderFeatures;
for (const auto& feature : pMaterialComponent->GetShaderFeatures())
if (isOpen)
{
activeShaderFeatures.emplace_back(nameof::nameof_enum(feature).data());
}
ImGuiUtils::ImGuiStringProperty("Vertex Shader", pMaterialComponent->GetVertexShaderName());
ImGuiUtils::ImGuiStringProperty("Fragment Shader", pMaterialComponent->GetFragmentShaderName());
ImGui::Separator();

if (!activeShaderFeatures.empty())
{
if (ImGui::BeginCombo("##combo", "Active shader features"))
std::vector<const char*> activeShaderFeatures;
for (const auto& feature : pMaterialComponent->GetShaderFeatures())
{
activeShaderFeatures.emplace_back(nameof::nameof_enum(feature).data());
}

if (!activeShaderFeatures.empty())
{
for (size_t index = 0; index < activeShaderFeatures.size(); ++index)
if (ImGui::BeginCombo("##combo", "Active shader features"))
{
ImGui::Selectable(activeShaderFeatures[index], false);
for (size_t index = 0; index < activeShaderFeatures.size(); ++index)
{
ImGui::Selectable(activeShaderFeatures[index], false);
}
ImGui::EndCombo();
}
ImGui::EndCombo();
}
}
}

ImGui::Separator();
ImGui::PopStyleVar();
ImGui::Separator();
ImGui::PopStyleVar();
}
}

ImGui::Separator();
Expand Down Expand Up @@ -256,23 +309,23 @@ void UpdateComponentWidget<engine::CameraComponent>(engine::SceneWorld* pSceneWo
ImGuiUtils::ImGuiBoolProperty("Open Bloom", pCameraComponent->GetIsBloomEnable());
if (pCameraComponent->GetIsBloomEnable())
{
ImGuiUtils::ImGuiIntProperty("DownSampleTimes", pCameraComponent->GetBloomDownSampleTimes(), cd::Unit::None, 4, 8, false, 1.0f);
ImGuiUtils::ImGuiIntProperty("DownSample Times", pCameraComponent->GetBloomDownSampleTimes(), cd::Unit::None, 4, 8, false, 1.0f);
ImGuiUtils::ImGuiFloatProperty("Bloom Intensity", pCameraComponent->GetBloomIntensity(), cd::Unit::None, 0.0f, 3.0f, false, 0.01f);
ImGuiUtils::ImGuiFloatProperty("Luminance Threshold", pCameraComponent->GetLuminanceThreshold(), cd::Unit::None, 0.0f, 3.0f, false, 0.01f);
}

ImGui::TreePop();
}

if (ImGui::TreeNode("Gaussian Blur"))
{
ImGuiUtils::ImGuiBoolProperty("Open Blur", pCameraComponent->GetIsBlurEnable());
if (pCameraComponent->GetIsBlurEnable())
{
ImGuiUtils::ImGuiIntProperty("BlurIteration", pCameraComponent->GetBlurTimes(), cd::Unit::None, 0, 20, false, 1.0f);
ImGuiUtils::ImGuiFloatProperty("Blur Size", pCameraComponent->GetBlurSize(), cd::Unit::None, 0.0f, 3.0f);
ImGuiUtils::ImGuiIntProperty("Blur Scaling", pCameraComponent->GetBlurScaling(), cd::Unit::None, 1, 4, false, 1.0f);
if (ImGui::TreeNode("Gaussian Blur"))
{
ImGuiUtils::ImGuiBoolProperty("Open Blur", pCameraComponent->GetIsBlurEnable());
if (pCameraComponent->GetIsBlurEnable())
{
ImGuiUtils::ImGuiIntProperty("Blur Iteration", pCameraComponent->GetBlurTimes(), cd::Unit::None, 0, 20, false, 1.0f);
ImGuiUtils::ImGuiFloatProperty("Blur Size", pCameraComponent->GetBlurSize(), cd::Unit::None, 0.0f, 3.0f);
ImGuiUtils::ImGuiIntProperty("Blur Scaling", pCameraComponent->GetBlurScaling(), cd::Unit::None, 1, 4, false, 1.0f);
}
ImGui::TreePop();
}
}

ImGui::TreePop();
}

Expand Down Expand Up @@ -549,32 +602,40 @@ void Inspector::Init()

void Inspector::Update()
{
auto flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse;
ImGui::Begin(GetName(), &m_isEnable, flags);

engine::SceneWorld* pSceneWorld = GetSceneWorld();
engine::Entity selectedEntity = pSceneWorld->GetSelectedEntity();
if (engine::INVALID_ENTITY == selectedEntity)
if (engine::Entity selectedEntity = pSceneWorld->GetSelectedEntity(); selectedEntity != engine::INVALID_ENTITY)
{
// Entity will be invalid in two cases : 1.Select nothing 2.The selected entity has been deleted
// Here we only want to capture the case 1 not to clear Inspector properties.
// For case 2, it still uses a valid entity to update but nothing updated.
// It is OK if we don't reuse the entity id intermediately.
m_lastSelectedEntity = selectedEntity;
}

constexpr auto flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse;
ImGui::Begin(GetName(), &m_isEnable, flags);
if (m_lastSelectedEntity == engine::INVALID_ENTITY)
{
// Call ImGui::Begin to show the panel though we will do nothing.
ImGui::End();
return;
}

ImGui::BeginChild("Inspector");

details::UpdateComponentWidget<engine::NameComponent>(pSceneWorld, selectedEntity);
details::UpdateComponentWidget<engine::TransformComponent>(pSceneWorld, selectedEntity);
details::UpdateComponentWidget<engine::CameraComponent>(pSceneWorld, selectedEntity);
details::UpdateComponentWidget<engine::LightComponent>(pSceneWorld, selectedEntity);
details::UpdateComponentWidget<engine::SkyComponent>(pSceneWorld, selectedEntity);
details::UpdateComponentWidget<engine::TerrainComponent>(pSceneWorld, selectedEntity);
details::UpdateComponentWidget<engine::StaticMeshComponent>(pSceneWorld, selectedEntity);
details::UpdateComponentWidget<engine::ParticleComponent>(pSceneWorld, selectedEntity);
details::UpdateComponentWidget<engine::CollisionMeshComponent>(pSceneWorld, selectedEntity);
details::UpdateComponentWidget<engine::MaterialComponent>(pSceneWorld, selectedEntity);
details::UpdateComponentWidget<engine::NameComponent>(pSceneWorld, m_lastSelectedEntity);
details::UpdateComponentWidget<engine::TransformComponent>(pSceneWorld, m_lastSelectedEntity);
details::UpdateComponentWidget<engine::CameraComponent>(pSceneWorld, m_lastSelectedEntity);
details::UpdateComponentWidget<engine::LightComponent>(pSceneWorld, m_lastSelectedEntity);
details::UpdateComponentWidget<engine::SkyComponent>(pSceneWorld, m_lastSelectedEntity);
details::UpdateComponentWidget<engine::TerrainComponent>(pSceneWorld, m_lastSelectedEntity);
details::UpdateComponentWidget<engine::StaticMeshComponent>(pSceneWorld, m_lastSelectedEntity);
details::UpdateComponentWidget<engine::MaterialComponent>(pSceneWorld, m_lastSelectedEntity);
details::UpdateComponentWidget<engine::ParticleComponent>(pSceneWorld, m_lastSelectedEntity);
details::UpdateComponentWidget<engine::CollisionMeshComponent>(pSceneWorld, m_lastSelectedEntity);

#ifdef ENABLE_DDGI
details::UpdateComponentWidget<engine::DDGIComponent>(pSceneWorld, selectedEntity);
details::UpdateComponentWidget<engine::DDGIComponent>(pSceneWorld, m_lastSelectedEntity);
#endif

ImGui::EndChild();
Expand Down
3 changes: 3 additions & 0 deletions Engine/Source/Editor/UILayers/Inspector.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ class Inspector : public engine::ImGuiBaseLayer

virtual void Init() override;
virtual void Update() override;

private:
engine::Entity m_lastSelectedEntity = engine::INVALID_ENTITY;
};

}
18 changes: 5 additions & 13 deletions Engine/Source/Runtime/ImGui/ImGuiUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ static bool ImGuiIntProperty(const char* pName, int& value, cd::Unit unit = cd::
ImGui::NextColumn();
ImGui::PushItemWidth(-1);

std::string labelName = "##";
labelName += pName;
if (ImGui::DragInt(labelName.c_str(), &value, speed, minValue, maxValue, "%d"))
if (ImGui::DragInt(pName, &value, speed, minValue, maxValue, "%d"))
{
dirty = true;
}
Expand All @@ -69,15 +67,12 @@ static bool ImGuiFloatProperty(const char* pName, float& value, cd::Unit unit =
ImGui::NextColumn();
ImGui::PushItemWidth(-1);

//std::string labelName = std::format("##{}", pName);
std::string labelName = "##";
labelName += pName;
//std::string metricName = std::format("%.2f{}", cd::GetUnitName(unit));
std::string metricName = "%.2f";
metricName += cd::GetUnitName(unit);
float delta = maxValue - minValue;
float dragSpeed = (speed <= 0.0) ? (cd::Math::IsEqualToZero(delta) ? 1.0f : delta * 0.05f) : speed;
if (ImGui::DragFloat(labelName.c_str(), &value, dragSpeed, minValue, maxValue, metricName.c_str()))
if (ImGui::DragFloat(pName, &value, dragSpeed, minValue, maxValue, metricName.c_str()))
{
dirty = true;
}
Expand All @@ -104,31 +99,28 @@ static bool ImGuiVectorProperty(const char* pName, T& value, cd::Unit unit = cd:
ImGui::NextColumn();
ImGui::PushItemWidth(-1);

//std::string labelName = std::format("##{}", pName);
std::string labelName = "##";
labelName += pName;
//std::string metricName = std::format("%.2f{}", cd::GetUnitName(unit));
std::string metricName = "%.2f";
metricName += cd::GetUnitName(unit);
float delta = maxValue.x() - minValue.x();
float dragSpeed = (speed <= 0.0) ? (cd::Math::IsEqualToZero(delta) ? 1.0f : delta * 0.05f) : speed;
if constexpr (std::is_same<T, cd::Vec2f>())
{
if (ImGui::DragFloat2(labelName.c_str(), value.Begin(), dragSpeed, minValue.x(), maxValue.x(), metricName.c_str()))
if (ImGui::DragFloat2(pName, value.Begin(), dragSpeed, minValue.x(), maxValue.x(), metricName.c_str()))
{
dirty = true;
}
}
else if constexpr (std::is_same<T, cd::Vec3f>())
{
if (ImGui::DragFloat3(labelName.c_str(), value.Begin(), dragSpeed, minValue.x(), maxValue.x(), metricName.c_str()))
if (ImGui::DragFloat3(pName, value.Begin(), dragSpeed, minValue.x(), maxValue.x(), metricName.c_str()))
{
dirty = true;
}
}
else if constexpr (std::is_same<T, cd::Vec4f>())
{
if (ImGui::DragFloat4(labelName.c_str(), value.Begin(), dragSpeed, minValue.x(), maxValue.x(), metricName.c_str()))
if (ImGui::DragFloat4(pName, value.Begin(), dragSpeed, minValue.x(), maxValue.x(), metricName.c_str()))
{
dirty = true;
}
Expand Down
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,34 @@
[![win64_vs2022_clang](https://github.com/CatDogEngine/CatDogEngine/actions/workflows/win64_vs2022_clang.yml/badge.svg?branch=main)](https://github.com/CatDogEngine/CatDogEngine/actions/workflows/win64_vs2022_clang.yml)

## Snapshots

![image](https://github.com/CatDogEngine/CatDogEngine/assets/75730859/4f1f0006-76e4-40cf-bd3a-ae70ecf4b6b5)
![image](https://github.com/CatDogEngine/CatDogEngine/assets/75730859/52ffa26b-6cc7-441a-8441-513ca11b9813)
![image](https://github.com/CatDogEngine/CatDogEngine/assets/75730859/6a383b35-a1cd-45fd-98bb-a1d14709cc3e)
![image](https://github.com/CatDogEngine/CatDogEngine/assets/75730859/bdeb4f25-fe78-4aca-92ca-8cd39022e194)
![image](https://github.com/CatDogEngine/CatDogEngine/assets/75730859/22da0826-baaa-47e2-b1b2-e49954345fbe)

## Features

* Basic Cross Platform Editor based on ImGui
* Basic Entity/Component Framework
* Basic Physically Based Rendering
* Basic PostEffects
* Bloom
* Exposure
* Gamma Correction
* Tone Mapping
* Basic Scene Graph SDK
* Standard Atmospheric Scattering

## Developing Features

* Animation
* BlendShape
* Skeletion
* JobSystem
* Modern RHI except bgfx
* Particle System
* Procedural Generated Terrain
* RenderGraph
* Skeleton Animation

## TODO List

Expand All @@ -32,7 +42,6 @@
* Foliage Rendering
* Memory Management based on multiple allocators
* Optimized STL specific for GameEngine
* Particle System
* Physical Engine

## ThirdParty
Expand Down

0 comments on commit 6b0fd02

Please sign in to comment.