Compiling simple function

This commit is contained in:
Maddie Slockbower 2024-10-22 18:50:13 -04:00
parent e53566a582
commit 14b7c35b74
24 changed files with 1326 additions and 1100 deletions

View File

@ -18,6 +18,8 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_SYSTEM_NAME})
# Find dependenices
find_package(PkgConfig REQUIRED)
find_package(assimp REQUIRED)
find_package(stb REQUIRED)
find_package(Freetype REQUIRED)
find_package(GLEW REQUIRED)
find_package(glm REQUIRED)
@ -53,30 +55,46 @@ add_executable(OpenShaderDesigner
Source/Entry.cpp
# Core
Source/Core/Window.cpp
Source/Core/Console.cpp
Source/Core/EventSystem.cpp
Source/Core/Engine.cpp
Source/Core/Window.cpp Include/Core/Window.h
Source/Core/Console.cpp Include/Core/Console.h
Source/Core/EventSystem.cpp Include/Core/EventSystem.h
Source/Core/Engine.cpp Include/Core/Engine.h
Source/Renderer/Renderer.cpp Include/Renderer/Renderer.h
# Editor
Source/Editor/EditorSystem.cpp
Source/Editor/EditorWindow.cpp
Source/Editor/ConsoleWindow.cpp
Source/Editor/Profiler.cpp
Include/Editor/MainMenuBar.h
Include/Editor/EditorWindow.h
Source/Editor/EditorSystem.cpp Include/Editor/EditorSystem.h
Source/Editor/EditorWindow.cpp Include/Editor/EditorWindow.h
Source/Editor/ConsoleWindow.cpp Include/Editor/ConsoleWindow.h
Source/Editor/Profiler.cpp Include/Editor/Profiler.h
# File System
Source/FileSystem/FileManager.cpp Include/FileSystem/FileManager.h
# Assets
Source/Project/Project.cpp Include/Project/Project.h
# Graph
Source/Graph/ShaderGraph.cpp
Source/Graph/ShaderGraph.cpp Include/Graph/ShaderGraph.h
# 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
Source/Graph/Nodes/Maths.cpp Include/Graph/Nodes/Maths.h
Source/Graph/Nodes/Shaders.cpp Include/Graph/Nodes/Shaders.h
# Utilities
Include/Utility/Timer.h
Include/Renderer/Assets/Texture.h
Source/Renderer/Assets/Texture.cpp
)
# Preprocessor Definitions
target_compile_definitions(OpenShaderDesigner PRIVATE
PROJECT_VERSION="${PROJECT_VERSION}"
PROJECT_VERSION_MAJOR=${VERSION_MAJOR}
PROJECT_VERSION_MINOR=${VERSION_MINOR}
PROJECT_VERSION_PATCH=${VERSION_PATCH}
PROJECT_DIR="${CMAKE_CURRENT_SOURCE_DIR}"
)
target_link_libraries(OpenShaderDesigner PRIVATE
@ -84,6 +102,7 @@ target_link_libraries(OpenShaderDesigner PRIVATE
GLEW::GLEW
OpenGL::GL
${SDL2_LIBRARIES}
assimp::assimp
rapidjson
open-cpp-utils
imgui-docking

View File

@ -18,6 +18,7 @@
#define CONSOLE_H
#include <imgui-docking/imgui.h>
#include <filesystem>
#include <format>
#include <iostream>
#include <sstream>
@ -170,10 +171,11 @@ void Console::Log(
#pragma warning(disable:4996)
#endif
auto tm = *std::localtime(&t);
const auto rel = std::filesystem::relative(file, PROJECT_DIR).string();
std::lock_guard guard(Lock_);
LogEntry entry{
std::vformat(fmt.get(), std::make_format_args(vargs...)), severity, file, std::format(
std::vformat(fmt.get(), std::make_format_args(vargs...)), severity, rel, std::format(
"{:0>2}:{:0>2}:{:0>2}", tm.tm_hour, tm.tm_min, tm.tm_sec),
ThreadID(), line
};

View File

@ -29,6 +29,11 @@ public:
static void Start(const Window::Configuration& config);
static void Stop();
static inline const char* VersionString() { return PROJECT_VERSION; }
static inline int VersionMajor() { return PROJECT_VERSION_MAJOR; }
static inline int VersionMinor() { return PROJECT_VERSION_MINOR; }
static inline int VersionPatch() { return PROJECT_VERSION_PATCH; }
static Window& GetMainWindow() { return *MainWindow; }
private:
static void Initialize();

View File

@ -17,11 +17,13 @@
#define FILESYSTEM_H
#include <Editor/EditorWindow.h>
#include <FileSystem/Asset.h>
#include <open-cpp-utils/filesystem.h>
#include <open-cpp-utils/map.h>
#include <open-cpp-utils/startup.h>
#define RegisterAsset(Name, Type, ...) \
STARTUP(_Register##Type) { FileManager::Register(Name, { __VA_ARGS__ }, ##Type::Create, ##Type::Load, ##Type::Import); }
namespace ocu = open_cpp_utils;
@ -31,31 +33,84 @@ namespace OpenShaderDesigner
class FileManager : public EditorWindow
{
public:
class Asset;
using FileSystem = ocu::filesystem<Asset, FileManager>;
using File = FileSystem::file;
using Path = std::filesystem::path;
using FileID = FileSystem::file_id;
using FileType = uint32_t;
using CreateFunc = Asset* (*)(const Path&);
using LoadFunc = Asset* (*)(const Path&);
using ImportFunc = Asset* (*)(const Path&, const Path&);
friend FileSystem;
enum FileType_
private:
struct AssetDetail
{
FileType_Folder = 0
, FileType_Project
std::string Name;
std::vector<std::string> Extensions;
CreateFunc Create;
LoadFunc Load;
ImportFunc Import;
AssetDetail() : Create(nullptr), Load(nullptr), Import(nullptr) { }
AssetDetail(const std::string& name) : Name(name), Create(nullptr), Load(nullptr), Import(nullptr) {}
AssetDetail(const std::string& name, const std::vector<std::string>& exts,
const CreateFunc create, const LoadFunc load, const ImportFunc import)
: Name(name), Extensions(exts), Create(create), Load(load), Import(import) {}
};
inline static ocu::map<std::string, FileType> ExtensionMap = {
{ "", FileType_Folder }
, { ".sgp", FileType_Project }
using AssetMenuHierarchy = ocu::directed_tree<AssetDetail>;
using AssetType = AssetMenuHierarchy::node;
using ExtensionMapping = ocu::map<std::string, AssetType>;
static AssetMenuHierarchy& AssetMenu() { static AssetMenuHierarchy Menu; return Menu; }
static ExtensionMapping& ExtensionMap() { static ExtensionMapping Map; return Map; }
public:
class Asset
{
public:
Asset(const Path& path) : Dirty_(false) { }
virtual ~Asset() = default;
bool Dirty() const { return Dirty_; }
virtual void Open() { };
virtual void Save(const Path& path) { Dirty_ = false; }
File& GetFile() { return Manager_->Get(File_); }
FileID GetID() const { return File_; }
protected:
void MakeDirty() { Dirty_ = true; }
FileManager* Parent() const { return Manager_; }
private:
FileManager* Manager_;
FileID File_;
bool Dirty_;
friend FileManager;
};
struct Folder : Asset
{
Folder(const std::filesystem::path& p) : Asset(p) { };
virtual ~Folder() = default;
void Open() override { Manager_->CurrentDirectory_ = GetID(); }
};
private:
static Asset* load(const Path& file);
static Asset* import(const Path& src, const Path& dst);
static Asset* create(const Path& file);
static Asset* load(const Path& file, FileID id);
static Asset* import(const Path& src, const Path& dst, FileID id);
static Asset* create(const Path& file, FileID id);
public:
FileManager();
virtual ~FileManager() = default;
void DrawMenu() override;
void DrawWindow() override;
@ -64,13 +119,13 @@ public:
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 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); }
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]; }
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); }
@ -78,6 +133,9 @@ public:
void SaveAll();
static Path GetHomeDirectory();
static void Register(const std::filesystem::path& path,
const std::vector<std::string>& extension,
CreateFunc create, LoadFunc load, ImportFunc import);
private:
FileSystem Filesystem_;
FileID CurrentDirectory_, Selected_;

View File

@ -1,19 +0,0 @@
// =====================================================================================================================
// 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 COMPILER_H
#define COMPILER_H
#endif //COMPILER_H

View File

@ -13,24 +13,24 @@
// limitations under the License.
// =====================================================================================================================
#ifndef MATH_H
#define MATH_H
#ifndef OSD_MATH_H
#define OSD_MATH_H
#include <glm/vec4.hpp>
#include <Graph/ShaderGraph.h>
#include <open-cpp-utils/any.h>
namespace ocu = open_cpp_utils;
namespace OpenShaderDesigner::Nodes::Math
{
// Header Colors =======================================================================================================
inline static constexpr ImColor HeaderColor = ImColor(0xA7, 0x62, 0x53);
inline static constexpr ImColor HeaderHoveredColor = ImColor(0xC5, 0x79, 0x67);
inline static constexpr ImColor HeaderActiveColor = ImColor(0x82, 0x4C, 0x40);
inline static const std::string HeaderMarker = "\uF3B9 ";
inline static const std::string HeaderMarker = "\uF3B9 ";
@ -43,16 +43,14 @@ inline static const std::string HeaderMarker = "\uF3B9 ";
struct Integer : public Node
{
using ValueType = ocu::any<int, unsigned int, float, glm::vec4>;
Integer(ShaderGraph& graph, ImVec2 pos);
virtual ~Integer() = default;
~Integer() override = default;
[[nodiscard]] Node* Copy(ShaderGraph& graph) const override;
void Inspect() override;
};
RegisterNode("Math/Constants/Integer", Integer);
std::string GetCode() const override;
};
// Unsigned Integer ----------------------------------------------------------------------------------------------------
@ -62,13 +60,13 @@ struct UnsignedInteger : public Node
using ValueType = ocu::any<int, unsigned int, float, glm::vec4>;
UnsignedInteger(ShaderGraph& graph, ImVec2 pos);
virtual ~UnsignedInteger() = default;
~UnsignedInteger() override = default;
[[nodiscard]] Node* Copy(ShaderGraph& graph) const override;
void Inspect() override;
};
RegisterNode("Math/Constants/Unsigned Integer", UnsignedInteger);
std::string GetCode() const override;
};
// Scalar --------------------------------------------------------------------------------------------------------------
@ -78,13 +76,13 @@ struct Scalar : public Node
using ValueType = ocu::any<int, unsigned int, float, glm::vec4>;
Scalar(ShaderGraph& graph, ImVec2 pos);
virtual ~Scalar() = default;
~Scalar() override = default;
[[nodiscard]] Node* Copy(ShaderGraph& graph) const override;
void Inspect() override;
};
RegisterNode("Math/Constants/Scalar", Scalar);
std::string GetCode() const override;
};
// Vector --------------------------------------------------------------------------------------------------------------
@ -94,13 +92,13 @@ struct Vector : public Node
using ValueType = ocu::any<int, unsigned int, float, glm::vec4>;
Vector(ShaderGraph& graph, ImVec2 pos);
virtual ~Vector() = default;
~Vector() override = default;
[[nodiscard]] Node* Copy(ShaderGraph& graph) const override;
void Inspect() override;
};
RegisterNode("Math/Constants/Vector", Vector);
std::string GetCode() const override;
};
@ -114,7 +112,7 @@ RegisterNode("Math/Constants/Vector", Vector);
struct MathOp : public Node
{
MathOp(ShaderGraph& graph, ImVec2 pos);
virtual ~MathOp() = default;
~MathOp() override = default;
virtual bool CheckConnection(Pin *, Pin *) override;
virtual void ValidateConnections() override;
@ -128,13 +126,13 @@ struct MathOp : public Node
struct Add : public MathOp
{
Add(ShaderGraph& graph, ImVec2 pos);
virtual ~Add() = default;
~Add() override = default;
[[nodiscard]] Node* Copy(ShaderGraph& graph) const override;
void Inspect() override;
};
RegisterNode("Math/Operators/Add", Add);
std::string GetCode() const override;
};
// Subtract ------------------------------------------------------------------------------------------------------------
@ -142,27 +140,26 @@ RegisterNode("Math/Operators/Add", Add);
struct Subtract : public MathOp
{
Subtract(ShaderGraph& graph, ImVec2 pos);
virtual ~Subtract() = default;
~Subtract() override = default;
[[nodiscard]] Node* Copy(ShaderGraph& graph) const override;
void Inspect() override;
std::string GetCode() const override;
};
RegisterNode("Math/Operators/Subtract", Subtract);
// Multiply ------------------------------------------------------------------------------------------------------------
struct Multiply : public MathOp
{
Multiply(ShaderGraph& graph, ImVec2 pos);
virtual ~Multiply() = default;
~Multiply() override = default;
[[nodiscard]] Node* Copy(ShaderGraph& graph) const override;
void Inspect() override;
};
RegisterNode("Math/Operators/Multiply", Multiply);
std::string GetCode() const override;
};
// Divide --------------------------------------------------------------------------------------------------------------
@ -170,16 +167,15 @@ RegisterNode("Math/Operators/Multiply", Multiply);
struct Divide : public MathOp
{
Divide(ShaderGraph& graph, ImVec2 pos);
virtual ~Divide() = default;
~Divide() override = default;
[[nodiscard]] Node* Copy(ShaderGraph& graph) const override;
void Inspect() override;
std::string GetCode() const override;
};
RegisterNode("Math/Operators/Divide", Divide);
// =====================================================================================================================
// Utilities
// =====================================================================================================================
@ -190,13 +186,13 @@ RegisterNode("Math/Operators/Divide", Divide);
struct MakeVector : public Node
{
MakeVector(ShaderGraph& graph, ImVec2 pos);
virtual ~MakeVector() = default;
~MakeVector() override = default;
[[nodiscard]] Node* Copy(ShaderGraph& graph) const override;
void Inspect() override;
};
RegisterNode("Math/Utilities/Make Vector", MakeVector);
std::string GetCode() const override;
};
// Break Vector ---------------------------------------------------------------------------------------------------------
@ -204,14 +200,14 @@ struct MakeVector : public Node
struct BreakVector : public Node
{
BreakVector(ShaderGraph& graph, ImVec2 pos);
virtual ~BreakVector() = default;
~BreakVector() override = default;
[[nodiscard]] Node* Copy(ShaderGraph& graph) const override;
void Inspect() override;
};
RegisterNode("Math/Utilities/Break Vector", BreakVector);
std::string GetCode() const override;
};
}
#endif //MATH_H
#endif // OPEN_SHADER_DESIGNER_MATH_H

View File

@ -0,0 +1,65 @@
// =====================================================================================================================
// 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 OSD_SHADERS_H
#define OSD_SHADERS_H
#include <glm/vec4.hpp>
#include <Graph/ShaderGraph.h>
namespace OpenShaderDesigner::Nodes::Shaders
{
// Header Colors =======================================================================================================
inline static constexpr ImColor HeaderColor = ImColor(0xA9, 0x85, 0xC1);
inline static constexpr ImColor HeaderHoveredColor = ImColor(0xBB, 0x96, 0xD4);
inline static constexpr ImColor HeaderActiveColor = ImColor(0x8D, 0x68, 0xA6);
inline static const std::string HeaderMarker = "\uF42E ";
// =====================================================================================================================
// Shaders
// =====================================================================================================================
// Function ------------------------------------------------------------------------------------------------------------
class Function : public Node, public ShaderAsset
{
public:
Function(const FileManager::Path& path, ShaderGraph& graph);
~Function() override = default;
[[nodiscard]] Node* Copy(ShaderGraph& graph) const override;
void Inspect() override;
void Compile() override;
void Open() override;
static Asset* Create(const FileManager::Path& path);
static Asset* Load(const FileManager::Path& path);
static Asset* Import(const FileManager::Path& src, const FileManager::Path& dst);
std::string GetCode() const override;
private:
NodeId ID_;
};
}
#endif // OSD_SHADERS_H

View File

@ -13,33 +13,33 @@
// limitations under the License.
// =====================================================================================================================
#ifndef SHADERGRAPH_H
#define SHADERGRAPH_H
#ifndef OSD_SHADERGRAPH_H
#define OSD_SHADERGRAPH_H
#include <Editor/EditorWindow.h>
#include <vector>
#include <unordered_map>
#include <filesystem>
#include <unordered_set>
#include <set>
#include <stack>
#include <glm/glm.hpp>
#include <glw/common.h>
#include <open-cpp-utils/startup.h>
#include <open-cpp-utils/directed_tree.h>
#include <open-cpp-utils/optional.h>
#include <open-cpp-utils/any.h>
#include <open-cpp-utils/object_pool.h>
#include <imnode-graph/imnode_graph.h>
#include "open-cpp-utils/any.h"
#include "open-cpp-utils/object_pool.h"
#include "FileSystem/FileManager.h"
namespace ocu = open_cpp_utils;
#define RegisterNode(Name, Type) \
Node* Create##Type(ShaderGraph& graph, ImVec2 pos) { return new Type(graph, pos); } \
inline Node* Create##Type(ShaderGraph& graph, ImVec2 pos) { return new Type(graph, pos); } \
STARTUP(_Register##Type) { ShaderGraph::Register(Name, Create##Type); }
namespace OpenShaderDesigner
@ -66,6 +66,13 @@ namespace OpenShaderDesigner
, PinFlags_AlwaysCollapse = 1 << 1
, PinFlags_NoPadding = 1 << 2
, PinFlags_Ambiguous = 1 << 3
};
enum InterpolationType_ : glw::enum_t
{
InterpolationType_Flat = 0
, InterpolationType_Screen
, InterpolationType_Smooth
};
struct Pin
@ -86,6 +93,14 @@ namespace OpenShaderDesigner
, "Any"
};
inline const static std::string TypeKeywords[PinType_COUNT] = {
"uint"
, "int"
, "float"
, "vec3"
, "vec3"
};
inline const static int TypeWidths[PinType_COUNT] = {
1 // Unsigned Int
, 1 // Int
@ -130,57 +145,115 @@ namespace OpenShaderDesigner
struct
{
std::string Alias;
bool Const;
} Info;
Node(ShaderGraph& graph, ImVec2 pos);
~Node() = default;
virtual ~Node() = default;
void DrawPin(int id, Pin& pin, ImPinDirection direction);
void Draw(ImGuiID id);
virtual bool CheckConnection(Pin*, Pin*) { return false; }
inline virtual bool CheckConnection(Pin*, Pin*) { return false; }
virtual void ValidateConnections() { }
virtual Node* Copy(ShaderGraph& graph) const = 0;
virtual void Inspect() = 0;
virtual std::string GetCode() const = 0;
};
using NodeList = ocu::object_list<Node*>;
using NodeId = NodeList::uuid_type;
struct Attribute
{
std::string Name;
glw::enum_t Type;
glw::enum_t Interpolation;
glw::size_t Count;
};
struct Parameter
{
std::string Name;
glw::enum_t Type;
glw::size_t Count; // For arrays
};
struct GraphState
{
ShaderGraph& Parent;
NodeList Nodes;
GraphState(ShaderGraph& parent);
GraphState(const GraphState& other);
~GraphState();
NodeId AddNode(Node* node) { return Nodes.insert(node); }
void RemoveNode(NodeId node) { if(Nodes[node]->Info.Const) return; Nodes.erase(node); }
GraphState& operator=(const GraphState& other);
};
class ShaderAsset : public FileManager::Asset
{
public:
inline static const std::string VersionString = "#version 430 core";
ShaderAsset(const FileManager::Path& path, ShaderGraph& graph)
: Asset(path)
, State_(graph)
{ }
void PushState() { History_.push(State_); }
void PopState() { State_ = History_.top(); History_.pop();}
GraphState& GetState() { return State_; }
const GraphState& GetState() const { return State_; }
ShaderGraph& GetGraph() { return State_.Parent; }
const ShaderGraph& GetGraph() const { return State_.Parent; }
virtual void Compile() = 0;
std::string GetCode() const { return Code; }
protected:
std::string Code;
private:
GraphState State_;
std::stack<GraphState> History_;
};
class ShaderGraph
: public EditorWindow
{
public:
struct GraphState
{
ShaderGraph& Parent;
ocu::object_list<Node*> Nodes;
GraphState(ShaderGraph& parent);
GraphState(const GraphState& other);
~GraphState();
GraphState& operator=(const GraphState& other);
};
private:
friend Node;
using ConstructorPtr = Node*(*)(ShaderGraph&, ImVec2);
struct ContextMenuItem
{
std::string Name;
ConstructorPtr Constructor;
std::string Name;
ConstructorPtr Constructor;
};
using ContextMenuHierarchy = ocu::directed_tree<ContextMenuItem>;
using ContextID = ContextMenuHierarchy::node;
inline static ContextMenuHierarchy ContextMenu;
static ContextMenuHierarchy& ContextMenu() { static ContextMenuHierarchy Menu {{ "", nullptr }}; return Menu; }
public:
ShaderGraph();
~ShaderGraph();
virtual ~ShaderGraph();
void OnOpen() override;
void DrawMenu() override;
void DrawWindow() override;
void DrawContextMenu();
@ -188,23 +261,21 @@ namespace OpenShaderDesigner
void Copy();
void Erase();
void Paste(ImVec2 pos);
void Clear();
Node* FindNode(ImPinPtr ptr);
Pin& FindPin(ImPinPtr ptr);
std::string GetValue(ImPinPtr ptr);
void OpenShader(ShaderAsset* asset) { Shader_ = asset; }
static void Register(const std::filesystem::path& path, ConstructorPtr constructor);
// History Functionality
void PushState();
void PopState();
GraphState& GetState() { return State_; }
private:
// TODO: Make bitfield
bool GrabFocus_;
GraphState State_;
std::stack<GraphState> History_;
ShaderAsset* Shader_;
ImVec2 ContextMenuPosition_;
@ -226,4 +297,4 @@ namespace OpenShaderDesigner
};
}
#endif //SHADERGRAPH_H
#endif // OSD_SHADERGRAPH_H

View File

@ -1,6 +1,17 @@
// =====================================================================================================================
// 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
//
// Created by Maddie on 9/14/2024.
// 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 PROJECT_H
#define PROJECT_H
@ -11,7 +22,7 @@
namespace OpenShaderDesigner
{
class Project : public MainMenuBar, public Asset
class Project : public MainMenuBar, public FileManager::Asset
{
public:
Project();
@ -20,9 +31,11 @@ public:
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);
static Asset* Create(const FileManager::Path& path);
static Asset* Load(const FileManager::Path& path);
static Asset* Import(const FileManager::Path& src, const FileManager::Path& dst);
private:
void Reset();

View File

@ -13,34 +13,37 @@
// limitations under the License.
// =====================================================================================================================
#ifndef ASSET_H
#define ASSET_H
#ifndef TEXTURE_H
#define TEXTURE_H
#include <open-cpp-utils/filesystem.h>
#include <glw/texture.h>
namespace ocu = open_cpp_utils;
#include "FileSystem/FileManager.h"
namespace OpenShaderDesigner
{
class Asset
class Texture : public FileManager::Asset
{
public:
Asset() : Dirty_(false) { }
using HandleType = glw::texture<glw::texture2D, glw::rgba8>;
bool Dirty() const { return Dirty_; }
Texture(const FileManager::Path& path);
Texture(const FileManager::Path& src, const FileManager::Path& dst);
~Texture() override;
virtual void Open() = 0;
virtual void Load(const std::filesystem::path& path) = 0;
virtual void Save(const std::filesystem::path& path) { Dirty_ = false; };
void Open() override;
protected:
void MakeDirty() { Dirty_ = true; }
static Asset* Create(const FileManager::Path& path);
static Asset* Load(const FileManager::Path& path);
static Asset* Import(const FileManager::Path& src, const FileManager::Path& dst);
HandleType* operator->() { return Handle_; }
const HandleType* operator->() const { return Handle_; }
private:
bool Dirty_;
HandleType* Handle_;
};
}
#endif //ASSET_H
#endif //TEXTURE_H

View File

@ -17,14 +17,40 @@
#ifndef RENDERER_H
#define RENDERER_H
#include <Editor/EditorWindow.h>
#include <Renderer/Assets/Texture.h>
#include "glw/shader.h"
namespace OpenShaderDesigner
{
class Renderer
class Renderer : public EditorWindow
{
public:
enum mode : glw::enum_t
{
none = 0
, view_texture
, function
};
Renderer();
virtual ~Renderer();
void DrawMenu() override;
void DrawWindow() override;
void OpenTexture(Texture* texture);
private:
void DrawTexture();
void DrawFunction();
glw::enum_t Mode_;
Texture* ViewTexture_;
glw::shader* Shader_;
};
}

View File

@ -20,15 +20,20 @@
#include <Editor/ConsoleWindow.h>
#include <Editor/Profiler.h>
#include <Renderer/Renderer.h>
#include <FileSystem/FileManager.h>
#include <Graph/ShaderGraph.h>
#include "Project/Project.h"
void OpenShaderDesigner::Engine::Start(const Window::Configuration& config)
using namespace OpenShaderDesigner;
void Engine::Start(const Window::Configuration& config)
{
Console::Log(Console::Severity::Alert, "Starting {}", config.Application.Title);
std::string version = VersionString();
Console::Log(Console::Severity::Alert, "Starting {} ({})", config.Application.Title, version);
Console::Log(Console::Message, "Creating Main Window");
MainWindow = new Window(config);
@ -44,12 +49,12 @@ void OpenShaderDesigner::Engine::Start(const Window::Configuration& config)
Shutdown();
}
void OpenShaderDesigner::Engine::Stop()
void Engine::Stop()
{
MainWindow->Close();
}
void OpenShaderDesigner::Engine::Initialize()
void Engine::Initialize()
{
Console::Log(Console::Message, "Initializing Engine");
@ -69,16 +74,23 @@ void OpenShaderDesigner::Engine::Initialize()
EditorSystem::Open<Inspector>();
EditorSystem::Open<ShaderGraph>();
Console::Log(Console::Message, "Opening Renderer");
EditorSystem::Open<Renderer>();
Console::Log(Console::Message, "Setting up Project");
EditorSystem::SetMainMenuBar<Project>();
FileManager* filesystem = EditorSystem::Get<FileManager>();
filesystem->LoadDirectory("./Test/");
}
void OpenShaderDesigner::Engine::Shutdown()
void Engine::Shutdown()
{
EditorSystem::Shutdown();
}
void OpenShaderDesigner::Engine::Update()
void Engine::Update()
{
_Delta = Frame.Poll();
Frame.Reset();

View File

@ -28,7 +28,7 @@ Window::Window(const Configuration& config)
flags |= Config_.Video.Fullscreen == FullscreenMode::WINDOWED ? SDL_WINDOW_RESIZABLE : 0;
SDL_Init(SDL_INIT_EVERYTHING & ~SDL_INIT_AUDIO);
#ifdef NDEBUG
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
#else
@ -49,13 +49,12 @@ Window::Window(const Configuration& config)
SDL_GL_SetAttribute(SDL_GL_FLOATBUFFERS, SDL_TRUE);
}
if(Config_.Video.Multisamples())
if(Config_.Video.Multisamples() && Config_.Video.Multisamples > 1)
{
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, SDL_TRUE);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, Config_.Video.Multisamples);
}
if((Handle_ = SDL_CreateWindow(
Config_.Application.Title.c_str(),
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,

View File

@ -23,7 +23,7 @@ int main(int, char**)
Window::Configuration config;
config.Application.Title = "OpenShaderDesigner";
config.Video.Multisamples = 16;
//config.Video.Multisamples = 4;
config.Video.Fullscreen = Window::FullscreenMode::WINDOWED;
config.Video.Resolution = { 1280, 720 };
config.Video.HDR = false;

View File

@ -17,54 +17,80 @@
#include <FileSystem/FileManager.h>
#include <Core/Console.h>
#include <imgui-docking/misc/cpp/imgui_stdlib.h>
#include "Project/Project.h"
using namespace OpenShaderDesigner;
OpenShaderDesigner::Asset * OpenShaderDesigner::FileManager::load(const Path& path)
FileManager::Asset* FileManager::load(const Path& path, FileID id)
{
Console::Log(Console::Message, "Loading File {}", path.string());
FileType type = ExtensionMap[path.extension().string()];
switch (type)
// Create Folder dummy Asset for Folders
if(is_directory(path))
{
case FileType_Project:
{
Project* project = EditorSystem::GetMainMenuBar<Project>();
project->Load(path);
return project;
Asset* asset = new Folder(path);
asset->Manager_ = EditorSystem::Get<FileManager>();
asset->File_ = id;
return asset;
}
default:
return nullptr;
// Get the type and load the asset
AssetType type = ExtensionMap()[path.extension().string()];
Asset* asset = AssetMenu()[type].Load(path);
// Set the ID and Manager of the file
if(asset)
{
asset->Manager_ = EditorSystem::Get<FileManager>();
asset->File_ = id;
}
return asset;
}
OpenShaderDesigner::Asset * OpenShaderDesigner::FileManager::import(const Path &src, const Path &dst)
FileManager::Asset* FileManager::import(const Path &src, const Path &dst, FileID id)
{
return nullptr;
Console::Log(Console::Message, "Importing File {} to {}", src.string(), dst.string());
// Get the type and load the asset
AssetType type = ExtensionMap()[src.extension().string()];
Asset* asset = AssetMenu()[type].Import(src, dst);
if(asset)
{
asset->Manager_ = EditorSystem::Get<FileManager>();
asset->File_ = id;
}
return asset;
}
OpenShaderDesigner::Asset * OpenShaderDesigner::FileManager::create(const Path &path)
FileManager::Asset* FileManager::create(const Path &path, FileID id)
{
Console::Log(Console::Message, "Creating File {}", path.string());
FileType type = ExtensionMap[path.extension().string()];
switch (type)
// Create Folder dummy Asset for Folders
if(is_directory(path))
{
case FileType_Project:
{
Project* project = EditorSystem::GetMainMenuBar<Project>();
project->Create(path);
return project;
}
default:
return nullptr;
Asset* asset = new Folder(path);
asset->Manager_ = EditorSystem::Get<FileManager>();
return asset;
}
// Get the type and load the asset
AssetType type = ExtensionMap()[path.extension().string()];
Asset* asset = AssetMenu()[type].Create(path);
if(asset)
{
asset->Manager_ = EditorSystem::Get<FileManager>();
asset->File_ = id;
}
return asset;
}
OpenShaderDesigner::FileManager::FileManager()
FileManager::FileManager()
: EditorWindow("File Manager", ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoScrollbar)
, CurrentDirectory_(FileSystem::root), Selected_(FileSystem::root)
, Rename_(false), FocusRename_(false)
@ -72,12 +98,78 @@ OpenShaderDesigner::FileManager::FileManager()
//CurrentDirectory_ = Filesystem_.load_directory(std::filesystem::current_path());
}
void OpenShaderDesigner::FileManager::DrawMenu()
void FileManager::DrawMenu()
{
if(ImGui::BeginMenu("File"))
{
if(ImGui::BeginMenu("Create"))
{
struct Visitor
{
bool operator()(AssetDetail& item, AssetType id)
{
AssetMenuHierarchy& AssetMenu = FileManager::AssetMenu();
const auto depth = AssetMenu.depth(id);
if(depth > Context.size()) return false;
if(item.Name == "##") return false;
while(depth < Context.size())
{
Context.pop();
ImGui::EndMenu();
}
if(Context.top() != AssetMenu.parent(id)) return false;
std::string name = std::format("{}##{}", item.Name, id);
if(item.Create != nullptr)
{
if(ImGui::MenuItem(name.c_str()))
{
Manager.Create(std::format("{}{}", item.Name, item.Extensions[0]));
}
}
else
{
if(ImGui::BeginMenu(name.c_str()))
{
Context.push(id);
}
else
{
return false;
}
}
return false;
}
FileManager& Manager;
std::stack<AssetType> Context;
} MenuVisitor
{
.Manager = *this
};
MenuVisitor.Context.push(0);
AssetMenu().traverse<AssetMenuHierarchy::pre_order>(MenuVisitor);
MenuVisitor.Context.pop();
while(MenuVisitor.Context.empty() == false)
{
ImGui::EndMenu();
MenuVisitor.Context.pop();
}
ImGui::EndPopup();
}
ImGui::EndMenu();
}
}
void OpenShaderDesigner::FileManager::DrawWindow()
void FileManager::DrawWindow()
{
// Directory Hierarchy
ImGui::BeginGroup();
@ -90,9 +182,9 @@ void OpenShaderDesigner::FileManager::DrawWindow()
{
const FileSystem& tree = file.system();
uint32_t depth = tree.depth(id);
// Skip root
if(id == FileSystem::root) return false;
if(id == FileSystem::root) return false; // Skip root
if(*file == nullptr) return false; // Skip files without assets
// Skip if we are in a closed directory
if(depth > stack.size()) return false;
@ -190,6 +282,13 @@ void OpenShaderDesigner::FileManager::DrawWindow()
{
Selected_ = Rename_ ? Selected_ : it;
}
if(ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) && selected)
{
File& file = Filesystem_[Selected_];
Asset* asset = *file;
asset->Open();
}
// Renaming
if(selected && Rename_)
@ -225,14 +324,15 @@ void OpenShaderDesigner::FileManager::DrawWindow()
}
}
bool OpenShaderDesigner::FileManager::AnyDirty()
bool FileManager::AnyDirty()
{
bool res = false;
struct Visitor
{
bool operator()(File& file, FileID id)
{
if(id == FileSystem::root) return false;
if(id == FileSystem::root) return false; // Continue if root node
if(*file == nullptr) return false; // Continue if no asset associated with file
res |= file->Dirty();
return false;
@ -244,12 +344,12 @@ bool OpenShaderDesigner::FileManager::AnyDirty()
return res;
}
void OpenShaderDesigner::FileManager::SaveAll()
void FileManager::SaveAll()
{
}
OpenShaderDesigner::FileManager::Path OpenShaderDesigner::FileManager::GetHomeDirectory()
FileManager::Path FileManager::GetHomeDirectory()
{
#ifdef WIN32
return Path(getenv("HOMEDRIVE")) / getenv("HOMEPATH");
@ -257,3 +357,108 @@ OpenShaderDesigner::FileManager::Path OpenShaderDesigner::FileManager::GetHomeDi
return getenv("HOME");
#endif
}
void FileManager::Register(const std::filesystem::path& path,
const std::vector<std::string>& extensions,
CreateFunc create, LoadFunc load, ImportFunc import)
{
const std::string name = path.filename().string();
AssetMenuHierarchy& AssetMenu = FileManager::AssetMenu();
ExtensionMapping& ExtensionMap = FileManager::ExtensionMap();
AssetType node = 0;
for(auto it = path.begin(); it != path.end();)
{
AssetType child = AssetMenu.first_child(node);
while(child)
{
if(AssetMenu[child].Name == it->filename())
{
node = child;
++it;
break;
}
child = AssetMenu.next_sibling(child);
}
if(node == 0 || node != child)
{
node = AssetMenu.insert({ it->string(), {}, nullptr, nullptr, nullptr }, node);
++it;
}
}
AssetMenu[node].Create = create;
AssetMenu[node].Import = import;
AssetMenu[node].Load = load;
AssetMenu[node].Extensions = extensions;
for(const auto& ext : extensions)
{
ExtensionMap[ext] = node;
}
}

View File

@ -1,3 +0,0 @@
//
// Created by Maddie on 9/11/2024.
//

View File

@ -13,14 +13,24 @@
// limitations under the License.
// =====================================================================================================================
#include <Graph/Nodes/Math.h>
#include <imgui-extras/imgui_extras.h>
#include <Graph/Nodes/Maths.h>
#include <queue>
using namespace OpenShaderDesigner;
using namespace OpenShaderDesigner::Nodes::Math;
RegisterNode("Math/Constants/Integer", Integer);
RegisterNode("Math/Constants/Unsigned Integer", UnsignedInteger);
RegisterNode("Math/Constants/Scalar", Scalar);
RegisterNode("Math/Constants/Vector", Vector);
RegisterNode("Math/Operators/Add", Add);
RegisterNode("Math/Operators/Subtract", Subtract);
RegisterNode("Math/Operators/Multiply", Multiply);
RegisterNode("Math/Operators/Divide", Divide);
RegisterNode("Math/Utilities/Make Vector", MakeVector);
RegisterNode("Math/Utilities/Break Vector", BreakVector);
// =====================================================================================================================
// Constants
// =====================================================================================================================
@ -31,6 +41,7 @@ using namespace OpenShaderDesigner::Nodes::Math;
Integer::Integer(ShaderGraph& graph, ImVec2 pos)
: Node(graph, pos)
{
Info.Alias = "Integer";
Header.Title = HeaderMarker + "Integer";
Header.Color = HeaderColor;
Header.HoveredColor = HeaderHoveredColor;
@ -49,12 +60,21 @@ void Integer::Inspect()
}
std::string Integer::GetCode() const
{
return std::format("const int {} = {};",
Graph.GetValue(IO.Outputs[0].Ptr)
, IO.Outputs[0].Value.get<int>()
);
}
// Unsigned Integer ----------------------------------------------------------------------------------------------------
UnsignedInteger::UnsignedInteger(ShaderGraph& graph, ImVec2 pos)
: Node(graph, pos)
{
Info.Alias = "UnsignedInteger";
Header.Title = HeaderMarker + "Unsigned Integer";
Header.Color = HeaderColor;
Header.HoveredColor = HeaderHoveredColor;
@ -73,12 +93,21 @@ void UnsignedInteger::Inspect()
}
std::string UnsignedInteger::GetCode() const
{
return std::format("const unsigned int {} = {};",
Graph.GetValue(IO.Outputs[0].Ptr)
, IO.Outputs[0].Value.get<unsigned int>()
);
}
// Scalar --------------------------------------------------------------------------------------------------------------
Scalar::Scalar(ShaderGraph& graph, ImVec2 pos)
: Node(graph, pos)
{
Info.Alias = "Scalar";
Header.Title = HeaderMarker + "Scalar";
Header.Color = HeaderColor;
Header.HoveredColor = HeaderHoveredColor;
@ -97,12 +126,21 @@ void Scalar::Inspect()
}
std::string Scalar::GetCode() const
{
return std::format("const float {} = {};",
Graph.GetValue(IO.Outputs[0].Ptr)
, IO.Outputs[0].Value.get<float>()
);
}
// Vector --------------------------------------------------------------------------------------------------------------
Vector::Vector(ShaderGraph &graph, ImVec2 pos)
: Node(graph, pos)
{
Info.Alias = "Vector";
Header.Title = HeaderMarker + "Vector";
Header.Color = HeaderColor;
Header.HoveredColor = HeaderHoveredColor;
@ -123,6 +161,15 @@ void Vector::Inspect()
}
std::string Vector::GetCode() const
{
const glm::vec3& val = IO.Outputs[0].Value.get<glm::vec3>();
return std::format("const int {} = vec3({},{},{});",
Graph.GetValue(IO.Outputs[0].Ptr)
, val.x, val.y, val.z
);
}
// =====================================================================================================================
// Math Operations
@ -193,6 +240,7 @@ void MathOp::ValidateConnections()
Add::Add(ShaderGraph& graph, ImVec2 pos)
: MathOp(graph, pos)
{
Info.Alias = "Add";
Header.Title = HeaderMarker + "Add";
Header.Color = HeaderColor;
Header.HoveredColor = HeaderHoveredColor;
@ -215,12 +263,24 @@ void Add::Inspect()
}
std::string Add::GetCode() const
{
// TODO: Support more than 2 inputs
return std::format("const {} {} = {} + {};",
Pin::TypeKeywords[IO.Outputs[0].Type]
, Graph.GetValue(IO.Outputs[0].Ptr)
, Graph.GetValue(IO.Inputs[0].Ptr)
, Graph.GetValue(IO.Inputs[1].Ptr)
);
}
// Subtract ------------------------------------------------------------------------------------------------------------
Subtract::Subtract(ShaderGraph& graph, ImVec2 pos)
: MathOp(graph, pos)
{
Info.Alias = "Subtract";
Header.Title = HeaderMarker + "Subtract";
Header.Color = HeaderColor;
Header.HoveredColor = HeaderHoveredColor;
@ -243,12 +303,24 @@ void Subtract::Inspect()
}
std::string Subtract::GetCode() const
{
// TODO: Support more than 2 inputs
return std::format("const {} {} = {} - {};",
Pin::TypeKeywords[IO.Outputs[0].Type]
, Graph.GetValue(IO.Outputs[0].Ptr)
, Graph.GetValue(IO.Inputs[0].Ptr)
, Graph.GetValue(IO.Inputs[1].Ptr)
);
}
// Multiply ------------------------------------------------------------------------------------------------------------
Multiply::Multiply(ShaderGraph& graph, ImVec2 pos)
: MathOp(graph, pos)
{
Info.Alias = "Multiply";
Header.Title = HeaderMarker + "Multiply";
Header.Color = HeaderColor;
Header.HoveredColor = HeaderHoveredColor;
@ -273,12 +345,24 @@ void Multiply::Inspect()
}
std::string Multiply::GetCode() const
{
// TODO: Support more than 2 inputs
return std::format("const {} {} = {} * {};",
Pin::TypeKeywords[IO.Outputs[0].Type]
, Graph.GetValue(IO.Outputs[0].Ptr)
, Graph.GetValue(IO.Inputs[0].Ptr)
, Graph.GetValue(IO.Inputs[1].Ptr)
);
}
// Divide --------------------------------------------------------------------------------------------------------------
Divide::Divide(ShaderGraph& graph, ImVec2 pos)
: MathOp(graph, pos)
{
Info.Alias = "Divide";
Header.Title = HeaderMarker + "Divide";
Header.Color = HeaderColor;
Header.HoveredColor = HeaderHoveredColor;
@ -303,6 +387,17 @@ void Divide::Inspect()
}
std::string Divide::GetCode() const
{
// TODO: Support more than 2 inputs
return std::format("const {} {} = {} / {};",
Pin::TypeKeywords[IO.Outputs[0].Type]
, Graph.GetValue(IO.Outputs[0].Ptr)
, Graph.GetValue(IO.Inputs[0].Ptr)
, Graph.GetValue(IO.Inputs[1].Ptr)
);
}
// =====================================================================================================================
@ -315,6 +410,7 @@ void Divide::Inspect()
MakeVector::MakeVector(ShaderGraph& graph, ImVec2 pos)
: Node(graph, pos)
{
Info.Alias = "MakeVector";
Header.Title = HeaderMarker + "Make Vector";
Header.Color = HeaderColor;
Header.HoveredColor = HeaderHoveredColor;
@ -337,13 +433,25 @@ void MakeVector::Inspect()
}
std::string MakeVector::GetCode() const
{
// TODO: Support more than 2 inputs
return std::format("const vec3 {} = vec3({}, {}, {});",
Graph.GetValue(IO.Outputs[0].Ptr)
, Graph.GetValue(IO.Inputs[0].Ptr)
, Graph.GetValue(IO.Inputs[1].Ptr)
, Graph.GetValue(IO.Inputs[2].Ptr)
);
}
// Break Vector ---------------------------------------------------------------------------------------------------------
BreakVector::BreakVector(ShaderGraph& graph, ImVec2 pos)
: Node(graph, pos)
{
Header.Title = HeaderMarker + "Make Vector";
Info.Alias = "BreakVector";
Header.Title = HeaderMarker + "Break Vector";
Header.Color = HeaderColor;
Header.HoveredColor = HeaderHoveredColor;
Header.ActiveColor = HeaderActiveColor;
@ -364,3 +472,21 @@ void BreakVector::Inspect()
{
}
std::string BreakVector::GetCode() const
{
// TODO: Support more than 2 inputs
return std::format(
"const float {} = {}.x;\n"
"const float {} = {}.y;\n"
"const float {} = {}.z;"
, Graph.GetValue(IO.Outputs[0].Ptr)
, Graph.GetValue(IO.Inputs[0].Ptr)
, Graph.GetValue(IO.Outputs[1].Ptr)
, Graph.GetValue(IO.Inputs[0].Ptr)
, Graph.GetValue(IO.Outputs[2].Ptr)
, Graph.GetValue(IO.Inputs[0].Ptr)
);
}

View File

@ -0,0 +1,150 @@
// =====================================================================================================================
// 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 <queue>
#include <Graph/Nodes/Shaders.h>
#include "Editor/EditorSystem.h"
using namespace OpenShaderDesigner;
using namespace OpenShaderDesigner::Nodes::Shaders;
RegisterAsset("Shaders/Function", Function, ".sf");
// =====================================================================================================================
// Shaders
// =====================================================================================================================
// Function ------------------------------------------------------------------------------------------------------------
Function::Function(const FileManager::Path& path, ShaderGraph& graph)
: Node(graph, { 0, 0 })
, ShaderAsset(path, graph)
{
Info.Const = true;
Header.Title = HeaderMarker + "Function";
Header.Color = HeaderColor;
Header.HoveredColor = HeaderHoveredColor;
Header.ActiveColor = HeaderActiveColor;
IO.Inputs.emplace_back("Out", PinType_Vector, PinFlags_NoCollapse | PinFlags_NoPadding | PinFlags_Ambiguous);
GetState().AddNode(this);
MakeDirty();
}
Node* Function::Copy(ShaderGraph &graph) const
{
return nullptr; // Non Copyable
}
void Function::Inspect()
{
}
void Function::Compile()
{
// Get Static Objects
ShaderGraph& Graph = *EditorSystem::Get<ShaderGraph>();
GraphState& State = GetState();
// Generate node priorities
ocu::map<NodeId, int> Priority;
ocu::set<int> Skip;
int p = 0;
std::deque VisitQueue { IO.Inputs[0].Ptr };
while(not VisitQueue.empty())
{
ImPinPtr pin = VisitQueue.front(); VisitQueue.pop_front();
NodeId node = ImNodeGraph::GetUserID(pin.Node).Int;
if(Priority.contains(node))
Skip.insert(Priority[node]);
Priority[node] = p++;
for(Pin& pin : State.Nodes[node]->IO.Inputs)
{
const ImVector<ImGuiID>& connections = ImNodeGraph::GetConnections(pin.Ptr);
if(connections.empty()) continue;
ImPinConnection connection = ImNodeGraph::GetConnection(connections[0]);
if(connection.A == pin.Ptr)
VisitQueue.push_back(connection.B);
else
VisitQueue.push_back(connection.A);
}
}
ocu::dynarray<NodeId> Order(p, 0);
for(auto it = Priority.begin(); it != Priority.end(); ++it)
{
Order[it->value] = it->key;
}
// Write out the code
std::stringstream Out;
Out << std::format("{} {}()",
Pin::TypeKeywords[IO.Inputs[0].Type] // Return Type
, GetFile().path().stem().string()
) << std::endl;
Out << "{" << std::endl;
for(int i = 0; i < p; ++i)
{
if(Skip.contains(i)) continue;
Out << State.Nodes[Order[p - i - 1]]->GetCode() << std::endl;
}
Out << "}" << std::endl;
Code = Out.str();
}
void Function::Open()
{
EditorSystem::Get<ShaderGraph>()->OpenShader(this);
}
FileManager::Asset* Function::Create(const FileManager::Path &path)
{
return new Function(path, *EditorSystem::Get<ShaderGraph>());
}
FileManager::Asset* Function::Load(const FileManager::Path &path)
{
return nullptr;
}
FileManager::Asset* Function::Import(const FileManager::Path &src, const FileManager::Path &dst)
{
return nullptr;
}
std::string Function::GetCode() const
{
return std::format("return {};", Graph.GetValue(IO.Inputs[0].Ptr));
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,17 @@
// =====================================================================================================================
// 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
//
// Created by Maddie on 9/14/2024.
// 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 <Core/Engine.h>
#include <Editor/EditorSystem.h>
@ -16,23 +27,28 @@
#include <rapidjson/ostreamwrapper.h>
#include <rapidjson/prettywriter.h>
OpenShaderDesigner::Project::Project()
: ProjectFile_(NULL)
using namespace OpenShaderDesigner;
RegisterAsset("##/Project", Project, ".sgp");
Project::Project()
: Asset("")
, ProjectFile_(NULL)
{
}
Project::~Project()
{
}
OpenShaderDesigner::Project::~Project()
{
}
void OpenShaderDesigner::Project::DrawMenuBar()
void Project::DrawMenuBar()
{
FileManager* filesystem = EditorSystem::Get<FileManager>();
if(ImGui::BeginMenu("File"))
{
Console::Log(Console::Message, "BeginMenu File");
if(ImGui::MenuItem("\uecc9 New..."))
{
Console::Log(Console::Message, "Creating Project");
@ -112,32 +128,30 @@ void OpenShaderDesigner::Project::DrawMenuBar()
Console::Log(Console::Message, "Closing Old Project");
filesystem->CloseDirectory(filesystem->Parent(ProjectFile_));
Console::Log(Console::Message, "Closing New Project");
Console::Log(Console::Message, "Opening 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");
Console::Log(Console::Message, "Retrieving Project File {}", res.string());
ProjectFile_ = filesystem->Get(res);
Console::Log(Console::Message, "Loaded Project");
}
}
}
ImGui::EndMenu();
Console::Log(Console::Message, "EndMenu File");
}
}
void OpenShaderDesigner::Project::Open()
void 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)
void Project::Save(const FileManager::Path& path)
{
// Setup
rapidjson::Document document;
@ -156,14 +170,30 @@ void OpenShaderDesigner::Project::Save(const FileManager::Path& path)
Console::Log(Console::Alert, "Saved Project {} to {}", path.filename().string(), path.parent_path().string());
}
void OpenShaderDesigner::Project::Create(const FileManager::Path &path)
FileManager::Asset* Project::Load(const FileManager::Path& path)
{
Console::Log(Console::Message, "Setting Up New Project");
Reset();
Save(path);
Project* project = EditorSystem::GetMainMenuBar<Project>();
Console::Log(Console::Message, "Loading Project {}", path.string());
return project;
}
void OpenShaderDesigner::Project::Reset()
FileManager::Asset* Project::Import(const FileManager::Path &src,
const FileManager::Path &dst)
{
return nullptr;
}
FileManager::Asset* Project::Create(const FileManager::Path &path)
{
Project* project = EditorSystem::GetMainMenuBar<Project>();
Console::Log(Console::Message, "Loading Project {}", path.string());
project->Reset();
return project;
}
void Project::Reset()
{
}

View File

@ -0,0 +1,102 @@
// =====================================================================================================================
// 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 <Renderer/Assets/Texture.h>
#include <FileSystem/FileManager.h>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#include "Core/Console.h"
#include "Editor/EditorSystem.h"
#include "Renderer/Renderer.h"
using namespace OpenShaderDesigner;
RegisterAsset("##/Texture", Texture, ".png", ".jpg", ".bmp");
Texture::Texture(const FileManager::Path &path)
: Asset(path)
, Handle_(nullptr)
{
int width, height, channels;
uint8_t* pixels = stbi_load(path.string().c_str(), &width, &height, &channels, 0);
Handle_ = new HandleType({ width, height });
glw::enum_t layout;
switch (channels)
{
case 1: layout = glw::r; break;
case 2: layout = glw::rg; break;
case 3: layout = glw::rgb; break;
case 4: layout = glw::rgba; break;
default: layout = glw::r; break;
}
Handle_->upload(pixels, { width, height }, { 0, 0 }, 0, layout, glw::uint8);
Handle_->generate_mipmaps();
stbi_image_free(pixels);
}
Texture::Texture(const FileManager::Path &src, const FileManager::Path &dst)
: Asset(dst)
, Handle_(nullptr)
{
int width, height, channels;
uint8_t* pixels = stbi_load(src.string().c_str(), &width, &height, &channels, 0);
Handle_ = new HandleType({ width, height });
glw::enum_t layout;
switch (channels)
{
case 1: layout = glw::r8_i; break;
case 2: layout = glw::rg8_i; break;
case 3: layout = glw::rgb8_i; break;
case 4: layout = glw::rgba8_i; break;
default: layout = glw::r8_i; break;
}
Handle_->upload(pixels, { width, height }, { 0, 0 }, 0, layout, glw::uint8);
Handle_->generate_mipmaps();
stbi_image_free(pixels);
}
Texture::~Texture()
{
delete Handle_;
}
void Texture::Open()
{
EditorSystem::Get<Renderer>()->OpenTexture(this);
}
FileManager::Asset* Texture::Create(const FileManager::Path &path)
{
return nullptr;
}
FileManager::Asset* Texture::Load(const FileManager::Path &path)
{
Console::Log(Console::Alert, "Loading {}", path.string());
return new Texture(path);
}
FileManager::Asset * Texture::Import(const FileManager::Path &src, const FileManager::Path &dst)
{
return new Texture(src, dst);
}

View File

@ -0,0 +1,96 @@
// =====================================================================================================================
// 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 <Renderer/Renderer.h>
#include "Core/Console.h"
using namespace OpenShaderDesigner;
Renderer::Renderer()
: EditorWindow("View", 0)
, Mode_(view_texture)
, ViewTexture_(nullptr)
, Shader_(new glw::shader())
{
if(not Shader_->attach_source(glw::compute, {
"#version 430 core\n"
"\n"
"layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;\n"
"\n"
"layout (rgba32f, binding = 0) uniform restrict image2D out_Colour0;\n"
"\n"
"void main(void)\n"
"{\n"
" imageStore(out_Colour0, ivec2(gl_GlobalInvocationID.xy), vec4(1, 0, 0, 1));\n"
"}\n"
}))
{
Console::Log(Console::Error, "Failed to compile shader: \n{}", Shader_->get_error_string());
}
if(not Shader_->link())
{
Console::Log(Console::Error, "Failed to link shader: \n{}", Shader_->get_error_string());
}
}
Renderer::~Renderer()
{
delete ViewTexture_;
delete Shader_;
}
void Renderer::DrawMenu()
{
}
void Renderer::DrawWindow()
{
switch(Mode_)
{
default: return;
case view_texture:
DrawTexture();
return;
}
}
void Renderer::OpenTexture(Texture* texture)
{
ViewTexture_ = texture;
Mode_ = view_texture;
}
void Renderer::DrawTexture()
{
if(ViewTexture_ == nullptr) return;
ImVec2 reg = ImGui::GetContentRegionAvail();
glm::vec2 size = (*ViewTexture_)->size();
float min_r = glm::min(reg.x / size.x, reg.y / size.y);
ImGui::Image(
reinterpret_cast<ImTextureID>(static_cast<intptr_t>((*ViewTexture_)->handle())),
{ size.x * min_r, size.y * min_r }
);
}
void Renderer::DrawFunction()
{
}

View File

@ -8,28 +8,28 @@ Size=400,400
Collapsed=0
[Window][Dear ImGui Demo]
Pos=3070,104
Size=370,884
Pos=3172,977
Size=268,54
Collapsed=0
DockId=0x00000008,0
[Window][ Console]
Pos=468,990
Size=2972,427
Pos=1012,1011
Size=2428,406
Collapsed=0
DockId=0x0000000B,1
[Window][ Profiler]
Pos=0,1011
Size=1010,406
Collapsed=0
DockId=0x00000004,0
[Window][ Profiler]
Pos=0,990
Size=466,427
Collapsed=0
DockId=0x00000003,0
[Window][ Shader Graph]
Pos=0,24
Size=3068,964
Pos=344,24
Size=2826,985
Collapsed=0
DockId=0x00000005,0
DockId=0x00000009,0
[Window][WindowOverViewport_11111111]
Pos=0,24
@ -65,29 +65,37 @@ Size=487,534
Collapsed=0
[Window][Inspector]
Pos=3070,24
Size=370,78
Pos=3172,24
Size=268,951
Collapsed=0
DockId=0x00000007,0
[Window][File Manager]
Pos=468,990
Size=2972,427
Pos=1012,1011
Size=2428,406
Collapsed=0
DockId=0x00000004,1
DockId=0x0000000B,0
[Window][File Manager/##hierarchy_CA8B7713]
IsChild=1
Size=289,363
Size=289,295
[Window][View]
Pos=0,24
Size=342,985
Collapsed=0
DockId=0x00000002,0
[Docking][Data]
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,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
DockNode ID=0x00000001 Parent=0x7C6B3D9B SizeRef=3440,985 Split=X
DockNode ID=0x00000005 Parent=0x00000001 SizeRef=715,1417 Split=X Selected=0xD4C89E35
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=342,395 Selected=0x530C566C
DockNode ID=0x00000009 Parent=0x00000005 SizeRef=666,395 CentralNode=1 Selected=0xD4C89E35
DockNode ID=0x00000006 Parent=0x00000001 SizeRef=268,1417 Split=Y Selected=0xE7039252
DockNode ID=0x00000007 Parent=0x00000006 SizeRef=370,951 Selected=0xE7039252
DockNode ID=0x00000008 Parent=0x00000006 SizeRef=370,32 Selected=0xE87781F4
DockNode ID=0x00000003 Parent=0x7C6B3D9B SizeRef=3440,406 Split=X
DockNode ID=0x00000004 Parent=0x00000003 SizeRef=292,427 Selected=0xAC4B19AE
DockNode ID=0x0000000B Parent=0x00000003 SizeRef=702,427 Selected=0xE9F1AFD1

View File

@ -35,8 +35,14 @@
}, {
"name" : "rapidjson",
"version>=" : "2023-07-17#1"
}, {
"name" : "assimp",
"version>=" : "5.4.3"
}, {
"name" : "stb",
"version>=" : "2024-07-29#1"
}, {
"name" : "sdl2",
"version>=" : "2.30.6"
"version>=" : "2.30.8"
} ]
}