rays 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.doc/ext/rays/bitmap.cpp +70 -233
- data/.doc/ext/rays/bounds.cpp +339 -57
- data/.doc/ext/rays/color.cpp +58 -48
- data/.doc/ext/rays/color_space.cpp +174 -0
- data/.doc/ext/rays/font.cpp +31 -53
- data/.doc/ext/rays/image.cpp +64 -67
- data/.doc/ext/rays/matrix.cpp +22 -50
- data/.doc/ext/rays/native.cpp +9 -2
- data/.doc/ext/rays/painter.cpp +276 -259
- data/.doc/ext/rays/point.cpp +186 -52
- data/.doc/ext/rays/rays.cpp +25 -20
- data/.doc/ext/rays/shader.cpp +61 -0
- data/.doc/ext/rays/texture.cpp +47 -59
- data/{README → README.md} +0 -0
- data/Rakefile +6 -5
- data/VERSION +1 -1
- data/ext/rays/bitmap.cpp +88 -248
- data/ext/rays/bounds.cpp +437 -141
- data/ext/rays/color.cpp +79 -69
- data/ext/rays/color_space.cpp +185 -0
- data/ext/rays/extconf.rb +14 -63
- data/ext/rays/font.cpp +44 -65
- data/ext/rays/image.cpp +82 -81
- data/ext/rays/matrix.cpp +32 -60
- data/ext/rays/native.cpp +9 -2
- data/ext/rays/painter.cpp +345 -321
- data/ext/rays/point.cpp +212 -69
- data/ext/rays/rays.cpp +29 -23
- data/ext/rays/shader.cpp +63 -0
- data/ext/rays/texture.cpp +64 -74
- data/include/rays/bitmap.h +21 -12
- data/include/rays/bounds.h +67 -9
- data/include/rays/color.h +23 -7
- data/include/rays/{colorspace.h → color_space.h} +6 -3
- data/include/rays/exception.h +17 -11
- data/include/rays/font.h +4 -3
- data/include/rays/image.h +11 -6
- data/include/rays/matrix.h +15 -12
- data/include/rays/opengl.h +54 -1
- data/include/rays/painter.h +98 -108
- data/include/rays/point.h +45 -5
- data/include/rays/rays.h +2 -2
- data/include/rays/ruby/bitmap.h +2 -16
- data/include/rays/ruby/bounds.h +4 -16
- data/include/rays/ruby/color.h +3 -16
- data/include/rays/ruby/color_space.h +27 -0
- data/include/rays/ruby/font.h +2 -16
- data/include/rays/ruby/image.h +2 -16
- data/include/rays/ruby/matrix.h +2 -16
- data/include/rays/ruby/painter.h +2 -16
- data/include/rays/ruby/point.h +3 -16
- data/include/rays/ruby/shader.h +27 -0
- data/include/rays/ruby/texture.h +2 -16
- data/include/rays/ruby.h +1 -0
- data/include/rays/shader.h +48 -0
- data/include/rays/texture.h +13 -2
- data/include/rays.h +2 -1
- data/lib/rays/bitmap.rb +20 -11
- data/lib/rays/bounds.rb +29 -68
- data/lib/rays/color.rb +39 -0
- data/lib/rays/color_space.rb +33 -0
- data/lib/rays/font.rb +29 -0
- data/lib/rays/image.rb +22 -0
- data/lib/rays/module.rb +11 -7
- data/lib/rays/painter.rb +103 -40
- data/lib/rays/point.rb +19 -36
- data/lib/rays/shader.rb +13 -0
- data/lib/rays/texture.rb +9 -0
- data/lib/rays.rb +4 -0
- data/rays.gemspec +3 -4
- data/src/bounds.cpp +272 -63
- data/src/color.cpp +168 -21
- data/src/{colorspace.cpp → color_space.cpp} +38 -1
- data/src/exception.cpp +24 -15
- data/src/frame_buffer.cpp +275 -0
- data/src/frame_buffer.h +79 -0
- data/src/image.cpp +80 -36
- data/src/ios/bitmap.mm +340 -0
- data/src/ios/font.mm +206 -0
- data/src/{cocoa → ios}/helper.h +2 -2
- data/src/{cocoa → ios}/helper.mm +0 -0
- data/src/ios/opengl.mm +21 -0
- data/src/ios/program.cpp +122 -0
- data/src/{cocoa → ios}/rays.mm +8 -7
- data/src/matrix.cpp +10 -22
- data/src/opengl.cpp +64 -0
- data/src/{cocoa → osx}/bitmap.mm +121 -70
- data/src/{cocoa → osx}/font.mm +32 -24
- data/src/osx/helper.h +26 -0
- data/src/osx/helper.mm +25 -0
- data/src/osx/opengl.mm +103 -0
- data/src/osx/rays.mm +43 -0
- data/src/painter.cpp +596 -422
- data/src/point.cpp +154 -11
- data/src/program.cpp +513 -0
- data/src/program.h +73 -0
- data/src/render_buffer.cpp +120 -0
- data/src/render_buffer.h +47 -0
- data/src/shader.cpp +117 -0
- data/src/texture.cpp +104 -134
- data/test/helper.rb +10 -3
- data/test/test_bitmap.rb +18 -0
- data/test/test_bounds.rb +81 -35
- data/test/test_color.rb +29 -2
- data/test/test_image.rb +63 -0
- data/test/test_painter.rb +120 -0
- data/test/test_point.rb +30 -9
- data/test/test_shader.rb +37 -0
- data/test/test_texture.rb +18 -0
- metadata +75 -58
- data/.gitignore +0 -14
- data/ChangeLog +0 -8
data/src/point.cpp
CHANGED
@@ -1,18 +1,22 @@
|
|
1
1
|
#include "rays/point.h"
|
2
2
|
|
3
3
|
|
4
|
+
#include <xot/string.h>
|
5
|
+
#include "rays/exception.h"
|
6
|
+
|
7
|
+
|
4
8
|
namespace Rays
|
5
9
|
{
|
6
10
|
|
7
11
|
|
8
12
|
Point::Point (coord value)
|
9
13
|
{
|
10
|
-
|
14
|
+
reset(value);
|
11
15
|
}
|
12
16
|
|
13
17
|
Point::Point (coord x, coord y, coord z)
|
14
18
|
{
|
15
|
-
|
19
|
+
reset(x, y, z);
|
16
20
|
}
|
17
21
|
|
18
22
|
Point
|
@@ -22,13 +26,13 @@ namespace Rays
|
|
22
26
|
}
|
23
27
|
|
24
28
|
Point&
|
25
|
-
Point::
|
29
|
+
Point::reset (coord value)
|
26
30
|
{
|
27
|
-
return
|
31
|
+
return reset(value, value, 0);
|
28
32
|
}
|
29
33
|
|
30
34
|
Point&
|
31
|
-
Point::
|
35
|
+
Point::reset (coord x, coord y, coord z)
|
32
36
|
{
|
33
37
|
this->x = x;
|
34
38
|
this->y = y;
|
@@ -36,16 +40,155 @@ namespace Rays
|
|
36
40
|
return *this;
|
37
41
|
}
|
38
42
|
|
39
|
-
|
40
|
-
Point::
|
43
|
+
Point&
|
44
|
+
Point::move_to (coord x, coord y, coord z)
|
45
|
+
{
|
46
|
+
return reset(x, y, z);
|
47
|
+
}
|
48
|
+
|
49
|
+
Point&
|
50
|
+
Point::move_to (const Point& point)
|
51
|
+
{
|
52
|
+
return reset(point.x, point.y, point.z);
|
53
|
+
}
|
54
|
+
|
55
|
+
Point&
|
56
|
+
Point::move_by (coord x, coord y, coord z)
|
57
|
+
{
|
58
|
+
return reset(this->x + x, this->y + y, this->z + z);
|
59
|
+
}
|
60
|
+
|
61
|
+
Point&
|
62
|
+
Point::move_by (const Point& point)
|
41
63
|
{
|
42
|
-
return (
|
64
|
+
return reset(this->x + point.x, this->y + point.y, this->z + point.z);
|
65
|
+
}
|
66
|
+
|
67
|
+
String
|
68
|
+
Point::inspect () const
|
69
|
+
{
|
70
|
+
return Xot::stringf("x=%f y=%f z=%f", x, y, z);
|
71
|
+
}
|
72
|
+
|
73
|
+
coord&
|
74
|
+
Point::operator [] (size_t index)
|
75
|
+
{
|
76
|
+
if (index >= 3)
|
77
|
+
argument_error(__FILE__, __LINE__);
|
78
|
+
|
79
|
+
return array[index];
|
80
|
+
}
|
81
|
+
|
82
|
+
const coord&
|
83
|
+
Point::operator [] (size_t index) const
|
84
|
+
{
|
85
|
+
return const_cast<Point*>(this)->operator[](index);
|
86
|
+
}
|
87
|
+
|
88
|
+
Point
|
89
|
+
Point::operator - () const
|
90
|
+
{
|
91
|
+
return Point(-x, -y, -z);
|
92
|
+
}
|
93
|
+
|
94
|
+
Point&
|
95
|
+
Point::operator += (const Point& rhs)
|
96
|
+
{
|
97
|
+
x += rhs.x;
|
98
|
+
y += rhs.y;
|
99
|
+
z += rhs.z;
|
100
|
+
return *this;
|
101
|
+
}
|
102
|
+
|
103
|
+
Point&
|
104
|
+
Point::operator -= (const Point& rhs)
|
105
|
+
{
|
106
|
+
x -= rhs.x;
|
107
|
+
y -= rhs.y;
|
108
|
+
z -= rhs.z;
|
109
|
+
return *this;
|
43
110
|
}
|
44
111
|
|
45
|
-
|
46
|
-
Point::
|
112
|
+
Point&
|
113
|
+
Point::operator *= (const Point& rhs)
|
114
|
+
{
|
115
|
+
x *= rhs.x;
|
116
|
+
y *= rhs.y;
|
117
|
+
z *= rhs.z;
|
118
|
+
return *this;
|
119
|
+
}
|
120
|
+
|
121
|
+
Point&
|
122
|
+
Point::operator /= (const Point& rhs)
|
123
|
+
{
|
124
|
+
x /= rhs.x;
|
125
|
+
y /= rhs.y;
|
126
|
+
z /= rhs.z;
|
127
|
+
return *this;
|
128
|
+
}
|
129
|
+
|
130
|
+
Point&
|
131
|
+
Point::operator /= (coord rhs)
|
132
|
+
{
|
133
|
+
x /= rhs;
|
134
|
+
y /= rhs;
|
135
|
+
z /= rhs;
|
136
|
+
return *this;
|
137
|
+
}
|
138
|
+
|
139
|
+
bool
|
140
|
+
operator == (const Point& lhs, const Point& rhs)
|
141
|
+
{
|
142
|
+
return
|
143
|
+
lhs.x == rhs.x &&
|
144
|
+
lhs.y == rhs.y &&
|
145
|
+
lhs.z == rhs.z;
|
146
|
+
}
|
147
|
+
|
148
|
+
bool
|
149
|
+
operator != (const Point& lhs, const Point& rhs)
|
150
|
+
{
|
151
|
+
return !operator==(lhs, rhs);
|
152
|
+
}
|
153
|
+
|
154
|
+
Point
|
155
|
+
operator + (const Point& lhs, const Point& rhs)
|
156
|
+
{
|
157
|
+
Point t = lhs;
|
158
|
+
t += rhs;
|
159
|
+
return t;
|
160
|
+
}
|
161
|
+
|
162
|
+
Point
|
163
|
+
operator - (const Point& lhs, const Point& rhs)
|
164
|
+
{
|
165
|
+
Point t = lhs;
|
166
|
+
t -= rhs;
|
167
|
+
return t;
|
168
|
+
}
|
169
|
+
|
170
|
+
Point
|
171
|
+
operator * (const Point& lhs, const Point& rhs)
|
172
|
+
{
|
173
|
+
Point t = lhs;
|
174
|
+
t *= rhs;
|
175
|
+
return t;
|
176
|
+
}
|
177
|
+
|
178
|
+
Point
|
179
|
+
operator / (const Point& lhs, const Point& rhs)
|
180
|
+
{
|
181
|
+
Point t = lhs;
|
182
|
+
t /= rhs;
|
183
|
+
return t;
|
184
|
+
}
|
185
|
+
|
186
|
+
Point
|
187
|
+
operator / (const Point& lhs, coord rhs)
|
47
188
|
{
|
48
|
-
|
189
|
+
Point t = lhs;
|
190
|
+
t /= rhs;
|
191
|
+
return t;
|
49
192
|
}
|
50
193
|
|
51
194
|
|
data/src/program.cpp
ADDED
@@ -0,0 +1,513 @@
|
|
1
|
+
#include "program.h"
|
2
|
+
|
3
|
+
|
4
|
+
#include <vector>
|
5
|
+
#include <algorithm>
|
6
|
+
#include <boost/scoped_ptr.hpp>
|
7
|
+
#include <boost/scoped_array.hpp>
|
8
|
+
#include "rays/exception.h"
|
9
|
+
#include "rays/shader.h"
|
10
|
+
|
11
|
+
|
12
|
+
namespace Rays
|
13
|
+
{
|
14
|
+
|
15
|
+
|
16
|
+
class UniformValue
|
17
|
+
{
|
18
|
+
|
19
|
+
public:
|
20
|
+
|
21
|
+
virtual ~UniformValue () {}
|
22
|
+
|
23
|
+
virtual void apply (GLint location) const =0;
|
24
|
+
|
25
|
+
};// UniformValue
|
26
|
+
|
27
|
+
|
28
|
+
template <typename T, int DIMENSION>
|
29
|
+
class UniformValueT : public UniformValue
|
30
|
+
{
|
31
|
+
|
32
|
+
public:
|
33
|
+
|
34
|
+
UniformValueT (T arg1)
|
35
|
+
{
|
36
|
+
assert(DIMENSION == 1);
|
37
|
+
array[0] = arg1;
|
38
|
+
}
|
39
|
+
|
40
|
+
UniformValueT (T arg1, T arg2)
|
41
|
+
{
|
42
|
+
assert(DIMENSION == 2);
|
43
|
+
array[0] = arg1;
|
44
|
+
array[1] = arg2;
|
45
|
+
}
|
46
|
+
|
47
|
+
UniformValueT (T arg1, T arg2, T arg3)
|
48
|
+
{
|
49
|
+
assert(DIMENSION == 3);
|
50
|
+
array[0] = arg1;
|
51
|
+
array[1] = arg2;
|
52
|
+
array[2] = arg3;
|
53
|
+
}
|
54
|
+
|
55
|
+
UniformValueT (T arg1, T arg2, T arg3, T arg4)
|
56
|
+
{
|
57
|
+
assert(DIMENSION == 4);
|
58
|
+
array[0] = arg1;
|
59
|
+
array[1] = arg2;
|
60
|
+
array[2] = arg3;
|
61
|
+
array[3] = arg4;
|
62
|
+
}
|
63
|
+
|
64
|
+
UniformValueT (const T* args, size_t size)
|
65
|
+
{
|
66
|
+
assert(size == DIMENSION);
|
67
|
+
for (size_t i = 0; i < size; ++i)
|
68
|
+
array[i] = args[i];
|
69
|
+
}
|
70
|
+
|
71
|
+
void apply (GLint location) const;
|
72
|
+
|
73
|
+
private:
|
74
|
+
|
75
|
+
T array[DIMENSION];
|
76
|
+
|
77
|
+
};// UniformValueT
|
78
|
+
|
79
|
+
|
80
|
+
template <> void UniformValueT<int, 1>::apply (GLint location) const {glUniform1iv(location, 1, array);}
|
81
|
+
|
82
|
+
template <> void UniformValueT<int, 2>::apply (GLint location) const {glUniform2iv(location, 1, array);}
|
83
|
+
|
84
|
+
template <> void UniformValueT<int, 3>::apply (GLint location) const {glUniform3iv(location, 1, array);}
|
85
|
+
|
86
|
+
template <> void UniformValueT<int, 4>::apply (GLint location) const {glUniform4iv(location, 1, array);}
|
87
|
+
|
88
|
+
template <> void UniformValueT<float, 1>::apply (GLint location) const {glUniform1fv(location, 1, array);}
|
89
|
+
|
90
|
+
template <> void UniformValueT<float, 2>::apply (GLint location) const {glUniform2fv(location, 1, array);}
|
91
|
+
|
92
|
+
template <> void UniformValueT<float, 3>::apply (GLint location) const {glUniform3fv(location, 1, array);}
|
93
|
+
|
94
|
+
template <> void UniformValueT<float, 4>::apply (GLint location) const {glUniform4fv(location, 1, array);}
|
95
|
+
|
96
|
+
|
97
|
+
struct Uniform
|
98
|
+
{
|
99
|
+
|
100
|
+
struct Data
|
101
|
+
{
|
102
|
+
|
103
|
+
String name;
|
104
|
+
|
105
|
+
boost::scoped_ptr<const UniformValue> value;
|
106
|
+
|
107
|
+
};// Data
|
108
|
+
|
109
|
+
Xot::PImpl<Data, true> self;
|
110
|
+
|
111
|
+
Uniform (const char* name, const UniformValue* value)
|
112
|
+
{
|
113
|
+
if (!name || !value || name[0] == '\0')
|
114
|
+
argument_error(__FILE__, __LINE__);
|
115
|
+
|
116
|
+
self->name = name;
|
117
|
+
self->value.reset(value);
|
118
|
+
}
|
119
|
+
|
120
|
+
void apply (GLuint program) const
|
121
|
+
{
|
122
|
+
GLint location = glGetUniformLocation(program, self->name);
|
123
|
+
if (location < 0) return;
|
124
|
+
|
125
|
+
self->value->apply(location);
|
126
|
+
check_error(__FILE__, __LINE__);
|
127
|
+
}
|
128
|
+
|
129
|
+
bool operator == (const Uniform& rhs) const
|
130
|
+
{
|
131
|
+
return self.get() == rhs.self.get();
|
132
|
+
}
|
133
|
+
|
134
|
+
bool operator != (const Uniform& rhs) const
|
135
|
+
{
|
136
|
+
return !operator==(rhs);
|
137
|
+
}
|
138
|
+
|
139
|
+
};// Uniform
|
140
|
+
|
141
|
+
|
142
|
+
typedef std::vector<Shader> ShaderList;
|
143
|
+
|
144
|
+
typedef std::vector<ShaderList> ShaderStack;
|
145
|
+
|
146
|
+
typedef std::vector<Uniform> UniformList;
|
147
|
+
|
148
|
+
typedef std::vector<UniformList> UniformStack;
|
149
|
+
|
150
|
+
|
151
|
+
struct Program::Data
|
152
|
+
{
|
153
|
+
|
154
|
+
int id;
|
155
|
+
|
156
|
+
ShaderStack shader_stack;
|
157
|
+
|
158
|
+
UniformStack uniform_stack;
|
159
|
+
|
160
|
+
bool need_link, using_;
|
161
|
+
|
162
|
+
Data ()
|
163
|
+
: id(-1), need_link(false), using_(false)
|
164
|
+
{
|
165
|
+
shader_stack.push_back(ShaderList());
|
166
|
+
uniform_stack.push_back(UniformList());
|
167
|
+
}
|
168
|
+
|
169
|
+
~Data ()
|
170
|
+
{
|
171
|
+
clear();
|
172
|
+
}
|
173
|
+
|
174
|
+
void create ()
|
175
|
+
{
|
176
|
+
if (is_valid())
|
177
|
+
invalid_state_error(__FILE__, __LINE__, "program is already created.");
|
178
|
+
|
179
|
+
id = glCreateProgram();
|
180
|
+
}
|
181
|
+
|
182
|
+
void clear ()
|
183
|
+
{
|
184
|
+
if (shader_stack.size() != 1 || uniform_stack.size() != 1)
|
185
|
+
invalid_state_error(__FILE__, __LINE__, "stack state is invalid.");
|
186
|
+
|
187
|
+
ShaderList& list = shader_stack.back();
|
188
|
+
for (ShaderList::iterator it = list.begin(); it != list.end(); ++it)
|
189
|
+
detach(*it);
|
190
|
+
|
191
|
+
if (id >= 0) glDeleteProgram((GLuint) id);
|
192
|
+
|
193
|
+
id = -1;
|
194
|
+
}
|
195
|
+
|
196
|
+
void attach (const Shader& shader)
|
197
|
+
{
|
198
|
+
if (!is_valid()) create();
|
199
|
+
|
200
|
+
ShaderList& list = shader_stack.back();
|
201
|
+
ShaderList::iterator it = std::find(list.begin(), list.end(), shader);
|
202
|
+
if (it != list.end()) return;
|
203
|
+
|
204
|
+
glAttachShader(id, shader.id());
|
205
|
+
check_error(__FILE__, __LINE__);
|
206
|
+
|
207
|
+
list.push_back(shader);
|
208
|
+
need_link = true;
|
209
|
+
}
|
210
|
+
|
211
|
+
void detach (const Shader& shader)
|
212
|
+
{
|
213
|
+
ShaderList& list = shader_stack.back();
|
214
|
+
ShaderList::iterator it = std::find(list.begin(), list.end(), shader);
|
215
|
+
if (it == list.end())
|
216
|
+
rays_error(__FILE__, __LINE__, "shader is not attached.");
|
217
|
+
|
218
|
+
glDetachShader(id, shader.id());
|
219
|
+
check_error(__FILE__, __LINE__);
|
220
|
+
|
221
|
+
list.erase(it);
|
222
|
+
need_link = true;
|
223
|
+
}
|
224
|
+
|
225
|
+
void set_uniform (const char* name, const UniformValue* value)
|
226
|
+
{
|
227
|
+
if (uniform_stack.empty())
|
228
|
+
invalid_state_error(__FILE__, __LINE__);
|
229
|
+
|
230
|
+
UniformList& list = uniform_stack.back();
|
231
|
+
std::remove_if(list.begin(), list.end(), UniformNameEqualFun(name));
|
232
|
+
list.push_back(Uniform(name, value));
|
233
|
+
|
234
|
+
if (using_) list.back().apply(id);
|
235
|
+
}
|
236
|
+
|
237
|
+
void update (bool uniforms = true)
|
238
|
+
{
|
239
|
+
link();
|
240
|
+
|
241
|
+
use(!shader_stack.back().empty());
|
242
|
+
if (using_ && uniforms) apply_all_uniforms();
|
243
|
+
}
|
244
|
+
|
245
|
+
bool is_valid () const
|
246
|
+
{
|
247
|
+
return id >= 0;
|
248
|
+
}
|
249
|
+
|
250
|
+
private:
|
251
|
+
|
252
|
+
void link ()
|
253
|
+
{
|
254
|
+
if (!need_link) return;
|
255
|
+
|
256
|
+
glLinkProgram(id);
|
257
|
+
|
258
|
+
GLint status = GL_FALSE;
|
259
|
+
glGetProgramiv(id, GL_LINK_STATUS, &status);
|
260
|
+
if (status == GL_FALSE)
|
261
|
+
{
|
262
|
+
int len = 0;
|
263
|
+
glGetProgramiv(id, GL_INFO_LOG_LENGTH, &len);
|
264
|
+
|
265
|
+
boost::scoped_array<char> buffer(new char[len]);
|
266
|
+
int written = 0;
|
267
|
+
glGetProgramInfoLog(id, len, &written, &buffer[0]);
|
268
|
+
|
269
|
+
opengl_error(__FILE__, __LINE__, &buffer[0]);
|
270
|
+
}
|
271
|
+
|
272
|
+
check_error(__FILE__, __LINE__);
|
273
|
+
|
274
|
+
need_link = false;
|
275
|
+
}
|
276
|
+
|
277
|
+
void use (bool state)
|
278
|
+
{
|
279
|
+
if (state == using_) return;
|
280
|
+
|
281
|
+
glUseProgram(state ? id : 0);
|
282
|
+
using_ = state;
|
283
|
+
}
|
284
|
+
|
285
|
+
void apply_all_uniforms ()
|
286
|
+
{
|
287
|
+
if (uniform_stack.empty())
|
288
|
+
invalid_state_error(__FILE__, __LINE__);
|
289
|
+
|
290
|
+
UniformList& list = uniform_stack.back();
|
291
|
+
for (UniformList::iterator it = list.begin(); it != list.end(); ++it)
|
292
|
+
it->apply(id);
|
293
|
+
}
|
294
|
+
|
295
|
+
struct UniformNameEqualFun
|
296
|
+
{
|
297
|
+
|
298
|
+
String name;
|
299
|
+
|
300
|
+
UniformNameEqualFun (const char* name)
|
301
|
+
: name(name)
|
302
|
+
{
|
303
|
+
}
|
304
|
+
|
305
|
+
bool operator () (const Uniform& uniform) const
|
306
|
+
{
|
307
|
+
return uniform.self->name == name;
|
308
|
+
}
|
309
|
+
|
310
|
+
};// UniformNameEqualFun
|
311
|
+
|
312
|
+
};// Program::Data
|
313
|
+
|
314
|
+
|
315
|
+
Program::Program ()
|
316
|
+
{
|
317
|
+
}
|
318
|
+
|
319
|
+
Program::~Program ()
|
320
|
+
{
|
321
|
+
}
|
322
|
+
|
323
|
+
void
|
324
|
+
Program::attach (const Shader& shader)
|
325
|
+
{
|
326
|
+
self->attach(shader);
|
327
|
+
self->update();
|
328
|
+
}
|
329
|
+
|
330
|
+
void
|
331
|
+
Program::detach (const Shader& shader)
|
332
|
+
{
|
333
|
+
if (!*this)
|
334
|
+
invalid_state_error(__FILE__, __LINE__);
|
335
|
+
|
336
|
+
self->detach(shader);
|
337
|
+
self->update(false);
|
338
|
+
}
|
339
|
+
|
340
|
+
void
|
341
|
+
Program::set_uniform (const char* name, int arg1)
|
342
|
+
{
|
343
|
+
self->set_uniform(name, new UniformValueT<int, 1>(arg1));
|
344
|
+
}
|
345
|
+
|
346
|
+
void
|
347
|
+
Program::set_uniform (const char* name, int arg1, int arg2)
|
348
|
+
{
|
349
|
+
self->set_uniform(name, new UniformValueT<int, 2>(arg1, arg2));
|
350
|
+
}
|
351
|
+
|
352
|
+
void
|
353
|
+
Program::set_uniform (const char* name, int arg1, int arg2, int arg3)
|
354
|
+
{
|
355
|
+
self->set_uniform(name, new UniformValueT<int, 3>(arg1, arg2, arg3));
|
356
|
+
}
|
357
|
+
|
358
|
+
void
|
359
|
+
Program::set_uniform (const char* name, int arg1, int arg2, int arg3, int arg4)
|
360
|
+
{
|
361
|
+
self->set_uniform(name, new UniformValueT<int, 4>(arg1, arg2, arg3, arg4));
|
362
|
+
}
|
363
|
+
|
364
|
+
void
|
365
|
+
Program::set_uniform (const char* name, const int* args, size_t size)
|
366
|
+
{
|
367
|
+
UniformValue* value = NULL;
|
368
|
+
switch (size)
|
369
|
+
{
|
370
|
+
case 1: value = new UniformValueT<int, 1>(args, 1); break;
|
371
|
+
case 2: value = new UniformValueT<int, 2>(args, 2); break;
|
372
|
+
case 3: value = new UniformValueT<int, 3>(args, 3); break;
|
373
|
+
case 4: value = new UniformValueT<int, 4>(args, 4); break;
|
374
|
+
}
|
375
|
+
|
376
|
+
if (value == NULL)
|
377
|
+
argument_error(__FILE__, __LINE__, "invalid 'size' value.");
|
378
|
+
|
379
|
+
self->set_uniform(name, value);
|
380
|
+
}
|
381
|
+
|
382
|
+
void
|
383
|
+
Program::set_uniform (const char* name, float arg1)
|
384
|
+
{
|
385
|
+
self->set_uniform(name, new UniformValueT<float, 1>(arg1));
|
386
|
+
}
|
387
|
+
|
388
|
+
void
|
389
|
+
Program::set_uniform (const char* name, float arg1, float arg2)
|
390
|
+
{
|
391
|
+
self->set_uniform(name, new UniformValueT<float, 2>(arg1, arg2));
|
392
|
+
}
|
393
|
+
|
394
|
+
void
|
395
|
+
Program::set_uniform (const char* name, float arg1, float arg2, float arg3)
|
396
|
+
{
|
397
|
+
self->set_uniform(name, new UniformValueT<float, 3>(arg1, arg2, arg3));
|
398
|
+
}
|
399
|
+
|
400
|
+
void
|
401
|
+
Program::set_uniform (const char* name, float arg1, float arg2, float arg3, float arg4)
|
402
|
+
{
|
403
|
+
self->set_uniform(name, new UniformValueT<float, 4>(arg1, arg2, arg3, arg4));
|
404
|
+
}
|
405
|
+
|
406
|
+
void
|
407
|
+
Program::set_uniform (const char* name, const float* args, size_t size)
|
408
|
+
{
|
409
|
+
UniformValue* value = NULL;
|
410
|
+
switch (size)
|
411
|
+
{
|
412
|
+
case 1: value = new UniformValueT<float, 1>(args, 1); break;
|
413
|
+
case 2: value = new UniformValueT<float, 2>(args, 2); break;
|
414
|
+
case 3: value = new UniformValueT<float, 3>(args, 3); break;
|
415
|
+
case 4: value = new UniformValueT<float, 4>(args, 4); break;
|
416
|
+
}
|
417
|
+
|
418
|
+
if (value == NULL)
|
419
|
+
argument_error(__FILE__, __LINE__, "invalid 'size' value.");
|
420
|
+
|
421
|
+
self->set_uniform(name, value);
|
422
|
+
}
|
423
|
+
|
424
|
+
void
|
425
|
+
Program::push ()
|
426
|
+
{
|
427
|
+
self->shader_stack.push_back(self->shader_stack.back());
|
428
|
+
self->uniform_stack.push_back(self->uniform_stack.back());
|
429
|
+
}
|
430
|
+
|
431
|
+
static void
|
432
|
+
pop_shader_stack (Program::Data* self)
|
433
|
+
{
|
434
|
+
if (!self)
|
435
|
+
argument_error(__FILE__, __LINE__);
|
436
|
+
|
437
|
+
if (self->shader_stack.size() < 2)
|
438
|
+
invalid_state_error(__FILE__, __LINE__, "shader stack underflow.");
|
439
|
+
|
440
|
+
size_t size = self->shader_stack.size();
|
441
|
+
ShaderList& prev = self->shader_stack[size - 1];
|
442
|
+
ShaderList& next = self->shader_stack[size - 2];
|
443
|
+
|
444
|
+
ShaderList::iterator prev_end = prev.end();
|
445
|
+
ShaderList::iterator next_end = next.end();
|
446
|
+
|
447
|
+
for (ShaderList::iterator it = prev.begin(); it != prev_end; ++it)
|
448
|
+
{
|
449
|
+
ShaderList::iterator found = std::find(next.begin(), next_end, *it);
|
450
|
+
if (found == next_end) self->detach(*it);
|
451
|
+
}
|
452
|
+
|
453
|
+
for (ShaderList::iterator it = next.begin(); it != next_end; ++it)
|
454
|
+
{
|
455
|
+
ShaderList::iterator found = std::find(prev.begin(), prev_end, *it);
|
456
|
+
if (found == prev_end) self->attach(*it);
|
457
|
+
}
|
458
|
+
|
459
|
+
self->shader_stack.pop_back();
|
460
|
+
}
|
461
|
+
|
462
|
+
static void
|
463
|
+
pop_uniform_stack (Program::Data* self)
|
464
|
+
{
|
465
|
+
if (!self)
|
466
|
+
argument_error(__FILE__, __LINE__);
|
467
|
+
|
468
|
+
if (self->uniform_stack.size() < 2)
|
469
|
+
invalid_state_error(__FILE__, __LINE__, "uniform stack underflow.");
|
470
|
+
|
471
|
+
size_t size = self->uniform_stack.size();
|
472
|
+
UniformList& prev = self->uniform_stack[size - 1];
|
473
|
+
UniformList& next = self->uniform_stack[size - 2];
|
474
|
+
|
475
|
+
UniformList::iterator prev_end = prev.end();
|
476
|
+
UniformList::iterator next_end = next.end();
|
477
|
+
|
478
|
+
for (UniformList::iterator it = next.begin(); it != next_end; ++it)
|
479
|
+
{
|
480
|
+
UniformList::iterator found = std::find(prev.begin(), prev_end, *it);
|
481
|
+
if (found == prev_end) it->apply(self->id);
|
482
|
+
}
|
483
|
+
|
484
|
+
self->uniform_stack.pop_back();
|
485
|
+
}
|
486
|
+
|
487
|
+
void
|
488
|
+
Program::pop ()
|
489
|
+
{
|
490
|
+
pop_shader_stack(self.get());
|
491
|
+
pop_uniform_stack(self.get());
|
492
|
+
self->update();
|
493
|
+
}
|
494
|
+
|
495
|
+
GLuint
|
496
|
+
Program::id () const
|
497
|
+
{
|
498
|
+
return self->id;
|
499
|
+
}
|
500
|
+
|
501
|
+
Program::operator bool () const
|
502
|
+
{
|
503
|
+
return self->is_valid();
|
504
|
+
}
|
505
|
+
|
506
|
+
bool
|
507
|
+
Program::operator ! () const
|
508
|
+
{
|
509
|
+
return !operator bool();
|
510
|
+
}
|
511
|
+
|
512
|
+
|
513
|
+
}// Rays
|