]> git.tdb.fi Git - libs/gl.git/blob - source/programbuilder.h
Generalize shader interface handling
[libs/gl.git] / source / programbuilder.h
1 #ifndef MSP_GL_PROGRAMBUILDER_H_
2 #define MSP_GL_PROGRAMBUILDER_H_
3
4 #include <map>
5 #include <string>
6 #include <vector>
7 #include <msp/datafile/objectloader.h>
8
9 namespace Msp {
10 namespace GL {
11
12 class Program;
13
14 class invalid_variable_definition: public std::invalid_argument
15 {
16 public:
17         invalid_variable_definition(const std::string &w): std::invalid_argument(w) { }
18         virtual ~invalid_variable_definition() throw() { }
19 };
20
21 class ProgramBuilder
22 {
23 public:
24         struct StandardFeatures
25         {
26                 class Loader: public DataFile::ObjectLoader<StandardFeatures>
27                 {
28                 public:
29                         Loader(StandardFeatures &);
30                 };
31
32                 bool texture;
33                 bool material;
34                 bool lighting;
35                 bool specular;
36                 bool normalmap;
37                 bool shadow;
38                 bool reflection;
39                 bool legacy;
40                 std::string custom;
41
42                 StandardFeatures();
43
44                 std::string create_flags() const;
45         };
46
47 private:
48         enum VariableScope
49         {
50                 NO_SCOPE,
51                 UNIFORM,
52                 ATTRIBUTE,
53                 VERTEX,
54                 FRAGMENT
55         };
56
57         enum InterfaceFlags
58         {
59                 NO_INTERFACE = 0,
60                 INPUT = 1,
61                 OUTPUT = 2,
62                 PASSTHROUGH = INPUT|OUTPUT,
63                 GOAL = 4
64         };
65
66         struct VariableDefinition
67         {
68                 VariableScope scope;
69                 const char *name;
70                 const char *type;
71                 const char *expression;
72                 const char *flags;
73         };
74
75         struct ShaderVariable
76         {
77                 std::string name;
78                 const VariableDefinition *variable;
79                 std::string resolved_name;
80                 bool fuzzy_space;
81                 std::string resolved_space;
82                 std::list<ShaderVariable *> referenced_vars;
83                 std::list<ShaderVariable *> referenced_by;
84                 bool inlined;
85                 bool inline_parens;
86
87                 ShaderVariable(const std::string &);
88
89                 void resolve(const VariableDefinition &);
90                 void resolve(ShaderVariable &);
91                 void resolve_space(const std::string &);
92                 void add_reference(ShaderVariable &);
93                 void update_reference(ShaderVariable &, ShaderVariable &);
94                 void check_inline(bool, bool);
95                 bool is_referenced_from(VariableScope) const;
96                 InterfaceFlags get_interface_flags(VariableScope) const;
97                 std::string create_declaration(char = 0) const;
98                 std::string create_replacement(VariableScope) const;
99                 std::string create_expression() const;
100         };
101
102         enum MatchLevel
103         {
104                 NO_MATCH,
105                 EXACT,
106                 FUZZY
107         };
108
109         StandardFeatures features;
110         std::list<VariableDefinition> custom_variables;
111         std::string feature_flags;
112         bool optimize;
113
114         static const VariableDefinition standard_variables[];
115         static const char interfaces[];
116
117 public:
118         ProgramBuilder(const StandardFeatures &);
119
120         void set_optimize(bool);
121         Program *create_program() const;
122         void add_shaders(Program &) const;
123 private:
124         std::string create_source(const std::list<ShaderVariable *> &, VariableScope) const;
125         bool evaluate_flags(const char *) const;
126         static MatchLevel name_match(const char *, const char *, const char ** = 0);
127         static bool parse_identifier(const char *, unsigned &, unsigned &);
128         static std::vector<std::string> extract_identifiers(const char *);
129         static std::string replace_identifiers(const char *, const std::map<std::string, std::string> &);
130 };
131
132 } // namespace GL
133 } // namespace Msp
134
135 #endif