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