add auto exposure
This commit is contained in:
@ -16,7 +16,7 @@ file(GLOB_RECURSE SRC_SOURCE ./**.cpp)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SRC_SOURCE})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Prism-shared)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Prism-static)
|
||||
|
||||
# Enable ImGui Docking space
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE ENABLE_DOCKSPACE)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,7 @@
|
||||
#define EDITORLAYER_H
|
||||
|
||||
#include "Prism.h"
|
||||
#include "Prism/Editor/AssetsManagerPanel.h"
|
||||
#include "Prism/Editor/ContentBrowserPanel.h"
|
||||
#include "Prism/Editor/ObjectsPanel.h"
|
||||
#include "Prism/Editor/SceneHierachyPanel.h"
|
||||
|
||||
@ -58,7 +58,7 @@ namespace Prism
|
||||
float GetSnapValue() const;
|
||||
private:
|
||||
Scope<SceneHierarchyPanel> m_SceneHierarchyPanel;
|
||||
Scope<AssetsManagerPanel> m_AssetManagerPanel;
|
||||
Scope<ContentBrowserPanel> m_ContentBrowserPanel;
|
||||
Scope<ObjectsPanel> m_ObjectsPanel;
|
||||
|
||||
Ref<Scene> m_CurrentScene;
|
||||
@ -133,7 +133,7 @@ namespace Prism
|
||||
|
||||
// Editor resources
|
||||
Ref<Texture2D> m_CheckerboardTex;
|
||||
Ref<Texture2D> m_PlayButtonTex;
|
||||
Ref<Texture2D> m_PlayButtonTex, m_StopButtonTex, m_PauseButtonTex;
|
||||
|
||||
|
||||
// configure button
|
||||
|
||||
BIN
Editor/assets/editor/PauseButton.png
Normal file
BIN
Editor/assets/editor/PauseButton.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 119 B |
@ -1,6 +1,6 @@
|
||||
[Window][DockSpace Demo]
|
||||
Pos=0,0
|
||||
Size=2066,1198
|
||||
Size=2560,1566
|
||||
Collapsed=0
|
||||
|
||||
[Window][Debug##Default]
|
||||
@ -9,32 +9,32 @@ Size=400,400
|
||||
Collapsed=0
|
||||
|
||||
[Window][Scene Hierarchy]
|
||||
Pos=1595,24
|
||||
Size=471,428
|
||||
Pos=2089,24
|
||||
Size=471,563
|
||||
Collapsed=0
|
||||
DockId=0x00000009,0
|
||||
|
||||
[Window][Properties]
|
||||
Pos=1595,454
|
||||
Size=471,744
|
||||
Pos=2089,589
|
||||
Size=471,977
|
||||
Collapsed=0
|
||||
DockId=0x0000000A,0
|
||||
|
||||
[Window][Scene Renderer]
|
||||
Pos=0,648
|
||||
Size=481,550
|
||||
Pos=0,843
|
||||
Size=481,723
|
||||
Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
[Window][Materials]
|
||||
Pos=0,24
|
||||
Size=481,622
|
||||
Size=481,817
|
||||
Collapsed=0
|
||||
DockId=0x00000005,0
|
||||
|
||||
[Window][Script Engine Debug]
|
||||
Pos=1595,454
|
||||
Size=471,744
|
||||
Pos=2089,589
|
||||
Size=471,977
|
||||
Collapsed=0
|
||||
DockId=0x0000000A,2
|
||||
|
||||
@ -52,25 +52,25 @@ DockId=0x00000001,0
|
||||
|
||||
[Window][Viewport]
|
||||
Pos=483,58
|
||||
Size=1110,722
|
||||
Size=1604,955
|
||||
Collapsed=0
|
||||
DockId=0x0000000B,0
|
||||
|
||||
[Window][Environment]
|
||||
Pos=1595,454
|
||||
Size=471,744
|
||||
Pos=2089,589
|
||||
Size=471,977
|
||||
Collapsed=0
|
||||
DockId=0x0000000A,1
|
||||
|
||||
[Window][Project]
|
||||
Pos=483,782
|
||||
Size=1110,416
|
||||
Pos=483,1015
|
||||
Size=1604,551
|
||||
Collapsed=0
|
||||
DockId=0x0000000C,0
|
||||
|
||||
[Window][Objects]
|
||||
Pos=483,782
|
||||
Size=1110,416
|
||||
Pos=483,1015
|
||||
Size=1604,551
|
||||
Collapsed=0
|
||||
DockId=0x0000000C,1
|
||||
|
||||
@ -79,17 +79,23 @@ Pos=189,113
|
||||
Size=468,371
|
||||
Collapsed=0
|
||||
|
||||
[Window][##tool_bar]
|
||||
Pos=483,24
|
||||
Size=1604,32
|
||||
Collapsed=0
|
||||
DockId=0x00000001,0
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0xC0DFADC4 Window=0xD0388BC8 Pos=150,89 Size=2066,1174 Split=X Selected=0x0C01D6D5
|
||||
DockSpace ID=0xC0DFADC4 Window=0xD0388BC8 Pos=0,58 Size=2560,1542 Split=X Selected=0x0C01D6D5
|
||||
DockNode ID=0x00000007 Parent=0xC0DFADC4 SizeRef=1557,1542 Split=X
|
||||
DockNode ID=0x00000003 Parent=0x00000007 SizeRef=481,1542 Split=Y Selected=0x5D711C2C
|
||||
DockNode ID=0x00000005 Parent=0x00000003 SizeRef=481,817 Selected=0x5D711C2C
|
||||
DockNode ID=0x00000006 Parent=0x00000003 SizeRef=481,723 Selected=0x68D924E0
|
||||
DockNode ID=0x00000004 Parent=0x00000007 SizeRef=1074,1542 Split=Y
|
||||
DockNode ID=0x00000001 Parent=0x00000004 SizeRef=2560,32 CentralNode=1 HiddenTabBar=1 Selected=0x0C01D6D5
|
||||
DockNode ID=0x00000001 Parent=0x00000004 SizeRef=2560,32 CentralNode=1 HiddenTabBar=1 Selected=0xE8CD5B84
|
||||
DockNode ID=0x00000002 Parent=0x00000004 SizeRef=2560,1508 Split=Y Selected=0xC450F867
|
||||
DockNode ID=0x0000000B Parent=0x00000002 SizeRef=1401,669 HiddenTabBar=1 Selected=0xC450F867
|
||||
DockNode ID=0x0000000C Parent=0x00000002 SizeRef=1401,386 Selected=0x9C21DE82
|
||||
DockNode ID=0x0000000B Parent=0x00000002 SizeRef=1401,955 HiddenTabBar=1 Selected=0xC450F867
|
||||
DockNode ID=0x0000000C Parent=0x00000002 SizeRef=1401,551 Selected=0x9C21DE82
|
||||
DockNode ID=0x00000008 Parent=0xC0DFADC4 SizeRef=471,1542 Split=Y Selected=0x8C72BEA8
|
||||
DockNode ID=0x00000009 Parent=0x00000008 SizeRef=315,563 Selected=0xB8729153
|
||||
DockNode ID=0x0000000A Parent=0x00000008 SizeRef=315,977 Selected=0x73E3D51F
|
||||
|
||||
@ -66,7 +66,8 @@ elseif (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
endif ()
|
||||
|
||||
include_directories(vendor/PhysX/physx/include)
|
||||
link_directories("vendor/PhysX/physx/bin/win.x86_64.vc143.md/${PHYSX_BUILD_TYPE}") # This is the path where PhysX libraries are installed
|
||||
set(PHYSX_LIB_DIR "vendor/PhysX/physx/bin/win.x86_64.vc143.md/${PHYSX_BUILD_TYPE}") # This is the path where PhysX libraries are installed
|
||||
link_directories(${PHYSX_LIB_DIR})
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
message("Building snippet in debug with PhysX ${PHYSX_BUILD_TYPE} configuration")
|
||||
@ -139,6 +140,11 @@ target_compile_definitions(${STATIC_LIBRARY} PRIVATE
|
||||
target_include_directories(${STATIC_LIBRARY} PUBLIC
|
||||
${TARGET_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
target_link_directories(${STATIC_LIBRARY} INTERFACE
|
||||
${PHYSX_LIB_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(${STATIC_LIBRARY}
|
||||
PRIVATE
|
||||
${LINK_LIBRARIES_PRIVATE}
|
||||
|
||||
@ -102,7 +102,6 @@ namespace Prism
|
||||
{
|
||||
m_ImGuiLayer->Begin();
|
||||
|
||||
/*
|
||||
ImGui::Begin("Renderer");
|
||||
const auto& caps = RendererAPI::GetCapabilities();
|
||||
ImGui::Text("Vendor: %s", caps.Vendor.c_str());
|
||||
@ -110,7 +109,6 @@ namespace Prism
|
||||
ImGui::Text("Version: %s", caps.Version.c_str());
|
||||
ImGui::Text("Frame Time: %.2fms\n", m_TimeStep.GetMilliseconds());
|
||||
ImGui::End();
|
||||
*/
|
||||
|
||||
for (Layer* layer : m_LayerStack)
|
||||
layer->OnImGuiRender();
|
||||
|
||||
31
Prism/src/Prism/Core/ImGui/ImGui.cpp
Normal file
31
Prism/src/Prism/Core/ImGui/ImGui.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
//
|
||||
// Created by Atdunbg on 2026/2/21.
|
||||
//
|
||||
#include "ImGui.h"
|
||||
|
||||
#include "Prism/Renderer/RendererAPI.h"
|
||||
#include "Prism/Renderer/Texture.h"
|
||||
|
||||
namespace Prism::UI
|
||||
{
|
||||
|
||||
void Image(const Ref<Texture2D>& texture, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col)
|
||||
{
|
||||
ImGui::PushID(texture->Handle);
|
||||
if (RendererAPI::Current() == RendererAPIType::OpenGL)
|
||||
{
|
||||
ImGui::Image((ImTextureID)texture->GetRendererID(), size, uv0, uv1, tint_col, border_col);
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
bool ImageButton(const Ref<Texture2D>& texture, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col)
|
||||
{
|
||||
if (RendererAPI::Current() == RendererAPIType::OpenGL)
|
||||
{
|
||||
return ImGui::ImageButton(std::string_view("##" + std::to_string(texture->Handle)).data(), (ImTextureID)texture->GetRendererID(), size, uv0, uv1, bg_col, tint_col);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -9,8 +9,13 @@
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include "../../Asset/Asset.h"
|
||||
#include "../../Asset/AssetsManager.h"
|
||||
#include "Prism/Asset/Asset.h"
|
||||
#include "Prism/Asset/AssetsManager.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
class Texture2D;
|
||||
}
|
||||
|
||||
namespace Prism::UI {
|
||||
|
||||
@ -259,6 +264,157 @@ namespace Prism::UI {
|
||||
return modified;
|
||||
}
|
||||
|
||||
static bool PropertySlider(const char* label, float& value, const float min, const float max)
|
||||
{
|
||||
bool modified = false;
|
||||
|
||||
ImGui::Text("%s", label);
|
||||
ImGui::NextColumn();
|
||||
ImGui::PushItemWidth(-1);
|
||||
|
||||
s_IDBuffer[0] = '#';
|
||||
s_IDBuffer[1] = '#';
|
||||
memset(s_IDBuffer + 2, 0, 14);
|
||||
snprintf(s_IDBuffer + 2, 14, "%x", s_Counter++);
|
||||
if (ImGui::SliderFloat(s_IDBuffer, &value, min, max))
|
||||
modified = true;
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::NextColumn();
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
||||
static bool PropertySlider(const char* label, glm::vec2& value, const float min, const float max)
|
||||
{
|
||||
bool modified = false;
|
||||
|
||||
ImGui::Text("%s", label);
|
||||
ImGui::NextColumn();
|
||||
ImGui::PushItemWidth(-1);
|
||||
|
||||
s_IDBuffer[0] = '#';
|
||||
s_IDBuffer[1] = '#';
|
||||
memset(s_IDBuffer + 2, 0, 14);
|
||||
snprintf(s_IDBuffer + 2, 14, "%x", s_Counter++);
|
||||
if (ImGui::SliderFloat2(s_IDBuffer, glm::value_ptr(value), min, max))
|
||||
modified = true;
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::NextColumn();
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
||||
static bool PropertySlider(const char* label, glm::vec3& value, const float min, const float max)
|
||||
{
|
||||
bool modified = false;
|
||||
|
||||
ImGui::Text("%s", label);
|
||||
ImGui::NextColumn();
|
||||
ImGui::PushItemWidth(-1);
|
||||
|
||||
s_IDBuffer[0] = '#';
|
||||
s_IDBuffer[1] = '#';
|
||||
memset(s_IDBuffer + 2, 0, 14);
|
||||
snprintf(s_IDBuffer + 2, 14, "%x", s_Counter++);
|
||||
if (ImGui::SliderFloat3(s_IDBuffer, glm::value_ptr(value), min, max))
|
||||
modified = true;
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::NextColumn();
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
||||
static bool PropertySlider(const char* label, glm::vec4& value, float min, float max)
|
||||
{
|
||||
bool modified = false;
|
||||
|
||||
ImGui::Text("%s", label);
|
||||
ImGui::NextColumn();
|
||||
ImGui::PushItemWidth(-1);
|
||||
|
||||
s_IDBuffer[0] = '#';
|
||||
s_IDBuffer[1] = '#';
|
||||
memset(s_IDBuffer + 2, 0, 14);
|
||||
snprintf(s_IDBuffer + 2, 14, "%x", s_Counter++);
|
||||
if (ImGui::SliderFloat4(s_IDBuffer, glm::value_ptr(value), min, max))
|
||||
modified = true;
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::NextColumn();
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
||||
static bool PropertyDropdown(const char* label, const char** options, int32_t optionCount, int32_t* selected)
|
||||
{
|
||||
const char* current = options[*selected];
|
||||
ImGui::Text("%s", label);
|
||||
ImGui::NextColumn();
|
||||
ImGui::PushItemWidth(-1);
|
||||
|
||||
bool changed = false;
|
||||
|
||||
const std::string id = "##" + std::string(label);
|
||||
if (ImGui::BeginCombo(id.c_str(), current))
|
||||
{
|
||||
for (int i = 0; i < optionCount; i++)
|
||||
{
|
||||
const bool is_selected = (current == options[i]);
|
||||
if (ImGui::Selectable(options[i], is_selected))
|
||||
{
|
||||
current = options[i];
|
||||
*selected = i;
|
||||
changed = true;
|
||||
}
|
||||
if (is_selected)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::NextColumn();
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static bool PropertyDropdown(const char* label, const std::vector<std::string>& options, int32_t optionCount, int32_t* selected)
|
||||
{
|
||||
const char* current = options[*selected].c_str();
|
||||
ImGui::Text("%s", label);
|
||||
ImGui::NextColumn();
|
||||
ImGui::PushItemWidth(-1);
|
||||
|
||||
bool changed = false;
|
||||
|
||||
const std::string id = "##" + std::string(label);
|
||||
if (ImGui::BeginCombo(id.c_str(), current))
|
||||
{
|
||||
for (int i = 0; i < optionCount; i++)
|
||||
{
|
||||
const bool is_selected = (current == options[i]);
|
||||
if (ImGui::Selectable(options[i].c_str(), is_selected))
|
||||
{
|
||||
current = options[i].c_str();
|
||||
*selected = i;
|
||||
changed = true;
|
||||
}
|
||||
if (is_selected)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::NextColumn();
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
static bool PropertyAssetReference(const char* label, Ref<T>& object, const AssetType supportedType)
|
||||
{
|
||||
@ -353,6 +509,10 @@ namespace Prism::UI {
|
||||
s_CheckboxCount = 0;
|
||||
}
|
||||
|
||||
void Image(const Ref<Texture2D>& texture, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col = ImVec4(0,0,0,0), const ImVec4& border_col = ImVec4(1,1,1,1));
|
||||
|
||||
bool ImageButton(const Ref<Texture2D>& texture, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1));
|
||||
|
||||
}
|
||||
|
||||
#endif //IMGUI_H
|
||||
|
||||
@ -2,18 +2,19 @@
|
||||
// Created by Atdunbg on 2026/1/20.
|
||||
//
|
||||
|
||||
#include "AssetsManagerPanel.h"
|
||||
#include "ContentBrowserPanel.h"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include "AssetEditorPanel.h"
|
||||
#include "imgui_internal.h"
|
||||
#include "Prism/Core/Application.h"
|
||||
#include "Prism/Core/Input.h"
|
||||
#include "Prism/Core/Log.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
AssetsManagerPanel::AssetsManagerPanel()
|
||||
ContentBrowserPanel::ContentBrowserPanel()
|
||||
{
|
||||
AssetsManager::SetAssetChangeCallback([&]()
|
||||
{
|
||||
@ -47,7 +48,7 @@ namespace Prism
|
||||
|
||||
static int s_ColumnCount = 10;
|
||||
|
||||
void AssetsManagerPanel::OnImGuiRender()
|
||||
void ContentBrowserPanel::OnImGuiRender()
|
||||
{
|
||||
ImGui::Begin("Project", nullptr, ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_MenuBar);
|
||||
{
|
||||
@ -73,7 +74,6 @@ namespace Prism
|
||||
|
||||
// Grid and list files
|
||||
ImGui::BeginChild("##directory_structure", ImVec2(ImGui::GetColumnWidth() - 12, ImGui::GetWindowHeight() - 60));
|
||||
// ImGui::BeginChild("##directory_structure", ImVec2(ImGui::GetColumnWidth() - 12, ImGui::GetContentRegionAvail().y));
|
||||
{
|
||||
ImGui::BeginChild("##directory_breadcrumbs", ImVec2(ImGui::GetColumnWidth() - 100, 30));
|
||||
RenderBreadCrumbs();
|
||||
@ -195,26 +195,51 @@ namespace Prism
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void AssetsManagerPanel::DrawDirectoryInfo(const AssetHandle& directory)
|
||||
void ContentBrowserPanel::DrawDirectoryInfo(const AssetHandle& directory)
|
||||
{
|
||||
const Ref<Directory>& dir = AssetsManager::GetAsset<Directory>(directory);
|
||||
|
||||
if (ImGui::TreeNode(dir->FileName.c_str()))
|
||||
{
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
|
||||
UpdateCurrentDirectory(directory);
|
||||
ImGui::PushID((int)directory);
|
||||
|
||||
for (AssetHandle child : dir->ChildDirectories)
|
||||
// 保存调用 TreeNodeEx 前的光标位置(箭头起始位置)
|
||||
const ImVec2 arrow_pos = ImGui::GetCursorScreenPos();
|
||||
|
||||
// 设置标志:仅箭头点击展开,双击文本也可展开(可选)
|
||||
constexpr ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick;
|
||||
const bool node_open = ImGui::TreeNodeEx(dir->FileName.c_str(), flags, "%s", dir->FileName.c_str());
|
||||
|
||||
const ImRect item_rect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||
|
||||
// 计算箭头区域矩形(宽度为字体大小,高度与项一致)
|
||||
const float arrow_width = ImGui::GetFontSize();
|
||||
const ImRect arrow_rect(arrow_pos, ImVec2(arrow_pos.x + arrow_width, item_rect.Max.y));
|
||||
|
||||
// 检测左键单击(排除双击)
|
||||
if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
|
||||
{
|
||||
const ImVec2 mouse_pos = ImGui::GetMousePos();
|
||||
// 仅当点击位置不在箭头区域内时,才触发选择
|
||||
if (!arrow_rect.Contains(mouse_pos))
|
||||
{
|
||||
UpdateCurrentDirectory(directory);
|
||||
}
|
||||
}
|
||||
|
||||
// 如果节点打开,绘制子文件夹
|
||||
if (node_open)
|
||||
{
|
||||
for (const AssetHandle& child : dir->ChildDirectories)
|
||||
{
|
||||
DrawDirectoryInfo(child);
|
||||
}
|
||||
|
||||
ImGui::TreePop();
|
||||
ImGui::TreePop(); // 必须与 TreeNodeEx 匹配
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
|
||||
void AssetsManagerPanel::RenderAsset(Ref<Asset>& asset)
|
||||
void ContentBrowserPanel::RenderAsset(Ref<Asset>& asset)
|
||||
{
|
||||
// These caches are currently required for when we change directories
|
||||
const AssetHandle assetHandle = asset->Handle;
|
||||
@ -345,7 +370,7 @@ namespace Prism
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
void AssetsManagerPanel::HandleDragDrop(const RendererID icon, const Ref<Asset>& asset)
|
||||
void ContentBrowserPanel::HandleDragDrop(const RendererID icon, const Ref<Asset>& asset)
|
||||
{
|
||||
if (asset->Type == AssetType::Directory && m_IsDragging)
|
||||
{
|
||||
@ -392,7 +417,7 @@ namespace Prism
|
||||
}
|
||||
|
||||
|
||||
void AssetsManagerPanel::RenderBreadCrumbs()
|
||||
void ContentBrowserPanel::RenderBreadCrumbs()
|
||||
{
|
||||
if (ImGui::ImageButton("##backbtn", (ImTextureID)m_BackbtnTex->GetRendererID(), ImVec2(20, 18)))
|
||||
{
|
||||
@ -475,7 +500,7 @@ namespace Prism
|
||||
|
||||
}
|
||||
|
||||
void AssetsManagerPanel::HandleRenaming(Ref<Asset>& asset)
|
||||
void ContentBrowserPanel::HandleRenaming(Ref<Asset>& asset)
|
||||
{
|
||||
if (m_SelectedAssets.SelectionCount() > 1)
|
||||
return;
|
||||
@ -502,7 +527,7 @@ namespace Prism
|
||||
}
|
||||
|
||||
|
||||
void AssetsManagerPanel::UpdateCurrentDirectory(AssetHandle directoryHandle)
|
||||
void ContentBrowserPanel::UpdateCurrentDirectory(AssetHandle directoryHandle)
|
||||
{
|
||||
m_UpdateBreadCrumbs = true;
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
// Created by Atdunbg on 2026/1/20.
|
||||
//
|
||||
|
||||
#ifndef PRISM_ASSETSMANAGERPANEL_H
|
||||
#define PRISM_ASSETSMANAGERPANEL_H
|
||||
#ifndef PRISM_CONTENTBROWSERPANEL_H
|
||||
#define PRISM_CONTENTBROWSERPANEL_H
|
||||
|
||||
#include "Prism/Asset/AssetsManager.h"
|
||||
#include "Prism/Renderer/Texture.h"
|
||||
@ -64,10 +64,10 @@ namespace Prism
|
||||
std::vector<T> m_Selections;
|
||||
};
|
||||
|
||||
class PRISM_API AssetsManagerPanel
|
||||
class PRISM_API ContentBrowserPanel
|
||||
{
|
||||
public:
|
||||
AssetsManagerPanel();
|
||||
ContentBrowserPanel();
|
||||
void OnImGuiRender();
|
||||
|
||||
private:
|
||||
@ -116,4 +116,4 @@ namespace Prism
|
||||
};
|
||||
}
|
||||
|
||||
#endif //PRISM_ASSETSMANAGERPANEL_H
|
||||
#endif //PRISM_CONTENTBROWSERPANEL_H
|
||||
@ -217,109 +217,6 @@ namespace Prism
|
||||
glDrawBuffer(GL_NONE);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
if (multisample)
|
||||
{
|
||||
glCreateTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_ColorAttachment);
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_ColorAttachment);
|
||||
|
||||
// TODO: Create Hazel texture object based on format here
|
||||
if (m_Specification.Format == FramebufferFormat::RGBA16F)
|
||||
{
|
||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_Specification.Samples, GL_RGBA16F, m_Specification.Width, m_Specification.Height, GL_FALSE);
|
||||
}
|
||||
else if (m_Specification.Format == FramebufferFormat::RGBA8)
|
||||
{
|
||||
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_Specification.Samples, GL_RGBA8, m_Specification.Width, m_Specification.Height, GL_FALSE);
|
||||
}
|
||||
// glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
// glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &m_ColorAttachment);
|
||||
glBindTexture(GL_TEXTURE_2D, m_ColorAttachment);
|
||||
|
||||
// TODO: Create Hazel texture object based on format here
|
||||
if (m_Specification.Format == FramebufferFormat::RGBA16F)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, m_Specification.Width, m_Specification.Height, 0, GL_RGBA, GL_FLOAT, nullptr);
|
||||
}
|
||||
else if (m_Specification.Format == FramebufferFormat::RG32F) // "Shadow" for now
|
||||
{
|
||||
glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT32F, m_Specification.Width, m_Specification.Height);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_ColorAttachment, 0);
|
||||
glDrawBuffer(GL_NONE);
|
||||
}
|
||||
else if (m_Specification.Format == FramebufferFormat::RGBA8)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_Specification.Width, m_Specification.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
}
|
||||
else if (m_Specification.Format == FramebufferFormat::COMP)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, m_Specification.Width, m_Specification.Height, 0, GL_RGBA, GL_FLOAT, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &m_ColorAttachment2);
|
||||
glBindTexture(GL_TEXTURE_2D, m_ColorAttachment2);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, m_Specification.Width, m_Specification.Height, 0, GL_RGBA, GL_FLOAT, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
}
|
||||
|
||||
if (m_Specification.Format != FramebufferFormat::RG32F)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_ColorAttachment, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (multisample)
|
||||
{
|
||||
glCreateTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_DepthAttachment);
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_DepthAttachment);
|
||||
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_Specification.Samples, GL_DEPTH24_STENCIL8, m_Specification.Width, m_Specification.Height, GL_FALSE);
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
|
||||
}
|
||||
else if (m_Specification.Format != FramebufferFormat::RG32F)
|
||||
{
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &m_DepthAttachment);
|
||||
glBindTexture(GL_TEXTURE_2D, m_DepthAttachment);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, m_Specification.Width, m_Specification.Height, 0,
|
||||
GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL
|
||||
);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_DepthAttachment, 0);
|
||||
}
|
||||
|
||||
if (m_Specification.Format != FramebufferFormat::RG32F)
|
||||
{
|
||||
if (multisample)
|
||||
{
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_ColorAttachment, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_ColorAttachment, 0);
|
||||
if (m_Specification.Format == FramebufferFormat::COMP)
|
||||
{
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, m_ColorAttachment2, 0);
|
||||
const GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
|
||||
glDrawBuffers(2, buffers);
|
||||
}
|
||||
}
|
||||
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, m_DepthAttachment, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
PM_CORE_ASSERT(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Framebuffer is incomplete!");
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
@ -154,6 +154,13 @@ namespace Prism
|
||||
UploadUniformInt(name, value);
|
||||
});
|
||||
}
|
||||
void OpenGLShader::SetUInt(const std::string& name, unsigned int value)
|
||||
{
|
||||
Renderer::Submit([=]() {
|
||||
UploadUniformUInt(name, value);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void OpenGLShader::SetMat4(const std::string& name, const glm::mat4& value)
|
||||
{
|
||||
@ -709,16 +716,36 @@ namespace Prism
|
||||
return GL_NONE;
|
||||
}
|
||||
|
||||
void OpenGLShader::UploadUniformBool(const std::string& name, const bool value) const
|
||||
{
|
||||
glUseProgram(m_RendererID);
|
||||
const auto location = glGetUniformLocation(m_RendererID, name.c_str());
|
||||
if (location != -1)
|
||||
glUniform1i(location, value);
|
||||
else
|
||||
PM_CORE_WARN("{0}: Uniform '{1}' not found!", m_Name,name);
|
||||
}
|
||||
|
||||
void OpenGLShader::UploadUniformInt(const std::string& name, const int value) const
|
||||
{
|
||||
glUseProgram(m_RendererID);
|
||||
auto location = glGetUniformLocation(m_RendererID, name.c_str());
|
||||
const auto location = glGetUniformLocation(m_RendererID, name.c_str());
|
||||
if (location != -1)
|
||||
glUniform1i(location, value);
|
||||
else
|
||||
PM_CORE_WARN("{0}: Uniform '{1}' not found!", m_Name,name);
|
||||
}
|
||||
|
||||
void OpenGLShader::UploadUniformUInt(const std::string& name, int value) const
|
||||
{
|
||||
glUseProgram(m_RendererID);
|
||||
const auto location = glGetUniformLocation(m_RendererID, name.c_str());
|
||||
if (location != -1)
|
||||
glUniform1ui(location, value);
|
||||
else
|
||||
PM_CORE_WARN("{0}: Uniform '{1}' not found!", m_Name,name);
|
||||
}
|
||||
|
||||
void OpenGLShader::UploadUniformFloat(const std::string& name, const float value) const
|
||||
{
|
||||
glUseProgram(m_RendererID);
|
||||
|
||||
@ -32,6 +32,7 @@ namespace Prism
|
||||
virtual void SetFloat2(const std::string& name, const glm::vec2& value) override;
|
||||
virtual void SetFloat3(const std::string& name, const glm::vec3& value) override;
|
||||
virtual void SetInt(const std::string& name, int value) override;
|
||||
virtual void SetUInt(const std::string& name, unsigned int value) override;
|
||||
virtual void SetMat4(const std::string& name, const glm::mat4& value) override;
|
||||
|
||||
virtual void SetIntArray(const std::string& name, int* values, uint32_t size) override;
|
||||
@ -43,7 +44,6 @@ namespace Prism
|
||||
|
||||
const std::string& GetName() const override;
|
||||
|
||||
|
||||
private:
|
||||
void Load(const std::string& source);
|
||||
|
||||
@ -64,7 +64,9 @@ namespace Prism
|
||||
|
||||
static GLenum ShaderTypeFromString(const std::string& type);
|
||||
|
||||
void UploadUniformBool(const std::string& name, bool value) const;
|
||||
void UploadUniformInt(const std::string& name, int value) const;
|
||||
void UploadUniformUInt(const std::string& name, int value) const;
|
||||
void UploadUniformFloat(const std::string& name, float value) const;
|
||||
void UploadUniformFloat2(const std::string& name, const glm::vec2& values) const;
|
||||
void UploadUniformFloat3(const std::string& name, const glm::vec3& values) const;
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
#include "RenderPass.h"
|
||||
#include "glad/glad.h"
|
||||
#include "Prism/Core/Timer.h"
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
@ -40,6 +42,18 @@ namespace Prism
|
||||
Ref<RenderPass> CompositePass;
|
||||
Ref<RenderPass> BloomBlurPass[2];
|
||||
Ref<RenderPass> BloomBlendPass;
|
||||
Ref<RenderPass> LuminancePass;
|
||||
|
||||
// Auto exposure
|
||||
struct AutoExposure
|
||||
{
|
||||
float CurrentExposure = 1.0f;
|
||||
bool EnableAutoExposure = true;
|
||||
float Key = 0.18f; // middle gray
|
||||
float AdaptationSpeed = 1.0f; // stops per second
|
||||
Timer ExposureTimer;
|
||||
float MaxExposure = 5.0f;
|
||||
}AutoExposure;
|
||||
|
||||
Ref<Shader> ShadowMapShader, ShadowMapAnimShader;
|
||||
Ref<RenderPass> ShadowMapRenderPass[4];
|
||||
@ -89,15 +103,104 @@ namespace Prism
|
||||
float ShadowPass = 0.0f;
|
||||
float GeometryPass = 0.0f;
|
||||
float CompositePass = 0.0f;
|
||||
float AutoExposurePass = 0.0f;
|
||||
|
||||
Timer ShadowPassTimer;
|
||||
Timer GeometryPassTimer;
|
||||
Timer CompositePassTimer;
|
||||
Timer AutoExposurePassTimer;
|
||||
};
|
||||
|
||||
static SceneRendererData s_Data;
|
||||
static SceneRendererStats s_Stats;
|
||||
|
||||
static void ComputeAutoExposure()
|
||||
{
|
||||
if (!s_Data.AutoExposure.EnableAutoExposure)
|
||||
return;
|
||||
|
||||
auto srcFB = s_Data.GeoPass->GetSpecification().TargetFramebuffer;
|
||||
auto dstFB = s_Data.LuminancePass->GetSpecification().TargetFramebuffer;
|
||||
if (!srcFB || !dstFB)
|
||||
return;
|
||||
|
||||
const uint32_t srcID = srcFB->GetColorAttachmentRendererID();
|
||||
const uint32_t dstID = dstFB->GetColorAttachmentRendererID();
|
||||
const uint32_t width = dstFB->GetWidth();
|
||||
const uint32_t height = dstFB->GetHeight();
|
||||
|
||||
Renderer::Submit([srcID, dstID, width, height, srcFB]() mutable
|
||||
{
|
||||
// Use framebuffer blit to resolve multisampled source into non-multisampled luminance target.
|
||||
GLuint srcFBO = srcFB->GetRendererID();
|
||||
GLuint dstFBO = s_Data.LuminancePass->GetSpecification().TargetFramebuffer->GetRendererID();
|
||||
|
||||
// Bind read/draw FBOs and blit color attachment 0
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFBO);
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
|
||||
// Source size — try to use srcFB dimensions if available
|
||||
int srcWidth = srcFB->GetWidth();
|
||||
int srcHeight = srcFB->GetHeight();
|
||||
|
||||
glBlitFramebuffer(0, 0, srcWidth, srcHeight, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
// Unbind
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
|
||||
// Generate mipmaps so the smallest mip is the average color
|
||||
glGenerateTextureMipmap(dstID);
|
||||
|
||||
// Determine highest mip level
|
||||
int maxLevel = (int)std::floor(std::log2((float)std::max(width, height)));
|
||||
if (maxLevel < 0) maxLevel = 0;
|
||||
|
||||
float pixel[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
glGetTextureImage(dstID, maxLevel, GL_RGBA, GL_FLOAT, sizeof(pixel), pixel);
|
||||
|
||||
// Sanitize pixel values (handle NaN/Inf or negative values coming from GPU)
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
if (!std::isfinite(pixel[i]) || pixel[i] < 0.0f)
|
||||
pixel[i] = 0.0f;
|
||||
}
|
||||
|
||||
// Convert to luminance
|
||||
float lum = 0.2126f * pixel[0] + 0.7152f * pixel[1] + 0.0722f * pixel[2];
|
||||
if (!std::isfinite(lum) || lum <= 0.0f)
|
||||
lum = 1e-6f; // fallback minimum luminance
|
||||
|
||||
// Compute desired exposure (simple key/avg approach)
|
||||
const float key = s_Data.AutoExposure.Key;
|
||||
constexpr float minLum = 1e-6f;
|
||||
float desiredExposure = key / std::max(lum, minLum);
|
||||
desiredExposure = std::clamp(desiredExposure, 0.0001f, s_Data.AutoExposure.MaxExposure);
|
||||
|
||||
|
||||
// Adapt exposure over time (exponential)
|
||||
const float dt = s_Data.AutoExposure.ExposureTimer.ElapsedMillis() / 1000.0f;
|
||||
s_Data.AutoExposure.ExposureTimer.Reset();
|
||||
const float tau = s_Data.AutoExposure.AdaptationSpeed;
|
||||
const float adaptFactor = 1.0f - std::exp(-tau * dt);
|
||||
s_Data.AutoExposure.CurrentExposure = s_Data.AutoExposure.CurrentExposure + (desiredExposure - s_Data.AutoExposure.CurrentExposure) * adaptFactor;
|
||||
s_Data.AutoExposure.CurrentExposure = std::clamp(s_Data.AutoExposure.CurrentExposure, 0.0001f, s_Data.AutoExposure.MaxExposure);
|
||||
|
||||
// Write exposure directly into composite shader program uniform so the subsequent composite pass uses it
|
||||
/*
|
||||
if (const GLuint prog = s_Data.CompositeShader->GetRendererID())
|
||||
{
|
||||
const GLint loc = glGetUniformLocation(prog, "u_Exposure");
|
||||
if (loc >= 0)
|
||||
glProgramUniform1f(prog, loc, s_Data.CurrentExposure);
|
||||
}
|
||||
*/
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void SceneRenderer::Init()
|
||||
{
|
||||
FramebufferSpecification geoFramebufferSpec;
|
||||
@ -140,6 +243,21 @@ namespace Prism
|
||||
s_Data.BloomBlendShader = Shader::Create("assets/shaders/BloomBlend.glsl");
|
||||
s_Data.BRDFLUT = Texture2D::Create("assets/textures/BRDF_LUT.tga");
|
||||
|
||||
// Luminance pass: used to compute average scene luminance (for auto exposure)
|
||||
FramebufferSpecification luminanceFramebufferSpec;
|
||||
luminanceFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA16F };
|
||||
luminanceFramebufferSpec.ClearColor = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
RenderPassSpecification luminanceRenderPassSpec;
|
||||
luminanceRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(luminanceFramebufferSpec);
|
||||
s_Data.LuminancePass = RenderPass::Create(luminanceRenderPassSpec);
|
||||
|
||||
// Auto exposure defaults
|
||||
s_Data.AutoExposure.CurrentExposure = 1.0f;
|
||||
s_Data.AutoExposure.EnableAutoExposure = true;
|
||||
s_Data.AutoExposure.Key = 0.18f;
|
||||
s_Data.AutoExposure.AdaptationSpeed = 1.0f;
|
||||
s_Data.AutoExposure.ExposureTimer.Reset();
|
||||
|
||||
// Grid
|
||||
const auto gridShader = Shader::Create("assets/shaders/Grid.glsl");
|
||||
@ -200,6 +318,8 @@ namespace Prism
|
||||
{
|
||||
s_Data.GeoPass->GetSpecification().TargetFramebuffer->Resize(width, height);
|
||||
s_Data.CompositePass->GetSpecification().TargetFramebuffer->Resize(width, height);
|
||||
if (s_Data.LuminancePass)
|
||||
s_Data.LuminancePass->GetSpecification().TargetFramebuffer->Resize(width, height);
|
||||
}
|
||||
|
||||
void SceneRenderer::BeginScene(const Scene* scene, const SceneRendererCamera& camera)
|
||||
@ -361,40 +481,29 @@ namespace Prism
|
||||
memset(&s_Stats, 0, sizeof(SceneRendererStats));
|
||||
|
||||
{
|
||||
Renderer::Submit([]()
|
||||
{
|
||||
s_Stats.ShadowPassTimer.Reset();
|
||||
});
|
||||
Renderer::Submit([]() { s_Stats.ShadowPassTimer.Reset(); });
|
||||
ShadowMapPass();
|
||||
Renderer::Submit([]
|
||||
{
|
||||
s_Stats.ShadowPass = s_Stats.ShadowPassTimer.ElapsedMillis();
|
||||
});
|
||||
Renderer::Submit([] { s_Stats.ShadowPass = s_Stats.ShadowPassTimer.ElapsedMillis(); });
|
||||
}
|
||||
|
||||
{
|
||||
Renderer::Submit([]()
|
||||
{
|
||||
s_Stats.GeometryPassTimer.Reset();
|
||||
});
|
||||
Renderer::Submit([]() { s_Stats.GeometryPassTimer.Reset(); });
|
||||
GeometryPass();
|
||||
Renderer::Submit([]
|
||||
{
|
||||
s_Stats.GeometryPass = s_Stats.GeometryPassTimer.ElapsedMillis();
|
||||
});
|
||||
Renderer::Submit([] { s_Stats.GeometryPass = s_Stats.GeometryPassTimer.ElapsedMillis(); });
|
||||
}
|
||||
|
||||
// Compute average luminance and update exposure (GPU-copy + mipmap -> read 1 texel)
|
||||
{
|
||||
Renderer::Submit([]()
|
||||
{
|
||||
s_Stats.CompositePassTimer.Reset();
|
||||
});
|
||||
Renderer::Submit([]() { s_Stats.AutoExposurePassTimer.Reset(); });
|
||||
ComputeAutoExposure();
|
||||
Renderer::Submit([] { s_Stats.AutoExposurePass = s_Stats.AutoExposurePassTimer.ElapsedMillis(); });
|
||||
}
|
||||
|
||||
{
|
||||
Renderer::Submit([]() { s_Stats.CompositePassTimer.Reset(); });
|
||||
CompositePass();
|
||||
Renderer::Submit([]
|
||||
{
|
||||
s_Stats.CompositePass = s_Stats.CompositePassTimer.ElapsedMillis();
|
||||
});
|
||||
|
||||
BloomBlurPass();
|
||||
Renderer::Submit([] { s_Stats.CompositePass = s_Stats.CompositePassTimer.ElapsedMillis(); });
|
||||
BloomBlurPass();
|
||||
}
|
||||
|
||||
s_Data.DrawList.clear();
|
||||
@ -684,7 +793,7 @@ namespace Prism
|
||||
|
||||
Renderer::BeginRenderPass(s_Data.CompositePass);
|
||||
s_Data.CompositeShader->Bind();
|
||||
s_Data.CompositeShader->SetFloat("u_Exposure", s_Data.SceneData.SceneCamera.Camera.GetExposure());
|
||||
s_Data.CompositeShader->SetFloat("u_Exposure", s_Data.AutoExposure.EnableAutoExposure ? s_Data.AutoExposure.CurrentExposure : s_Data.SceneData.SceneCamera.Camera.GetExposure());
|
||||
s_Data.CompositeShader->SetInt("u_TextureSamples", s_Data.GeoPass->GetSpecification().TargetFramebuffer->GetSpecification().Samples);
|
||||
// s_Data.CompositeShader->SetFloat2("u_ViewportSize", glm::vec2(compositeBuffer->GetWidth(), compositeBuffer->GetHeight()));
|
||||
// s_Data.CompositeShader->SetFloat2("u_FocusPoint", s_Data.FocusPoint);
|
||||
@ -741,7 +850,8 @@ namespace Prism
|
||||
Renderer::BeginRenderPass(s_Data.BloomBlendPass);
|
||||
s_Data.BloomBlendShader->Bind();
|
||||
auto & adad =s_Data;
|
||||
s_Data.BloomBlendShader->SetFloat("u_Exposure", s_Data.SceneData.SceneCamera.Camera.GetExposure());
|
||||
// s_Data.BloomBlendShader->SetFloat("u_Exposure", s_Data.SceneData.SceneCamera.Camera.GetExposure());
|
||||
s_Data.CompositeShader->SetFloat("u_Exposure", s_Data.AutoExposure.EnableAutoExposure ? s_Data.AutoExposure.CurrentExposure : s_Data.SceneData.SceneCamera.Camera.GetExposure());
|
||||
s_Data.BloomBlendShader->SetBool("u_EnableBloom", s_Data.EnableBloom);
|
||||
|
||||
s_Data.CompositePass->GetSpecification().TargetFramebuffer->BindTexture(0);
|
||||
@ -796,7 +906,7 @@ namespace Prism
|
||||
cascadeSplits[i] = (d - nearClip) / clipRange;
|
||||
}
|
||||
|
||||
cascadeSplits[3] = 0.3f;
|
||||
// cascadeSplits[3] = 0.3f;
|
||||
|
||||
// Manually set cascades here
|
||||
// cascadeSplits[0] = 0.05f;
|
||||
@ -994,6 +1104,20 @@ namespace Prism
|
||||
UI::EndTreeNode();
|
||||
}
|
||||
|
||||
if (UI::BeginTreeNode("Auto Exposure"))
|
||||
{
|
||||
UI::Property("Auto Exposure Pass time: %.2fs", s_Stats.AutoExposurePass);
|
||||
|
||||
UI::BeginPropertyGrid();
|
||||
UI::Property("Enable Auto Exposure", s_Data.AutoExposure.EnableAutoExposure);
|
||||
UI::Property("Key (middle gray)", s_Data.AutoExposure.Key, 0.001f, 0.001f, 2.5f);
|
||||
UI::Property("Adaptation Speed", s_Data.AutoExposure.AdaptationSpeed, 0.01f, 0.001f, 5.0f);
|
||||
UI::Property("Current Exposure", s_Data.AutoExposure.CurrentExposure, 0.01f, 0.0f, 0.0f, true);
|
||||
UI::EndPropertyGrid();
|
||||
|
||||
UI::EndTreeNode();
|
||||
}
|
||||
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
@ -32,6 +32,7 @@ namespace Prism
|
||||
{
|
||||
public:
|
||||
static void Init();
|
||||
void InitAutoExposure();
|
||||
|
||||
static void SetViewportSize(uint32_t width, uint32_t height);
|
||||
|
||||
|
||||
@ -111,6 +111,7 @@ namespace Prism
|
||||
virtual void UploadUniformBuffer(const UniformBufferBase& uniformBuffer) = 0;
|
||||
|
||||
virtual void SetInt(const std::string& name, int value) = 0;
|
||||
virtual void SetUInt(const std::string& name, unsigned int value) = 0;
|
||||
virtual void SetBool(const std::string& name, bool value) = 0;
|
||||
virtual void SetFloat(const std::string& name, float value) = 0;
|
||||
virtual void SetFloat2(const std::string& name, const glm::vec2& value) = 0;
|
||||
|
||||
Reference in New Issue
Block a user