isf.hpp
1 #pragma once
2 #include <ossia/detail/variant.hpp>
3 
4 #include <array>
5 #include <optional>
6 #include <stdexcept>
7 #include <string>
8 #include <vector>
9 
10 namespace isf
11 {
12 class invalid_file : public std::runtime_error
13 {
14 public:
15  using std::runtime_error::runtime_error;
16 };
17 
18 struct event_input
19 {
20 };
21 
22 struct bool_input
23 {
24  using value_type = bool;
25  using has_default = std::true_type;
26  bool def{};
27 };
28 
29 struct long_input
30 {
31  using value_type = int64_t;
32  using has_minmax = std::true_type;
33  std::vector<int64_t> values;
34  std::vector<std::string> labels;
35  std::size_t def{}; // index of default value
36 };
37 struct float_input
38 {
39  using value_type = double;
40  using has_minmax = std::true_type;
41  double min{};
42  double max{};
43  double def{};
44 };
45 
46 struct point2d_input
47 {
48  using value_type = std::array<double, 2>;
49  using has_minmax = std::true_type;
50  std::optional<value_type> def{};
51  std::optional<value_type> min{};
52  std::optional<value_type> max{};
53 };
54 
55 struct point3d_input
56 {
57  using value_type = std::array<double, 3>;
58  using has_minmax = std::true_type;
59  std::optional<value_type> def{};
60  std::optional<value_type> min{};
61  std::optional<value_type> max{};
62 };
63 
64 struct color_input
65 {
66  using value_type = std::array<double, 4>;
67  using has_minmax = std::true_type;
68  std::optional<value_type> def{};
69  std::optional<value_type> min{};
70  std::optional<value_type> max{};
71 };
72 
73 struct image_input
74 {
75 };
76 
77 struct audio_input
78 {
79  int max{};
80 };
81 
82 struct audioFFT_input
83 {
84  int max{};
85 };
86 
87 struct input
88 {
89  using input_impl = ossia::variant<
90  float_input, long_input, event_input, bool_input, color_input, point2d_input,
91  point3d_input, image_input, audio_input, audioFFT_input>;
92 
93  std::string name;
94  std::string label;
95 
96  input_impl data;
97 };
98 
99 struct pass
100 {
101  std::string target;
102  bool persistent{};
103  bool float_storage{};
104  std::string width_expression{};
105  std::string height_expression{};
106 };
107 
108 struct descriptor
109 {
110  std::string description;
111  std::string credits;
112  std::vector<std::string> categories;
113  std::vector<input> inputs;
114  std::vector<pass> passes;
115  std::vector<std::string> pass_targets;
116  bool default_vertex_shader{};
117 };
118 
119 class parser
120 {
121  std::string m_sourceVertex;
122  std::string m_sourceFragment;
123  std::string m_source_geometry_filter;
124  int m_version{450};
125 
126  std::string m_vertex;
127  std::string m_fragment;
128  std::string m_geometry_filter;
129 
130  descriptor m_desc;
131 
132 public:
133  enum class ShaderType
134  {
135  Autodetect,
136  ISF,
137  ShaderToy,
138  GLSLSandBox,
139  GeometryFilter
140  };
141  parser(
142  std::string vert, std::string frag, int glslVersion = 450,
143  ShaderType = ShaderType::Autodetect);
144  explicit parser(std::string isf_geom_filter);
145 
146  descriptor data() const;
147  std::string vertex() const;
148  std::string fragment() const;
149  std::string geometry_filter() const;
150 
151 private:
152  void parse_isf();
153  void parse_shadertoy();
154  void parse_glsl_sandbox();
155  void parse_geometry_filter();
156 
157  std::string parse_isf_header(std::string_view source);
158 };
159 }