cgv
Loading...
Searching...
No Matches
shader_program.cxx
1#include <cgv/base/base.h>
2#include "shader_program.h"
3#include <cgv/utils/file.h>
4#include <cgv/utils/dir.h>
5#include <cgv/utils/scan.h>
7#include <cgv/utils/tokenizer.h>
8#include <cgv/base/import.h>
9
10using namespace cgv::utils;
11
12namespace cgv {
13 namespace render {
14
15std::map<std::string, std::string> shader_program::program_file_cache;
16std::map<std::string, std::vector<std::string>> shader_program::files_cache;
17
18
19void shader_program::inspect_program_variables(const context& ctx, cgv::render::ProgramVariableKind kind, std::vector<cgv::render::program_variable_info>& Vs,
20 bool get_location, bool get_value)
21{
22 ctx.shader_program_inspect_variables(*this, kind, Vs, get_location, get_value);
23}
24
26bool shader_program::attach_files(const context& ctx, const std::vector<std::string>& file_names, const shader_compile_options& options)
27{
28 bool no_error = true;
29 for(unsigned int i = 0; i < file_names.size(); ++i) {
30 no_error = attach_file(ctx, file_names[i], ST_DETECT, options) && no_error;
31 if(!no_error)
32 std::cout << last_error << std::endl;
33 }
34 return no_error;
35}
36
37bool shader_program::collect_files_from_cache(const std::string& name, std::vector<std::string>& file_names, bool& added_files) {
38
39 auto it = files_cache.find(name);
40 if(it != files_cache.end()) {
41 const std::vector<std::string>& cached_file_names = it->second;
42 for(size_t i = 0; i < cached_file_names.size(); ++i)
43 file_names.push_back(cached_file_names[i]);
44
45 added_files = !cached_file_names.empty();
46 return true;
47 }
48
49 added_files = false;
50 return false;
51}
52
53bool shader_program::collect_file(const std::string& file_name, bool use_cache, std::vector<std::string>& file_names)
54{
55 if(use_cache) {
56 bool added_files = false;
57 if(collect_files_from_cache(file_name, file_names, added_files))
58 return added_files;
59 }
60
61 std::vector<std::string> collected_file_names;
62
63 std::string fn = shader_code::find_file(file_name);
64 bool found = false;
65
66 if (!fn.empty()) {
67 file_names.push_back(fn);
68 if(use_cache)
69 collected_file_names.push_back(fn);
70 found = true;
71 }
72
73 if(use_cache)
74 files_cache.emplace(file_name, collected_file_names);
75
76 return found;
77}
78
79bool shader_program::collect_files(const std::string& base_name, bool use_cache, std::vector<std::string>& file_names)
80{
81 if(use_cache) {
82 bool added_files = false;
83 if(collect_files_from_cache(base_name, file_names, added_files))
84 return added_files;
85 }
86
87 std::vector<std::string> collected_file_names;
88
89 const char* exts[] = { "glvs", "glgs", "glfs", "glcs", "gltc", "glte", "pglvs", "pglfs", "pglgs", "pglcs", "pgltc", "pglte", 0 };
90 const char** iter = exts;
91 bool added_file = false;
92 while (*iter) {
93 std::string fn = shader_code::find_file(base_name+"."+*iter);
94 if (!fn.empty()) {
95 file_names.push_back(fn);
96
97 if(use_cache)
98 collected_file_names.push_back(fn);
99
100 added_file = true;
101 }
102 ++iter;
103 }
104 if(!added_file)
105 std::cerr << "could not find shader file " << base_name.c_str() << std::endl;
106
107 if(use_cache)
108 files_cache.emplace(base_name, collected_file_names);
109
110 return added_file;
111}
112
113bool shader_program::collect_dir(const std::string& dir_name, bool recursive, std::vector<std::string>& file_names)
114{
115 std::string dn = dir_name;
116 if (!dir::exists(dn)) {
117 if (get_shader_config()->shader_path.empty()) {
118 return false;
119 }
120 dn = file::find_in_paths(dir_name, get_shader_config()->shader_path, true);
121 if (dn.empty()) {
122 return false;
123 }
124 }
125 void* handle = file::find_first(dn+"/*.gl*");
126 if (!handle)
127 return false;
128 while (handle) {
129 file_names.push_back(dir_name+"/"+file::find_name(handle));
130 handle = file::find_next(handle);
131 }
132 return true;
133}
134
135bool shader_program::collect_program(const std::string& file_name, bool use_cache, std::vector<std::string>& file_names)
136{
137 std::string fn = shader_code::find_file(file_name);
138 if (fn.empty())
139 return false;
140 std::string content;
141 if (!cgv::base::read_data_file(fn, content, true))
142 return false;
143
145
146 std::vector<line> lines;
147 split_to_lines(content, lines);
148 bool added_file = false;
149 std::string old_shader_path = get_shader_config()->shader_path;
150 std::string path = file::get_path(file_name);
151 if (!path.empty())
152 get_shader_config()->shader_path = path+";"+get_shader_config()->shader_path;
153
154 for (auto line : lines) {
155 std::string l = to_string((const token&)line);
156 if (l.substr(0,5) == "file:")
157 added_file = collect_file(l.substr(5), use_cache, file_names) || added_file;
158 else if (l.substr(0,12) == "vertex_file:")
159 added_file = collect_file(l.substr(12), use_cache, file_names) || added_file;
160 else if (l.substr(0, 14) == "geometry_file:")
161 added_file = collect_file(l.substr(14), use_cache, file_names) || added_file;
162 else if (l.substr(0, 26) == "tessellation_control_file:")
163 added_file = collect_file(l.substr(26), use_cache, file_names) || added_file;
164 else if (l.substr(0, 29) == "tessellation_evaluation_file:")
165 added_file = collect_file(l.substr(29), use_cache, file_names) || added_file;
166 else if (l.substr(0,14) == "fragment_file:")
167 added_file = collect_file(l.substr(14), use_cache, file_names) || added_file;
168 else if (l.substr(0,6) == "files:")
169 added_file = collect_files(l.substr(6), use_cache, file_names) || added_file;
170 else if (l.substr(0,4) == "dir:")
171 added_file = collect_dir(l.substr(4), false, file_names) || added_file;
172 else if (l.substr(0,8) == "rec_dir:")
173 added_file = collect_dir(l.substr(8), true, file_names) || added_file;
174 else if (l.substr(0,8) == "program:")
175 added_file = collect_program(l.substr(8), use_cache, file_names) || added_file;
176 }
177
178 get_shader_config()->shader_path = old_shader_path;
179 return added_file;
180}
181
183shader_program::shader_program(bool _show_code_errors)
184{
185 show_code_errors = _show_code_errors;
186 linked = false;
187 state_out_of_date = true;
188 nr_attached_geometry_shaders = 0;
189}
190
193{
194 if (ctx_ptr && ctx_ptr->make_current())
196 else
197 if (handle != 0)
198 std::cerr << "could not destruct shader program properly" << std::endl;
199}
200
203{
204 state_out_of_date = true;
205 nr_attached_geometry_shaders = 0;
206 if (ctx_ptr)
208 else
209 if (handle)
210 destruct(ctx);
211 ctx_ptr = &ctx;
212 return ctx.shader_program_create(*this);
213}
214
217{
218 if (!handle) {
219 last_error = "attach_code to shader program that was not created";
220 return false;
221 }
222 if (!code.handle) {
223 last_error = "attempt to attach_code that is not created to shader program";
224 return false;
225 }
226 if(!code.is_compiled()) {
227 last_error = "attempt to attach_code that is not compiled to shader program";
228 return false;
229 }
230 ctx.shader_program_attach(*this, code);
231 if(code.get_shader_type() == ST_GEOMETRY)
232 ++nr_attached_geometry_shaders;
233 return true;
234}
235
237bool shader_program::detach_code(const context& ctx, const shader_code& code) {
238 if(!handle) {
239 last_error = "detach_code from shader program that was not created";
240 return false;
241 }
242 if(!code.handle) {
243 last_error = "attempt to detach_code that is not created to shader program";
244 return false;
245 }
246 ctx.shader_program_detach(*this, code);
247 if(code.get_shader_type() == ST_GEOMETRY)
248 --nr_attached_geometry_shaders;
249 return true;
250}
251
252
254bool shader_program::attach_code(const context& ctx, const std::string& source, ShaderType st) {
255 shader_code* code_ptr = new shader_code;
256 if(code_ptr->set_code(ctx, source, st) && code_ptr->compile(ctx)) {
257 managed_codes.push_back(code_ptr);
258 return attach_code(ctx, *code_ptr);
259 }
260 last_error = code_ptr->last_error;
261 delete code_ptr;
262 return false;
263}
264
265
267bool shader_program::attach_file(const context& ctx, const std::string& file_name, ShaderType st, const shader_compile_options& options) {
268 shader_code* code_ptr = new shader_code;
269 if(!code_ptr->read_and_compile(ctx, file_name, st, options, show_code_errors)) {
270 last_error = code_ptr->last_error;
271 delete code_ptr;
272 return false;
273 }
274 managed_codes.push_back(code_ptr);
275 return attach_code(ctx, *code_ptr);
276}
277
279bool shader_program::attach_files(const context& ctx, const std::string& base_name, const shader_compile_options& options) {
280 std::vector<std::string> file_names;
281 if(!collect_files(base_name, ctx.is_shader_file_cache_enabled(), file_names))
282 return false;
283 return attach_files(ctx, file_names, options);
284}
286bool shader_program::attach_dir(const context& ctx, const std::string& dir_name, bool recursive, const shader_compile_options& options) {
287 std::vector<std::string> file_names;
288 if(!collect_dir(dir_name, recursive, file_names))
289 return false;
290 return attach_files(ctx, file_names, options);
291}
292bool shader_program::open_program_file(std::string& file_name, bool use_cache, std::string& content, std::vector<line>& lines, std::string* last_error_ptr)
293{
294 std::string fn = "";
295
296 if(use_cache) {
297 auto it = program_file_cache.find(file_name);
298 if(it != program_file_cache.end()) {
299 fn = it->second;
300 }
301 }
302
303 if(fn.empty())
304 fn = shader_code::find_file(file_name);
305
306 if(use_cache)
307 program_file_cache.emplace(file_name, fn);
308
309 if (fn.empty()) {
310 if (last_error_ptr)
311 *last_error_ptr = "could not find shader program file " + file_name;
312 return false;
313 }
314 if (!cgv::base::read_data_file(fn, content, true)) {
315 if (last_error_ptr)
316 *last_error_ptr = "could not read shader program file " + file_name;
317 return false;
318 }
320 split_to_lines(content, lines);
321 file_name = fn;
322 return true;
323}
324std::vector<shader_compile_options> shader_program::extract_instances(std::string file_name)
325{
326 std::string content;
327 std::vector<line> lines;
328 std::vector<shader_compile_options> result;
329 if (!open_program_file(file_name, false, content, lines))
330 return result;
331 for (unsigned int i = 0; i < lines.size(); ++i) {
332 token tok = lines[i];
333 while (tok.begin < tok.end && is_space(*tok.begin))
334 ++tok.begin;
335 std::string l = to_string(tok);
336 if (l.empty() || l[0] == '/')
337 continue;
338 if (l.substr(0, 9) != "instance:")
339 continue;
340 std::string defs=l.substr(9);
341 std::vector<token> toks;
342 split_to_tokens(defs, toks, "", false, "", "", ";");
344 for (const auto& t : toks) {
345 std::vector<token> sides;
346 split_to_tokens(t, sides, "", false, "", "", "=");
347 std::vector<std::string> S;
348 for (auto& s : sides) {
349 while (s.begin < s.end && is_space(*s.begin))
350 ++s.begin;
351 while (s.begin < s.end && is_space(s.end[-1]))
352 --s.end;
353 if (s.begin < s.end)
354 S.push_back(to_string(s));
355 }
356 if(S.size() == 2)
357 options.define_macro(S[0], S[1]);
358 }
359 result.push_back(options);
360 }
361 return result;
362}
363
364bool shader_program::attach_program(const context& ctx, std::string file_name, bool show_error, const shader_compile_options& options)
365{
366 std::string content;
367 std::vector<line> lines;
368 if (!open_program_file(file_name, ctx.is_shader_file_cache_enabled(), content, lines, &last_error)) {
369 std::cerr << last_error << std::endl;
370 return false;
371 }
372 if (get_shader_config()->show_file_paths)
373 std::cout << "read shader program <" << file_name << ">" << std::endl;
374 std::string old_shader_path = get_shader_config()->shader_path;
375 std::string path = file::get_path(file_name);
376 if (!path.empty())
377 get_shader_config()->shader_path = path+";"+get_shader_config()->shader_path;
378
379 bool no_error = true;
380 std::string error = "2 : attach command failed";
381 for (unsigned int i=0; i<lines.size(); ++i) {
382 token tok = lines[i];
383 while (tok.begin < tok.end && is_space(*tok.begin))
384 ++tok.begin;
385 std::string l = to_string(tok);
386
387 bool success = true;
388 // ignore empty lines
389 if (l.empty())
390 continue;
391 // ignore comments
392 if (l[0] == '/')
393 continue;
394 if (l.substr(0,5) == "file:")
395 success = attach_file(ctx, l.substr(5), ST_DETECT, options);
396 else if (l.substr(0,12) == "vertex_file:")
397 success = attach_file(ctx, l.substr(12), ST_VERTEX, options);
398 else if (l.substr(0,14) == "geometry_file:")
399 success = attach_file(ctx, l.substr(14), ST_GEOMETRY, options);
400 else if (l.substr(0, 26) == "tessellation_control_file:")
401 success = attach_file(ctx, l.substr(26), ST_TESS_CONTROL, options);
402 else if (l.substr(0, 29) == "tessellation_evaluation_file:")
403 success = attach_file(ctx, l.substr(29), ST_TESS_EVALUATION, options);
404 else if (l.substr(0,14) == "fragment_file:")
405 success = attach_file(ctx, l.substr(14), ST_FRAGMENT, options);
406 else if(l.substr(0, 13) == "compute_file:")
407 success = attach_file(ctx, l.substr(13), ST_COMPUTE, options);
408 else if (l.substr(0,6) == "files:")
409 success = attach_files(ctx, l.substr(6), options);
410 else if (l.substr(0,4) == "dir:")
411 success = attach_dir(ctx, l.substr(4), false);
412 else if (l.substr(0,8) == "rec_dir:")
413 success = attach_dir(ctx, l.substr(8), true);
414 else if (l.substr(0,8) == "program:")
415 success = attach_program(ctx, l.substr(8));
416 else if (l.substr(0,21) == "geometry_shader_info:") {
417 std::vector<token> toks;
418 std::string l1 = l.substr(21);
419 tokenizer(l1).set_ws(";").bite_all(toks);
420 if (toks.size() == 3) {
421 PrimitiveType i_pt = PT_UNDEF, o_pt = PT_UNDEF;
422 int pi, count = 0;
423 for (pi = PT_UNDEF+1; pi < PT_LAST; ++pi) {
425 std::string s = to_string(pt);
426 if (s == to_string(toks[0]))
427 i_pt = pt;
428 if (s == to_string(toks[1]))
429 o_pt = pt;
430 }
431 if (i_pt == PT_UNDEF) {
432 error = "4 : unknown input_type for geometry shader <";
433 error += to_string(toks[0])+">";
434 success = false;
435 }
436 else if (o_pt == PT_UNDEF) {
437 error = "5 : unknown ouput_type for geometry shader <";
438 error += to_string(toks[1])+">";
439 success = false;
440 }
441 else if (!is_integer(toks[2].begin,toks[2].end,count)) {
442 error = "6 : max_output_count of geometry shader must be an integer but received <";
443 error += to_string(toks[2])+">";
444 success = false;
445 }
446 else {
447 set_geometry_shader_info(i_pt, o_pt, count);
448 }
449 }
450 else {
451 success = false;
452 error = "3 : geometry_shader_info takes three arguments separated by colons";
453 }
454 }
455 else if (l.substr(0, 9) == "instance:") {
456 }
457 else if (show_error) {
458 std::cerr << file_name.c_str() << " (" << i + 1
459 << "): warning G0001 : syntax error in line '"
460 << l.c_str() << "'" << std::endl;
461 }
462 if (!success) {
463 if (show_error) {
464 std::cerr << file_name.c_str() << " (" << i+1
465 << "): error G000" << error.c_str() << std::endl;
466 }
467 no_error = false;
468 }
469 }
470
471 get_shader_config()->shader_path = old_shader_path;
472 if (show_error && !no_error)
473 std::cerr << last_error << std::endl;
474 return no_error;
475}
476
478bool shader_program::build_files(const context& ctx, const std::string& base_name, bool show_error) {
479 return build_files(ctx, base_name, {}, show_error);
480}
481
483bool shader_program::build_dir(const context& ctx, const std::string& dir_name, bool recursive, bool show_error) {
484 return build_dir(ctx, dir_name, {}, recursive, show_error);
485}
486
488bool shader_program::build_program(const context& ctx, const std::string& file_name, bool show_error) {
489 return build_program(ctx, file_name, {}, show_error);
490}
491
493bool shader_program::build_files(const context& ctx, const std::string& base_name, const shader_compile_options& options, bool show_error) {
494 return (is_created() || create(ctx)) &&
495 attach_files(ctx, base_name, options) && link(ctx, show_error);
496}
498bool shader_program::build_dir(const context& ctx, const std::string& dir_name, const shader_compile_options& options, bool recursive, bool show_error) {
499 return (is_created() || create(ctx)) &&
500 attach_dir(ctx, dir_name, recursive, options) && link(ctx, show_error);
501}
502
504bool shader_program::build_program(const context& ctx, const std::string& file_name, const shader_compile_options& options, bool show_error) {
505 if(!(is_created() || create(ctx)))
506 return false;
507
508 if(!attach_program(ctx, file_name, show_error, options))
509 return false;
510
511 if(!link(ctx, show_error)) {
512 if(show_error) {
513 std::string fn = shader_code::find_file(file_name);
514 std::vector<line> lines;
516 std::string formated_error;
517 for(unsigned int i = 0; i < lines.size(); ++i) {
518 formated_error += fn + "(1) : error G0002: " + to_string(lines[i]) + "\n";
519 }
520 std::cerr << formated_error.c_str() << std::endl;
521 }
522 return false;
523 }
524
525 return true;
526}
527
530{
531 return ctx.get_device_capabilities().max_geometry_shader_output_vertex_count;
532}
533
536{
537 if (state_out_of_date) {
538 if (nr_attached_geometry_shaders > 0) {
539 if (geometry_shader_output_count < 1)
540 geometry_shader_output_count = get_max_nr_geometry_shader_output_vertices(ctx);
541 ctx.shader_program_set_state(*this);
542 }
543 state_out_of_date = false;
544 }
545}
546
548bool shader_program::link(const context& ctx, bool show_error)
549{
550 update_state(ctx);
551 if (ctx.shader_program_link(*this)) {
552 ctx.shader_program_set_uniform_locations(*this);
553 linked = true;
554 return true;
555 }
556 else {
557 linked = false;
558 if (show_error)
559 std::cerr << "link error:\n" << last_error.c_str() << std::endl;
560 return false;
561 }
562}
565{
566 return linked;
567}
568
570void shader_program::set_geometry_shader_info(PrimitiveType input_type, PrimitiveType output_type, int max_output_count)
571{
572 geometry_shader_input_type = input_type;
573 geometry_shader_output_type = output_type;
574 geometry_shader_output_count = max_output_count;
575 state_out_of_date = true;
576}
577
580{
581 if (!is_created()) {
582 ctx.error("attempt to enable shader_program that is not created", this);
583 return false;
584 }
585 if (!is_linked()) {
586 ctx.error("attempt to enable shader_program that is not linked", this);
587 return false;
588 }
589 if (is_enabled()) {
590 ctx.error("attempt to enable shader_program that is already enabled or was not disabled properly", this);
591 return false;
592 }
593 update_state(ctx);
594 bool res = ctx.shader_program_enable(*this);
595 if (res)
596 shader_program_base::is_enabled = true;
597 return res;
598}
599
602{
603 if (!is_enabled()) {
604 ctx.error("attempt to disable shader_program that is not enabled", this);
605 return false;
606 }
607 bool res = ctx.shader_program_disable(*this);
608 shader_program_base::is_enabled = false;
609 return res;
610}
611
613const std::map<std::string, int>& shader_program::get_uniform_locations() const
614{
615 return uniform_locations;
616}
617
619int shader_program::get_uniform_location(const context& ctx, const std::string& name) const
620{
621 // debug fallback: get uniform location from context through GL call
622 //return ctx.get_uniform_location(*this, name);
623
624 // get from cache
625 auto it = uniform_locations.find(name);
626 return it != uniform_locations.end() ? it->second : -1;
627}
629bool shader_program::set_material_uniform(const context& ctx, const std::string& name, const cgv::media::illum::surface_material& material, bool generate_error)
630{
631 bool res = set_uniform(ctx, name + ".brdf_type", static_cast<int>(material.brdf_type), generate_error);
632 res = set_uniform(ctx, name + ".diffuse_reflectance", material.diffuse_reflectance, generate_error) && res;
633 res = set_uniform(ctx, name + ".roughness", material.roughness, generate_error) && res;
634 res = set_uniform(ctx, name + ".ambient_occlusion", material.ambient_occlusion, generate_error) && res;
635 res = set_uniform(ctx, name + ".emission", material.emission, generate_error) && res;
636 res = set_uniform(ctx, name + ".specular_reflectance", material.specular_reflectance, generate_error) && res;
637 res = set_uniform(ctx, name + ".roughness_anisotropy", material.roughness_anisotropy, generate_error) && res;
638 res = set_uniform(ctx, name + ".roughness_orientation", material.roughness_orientation, generate_error) && res;
639 res = set_uniform(ctx, name + ".propagation_slow_down", vec2(material.propagation_slow_down.real(), material.propagation_slow_down.imag()), generate_error) && res;
640 res = set_uniform(ctx, name + ".transparency", material.transparency, generate_error) && res;
641 res = set_uniform(ctx, name + ".metalness", material.metalness, generate_error) && res;
642 return res;
643}
644
646bool shader_program::set_textured_material_uniform(const context& ctx, const std::string& name, const textured_material& material, bool generate_error)
647{
648 const char* texture_names[] = {
649 "tex0", "tex1", "tex2", "tex3", "tex4", "tex5"
650 };
651 for (int i = 0; i < (int)material.get_nr_textures(); ++i)
652 if (!set_uniform(ctx, texture_names[i], i, generate_error))
653 return false;
654 bool res = set_material_uniform(ctx, name, material, generate_error);
655 res = set_uniform(ctx, "sRGBA_textures", material.sRGBA_textures, generate_error) && res;
656 res = set_uniform(ctx, "diffuse_index", material.diffuse_index, generate_error) && res;
657 res = set_uniform(ctx, "roughness_index", material.roughness_index, generate_error) && res;
658 res = set_uniform(ctx, "metalness_index", material.metalness_index, generate_error) && res;
659 res = set_uniform(ctx, "ambient_index", material.ambient_index, generate_error) && res;
660 res = set_uniform(ctx, "emission_index", material.emission_index, generate_error) && res;
661 res = set_uniform(ctx, "transparency_index", material.transparency_index, generate_error) && res;
662 res = set_uniform(ctx, "bump_index", material.bump_index, generate_error) && res;
663 res = set_uniform(ctx, "specular_index", material.specular_index, generate_error) && res;
664 return res;
665}
666
667
668
670bool shader_program::set_light_uniform(const context& ctx, const std::string& name, const cgv::media::illum::light_source& L, bool generate_error)
671{
672 if (!set_uniform(ctx, name + ".light_source_type", static_cast<int>(L.get_type()), generate_error))
673 return false;
674 if (!set_uniform(ctx, name + ".position", L.get_position(), generate_error))
675 return false;
676 if (!set_uniform(ctx, name + ".emission", L.get_emission(), generate_error))
677 return false;
678 if (!set_uniform(ctx, name + ".ambient_scale", L.get_ambient_scale(), generate_error))
679 return false;
680 if (!set_uniform(ctx, name + ".spot_direction", L.get_spot_direction(), generate_error))
681 return false;
682 if (!set_uniform(ctx, name + ".spot_exponent", L.get_spot_exponent(), generate_error))
683 return false;
684 if (!set_uniform(ctx, name + ".spot_cos_cutoff", cos(0.01745329252f*L.get_spot_cutoff()), generate_error))
685 return false;
686 if (!set_uniform(ctx, name + ".constant_attenuation", L.get_constant_attenuation(), generate_error))
687 return false;
688 if (!set_uniform(ctx, name + ".linear_attenuation", L.get_linear_attenuation(), generate_error))
689 return false;
690 if (!set_uniform(ctx, name + ".quadratic_attenuation", L.get_quadratic_attenuation(), generate_error))
691 return false;
692 return true;
693}
694
696int shader_program::get_attribute_location(const context& ctx, const std::string& name) const
697{
698 return ctx.get_attribute_location(*this, name);
699}
700
703{
704 while (managed_codes.size() > 0) {
705 delete managed_codes.back();
706 managed_codes.pop_back();
707 }
708 if (handle) {
709 ctx.shader_program_destruct(*this);
710 handle = 0;
711 }
712 linked = false;
713 state_out_of_date = true;
714 auto_detect_uniforms = true;
715 auto_detect_vertex_attributes = true;
716 nr_attached_geometry_shaders = 0;
717}
718
719 }
720}
More advanced text processing for splitting text into lines or tokens.
bool empty() const
check if pointer is not yet set
Definition ref_ptr.h:230
>simple class to hold the properties of a light source
int metalness_index
index of image from which metalness should be mapped, -1 corresponds to no mapping
int transparency_index
index of image from which transparency should be mapped, -1 corresponds to no mapping
bool sRGBA_textures
whether textures are in sRGB format
int roughness_index
index of image from which roughness should be mapped, -1 corresponds to no mapping
int specular_index
index of image from which specular_reflectance should be mapped, -1 corresponds to no mapping
int ambient_index
index of image from which ambient_occlusion should be mapped, -1 corresponds to no mapping
int emission_index
index of image from which emission should be mapped, -1 corresponds to no mapping
int bump_index
index of image from which bumps should be mapped, -1 corresponds to no mapping
int diffuse_index
index of image from which diffuse_reflectance should be mapped, -1 corresponds to no mapping
base class for all drawables, which is independent of the used rendering API.
Definition context.h:672
virtual void error(const std::string &message, const render_component *rc=0) const
error handling
Definition context.cxx:306
bool is_shader_file_cache_enabled() const
whether the shader file caches are enabled
Definition context.cxx:554
virtual bool make_current() const =0
make the current context current if possible
virtual bool is_created() const
return whether component has been created
Definition context.cxx:2188
const context * ctx_ptr
keep pointer to my context
Definition context.h:361
std::string last_error
a string that contains the last error
Definition context.h:363
a shader code object holds a code fragment of a geometry vertex or fragment shader and can be added t...
static std::string find_file(const std::string &file_name, bool search_exhaustive=false)
Find the full path to a shader by its file name.
ShaderType get_shader_type() const
return the shader type of this code
bool is_compiled() const
return whether shader has been compiled successfully
static void decode_if_base64(std::string &content)
decode a string if it is base64 encoded
bool compile(const context &ctx)
compile attached source; returns true if successful
bool set_code(const context &ctx, const std::string &source, ShaderType st)
set shader code from string
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)
read shader code with read_code and compile.
Stores preprocessor options used for conditionally compiling shader programs.
Definition shader_code.h:73
void define_macro(const std::string &identifier)
Define a macro as identifier and no replacement text.
Definition shader_code.h:99
bool enable(context &ctx)
enable the shader program
bool disable(context &ctx)
disable shader program and restore fixed functionality
static bool collect_file(const std::string &file_name, bool use_cache, std::vector< std::string > &file_names)
resolve file name with shader_code::find_file and add file to list if found
shader_program(bool _show_code_errors=false)
create empty shader program and set the option whether errors during shader code attachment should be...
static std::map< std::string, std::string > program_file_cache
maps used to cache program file contents and valid file names indexed by their respective file name
bool set_uniform(const context &ctx, const std::string &name, const T &value, bool generate_error=false)
Set the value of a uniform by name, where the type can be any of int, unsigned, float,...
static unsigned int get_max_nr_geometry_shader_output_vertices(const context &ctx)
return the maximum number of output vertices of a geometry shader
~shader_program()
call destruct method
static bool collect_files_from_cache(const std::string &name, std::vector< std::string > &file_names, bool &added_files)
resolve file name with shader_code::find_file and add file to list if found
bool attach_dir(const context &ctx, const std::string &dir_name, bool recursive, const shader_compile_options &options={})
collect shader code files from directory, compile and attach.
void destruct(const context &ctx)
destruct shader program
bool build_dir(const context &ctx, const std::string &dir_name, bool recursive=false, bool show_error=false)
successively calls create, attach_dir and link.
static bool open_program_file(std::string &file_name, bool use_cache, std::string &content, std::vector< cgv::utils::line > &lines, std::string *last_error_ptr=0)
common code necessary to open file
bool detach_code(const context &ctx, const shader_code &code)
detach a shader code
bool attach_program(const context &ctx, std::string file_name, bool show_error=false, const shader_compile_options &options={})
collect shader code files declared in shader program file, compile and attach them
static bool collect_files(const std::string &base_name, bool use_cache, std::vector< std::string > &file_names)
collect shader code files that extent the given base name.
int get_attribute_location(const context &ctx, const std::string &name) const
query location index of an attribute
bool attach_code(const context &ctx, const shader_code &code)
attach a compiled shader code instance that is managed outside of program
void update_state(const context &ctx)
ensure that the state has been set in the context
void inspect_program_variables(const context &ctx, cgv::render::ProgramVariableKind kind, std::vector< cgv::render::program_variable_info > &Vs, bool get_location=true, bool get_value=true)
retrieve information on all uniform or attribute variables of a shader program
bool create(const context &ctx)
create the shader program
void set_geometry_shader_info(PrimitiveType input_type, PrimitiveType output_type, int max_output_count=0)
configure the geometry shader, if count < 1 set it to get_max_nr_geometry_shader_output_vertices
bool is_linked() const
return whether program is linked
bool link(const context &ctx, bool show_error=false)
link shaders to an executable program
bool build_program(const context &ctx, const std::string &file_name, bool show_error=false)
successively calls create, attach_program and link.
static bool collect_dir(const std::string &dir_name, bool recursive, std::vector< std::string > &file_names)
collect shader code files from directory.
bool is_enabled() const
check whether program is currently enabled
static std::vector< shader_compile_options > extract_instances(std::string file_name)
find and parse all instance definitions in a shader program file
bool attach_file(const context &ctx, const std::string &file_name, ShaderType st=ST_DETECT, const shader_compile_options &options={})
read shader code from file, compile and attach to program
bool set_textured_material_uniform(const context &ctx, const std::string &name, const textured_material &material, bool generate_error=false)
set a uniform of type textured_material
bool set_light_uniform(const context &ctx, const std::string &name, const cgv::media::illum::light_source &light, bool generate_error=false)
set a uniform of type light source
int get_uniform_location(const context &ctx, const std::string &name) const
query location index of an uniform
bool set_material_uniform(const context &ctx, const std::string &name, const cgv::media::illum::surface_material &material, bool generate_error=false)
set a uniform of type material
const std::map< std::string, int > & get_uniform_locations() const
return uniform name and location pairs
bool attach_files(const context &ctx, const std::vector< std::string > &file_names, const shader_compile_options &options={})
attach a list of files
bool build_files(const context &ctx, const std::string &base_name, bool show_error=false)
successively calls create, attach_files and link.
static bool collect_program(const std::string &file_name, bool use_cache, std::vector< std::string > &file_names)
collect shader code files declared in a shader program file.
class that extends obj_material with the management of textures
size_t get_nr_textures() const
virtual method to query number of textures
the tokenizer allows to split text into tokens in a convenient way.
Definition tokenizer.h:68
tokenizer & set_ws(const std::string &ws)
set the list of white spaces, that separate tokens and are skipped
Definition tokenizer.cxx:38
bool read_data_file(const std::string &file_name, std::string &content, bool ascii)
read ascii file into a string
Definition import.cxx:388
shader_config_ptr get_shader_config()
return a reference to the current shader configuration
ProgramVariableKind
enumerates different kinds of shader program variables
Definition context.h:89
ShaderType
different shader types
Definition context.h:541
PrimitiveType
different primitive types
Definition context.h:279
namespace that holds tools that dont fit any other namespace
void split_to_tokens(const char *begin, const char *end, std::vector< token > &tokens, const std::string &separators, bool merge_separators, const std::string &open_parenthesis, const std::string &close_parenthesis, const std::string &whitespaces, unsigned int max_nr_tokens)
this function splits a text range into tokens.
std::string to_string(const std::string &v, unsigned int w, unsigned int p, bool)
specialization of conversion from string to strings
bool is_integer(const char *begin, const char *end, int &value)
check if the text range (begin,end( defines an integer value. If yes, store the value in the passed r...
Definition scan.cxx:367
void split_to_lines(const char *global_begin, const char *global_end, std::vector< line > &lines, bool truncate_trailing_spaces)
this function splits a text range at the newline characters into single lines.
bool is_space(char c)
check if char is a whitespace
Definition scan.cxx:12
the cgv namespace
Definition print.h:11
cgv::math::fvec< float, 2 > vec2
declare type of 2d single precision floating point vectors
Definition fvec.h:659
Helper functions to process strings.
Stores properties of a surface material.
color_type diffuse_reflectance
diffuse reflectance of surface, defaults to 0.5,0.5,0.5
BrdfType brdf_type
store brdf type, defaults to BT_STRAUSS_DIFFUSE + BT_STRAUSS
color_type emission
emissive color component, defaults to 0,0,0
float roughness_orientation
orientation of roughness in range [0,1], where 0 corresponds to u-direction and 0....
color_type specular_reflectance
specular color used to modulate specular reflection component, should be 1,1,1
float roughness_anisotropy
difference of roughness matrix eigenvalues in range [0,1] relative to roughness, i....
std::complex< float > propagation_slow_down
complex fraction of complex interior over real exterior index of refraction, defaults to 1....
float metalness
metalness of surface, defaults to 0
float transparency
modulation for transparency, defaults to 0
float roughness
surface roughness in the range [0,1] (1/2 trace of symmetric 2x2 matrix for anisotropic case where di...
float ambient_occlusion
scalar factor to down scale ambient light, defaults to 1
int max_geometry_shader_output_vertex_count
the maximum supported size for renderbuffers in any dimension
Definition context.h:43
a line in a text is simply represented as a token
representation of a token in a text by two pointers begin and end, that point to the first character ...
Definition token.h:18
const char * begin
pointers that define the range of characters
Definition token.h:20