OpenShaderDesigner 0.0.1
Loading...
Searching...
No Matches
ShaderGraph.h
1// =====================================================================================================================
2// OpenShaderDesigner, an open source software utility to create materials and shaders.
3// Copyright (C) 2024 Medusa Slockbower
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <https://www.gnu.org/licenses/>.
17// =====================================================================================================================
18
19#ifndef OSD_SHADERGRAPH_H
20#define OSD_SHADERGRAPH_H
21
22#include <Editor/EditorWindow.h>
23
24#include <vector>
25#include <filesystem>
26#include <unordered_set>
27#include <stack>
28
29#include <glm/glm.hpp>
30#include <glw/common.h>
31
32#include <open-cpp-utils/startup.h>
33#include <open-cpp-utils/directed_tree.h>
34#include <open-cpp-utils/any.h>
35#include <open-cpp-utils/object_pool.h>
36
37#include <imnode-graph/imnode_graph.h>
38
39#include "FileSystem/FileManager.h"
40#include <Renderer/Assets/Texture.h>
41
42
43namespace ocu = open_cpp_utils;
44
45#define RegisterNode(Name, Type) \
46 inline Node* Create##Type(ShaderGraph& graph, ImVec2 pos) { return new Type(graph, pos); } \
47 STARTUP(_Register##Type) { ShaderGraph::Register(Name, Create##Type); }
48
49namespace OpenShaderDesigner
50{
51 class ShaderGraph;
52
53 using PinType = int;
54 enum PinType_
55 {
56 PinType_UInt = 0
57 , PinType_Int
58 , PinType_Float
59 , PinType_Vector
60
61 , PinType_Any
62 , PinType_COUNT
63 };
64
65 using FlagT = unsigned int;
66 enum PinFlags_
67 {
68 PinFlags_None = 0
69 , PinFlags_NoCollapse = 1 << 0
70 , PinFlags_AlwaysCollapse = 1 << 1
71 , PinFlags_NoPadding = 1 << 2
72 , PinFlags_Ambiguous = 1 << 3
73 };
74
75 enum InterpolationType_ : glw::enum_t
76 {
77 InterpolationType_Flat = 0
78 , InterpolationType_Screen
79 , InterpolationType_Smooth
80 };
81
82 struct Pin
83 {
84 inline const static ImColor Colors[PinType_COUNT] = {
85 ImColor(0x7A, 0x9F, 0x82) // Unsigned Int
86 , ImColor(0x64, 0x94, 0xAA) // Int
87 , ImColor(0xA6, 0x3D, 0x40) // Float
88 , ImColor(0xE9, 0xB8, 0x72) // Vector
89 , ImColor(0xFF, 0xFF, 0xFF) // Any
90 };
91
92 inline static constexpr const char* TypeNames[PinType_COUNT] = {
93 "Unsigned Int"
94 , "Int"
95 , "Float"
96 , "Vector"
97 , "Any"
98 };
99
100 inline const static std::string TypeKeywords[PinType_COUNT] = {
101 "uint"
102 , "int"
103 , "float"
104 , "vec3"
105 , "vec3"
106 };
107
108 inline const static int TypeWidths[PinType_COUNT] = {
109 1 // Unsigned Int
110 , 1 // Int
111 , 1 // Float
112 , 3 // Vector
113 , -1 // Any
114 };
115
116 using Ambiguous = ocu::any<glm::int32, glm::uint32, glm::float32, glm::vec3>;
117
118 std::string Name;
119 PinType Type;
120 FlagT Flags;
121 Ambiguous Value;
122 ImPinPtr Ptr;
123
124 Pin(const std::string& name, PinType type, FlagT flags = PinFlags_None)
125 : Name(name)
126 , Type(type)
127 , Flags(flags)
128 { }
129
130 std::string GetVarName() const { return std::format("{}_{}", Name, Ptr.Node); }
131 };
132
133 enum NodeFlags_
134 {
135 NodeFlags_None = 0
136 , NodeFlags_Const = 0x0000'0001
137 , NodeFlags_DynamicInputs = 0x0000'0002
138 , NodeFlags_DynamicOutputs = 0x0000'0004
139 };
140
141 struct Node
142 {
143 public:
144 ShaderGraph& Graph;
145 ImVec2 Position = { 0, 0 };
146
147 struct
148 {
149 std::string Title;
150 ImColor Color, HoveredColor, ActiveColor;
151 bool Enabled;
152 } Header;
153
154 struct
155 {
156 std::vector<Pin> Inputs, Outputs;
157 } IO;
158
159 struct
160 {
161 std::string Alias;
162 FlagT Flags;
163 } Info;
164
165 Node(ShaderGraph& graph, ImVec2 pos);
166 virtual ~Node() = default;
167
168 void DrawPin(int id, Pin& pin, ImPinDirection direction);
169 void Draw(ImGuiID id);
170
171 inline virtual bool CheckConnection(Pin*, Pin*) { return true; }
172 virtual void ValidateConnections() { }
173
174 virtual Node* Copy(ShaderGraph& graph) const = 0;
175 virtual void Inspect() = 0;
176 virtual std::string GetCode() const = 0;
177 };
178
179 using NodeList = ocu::object_list<Node*>;
180 using NodeId = NodeList::uuid_type;
181
183 {
184 std::string Name;
185 glw::enum_t Type;
186 glw::enum_t Interpolation;
187 glw::size_t Count;
188 };
189
191 {
192 std::string Name;
193 glw::enum_t Type;
194 glw::size_t Count; // For arrays
195 };
196
198 {
199
200 ShaderGraph& Parent;
201 NodeList Nodes;
202
203 GraphState(ShaderGraph& parent);
204 GraphState(const GraphState& other);
205 ~GraphState();
206
207 NodeId AddNode(Node* node) { return Nodes.insert(node); }
208 void RemoveNode(NodeId node) { if(Nodes[node]->Info.Flags & NodeFlags_Const) return; Nodes.erase(node); }
209
210 GraphState& operator=(const GraphState& other);
211 };
212
214 {
215 public:
216 inline static const std::string VersionString = "#version 430 core";
217
218 ShaderAsset(const FileManager::Path& path, ShaderGraph& graph)
219 : Asset(path)
220 , State_(graph)
221 { }
222
223 void PushState() { History_.push(State_); }
224 void PopState() { State_ = History_.top(); History_.pop();}
225
226 GraphState& GetState() { return State_; }
227 const GraphState& GetState() const { return State_; }
228
229 ShaderGraph& GetGraph() { return State_.Parent; }
230 const ShaderGraph& GetGraph() const { return State_.Parent; }
231
232 virtual void Compile() = 0;
233 virtual void View(HDRTexture::HandleType* Target) = 0;
234
235 protected:
236 std::string Code;
237
238
239 private:
240 GraphState State_;
241 std::stack<GraphState> History_;
242 };
243
245 : public EditorWindow
246 {
247 private:
248 friend Node;
249
250 using ConstructorPtr = Node*(*)(ShaderGraph&, ImVec2);
251 struct ContextMenuItem
252 {
253 std::string Name;
254 ConstructorPtr Constructor;
255 };
256
257 using ContextMenuHierarchy = ocu::directed_tree<ContextMenuItem>;
258 using ContextID = ContextMenuHierarchy::node;
259
260 static ContextMenuHierarchy& ContextMenu() { static ContextMenuHierarchy Menu {{ "", nullptr }}; return Menu; }
261
262
263 public:
264 ShaderGraph();
265 virtual ~ShaderGraph();
266
267 void OnOpen() override;
268 void DrawMenu() override;
269 void DrawWindow() override;
270
271 void DrawContextMenu();
272
273 void Copy();
274 void Erase();
275 void Paste(ImVec2 pos);
276 void Clear();
277
278 Node* FindNode(ImPinPtr ptr);
279 Node* FindNode(ImGuiID id);
280 Pin& FindPin(ImPinPtr ptr);
281
282 std::string GetValue(ImPinPtr ptr);
283
284 void OpenShader(ShaderAsset* asset) { Shader_ = asset; }
285
286 static void Register(const std::filesystem::path& path, ConstructorPtr constructor);
287
288 private:
289 // TODO: Make bitfield
290 bool GrabFocus_;
291 ShaderAsset* Shader_;
292 ImVec2 ContextMenuPosition_;
293 ocu::optional<NodeId> Selected_;
294
295
296
297 friend class Inspector;
298 };
299
301 : public EditorWindow
302 {
303 public:
304 Inspector();
305 virtual ~Inspector() = default;
306
307 void DrawWindow() override;
308
309 private:
310 ShaderGraph* Graph;
311
312 friend class ShaderGraph;
313 };
314}
315
316#endif // OSD_SHADERGRAPH_H
EditorWindow class for wrapping ImGui window functionality.
Definition EditorWindow.h:32
Definition FileManager.h:77
Definition ShaderGraph.h:302
void DrawWindow() override
DrawWindow function for when the EditorWindow is being drawn.
Definition ShaderGraph.cpp:514
Definition ShaderGraph.h:214
Definition ShaderGraph.h:246
void OnOpen() override
OnOpen callback for when the EditorWindow is opened.
Definition ShaderGraph.cpp:222
void DrawMenu() override
DrawMenu function for when the EditorWindow Menu is being drawn.
Definition ShaderGraph.cpp:229
void DrawWindow() override
DrawWindow function for when the EditorWindow is being drawn.
Definition ShaderGraph.cpp:242
Definition ShaderGraph.h:183
Definition ShaderGraph.h:198
Definition ShaderGraph.h:142
Definition ShaderGraph.h:191
Definition ShaderGraph.h:83