1 #pragma once 2 #ifndef SHADERS_HPP_INCLUDED 3 #define SHADERS_HPP_INCLUDED 4 5 #include <map> 6 #include <vector> 7 #include <boost/intrusive_ptr.hpp> 8 #include <boost/shared_ptr.hpp> 9 10 #include "asserts.hpp" 11 #include "entity_fwd.hpp" 12 #include "formula_callable.hpp" 13 #include "formula_variable_storage.hpp" 14 15 namespace gles2 16 { 17 18 class shader 19 { 20 public: 21 static void set_runtime_error(const std::string& msg); 22 static std::string get_and_clear_runtime_error(); 23 shader()24 shader() : type_(0), shader_(0) 25 {} 26 explicit shader(GLenum type, const std::string& name, const std::string& code); get() const27 GLuint get() const { return shader_; } name() const28 std::string name() const { return name_; } 29 protected: 30 bool compile(const std::string& code); 31 private: 32 GLenum type_; 33 GLuint shader_; 34 std::string name_; 35 }; 36 37 struct actives 38 { 39 // Name of variable. 40 std::string name; 41 // type of the uniform/attribute variable 42 GLenum type; 43 // If an array type, this is the maximum number of array elements used 44 // in the program. Value is 1 if type is not an array type. 45 GLsizei num_elements; 46 // Location of the active uniform/attribute 47 GLint location; 48 // Last value 49 variant last_value; 50 }; 51 52 class program; 53 typedef boost::intrusive_ptr<program> program_ptr; 54 typedef boost::intrusive_ptr<const program> const_program_ptr; 55 56 class program : public game_logic::formula_callable 57 { 58 public: 59 program(); 60 explicit program(const std::string& name, const shader& vs, const shader& fs); ~program()61 virtual ~program() 62 {} 63 void init(const std::string& name, const shader& vs, const shader& fs); get() const64 GLuint get() const { return object_; } 65 GLuint get_attribute(const std::string& attr) const; 66 GLuint get_uniform(const std::string& attr) const; name() const67 std::string name() const { return name_; } 68 game_logic::formula_ptr create_formula(const variant& v); 69 bool execute_command(const variant& var); 70 void set_uniform(const std::map<std::string,actives>::iterator& it, const variant& value); 71 void set_uniform_or_defer(const std::string& key, const variant& value); 72 variant get_uniform_value(const std::string& key) const; 73 void set_attributes(const std::string& key, const variant& value); 74 variant get_attributes_value(const std::string& key) const; get_environment()75 game_logic::formula_callable* get_environment() { return environ_; } 76 void set_deferred_uniforms(); 77 78 virtual variant write(); 79 80 void vertex_attrib_array(GLint ndx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr); 81 82 virtual void vertex_array(GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr); 83 virtual void texture_array(GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr); 84 virtual void color_array(GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr); 85 virtual void set_fixed_attributes(const variant& node); 86 87 void disable_vertex_attrib(GLint); 88 89 static void load_shaders(const std::string& shader_data); 90 static program_ptr find_program(const std::string& prog_name); 91 static void add_shader(const std::string& program_name, 92 const shader& v_shader, 93 const shader& f_shader, 94 const variant& prog); 95 static std::map<std::string, gles2::program_ptr>& get_shaders(); 96 static void clear_shaders(); 97 protected: 98 bool link(); 99 bool queryUniforms(); 100 bool queryAttributes(); 101 102 virtual variant get_value(const std::string& key) const; 103 virtual void set_value(const std::string& key, const variant& value); 104 105 std::vector<GLint> active_attributes_; 106 variant stored_attributes_; 107 private: 108 game_logic::formula_callable* environ_; 109 std::string name_; 110 shader vs_; 111 shader fs_; 112 GLuint object_; 113 std::map<std::string, actives> attribs_; 114 std::map<std::string, actives> uniforms_; 115 116 std::vector<std::string> uniforms_to_update_; 117 118 friend class shader_program; 119 }; 120 121 class shader_program : public game_logic::formula_callable 122 { 123 public: 124 shader_program(); 125 explicit shader_program(const variant& node, entity* obj = NULL); 126 explicit shader_program(const std::string& program_name); ~shader_program()127 virtual ~shader_program() 128 {} 129 void configure(const variant& node, entity* obj = NULL); 130 void init(entity* obj); 131 game_logic::formula_ptr create_formula(const variant& v); 132 bool execute_command(const variant& var); zorder() const133 int zorder() const { return zorder_; } 134 135 void prepare_draw(); 136 program_ptr shader() const; name() const137 const std::string& name() const { return name_; } parent() const138 entity* parent() const { return parent_; } set_parent(entity * obj)139 void set_parent(entity* obj) { parent_ = obj; } 140 vars()141 game_logic::formula_callable* vars() { return vars_.get(); } vars() const142 const game_logic::formula_callable* vars() const { return vars_.get(); } 143 144 void clear(); 145 variant write(); 146 protected: 147 virtual variant get_value(const std::string& key) const; 148 virtual void set_value(const std::string& key, const variant& value); 149 private: 150 std::string name_; 151 program_ptr program_object_; 152 153 game_logic::formula_variable_storage_ptr vars_; 154 155 std::vector<std::string> create_commands_; 156 std::vector<std::string> draw_commands_; 157 std::vector<game_logic::formula_ptr> create_formulas_; 158 std::vector<game_logic::formula_ptr> draw_formulas_; 159 160 // fake zorder value 161 int zorder_; 162 163 entity* parent_; 164 }; 165 166 typedef boost::intrusive_ptr<shader_program> shader_ptr; 167 typedef boost::intrusive_ptr<const shader_program> const_shader_ptr; 168 169 } 170 171 #endif 172