rays 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +7 -0
  2. data/.doc/ext/rays/bitmap.cpp +70 -233
  3. data/.doc/ext/rays/bounds.cpp +339 -57
  4. data/.doc/ext/rays/color.cpp +58 -48
  5. data/.doc/ext/rays/color_space.cpp +174 -0
  6. data/.doc/ext/rays/font.cpp +31 -53
  7. data/.doc/ext/rays/image.cpp +64 -67
  8. data/.doc/ext/rays/matrix.cpp +22 -50
  9. data/.doc/ext/rays/native.cpp +9 -2
  10. data/.doc/ext/rays/painter.cpp +276 -259
  11. data/.doc/ext/rays/point.cpp +186 -52
  12. data/.doc/ext/rays/rays.cpp +25 -20
  13. data/.doc/ext/rays/shader.cpp +61 -0
  14. data/.doc/ext/rays/texture.cpp +47 -59
  15. data/{README → README.md} +0 -0
  16. data/Rakefile +6 -5
  17. data/VERSION +1 -1
  18. data/ext/rays/bitmap.cpp +88 -248
  19. data/ext/rays/bounds.cpp +437 -141
  20. data/ext/rays/color.cpp +79 -69
  21. data/ext/rays/color_space.cpp +185 -0
  22. data/ext/rays/extconf.rb +14 -63
  23. data/ext/rays/font.cpp +44 -65
  24. data/ext/rays/image.cpp +82 -81
  25. data/ext/rays/matrix.cpp +32 -60
  26. data/ext/rays/native.cpp +9 -2
  27. data/ext/rays/painter.cpp +345 -321
  28. data/ext/rays/point.cpp +212 -69
  29. data/ext/rays/rays.cpp +29 -23
  30. data/ext/rays/shader.cpp +63 -0
  31. data/ext/rays/texture.cpp +64 -74
  32. data/include/rays/bitmap.h +21 -12
  33. data/include/rays/bounds.h +67 -9
  34. data/include/rays/color.h +23 -7
  35. data/include/rays/{colorspace.h → color_space.h} +6 -3
  36. data/include/rays/exception.h +17 -11
  37. data/include/rays/font.h +4 -3
  38. data/include/rays/image.h +11 -6
  39. data/include/rays/matrix.h +15 -12
  40. data/include/rays/opengl.h +54 -1
  41. data/include/rays/painter.h +98 -108
  42. data/include/rays/point.h +45 -5
  43. data/include/rays/rays.h +2 -2
  44. data/include/rays/ruby/bitmap.h +2 -16
  45. data/include/rays/ruby/bounds.h +4 -16
  46. data/include/rays/ruby/color.h +3 -16
  47. data/include/rays/ruby/color_space.h +27 -0
  48. data/include/rays/ruby/font.h +2 -16
  49. data/include/rays/ruby/image.h +2 -16
  50. data/include/rays/ruby/matrix.h +2 -16
  51. data/include/rays/ruby/painter.h +2 -16
  52. data/include/rays/ruby/point.h +3 -16
  53. data/include/rays/ruby/shader.h +27 -0
  54. data/include/rays/ruby/texture.h +2 -16
  55. data/include/rays/ruby.h +1 -0
  56. data/include/rays/shader.h +48 -0
  57. data/include/rays/texture.h +13 -2
  58. data/include/rays.h +2 -1
  59. data/lib/rays/bitmap.rb +20 -11
  60. data/lib/rays/bounds.rb +29 -68
  61. data/lib/rays/color.rb +39 -0
  62. data/lib/rays/color_space.rb +33 -0
  63. data/lib/rays/font.rb +29 -0
  64. data/lib/rays/image.rb +22 -0
  65. data/lib/rays/module.rb +11 -7
  66. data/lib/rays/painter.rb +103 -40
  67. data/lib/rays/point.rb +19 -36
  68. data/lib/rays/shader.rb +13 -0
  69. data/lib/rays/texture.rb +9 -0
  70. data/lib/rays.rb +4 -0
  71. data/rays.gemspec +3 -4
  72. data/src/bounds.cpp +272 -63
  73. data/src/color.cpp +168 -21
  74. data/src/{colorspace.cpp → color_space.cpp} +38 -1
  75. data/src/exception.cpp +24 -15
  76. data/src/frame_buffer.cpp +275 -0
  77. data/src/frame_buffer.h +79 -0
  78. data/src/image.cpp +80 -36
  79. data/src/ios/bitmap.mm +340 -0
  80. data/src/ios/font.mm +206 -0
  81. data/src/{cocoa → ios}/helper.h +2 -2
  82. data/src/{cocoa → ios}/helper.mm +0 -0
  83. data/src/ios/opengl.mm +21 -0
  84. data/src/ios/program.cpp +122 -0
  85. data/src/{cocoa → ios}/rays.mm +8 -7
  86. data/src/matrix.cpp +10 -22
  87. data/src/opengl.cpp +64 -0
  88. data/src/{cocoa → osx}/bitmap.mm +121 -70
  89. data/src/{cocoa → osx}/font.mm +32 -24
  90. data/src/osx/helper.h +26 -0
  91. data/src/osx/helper.mm +25 -0
  92. data/src/osx/opengl.mm +103 -0
  93. data/src/osx/rays.mm +43 -0
  94. data/src/painter.cpp +596 -422
  95. data/src/point.cpp +154 -11
  96. data/src/program.cpp +513 -0
  97. data/src/program.h +73 -0
  98. data/src/render_buffer.cpp +120 -0
  99. data/src/render_buffer.h +47 -0
  100. data/src/shader.cpp +117 -0
  101. data/src/texture.cpp +104 -134
  102. data/test/helper.rb +10 -3
  103. data/test/test_bitmap.rb +18 -0
  104. data/test/test_bounds.rb +81 -35
  105. data/test/test_color.rb +29 -2
  106. data/test/test_image.rb +63 -0
  107. data/test/test_painter.rb +120 -0
  108. data/test/test_point.rb +30 -9
  109. data/test/test_shader.rb +37 -0
  110. data/test/test_texture.rb +18 -0
  111. metadata +75 -58
  112. data/.gitignore +0 -14
  113. 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
- set(value);
14
+ reset(value);
11
15
  }
12
16
 
13
17
  Point::Point (coord x, coord y, coord z)
14
18
  {
15
- set(x, y, z);
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::set (coord value)
29
+ Point::reset (coord value)
26
30
  {
27
- return set(value, value, 0);
31
+ return reset(value, value, 0);
28
32
  }
29
33
 
30
34
  Point&
31
- Point::set (coord x, coord y, coord z)
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
- coord*
40
- Point::array ()
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 (coord*) this;
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
- const coord*
46
- Point::array () const
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
- return const_cast<Point*>(this)->array();
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