add args for entry Application; using efsw to replace custom filewatcher; remove some useless code; move FileOpenSelector from Application to FileSystem;some tweaks
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -32,3 +32,6 @@
|
||||
[submodule "Prism/vendor/ImViewGuizmo"]
|
||||
path = Prism/vendor/ImViewGuizmo
|
||||
url = https://github.com/Ka1serM/ImViewGuizmo
|
||||
[submodule "Prism/vendor/efsw"]
|
||||
path = Prism/vendor/efsw
|
||||
url = https://github.com/SpartanJ/efsw
|
||||
|
||||
@ -2,7 +2,7 @@ project(PrismEditor)
|
||||
|
||||
set(CMAKE_BINARY_DIR ${CMAKE_BINARY_DIR}/bin)
|
||||
|
||||
file(GLOB ASSETS assets)
|
||||
file(GLOB ASSETS "assets")
|
||||
file(COPY ${ASSETS} DESTINATION ${CMAKE_BINARY_DIR})
|
||||
|
||||
# imgui.ini file
|
||||
|
||||
@ -23,7 +23,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
Prism::Application* Prism::CreateApplication()
|
||||
Prism::Application* Prism::CreateApplication(const CommandArgs args)
|
||||
{
|
||||
return new Editor({"hello wrold", 1920, 1080});
|
||||
return new Editor({"hello world", 1920, 1080, args});
|
||||
}
|
||||
|
||||
@ -280,6 +280,31 @@ namespace Prism
|
||||
{
|
||||
auto& materials = mesh->GetMaterials();
|
||||
static uint32_t selectedMaterialIndex = 0;
|
||||
{
|
||||
ImGui::BeginChild("MaterialList", ImVec2(0, 150), ImGuiChildFlags_Borders);
|
||||
|
||||
static ImGuiTextFilter filter;
|
||||
filter.Draw("Filter", ImGui::GetContentRegionAvail().x);
|
||||
|
||||
if (ImGui::BeginListBox("##MaterialsListBox", ImVec2(-FLT_MIN, -FLT_MIN)))
|
||||
{
|
||||
for (uint32_t i = 0; i < materials.size(); i++)
|
||||
{
|
||||
const auto& materialInstance = materials[i];
|
||||
std::string name = materialInstance->GetName();
|
||||
|
||||
if (!filter.PassFilter(name.c_str()))
|
||||
continue;
|
||||
|
||||
bool isSelected = (selectedMaterialIndex == i);
|
||||
if (ImGui::Selectable(name.c_str(), isSelected))
|
||||
selectedMaterialIndex = i;
|
||||
}
|
||||
ImGui::EndListBox();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
/*
|
||||
for (uint32_t i = 0; i < materials.size(); i++)
|
||||
{
|
||||
const auto& materialInstance = materials[i];
|
||||
@ -294,6 +319,7 @@ namespace Prism
|
||||
ImGui::TreePop();
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
@ -327,8 +353,7 @@ namespace Prism
|
||||
}
|
||||
if (ImGui::IsItemClicked())
|
||||
{
|
||||
std::string filename = Application::Get().OpenFile("");
|
||||
if (filename != "")
|
||||
if (std::string filename = FileSystem::OpenFileSelector("*.png;*.tga;*.jpg;*.jpeg"); !filename.empty())
|
||||
{
|
||||
albedoMap = Texture2D::Create(filename, true/*m_AlbedoInput.SRGB*/);
|
||||
materialInstance->Set("u_AlbedoTexture", albedoMap);
|
||||
@ -374,8 +399,7 @@ namespace Prism
|
||||
}
|
||||
if (ImGui::IsItemClicked())
|
||||
{
|
||||
std::string filename = Application::Get().OpenFile("");
|
||||
if (filename != "")
|
||||
if (std::string filename = FileSystem::OpenFileSelector("*.png;*.tga;*.jpg;*.jpeg"); !filename.empty())
|
||||
{
|
||||
normalMap = Texture2D::Create(filename);
|
||||
materialInstance->Set("u_NormalTexture", normalMap);
|
||||
@ -412,8 +436,7 @@ namespace Prism
|
||||
}
|
||||
if (ImGui::IsItemClicked())
|
||||
{
|
||||
std::string filename = Application::Get().OpenFile("");
|
||||
if (filename != "")
|
||||
if (std::string filename = FileSystem::OpenFileSelector("*.png;*.tga;*.jpg;*.jpeg"); !filename.empty())
|
||||
{
|
||||
metalnessMap = Texture2D::Create(filename);
|
||||
materialInstance->Set("u_MetalnessTexture", metalnessMap);
|
||||
@ -451,8 +474,7 @@ namespace Prism
|
||||
}
|
||||
if (ImGui::IsItemClicked())
|
||||
{
|
||||
std::string filename = Application::Get().OpenFile("");
|
||||
if (filename != "")
|
||||
if (std::string filename = FileSystem::OpenFileSelector("*.png;*.tga;*.jpg;*.jpeg"); !filename.empty())
|
||||
{
|
||||
roughnessMap = Texture2D::Create(filename);
|
||||
materialInstance->Set("u_RoughnessTexture", roughnessMap);
|
||||
@ -493,31 +515,13 @@ namespace Prism
|
||||
UI::BeginPropertyGrid();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
|
||||
auto& light = m_EditorScene->GetLight();
|
||||
UI::PropertySlider("Light Direction", light.Direction, -1.0f, 1.0f);
|
||||
UI::PropertyColor("Light Radiance", light.Radiance);
|
||||
UI::PropertySlider("Light Multiplier", light.Multiplier, 0.0f, 5.0f);
|
||||
|
||||
UI::PropertySlider("Exposure", m_EditorCamera.GetExposure(), 0.0f, 5.0f);
|
||||
|
||||
UI::Property("Radiance Prefiltering", m_RadiancePrefilter);
|
||||
UI::PropertySlider("Env Map Rotation", m_EnvMapRotation, -360.0f, 360.0f);
|
||||
|
||||
if (m_SceneState == SceneState::Edit)
|
||||
float physics2DGravity = m_EditorScene->GetPhysics2DGravity();
|
||||
if (UI::Property("2D World Gravity", physics2DGravity, -100.0f, 100.0f))
|
||||
{
|
||||
float physics2DGravity = m_EditorScene->GetPhysics2DGravity();
|
||||
if (UI::Property("2D World Gravity", physics2DGravity, -10000.0f, 10000.0f))
|
||||
{
|
||||
m_EditorScene->SetPhysics2DGravity(physics2DGravity);
|
||||
}
|
||||
}
|
||||
else if (m_SceneState == SceneState::Play)
|
||||
{
|
||||
float physics2DGravity = m_RuntimeScene->GetPhysics2DGravity();
|
||||
if (UI::Property("2D World Gravity", physics2DGravity, -10000.0f, 10000.0f))
|
||||
{
|
||||
m_RuntimeScene->SetPhysics2DGravity(physics2DGravity);
|
||||
}
|
||||
m_EditorScene->SetPhysics2DGravity(physics2DGravity);
|
||||
}
|
||||
|
||||
UI::Property("Show Bounding Boxes", m_UIShowBoundingBoxes);
|
||||
@ -579,6 +583,15 @@ namespace Prism
|
||||
m_ViewportPanelHovered = ImGui::IsWindowHovered();
|
||||
m_ViewportPanelFocused = ImGui::IsWindowFocused();
|
||||
|
||||
if (!m_ViewportPanelFocused && m_ViewportPanelHovered)
|
||||
{
|
||||
if (Input::IsMouseButtonPressed(MouseButton::Right))
|
||||
{
|
||||
ImGui::SetWindowFocus("Viewport");
|
||||
m_ViewportPanelFocused = true;
|
||||
}
|
||||
}
|
||||
|
||||
auto viewportOffset = ImGui::GetCursorPos(); // includes tab bar
|
||||
auto viewportSize = ImGui::GetContentRegionAvail();
|
||||
|
||||
@ -693,7 +706,7 @@ namespace Prism
|
||||
}
|
||||
}else
|
||||
{
|
||||
glm::mat4 transformBase = transform * selection.Mesh->Transform;
|
||||
glm::mat4 transformBase = transform * selection.Mesh->LocalTransform;
|
||||
ImGuizmo::Manipulate(glm::value_ptr(m_EditorCamera.GetViewMatrix()),
|
||||
glm::value_ptr(m_EditorCamera.GetProjectionMatrix()),
|
||||
(ImGuizmo::OPERATION)m_GizmoType,
|
||||
@ -704,6 +717,7 @@ namespace Prism
|
||||
|
||||
if (ImGuizmo::IsUsing())
|
||||
{
|
||||
selection.Mesh->LocalTransform = glm::inverse(entityTransform.GetTransform()) * transformBase;
|
||||
selection.Mesh->Transform = glm::inverse(entityTransform.GetTransform()) * transformBase;
|
||||
}
|
||||
}
|
||||
@ -950,7 +964,7 @@ namespace Prism
|
||||
case KeyCode::B:
|
||||
// Toggle bounding boxes
|
||||
m_UIShowBoundingBoxes = !m_UIShowBoundingBoxes;
|
||||
ShowBoundingBoxes(m_UIShowBoundingBoxes,false);
|
||||
ShowBoundingBoxes(m_UIShowBoundingBoxes);
|
||||
break;
|
||||
case KeyCode::D:
|
||||
if (m_SelectionContext.size())
|
||||
@ -1059,9 +1073,9 @@ namespace Prism
|
||||
return false;
|
||||
}
|
||||
|
||||
void EditorLayer::ShowBoundingBoxes(bool show, bool onTop)
|
||||
void EditorLayer::ShowBoundingBoxes(const bool show)
|
||||
{
|
||||
SceneRenderer::GetOptions().ShowBoundingBoxes = show && !onTop;
|
||||
SceneRenderer::GetOptions().ShowBoundingBoxes = show;
|
||||
}
|
||||
|
||||
void EditorLayer::SelectEntity(Entity entity)
|
||||
@ -1157,9 +1171,7 @@ namespace Prism
|
||||
|
||||
void EditorLayer::OpenScene()
|
||||
{
|
||||
const auto& app = Application::Get();
|
||||
const std::string filepath = app.OpenFile("Hazel Scene (*.hsc)\0*.hsc\0");
|
||||
if (!filepath.empty())
|
||||
if (const std::string filepath = FileSystem::OpenFileSelector("*.scene"); !filepath.empty())
|
||||
OpenScene(filepath);
|
||||
}
|
||||
|
||||
@ -1199,8 +1211,7 @@ namespace Prism
|
||||
void EditorLayer::SaveSceneAs()
|
||||
{
|
||||
const auto& app = Application::Get();
|
||||
const std::string filepath = app.SaveFile("Prism Scene (*.hsc)\0*.hsc\0");
|
||||
if (!filepath.empty())
|
||||
if (const std::string filepath = FileSystem::SaveFileSelector("*.scene"); !filepath.empty())
|
||||
{
|
||||
PM_CLIENT_INFO("Saving scene to: {0}", m_SceneFilePath);
|
||||
SceneSerializer serializer(m_EditorScene);
|
||||
|
||||
@ -28,7 +28,7 @@ namespace Prism
|
||||
bool OnKeyPressedEvent(KeyPressedEvent& e);
|
||||
bool OnMouseButtonPressedEvent(MouseButtonPressedEvent& e);
|
||||
|
||||
void ShowBoundingBoxes(bool show, bool onTop = false);
|
||||
void ShowBoundingBoxes(bool show);
|
||||
void SelectEntity(Entity entity);
|
||||
|
||||
void UpdateWindowTitle(const std::string& sceneName);
|
||||
@ -126,10 +126,6 @@ namespace Prism
|
||||
|
||||
|
||||
// PBR params
|
||||
bool m_RadiancePrefilter = false;
|
||||
|
||||
float m_EnvMapRotation = 0.0f;
|
||||
|
||||
|
||||
// Editor resources
|
||||
Ref<Texture2D> m_CheckerboardTex;
|
||||
|
||||
@ -18,6 +18,7 @@ add_subdirectory(vendor/mono EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(vendor/FastNoise EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(vendor/yaml-cpp EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(vendor/Box2D EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(vendor/efsw EXCLUDE_FROM_ALL)
|
||||
|
||||
|
||||
# ------------- imgui -------------
|
||||
@ -91,6 +92,7 @@ set(LINK_LIBRARIES_PRIVATE
|
||||
tinyFileDialogs
|
||||
FastNoise
|
||||
yaml-cpp
|
||||
efsw
|
||||
|
||||
PhysXExtensions_static_64
|
||||
PhysX_static_64
|
||||
|
||||
@ -303,11 +303,11 @@ namespace Prism
|
||||
return newFileName;
|
||||
}
|
||||
|
||||
void AssetsManager::ImportAsset(const std::string& filepath, AssetHandle parentHandle)
|
||||
Ref<Asset> AssetsManager::ImportAsset(const std::string& filepath, AssetHandle parentHandle)
|
||||
{
|
||||
const std::string extension = Utils::GetExtension(filepath);
|
||||
if (extension == "meta")
|
||||
return;
|
||||
return Ref<Asset>();
|
||||
|
||||
const AssetType type = AssetTypes::GetAssetTypeFromExtension(extension);
|
||||
Ref<Asset> asset = AssetSerializer::LoadAssetInfo(filepath, parentHandle, type);
|
||||
@ -320,10 +320,12 @@ namespace Prism
|
||||
}
|
||||
|
||||
s_LoadedAssets[asset->Handle] = asset;
|
||||
|
||||
return asset;
|
||||
}
|
||||
|
||||
|
||||
AssetHandle AssetsManager::ProcessDirectory(const std::string& directoryPath, AssetHandle parentHandle)
|
||||
Ref<Asset> AssetsManager::ProcessDirectory(const std::string& directoryPath, AssetHandle parentHandle)
|
||||
{
|
||||
Ref<Directory> dirInfo = AssetSerializer::LoadAssetInfo(directoryPath, parentHandle, AssetType::Directory).As<Directory>();
|
||||
s_LoadedAssets[dirInfo->Handle] = dirInfo;
|
||||
@ -336,15 +338,17 @@ namespace Prism
|
||||
if (entry.is_directory())
|
||||
ProcessDirectory(entry.path().string(), dirInfo->Handle);
|
||||
else
|
||||
ImportAsset(entry.path().string(), dirInfo->Handle);
|
||||
{
|
||||
Ref<Asset> asset = ImportAsset(entry.path().string(), dirInfo->Handle);
|
||||
}
|
||||
}
|
||||
|
||||
return dirInfo->Handle;
|
||||
return dirInfo;
|
||||
}
|
||||
|
||||
void AssetsManager::ReloadAssets()
|
||||
Ref<Asset> AssetsManager::ReloadAssets()
|
||||
{
|
||||
ProcessDirectory("assets", 0);
|
||||
return ProcessDirectory("assets", 0);
|
||||
}
|
||||
|
||||
void AssetsManager::OnFileSystemChanged(FileSystemChangedEvent e)
|
||||
@ -363,35 +367,70 @@ namespace Prism
|
||||
if (e.IsDirectory)
|
||||
ProcessDirectory(e.FilePath, parentHandle);
|
||||
else
|
||||
ImportAsset(e.FilePath, parentHandle);
|
||||
{
|
||||
Ref<Asset> asset = ImportAsset(e.FilePath, parentHandle);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case FileSystemAction::Modified:
|
||||
{
|
||||
if (!e.IsDirectory)
|
||||
ImportAsset(e.FilePath, parentHandle);
|
||||
{
|
||||
Ref<Asset> asset = ImportAsset(e.FilePath, parentHandle);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FileSystemAction::Rename:
|
||||
{
|
||||
Ref<Asset> asset;
|
||||
|
||||
for (auto it = s_LoadedAssets.begin(); it != s_LoadedAssets.end(); it++)
|
||||
{
|
||||
if (it->second->FileName == e.OldName)
|
||||
{
|
||||
it->second->FilePath = e.FilePath;
|
||||
it->second->FileName = e.NewName;
|
||||
asset = it->second;
|
||||
}
|
||||
}
|
||||
|
||||
if (asset)
|
||||
{
|
||||
if (asset->Type != AssetTypes::GetAssetTypeFromExtension(Utils::GetExtension(e.FilePath)))
|
||||
{
|
||||
RemoveAsset(asset->Handle);
|
||||
FileSystem::PrismDeleteFile(asset->FilePath + ".meta");
|
||||
asset = ImportAsset(e.FilePath, parentHandle);
|
||||
}else
|
||||
{
|
||||
std::string oldMetaPath = asset->FilePath + ".meta";
|
||||
std::string newMetaPath = e.FilePath + ".meta";
|
||||
|
||||
std::error_code ec;
|
||||
std::filesystem::rename(oldMetaPath, newMetaPath, ec);
|
||||
if (ec)
|
||||
{
|
||||
PM_CORE_ERROR("Failed to rename meta file: {}", ec.message());
|
||||
}
|
||||
|
||||
asset->FilePath = e.FilePath;
|
||||
asset->FileName = e.NewName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case FileSystemAction::Delete:
|
||||
{
|
||||
for (auto it = s_LoadedAssets.begin(); it != s_LoadedAssets.end(); it++)
|
||||
{
|
||||
if (it->second->FilePath != e.FilePath)
|
||||
std::string filePath = Utils::NormalizePath(it->second->FilePath);
|
||||
std::string eFilePath = Utils::NormalizePath(e.FilePath);
|
||||
if (filePath != eFilePath)
|
||||
continue;
|
||||
|
||||
RemoveAsset(it->first);
|
||||
FileSystem::PrismDeleteFile(eFilePath + ".meta");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include "Asset.h"
|
||||
#include "Prism/Utilities/FileSystem.h"
|
||||
#include "Prism/Core/Ref.h"
|
||||
#include "Prism/Project/Project.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
@ -66,9 +67,14 @@ namespace Prism
|
||||
|
||||
private:
|
||||
|
||||
static void ImportAsset(const std::string& filepath, AssetHandle parentHandle);
|
||||
static AssetHandle ProcessDirectory(const std::string& directoryPath, AssetHandle parentHandle);
|
||||
static void ReloadAssets();
|
||||
static Ref<Asset> ImportAsset(const std::string& filepath, AssetHandle parentHandle);
|
||||
static Ref<Asset> ProcessDirectory(const std::string& directoryPath, AssetHandle parentHandle);
|
||||
/**
|
||||
* this will load from projectPath all assets, and return the root Asset Ref
|
||||
* @param projectPath assets path
|
||||
* @return the root asset Ref
|
||||
*/
|
||||
static Ref<Asset> ReloadAssets();
|
||||
|
||||
static void OnFileSystemChanged(FileSystemChangedEvent e);
|
||||
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
#include "GLFW/glfw3.h"
|
||||
#include "Prism/Renderer/FrameBuffer.h"
|
||||
|
||||
#include "tinyfiledialogs.h"
|
||||
#include "Prism/Physics/Physics3D.h"
|
||||
#include "Prism/Script/ScriptEngine.h"
|
||||
#include "Prism/Asset/AssetsManager.h"
|
||||
@ -28,6 +27,10 @@ namespace Prism
|
||||
|
||||
Application::Application(const ApplicationProps& props)
|
||||
{
|
||||
if (s_Instance != nullptr)
|
||||
{
|
||||
PM_CORE_ASSERT(false, "Application already exists!");
|
||||
}
|
||||
s_Instance = this;
|
||||
|
||||
m_Window = std::unique_ptr<Window>(Window::Create(WindowProps{props.Name, props.Width, props.Height}));
|
||||
@ -101,6 +104,9 @@ namespace Prism
|
||||
{
|
||||
m_ImGuiLayer->Begin();
|
||||
|
||||
for (Layer* layer : m_LayerStack)
|
||||
layer->OnImGuiRender();
|
||||
|
||||
ImGui::Begin("Renderer");
|
||||
const auto& caps = RendererAPI::GetCapabilities();
|
||||
ImGui::Text("Vendor: %s", caps.Vendor.c_str());
|
||||
@ -109,90 +115,9 @@ namespace Prism
|
||||
ImGui::Text("Frame Time: %.2fms\n", m_TimeStep.GetMilliseconds());
|
||||
ImGui::End();
|
||||
|
||||
for (Layer* layer : m_LayerStack)
|
||||
layer->OnImGuiRender();
|
||||
|
||||
m_ImGuiLayer->End();
|
||||
}
|
||||
|
||||
// TODO: fix this to prase filter
|
||||
std::string Application::OpenFile(const std::string& filter) const
|
||||
{
|
||||
// TODO: will move it to other folder
|
||||
// 处理过滤器
|
||||
std::vector<const char*> filterPatterns;
|
||||
std::vector<std::string> patternStorage;
|
||||
|
||||
if (!filter.empty()) {
|
||||
const char* ptr = filter.c_str();
|
||||
bool isDescription = true;
|
||||
|
||||
while (*ptr) {
|
||||
if (isDescription) {
|
||||
// 跳过描述
|
||||
isDescription = false;
|
||||
} else {
|
||||
// 添加模式
|
||||
patternStorage.push_back(ptr);
|
||||
isDescription = true;
|
||||
}
|
||||
ptr += strlen(ptr) + 1;
|
||||
}
|
||||
|
||||
// 转换为 C 字符串数组
|
||||
for (const auto& pattern : patternStorage) {
|
||||
filterPatterns.push_back(pattern.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有过滤器,添加默认值
|
||||
if (filterPatterns.empty()) {
|
||||
filterPatterns.push_back("*");
|
||||
}
|
||||
|
||||
// 构建过滤器描述
|
||||
std::string filterDesc;
|
||||
if (!patternStorage.empty()) {
|
||||
std::stringstream ss;
|
||||
ss << "Files (";
|
||||
for (size_t i = 0; i < patternStorage.size(); ++i) {
|
||||
if (i > 0) ss << ",";
|
||||
ss << patternStorage[i];
|
||||
}
|
||||
ss << ")";
|
||||
filterDesc = ss.str();
|
||||
}
|
||||
|
||||
const char* result = tinyfd_openFileDialog(
|
||||
"Open File", // 对话框标题
|
||||
nullptr, // 初始路径,nullptr 表示使用默认
|
||||
0, // 过滤器数量 (注意:这里需要根据解析情况调整,见下文)
|
||||
nullptr, // 过滤器模式数组
|
||||
nullptr, // 过滤器描述
|
||||
0 // 是否允许多选:0 为单选,1 为多选
|
||||
);
|
||||
|
||||
// 调用文件对话框
|
||||
/*
|
||||
const char* result = tinyfd_openFileDialog(
|
||||
"Open File", // 标题
|
||||
nullptr, // 初始目录
|
||||
static_cast<int>(filterPatterns.size()), // 过滤器数量
|
||||
filterPatterns.data(), // 过滤器模式
|
||||
filterDesc.empty() ? nullptr : filterDesc.c_str(), // 描述
|
||||
0 // 单选
|
||||
);
|
||||
*/
|
||||
|
||||
return result ? std::string(result) : std::string();
|
||||
|
||||
}
|
||||
|
||||
std::string Application::SaveFile(const std::string& filter) const
|
||||
{
|
||||
return OpenFile(filter);
|
||||
}
|
||||
|
||||
Application& Application::Get()
|
||||
{
|
||||
return *s_Instance;
|
||||
|
||||
@ -13,10 +13,29 @@
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
class Project;
|
||||
|
||||
struct CommandArgs
|
||||
{
|
||||
int count = 0;
|
||||
char** args = nullptr;
|
||||
|
||||
const char* operator[](const int index)
|
||||
{
|
||||
if (index >= count)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return args[count];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct ApplicationProps
|
||||
{
|
||||
std::string Name;
|
||||
uint32_t Width, Height;
|
||||
CommandArgs CommandArgs;
|
||||
};
|
||||
|
||||
class PRISM_API Application
|
||||
@ -35,9 +54,6 @@ namespace Prism
|
||||
|
||||
void RenderImGui();
|
||||
|
||||
std::string OpenFile(const std::string& filter = "All\0*.*\0") const;
|
||||
std::string SaveFile(const std::string& filter = "All\0*.*\0") const;
|
||||
|
||||
inline Window& GetWindow() { return *m_Window; }
|
||||
|
||||
static Application& Get();
|
||||
@ -70,7 +86,7 @@ namespace Prism
|
||||
|
||||
|
||||
// this function will implemented by client
|
||||
Application* CreateApplication();
|
||||
Application* CreateApplication(CommandArgs args);
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
|
||||
@ -5,17 +5,26 @@
|
||||
#ifndef ENTRYPOINT_H
|
||||
#define ENTRYPOINT_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
extern Prism::Application* Prism::CreateApplication();
|
||||
extern Prism::Application* Prism::CreateApplication(CommandArgs args);
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
//TODO: this will use other method to impl
|
||||
std::cout << std::filesystem::current_path() << std::endl;
|
||||
std::filesystem::current_path(std::filesystem::path(argv[0]).parent_path());
|
||||
std::cout << std::filesystem::current_path() << std::endl;
|
||||
|
||||
#ifdef PRISM_STATIC
|
||||
Prism::InitializeCore();
|
||||
#endif
|
||||
|
||||
Prism::Application* app = Prism::CreateApplication();
|
||||
const Prism::CommandArgs args{ argc, argv };
|
||||
|
||||
Prism::Application* app = Prism::CreateApplication(args);
|
||||
app->Run();
|
||||
delete app;
|
||||
|
||||
|
||||
@ -10,9 +10,11 @@
|
||||
#include "spdlog/sinks/stdout_color_sinks-inl.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define LOG_LEVEL spdlog::level::trace
|
||||
#define LOG_LEVEL spdlog::level::trace
|
||||
#define LOG_PATTERN "%^[%@:%#][%Y-%m-%d %H:%M:%S.%e] [%l] %v%$"
|
||||
#else
|
||||
#define LOG_LEVEL spdlog::level::trace
|
||||
#define LOG_PATTERN "%^[%Y-%m-%d %H:%M:%S.%e] [%l] %v%$"
|
||||
#endif
|
||||
|
||||
namespace Prism
|
||||
@ -40,11 +42,11 @@ namespace Prism
|
||||
|
||||
s_CoreLogger = std::make_shared<spdlog::logger>("PRISM", prismSinks.begin(), prismSinks.end());
|
||||
s_CoreLogger->set_level(LOG_LEVEL);
|
||||
s_CoreLogger->set_pattern("%^[%Y-%m-%d %H:%M:%S.%e] [%l] %v%$");
|
||||
s_CoreLogger->set_pattern(LOG_PATTERN);
|
||||
|
||||
s_ClientLogger = std::make_shared<spdlog::logger>("APP", appSinks.begin(), appSinks.end());
|
||||
s_ClientLogger->set_level(LOG_LEVEL);
|
||||
s_CoreLogger->set_pattern("%^[%Y-%m-%d %H:%M:%S.%e] [%l] %v%$");
|
||||
s_ClientLogger->set_pattern(LOG_PATTERN);
|
||||
}
|
||||
|
||||
void Log::Shutdown()
|
||||
|
||||
@ -25,13 +25,22 @@ namespace Prism
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define PM_CORE_TRACE(...) SPDLOG_LOGGER_TRACE(::Prism::Log::GetCoreLogger(), __VA_ARGS__)
|
||||
#define PM_CORE_DEBUG(...) SPDLOG_LOGGER_DEBUG(::Prism::Log::GetCoreLogger(), __VA_ARGS__)
|
||||
#define PM_CORE_INFO(...) SPDLOG_LOGGER_INFO(::Prism::Log::GetCoreLogger(), __VA_ARGS__)
|
||||
#define PM_CORE_WARN(...) SPDLOG_LOGGER_WARN(::Prism::Log::GetCoreLogger(), __VA_ARGS__)
|
||||
#define PM_CORE_ERROR(...) SPDLOG_LOGGER_ERROR(::Prism::Log::GetCoreLogger(), __VA_ARGS__)
|
||||
#define PM_CORE_FATAL(...) SPDLOG_LOGGER_CRITICAL(::Prism::Log::GetCoreLogger(), __VA_ARGS__)
|
||||
#else
|
||||
#define PM_CORE_TRACE(...) ::Prism::Log::GetCoreLogger()->trace(__VA_ARGS__)
|
||||
#define PM_CORE_DEBUG(...) ::Prism::Log::GetCoreLogger()->debug( __VA_ARGS__)
|
||||
#define PM_CORE_INFO(...) ::Prism::Log::GetCoreLogger()->info(__VA_ARGS__)
|
||||
#define PM_CORE_WARN(...) ::Prism::Log::GetCoreLogger()->warn(__VA_ARGS__)
|
||||
#define PM_CORE_ERROR(...) ::Prism::Log::GetCoreLogger()->error(__VA_ARGS__)
|
||||
#define PM_CORE_FATAL(...) ::Prism::Log::GetCoreLogger()->critical(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define PM_CORE_TRACE(...) ::Prism::Log::GetCoreLogger()->trace(__VA_ARGS__)
|
||||
#define PM_CORE_DEBUG(...) ::Prism::Log::GetCoreLogger()->debug( __VA_ARGS__)
|
||||
#define PM_CORE_INFO(...) ::Prism::Log::GetCoreLogger()->info(__VA_ARGS__)
|
||||
#define PM_CORE_WARN(...) ::Prism::Log::GetCoreLogger()->warn(__VA_ARGS__)
|
||||
#define PM_CORE_ERROR(...) ::Prism::Log::GetCoreLogger()->error(__VA_ARGS__)
|
||||
#define PM_CORE_FATAL(...) ::Prism::Log::GetCoreLogger()->critical(__VA_ARGS__)
|
||||
|
||||
#define PM_CLIENT_TRACE(...) ::Prism::Log::GetClientLogger()->trace(__VA_ARGS__)
|
||||
#define PM_CLIENT_DEBUG(...) ::Prism::Log::GetClientLogger()->debug(__VA_ARGS__)
|
||||
|
||||
@ -133,7 +133,7 @@ namespace Prism
|
||||
|
||||
if (ImGui::MenuItem("Import"))
|
||||
{
|
||||
//std::string filename = Application::Get().OpenFile("");
|
||||
// std::string filename = FileSystem::OpenFileSelector();
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Refresh"))
|
||||
|
||||
@ -9,16 +9,158 @@
|
||||
#include <Windows.h>
|
||||
#include <filesystem>
|
||||
|
||||
#include "tinyfiledialogs.h"
|
||||
#include <sstream>
|
||||
#include "Prism/Core/Log.h"
|
||||
#include "Prism/Asset/AssetsManager.h"
|
||||
#include "Prism/Core/Application.h"
|
||||
|
||||
#include "efsw/efsw.hpp"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
FileSystem::FileSystemChangedCallbackFn FileSystem::s_Callback;
|
||||
|
||||
static bool s_Watching = true;
|
||||
static bool s_IgnoreNextChange = false;
|
||||
static HANDLE s_WatcherThread;
|
||||
std::atomic<bool> FileSystem::s_IgnoreNextChange = false;
|
||||
efsw::FileWatcher* FileSystem::s_FileWatcher = nullptr;
|
||||
PrismFileWatcherListener* FileSystem::s_Listener = nullptr;
|
||||
|
||||
class PrismFileWatcherListener : public efsw::FileWatchListener
|
||||
{
|
||||
public:
|
||||
void handleFileAction(efsw::WatchID watchid,
|
||||
const std::string& dir,
|
||||
const std::string& filename,
|
||||
efsw::Action action,
|
||||
std::string oldFilename = "") override
|
||||
{
|
||||
// 如果引擎自身操作设置了忽略标志,则跳过本次事件
|
||||
if (FileSystem::s_IgnoreNextChange.load())
|
||||
return;
|
||||
|
||||
std::filesystem::path fullPath = std::filesystem::path(dir) / filename;
|
||||
|
||||
FileSystemChangedEvent e;
|
||||
e.FilePath = fullPath.string();
|
||||
e.NewName = filename;
|
||||
e.OldName = oldFilename; // efsw 在重命名时会提供旧文件名
|
||||
e.IsDirectory = false; // 稍后根据实际情况判断
|
||||
|
||||
// 判断是否为目录(可能抛出异常,使用 error_code 版本)
|
||||
std::error_code ec;
|
||||
if (std::filesystem::is_directory(fullPath, ec))
|
||||
e.IsDirectory = true;
|
||||
// 如果 ec 有错误(文件可能已被删除),保持 false
|
||||
|
||||
// 映射 efsw 动作到你的枚举
|
||||
switch (action)
|
||||
{
|
||||
case efsw::Actions::Add:
|
||||
e.Action = FileSystemAction::Added;
|
||||
break;
|
||||
case efsw::Actions::Delete:
|
||||
e.Action = FileSystemAction::Delete;
|
||||
break;
|
||||
case efsw::Actions::Modified:
|
||||
e.Action = FileSystemAction::Modified;
|
||||
break;
|
||||
case efsw::Actions::Moved:
|
||||
e.Action = FileSystemAction::Rename;
|
||||
break;
|
||||
default:
|
||||
return; // 忽略未知事件
|
||||
}
|
||||
|
||||
// 调用外部回调(需确保线程安全)
|
||||
if (FileSystem::s_Callback)
|
||||
FileSystem::s_Callback(e);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
std::string FileSystem::OpenFileSelector(const std::string& filter)
|
||||
{
|
||||
std::vector<const char*> patternCstrs;
|
||||
std::vector<std::string> patterns;
|
||||
std::string description = "All files (*.*)";
|
||||
|
||||
if (!filter.empty() && filter != "*.*") {
|
||||
std::istringstream iss(filter);
|
||||
std::string token;
|
||||
while (std::getline(iss, token, ';')) {
|
||||
if (!token.empty()) {
|
||||
patterns.push_back(token);
|
||||
}
|
||||
}
|
||||
|
||||
// 构建描述文字
|
||||
if (!patterns.empty()) {
|
||||
description = "Custom files (";
|
||||
for (size_t i = 0; i < patterns.size(); ++i) {
|
||||
if (i > 0) description += "; ";
|
||||
description += patterns[i];
|
||||
}
|
||||
description += ")";
|
||||
|
||||
// 准备 C 字符串数组
|
||||
for (const auto& p : patterns) {
|
||||
patternCstrs.push_back(p.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* result = tinyfd_openFileDialog(
|
||||
"Open File", // title
|
||||
"", // default open path
|
||||
static_cast<int>(patternCstrs.size()), // filter count
|
||||
patternCstrs.empty() ? nullptr : patternCstrs.data(), // filter pattern
|
||||
description.c_str(), // filter description
|
||||
0 // 0 is single select, 1 is Multiple select
|
||||
);
|
||||
|
||||
return result ? std::string(result) : std::string();
|
||||
}
|
||||
|
||||
std::string FileSystem::SaveFileSelector(const std::string& filter)
|
||||
{
|
||||
std::vector<const char*> patternCstrs;
|
||||
std::string description = "All files (*.*)";
|
||||
std::vector<std::string> patterns;
|
||||
|
||||
if (!filter.empty() && filter != "*.*") {
|
||||
std::istringstream iss(filter);
|
||||
std::string token;
|
||||
while (std::getline(iss, token, ';')) {
|
||||
if (!token.empty()) {
|
||||
patterns.push_back(token);
|
||||
}
|
||||
}
|
||||
|
||||
if (!patterns.empty()) {
|
||||
description = "Custom files (";
|
||||
for (size_t i = 0; i < patterns.size(); ++i) {
|
||||
if (i > 0) description += "; ";
|
||||
description += patterns[i];
|
||||
}
|
||||
description += ")";
|
||||
|
||||
for (const auto& p : patterns) {
|
||||
patternCstrs.push_back(p.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* result = tinyfd_saveFileDialog(
|
||||
"Save File",
|
||||
"",
|
||||
static_cast<int>(patternCstrs.size()),
|
||||
patternCstrs.empty() ? nullptr : patternCstrs.data(),
|
||||
description.c_str()
|
||||
);
|
||||
|
||||
return result ? std::string(result) : std::string();
|
||||
}
|
||||
|
||||
|
||||
bool FileSystem::CreateFolder(const std::filesystem::path& filepath)
|
||||
{
|
||||
@ -54,57 +196,29 @@ namespace Prism
|
||||
s_Callback = callback;
|
||||
}
|
||||
|
||||
/*
|
||||
static std::string wchar_to_string(wchar_t* input)
|
||||
{
|
||||
std::wstring string_input(input);
|
||||
std::string converted(string_input.begin(), string_input.end());
|
||||
return converted;
|
||||
}
|
||||
*/
|
||||
|
||||
static std::string wchar_to_string(const wchar_t* input)
|
||||
{
|
||||
if (!input) return {};
|
||||
|
||||
const int bufferSize = WideCharToMultiByte(CP_UTF8, 0, input, -1, nullptr, 0, nullptr, nullptr);
|
||||
if (bufferSize == 0) return {};
|
||||
|
||||
std::string result(bufferSize, 0);
|
||||
WideCharToMultiByte(CP_UTF8, 0, input, -1, &result[0], bufferSize, nullptr, nullptr);
|
||||
|
||||
// 移除末尾的null终止符
|
||||
result.pop_back();
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string FileSystem::Rename(const std::string& filepath, const std::string& newName)
|
||||
{
|
||||
s_IgnoreNextChange = true;
|
||||
std::filesystem::path p = filepath;
|
||||
const std::filesystem::path p = filepath;
|
||||
std::string newFilePath = p.parent_path().string() + "/" + newName + p.extension().string();
|
||||
MoveFileA(filepath.c_str(), newFilePath.c_str());
|
||||
s_IgnoreNextChange = false;
|
||||
return newFilePath;
|
||||
}
|
||||
|
||||
|
||||
bool FileSystem::PrismDeleteFile(const std::string& filepath)
|
||||
{
|
||||
s_IgnoreNextChange = true;
|
||||
std::string fp = filepath;
|
||||
fp.append(1, '\0');
|
||||
SHFILEOPSTRUCTA file_op;
|
||||
file_op.hwnd = NULL;
|
||||
file_op.wFunc = FO_DELETE;
|
||||
file_op.pFrom = fp.c_str();
|
||||
file_op.pTo = "";
|
||||
file_op.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;
|
||||
file_op.fAnyOperationsAborted = false;
|
||||
file_op.hNameMappings = 0;
|
||||
file_op.lpszProgressTitle = "";
|
||||
const int result = SHFileOperationA(&file_op);
|
||||
std::error_code ec;
|
||||
const bool removed = std::filesystem::remove(filepath, ec);
|
||||
s_IgnoreNextChange = false;
|
||||
return result == 0;
|
||||
if (!removed || ec)
|
||||
{
|
||||
PM_CORE_ERROR("Delete failed: {}", ec.message());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileSystem::PrismMoveFile(const std::string& filepath, const std::string& dest)
|
||||
@ -120,139 +234,41 @@ namespace Prism
|
||||
|
||||
void FileSystem::StartWatching()
|
||||
{
|
||||
DWORD threadId;
|
||||
s_WatcherThread = CreateThread(NULL, 0, Watch, NULL, 0, &threadId);
|
||||
PM_CORE_ASSERT(s_WatcherThread != NULL);
|
||||
PM_CORE_TRACE("Starting file watching services");
|
||||
if (s_FileWatcher) return;
|
||||
|
||||
s_FileWatcher = new efsw::FileWatcher();
|
||||
|
||||
s_Listener = new PrismFileWatcherListener();
|
||||
|
||||
efsw::WatchID watchID = s_FileWatcher->addWatch("assets", s_Listener, true);
|
||||
if (watchID < 0)
|
||||
{
|
||||
PM_CORE_ERROR("Failed to add watch for {}", "assets");
|
||||
delete s_FileWatcher;
|
||||
s_FileWatcher = nullptr;
|
||||
delete s_Listener;
|
||||
s_Listener = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
s_FileWatcher->watch();
|
||||
|
||||
PM_CORE_TRACE("Started file watching services on {}", "assets");
|
||||
}
|
||||
|
||||
void FileSystem::StopWatching()
|
||||
{
|
||||
// TODO: this delay is too long
|
||||
s_Watching = false;
|
||||
const DWORD result = WaitForSingleObject(s_WatcherThread, 1000);
|
||||
if (result == WAIT_TIMEOUT)
|
||||
TerminateThread(s_WatcherThread, 0);
|
||||
CloseHandle(s_WatcherThread);
|
||||
PM_CORE_TRACE("closing file watching services");
|
||||
}
|
||||
|
||||
unsigned long FileSystem::Watch(void* param)
|
||||
{
|
||||
const LPCSTR filepath = "assets";
|
||||
BYTE* buffer = new BYTE[10 * 1024]; // 1 MB
|
||||
OVERLAPPED overlapped = { 0 };
|
||||
HANDLE handle = NULL;
|
||||
DWORD bytesReturned = 0;
|
||||
|
||||
handle = CreateFile(
|
||||
filepath,
|
||||
FILE_LIST_DIRECTORY,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
|
||||
NULL
|
||||
);
|
||||
|
||||
ZeroMemory(&overlapped, sizeof(overlapped));
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
PM_CORE_ERROR("Unable to accquire directory handle: {0}", GetLastError());
|
||||
|
||||
overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
if (overlapped.hEvent == NULL)
|
||||
if (s_FileWatcher)
|
||||
{
|
||||
PM_CORE_ERROR("CreateEvent failed!");
|
||||
return 0;
|
||||
delete s_FileWatcher;
|
||||
s_FileWatcher = nullptr;
|
||||
}
|
||||
|
||||
while (s_Watching)
|
||||
if (s_Listener)
|
||||
{
|
||||
DWORD status = ReadDirectoryChangesW(
|
||||
handle,
|
||||
buffer,
|
||||
10 * 1024 * sizeof(BYTE),
|
||||
TRUE,
|
||||
FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME,
|
||||
&bytesReturned,
|
||||
&overlapped,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (!status)
|
||||
PM_CORE_ERROR("{0}", GetLastError());
|
||||
|
||||
const DWORD waitOperation = WaitForSingleObject(overlapped.hEvent, 2000);
|
||||
if (waitOperation != WAIT_OBJECT_0)
|
||||
continue;
|
||||
|
||||
if (s_IgnoreNextChange)
|
||||
continue;
|
||||
|
||||
std::string oldName;
|
||||
char fileName[MAX_PATH * 10] = "";
|
||||
|
||||
FILE_NOTIFY_INFORMATION* current = (FILE_NOTIFY_INFORMATION*)buffer;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
ZeroMemory(fileName, sizeof(fileName));
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, current->FileName, current->FileNameLength / sizeof(WCHAR), fileName, sizeof(fileName), NULL, NULL);
|
||||
std::filesystem::path filePath = std::filesystem::path("assets") / std::string(fileName);
|
||||
|
||||
FileSystemChangedEvent e;
|
||||
e.FilePath = filePath.string();
|
||||
e.NewName = filePath.filename().string();
|
||||
e.OldName = filePath.filename().string();
|
||||
e.IsDirectory = std::filesystem::is_directory(filePath);
|
||||
|
||||
switch (current->Action)
|
||||
{
|
||||
case FILE_ACTION_ADDED:
|
||||
{
|
||||
e.Action = FileSystemAction::Added;
|
||||
s_Callback(e);
|
||||
break;
|
||||
}
|
||||
case FILE_ACTION_REMOVED:
|
||||
{
|
||||
e.IsDirectory = AssetsManager::IsDirectory(e.FilePath);
|
||||
e.Action = FileSystemAction::Delete;
|
||||
s_Callback(e);
|
||||
break;
|
||||
}
|
||||
case FILE_ACTION_MODIFIED:
|
||||
{
|
||||
e.Action = FileSystemAction::Modified;
|
||||
s_Callback(e);
|
||||
break;
|
||||
}
|
||||
case FILE_ACTION_RENAMED_OLD_NAME:
|
||||
{
|
||||
oldName = filePath.filename().string();
|
||||
break;
|
||||
}
|
||||
case FILE_ACTION_RENAMED_NEW_NAME:
|
||||
{
|
||||
e.OldName = oldName;
|
||||
e.Action = FileSystemAction::Rename;
|
||||
s_Callback(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!current->NextEntryOffset)
|
||||
break;
|
||||
|
||||
current += current->NextEntryOffset;
|
||||
}
|
||||
delete s_Listener;
|
||||
s_Listener = nullptr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
PM_CORE_TRACE("Stopped file watching services");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -163,7 +163,7 @@ namespace Prism
|
||||
//////////////// BloomPass ////////////////
|
||||
{
|
||||
FramebufferSpecification bloomBlurFramebufferSpec;
|
||||
bloomBlurFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA16F , FramebufferTextureFormat::RGBA8};
|
||||
bloomBlurFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA16F , FramebufferTextureFormat::RGBA16F};
|
||||
bloomBlurFramebufferSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f };
|
||||
|
||||
RenderPassSpecification bloomBlurRenderPassSpec;
|
||||
@ -173,7 +173,7 @@ namespace Prism
|
||||
s_Data.BloomBlurPass[1] = RenderPass::Create(bloomBlurRenderPassSpec);
|
||||
|
||||
FramebufferSpecification bloomBlendFramebufferSpec;
|
||||
bloomBlendFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA8 };
|
||||
bloomBlendFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA16F };
|
||||
bloomBlendFramebufferSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f };
|
||||
|
||||
RenderPassSpecification bloomBlendRenderPassSpec;
|
||||
@ -275,7 +275,6 @@ namespace Prism
|
||||
s_Data.SceneData.SkyboxMaterial = scene->m_SkyboxMaterial;
|
||||
s_Data.SceneData.SceneEnvironment = scene->m_Environment;
|
||||
s_Data.SceneData.SceneEnvironmentIntensity = scene->m_EnvironmentIntensity;
|
||||
s_Data.SceneData.ActiveLight = scene->m_Light;
|
||||
s_Data.SceneData.SceneLightEnvironment = scene->m_LightEnvironment;
|
||||
}
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ namespace Prism
|
||||
void SceneRenderer::Init()
|
||||
{
|
||||
FramebufferSpecification finalFramebufferSpec;
|
||||
finalFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA8, FramebufferTextureFormat::Depth};
|
||||
finalFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA16F, FramebufferTextureFormat::Depth};
|
||||
finalFramebufferSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f };
|
||||
|
||||
RenderPassSpecification finalRenderPassSpec;
|
||||
|
||||
@ -594,9 +594,6 @@ namespace Prism
|
||||
|
||||
void Scene::CopyTo(Ref<Scene>& target)
|
||||
{
|
||||
target->m_Light = m_Light;
|
||||
target->m_LightMultiplier = m_LightMultiplier;
|
||||
|
||||
target->m_Environment = m_Environment;
|
||||
target->m_SkyboxTexture = m_SkyboxTexture;
|
||||
target->m_SkyboxMaterial = m_SkyboxMaterial;
|
||||
@ -658,6 +655,11 @@ namespace Prism
|
||||
return gravity.y;
|
||||
}
|
||||
|
||||
void Scene::SetPhysics2DGravity(const glm::vec2& vec)
|
||||
{
|
||||
b2World_SetGravity(m_Registry.get<Box2DWorldComponent>(m_SceneEntity).World, {vec.x, vec.y});
|
||||
}
|
||||
|
||||
void Scene::SetPhysics2DGravity(const float gravity)
|
||||
{
|
||||
b2World_SetGravity(m_Registry.get<Box2DWorldComponent>(m_SceneEntity).World, {0.0f, gravity});
|
||||
|
||||
@ -75,9 +75,6 @@ namespace Prism
|
||||
|
||||
float& GetSkyboxLod() { return m_SkyboxLod; }
|
||||
|
||||
Light& GetLight() { return m_Light; }
|
||||
const Light& GetLight() const { return m_Light; }
|
||||
|
||||
Entity GetMainCameraEntity();
|
||||
|
||||
void AddEntity(Entity* entity);
|
||||
@ -107,6 +104,16 @@ namespace Prism
|
||||
static Ref<Scene> GetScene(const UUID& uuid);
|
||||
|
||||
float GetPhysics2DGravity() const;
|
||||
/**
|
||||
* set 2D gravity two directions
|
||||
* @param vec (x,y) two directory
|
||||
*/
|
||||
void SetPhysics2DGravity(const glm::vec2& vec);
|
||||
|
||||
/**
|
||||
* only set y-axis gravity
|
||||
* @param gravity y gravity
|
||||
*/
|
||||
void SetPhysics2DGravity(float gravity);
|
||||
|
||||
// Editor-specific
|
||||
@ -129,8 +136,6 @@ namespace Prism
|
||||
Entity* m_Physics2DBodyEntityBuffer = nullptr;
|
||||
Entity* m_Physics3DBodyEntityBuffer = nullptr;
|
||||
|
||||
Light m_Light;
|
||||
float m_LightMultiplier = 0.3f;
|
||||
LightEnvironment m_LightEnvironment;
|
||||
|
||||
bool m_IsPlaying = false;
|
||||
|
||||
@ -588,13 +588,6 @@ namespace Prism
|
||||
out << YAML::Value;
|
||||
out << YAML::BeginMap; // Environment
|
||||
out << YAML::Key << "AssetHandle" << YAML::Value << scene->GetEnvironment()->Handle;
|
||||
const auto& light = scene->GetLight();
|
||||
out << YAML::Key << "Light" << YAML::Value;
|
||||
out << YAML::BeginMap; // Light
|
||||
out << YAML::Key << "Direction" << YAML::Value << light.Direction;
|
||||
out << YAML::Key << "Radiance" << YAML::Value << light.Radiance;
|
||||
out << YAML::Key << "Multiplier" << YAML::Value << light.Multiplier;
|
||||
out << YAML::EndMap; // Light
|
||||
out << YAML::EndMap; // Environment
|
||||
}
|
||||
|
||||
|
||||
@ -7,6 +7,12 @@
|
||||
|
||||
#include <functional>
|
||||
|
||||
|
||||
namespace efsw
|
||||
{
|
||||
class FileWatcher;
|
||||
}
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
enum class FileSystemAction
|
||||
@ -29,6 +35,9 @@ namespace Prism
|
||||
using FileSystemChangedCallbackFn = std::function<void(FileSystemChangedEvent)>;
|
||||
|
||||
public:
|
||||
static std::string OpenFileSelector(const std::string& filter = "");
|
||||
static std::string SaveFileSelector(const std::string& filter = "");
|
||||
|
||||
static bool CreateFolder(const std::filesystem::path& filepath);
|
||||
static bool Exists(const std::string& filepath);
|
||||
static std::string Rename(const std::string& filepath, const std::string& newName);
|
||||
@ -40,10 +49,13 @@ namespace Prism
|
||||
static void StopWatching();
|
||||
|
||||
private:
|
||||
static unsigned long Watch(void* param);
|
||||
static std::atomic<bool> s_IgnoreNextChange;
|
||||
static efsw::FileWatcher* s_FileWatcher;
|
||||
static class PrismFileWatcherListener* s_Listener;
|
||||
static FileSystemChangedCallbackFn s_Callback;
|
||||
|
||||
private:
|
||||
static FileSystemChangedCallbackFn s_Callback;
|
||||
friend class PrismFileWatcherListener;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -17,13 +17,10 @@ namespace Prism::Utils
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string GetExtension(const std::string& filename)
|
||||
std::string GetExtension(const std::string& filename, const bool includeDot)
|
||||
{
|
||||
std::vector<std::string> parts = SplitString(filename, '.');
|
||||
|
||||
if (parts.size() > 1)
|
||||
return parts[parts.size() - 1];
|
||||
|
||||
if (const std::vector<std::string> parts = SplitString(filename, '.'); parts.size() > 1)
|
||||
return parts[ includeDot ? parts.size() - 1 : parts.size()];
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
namespace Prism::Utils
|
||||
{
|
||||
std::string GetFilename(const std::string& filepath);
|
||||
std::string GetExtension(const std::string& filename);
|
||||
std::string GetExtension(const std::string& filename, bool includeDot = true);
|
||||
std::string RemoveExtension(const std::string& filename);
|
||||
std::string NormalizePath(std::string path);
|
||||
std::string StringToLower(const std::string& str);
|
||||
|
||||
1
Prism/vendor/efsw
vendored
Submodule
1
Prism/vendor/efsw
vendored
Submodule
Submodule Prism/vendor/efsw added at 22f17a0bcd
Reference in New Issue
Block a user