cgv
Loading...
Searching...
No Matches
shader_code.h
1#pragma once
2
3#include <cgv/render/context.h>
4#include <set>
5
6#include "lib_begin.h"
7
8namespace cgv {
9 namespace render {
10
25struct CGV_API shader_config : public cgv::base::base
26{
28 std::string shader_path;
34 std::vector<std::string> shader_file_names;
36 std::vector<std::string> inserted_shader_file_names;
40 std::string get_type_name() const;
42 bool self_reflect(cgv::reflect::reflection_handler& srh);
43};
44
47
50
74public:
75 using string_map = std::map<std::string, std::string>;
76
78 bool empty() const {
79 return defines.empty() && snippets.empty();
80 }
81
83 void clear() {
84 defines.clear();
85 snippets.clear();
86 }
87
89 const string_map& get_macros() const {
90 return defines;
91 }
92
94 const string_map& get_snippets() const {
95 return snippets;
96 }
97
99 void define_macro(const std::string& identifier) {
100 defines[identifier] = "";
101 }
102
114 template<typename T, typename std::enable_if<std::is_arithmetic_v<T>, bool>::type = true>
115 void define_macro(const std::string& identifier, const T& value) {
116 defines[identifier] = std::to_string(value);
117 }
118
119 template<typename T, typename std::enable_if<std::is_enum_v<T>, bool>::type = true>
120 void define_macro(const std::string& identifier, const T& value) {
121 defines[identifier] = std::to_string(static_cast<std::underlying_type_t<T>>(value));
122 }
123
124 void define_macro(const std::string& identifier, bool value) {
125 defines[identifier] = value ? "1" : "0";
126 }
127
128 void define_macro(const std::string& identifier, const std::string& value) {
129 defines[identifier] = value;
130 }
131
147 template<typename T, typename std::enable_if<std::is_arithmetic_v<T>, bool>::type = true>
148 void define_macro_if_not_default(const std::string& identifier, const T& value, const T& default_value) {
149 if(value != default_value)
150 defines[identifier] = std::to_string(value);
151 else
152 defines.erase(identifier);
153 }
154
155 template<typename T, typename std::enable_if<std::is_enum_v<T>, bool>::type = true>
156 void define_macro_if_not_default(const std::string& identifier, const T& value, const T& default_value) {
157 if(value != default_value)
158 defines[identifier] = std::to_string(static_cast<std::underlying_type_t<T>>(value));
159 else
160 defines.erase(identifier);
161 }
162
163 void define_macro_if_not_default(const std::string& identifier, bool value, bool default_value) {
164 if(value != default_value)
165 defines[identifier] = value ? "1" : "0";
166 else
167 defines.erase(identifier);
168 }
169
170 void define_macro_if_not_default(const std::string& identifier, const std::string& value, const std::string& default_value) {
171 if(value != default_value)
172 defines[identifier] = value;
173 else
174 defines.erase(identifier);
175 }
176
184 void define_macro_if_true(bool predicate, const std::string& identifier) {
185 if(predicate)
186 define_macro(identifier, "1");
187 else
188 undefine_macro(identifier);
189 }
190
193 void undefine_macro(const std::string& identifier) {
194 defines.erase(identifier);
195 }
196
200 void define_snippet(const std::string& identifier, const std::string& replacement_text) {
201 snippets[identifier] = replacement_text;
202 }
203
206 void undefine_snippet(const std::string& identifier) {
207 snippets.erase(identifier);
208 }
209
216 void extend(const shader_compile_options& other, bool overwrite) {
217 if(overwrite) {
218 for(const auto& define : other.defines)
219 defines[define.first] = define.second;
220
221 for(const auto& snippet : other.snippets)
222 snippets[snippet.first] = snippet.second;
223 } else {
224 defines.insert(other.defines.begin(), other.defines.end());
225 snippets.insert(other.snippets.begin(), other.snippets.end());
226 }
227 }
228
230 bool operator==(const shader_compile_options& other) const {
231 return defines == other.defines && snippets == other.snippets;
232 }
233
235 bool operator!=(const shader_compile_options& other) const {
236 return !(*this == other);
237 }
238
239private:
241 string_map defines;
243 string_map snippets;
244};
245
249class CGV_API shader_code : public render_component
250{
251public:
253 shader_code();
255 ~shader_code();
257 static void decode_if_base64(std::string& content);
272 static std::string find_file(const std::string& file_name, bool search_exhaustive = false);
274 static std::string get_last_error(const std::string& file_name, const std::string& last_error);
276 static std::string read_code_file(const std::string &file_name, std::string* _last_error = 0);
278 static std::string retrieve_code(const std::string& file_name, bool use_cache, std::string* _last_error);
286 static ShaderType detect_shader_type(const std::string& file_name);
288 void destruct(const context& ctx);
292 bool read_code(const context& ctx, const std::string &file_name, ShaderType st = ST_DETECT, const shader_compile_options& options = {});
294 bool set_code(const context& ctx, const std::string &source, ShaderType st);
296 ShaderType get_shader_type() const;
298 bool compile(const context& ctx);
302 bool read_and_compile(const context& ctx, const std::string& file_name, ShaderType st = ST_DETECT, const shader_compile_options& options = {}, bool show_error = true);
304 bool is_compiled() const;
305
306protected:
308 static std::map<std::string, std::string> shader_file_name_map;
312 static std::map<std::string, std::string> code_cache;
313
316
317private:
319 static std::string resolve_includes(const std::string& source, bool use_cache, std::set<std::string>& included_file_names, std::string* _last_error = 0);
321 static std::string resolve_includes(const std::string& source, bool use_cache, std::string* _last_error = 0);
323 static void resolve_version_and_extensions(std::string& source);
325 static void set_defines_and_snippets(std::string& source, const shader_compile_options& options);
327 static void set_vertex_attrib_locations(std::string& source);
328};
329
330
331 }
332}
333
334#include <cgv/config/lib_end.h>
base class for all classes that can be registered with support for dynamic properties (see also secti...
Definition base.h:75
reference counted pointer, which can work together with types that are derived from ref_counted,...
Definition ref_ptr.h:160
the self reflection handler is passed to the virtual self_reflect() method of cgv::base::base.
base class for all drawables, which is independent of the used rendering API.
Definition context.h:627
base interface for all render components
Definition context.h:310
a shader code object holds a code fragment of a geometry vertex or fragment shader and can be added t...
static bool shader_file_name_map_initialized
whether the shader file name map is initialized
static std::map< std::string, std::string > code_cache
map that caches shader file contents indexed by their file name
ShaderType st
store the shader type
static std::map< std::string, std::string > shader_file_name_map
map that caches full shader file paths indexed by the shader file name
Stores preprocessor options used for conditionally compiling shader programs.
Definition shader_code.h:73
bool operator==(const shader_compile_options &other) const
Compare two shader_compile_options for equality.
void define_macro_if_true(bool predicate, const std::string &identifier)
Conditionally define identifier as a macro with replacement text 1.
void define_macro(const std::string &identifier)
Define a macro as identifier and no replacement text.
Definition shader_code.h:99
void clear()
Clear everything, i.e. remove all defines and snippets.
Definition shader_code.h:83
void undefine_macro(const std::string &identifier)
Remove (undefine) the macro with the given identifier.
void undefine_snippet(const std::string &identifier)
Remove (undefine) the snippet with the given identifier.
const string_map & get_macros() const
Return const reference to defined macros.
Definition shader_code.h:89
void define_snippet(const std::string &identifier, const std::string &replacement_text)
Define a text replacement snippet.
void define_macro(const std::string &identifier, const T &value)
Define identifier as a macro with value as replacement text.
void define_macro_if_not_default(const std::string &identifier, const T &value, const T &default_value)
Conditionally define identifier as a macro with value as replacement text.
bool empty() const
Return true if no options are set.
Definition shader_code.h:78
void extend(const shader_compile_options &other, bool overwrite)
Extend options by content of other shader_compile_options via merging.
const string_map & get_snippets() const
Return const reference to defined snippets.
Definition shader_code.h:94
bool operator!=(const shader_compile_options &other) const
Compare two shader_compile_options for inequality.
shader_config_ptr get_shader_config()
return a reference to the current shader configuration
cgv::data::ref_ptr< shader_config > shader_config_ptr
type of ref counted pointer to shader configuration
Definition shader_code.h:46
ShaderType
different shader types
Definition context.h:496
the cgv namespace
Definition print.h:11
a globally unique shader config is registered by default when the cgv library is used.
Definition shader_code.h:26
std::vector< std::string > shader_file_names
mapping of shader index to file name
Definition shader_code.h:34
bool show_file_paths
whether to output full paths of read shaders
Definition shader_code.h:32
bool trace_file_names
whether to keep track of file names
Definition shader_code.h:30
std::string shader_path
the path used to find shaders with the cgv::utils::file::find_in_paths function
Definition shader_code.h:28
std::vector< std::string > inserted_shader_file_names
mapping of shader index to inserted files name
Definition shader_code.h:36