1#include <cgv/base/base.h>
2#include "shader_code.h"
3#include <cgv/base/register.h>
4#include <cgv/base/import.h>
6#include <cgv/utils/tokenizer.h>
7#include <cgv/ppp/ph_processor.h>
8#include <cgv/utils/dir.h>
9#include <cgv/utils/file.h>
10#include <cgv/type/variant.h>
13#pragma warning(disable:4996)
37 return "shader_config";
54 if (
getenv(
"CGV_SHADER_PATH"))
56 else if (
getenv(
"CGV_DIR"))
58 std::string(
getenv(
"CGV_DIR"))+
"/libs/cgv_gl/glsl;"+
59 std::string(
getenv(
"CGV_DIR"))+
"/libs/plot/glsl;"+
60 std::string(
getenv(
"CGV_DIR")) +
"/libs/cgv_app/glsl;" +
61 std::string(
getenv(
"CGV_DIR")) +
"/libs/cgv_g2d/glsl;" +
62 std::string(
getenv(
"CGV_DIR")) +
"/libs/cgv_gpgpu/glsl;" +
63 std::string(
getenv(
"CGV_DIR")) +
"/libs/holo_disp;" +
64 std::string(
getenv(
"CGV_DIR")) +
"/plugins/examples";
71 if (!content.empty()) {
73 if(content[0] ==
char(0xA7))
96 std::vector<line> lines;
99 for (
unsigned int i = 0;
i<lines.size(); ++
i) {
101 if (
to_upper(
l.substr(0, 5)) ==
"ERROR") {
102 std::vector<token>
toks;
105 if (
toks.size() > 4) {
118 std::vector<token>
toks;
120 unsigned int i,
j, k;
int n;
121 for (
i=0;
i<
toks.size(); ++
i) {
125 for (
j=0;
j<
toks.size(); ++
j) {
129 for (k=0; k<
toks.size(); ++k) {
134 std::string
_fn =
fn;
168 std::cerr <<
"shader code not destructed correctly" << std::endl;
176 ctx.shader_code_destruct(*
this);
182 if (file_name.substr(0, 6) ==
"str://" || file_name.substr(0, 6) ==
"res://") {
183 std::map<std::string, resource_file_info>::const_iterator
it =
ref_resource_file_map().find(file_name.substr(6));
189 if (file::exists(file_name))
196 std::map<std::string, resource_file_info>::const_iterator
it =
199 if (
it->second.file_offset == -1)
200 return std::string(
"str://") + file_name;
202 return std::string(
"res://") + file_name;
205 try_name = std::string(
"glsl/") + file_name;
221 if(
end_pos == std::string::npos) {
233 std::string
ext = file::get_extension(file_name);
234 if(
ext.length() > 2) {
235 if(
ext[0] ==
'g' &&
ext[1] ==
'l' ||
236 ext[0] ==
'p' &&
ext[1] ==
'g' &&
ext[2] ==
'l')
259 std::string source =
"";
281 std::string
ext =
to_lower(file::get_extension(file_name));
283 if (
ext ==
"glfs" ||
ext ==
"pglfs")
285 else if (
ext ==
"glgs" ||
ext ==
"pglgs")
287 else if (
ext ==
"glcs" ||
ext ==
"pglcs")
289 else if (
ext ==
"gltc" ||
ext ==
"pgltc")
290 st = ST_TESS_CONTROL;
291 else if (
ext ==
"glte" ||
ext ==
"pglte")
292 st = ST_TESS_EVALUATION;
302 std::vector<line> lines;
305 for(
size_t i = 0;
i < lines.size(); ++
i) {
368 std::cout <<
"read shader code <" <<
fn <<
">" << std::endl;
372 if (file::get_extension(file_name)[0] ==
'p') {
375 std::string
paths = file::get_path(
fn);
381 if (!
php.parse_string(source))
383 if (!
php.process_to_string(
code))
385 cgv::ppp::clear_variables();
420 return ctx.shader_code_create(*
this,
st, source);
426 for (
const auto &
entry : defines) {
427 std::string name =
entry.first;
428 std::string value =
entry.second;
433 size_t define_pos = source.find(
"#define " + name);
438 if(source[
define_pos + 8 + name.length()] ==
'\n')
458 std::string type =
"";
459 std::string name =
"";
464 std::string
str =
"layout (location = ";
465 str += std::to_string(location);
473 std::vector<token>
parts;
474 std::vector<token> tokens;
475 std::vector<vertex_attribute>
attribs;
494 if(tokens.size() > 1 && tokens[0] ==
"#version") {
503 if(tokens.size() == 3 && tokens[2] ==
"core")
513 if(tokens.size() > 1 && tokens[0] ==
"#define") {
514 if(tokens[1] ==
"NO_UPGRADE") {
536 for(
unsigned i = 0;
i <
tok.size() - 2; ++
i) {
547 if(c ==
'i' &&
tok[
i + 1] ==
'n' &&
tok[
i + 2] ==
' ') {
571 size_t size = tokens.size();
573 if(tokens.size() > 2) {
580 for(
size_t j = 0;
j < size; ++
j) {
581 auto&
tok = tokens[
j];
582 if(
tok.size() == 1 &&
tok[0] ==
'=')
610 for(
size_t i = 0;
i <
parts.size(); ++
i) {
620 std::string
str =
"";
634 std::string
first_part = source.substr(0, offset);
635 std::string
second_part = source.substr(offset + length + 1);
645 if (!ctx.shader_code_compile(*
this)) {
650 user_data = (
void*&)
id;
672 return user_data != 0;
More advanced text processing for splitting text into lines or tokens.
virtual bool end()
perform the leave part of the action on the current object
complete implementation of method actions that only call one method when entering a node
bool begin()
uses call_method of base class method_action to call the method refered to by the stored method point...
reference counted pointer, which can work together with types that are derived from ref_counted,...
bool empty() const
check if pointer is not yet set
the pre header processor parses a pre header file and converts it to a header file or uses the inform...
the self reflection handler is passed to the virtual self_reflect() method of cgv::base::base.
bool reflect_member(const std::string &member_name, T &member_ref, bool hard_cast=false)
call this to reflect a member by member name and reference to the member.
base class for all drawables, which is independent of the used rendering API.
virtual GPUVendorID get_gpu_vendor_id() const
device information
bool is_shader_file_cache_enabled() const
whether the shader file caches are enabled
const context * ctx_ptr
keep pointer to my context
std::string last_error
a string that contains the last error
static bool shader_file_name_map_initialized
whether the shader file name map is initialized
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.
shader_code()
create shader a shader code object
static std::string read_code_file(const std::string &file_name, std::string *_last_error=0)
read shader code from file and return string with content or empty string if read failed
static std::map< std::string, std::string > code_cache
map that caches shader file contents indexed by their file name
bool read_code(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 that is searched for with find_file.
ShaderType get_shader_type() const
return the shader type of this code
void set_defines(std::string &source, const shader_define_map &defines)
set shader code defines
static std::string resolve_includes(const std::string &source, bool use_cache, std::set< std::string > &included_file_names, std::string *_last_error=0)
search for include directives in the given source code, replace them by the included file contents an...
bool is_compiled() const
return whether shader has been compiled successfully
void destruct(const context &ctx)
destruct shader code
~shader_code()
calls the destruct method
static void decode_if_base64(std::string &content)
decode a string if it is base64 encoded
static std::string retrieve_code(const std::string &file_name, bool use_cache, std::string *_last_error)
retreive shader code either by reading the file from disk or from the cache if enabled
ShaderType st
store the shader type
static std::string get_last_error(const std::string &file_name, const std::string &last_error)
format given last error in a way that developer environments can locate errors in the source file
static std::map< std::string, std::string > shader_file_name_map
map that caches full shader file paths indexed by the shader file name
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
void set_vertex_attrib_locations(std::string &source)
set shader code vertex attribute locations (a hotfix for AMD driver behaviour on vertex shaders)
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.
static ShaderType detect_shader_type(const std::string &file_name)
detect the shader type from the extension of the given file_name, i.e.
the tokenizer allows to split text into tokens in a convenient way.
tokenizer & set_sep(const std::string &sep, bool merge)
set the list of separators and specify whether succeeding separators are merged into single tokens
tokenizer & set_ws(const std::string &ws)
set the list of white spaces, that separate tokens and are skipped
the base namespace holds the base hierarchy, support for plugin registration and signals
bool read_data_file(const std::string &file_name, std::string &content, bool ascii)
read ascii file into a string
std::map< std::string, resource_file_info > & ref_resource_file_map()
return a reference to a mapping of resource file names to resource file infos
void register_object(base_ptr object, const std::string &options)
register an object and send event to all current registration ref_listeners()
std::string & ref_prog_name()
return a refence to the name of the started executable
std::map< std::string, std::string > shader_define_map
typedef for shader define map data structure
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
ShaderType
different shader types
namespace for compile time type information
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...
std::string & trim(std::string &str, const std::string &chars)
trim white space or other characters from start and end of string
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.
char to_lower(char c)
convert char to lower case
char to_upper(char c)
convert char to upper case
bool is_space(char c)
check if char is a whitespace
std::string decode_base64(std::string const &encoded_string)
decode a base64 encoded string
std::string strip_cpp_comments(const std::string &source, bool correct_new_lines)
remove cpp-style comments from string
a globally unique shader config is registered by default when the cgv library is used.
std::string get_type_name() const
return "shader_config"
bool show_file_paths
whether to output full paths of read shaders
shader_config()
construct config without file name tracing
bool trace_file_names
whether to keep track of file names
bool self_reflect(cgv::reflect::reflection_handler &srh)
reflect the shader_path member
std::string shader_path
the path used to find shaders with the cgv::utils::file::find_in_paths function
representation of a token in a text by two pointers begin and end, that point to the first character ...