X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fprogrambuilder.h;h=053eb567487a9a03964235a5d04b3d84c555a68c;hp=69170e02ef979f543b16f1fc53ef0c9adbc0c2d1;hb=4e4a3514961d130045619ea74d0bbab71580838c;hpb=d542522823423f9ed2a5d412de9250ee8367334b diff --git a/source/programbuilder.h b/source/programbuilder.h index 69170e02..053eb567 100644 --- a/source/programbuilder.h +++ b/source/programbuilder.h @@ -18,9 +18,46 @@ public: virtual ~invalid_variable_definition() throw() { } }; +/** +Generates shaders with common features. + +The shader generation model is based on variable substitutions. Initially, a +goal variable is given for each shader stage. The expression for computing +each variable is examined for further variable definitions. When there are no +more known variables available for substitution, the process terminates. Any +unknown variables at this point are assumed to be provided by OpenGL. + +Variables can be defined in a number of scopes. The scope of a variable +determines where its value is computed. If a variable is referenced from a +scope that comes after the declaration scope, an interface variable is +automatically emitted. + +Generated shaders are normally optimized by inlining variables with a single +reference into the expression referencing them. This can result in expressions +of several hundreds of characters in length, so optimizations can be disabled +with the set_optimize() method for debugging purposes. + +Custom variables can be injected to the generated shaders with the custom +member of the StandardFeatures struct. The syntax is: + + := [ ...] + := [= ] ; + := uniform | attribute | vertex | fragment + := (any GLSL type) + := (valid identifier) + := (GLSL expression) + +The custom variables should always include at least one override for a built-in +variable; otherwise they will be ignored as no built-in expression references +them. +*/ class ProgramBuilder { public: + /** + Describes the features of a standard shader program. All boolean features + default to false unless stated otherwise. + */ struct StandardFeatures { class Loader: public DataFile::ObjectLoader @@ -29,14 +66,52 @@ public: Loader(StandardFeatures &); }; + /** Use a diffuse map texture. */ bool texture; + + /** Use material properties if lighting is true, or vertex colors if + lighting is false. */ bool material; + + /** Use lighting to compute the brightness of surfaces. */ bool lighting; + + /** Number of lights to use in lighting calculations. Defaults to 1. */ + unsigned max_lights; + + /** Use a skylight component for ambient lighting. */ + bool skylight; + + bool fog; + + /** Use a specular lighting component. */ bool specular; - bool normalmap; + + /** Use a normal map texture. Only used if lighting is true. */ + bool normal_map; + + /** Use a shadow map. Requires a ShadowMap effect or equivalent in the + pipeline. */ bool shadow; + + /** Use a reflection cube map. Requires an EnvironmentMap effect or + equivalend in the pipeline. */ bool reflection; + + /** Clip primitives against user defined clip planes. */ + bool clipping; + + /** Number of clipping planes to process. */ + unsigned max_clip_planes; + + /** Use a geometry shader. */ + bool geometry; + + /** Force the use of legacy shaders conforming to GLSL 1.10. Defaults + to true if the version of GLSL is less than 1.30, false otherwise. */ bool legacy; + + /** Custom variables to use in the shader. */ std::string custom; StandardFeatures(); @@ -48,10 +123,14 @@ private: enum VariableScope { NO_SCOPE, + TYPE, + FUNCTION, UNIFORM, ATTRIBUTE, VERTEX, - FRAGMENT + GEOMETRY, + FRAGMENT, + N_SCOPES }; enum InterfaceFlags @@ -59,7 +138,6 @@ private: NO_INTERFACE = 0, INPUT = 1, OUTPUT = 2, - PASSTHROUGH = INPUT|OUTPUT, GOAL = 4 }; @@ -76,39 +154,51 @@ private: { std::string name; const VariableDefinition *variable; + const VariableDefinition *type; std::string resolved_name; + std::string resolved_block; bool fuzzy_space; std::string resolved_space; + bool array_sum; + std::string array_subscript; + unsigned array_size; std::list referenced_vars; std::list referenced_by; bool inlined; bool inline_parens; + bool in_loop; ShaderVariable(const std::string &); void resolve(const VariableDefinition &); void resolve(ShaderVariable &); + void resolve_type(const VariableDefinition &); void resolve_space(const std::string &); + void resolve_array(const StandardFeatures &, unsigned = 0); void add_reference(ShaderVariable &); void update_reference(ShaderVariable &, ShaderVariable &); void check_inline(bool, bool); bool is_referenced_from(VariableScope) const; InterfaceFlags get_interface_flags(VariableScope) const; - std::string create_declaration(char = 0) const; - std::string create_replacement(VariableScope) const; - std::string create_expression() const; + std::string create_type_declaration() const; + std::string create_declaration(char = 0, bool = false) const; + std::string create_replacement(VariableScope, unsigned, const char * = 0) const; + std::string create_expression(unsigned, const char * = 0) const; }; - enum MatchLevel + enum MatchType { NO_MATCH, EXACT, - FUZZY + FUZZY, + ARRAY }; StandardFeatures features; std::list custom_variables; std::string feature_flags; + unsigned enabled_scopes; + std::map aliases; bool optimize; static const VariableDefinition standard_variables[]; @@ -117,16 +207,25 @@ private: public: ProgramBuilder(const StandardFeatures &); + /// Enable or disable optimization. Defaults to enabled. void set_optimize(bool); + + /// Create a new Program with the features associated with the builder. Program *create_program() const; + + /// Generate shaders and add them to an existing program. void add_shaders(Program &) const; + private: std::string create_source(const std::list &, VariableScope) const; bool evaluate_flags(const char *) const; - static MatchLevel name_match(const char *, const char *, const char ** = 0); + static const char *unqualified_name(const char *); + static MatchType name_match(const char *, const char *, const char ** = 0); static bool parse_identifier(const char *, unsigned &, unsigned &); static std::vector extract_identifiers(const char *); - static std::string replace_identifiers(const char *, const std::map &); + static std::string replace_identifiers(const char *, const std::map &, bool = false); + static VariableScope previous_scope(VariableScope, unsigned); + std::string create_expression(const ShaderVariable &, const char * = 0) const; }; } // namespace GL