rays 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|