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
19bool shader_program::attach_files(const context& ctx, const std::vector<std::string>& file_names, const shader_define_map& defines)
20{
21 bool no_error = true;
22 for(unsigned int i = 0; i < file_names.size(); ++i) {
23 no_error = attach_file(ctx, file_names[i], ST_DETECT, defines) && no_error;
24 if(!no_error)
25 std::cout << last_error << std::endl;
26 }
27 return no_error;
28}
29
30bool shader_program::collect_files_from_cache(const std::string& name, std::vector<std::string>& file_names, bool& added_files) {
31
32 auto it = files_cache.find(name);
33 if(it != files_cache.end()) {
34 const std::vector<std::string>& cached_file_names = it->second;
35 for(size_t i = 0; i < cached_file_names.size(); ++i)
36 file_names.push_back(cached_file_names[i]);
37
38 added_files = !cached_file_names.empty();
39 return true;
40 }
41
42 added_files = false;
43 return false;
44}
45
46bool shader_program::collect_file(const std::string& file_name, bool use_cache, std::vector<std::string>& file_names)
47{
48 if(use_cache) {
49 bool added_files = false;
50 if(collect_files_from_cache(file_name, file_names, added_files))
51 return added_files;
52 }
53
54 std::vector<std::string> collected_file_names;
55
56 std::string fn = shader_code::find_file(file_name);
57 bool found = false;
58
59 if (!fn.empty()) {
60 file_names.push_back(fn);
61 if(use_cache)
62 collected_file_names.push_back(fn);
63 found = true;
64 }
65
66 if(use_cache)
67 files_cache.emplace(file_name, collected_file_names);
68
69 return found;
70}
71
72bool shader_program::collect_files(const std::string& base_name, bool use_cache, std::vector<std::string>& file_names)
73{
74 if(use_cache) {
75 bool added_files = false;
76 if(collect_files_from_cache(base_name, file_names, added_files))
77 return added_files;
78 }
79
80 std::vector<std::string> collected_file_names;
81
82 const char* exts[] = { "glvs", "glgs", "glfs", "glcs", "gltc", "glte", "pglvs", "pglfs", "pglgs", "pglcs", "pgltc", "pglte", 0 };
83 const char** iter = exts;
84 bool added_file = false;
85 while (*iter) {
86 std::string fn = shader_code::find_file(base_name+"."+*iter);
87 if (!fn.empty()) {
88 file_names.push_back(fn);
89
90 if(use_cache)
91 collected_file_names.push_back(fn);
92
93 added_file = true;
94 }
95 ++iter;
96 }
97 if(!added_file)
98 std::cerr << "could not find shader file " << base_name.c_str() << std::endl;
99
100 if(use_cache)
101 files_cache.emplace(base_name, collected_file_names);
102
103 return added_file;
104}
105
106bool shader_program::collect_dir(const std::string& dir_name, bool recursive, std::vector<std::string>& file_names)
107{
108 std::string dn = dir_name;
109 if (!dir::exists(dn)) {
110 if (get_shader_config()->shader_path.empty()) {
111 return false;
112 }
113 dn = file::find_in_paths(dir_name, get_shader_config()->shader_path, true);
114 if (dn.empty()) {
115 return false;
116 }
117 }
118 void* handle = file::find_first(dn+"/*.gl*");
119 if (!handle)
120 return false;
121 while (handle) {
122 file_names.push_back(dir_name+"/"+file::find_name(handle));
123 handle = file::find_next(handle);
124 }
125 return true;
126}
127
128bool shader_program::collect_program(const std::string& file_name, bool use_cache, std::vector<std::string>& file_names)
129{
130 std::string fn = shader_code::find_file(file_name);
131 if (fn.empty())
132 return false;
133 std::string content;
134 if (!cgv::base::read_data_file(fn, content, true))
135 return false;
136
138
139 std::vector<line> lines;
140 split_to_lines(content, lines);
141 bool added_file = false;
142 std::string old_shader_path = get_shader_config()->shader_path;
143 std::string path = file::get_path(file_name);
144 if (!path.empty())
145 get_shader_config()->shader_path = path+";"+get_shader_config()->shader_path;
146
147 for (auto line : lines) {
148 std::string l = to_string((const token&)line);
149 if (l.substr(0,5) == "file:")
150 added_file = collect_file(l.substr(5), use_cache, file_names) || added_file;
151 else if (l.substr(0,12) == "vertex_file:")
152 added_file = collect_file(l.substr(12), use_cache, file_names) || added_file;
153 else if (l.substr(0, 14) == "geometry_file:")
154 added_file = collect_file(l.substr(14), use_cache, file_names) || added_file;
155 else if (l.substr(0, 26) == "tessellation_control_file:")
156 added_file = collect_file(l.substr(26), use_cache, file_names) || added_file;
157 else if (l.substr(0, 29) == "tessellation_evaluation_file:")
158 added_file = collect_file(l.substr(29), use_cache, file_names) || added_file;
159 else if (l.substr(0,14) == "fragment_file:")
160 added_file = collect_file(l.substr(14), use_cache, file_names) || added_file;
161 else if (l.substr(0,6) == "files:")
162 added_file = collect_files(l.substr(6), use_cache, file_names) || added_file;
163 else if (l.substr(0,4) == "dir:")
164 added_file = collect_dir(l.substr(4), false, file_names) || added_file;
165 else if (l.substr(0,8) == "rec_dir:")
166 added_file = collect_dir(l.substr(8), true, file_names) || added_file;
167 else if (l.substr(0,8) == "program:")
168 added_file = collect_program(l.substr(8), use_cache, file_names) || added_file;
169 }
170
171 get_shader_config()->shader_path = old_shader_path;
172 return added_file;
173}
174
176shader_program::shader_program(bool _show_code_errors)
177{
178 show_code_errors = _show_code_errors;
179 linked = false;
180 state_out_of_date = true;
181 nr_attached_geometry_shaders = 0;
182}
183
186{
187 if (ctx_ptr && ctx_ptr->make_current())
189 else
190 if (handle != 0)
191 std::cerr << "could not destruct shader program properly" << std::endl;
192}
193
196{
197 state_out_of_date = true;
198 nr_attached_geometry_shaders = 0;
199 if (ctx_ptr)
201 else
202 if (handle)
203 destruct(ctx);
204 ctx_ptr = &ctx;
205 return ctx.shader_program_create(*this);
206}
207
210{
211 if (!handle) {
212 last_error = "attach_code to shader program that was not created";
213 return false;
214 }
215 if (!code.handle) {
216 last_error = "attempt to attach_code that is not created to shader program";
217 return false;
218 }
219 if(!code.is_compiled()) {
220 last_error = "attempt to attach_code that is not compiled to shader program";
221 return false;
222 }
223 ctx.shader_program_attach(*this, code);
224 if(code.get_shader_type() == ST_GEOMETRY)
225 ++nr_attached_geometry_shaders;
226 return true;
227}
228
230bool shader_program::detach_code(const context& ctx, const shader_code& code) {
231 if(!handle) {
232 last_error = "detach_code from shader program that was not created";
233 return false;
234 }
235 if(!code.handle) {
236 last_error = "attempt to detach_code that is not created to shader program";
237 return false;
238 }
239 ctx.shader_program_detach(*this, code);
240 if(code.get_shader_type() == ST_GEOMETRY)
241 --nr_attached_geometry_shaders;
242 return true;
243}
244
245
247bool shader_program::attach_code(const context& ctx, const std::string& source, ShaderType st) {
248 shader_code* code_ptr = new shader_code;
249 if(code_ptr->set_code(ctx, source, st) && code_ptr->compile(ctx)) {
250 managed_codes.push_back(code_ptr);
251 return attach_code(ctx, *code_ptr);
252 }
253 last_error = code_ptr->last_error;
254 delete code_ptr;
255 return false;
256}
257
258
260bool shader_program::attach_file(const context& ctx, const std::string& file_name, ShaderType st, const shader_define_map& defines) {
261 shader_code* code_ptr = new shader_code;
262 if(!code_ptr->read_and_compile(ctx, file_name, st, show_code_errors, defines)) {
263 last_error = code_ptr->last_error;
264 delete code_ptr;
265 return false;
266 }
267 managed_codes.push_back(code_ptr);
268 return attach_code(ctx, *code_ptr);
269}
270
272bool shader_program::attach_files(const context& ctx, const std::string& base_name, const shader_define_map& defines) {
273 std::vector<std::string> file_names;
274 if(!collect_files(base_name, ctx.is_shader_file_cache_enabled(), file_names))
275 return false;
276 return attach_files(ctx, file_names, defines);
277}
279bool shader_program::attach_dir(const context& ctx, const std::string& dir_name, bool recursive) {
280 std::vector<std::string> file_names;
281 if(!collect_dir(dir_name, recursive, file_names))
282 return false;
283 return attach_files(ctx, file_names);
284}
285bool shader_program::open_program_file(std::string& file_name, bool use_cache, std::string& content, std::vector<line>& lines, std::string* last_error_ptr)
286{
287 std::string fn = "";
288
289 if(use_cache) {
290 auto it = program_file_cache.find(file_name);
291 if(it != program_file_cache.end()) {
292 fn = it->second;
293 }
294 }
295
296 if(fn.empty())
297 fn = shader_code::find_file(file_name);
298
299 if(use_cache)
300 program_file_cache.emplace(file_name, fn);
301
302 if (fn.empty()) {
303 if (last_error_ptr)
304 *last_error_ptr = "could not find shader program file " + file_name;
305 return false;
306 }
307 if (!cgv::base::read_data_file(fn, content, true)) {
308 if (last_error_ptr)
309 *last_error_ptr = "could not read shader program file " + file_name;
310 return false;
311 }
313 split_to_lines(content, lines);
314 file_name = fn;
315 return true;
316}
317std::vector<shader_define_map> shader_program::extract_instances(std::string file_name)
318{
319 std::string content;
320 std::vector<line> lines;
321 std::vector<shader_define_map> result;
322 if (!open_program_file(file_name, false, content, lines))
323 return result;
324 for (unsigned int i = 0; i < lines.size(); ++i) {
325 token tok = lines[i];
326 while (tok.begin < tok.end && is_space(*tok.begin))
327 ++tok.begin;
328 std::string l = to_string(tok);
329 if (l.empty() || l[0] == '/')
330 continue;
331 if (l.substr(0, 9) != "instance:")
332 continue;
333 std::string defs=l.substr(9);
334 std::vector<token> toks;
335 split_to_tokens(defs, toks, "", false, "", "", ";");
336 shader_define_map defines;
337 for (const auto& t : toks) {
338 std::vector<token> sides;
339 split_to_tokens(t, sides, "", false, "", "", "=");
340 std::vector<std::string> S;
341 for (auto& s : sides) {
342 while (s.begin < s.end && is_space(*s.begin))
343 ++s.begin;
344 while (s.begin < s.end && is_space(s.end[-1]))
345 --s.end;
346 if (s.begin < s.end)
347 S.push_back(to_string(s));
348 }
349 if (S.size() == 2)
350 defines[S[0]] = S[1];
351 }
352 result.push_back(defines);
353 }
354 return result;
355}
356
357bool shader_program::attach_program(const context& ctx, std::string file_name, bool show_error, const shader_define_map& defines)
358{
359 std::string content;
360 std::vector<line> lines;
361 if (!open_program_file(file_name, ctx.is_shader_file_cache_enabled(), content, lines, &last_error)) {
362 std::cerr << last_error << std::endl;
363 return false;
364 }
365 if (get_shader_config()->show_file_paths)
366 std::cout << "read shader program <" << file_name << ">" << std::endl;
367 std::string old_shader_path = get_shader_config()->shader_path;
368 std::string path = file::get_path(file_name);
369 if (!path.empty())
370 get_shader_config()->shader_path = path+";"+get_shader_config()->shader_path;
371
372 bool no_error = true;
373 std::string error = "2 : attach command failed";
374 for (unsigned int i=0; i<lines.size(); ++i) {
375 token tok = lines[i];
376 while (tok.begin < tok.end && is_space(*tok.begin))
377 ++tok.begin;
378 std::string l = to_string(tok);
379
380 bool success = true;
381 // ignore empty lines
382 if (l.empty())
383 continue;
384 // ignore comments
385 if (l[0] == '/')
386 continue;
387 if (l.substr(0,5) == "file:")
388 success = attach_file(ctx, l.substr(5), ST_DETECT, defines);
389 else if (l.substr(0,12) == "vertex_file:")
390 success = attach_file(ctx, l.substr(12), ST_VERTEX, defines);
391 else if (l.substr(0,14) == "geometry_file:")
392 success = attach_file(ctx, l.substr(14), ST_GEOMETRY, defines);
393 else if (l.substr(0, 26) == "tessellation_control_file:")
394 success = attach_file(ctx, l.substr(26), ST_TESS_CONTROL, defines);
395 else if (l.substr(0, 29) == "tessellation_evaluation_file:")
396 success = attach_file(ctx, l.substr(29), ST_TESS_EVALUATION, defines);
397 else if (l.substr(0,14) == "fragment_file:")
398 success = attach_file(ctx, l.substr(14), ST_FRAGMENT, defines);
399 else if(l.substr(0, 13) == "compute_file:")
400 success = attach_file(ctx, l.substr(13), ST_COMPUTE, defines);
401 else if (l.substr(0,6) == "files:")
402 success = attach_files(ctx, l.substr(6), defines);
403 else if (l.substr(0,4) == "dir:")
404 success = attach_dir(ctx, l.substr(4), false);
405 else if (l.substr(0,8) == "rec_dir:")
406 success = attach_dir(ctx, l.substr(8), true);
407 else if (l.substr(0,8) == "program:")
408 success = attach_program(ctx, l.substr(8));
409 else if (l.substr(0,21) == "geometry_shader_info:") {
410 std::vector<token> toks;
411 std::string l1 = l.substr(21);
412 tokenizer(l1).set_ws(";").bite_all(toks);
413 if (toks.size() == 3) {
414 PrimitiveType i_pt = PT_UNDEF, o_pt = PT_UNDEF;
415 int pi, count = 0;
416 for (pi = PT_UNDEF+1; pi < PT_LAST; ++pi) {
418 std::string s = to_string(pt);
419 if (s == to_string(toks[0]))
420 i_pt = pt;
421 if (s == to_string(toks[1]))
422 o_pt = pt;
423 }
424 if (i_pt == PT_UNDEF) {
425 error = "4 : unknown input_type for geometry shader <";
426 error += to_string(toks[0])+">";
427 success = false;
428 }
429 else if (o_pt == PT_UNDEF) {
430 error = "5 : unknown ouput_type for geometry shader <";
431 error += to_string(toks[1])+">";
432 success = false;
433 }
434 else if (!is_integer(toks[2].begin,toks[2].end,count)) {
435 error = "6 : max_output_count of geometry shader must be an integer but received <";
436 error += to_string(toks[2])+">";
437 success = false;
438 }
439 else {
440 set_geometry_shader_info(i_pt, o_pt, count);
441 }
442 }
443 else {
444 success = false;
445 error = "3 : geometry_shader_info takes three arguments separated by colons";
446 }
447 }
448 else if (l.substr(0, 9) == "instance:") {
449 }
450 else if (show_error) {
451 std::cerr << file_name.c_str() << " (" << i + 1
452 << "): warning G0001 : syntax error in line '"
453 << l.c_str() << "'" << std::endl;
454 }
455 if (!success) {
456 if (show_error) {
457 std::cerr << file_name.c_str() << " (" << i+1
458 << "): error G000" << error.c_str() << std::endl;
459 }
460 no_error = false;
461 }
462 }
463
464 get_shader_config()->shader_path = old_shader_path;
465 if (show_error && !no_error)
466 std::cerr << last_error << std::endl;
467 return no_error;
468}
469
471bool shader_program::build_files(const context& ctx, const std::string& base_name, bool show_error, const shader_define_map& defines)
472{
473 return (is_created() || create(ctx)) &&
474 attach_files(ctx, base_name, defines) && link(ctx, show_error);
475}
477bool shader_program::build_dir(const context& ctx, const std::string& dir_name, bool recursive, bool show_error)
478{
479 return (is_created() || create(ctx)) &&
480 attach_dir(ctx, dir_name, recursive) && link(ctx, show_error);
481}
482
484bool shader_program::build_program(const context& ctx, const std::string& file_name, bool show_error, const shader_define_map& defines)
485{
486 if (!(is_created() || create(ctx)))
487 return false;
488
489 if (!attach_program(ctx, file_name, show_error, defines))
490 return false;
491
492 if (!link(ctx, show_error)) {
493 if (show_error) {
494 std::string fn = shader_code::find_file(file_name);
495 std::vector<line> lines;
497 std::string formated_error;
498 for (unsigned int i = 0; i < lines.size(); ++i) {
499 formated_error += fn + "(1) : error G0002: " + to_string(lines[i]) + "\n";
500 }
501 std::cerr << formated_error.c_str() << std::endl;
502 }
503 return false;
504 }
505
506 return true;
507}
508
511{
512 return ctx.query_integer_constant(MAX_NR_GEOMETRY_SHADER_OUTPUT_VERTICES);
513}
514
517{
518 if (state_out_of_date) {
519 if (nr_attached_geometry_shaders > 0) {
520 if (geometry_shader_output_count < 1)
521 geometry_shader_output_count = get_max_nr_geometry_shader_output_vertices(ctx);
522 ctx.shader_program_set_state(*this);
523 }
524 state_out_of_date = false;
525 }
526}
528bool shader_program::link(const context& ctx, bool show_error)
529{
530 update_state(ctx);
531 if (ctx.shader_program_link(*this)) {
532 linked = true;
533 return true;
534 }
535 else {
536 linked = false;
537 if (show_error)
538 std::cerr << "link error:\n" << last_error.c_str() << std::endl;
539 return false;
540 }
541}
544{
545 return linked;
546}
547
549void shader_program::set_geometry_shader_info(PrimitiveType input_type, PrimitiveType output_type, int max_output_count)
550{
551 geometry_shader_input_type = input_type;
552 geometry_shader_output_type = output_type;
553 geometry_shader_output_count = max_output_count;
554 state_out_of_date = true;
555}
556
559{
560 if (!is_created()) {
561 ctx.error("attempt to enable shader_program that is not created", this);
562 return false;
563 }
564 if (!is_linked()) {
565 ctx.error("attempt to enable shader_program that is not linked", this);
566 return false;
567 }
568 if (is_enabled()) {
569 ctx.error("attempt to enable shader_program that is already enabled or was not disabled properly", this);
570 return false;
571 }
572 update_state(ctx);
573 bool res = ctx.shader_program_enable(*this);
574 if (res)
575 shader_program_base::is_enabled = true;
576 return res;
577}
578
581{
582 if (!is_enabled()) {
583 ctx.error("attempt to disable shader_program that is not enabled", this);
584 return false;
585 }
586 bool res = ctx.shader_program_disable(*this);
587 shader_program_base::is_enabled = false;
588 return res;
589}
590
592int shader_program::get_uniform_location(const context& ctx, const std::string& name) const
593{
594 return ctx.get_uniform_location(*this, name);
595}
597bool shader_program::set_material_uniform(const context& ctx, const std::string& name, const cgv::media::illum::surface_material& material, bool generate_error)
598{
599 return
600 set_uniform(ctx, name + ".brdf_type", (int)material.get_brdf_type(), generate_error) &&
601 set_uniform(ctx, name + ".diffuse_reflectance", material.get_diffuse_reflectance(), generate_error) &&
602 set_uniform(ctx, name + ".roughness", material.get_roughness(), generate_error) &&
603 set_uniform(ctx, name + ".ambient_occlusion", material.get_ambient_occlusion(), generate_error) &&
604 set_uniform(ctx, name + ".emission", material.get_emission(), generate_error) &&
605 set_uniform(ctx, name + ".specular_reflectance", material.get_specular_reflectance(), generate_error) &&
606 set_uniform(ctx, name + ".roughness_anisotropy", material.get_roughness_anisotropy(), generate_error) &&
607 set_uniform(ctx, name + ".roughness_orientation", material.get_roughness_orientation(), generate_error) &&
608 set_uniform(ctx, name + ".propagation_slow_down", cgv::math::fvec<float, 2>(material.get_propagation_slow_down().real(), material.get_propagation_slow_down().imag()), generate_error) &&
609 set_uniform(ctx, name + ".transparency", material.get_transparency(), generate_error) &&
610 set_uniform(ctx, name + ".metalness", material.get_metalness(), generate_error);
611}
612
614bool shader_program::set_textured_material_uniform(const context& ctx, const std::string& name, const textured_material& material, bool generate_error)
615{
616 const char* texture_names[] = {
617 "tex0", "tex1", "tex2", "tex3"
618 };
619 for (int i = 0; i < (int)material.get_nr_image_files(); ++i)
620 if (!set_uniform(ctx, texture_names[i], i, generate_error))
621 return false;
622 return
623 set_material_uniform(ctx, name, material, generate_error) &&
624 set_uniform(ctx, "sRGBA_textures", material.get_sRGBA_textures(), generate_error) &&
625 set_uniform(ctx, "diffuse_index", material.get_diffuse_index(), generate_error) &&
626 set_uniform(ctx, "roughness_index", material.get_roughness_index(), generate_error) &&
627 set_uniform(ctx, "metalness_index", material.get_metalness_index(), generate_error) &&
628 set_uniform(ctx, "ambient_index", material.get_ambient_index(), generate_error) &&
629 set_uniform(ctx, "emission_index", material.get_emission_index(), generate_error) &&
630 set_uniform(ctx, "transparency_index", material.get_transparency_index(), generate_error) &&
631 set_uniform(ctx, "bump_index", material.get_bump_index(), generate_error) &&
632 set_uniform(ctx, "specular_index", material.get_specular_index(), generate_error);
633}
634
635
636
638bool shader_program::set_light_uniform(const context& ctx, const std::string& name, const cgv::media::illum::light_source& L, bool generate_error)
639{
640 if (!set_uniform(ctx, name + ".light_source_type", static_cast<int>(L.get_type()), generate_error))
641 return false;
642 if (!set_uniform(ctx, name + ".position", L.get_position(), generate_error))
643 return false;
644 if (!set_uniform(ctx, name + ".emission", L.get_emission(), generate_error))
645 return false;
646 if (!set_uniform(ctx, name + ".ambient_scale", L.get_ambient_scale(), generate_error))
647 return false;
648 if (!set_uniform(ctx, name + ".spot_direction", L.get_spot_direction(), generate_error))
649 return false;
650 if (!set_uniform(ctx, name + ".spot_exponent", L.get_spot_exponent(), generate_error))
651 return false;
652 if (!set_uniform(ctx, name + ".spot_cos_cutoff", cos(0.01745329252f*L.get_spot_cutoff()), generate_error))
653 return false;
654 if (!set_uniform(ctx, name + ".constant_attenuation", L.get_constant_attenuation(), generate_error))
655 return false;
656 if (!set_uniform(ctx, name + ".linear_attenuation", L.get_linear_attenuation(), generate_error))
657 return false;
658 if (!set_uniform(ctx, name + ".quadratic_attenuation", L.get_quadratic_attenuation(), generate_error))
659 return false;
660 return true;
661}
662
664int shader_program::get_attribute_location(const context& ctx, const std::string& name) const
665{
666 return ctx.get_attribute_location(*this, name);
667}
668
671{
672 while (managed_codes.size() > 0) {
673 delete managed_codes.back();
674 managed_codes.pop_back();
675 }
676 if (handle) {
677 ctx.shader_program_destruct(*this);
678 handle = 0;
679 }
680 linked = false;
681 state_out_of_date = true;
682 auto_detect_uniforms = true;
683 auto_detect_vertex_attributes = true;
684 nr_attached_geometry_shaders = 0;
685}
686
687 }
688}
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
A vector with zero based index.
Definition fvec.h:26
>simple class to hold the properties of a light source
simple class to hold the material properties of a phong material
unsigned get_nr_image_files() const
return number of image files
bool get_sRGBA_textures() const
return whether textures are interpreted in sRGB format
base class for all drawables, which is independent of the used rendering API.
Definition context.h:621
virtual void error(const std::string &message, const render_component *rc=0) const
error handling
Definition context.cxx:219
bool is_shader_file_cache_enabled() const
whether the shader file caches are enabled
Definition context.cxx:463
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:2046
const context * ctx_ptr
keep pointer to my context
Definition context.h:307
std::string last_error
a string that contains the last error
Definition context.h:309
a shader code object holds a code fragment of a geometry vertex or fragment shader and can be added t...
Definition shader_code.h:58
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, bool show_error=true, const shader_define_map &defines=shader_define_map())
read shader code with read_code and compile.
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 std::vector< shader_define_map > extract_instances(std::string file_name)
find and parse all instance definitions in a shader program file
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
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_define_map &defines=shader_define_map())
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
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
static bool collect_dir(const std::string &dir_name, bool recursive, std::vector< std::string > &file_names)
collect shader code files from directory.
bool attach_file(const context &ctx, const std::string &file_name, ShaderType st=ST_DETECT, const shader_define_map &defines=shader_define_map())
read shader code from file, compile and attach to program
bool is_enabled() const
check whether program is currently enabled
bool attach_dir(const context &ctx, const std::string &dir_name, bool recursive)
collect shader code files from directory, compile and attach.
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 attach_files(const context &ctx, const std::vector< std::string > &file_names, const shader_define_map &defines=shader_define_map())
attach a list of files
bool build_files(const context &ctx, const std::string &base_name, bool show_error=false, const shader_define_map &defines=shader_define_map())
successively calls create, attach_files and link.
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
bool build_program(const context &ctx, const std::string &file_name, bool show_error=false, const shader_define_map &defines=shader_define_map())
successively calls create, attach_program 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
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
std::map< std::string, std::string > shader_define_map
typedef for shader define map data structure
Definition shader_code.h:52
shader_config_ptr get_shader_config()
return a reference to the current shader configuration
ShaderType
different shader types
Definition context.h:485
PrimitiveType
different primitive types
Definition context.h:225
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
Helper functions to process strings.
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