File System
This commit is contained in:
parent
2fbdfd14b9
commit
93d383ece0
@ -23,6 +23,7 @@ find_package(GLEW REQUIRED)
|
||||
find_package(glm REQUIRED)
|
||||
find_package(OpenGL REQUIRED COMPONENTS OpenGL)
|
||||
find_package(SDL2 REQUIRED)
|
||||
find_package(RapidJSON REQUIRED)
|
||||
|
||||
if(MSVC)
|
||||
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
|
||||
@ -33,6 +34,7 @@ include_directories(Include)
|
||||
include_directories(External)
|
||||
|
||||
# Add External Libraries
|
||||
add_subdirectory(External/portable-file-dialogs)
|
||||
add_subdirectory(External/open-cpp-utils)
|
||||
add_subdirectory(External/glw)
|
||||
|
||||
@ -55,7 +57,6 @@ add_executable(OpenShaderDesigner
|
||||
Source/Core/Console.cpp
|
||||
Source/Core/EventSystem.cpp
|
||||
Source/Core/Engine.cpp
|
||||
Source/Core/Renderer.cpp
|
||||
|
||||
# Editor
|
||||
Source/Editor/EditorSystem.cpp
|
||||
@ -68,6 +69,14 @@ add_executable(OpenShaderDesigner
|
||||
|
||||
# Nodes
|
||||
Source/Graph/Nodes/Math.cpp
|
||||
Include/Graph/Compiler.h
|
||||
Source/Graph/Compiler.cpp
|
||||
Source/FileSystem/FileManager.cpp
|
||||
Include/FileSystem/FileManager.h
|
||||
Include/FileSystem/Asset.h
|
||||
Source/Project/Project.cpp
|
||||
Include/Project/Project.h
|
||||
Include/Editor/MainMenuBar.h
|
||||
)
|
||||
|
||||
target_link_libraries(OpenShaderDesigner PRIVATE
|
||||
@ -75,6 +84,8 @@ target_link_libraries(OpenShaderDesigner PRIVATE
|
||||
GLEW::GLEW
|
||||
OpenGL::GL
|
||||
${SDL2_LIBRARIES}
|
||||
rapidjson
|
||||
open-cpp-utils
|
||||
imgui-docking
|
||||
imgui-extras
|
||||
imnode-graph
|
||||
|
2
External/imgui-docking/imgui.h
vendored
2
External/imgui-docking/imgui.h
vendored
@ -2282,7 +2282,7 @@ struct ImGuiIO
|
||||
bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard.
|
||||
bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag)
|
||||
bool ConfigWindowsMoveFromTitleBarOnly; // = false // Enable allowing to move windows only when clicking on their title bar. Does not apply to windows without a title bar.
|
||||
float ConfigMemoryCompactTimer; // = 60.0f // Timer (in seconds) to free transient windows/tables memory buffers when unused. Set to -1.0f to disable.
|
||||
float ConfigMemoryCompactTimer; // = 60.0f // Timer_ (in seconds) to free transient windows/tables memory buffers when unused. Set to -1.0f to disable.
|
||||
|
||||
// Inputs Behaviors
|
||||
// (other variables, ones which are expected to be tweaked within UI code, are exposed in ImGuiStyle)
|
||||
|
@ -27,158 +27,160 @@
|
||||
|
||||
namespace OpenShaderDesigner
|
||||
{
|
||||
class Console
|
||||
|
||||
class Console
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Setting for displaying log entries.
|
||||
*/
|
||||
enum Settings
|
||||
: uint8_t
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Setting for displaying log entries.
|
||||
*/
|
||||
enum Setting
|
||||
: uint8_t
|
||||
{
|
||||
SHOW_TIMESTAMP = 0b00000001
|
||||
, SHOW_THREAD = 0b00000010
|
||||
, SHOW_SEVERITY = 0b00000100
|
||||
, SHOW_FILE_INFO = 0b00001000
|
||||
, WRAP_TEXT = 0b00010000
|
||||
Settings_ShowTimeStamp = 0b00000001
|
||||
, Settings_ShowThread = 0b00000010
|
||||
, Settings_Severity = 0b00000100
|
||||
, Settings_ShowFileInfo = 0b00001000
|
||||
, Settings_WrapText = 0b00010000
|
||||
|
||||
, ALL_SETTINGS = 0xFF
|
||||
, DEFAULT_SETTINGS = ALL_SETTINGS ^ WRAP_TEXT
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief String representations of the settings.
|
||||
*/
|
||||
inline static const std::string SettingNames[] =
|
||||
{
|
||||
"Timestamps", "Thread IDs", "Severity", "File Info", "Wrapping"
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Severity levels for log entries.
|
||||
*/
|
||||
enum class Severity
|
||||
: int
|
||||
{
|
||||
MESSAGE = 0,
|
||||
WARNING,
|
||||
ERROR,
|
||||
FATAL,
|
||||
ALERT,
|
||||
COMMAND,
|
||||
COUNT,
|
||||
DEFAULT = WARNING
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief String representations of the Severity levels.
|
||||
*/
|
||||
static inline const std::string Severities[] =
|
||||
{
|
||||
"Message", "Warning", "Error", "Fatal", "Alert", "Command"
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Integer to floating point color. (ImGui APIVersion)
|
||||
* \param RGB The Integer color to convert.
|
||||
* \return The rgba floating point color.
|
||||
*/
|
||||
inline static constexpr ImVec4 ImGuiColor(unsigned int RGB)
|
||||
{
|
||||
return {
|
||||
static_cast<float>((RGB >> 24) & 255) / 255.0f, static_cast<float>((RGB >> 16) & 255) / 255.0f,
|
||||
static_cast<float>((RGB >> 8) & 255) / 255.0f, static_cast<float>((RGB >> 0) & 255) / 255.0f
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Color for rendering each Severity level text in editor.
|
||||
*/
|
||||
inline static const ImVec4 SeverityColors[] = {
|
||||
ImGuiColor(0xA4B9C4FF), ImGuiColor(0xF2C554FF), ImGuiColor(0xE57327FF), ImGuiColor(0xCC211EFF),
|
||||
ImGuiColor(0x9CDCFEFF),
|
||||
};
|
||||
|
||||
static std::string ThreadID()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::this_thread::get_id();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Thread-Safe Log function for debugging.
|
||||
* \tparam Args Variadic Arguments template for PixelLayout Parameters
|
||||
* \param file The name of the file this was called from.
|
||||
* \param line The line number this was called from.
|
||||
* \param severity The severity level of the log entry.
|
||||
* \param message A format string for the entry message.
|
||||
* \param vargs Arguments for the format string.
|
||||
*/
|
||||
template <typename... Args>
|
||||
static void Log(const std::string& file
|
||||
, const int line
|
||||
, Severity severity = Severity::DEFAULT
|
||||
, const std::format_string<Args...>& message = ""
|
||||
, Args&&... vargs);
|
||||
|
||||
static void DrawMenu();
|
||||
static void DrawWindow();
|
||||
|
||||
static inline bool Open = true;
|
||||
|
||||
private:
|
||||
struct LogEntry
|
||||
{
|
||||
const std::string Message;
|
||||
const Severity Severity;
|
||||
const std::string File, Timestamp, Thread;
|
||||
const int Line;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Get a formatted Entry for printing.
|
||||
* \param entry The Entry to format.
|
||||
* \return The Entry formatted into a string.
|
||||
*/
|
||||
static std::string Format(const LogEntry& entry, Setting settings);
|
||||
|
||||
/**
|
||||
* \brief Command handling.
|
||||
* \param command Command string to process.
|
||||
*/
|
||||
static void ProcessCommand(const std::string& command);
|
||||
|
||||
inline static std::list<LogEntry> EntryLog;
|
||||
inline static std::mutex Lock;
|
||||
inline static int Filter = static_cast<int>(0xFFFFFFFF);
|
||||
inline static Setting Settings = DEFAULT_SETTINGS;
|
||||
inline static std::string Command;
|
||||
, Settings_ALL = 0xFF
|
||||
, Settings_Default = Settings_ALL ^ Settings_WrapText
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
void Console::Log(
|
||||
const std::string& file
|
||||
, const int line
|
||||
, Severity severity
|
||||
, const std::format_string<Args...>& fmt
|
||||
, Args&&... vargs)
|
||||
/**
|
||||
* \brief String representations of the settings.
|
||||
*/
|
||||
inline static const std::string SettingNames[] =
|
||||
{
|
||||
auto t = std::time(nullptr);
|
||||
"Timestamps", "Thread IDs", "Severity", "File Info", "Wrapping"
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Severity levels for log entries.
|
||||
*/
|
||||
enum Severity
|
||||
: int
|
||||
{
|
||||
Message = 0,
|
||||
Warning,
|
||||
Error,
|
||||
Fatal,
|
||||
Alert,
|
||||
Command,
|
||||
COUNT,
|
||||
DEFAULT = Warning
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief String representations of the Severity levels.
|
||||
*/
|
||||
static inline const std::string Severities[] =
|
||||
{
|
||||
"Message", "Warning", "Error", "Fatal", "Alert", "Command"
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Integer to floating point color. (ImGui APIVersion)
|
||||
* \param RGB The Integer color to convert.
|
||||
* \return The rgba floating point color.
|
||||
*/
|
||||
inline static constexpr ImVec4 ImGuiColor(unsigned int RGB)
|
||||
{
|
||||
return {
|
||||
static_cast<float>((RGB >> 24) & 255) / 255.0f, static_cast<float>((RGB >> 16) & 255) / 255.0f,
|
||||
static_cast<float>((RGB >> 8) & 255) / 255.0f, static_cast<float>((RGB >> 0) & 255) / 255.0f
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Color for rendering each Severity level text in editor.
|
||||
*/
|
||||
inline static const ImVec4 SeverityColors[] = {
|
||||
ImGuiColor(0xA4B9C4FF), ImGuiColor(0xF2C554FF), ImGuiColor(0xE57327FF), ImGuiColor(0xCC211EFF),
|
||||
ImGuiColor(0x9CDCFEFF),
|
||||
};
|
||||
|
||||
static std::string ThreadID()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::this_thread::get_id();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Thread-Safe Log function for debugging.
|
||||
* \tparam Args Variadic Arguments template for PixelLayout Parameters
|
||||
* \param file The name of the file this was called from.
|
||||
* \param line The line number this was called from.
|
||||
* \param severity The severity level of the log entry.
|
||||
* \param message A format string for the entry message.
|
||||
* \param vargs Arguments for the format string.
|
||||
*/
|
||||
template <typename... Args>
|
||||
static void Log(const std::string& file
|
||||
, const int line
|
||||
, Severity severity = Severity::DEFAULT
|
||||
, const std::format_string<Args...>& message = ""
|
||||
, Args&&... vargs);
|
||||
|
||||
static void DrawMenu();
|
||||
static void DrawWindow();
|
||||
|
||||
static inline bool Open = true;
|
||||
|
||||
private:
|
||||
struct LogEntry
|
||||
{
|
||||
const std::string Message;
|
||||
const Severity Severity;
|
||||
const std::string File, Timestamp, Thread;
|
||||
const int Line;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Get a formatted Entry for printing.
|
||||
* \param entry The Entry to format.
|
||||
* \return The Entry formatted into a string.
|
||||
*/
|
||||
static std::string Format(const LogEntry& entry, uint8_t settings);
|
||||
|
||||
/**
|
||||
* \brief Command handling.
|
||||
* \param command Command string to process.
|
||||
*/
|
||||
static void ProcessCommand(const std::string& command);
|
||||
|
||||
inline static std::list<LogEntry> EntryLog_;
|
||||
inline static std::mutex Lock_;
|
||||
inline static int Filter_ = static_cast<int>(0xFFFFFFFF);
|
||||
inline static uint8_t Settings_ = Settings_Default;
|
||||
inline static std::string CommandBuffer_;
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
void Console::Log(
|
||||
const std::string& file
|
||||
, const int line
|
||||
, Severity severity
|
||||
, const std::format_string<Args...>& fmt
|
||||
, Args&&... vargs)
|
||||
{
|
||||
auto t = std::time(nullptr);
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4996)
|
||||
#endif
|
||||
auto tm = *std::localtime(&t);
|
||||
auto tm = *std::localtime(&t);
|
||||
|
||||
std::lock_guard guard(Lock);
|
||||
LogEntry entry{
|
||||
std::vformat(fmt.get(), std::make_format_args(vargs...)), severity, file, std::format(
|
||||
"{:0>2}:{:0>2}:{:0>2}", tm.tm_hour, tm.tm_min, tm.tm_sec),
|
||||
ThreadID(), line
|
||||
};
|
||||
EntryLog.push_back(entry);
|
||||
std::cout << Format(entry, ALL_SETTINGS) << std::endl;
|
||||
}
|
||||
std::lock_guard guard(Lock_);
|
||||
LogEntry entry{
|
||||
std::vformat(fmt.get(), std::make_format_args(vargs...)), severity, file, std::format(
|
||||
"{:0>2}:{:0>2}:{:0>2}", tm.tm_hour, tm.tm_min, tm.tm_sec),
|
||||
ThreadID(), line
|
||||
};
|
||||
EntryLog_.push_back(entry);
|
||||
std::cout << Format(entry, Settings_ALL) << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define Log(...) Log(__FILE__, __LINE__, __VA_ARGS__)
|
||||
|
@ -22,25 +22,27 @@
|
||||
|
||||
namespace OpenShaderDesigner
|
||||
{
|
||||
class Engine
|
||||
{
|
||||
public:
|
||||
static void Start(const Window::Configuration& config);
|
||||
static void Stop();
|
||||
|
||||
class Engine
|
||||
{
|
||||
public:
|
||||
static void Start(const Window::Configuration& config);
|
||||
static void Stop();
|
||||
|
||||
static Window& GetMainWindow() { return *MainWindow; }
|
||||
private:
|
||||
static void Initialize();
|
||||
static void Shutdown();
|
||||
static void Update();
|
||||
static Window& GetMainWindow() { return *MainWindow; }
|
||||
private:
|
||||
static void Initialize();
|
||||
static void Shutdown();
|
||||
static void Update();
|
||||
|
||||
inline static Timer Frame;
|
||||
inline static double _Delta;
|
||||
inline static Window* MainWindow;
|
||||
inline static Timer Frame;
|
||||
inline static double _Delta;
|
||||
inline static Window* MainWindow;
|
||||
|
||||
public:
|
||||
inline static const double& Delta = _Delta;
|
||||
};
|
||||
public:
|
||||
inline static const double& Delta = _Delta;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -29,113 +29,115 @@ namespace ocu = open_cpp_utils;
|
||||
|
||||
namespace OpenShaderDesigner
|
||||
{
|
||||
/**
|
||||
* \brief Base Event class for sending events to the Engine.
|
||||
*/
|
||||
struct Event
|
||||
{
|
||||
template<typename T>
|
||||
static uint8_t TypeOf() { return static_cast<uint8_t>(ocu::unique_id<uint8_t, T>()); }
|
||||
|
||||
/**
|
||||
* \brief Get the Event's type ID.
|
||||
* \return A pointer to the Event type ID.
|
||||
*/
|
||||
virtual inline uint8_t GetID() const = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Base EventHandler for abstraction.
|
||||
*/
|
||||
class _ImplEventHandler
|
||||
{
|
||||
virtual bool _HandleEvent(const Event* event) = 0;
|
||||
|
||||
friend class EventSystem;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief EventHandler interface for creating custom EventHandlers
|
||||
* \tparam EventType The ComponentType of Event handled by the EventHandler
|
||||
*/
|
||||
template<typename EventType>
|
||||
class EventHandler : private _ImplEventHandler
|
||||
{
|
||||
public:
|
||||
using HandledType = EventType; //!< The type handled by the EventHandler
|
||||
|
||||
/**
|
||||
* \brief Virtual function for custom EventHandler implementations.
|
||||
* \param event The Event being handled.
|
||||
*/
|
||||
virtual bool HandleEvent(const HandledType* event) = 0;
|
||||
private:
|
||||
|
||||
/**
|
||||
* \brief Override for abstraction.
|
||||
* \param event The Event being handled.
|
||||
*/
|
||||
bool _HandleEvent(const Event* event) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief EventSystem for posting Events to be handled.
|
||||
*/
|
||||
class EventSystem
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Post an Event to be Handled.
|
||||
*/
|
||||
static void PostEvent(const Event*);
|
||||
|
||||
/**
|
||||
* \brief Register an EventHandler with the EventSystem.
|
||||
* \tparam T ComponentType of Event handled by the EventHandler.
|
||||
*/
|
||||
template<typename T>
|
||||
static void RegisterHandler(EventHandler<T>*);
|
||||
|
||||
/**
|
||||
* \brief Unregister an EventHandler with the EventSystem.
|
||||
* \tparam T ComponentType of Event handled by the EventHandler.
|
||||
*/
|
||||
template<typename T>
|
||||
static void UnregisterHandler(EventHandler<T>*);
|
||||
|
||||
private:
|
||||
inline static std::list<_ImplEventHandler*> HandlerMap[MAX_EVENT_TYPES];
|
||||
inline static std::mutex Lock;
|
||||
|
||||
EventSystem(const EventSystem&) = delete;
|
||||
EventSystem(EventSystem&&) = delete;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Base Event class for sending events to the Engine.
|
||||
*/
|
||||
struct Event
|
||||
{
|
||||
template<typename T>
|
||||
void EventSystem::UnregisterHandler(EventHandler<T>* handler)
|
||||
{
|
||||
// Thread safe
|
||||
std::lock_guard guard(Lock);
|
||||
const uint8_t index = T::ID;
|
||||
std::erase(HandlerMap[index], reinterpret_cast<_ImplEventHandler*>(handler));
|
||||
}
|
||||
static uint8_t TypeOf() { return static_cast<uint8_t>(ocu::unique_id<uint8_t, T>()); }
|
||||
|
||||
/**
|
||||
* \brief Get the Event's type ID.
|
||||
* \return A pointer to the Event type ID.
|
||||
*/
|
||||
virtual inline uint8_t GetID() const = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Base EventHandler for abstraction.
|
||||
*/
|
||||
class _ImplEventHandler
|
||||
{
|
||||
virtual bool _HandleEvent(const Event* event) = 0;
|
||||
|
||||
friend class EventSystem;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief EventHandler interface for creating custom EventHandlers
|
||||
* \tparam EventType The ComponentType of Event handled by the EventHandler
|
||||
*/
|
||||
template<typename EventType>
|
||||
class EventHandler : private _ImplEventHandler
|
||||
{
|
||||
public:
|
||||
using HandledType = EventType; //!< The type handled by the EventHandler
|
||||
|
||||
/**
|
||||
* \brief Virtual function for custom EventHandler implementations.
|
||||
* \param event The Event being handled.
|
||||
*/
|
||||
virtual bool HandleEvent(const HandledType* event) = 0;
|
||||
private:
|
||||
|
||||
/**
|
||||
* \brief Override for abstraction.
|
||||
* \param event The Event being handled.
|
||||
*/
|
||||
bool _HandleEvent(const Event* event) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief EventSystem for posting Events to be handled.
|
||||
*/
|
||||
class EventSystem
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Post an Event to be Handled.
|
||||
*/
|
||||
static void PostEvent(const Event*);
|
||||
|
||||
/**
|
||||
* \brief Register an EventHandler with the EventSystem.
|
||||
* \tparam T ComponentType of Event handled by the EventHandler.
|
||||
*/
|
||||
template<typename T>
|
||||
void EventSystem::RegisterHandler(EventHandler<T>* handler)
|
||||
{
|
||||
// Thread safe
|
||||
std::lock_guard guard(Lock);
|
||||
const uint8_t index = T::ID;
|
||||
HandlerMap[index].push_back(reinterpret_cast<_ImplEventHandler*>(handler));
|
||||
}
|
||||
static void RegisterHandler(EventHandler<T>*);
|
||||
|
||||
template<typename EventType>
|
||||
bool EventHandler<EventType>::_HandleEvent(const Event *event)
|
||||
{
|
||||
if(EventType::ID != event->GetID()) return false;
|
||||
return HandleEvent(reinterpret_cast<const EventType*>(event));
|
||||
}
|
||||
/**
|
||||
* \brief Unregister an EventHandler with the EventSystem.
|
||||
* \tparam T ComponentType of Event handled by the EventHandler.
|
||||
*/
|
||||
template<typename T>
|
||||
static void UnregisterHandler(EventHandler<T>*);
|
||||
|
||||
private:
|
||||
inline static std::list<_ImplEventHandler*> HandlerMap_[MAX_EVENT_TYPES];
|
||||
inline static std::mutex Lock_;
|
||||
|
||||
EventSystem(const EventSystem&) = delete;
|
||||
EventSystem(EventSystem&&) = delete;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void EventSystem::UnregisterHandler(EventHandler<T>* handler)
|
||||
{
|
||||
// Thread safe
|
||||
std::lock_guard guard(Lock_);
|
||||
const uint8_t index = T::ID;
|
||||
std::erase(HandlerMap_[index], reinterpret_cast<_ImplEventHandler*>(handler));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void EventSystem::RegisterHandler(EventHandler<T>* handler)
|
||||
{
|
||||
// Thread safe
|
||||
std::lock_guard guard(Lock_);
|
||||
const uint8_t index = T::ID;
|
||||
HandlerMap_[index].push_back(reinterpret_cast<_ImplEventHandler*>(handler));
|
||||
}
|
||||
|
||||
template<typename EventType>
|
||||
bool EventHandler<EventType>::_HandleEvent(const Event *event)
|
||||
{
|
||||
if(EventType::ID != event->GetID()) return false;
|
||||
return HandleEvent(reinterpret_cast<const EventType*>(event));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define BeginEvent(EVENT) struct EVENT : OpenShaderDesigner::Event \
|
||||
|
@ -21,10 +21,12 @@
|
||||
|
||||
namespace OpenShaderDesigner
|
||||
{
|
||||
class Renderer
|
||||
{
|
||||
|
||||
};
|
||||
class Renderer
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,90 +27,92 @@ namespace ocu = open_cpp_utils;
|
||||
|
||||
namespace OpenShaderDesigner
|
||||
{
|
||||
BeginEvent(SDLEvent)
|
||||
const SDL_Event sdl_event;
|
||||
|
||||
SDLEvent() : sdl_event() {}
|
||||
BeginEvent(SDLEvent)
|
||||
const SDL_Event sdl_event;
|
||||
|
||||
explicit SDLEvent(const SDL_Event &event) : sdl_event(event) {}
|
||||
EndEvent
|
||||
SDLEvent() : sdl_event() {}
|
||||
|
||||
explicit SDLEvent(const SDL_Event &event) : sdl_event(event) {}
|
||||
EndEvent
|
||||
|
||||
|
||||
BeginEvent(BeginFrame)
|
||||
EndEvent;
|
||||
BeginEvent(BeginFrame)
|
||||
EndEvent;
|
||||
|
||||
BeginEvent(SDLEventsDone)
|
||||
EndEvent;
|
||||
BeginEvent(SDLEventsDone)
|
||||
EndEvent;
|
||||
|
||||
BeginEvent(EndFrame)
|
||||
EndEvent;
|
||||
BeginEvent(EndFrame)
|
||||
EndEvent;
|
||||
|
||||
|
||||
class Window
|
||||
class Window
|
||||
{
|
||||
public:
|
||||
enum class VSyncMode : int
|
||||
{
|
||||
public:
|
||||
enum class VSyncMode : int
|
||||
{
|
||||
DISABLED = 0,
|
||||
ENABLED = 1,
|
||||
ADAPTIVE = -1,
|
||||
DEFAULT = DISABLED,
|
||||
};
|
||||
|
||||
enum class FullscreenMode : int
|
||||
{
|
||||
WINDOWED = 0,
|
||||
FULLSCREEN = SDL_WINDOW_FULLSCREEN,
|
||||
FULLSCREEN_WINDOW = SDL_WINDOW_FULLSCREEN_DESKTOP,
|
||||
};
|
||||
|
||||
struct Configuration
|
||||
{
|
||||
struct
|
||||
{
|
||||
std::string Title;
|
||||
} Application;
|
||||
|
||||
struct
|
||||
{
|
||||
FullscreenMode Fullscreen;
|
||||
glm::ivec2 Resolution;
|
||||
VSyncMode VSync;
|
||||
bool HDR;
|
||||
ocu::optional<int> Multisamples;
|
||||
} Video;
|
||||
|
||||
Configuration()
|
||||
: Application { "App" }
|
||||
, Video { FullscreenMode::WINDOWED, glm::ivec2(1280, 720), VSyncMode::DISABLED, false }
|
||||
{ }
|
||||
};
|
||||
|
||||
inline static const Configuration DefaultConfiguration;
|
||||
|
||||
explicit Window(const Configuration& config);
|
||||
~Window();
|
||||
|
||||
void HandleEvents();
|
||||
void BeginFrame();
|
||||
void EndFrame();
|
||||
|
||||
void Close() { Open = false; }
|
||||
[[nodiscard]] bool IsOpen() const { return Open; }
|
||||
|
||||
SDL_Window* GetHandle() { return Handle; }
|
||||
[[nodiscard]] const SDL_Window* GetHandle() const { return Handle; }
|
||||
|
||||
SDL_GLContext GetContext() { return Context; }
|
||||
[[nodiscard]] const SDL_GLContext GetContext() const { return Context; }
|
||||
|
||||
[[nodiscard]] glm::ivec2 Size() const { return Config.Video.Resolution; }
|
||||
private:
|
||||
Configuration Config;
|
||||
SDL_Window* Handle;
|
||||
SDL_GLContext Context;
|
||||
bool Open;
|
||||
DISABLED = 0,
|
||||
ENABLED = 1,
|
||||
ADAPTIVE = -1,
|
||||
DEFAULT = DISABLED,
|
||||
};
|
||||
|
||||
enum class FullscreenMode : int
|
||||
{
|
||||
WINDOWED = 0,
|
||||
FULLSCREEN = SDL_WINDOW_FULLSCREEN,
|
||||
FULLSCREEN_WINDOW = SDL_WINDOW_FULLSCREEN_DESKTOP,
|
||||
};
|
||||
|
||||
struct Configuration
|
||||
{
|
||||
struct
|
||||
{
|
||||
std::string Title;
|
||||
} Application;
|
||||
|
||||
struct
|
||||
{
|
||||
FullscreenMode Fullscreen;
|
||||
glm::ivec2 Resolution;
|
||||
VSyncMode VSync;
|
||||
bool HDR;
|
||||
ocu::optional<int> Multisamples;
|
||||
} Video;
|
||||
|
||||
Configuration()
|
||||
: Application { "App" }
|
||||
, Video { FullscreenMode::WINDOWED, glm::ivec2(1280, 720), VSyncMode::DISABLED, false }
|
||||
{ }
|
||||
};
|
||||
|
||||
inline static const Configuration DefaultConfiguration;
|
||||
|
||||
explicit Window(const Configuration& config);
|
||||
~Window();
|
||||
|
||||
void HandleEvents();
|
||||
void BeginFrame();
|
||||
void EndFrame();
|
||||
|
||||
void Close() { Open_ = false; }
|
||||
[[nodiscard]] bool IsOpen() const { return Open_; }
|
||||
|
||||
SDL_Window* GetHandle() { return Handle_; }
|
||||
[[nodiscard]] const SDL_Window* GetHandle() const { return Handle_; }
|
||||
|
||||
SDL_GLContext GetContext() { return Context_; }
|
||||
[[nodiscard]] const SDL_GLContext GetContext() const { return Context_; }
|
||||
|
||||
[[nodiscard]] glm::ivec2 Size() const { return Config_.Video.Resolution; }
|
||||
private:
|
||||
Configuration Config_;
|
||||
SDL_Window* Handle_;
|
||||
SDL_GLContext Context_;
|
||||
bool Open_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -21,16 +21,16 @@
|
||||
namespace OpenShaderDesigner
|
||||
{
|
||||
|
||||
class ConsoleWindow : public EditorWindow
|
||||
{
|
||||
public:
|
||||
ConsoleWindow();
|
||||
class ConsoleWindow : public EditorWindow
|
||||
{
|
||||
public:
|
||||
ConsoleWindow();
|
||||
|
||||
void DrawMenu() override;
|
||||
void DrawWindow() override;
|
||||
void DrawMenu() override;
|
||||
void DrawWindow() override;
|
||||
|
||||
private:
|
||||
};
|
||||
private:
|
||||
};
|
||||
|
||||
} // OpenShaderDesigner
|
||||
|
||||
|
@ -21,41 +21,51 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include <Editor/EditorWindow.h>
|
||||
#include <Editor/MainMenuBar.h>
|
||||
|
||||
#define MAX_EDITORS 256
|
||||
|
||||
namespace OpenShaderDesigner
|
||||
{
|
||||
class EditorSystem
|
||||
|
||||
class EditorSystem
|
||||
{
|
||||
public:
|
||||
using WindowID = uint64_t;
|
||||
|
||||
template<typename T>
|
||||
static WindowID ID() { return open_cpp_utils::unique_id<WindowID, T>(); }
|
||||
|
||||
template<typename T>
|
||||
static T* Open() { T* window; (window = Get<T>())->Open(); return window; }
|
||||
|
||||
template<typename T>
|
||||
static T* Close() { T* window; (window = Get<T>())->Close(); return window; }
|
||||
|
||||
template<typename T>
|
||||
static T* Get()
|
||||
{
|
||||
public:
|
||||
using WindowID = uint64_t;
|
||||
T* window = reinterpret_cast<T*>(Windows_[ID<T>()]);
|
||||
if(window == nullptr) Windows_[ID<T>()] = window = new T();
|
||||
return window;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static WindowID ID() { return open_cpp_utils::unique_id<WindowID, T>(); }
|
||||
template<typename T>
|
||||
static T* SetMainMenuBar() { delete MainMenuBar_; T* bar = new T(); MainMenuBar_ = bar; return bar; }
|
||||
|
||||
template<typename T>
|
||||
static T* Open() { T* window; (window = Get<T>())->Open(); return window; }
|
||||
template<typename T>
|
||||
static T* GetMainMenuBar() { return static_cast<T*>(MainMenuBar_); }
|
||||
|
||||
template<typename T>
|
||||
static T* Close() { T* window; (window = Get<T>())->Close(); return window; }
|
||||
static void Initialize();
|
||||
static void Draw();
|
||||
static void Shutdown();
|
||||
static void HandleEvents(SDL_Event* event);
|
||||
|
||||
template<typename T>
|
||||
static T* Get()
|
||||
{
|
||||
T* window = reinterpret_cast<T*>(Windows[ID<T>()]);
|
||||
if(window == nullptr) Windows[ID<T>()] = window = new T();
|
||||
return window;
|
||||
}
|
||||
private:
|
||||
inline static EditorWindow* Windows_[MAX_EDITORS] { nullptr };
|
||||
inline static MainMenuBar* MainMenuBar_ = nullptr;
|
||||
};
|
||||
|
||||
static void Initialize();
|
||||
static void Draw();
|
||||
static void Shutdown();
|
||||
static void HandleEvents(SDL_Event* event);
|
||||
|
||||
private:
|
||||
inline static EditorWindow* Windows[MAX_EDITORS] { nullptr };
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
@ -21,85 +21,87 @@
|
||||
|
||||
namespace OpenShaderDesigner
|
||||
{
|
||||
|
||||
/**
|
||||
* \brief EditorWindow class for wrapping ImGui window functionality.
|
||||
*/
|
||||
class EditorWindow
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief EditorWindow class for wrapping ImGui window functionality.
|
||||
* \brief Open the EditorWindow.
|
||||
*/
|
||||
class EditorWindow
|
||||
void Open();
|
||||
|
||||
/**
|
||||
* \brief Draw the EditorWindow.
|
||||
*/
|
||||
void Draw();
|
||||
|
||||
/**
|
||||
* \brief Close the EditorWindow.
|
||||
*/
|
||||
void Close();
|
||||
|
||||
/**
|
||||
* \brief Check if the EditorWindow is open.
|
||||
* \return
|
||||
*/
|
||||
[[nodiscard]] bool IsOpen() const { return bOpen_; }
|
||||
|
||||
const std::string Title; //!< Title for the EditorWindow.
|
||||
|
||||
void SetFlags(ImGuiWindowFlags flags) { Flags_ |= flags; }
|
||||
void ClearFlags(ImGuiWindowFlags flags) { Flags_ &= ~flags; }
|
||||
void ToggleFlags(ImGuiWindowFlags flags) { Flags_ ^= flags; }
|
||||
[[nodiscard]] bool CheckFlag(ImGuiWindowFlags flag) const { return Flags_ & flag; }
|
||||
|
||||
[[nodiscard]] bool HasMenuBar() const { return CheckFlag(ImGuiWindowFlags_MenuBar); }
|
||||
|
||||
protected:
|
||||
~EditorWindow() = default;
|
||||
EditorWindow(const std::string& title
|
||||
, ImGuiWindowFlags flags);
|
||||
|
||||
/**
|
||||
* \brief OnOpen callback for when the EditorWindow is opened.
|
||||
*/
|
||||
virtual void OnOpen()
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Open the EditorWindow.
|
||||
*/
|
||||
void Open();
|
||||
|
||||
/**
|
||||
* \brief Draw the EditorWindow.
|
||||
*/
|
||||
void Draw();
|
||||
|
||||
/**
|
||||
* \brief Close the EditorWindow.
|
||||
*/
|
||||
void Close();
|
||||
|
||||
/**
|
||||
* \brief Check if the EditorWindow is open.
|
||||
* \return
|
||||
*/
|
||||
[[nodiscard]] bool IsOpen() const { return bOpen; }
|
||||
|
||||
const std::string Title; //!< Title for the EditorWindow.
|
||||
|
||||
void SetFlags(ImGuiWindowFlags flags) { Flags |= flags; }
|
||||
void ClearFlags(ImGuiWindowFlags flags) { Flags &= ~flags; }
|
||||
void ToggleFlags(ImGuiWindowFlags flags) { Flags ^= flags; }
|
||||
[[nodiscard]] bool CheckFlag(ImGuiWindowFlags flag) const { return Flags & flag; }
|
||||
|
||||
[[nodiscard]] bool HasMenuBar() const { return CheckFlag(ImGuiWindowFlags_MenuBar); }
|
||||
|
||||
protected:
|
||||
~EditorWindow() = default;
|
||||
EditorWindow(const std::string& title
|
||||
, ImGuiWindowFlags flags);
|
||||
|
||||
/**
|
||||
* \brief OnOpen callback for when the EditorWindow is opened.
|
||||
*/
|
||||
virtual void OnOpen()
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief DrawWindow function for when the EditorWindow is being drawn.
|
||||
*/
|
||||
virtual void DrawWindow()
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief DrawMenu function for when the EditorWindow Menu is being drawn.
|
||||
*/
|
||||
virtual void DrawMenu()
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief OnClose callback for when the EditorWindow is closed.
|
||||
*/
|
||||
virtual void OnClose()
|
||||
{
|
||||
};
|
||||
|
||||
private:
|
||||
EditorWindow(const EditorWindow&) = delete;
|
||||
|
||||
EditorWindow(EditorWindow&&) = delete;
|
||||
|
||||
int Flags;
|
||||
bool bOpen;
|
||||
|
||||
friend class EditorSystem;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief DrawWindow function for when the EditorWindow is being drawn.
|
||||
*/
|
||||
virtual void DrawWindow()
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief DrawMenu function for when the EditorWindow Menu is being drawn.
|
||||
*/
|
||||
virtual void DrawMenu()
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief OnClose callback for when the EditorWindow is closed.
|
||||
*/
|
||||
virtual void OnClose()
|
||||
{
|
||||
};
|
||||
|
||||
private:
|
||||
EditorWindow(const EditorWindow&) = delete;
|
||||
|
||||
EditorWindow(EditorWindow&&) = delete;
|
||||
|
||||
int Flags_;
|
||||
bool bOpen_;
|
||||
|
||||
friend class EditorSystem;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
26
Include/Editor/MainMenuBar.h
Normal file
26
Include/Editor/MainMenuBar.h
Normal file
@ -0,0 +1,26 @@
|
||||
//
|
||||
// Created by Maddie on 9/14/2024.
|
||||
//
|
||||
|
||||
#ifndef MAINMENUBAR_H
|
||||
#define MAINMENUBAR_H
|
||||
|
||||
#include <imgui-docking/imgui.h>
|
||||
|
||||
namespace OpenShaderDesigner
|
||||
{
|
||||
|
||||
class MainMenuBar
|
||||
{
|
||||
public:
|
||||
virtual void DrawMenuBar() = 0;
|
||||
|
||||
friend class EditorSystem;
|
||||
|
||||
private:
|
||||
void Draw() { ImGui::BeginMainMenuBar(); DrawMenuBar(); ImGui::EndMainMenuBar(); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //MAINMENUBAR_H
|
@ -24,37 +24,37 @@
|
||||
namespace OpenShaderDesigner
|
||||
{
|
||||
|
||||
class Profiler
|
||||
: public EditorWindow
|
||||
, public EventHandler<BeginFrame>
|
||||
, public EventHandler<EndFrame>
|
||||
class Profiler
|
||||
: public EditorWindow
|
||||
, public EventHandler<BeginFrame>
|
||||
, public EventHandler<EndFrame>
|
||||
{
|
||||
public:
|
||||
Profiler();
|
||||
~Profiler();
|
||||
|
||||
void DrawWindow() override;
|
||||
|
||||
bool HandleEvent(const EventHandler<BeginFrame>::HandledType* event) override;
|
||||
bool HandleEvent(const EventHandler<EndFrame>::HandledType* event) override;
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
public:
|
||||
Profiler();
|
||||
~Profiler();
|
||||
EVENTS = 0
|
||||
, RENDER
|
||||
, EDITOR
|
||||
, END
|
||||
|
||||
void DrawWindow() override;
|
||||
|
||||
bool HandleEvent(const EventHandler<BeginFrame>::HandledType* event) override;
|
||||
bool HandleEvent(const EventHandler<EndFrame>::HandledType* event) override;
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
EVENTS = 0
|
||||
, RENDER
|
||||
, EDITOR
|
||||
, END
|
||||
|
||||
, COUNT
|
||||
, LAST = COUNT - 1
|
||||
};
|
||||
|
||||
uint64_t Frame;
|
||||
double Deltas[COUNT];
|
||||
Timer Timer;
|
||||
, COUNT
|
||||
, LAST = COUNT - 1
|
||||
};
|
||||
|
||||
uint64_t Frame_;
|
||||
double Deltas_[COUNT];
|
||||
Timer Timer_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
46
Include/FileSystem/Asset.h
Normal file
46
Include/FileSystem/Asset.h
Normal file
@ -0,0 +1,46 @@
|
||||
// =====================================================================================================================
|
||||
// Copyright 2024 Medusa Slockbower
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef ASSET_H
|
||||
#define ASSET_H
|
||||
|
||||
#include <open-cpp-utils/filesystem.h>
|
||||
|
||||
namespace ocu = open_cpp_utils;
|
||||
|
||||
namespace OpenShaderDesigner
|
||||
{
|
||||
|
||||
class Asset
|
||||
{
|
||||
public:
|
||||
Asset() : Dirty_(false) { }
|
||||
|
||||
bool Dirty() const { return Dirty_; }
|
||||
|
||||
virtual void Open() = 0;
|
||||
virtual void Load(const std::filesystem::path& path) = 0;
|
||||
virtual void Save(const std::filesystem::path& path) { Dirty_ = false; };
|
||||
|
||||
protected:
|
||||
void MakeDirty() { Dirty_ = true; }
|
||||
|
||||
private:
|
||||
bool Dirty_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //ASSET_H
|
91
Include/FileSystem/FileManager.h
Normal file
91
Include/FileSystem/FileManager.h
Normal file
@ -0,0 +1,91 @@
|
||||
// =====================================================================================================================
|
||||
// Copyright 2024 Medusa Slockbower
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FILESYSTEM_H
|
||||
#define FILESYSTEM_H
|
||||
|
||||
#include <Editor/EditorWindow.h>
|
||||
#include <FileSystem/Asset.h>
|
||||
|
||||
#include <open-cpp-utils/filesystem.h>
|
||||
#include <open-cpp-utils/map.h>
|
||||
|
||||
|
||||
namespace ocu = open_cpp_utils;
|
||||
|
||||
namespace OpenShaderDesigner
|
||||
{
|
||||
|
||||
class FileManager : public EditorWindow
|
||||
{
|
||||
public:
|
||||
using FileSystem = ocu::filesystem<Asset, FileManager>;
|
||||
using File = FileSystem::file;
|
||||
using Path = std::filesystem::path;
|
||||
using FileID = FileSystem::file_id;
|
||||
using FileType = uint32_t;
|
||||
friend FileSystem;
|
||||
|
||||
enum FileType_
|
||||
{
|
||||
FileType_Folder = 0
|
||||
, FileType_Project
|
||||
};
|
||||
|
||||
inline static ocu::map<std::string, FileType> ExtensionMap = {
|
||||
{ "", FileType_Folder }
|
||||
, { ".sgp", FileType_Project }
|
||||
};
|
||||
|
||||
private:
|
||||
static Asset* load(const Path& file);
|
||||
static Asset* import(const Path& src, const Path& dst);
|
||||
static Asset* create(const Path& file);
|
||||
|
||||
public:
|
||||
FileManager();
|
||||
|
||||
void DrawMenu() override;
|
||||
void DrawWindow() override;
|
||||
|
||||
FileID CurrentDirectory() const { return CurrentDirectory_; }
|
||||
void CurrentDirectory(FileID id) { CurrentDirectory_ = id; }
|
||||
|
||||
FileID Create(const std::string& name) { return Filesystem_.create(name, CurrentDirectory_); }
|
||||
FileID Import(const Path& path) { return Filesystem_.import(path, CurrentDirectory_); }
|
||||
FileID LoadDirectory(const Path& path) { return Filesystem_.load_directory(path); }
|
||||
void CloseDirectory(FileID dir) { Filesystem_.close_directory(dir); }
|
||||
|
||||
FileID Get(const Path& path) const { return Filesystem_.find(path); }
|
||||
File& Get(FileID id) { return Filesystem_[id]; }
|
||||
const File& Get(FileID id) const { return Filesystem_[id]; }
|
||||
|
||||
FileID Parent(FileID id) const { return Filesystem_.parent(id); }
|
||||
|
||||
bool AnyDirty();
|
||||
void SaveAll();
|
||||
|
||||
static Path GetHomeDirectory();
|
||||
private:
|
||||
FileSystem Filesystem_;
|
||||
FileID CurrentDirectory_, Selected_;
|
||||
bool Rename_, FocusRename_;
|
||||
std::string RenameBuffer_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif //FILESYSTEM_H
|
@ -13,5 +13,7 @@
|
||||
// limitations under the License.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef COMPILER_H
|
||||
#define COMPILER_H
|
||||
|
||||
#include <Core/Renderer.h>
|
||||
#endif //COMPILER_H
|
@ -50,8 +50,6 @@ struct Integer : public Node
|
||||
|
||||
[[nodiscard]] Node* Copy(ShaderGraph& graph) const override;
|
||||
void Inspect() override;
|
||||
|
||||
ValueType Value;
|
||||
};
|
||||
|
||||
RegisterNode("Math/Constants/Integer", Integer);
|
||||
@ -68,8 +66,6 @@ struct UnsignedInteger : public Node
|
||||
|
||||
[[nodiscard]] Node* Copy(ShaderGraph& graph) const override;
|
||||
void Inspect() override;
|
||||
|
||||
ValueType Value;
|
||||
};
|
||||
|
||||
RegisterNode("Math/Constants/Unsigned Integer", UnsignedInteger);
|
||||
@ -86,8 +82,6 @@ struct Scalar : public Node
|
||||
|
||||
[[nodiscard]] Node* Copy(ShaderGraph& graph) const override;
|
||||
void Inspect() override;
|
||||
|
||||
ValueType Value;
|
||||
};
|
||||
|
||||
RegisterNode("Math/Constants/Scalar", Scalar);
|
||||
@ -104,8 +98,6 @@ struct Vector : public Node
|
||||
|
||||
[[nodiscard]] Node* Copy(ShaderGraph& graph) const override;
|
||||
void Inspect() override;
|
||||
|
||||
ValueType Value;
|
||||
};
|
||||
|
||||
RegisterNode("Math/Constants/Vector", Vector);
|
||||
|
@ -197,15 +197,16 @@ namespace OpenShaderDesigner
|
||||
// History Functionality
|
||||
void PushState();
|
||||
void PopState();
|
||||
GraphState& GetState() { return State; }
|
||||
GraphState& GetState() { return State_; }
|
||||
|
||||
private:
|
||||
bool GrabFocus;
|
||||
bool GrabFocus_;
|
||||
|
||||
GraphState State;
|
||||
std::stack<GraphState> History;
|
||||
GraphState State_;
|
||||
std::stack<GraphState> History_;
|
||||
|
||||
ImVec2 ContextMenuPosition;
|
||||
ImVec2 ContextMenuPosition_;
|
||||
|
||||
|
||||
friend class Inspector;
|
||||
};
|
||||
|
35
Include/Project/Project.h
Normal file
35
Include/Project/Project.h
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// Created by Maddie on 9/14/2024.
|
||||
//
|
||||
|
||||
#ifndef PROJECT_H
|
||||
#define PROJECT_H
|
||||
|
||||
#include <Editor/MainMenuBar.h>
|
||||
#include <FileSystem/FileManager.h>
|
||||
|
||||
namespace OpenShaderDesigner
|
||||
{
|
||||
|
||||
class Project : public MainMenuBar, public Asset
|
||||
{
|
||||
public:
|
||||
Project();
|
||||
virtual ~Project();
|
||||
|
||||
void DrawMenuBar() override;
|
||||
|
||||
void Open() override;
|
||||
void Load(const FileManager::Path& path) override;
|
||||
void Save(const FileManager::Path& path) override;
|
||||
void Create(const FileManager::Path& path);
|
||||
|
||||
private:
|
||||
void Reset();
|
||||
|
||||
FileManager::FileID ProjectFile_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //PROJECT_H
|
@ -20,18 +20,20 @@
|
||||
|
||||
namespace OpenShaderDesigner
|
||||
{
|
||||
class Timer
|
||||
{
|
||||
public:
|
||||
Timer() : Start(std::chrono::high_resolution_clock::now()) { }
|
||||
|
||||
class Timer
|
||||
{
|
||||
public:
|
||||
Timer() : Start(std::chrono::high_resolution_clock::now()) { }
|
||||
|
||||
void Reset() { Start = std::chrono::high_resolution_clock::now(); }
|
||||
void Reset() { Start = std::chrono::high_resolution_clock::now(); }
|
||||
|
||||
[[nodiscard]] double Poll() const
|
||||
{ return std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - Start).count(); }
|
||||
private:
|
||||
std::chrono::high_resolution_clock::time_point Start;
|
||||
};
|
||||
[[nodiscard]] double Poll() const
|
||||
{ return std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - Start).count(); }
|
||||
private:
|
||||
std::chrono::high_resolution_clock::time_point Start;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //TIMER_H
|
||||
|
@ -20,16 +20,16 @@ using namespace OpenShaderDesigner;
|
||||
|
||||
void Console::DrawMenu()
|
||||
{
|
||||
std::lock_guard guard(Lock);
|
||||
std::lock_guard guard(Lock_);
|
||||
|
||||
if(ImGui::BeginMenu("\uf0e5 Settings"))
|
||||
{
|
||||
for(uint8_t setting = 0; setting < sizeof(SettingNames) / sizeof(std::string); ++setting)
|
||||
{
|
||||
int flag = 0x1 << setting;
|
||||
if(ImGui::MenuItem(SettingNames[setting].c_str(), nullptr, Settings & flag))
|
||||
if(ImGui::MenuItem(SettingNames[setting].c_str(), nullptr, Settings_ & flag))
|
||||
{
|
||||
Settings = static_cast<Setting>(Settings ^ flag);
|
||||
Settings_ = Settings_ ^ flag;
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,9 +41,9 @@ void Console::DrawMenu()
|
||||
for(int severity = 0; severity < static_cast<int>(Severity::COUNT); ++severity)
|
||||
{
|
||||
int flag = 0x1 << severity;
|
||||
if(ImGui::MenuItem(Severities[severity].c_str(), NULL, Filter & flag))
|
||||
if(ImGui::MenuItem(Severities[severity].c_str(), NULL, Filter_ & flag))
|
||||
{
|
||||
Filter = Filter ^ flag;
|
||||
Filter_ = Filter_ ^ flag;
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,23 +53,23 @@ void Console::DrawMenu()
|
||||
|
||||
void Console::DrawWindow()
|
||||
{
|
||||
std::lock_guard guard(Lock);
|
||||
std::lock_guard guard(Lock_);
|
||||
|
||||
const auto& Log = EntryLog;
|
||||
const auto& Log = EntryLog_;
|
||||
|
||||
const float padding = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
|
||||
if(ImGui::BeginChild("##scrolling", ImVec2(0, -padding),
|
||||
ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AlwaysUseWindowPadding | ImGuiChildFlags_AutoResizeY
|
||||
, ImGuiWindowFlags_AlwaysVerticalScrollbar | (Settings & WRAP_TEXT ? ImGuiWindowFlags_None : ImGuiWindowFlags_AlwaysHorizontalScrollbar)))
|
||||
, ImGuiWindowFlags_AlwaysVerticalScrollbar | (Settings_ & Settings_WrapText ? ImGuiWindowFlags_None : ImGuiWindowFlags_AlwaysHorizontalScrollbar)))
|
||||
{
|
||||
for(const LogEntry& entry : Log)
|
||||
{
|
||||
int flag = 0x1 << static_cast<int>(entry.Severity);
|
||||
if((flag & Filter) == 0) continue;
|
||||
if((flag & Filter_) == 0) continue;
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, SeverityColors[static_cast<int>(entry.Severity)]);
|
||||
if(Settings & WRAP_TEXT) ImGui::TextWrapped("%s", Format(entry, Settings).c_str());
|
||||
else ImGui::Text("%s", Format(entry, Settings).c_str());
|
||||
if(Settings_ & Settings_WrapText) ImGui::TextWrapped("%s", Format(entry, Settings_).c_str());
|
||||
else ImGui::Text("%s", Format(entry, Settings_).c_str());
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
@ -80,23 +80,23 @@ void Console::DrawWindow()
|
||||
|
||||
ImGui::Text(">"); ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetWindowWidth() - ImGui::GetCursorPosX() - ImGui::GetStyle().WindowPadding.x);
|
||||
if(ImGui::InputText("##commandline", &Command, ImGuiInputTextFlags_EnterReturnsTrue))
|
||||
if(ImGui::InputText("##commandline", &CommandBuffer_, ImGuiInputTextFlags_EnterReturnsTrue))
|
||||
{
|
||||
ProcessCommand(Command);
|
||||
Command.clear();
|
||||
ProcessCommand(CommandBuffer_);
|
||||
CommandBuffer_.clear();
|
||||
ImGui::SetKeyboardFocusHere(-1);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Console::Format(const LogEntry& entry, Setting settings)
|
||||
std::string Console::Format(const LogEntry& entry, uint8_t settings)
|
||||
{
|
||||
std::string severity = std::format("<{}>", Severities[static_cast<int>(entry.Severity)]);
|
||||
|
||||
std::string message;
|
||||
|
||||
// Get Timestamp and Thread bits.
|
||||
const bool showTimestamp = (settings & SHOW_TIMESTAMP);
|
||||
const bool showThreadID = (settings & SHOW_THREAD) && entry.Severity != Severity::COMMAND;
|
||||
const bool showTimestamp = (settings & Settings_ShowTimeStamp);
|
||||
const bool showThreadID = (settings & Settings_ShowThread) && entry.Severity != Severity::Command;
|
||||
const bool check1 = showTimestamp || showThreadID;
|
||||
|
||||
// Print Timestamp and/or Thread if enabled.
|
||||
@ -104,8 +104,8 @@ std::string Console::Format(const LogEntry& entry, Setting settings)
|
||||
if(showThreadID) message += std::format("Thread #{:0>3} | ", entry.Thread);
|
||||
|
||||
// Get Severity and File bits.
|
||||
const bool showSeverity = (settings & SHOW_SEVERITY) && entry.Severity != Severity::COMMAND;
|
||||
const bool showFile = (settings & SHOW_FILE_INFO) && entry.Severity != Severity::COMMAND;
|
||||
const bool showSeverity = (settings & Settings_Severity) && entry.Severity != Severity::Command;
|
||||
const bool showFile = (settings & Settings_ShowFileInfo) && entry.Severity != Severity::Command;
|
||||
const bool check2 = showSeverity || showFile;
|
||||
|
||||
// Print Severity and/or File if enabled.
|
||||
@ -113,7 +113,7 @@ std::string Console::Format(const LogEntry& entry, Setting settings)
|
||||
if(showFile) message += std::format("{}({})", entry.File, entry.Line);
|
||||
|
||||
// Print separator if any are enabled
|
||||
if(check1 || check2) message += entry.Severity == Severity::COMMAND ? "> " : ": ";
|
||||
if(check1 || check2) message += entry.Severity == Severity::Command ? "> " : ": ";
|
||||
|
||||
// Add message.
|
||||
message += entry.Message;
|
||||
|
@ -20,18 +20,22 @@
|
||||
#include <Editor/ConsoleWindow.h>
|
||||
#include <Editor/Profiler.h>
|
||||
|
||||
#include <FileSystem/FileManager.h>
|
||||
|
||||
#include <Graph/ShaderGraph.h>
|
||||
|
||||
#include "Project/Project.h"
|
||||
|
||||
void OpenShaderDesigner::Engine::Start(const Window::Configuration& config)
|
||||
{
|
||||
Console::Log(Console::Severity::ALERT, "Starting {}", config.Application.Title);
|
||||
Console::Log(Console::Severity::Alert, "Starting {}", config.Application.Title);
|
||||
|
||||
Console::Log(Console::Severity::MESSAGE, "Creating Main Window");
|
||||
Console::Log(Console::Message, "Creating Main Window");
|
||||
MainWindow = new Window(config);
|
||||
|
||||
Initialize();
|
||||
|
||||
Console::Log(Console::Severity::MESSAGE, "Starting Main Loop");
|
||||
Console::Log(Console::Message, "Starting Main Loop");
|
||||
while(MainWindow->IsOpen())
|
||||
{
|
||||
Update();
|
||||
@ -47,20 +51,26 @@ void OpenShaderDesigner::Engine::Stop()
|
||||
|
||||
void OpenShaderDesigner::Engine::Initialize()
|
||||
{
|
||||
Console::Log(Console::Severity::MESSAGE, "Initializing Engine");
|
||||
Console::Log(Console::Message, "Initializing Engine");
|
||||
|
||||
Console::Log(Console::Severity::MESSAGE, "Initializing Editor");
|
||||
Console::Log(Console::Message, "Initializing Editor");
|
||||
EditorSystem::Initialize();
|
||||
|
||||
Console::Log(Console::Severity::MESSAGE, "Opening Console");
|
||||
Console::Log(Console::Message, "Opening Console");
|
||||
EditorSystem::Open<ConsoleWindow>();
|
||||
|
||||
Console::Log(Console::Severity::MESSAGE, "Opening Profiler");
|
||||
Console::Log(Console::Message, "Opening Profiler");
|
||||
EditorSystem::Open<Profiler>();
|
||||
|
||||
Console::Log(Console::Severity::MESSAGE, "Opening Shader Graph");
|
||||
Console::Log(Console::Message, "Opening File Manager");
|
||||
EditorSystem::Open<FileManager>();
|
||||
|
||||
Console::Log(Console::Message, "Opening Shader Graph");
|
||||
EditorSystem::Open<Inspector>();
|
||||
EditorSystem::Open<ShaderGraph>();
|
||||
|
||||
Console::Log(Console::Message, "Setting up Project");
|
||||
EditorSystem::SetMainMenuBar<Project>();
|
||||
}
|
||||
|
||||
void OpenShaderDesigner::Engine::Shutdown()
|
||||
|
@ -23,11 +23,11 @@ using namespace OpenShaderDesigner;
|
||||
void EventSystem::PostEvent(const Event* event)
|
||||
{
|
||||
// Thread safe
|
||||
std::lock_guard guard(Lock);
|
||||
std::lock_guard guard(Lock_);
|
||||
|
||||
// Alert Handlers
|
||||
const int index = event->GetID();
|
||||
for(_ImplEventHandler* handler : HandlerMap[index])
|
||||
for(_ImplEventHandler* handler : HandlerMap_[index])
|
||||
{
|
||||
if(handler->_HandleEvent(event)) break;
|
||||
}
|
||||
|
@ -22,10 +22,10 @@
|
||||
using namespace OpenShaderDesigner;
|
||||
|
||||
Window::Window(const Configuration& config)
|
||||
: Config(config)
|
||||
: Config_(config)
|
||||
{
|
||||
int flags = static_cast<int>(Config.Video.Fullscreen) | SDL_WINDOW_OPENGL;
|
||||
flags |= Config.Video.Fullscreen == FullscreenMode::WINDOWED ? SDL_WINDOW_RESIZABLE : 0;
|
||||
int flags = static_cast<int>(Config_.Video.Fullscreen) | SDL_WINDOW_OPENGL;
|
||||
flags |= Config_.Video.Fullscreen == FullscreenMode::WINDOWED ? SDL_WINDOW_RESIZABLE : 0;
|
||||
|
||||
SDL_Init(SDL_INIT_EVERYTHING & ~SDL_INIT_AUDIO);
|
||||
|
||||
@ -40,54 +40,54 @@ Window::Window(const Configuration& config)
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
|
||||
if(Config.Video.HDR)
|
||||
if(Config_.Video.HDR)
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 16);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 16);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 16);
|
||||
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 16);
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 10);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 10);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 10);
|
||||
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_FLOATBUFFERS, SDL_TRUE);
|
||||
}
|
||||
|
||||
if(Config.Video.Multisamples())
|
||||
if(Config_.Video.Multisamples())
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, SDL_TRUE);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, Config.Video.Multisamples);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, Config_.Video.Multisamples);
|
||||
}
|
||||
|
||||
|
||||
if((Handle = SDL_CreateWindow(
|
||||
Config.Application.Title.c_str(),
|
||||
if((Handle_ = SDL_CreateWindow(
|
||||
Config_.Application.Title.c_str(),
|
||||
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
Config.Video.Resolution.x, Config.Video.Resolution.y,
|
||||
Config_.Video.Resolution.x, Config_.Video.Resolution.y,
|
||||
flags)) == nullptr)
|
||||
{
|
||||
Console::Log(Console::Severity::FATAL, "Failed to create SDL Window: {}", SDL_GetError());
|
||||
Console::Log(Console::Severity::Fatal, "Failed to create SDL Window: {}", SDL_GetError());
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = SDL_GL_CreateContext(Handle);
|
||||
Context_ = SDL_GL_CreateContext(Handle_);
|
||||
|
||||
if(Context == nullptr)
|
||||
if(Context_ == nullptr)
|
||||
{
|
||||
Console::Log(Console::Severity::FATAL, "Failed to create OpenGL Context: {}", SDL_GetError());
|
||||
SDL_DestroyWindow(Handle);
|
||||
Console::Log(Console::Severity::Fatal, "Failed to create OpenGL Context: {}", SDL_GetError());
|
||||
SDL_DestroyWindow(Handle_);
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if(SDL_GL_MakeCurrent(Handle, Context))
|
||||
if(SDL_GL_MakeCurrent(Handle_, Context_))
|
||||
{
|
||||
Console::Log(Console::Severity::FATAL, "Failed to set OpenGL Context: {}", SDL_GetError());
|
||||
SDL_GL_DeleteContext(Context);
|
||||
SDL_DestroyWindow(Handle);
|
||||
Console::Log(Console::Severity::Fatal, "Failed to set OpenGL Context: {}", SDL_GetError());
|
||||
SDL_GL_DeleteContext(Context_);
|
||||
SDL_DestroyWindow(Handle_);
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set VSync Mode
|
||||
SDL_GL_SetSwapInterval(static_cast<int>(Config.Video.VSync));
|
||||
SDL_GL_SetSwapInterval(static_cast<int>(Config_.Video.VSync));
|
||||
|
||||
// Enable experimental features
|
||||
glewExperimental = GL_TRUE;
|
||||
@ -96,9 +96,9 @@ Window::Window(const Configuration& config)
|
||||
GLenum error;
|
||||
if((error = glewInit()) != GLEW_OK)
|
||||
{
|
||||
Console::Log(Console::Severity::FATAL, "Failed to Initialize GLEW: {}", reinterpret_cast<const char*>(glewGetErrorString(error)));
|
||||
SDL_GL_DeleteContext(Context);
|
||||
SDL_DestroyWindow(Handle);
|
||||
Console::Log(Console::Severity::Fatal, "Failed to Initialize GLEW: {}", reinterpret_cast<const char*>(glewGetErrorString(error)));
|
||||
SDL_GL_DeleteContext(Context_);
|
||||
SDL_DestroyWindow(Handle_);
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
@ -108,22 +108,22 @@ Window::Window(const Configuration& config)
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glClearColor(0, 0, 0, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
SDL_GL_SwapWindow(Handle);
|
||||
SDL_GL_SwapWindow(Handle_);
|
||||
|
||||
// Set running
|
||||
Open = true;
|
||||
Open_ = true;
|
||||
|
||||
const char* glVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
|
||||
const char* glewVersion = reinterpret_cast<const char*>(glewGetString(GLEW_VERSION));
|
||||
SDL_version sdlVersion; SDL_GetVersion(&sdlVersion);
|
||||
Console::Log(Console::Severity::ALERT, "Initialized SDL ({}.{}.{})", sdlVersion.major, sdlVersion.minor, sdlVersion.patch);
|
||||
Console::Log(Console::Severity::ALERT, "Running OpenGL ({}), GLEW ({})", glVersion, glewVersion);
|
||||
Console::Log(Console::Severity::Alert, "Initialized SDL ({}.{}.{})", sdlVersion.major, sdlVersion.minor, sdlVersion.patch);
|
||||
Console::Log(Console::Severity::Alert, "Running OpenGL ({}), GLEW ({})", glVersion, glewVersion);
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
SDL_GL_DeleteContext(Context);
|
||||
SDL_DestroyWindow(Handle);
|
||||
SDL_GL_DeleteContext(Context_);
|
||||
SDL_DestroyWindow(Handle_);
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
@ -147,8 +147,8 @@ void Window::HandleEvents()
|
||||
switch(event.window.event)
|
||||
{
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
Config.Video.Resolution.x = event.window.data1;
|
||||
Config.Video.Resolution.y = event.window.data2;
|
||||
Config_.Video.Resolution.x = event.window.data1;
|
||||
Config_.Video.Resolution.y = event.window.data2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -170,14 +170,14 @@ void Window::BeginFrame()
|
||||
HandleEvents();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glViewport(0, 0, Config.Video.Resolution.x, Config.Video.Resolution.y);
|
||||
glViewport(0, 0, Config_.Video.Resolution.x, Config_.Video.Resolution.y);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void Window::EndFrame()
|
||||
{
|
||||
SDL_GL_SwapWindow(Handle);
|
||||
SDL_GL_SwapWindow(Handle_);
|
||||
|
||||
OpenShaderDesigner::EndFrame event;
|
||||
EventSystem::PostEvent(&event);
|
||||
|
@ -30,7 +30,7 @@ void EditorSystem::Initialize()
|
||||
{
|
||||
Window& Window = Engine::GetMainWindow();
|
||||
|
||||
Console::Log(Console::Severity::ALERT, "Initializing Dear ImGUI");
|
||||
Console::Log(Console::Severity::Alert, "Initializing Dear ImGUI");
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
|
||||
@ -136,7 +136,7 @@ void EditorSystem::Initialize()
|
||||
ImGui_ImplSDL2_InitForOpenGL(Window.GetHandle(), Window.GetContext());
|
||||
ImGui_ImplOpenGL3_Init("#version 460 core");
|
||||
|
||||
Console::Log(Console::Severity::ALERT, "Initialized ImGui ({})", IMGUI_VERSION);
|
||||
Console::Log(Console::Severity::Alert, "Initialized ImGui ({})", IMGUI_VERSION);
|
||||
}
|
||||
|
||||
void EditorSystem::Draw()
|
||||
@ -152,11 +152,16 @@ void EditorSystem::Draw()
|
||||
ImGui::ResetMouseDragDelta();
|
||||
}
|
||||
|
||||
if(MainMenuBar_)
|
||||
{
|
||||
MainMenuBar_->Draw();
|
||||
}
|
||||
|
||||
ImGui::ShowDemoWindow();
|
||||
|
||||
for (int i = 0; i < MAX_EDITORS; ++i)
|
||||
{
|
||||
EditorWindow* editor = Windows[i];
|
||||
EditorWindow* editor = Windows_[i];
|
||||
if(editor == nullptr || !editor->IsOpen()) continue;
|
||||
editor->Draw();
|
||||
}
|
||||
@ -168,6 +173,9 @@ void EditorSystem::Draw()
|
||||
|
||||
void EditorSystem::Shutdown()
|
||||
{
|
||||
delete MainMenuBar_;
|
||||
for(auto it : Windows_) delete it;
|
||||
|
||||
// Shutdown ImGui
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplSDL2_Shutdown();
|
||||
|
@ -19,15 +19,15 @@ using namespace OpenShaderDesigner;
|
||||
|
||||
void EditorWindow::Open()
|
||||
{
|
||||
if(bOpen) return;
|
||||
bOpen = true;
|
||||
if(bOpen_) return;
|
||||
bOpen_ = true;
|
||||
OnOpen();
|
||||
}
|
||||
|
||||
void EditorWindow::Draw()
|
||||
{
|
||||
const bool prev = bOpen;
|
||||
if(ImGui::Begin(Title.c_str(), &bOpen, Flags))
|
||||
const bool prev = bOpen_;
|
||||
if(ImGui::Begin(Title.c_str(), &bOpen_, Flags_))
|
||||
{
|
||||
if(HasMenuBar())
|
||||
{
|
||||
@ -43,24 +43,24 @@ void EditorWindow::Draw()
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
if(bOpen != prev)
|
||||
if(bOpen_ != prev)
|
||||
{
|
||||
bOpen ? OnOpen() : OnClose();
|
||||
bOpen_ ? OnOpen() : OnClose();
|
||||
}
|
||||
}
|
||||
|
||||
void EditorWindow::Close()
|
||||
{
|
||||
if(!bOpen) return;
|
||||
bOpen = false;
|
||||
if(!bOpen_) return;
|
||||
bOpen_ = false;
|
||||
|
||||
OnClose();
|
||||
}
|
||||
|
||||
EditorWindow::EditorWindow(const std::string &title, ImGuiWindowFlags flags)
|
||||
: Title(title)
|
||||
, Flags(flags)
|
||||
, bOpen(false)
|
||||
, Flags_(flags)
|
||||
, bOpen_(false)
|
||||
{
|
||||
|
||||
}
|
@ -19,8 +19,8 @@ using namespace OpenShaderDesigner;
|
||||
|
||||
Profiler::Profiler()
|
||||
: EditorWindow("\uf214 Profiler", 0)
|
||||
, Frame(0), Deltas{ 0 }
|
||||
, Timer()
|
||||
, Frame_(0), Deltas_{ 0 }
|
||||
, Timer_()
|
||||
{
|
||||
EventSystem::RegisterHandler<BeginFrame>(this);
|
||||
EventSystem::RegisterHandler<EndFrame>(this);
|
||||
@ -34,19 +34,19 @@ Profiler::~Profiler()
|
||||
|
||||
void Profiler::DrawWindow()
|
||||
{
|
||||
ImGui::Text("Frame #%d", Frame);
|
||||
ImGui::Text("FPS: %07.02f (%06.02f ms)", 1.0 / Deltas[LAST], 1000.0 * Deltas[LAST]);
|
||||
ImGui::Text("Frame #%d", Frame_);
|
||||
ImGui::Text("FPS: %07.02f (%06.02f ms)", 1.0 / Deltas_[LAST], 1000.0 * Deltas_[LAST]);
|
||||
}
|
||||
|
||||
bool Profiler::HandleEvent(const EventHandler<BeginFrame>::HandledType* event)
|
||||
{
|
||||
++Frame;
|
||||
Timer.Reset();
|
||||
++Frame_;
|
||||
Timer_.Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Profiler::HandleEvent(const EventHandler<EndFrame>::HandledType* event)
|
||||
{
|
||||
Deltas[END] = Timer.Poll();
|
||||
Deltas_[END] = Timer_.Poll();
|
||||
return false;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <Core/Engine.h>
|
||||
#include <Editor/EditorSystem.h>
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
@ -30,4 +31,4 @@ int main(int, char**)
|
||||
Engine::Start(config);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
259
Source/FileSystem/FileManager.cpp
Normal file
259
Source/FileSystem/FileManager.cpp
Normal file
@ -0,0 +1,259 @@
|
||||
// =====================================================================================================================
|
||||
// Copyright 2024 Medusa Slockbower
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// =====================================================================================================================
|
||||
|
||||
#include <Editor/EditorSystem.h>
|
||||
#include <FileSystem/FileManager.h>
|
||||
#include <Core/Console.h>
|
||||
|
||||
#include <imgui-docking/misc/cpp/imgui_stdlib.h>
|
||||
|
||||
#include "Project/Project.h"
|
||||
|
||||
OpenShaderDesigner::Asset * OpenShaderDesigner::FileManager::load(const Path& path)
|
||||
{
|
||||
Console::Log(Console::Message, "Loading File {}", path.string());
|
||||
FileType type = ExtensionMap[path.extension().string()];
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case FileType_Project:
|
||||
{
|
||||
Project* project = EditorSystem::GetMainMenuBar<Project>();
|
||||
project->Load(path);
|
||||
return project;
|
||||
}
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
OpenShaderDesigner::Asset * OpenShaderDesigner::FileManager::import(const Path &src, const Path &dst)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OpenShaderDesigner::Asset * OpenShaderDesigner::FileManager::create(const Path &path)
|
||||
{
|
||||
Console::Log(Console::Message, "Creating File {}", path.string());
|
||||
FileType type = ExtensionMap[path.extension().string()];
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case FileType_Project:
|
||||
{
|
||||
Project* project = EditorSystem::GetMainMenuBar<Project>();
|
||||
project->Create(path);
|
||||
return project;
|
||||
}
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
OpenShaderDesigner::FileManager::FileManager()
|
||||
: EditorWindow("File Manager", ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoScrollbar)
|
||||
, CurrentDirectory_(FileSystem::root), Selected_(FileSystem::root)
|
||||
, Rename_(false), FocusRename_(false)
|
||||
{
|
||||
//CurrentDirectory_ = Filesystem_.load_directory(std::filesystem::current_path());
|
||||
}
|
||||
|
||||
void OpenShaderDesigner::FileManager::DrawMenu()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void OpenShaderDesigner::FileManager::DrawWindow()
|
||||
{
|
||||
// Directory Hierarchy
|
||||
ImGui::BeginGroup();
|
||||
if (ImGui::BeginChild("##hierarchy", ImVec2(200, 0),
|
||||
ImGuiChildFlags_ResizeX | ImGuiChildFlags_AlwaysUseWindowPadding | ImGuiChildFlags_Border))
|
||||
{
|
||||
struct Visitor
|
||||
{
|
||||
bool operator()(File& file, FileID id)
|
||||
{
|
||||
const FileSystem& tree = file.system();
|
||||
uint32_t depth = tree.depth(id);
|
||||
|
||||
// Skip root
|
||||
if(id == FileSystem::root) return false;
|
||||
|
||||
// Skip if we are in a closed directory
|
||||
if(depth > stack.size()) return false;
|
||||
|
||||
// Skip non-directories
|
||||
const bool is_dir = file.is_directory();
|
||||
if(not is_dir) return false;
|
||||
|
||||
// Pop dead paths
|
||||
while(depth < stack.size())
|
||||
{
|
||||
stack.pop();
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
// Skip if the top of the stack is not the parent of the file
|
||||
if(stack.top() != tree.parent(id)) return false;
|
||||
|
||||
// Generate display name
|
||||
const char* icon = "\ued53";
|
||||
std::string name = std::format("{} {}##{}", icon, file.path().stem().string(), id);
|
||||
|
||||
// Display flags
|
||||
int flags = 0;
|
||||
if(file.has_subdirectory())
|
||||
{
|
||||
flags |= ImGuiTreeNodeFlags_OpenOnArrow;
|
||||
flags |= ImGuiTreeNodeFlags_OpenOnDoubleClick;
|
||||
flags |= ImGuiTreeNodeFlags_SpanAvailWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= ImGuiTreeNodeFlags_Leaf;
|
||||
}
|
||||
|
||||
if(id == directory) flags |= ImGuiTreeNodeFlags_Selected;
|
||||
|
||||
if(ImGui::TreeNodeEx(name.c_str(), flags))
|
||||
{
|
||||
stack.push(id);
|
||||
}
|
||||
|
||||
if(ImGui::IsItemClicked()) directory = file.get_id();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::stack<FileID> stack;
|
||||
FileID directory;
|
||||
} visitor;
|
||||
|
||||
visitor.directory = CurrentDirectory_;
|
||||
visitor.stack.push(FileSystem::root);
|
||||
Filesystem_.traverse(visitor);
|
||||
|
||||
while(visitor.stack.size() > 1)
|
||||
{
|
||||
ImGui::TreePop();
|
||||
visitor.stack.pop();
|
||||
}
|
||||
|
||||
CurrentDirectory_ = visitor.directory;
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if(ImGui::BeginTable("##directory", 3, ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersOuter))
|
||||
{
|
||||
ImGui::TableSetupScrollFreeze(0, 1);
|
||||
|
||||
ImGui::TableSetupColumn(" Name");
|
||||
ImGui::TableSetupColumn("Type");
|
||||
ImGui::TableSetupColumn("Source");
|
||||
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for(FileID it = Filesystem_.begin(CurrentDirectory_); it != Filesystem_.end(CurrentDirectory_); it = Filesystem_.next(it))
|
||||
{
|
||||
File& file = Filesystem_[it];
|
||||
ImGui::TableNextRow();
|
||||
|
||||
const bool selected = Selected_ == it;
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
// Display Name
|
||||
bool dirty = *file ? file->Dirty() : false;
|
||||
std::string name = std::format("{}{}", dirty ? "\uea81 " : "", file.path().stem().string());
|
||||
if(ImGui::Selectable(
|
||||
std::format(" {}##{}", Rename_ && selected ? "" : name.c_str(), file.get_id()).c_str()
|
||||
, selected, ImGuiSelectableFlags_SpanAllColumns
|
||||
))
|
||||
{
|
||||
Selected_ = Rename_ ? Selected_ : it;
|
||||
}
|
||||
|
||||
// Renaming
|
||||
if(selected && Rename_)
|
||||
{
|
||||
ImGui::SameLine();
|
||||
if(FocusRename_) ImGui::SetKeyboardFocusHere();
|
||||
|
||||
if(ImGui::InputText(" ##rename", &RenameBuffer_, ImGuiInputTextFlags_EnterReturnsTrue))
|
||||
{
|
||||
if(not RenameBuffer_.empty()) Filesystem_.rename(Selected_, RenameBuffer_);
|
||||
|
||||
Rename_ = false;
|
||||
}
|
||||
|
||||
if(FocusRename_)
|
||||
{
|
||||
FocusRename_ = false;
|
||||
}
|
||||
else if(ImGui::IsItemFocused() == false)
|
||||
{
|
||||
Rename_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", file.path().extension().string().c_str());
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", file.path().string().c_str());
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenShaderDesigner::FileManager::AnyDirty()
|
||||
{
|
||||
bool res = false;
|
||||
struct Visitor
|
||||
{
|
||||
bool operator()(File& file, FileID id)
|
||||
{
|
||||
if(id == FileSystem::root) return false;
|
||||
|
||||
res |= file->Dirty();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool& res;
|
||||
} visitor{ res };
|
||||
Filesystem_.traverse(visitor);
|
||||
return res;
|
||||
}
|
||||
|
||||
void OpenShaderDesigner::FileManager::SaveAll()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
OpenShaderDesigner::FileManager::Path OpenShaderDesigner::FileManager::GetHomeDirectory()
|
||||
{
|
||||
#ifdef WIN32
|
||||
return Path(getenv("HOMEDRIVE")) / getenv("HOMEPATH");
|
||||
#else
|
||||
return getenv("HOME");
|
||||
#endif
|
||||
}
|
3
Source/Graph/Compiler.cpp
Normal file
3
Source/Graph/Compiler.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
//
|
||||
// Created by Maddie on 9/11/2024.
|
||||
//
|
@ -210,8 +210,8 @@ void Node::Draw(ImGuiID id)
|
||||
|
||||
ShaderGraph::ShaderGraph()
|
||||
: EditorWindow("\uED46 Shader Graph", 0)
|
||||
, GrabFocus(false)
|
||||
, State(*this)
|
||||
, GrabFocus_(false)
|
||||
, State_(*this)
|
||||
{
|
||||
}
|
||||
|
||||
@ -223,7 +223,7 @@ void ShaderGraph::OnOpen()
|
||||
{
|
||||
EditorSystem::Open<Inspector>()->Graph = this;
|
||||
|
||||
GrabFocus = true;
|
||||
GrabFocus_ = true;
|
||||
}
|
||||
|
||||
|
||||
@ -236,18 +236,18 @@ void ShaderGraph::DrawWindow()
|
||||
|
||||
ImNodeGraph::SetGraphValidation(ValidateConnection);
|
||||
|
||||
if(GrabFocus)
|
||||
if(GrabFocus_)
|
||||
{
|
||||
GrabFocus = false;
|
||||
GrabFocus_ = false;
|
||||
ImGui::SetWindowFocus();
|
||||
ImGui::SetNavWindow(ImGui::GetCurrentWindow());
|
||||
}
|
||||
|
||||
for(ImGuiID id = 0; id < State.Nodes.size(); ++id)
|
||||
for(ImGuiID id = 0; id < State_.Nodes.size(); ++id)
|
||||
{
|
||||
if(State.Nodes(id) == false) continue;
|
||||
if(State_.Nodes(id) == false) continue;
|
||||
|
||||
State.Nodes[id]->Draw(id);
|
||||
State_.Nodes[id]->Draw(id);
|
||||
}
|
||||
|
||||
DrawContextMenu();
|
||||
@ -257,14 +257,15 @@ void ShaderGraph::DrawWindow()
|
||||
|
||||
ImNodeGraph::BeginGraphPostOp("ShaderGraph");
|
||||
|
||||
if(ImGui::IsKeyPressed(ImGuiKey_Delete))
|
||||
if(ImGui::IsKeyPressed(ImGuiKey_Delete)) Erase();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
if(!(io.KeyMods & ~ImGuiMod_Ctrl))
|
||||
{
|
||||
auto& selected = ImNodeGraph::GetSelected();
|
||||
for(ImGuiID node : selected)
|
||||
{
|
||||
State.Nodes.erase(ImNodeGraph::GetUserID(node).Int);
|
||||
}
|
||||
selected.Clear();
|
||||
if(ImGui::IsKeyPressed(ImGuiKey_C)) Copy();
|
||||
if(ImGui::IsKeyPressed(ImGuiKey_P)) Paste(ImGui::GetMousePos());
|
||||
if(ImGui::IsKeyPressed(ImGuiKey_X)) { Copy(); Erase(); }
|
||||
}
|
||||
|
||||
ImNodeGraph::EndGraphPostOp();
|
||||
@ -275,7 +276,7 @@ void ShaderGraph::DrawContextMenu()
|
||||
{
|
||||
if(ImGui::IsMouseClicked(ImGuiMouseButton_Right))
|
||||
{
|
||||
ContextMenuPosition = ImNodeGraph::ScreenToGrid(ImGui::GetMousePos());
|
||||
ContextMenuPosition_ = ImNodeGraph::ScreenToGrid(ImGui::GetMousePos());
|
||||
}
|
||||
|
||||
if(ImGui::BeginPopupContextWindow("graph_context"))
|
||||
@ -286,7 +287,7 @@ void ShaderGraph::DrawContextMenu()
|
||||
Copy();
|
||||
Erase();
|
||||
}
|
||||
if(ImGui::MenuItem("Paste", "Ctrl+V", false, false)) Paste(ContextMenuPosition);
|
||||
if(ImGui::MenuItem("Paste", "Ctrl+V", false, false)) Paste(ContextMenuPosition_);
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
@ -295,7 +296,7 @@ void ShaderGraph::DrawContextMenu()
|
||||
ImGui::Separator();
|
||||
|
||||
// Create Nodes
|
||||
ImVec2 position = ContextMenuPosition;
|
||||
ImVec2 position = ContextMenuPosition_;
|
||||
|
||||
std::stack<ContextID> context; context.push(0);
|
||||
|
||||
@ -319,7 +320,7 @@ void ShaderGraph::DrawContextMenu()
|
||||
{
|
||||
if(ImGui::MenuItem(item.Name.c_str()))
|
||||
{
|
||||
Graph.State.Nodes.insert(item.Constructor(Graph, Location));
|
||||
Graph.State_.Nodes.insert(item.Constructor(Graph, Location));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -360,18 +361,31 @@ void ShaderGraph::DrawContextMenu()
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderGraph::Copy() {}
|
||||
void ShaderGraph::Erase() {}
|
||||
void ShaderGraph::Copy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ShaderGraph::Erase()
|
||||
{
|
||||
auto& selected = ImNodeGraph::GetSelected();
|
||||
for(ImGuiID node : selected)
|
||||
{
|
||||
State_.Nodes.erase(ImNodeGraph::GetUserID(node).Int);
|
||||
}
|
||||
selected.Clear();
|
||||
}
|
||||
|
||||
void ShaderGraph::Paste(ImVec2) {}
|
||||
|
||||
Node* ShaderGraph::FindNode(ImPinPtr ptr)
|
||||
{
|
||||
return State.Nodes[ImNodeGraph::GetUserID(ptr.Node).Int];
|
||||
return State_.Nodes[ImNodeGraph::GetUserID(ptr.Node).Int];
|
||||
}
|
||||
|
||||
Pin& ShaderGraph::FindPin(ImPinPtr ptr)
|
||||
{
|
||||
Node* node = State.Nodes[ImNodeGraph::GetUserID(ptr.Node).Int];
|
||||
Node* node = State_.Nodes[ImNodeGraph::GetUserID(ptr.Node).Int];
|
||||
auto& pins = ptr.Direction ? node->IO.Outputs : node->IO.Inputs;
|
||||
int idx = ImNodeGraph::GetUserID(ptr).Int;
|
||||
if(ptr.Direction) idx *= -1;
|
||||
@ -410,12 +424,12 @@ void ShaderGraph::Register(const std::filesystem::path& path, ConstructorPtr con
|
||||
|
||||
if(node == 0 || node != child)
|
||||
{
|
||||
node = ContextMenu.insert({ decomp.top(), nullptr }, node);
|
||||
node = ContextMenu.insert({ decomp.top(), nullptr }, node, -1);
|
||||
decomp.pop();
|
||||
}
|
||||
}
|
||||
|
||||
ContextMenu.insert({ name, constructor }, node);
|
||||
ContextMenu.insert({ name, constructor }, node, -1);
|
||||
}
|
||||
|
||||
Inspector::Inspector()
|
||||
|
169
Source/Project/Project.cpp
Normal file
169
Source/Project/Project.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
//
|
||||
// Created by Maddie on 9/14/2024.
|
||||
//
|
||||
|
||||
#include <Core/Engine.h>
|
||||
#include <Editor/EditorSystem.h>
|
||||
#include <Project/Project.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <Core/Console.h>
|
||||
|
||||
#include <portable-file-dialogs/portable-file-dialogs.h>
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/istreamwrapper.h>
|
||||
#include <rapidjson/ostreamwrapper.h>
|
||||
#include <rapidjson/prettywriter.h>
|
||||
|
||||
OpenShaderDesigner::Project::Project()
|
||||
: ProjectFile_(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
OpenShaderDesigner::Project::~Project()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void OpenShaderDesigner::Project::DrawMenuBar()
|
||||
{
|
||||
FileManager* filesystem = EditorSystem::Get<FileManager>();
|
||||
|
||||
if(ImGui::BeginMenu("File"))
|
||||
{
|
||||
if(ImGui::MenuItem("\uecc9 New..."))
|
||||
{
|
||||
Console::Log(Console::Message, "Creating Project");
|
||||
|
||||
bool cancelled = false;
|
||||
if(filesystem->AnyDirty())
|
||||
{
|
||||
auto save = pfd::message("Unsaved Changes", "Would you like to save your changes?", pfd::choice::yes_no_cancel);
|
||||
switch(save.result())
|
||||
{
|
||||
case pfd::button::yes:
|
||||
Console::Log(Console::Message, "Saving Old Project");
|
||||
filesystem->SaveAll();
|
||||
break;
|
||||
case pfd::button::cancel:
|
||||
Console::Log(Console::Message, "Cancelled");
|
||||
cancelled = true;
|
||||
break;
|
||||
default: case pfd::button::no:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(not cancelled)
|
||||
{
|
||||
filesystem->CloseDirectory(filesystem->Parent(ProjectFile_));
|
||||
|
||||
Console::Log(Console::Message, "Select Location");
|
||||
auto res = pfd::save_file("New", FileManager::GetHomeDirectory().string(), { "Project File (.sgp)", "*.sgp" }).result();
|
||||
|
||||
if(not res.empty())
|
||||
{
|
||||
FileManager::Path path = res;
|
||||
|
||||
if(not path.has_extension()) path = res + ".sgp";
|
||||
|
||||
Console::Log(Console::Alert, "Creating Project {} in {}", path.filename().string(), path.parent_path().string());
|
||||
|
||||
create_directories(path.parent_path());
|
||||
FileManager::FileID root = filesystem->LoadDirectory(path.parent_path());
|
||||
filesystem->CurrentDirectory(root);
|
||||
ProjectFile_ = filesystem->Create(path.filename().string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ImGui::MenuItem("\ued6f Open..."))
|
||||
{
|
||||
Console::Log(Console::Message, "Opening Project");
|
||||
|
||||
bool cancelled = false;
|
||||
if(filesystem->AnyDirty())
|
||||
{
|
||||
auto save = pfd::message("Unsaved Changes", "Would you like to save your changes?", pfd::choice::yes_no_cancel);
|
||||
switch(save.result())
|
||||
{
|
||||
case pfd::button::yes:
|
||||
Console::Log(Console::Message, "Saving Old Project");
|
||||
filesystem->SaveAll();
|
||||
break;
|
||||
case pfd::button::cancel:
|
||||
Console::Log(Console::Message, "Cancelled");
|
||||
cancelled = true;
|
||||
break;
|
||||
default: case pfd::button::no:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(not cancelled)
|
||||
{
|
||||
Console::Log(Console::Message, "Post Dialogue");
|
||||
auto project = pfd::open_file("Open", FileManager::GetHomeDirectory().string(), { "Project File (.sgp)", "*.sgp" });
|
||||
|
||||
if(not project.result().empty())
|
||||
{
|
||||
Console::Log(Console::Message, "Closing Old Project");
|
||||
filesystem->CloseDirectory(filesystem->Parent(ProjectFile_));
|
||||
|
||||
Console::Log(Console::Message, "Closing New Project");
|
||||
FileManager::Path res = FileManager::Path(project.result().front());
|
||||
FileManager::FileID root = filesystem->LoadDirectory(res.parent_path());
|
||||
filesystem->CurrentDirectory(root);
|
||||
|
||||
Console::Log(Console::Message, "Retrieving Project File");
|
||||
ProjectFile_ = filesystem->Get(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenShaderDesigner::Project::Open()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void OpenShaderDesigner::Project::Load(const FileManager::Path& path)
|
||||
{
|
||||
Console::Log(Console::Message, "Loading Project {}", path.string());
|
||||
}
|
||||
|
||||
void OpenShaderDesigner::Project::Save(const FileManager::Path& path)
|
||||
{
|
||||
// Setup
|
||||
rapidjson::Document document;
|
||||
document.SetObject();
|
||||
|
||||
// Write to file
|
||||
std::ofstream file(path);
|
||||
rapidjson::OStreamWrapper out(file);
|
||||
rapidjson::PrettyWriter writer(out);
|
||||
document.Accept(writer);
|
||||
file.close();
|
||||
|
||||
// Clear Dirty Flag
|
||||
Asset::Save(path);
|
||||
|
||||
Console::Log(Console::Alert, "Saved Project {} to {}", path.filename().string(), path.parent_path().string());
|
||||
}
|
||||
|
||||
void OpenShaderDesigner::Project::Create(const FileManager::Path &path)
|
||||
{
|
||||
Console::Log(Console::Message, "Setting Up New Project");
|
||||
Reset();
|
||||
Save(path);
|
||||
}
|
||||
|
||||
void OpenShaderDesigner::Project::Reset()
|
||||
{
|
||||
|
||||
}
|
48
imgui.ini
48
imgui.ini
@ -8,32 +8,32 @@ Size=400,400
|
||||
Collapsed=0
|
||||
|
||||
[Window][Dear ImGui Demo]
|
||||
Pos=3070,364
|
||||
Size=370,711
|
||||
Pos=3070,104
|
||||
Size=370,884
|
||||
Collapsed=0
|
||||
DockId=0x00000008,0
|
||||
|
||||
[Window][ Console]
|
||||
Pos=303,1077
|
||||
Size=3137,340
|
||||
Pos=468,990
|
||||
Size=2972,427
|
||||
Collapsed=0
|
||||
DockId=0x00000004,0
|
||||
|
||||
[Window][ Profiler]
|
||||
Pos=0,1077
|
||||
Size=301,340
|
||||
Pos=0,990
|
||||
Size=466,427
|
||||
Collapsed=0
|
||||
DockId=0x00000003,0
|
||||
|
||||
[Window][ Shader Graph]
|
||||
Pos=0,0
|
||||
Size=3068,1075
|
||||
Pos=0,24
|
||||
Size=3068,964
|
||||
Collapsed=0
|
||||
DockId=0x00000005,0
|
||||
|
||||
[Window][WindowOverViewport_11111111]
|
||||
Pos=0,0
|
||||
Size=3440,1417
|
||||
Pos=0,24
|
||||
Size=3440,1393
|
||||
Collapsed=0
|
||||
|
||||
[Window][Example: Custom rendering]
|
||||
@ -65,19 +65,29 @@ Size=487,534
|
||||
Collapsed=0
|
||||
|
||||
[Window][Inspector]
|
||||
Pos=3070,0
|
||||
Size=370,362
|
||||
Pos=3070,24
|
||||
Size=370,78
|
||||
Collapsed=0
|
||||
DockId=0x00000007,0
|
||||
|
||||
[Window][File Manager]
|
||||
Pos=468,990
|
||||
Size=2972,427
|
||||
Collapsed=0
|
||||
DockId=0x00000004,1
|
||||
|
||||
[Window][File Manager/##hierarchy_CA8B7713]
|
||||
IsChild=1
|
||||
Size=289,363
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,0 Size=3440,1417 Split=Y
|
||||
DockNode ID=0x00000001 Parent=0x7C6B3D9B SizeRef=3440,378 Split=X
|
||||
DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,24 Size=3440,1393 Split=Y
|
||||
DockNode ID=0x00000001 Parent=0x7C6B3D9B SizeRef=3440,964 Split=X
|
||||
DockNode ID=0x00000005 Parent=0x00000001 SizeRef=3068,1417 CentralNode=1 Selected=0xD4C89E35
|
||||
DockNode ID=0x00000006 Parent=0x00000001 SizeRef=370,1417 Split=Y Selected=0xE7039252
|
||||
DockNode ID=0x00000007 Parent=0x00000006 SizeRef=370,127 Selected=0xE7039252
|
||||
DockNode ID=0x00000008 Parent=0x00000006 SizeRef=370,249 Selected=0xE87781F4
|
||||
DockNode ID=0x00000002 Parent=0x7C6B3D9B SizeRef=3440,340 Split=X Selected=0xE9F1AFD1
|
||||
DockNode ID=0x00000003 Parent=0x00000002 SizeRef=301,448 Selected=0xAC4B19AE
|
||||
DockNode ID=0x00000004 Parent=0x00000002 SizeRef=3137,448 Selected=0xE9F1AFD1
|
||||
DockNode ID=0x00000007 Parent=0x00000006 SizeRef=370,78 Selected=0xE7039252
|
||||
DockNode ID=0x00000008 Parent=0x00000006 SizeRef=370,884 Selected=0xE87781F4
|
||||
DockNode ID=0x00000002 Parent=0x7C6B3D9B SizeRef=3440,427 Split=X Selected=0xE9F1AFD1
|
||||
DockNode ID=0x00000003 Parent=0x00000002 SizeRef=466,448 Selected=0xAC4B19AE
|
||||
DockNode ID=0x00000004 Parent=0x00000002 SizeRef=2972,448 Selected=0x9E7C6CAA
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user