rays 0.1.12 → 0.1.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +5 -5
  2. data/.doc/ext/rays/bitmap.cpp +22 -76
  3. data/.doc/ext/rays/bounds.cpp +95 -125
  4. data/.doc/ext/rays/color.cpp +224 -45
  5. data/.doc/ext/rays/color_space.cpp +137 -45
  6. data/.doc/ext/rays/defs.cpp +183 -0
  7. data/.doc/ext/rays/font.cpp +39 -21
  8. data/.doc/ext/rays/image.cpp +26 -37
  9. data/.doc/ext/rays/matrix.cpp +186 -29
  10. data/.doc/ext/rays/native.cpp +12 -6
  11. data/.doc/ext/rays/noise.cpp +53 -0
  12. data/.doc/ext/rays/painter.cpp +120 -308
  13. data/.doc/ext/rays/point.cpp +82 -77
  14. data/.doc/ext/rays/polygon.cpp +287 -0
  15. data/.doc/ext/rays/polygon_line.cpp +96 -0
  16. data/.doc/ext/rays/polyline.cpp +161 -0
  17. data/.doc/ext/rays/rays.cpp +0 -13
  18. data/.doc/ext/rays/shader.cpp +83 -9
  19. data/README.md +1 -1
  20. data/Rakefile +21 -9
  21. data/VERSION +1 -1
  22. data/ext/rays/bitmap.cpp +22 -80
  23. data/ext/rays/bounds.cpp +100 -128
  24. data/ext/rays/color.cpp +232 -51
  25. data/ext/rays/color_space.cpp +140 -46
  26. data/ext/rays/defs.cpp +183 -0
  27. data/ext/rays/defs.h +26 -2
  28. data/ext/rays/extconf.rb +1 -2
  29. data/ext/rays/font.cpp +39 -22
  30. data/ext/rays/image.cpp +27 -39
  31. data/ext/rays/matrix.cpp +198 -30
  32. data/ext/rays/native.cpp +12 -6
  33. data/ext/rays/noise.cpp +55 -0
  34. data/ext/rays/painter.cpp +129 -315
  35. data/ext/rays/point.cpp +89 -81
  36. data/ext/rays/polygon.cpp +301 -0
  37. data/ext/rays/polygon_line.cpp +99 -0
  38. data/ext/rays/polyline.cpp +170 -0
  39. data/ext/rays/rays.cpp +0 -14
  40. data/ext/rays/shader.cpp +84 -9
  41. data/include/rays.h +10 -2
  42. data/include/rays/bitmap.h +14 -26
  43. data/include/rays/bounds.h +21 -4
  44. data/include/rays/color.h +25 -14
  45. data/include/rays/color_space.h +11 -8
  46. data/include/rays/coord.h +114 -0
  47. data/include/rays/debug.h +22 -0
  48. data/include/rays/defs.h +3 -0
  49. data/include/rays/font.h +4 -4
  50. data/include/rays/image.h +11 -17
  51. data/include/rays/matrix.h +50 -24
  52. data/include/rays/noise.h +42 -0
  53. data/include/rays/opengl.h +2 -50
  54. data/include/rays/painter.h +57 -99
  55. data/include/rays/point.h +44 -51
  56. data/include/rays/polygon.h +164 -0
  57. data/include/rays/polyline.h +65 -0
  58. data/include/rays/rays.h +3 -0
  59. data/include/rays/ruby.h +7 -1
  60. data/include/rays/ruby/bounds.h +1 -1
  61. data/include/rays/ruby/color.h +1 -1
  62. data/include/rays/ruby/color_space.h +1 -1
  63. data/include/rays/ruby/font.h +1 -1
  64. data/include/rays/ruby/matrix.h +1 -1
  65. data/include/rays/ruby/point.h +1 -1
  66. data/include/rays/ruby/polygon.h +52 -0
  67. data/include/rays/ruby/polyline.h +41 -0
  68. data/include/rays/ruby/shader.h +1 -1
  69. data/include/rays/shader.h +36 -8
  70. data/lib/rays.rb +6 -1
  71. data/lib/rays/bitmap.rb +0 -15
  72. data/lib/rays/bounds.rb +17 -23
  73. data/lib/rays/color.rb +20 -47
  74. data/lib/rays/color_space.rb +13 -13
  75. data/lib/rays/image.rb +2 -6
  76. data/lib/rays/matrix.rb +28 -0
  77. data/lib/rays/module.rb +4 -19
  78. data/lib/rays/painter.rb +60 -97
  79. data/lib/rays/point.rb +13 -21
  80. data/lib/rays/polygon.rb +50 -0
  81. data/lib/rays/polygon_line.rb +36 -0
  82. data/lib/rays/polyline.rb +32 -0
  83. data/lib/rays/shader.rb +20 -1
  84. data/rays.gemspec +5 -7
  85. data/src/bitmap.h +36 -0
  86. data/src/bounds.cpp +74 -11
  87. data/src/color.cpp +58 -23
  88. data/src/color_space.cpp +50 -32
  89. data/src/color_space.h +22 -0
  90. data/src/coord.cpp +170 -0
  91. data/src/coord.h +35 -0
  92. data/src/font.cpp +118 -0
  93. data/src/font.h +64 -0
  94. data/src/frame_buffer.cpp +37 -71
  95. data/src/frame_buffer.h +4 -4
  96. data/src/image.cpp +171 -97
  97. data/src/image.h +25 -0
  98. data/src/ios/bitmap.mm +107 -105
  99. data/src/ios/font.mm +48 -60
  100. data/src/ios/helper.h +2 -2
  101. data/src/ios/opengl.mm +19 -4
  102. data/src/ios/rays.mm +3 -0
  103. data/src/matrix.cpp +111 -26
  104. data/src/matrix.h +30 -0
  105. data/src/noise.cpp +74 -0
  106. data/src/opengl.cpp +9 -27
  107. data/src/opengl.h +37 -0
  108. data/src/osx/bitmap.mm +111 -106
  109. data/src/osx/font.mm +48 -61
  110. data/src/osx/helper.h +2 -2
  111. data/src/osx/opengl.mm +19 -83
  112. data/src/osx/rays.mm +3 -0
  113. data/src/painter.cpp +780 -696
  114. data/src/painter.h +24 -0
  115. data/src/point.cpp +140 -119
  116. data/src/polygon.cpp +1100 -0
  117. data/src/polygon.h +32 -0
  118. data/src/polyline.cpp +158 -0
  119. data/src/polyline.h +67 -0
  120. data/src/render_buffer.cpp +11 -4
  121. data/src/render_buffer.h +2 -2
  122. data/src/shader.cpp +163 -106
  123. data/src/shader.h +38 -0
  124. data/src/shader_program.cpp +533 -0
  125. data/src/{program.h → shader_program.h} +28 -16
  126. data/src/shader_source.cpp +140 -0
  127. data/src/shader_source.h +52 -0
  128. data/src/texture.cpp +136 -160
  129. data/src/texture.h +65 -0
  130. data/src/win32/bitmap.cpp +62 -52
  131. data/src/win32/font.cpp +11 -13
  132. data/src/win32/font.h +24 -0
  133. data/src/win32/gdi.h +6 -6
  134. data/test/helper.rb +0 -3
  135. data/test/test_bitmap.rb +31 -7
  136. data/test/test_bounds.rb +36 -0
  137. data/test/test_color.rb +59 -19
  138. data/test/test_color_space.rb +95 -0
  139. data/test/test_image.rb +24 -20
  140. data/test/test_matrix.rb +106 -0
  141. data/test/test_painter.rb +92 -46
  142. data/test/test_painter_shape.rb +57 -0
  143. data/test/test_point.rb +21 -0
  144. data/test/test_polygon.rb +234 -0
  145. data/test/test_polygon_line.rb +167 -0
  146. data/test/test_polyline.rb +145 -0
  147. data/test/test_shader.rb +9 -9
  148. metadata +88 -67
  149. data/.doc/ext/rays/texture.cpp +0 -138
  150. data/ext/rays/texture.cpp +0 -149
  151. data/include/rays/ruby/texture.h +0 -41
  152. data/include/rays/texture.h +0 -71
  153. data/lib/rays/texture.rb +0 -24
  154. data/src/program.cpp +0 -648
  155. data/test/test_texture.rb +0 -27
@@ -0,0 +1,38 @@
1
+ // -*- c++ -*-
2
+ #pragma once
3
+ #ifndef __RAYS_SRC_SHADER_H__
4
+ #define __RAYS_SRC_SHADER_H__
5
+
6
+
7
+ #include <rays/shader.h>
8
+
9
+
10
+ namespace Rays
11
+ {
12
+
13
+
14
+ #define ATTRIB_POSITION "a_Position"
15
+ #define VARYING_POSITION "v_Position"
16
+ #define UNIFORM_POSITION_MATRIX "u_PositionMatrix"
17
+ #define ATTRIB_TEXCOORD "a_TexCoord"
18
+ #define VARYING_TEXCOORD "v_TexCoord"
19
+ #define UNIFORM_TEXCOORD_MIN "u_TexCoordMin"
20
+ #define UNIFORM_TEXCOORD_MAX "u_TexCoordMax"
21
+ #define UNIFORM_TEXCOORD_MATRIX "u_TexCoordMatrix"
22
+ #define ATTRIB_COLOR "a_Color"
23
+ #define VARYING_COLOR "v_Color"
24
+ //#define UNIFORM_COLOR_MATRIX "u_ColorMatrix"
25
+ #define UNIFORM_TEXTURE "u_Texture"
26
+ #define UNIFORM_TEXTURE_SIZE "u_TextureSize"
27
+
28
+
29
+ class ShaderProgram;
30
+
31
+
32
+ const ShaderProgram* Shader_get_program (const Shader& shader);
33
+
34
+
35
+ }// Rays
36
+
37
+
38
+ #endif//EOH
@@ -0,0 +1,533 @@
1
+ #include "shader_program.h"
2
+
3
+
4
+ #include <assert.h>
5
+ #include <vector>
6
+ #include <memory>
7
+ #include <algorithm>
8
+ #include "rays/exception.h"
9
+ #include "shader_source.h"
10
+ #include "texture.h"
11
+ #include "painter.h"
12
+
13
+
14
+ namespace Rays
15
+ {
16
+
17
+
18
+ static GLint
19
+ get_texture_unit_max ()
20
+ {
21
+ static GLint value = -1;
22
+ if (value < 0)
23
+ {
24
+ glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &value);
25
+ OpenGL_check_error(__FILE__, __LINE__);
26
+ }
27
+ return value;
28
+ }
29
+
30
+
31
+ class UniformValue
32
+ {
33
+
34
+ public:
35
+
36
+ virtual ~UniformValue () {}
37
+
38
+ virtual void apply (GLint location) const = 0;
39
+
40
+ };// UniformValue
41
+
42
+
43
+ template <typename T, int DIMENSION>
44
+ class UniformValueT : public UniformValue
45
+ {
46
+
47
+ public:
48
+
49
+ UniformValueT (T arg1)
50
+ {
51
+ assert(DIMENSION == 1);
52
+ array[0] = arg1;
53
+ }
54
+
55
+ UniformValueT (T arg1, T arg2)
56
+ {
57
+ assert(DIMENSION == 2);
58
+ array[0] = arg1;
59
+ array[1] = arg2;
60
+ }
61
+
62
+ UniformValueT (T arg1, T arg2, T arg3)
63
+ {
64
+ assert(DIMENSION == 3);
65
+ array[0] = arg1;
66
+ array[1] = arg2;
67
+ array[2] = arg3;
68
+ }
69
+
70
+ UniformValueT (T arg1, T arg2, T arg3, T arg4)
71
+ {
72
+ assert(DIMENSION == 4);
73
+ array[0] = arg1;
74
+ array[1] = arg2;
75
+ array[2] = arg3;
76
+ array[3] = arg4;
77
+ }
78
+
79
+ UniformValueT (const T* args, size_t size)
80
+ {
81
+ assert(size == DIMENSION);
82
+ for (size_t i = 0; i < size; ++i)
83
+ array[i] = args[i];
84
+ }
85
+
86
+ void apply (GLint location) const
87
+ {
88
+ apply_value(location);
89
+ OpenGL_check_error(__FILE__, __LINE__);
90
+ }
91
+
92
+ void apply_value (GLint location) const;
93
+
94
+ private:
95
+
96
+ T array[DIMENSION];
97
+
98
+ };// UniformValueT
99
+
100
+
101
+ template <> void UniformValueT<int, 1>::apply_value (GLint location) const
102
+ {
103
+ glUniform1iv(location, 1, array);
104
+ }
105
+
106
+ template <> void UniformValueT<int, 2>::apply_value (GLint location) const
107
+ {
108
+ glUniform2iv(location, 1, array);
109
+ }
110
+
111
+ template <> void UniformValueT<int, 3>::apply_value (GLint location) const
112
+ {
113
+ glUniform3iv(location, 1, array);
114
+ }
115
+
116
+ template <> void UniformValueT<int, 4>::apply_value (GLint location) const
117
+ {
118
+ glUniform4iv(location, 1, array);
119
+ }
120
+
121
+ template <> void UniformValueT<float, 1>::apply_value (GLint location) const
122
+ {
123
+ glUniform1fv(location, 1, array);
124
+ }
125
+
126
+ template <> void UniformValueT<float, 2>::apply_value (GLint location) const
127
+ {
128
+ glUniform2fv(location, 1, array);
129
+ }
130
+
131
+ template <> void UniformValueT<float, 3>::apply_value (GLint location) const
132
+ {
133
+ glUniform3fv(location, 1, array);
134
+ }
135
+
136
+ template <> void UniformValueT<float, 4>::apply_value (GLint location) const
137
+ {
138
+ glUniform4fv(location, 1, array);
139
+ }
140
+
141
+
142
+ class UniformTexture : public UniformValue
143
+ {
144
+
145
+ public:
146
+
147
+ UniformTexture (const Texture& texture)
148
+ : texture(texture)
149
+ {
150
+ }
151
+
152
+ void apply (GLint location) const
153
+ {
154
+ if (!texture) return;
155
+
156
+ GLint unit_max = get_texture_unit_max();
157
+ GLint unit = unit_max;
158
+ glGetIntegerv(GL_ACTIVE_TEXTURE, &unit);
159
+ assert(unit < unit_max);
160
+
161
+ glBindTexture(GL_TEXTURE_2D, texture.id());
162
+ glUniform1i(location, unit);
163
+ OpenGL_check_error(__FILE__, __LINE__);
164
+ }
165
+
166
+ private:
167
+
168
+ Texture texture;
169
+
170
+ };// UniformTexture
171
+
172
+
173
+ struct Uniform
174
+ {
175
+
176
+ struct Data
177
+ {
178
+
179
+ String name;
180
+
181
+ std::unique_ptr<const UniformValue> value;
182
+
183
+ bool applied = false;
184
+
185
+ };// Data
186
+
187
+ Xot::PSharedImpl<Data> self;
188
+
189
+ Uniform (const char* name, const UniformValue* value)
190
+ {
191
+ if (!name || name[0] == '\0')
192
+ argument_error(__FILE__, __LINE__);
193
+
194
+ reset(value);
195
+
196
+ self->name = name;
197
+ }
198
+
199
+ void reset (const UniformValue* value)
200
+ {
201
+ if (!value)
202
+ argument_error(__FILE__, __LINE__);
203
+
204
+ self->value.reset(value);
205
+ self->applied = false;
206
+ }
207
+
208
+ void apply (const ShaderProgram& program) const
209
+ {
210
+ if (!program || self->applied) return;
211
+ self->applied = true;
212
+
213
+ GLint location = glGetUniformLocation(program.id(), self->name);
214
+ if (location < 0) return;
215
+
216
+ self->value->apply(location);
217
+ }
218
+
219
+ bool operator == (const Uniform& rhs) const
220
+ {
221
+ return self.get() == rhs.self.get();
222
+ }
223
+
224
+ bool operator != (const Uniform& rhs) const
225
+ {
226
+ return !operator==(rhs);
227
+ }
228
+
229
+ };// Uniform
230
+
231
+
232
+ typedef std::vector<Uniform> UniformList;
233
+
234
+
235
+ struct ShaderProgram::Data
236
+ {
237
+
238
+ GLuint id = 0;
239
+
240
+ ShaderSource vertex, fragment;
241
+
242
+ UniformList uniform_values, uniform_textures;
243
+
244
+ mutable bool linked = false, applied = false;
245
+
246
+ Data ()
247
+ {
248
+ id = glCreateProgram();
249
+ if (id <= 0)
250
+ opengl_error(__FILE__, __LINE__, "failed to create program.");
251
+ }
252
+
253
+ ~Data ()
254
+ {
255
+ if (id > 0) glDeleteProgram(id);
256
+
257
+ uniform_values.clear();
258
+ uniform_textures.clear();
259
+ }
260
+
261
+ void set_uniform_value (const char* name, const UniformValue* value)
262
+ {
263
+ set_uniform(&uniform_values, name, value);
264
+ }
265
+
266
+ void set_uniform_texture (const char* name, const UniformValue* value)
267
+ {
268
+ if (uniform_textures.size() >= (size_t) get_texture_unit_max())
269
+ opengl_error(__FILE__, __LINE__, "too many texture units.");
270
+
271
+ set_uniform(&uniform_textures, name, value);
272
+ }
273
+
274
+ void set_uniform (
275
+ UniformList* uniforms, const char* name, const UniformValue* value)
276
+ {
277
+ assert(uniforms);
278
+
279
+ auto it = std::find_if(
280
+ uniforms->begin(), uniforms->end(), [&](const Uniform& uniform) {
281
+ return uniform.self->name == name;
282
+ });
283
+
284
+ if (it != uniforms->end())
285
+ it->reset(value);
286
+ else
287
+ uniforms->push_back(Uniform(name, value));
288
+
289
+ applied = false;
290
+ }
291
+
292
+ bool is_valid () const
293
+ {
294
+ return id > 0 && vertex && fragment;
295
+ }
296
+
297
+ void link () const
298
+ {
299
+ if (linked) return;
300
+ linked = true;
301
+
302
+ attach_shader(vertex);
303
+ attach_shader(fragment);
304
+
305
+ glLinkProgram(id);
306
+ OpenGL_check_error(__FILE__, __LINE__);
307
+
308
+ detach_shader(vertex);
309
+ detach_shader(fragment);
310
+
311
+ GLint status = GL_FALSE;
312
+ glGetProgramiv(id, GL_LINK_STATUS, &status);
313
+ if (status == GL_FALSE)
314
+ opengl_error(__FILE__, __LINE__, get_link_log().c_str());
315
+ }
316
+
317
+ void attach_shader (const ShaderSource& source) const
318
+ {
319
+ glAttachShader(id, source.id());
320
+ OpenGL_check_error(__FILE__, __LINE__);
321
+ }
322
+
323
+ void detach_shader (const ShaderSource& source) const
324
+ {
325
+ glDetachShader(id, source.id());
326
+ OpenGL_check_error(__FILE__, __LINE__);
327
+ }
328
+
329
+ String get_link_log () const
330
+ {
331
+ int len = 0;
332
+ glGetProgramiv(id, GL_INFO_LOG_LENGTH, &len);
333
+ if (len <= 0) return "";
334
+
335
+ std::unique_ptr<char[]> buffer(new char[len]);
336
+ int written = 0;
337
+ glGetProgramInfoLog(id, len, &written, &buffer[0]);
338
+ return &buffer[0];
339
+ }
340
+
341
+ void apply_uniforms (const ShaderProgram& program) const
342
+ {
343
+ if (applied) return;
344
+ applied = true;
345
+
346
+ for (const auto& value : uniform_values)
347
+ value.apply(program);
348
+
349
+ int unit = 0;
350
+ for (const auto& texture : uniform_textures)
351
+ {
352
+ glActiveTexture(unit++);
353
+ texture.apply(program);
354
+ }
355
+
356
+ OpenGL_check_error(__FILE__, __LINE__);
357
+ }
358
+
359
+ };// ShaderProgram::Data
360
+
361
+
362
+ void
363
+ ShaderProgram_activate (const ShaderProgram& program)
364
+ {
365
+ ShaderProgram::Data* self = program.self.get();
366
+
367
+ if (!self->is_valid()) return;
368
+
369
+ self->link();
370
+
371
+ glUseProgram(program.id());
372
+ OpenGL_check_error(__FILE__, __LINE__);
373
+
374
+ self->apply_uniforms(program);
375
+ }
376
+
377
+ void
378
+ ShaderProgram_deactivate ()
379
+ {
380
+ glUseProgram(0);
381
+ OpenGL_check_error(__FILE__, __LINE__);
382
+ }
383
+
384
+
385
+ ShaderProgram::ShaderProgram (
386
+ const ShaderSource& vertex, const ShaderSource& fragment)
387
+ {
388
+ self->vertex = vertex;
389
+ self->fragment = fragment;
390
+ }
391
+
392
+ ShaderProgram::~ShaderProgram ()
393
+ {
394
+ }
395
+
396
+ void
397
+ ShaderProgram::set_uniform (const char* name, int arg1)
398
+ {
399
+ self->set_uniform_value(name, new UniformValueT<int, 1>(arg1));
400
+ }
401
+
402
+ void
403
+ ShaderProgram::set_uniform (const char* name, int arg1, int arg2)
404
+ {
405
+ self->set_uniform_value(name, new UniformValueT<int, 2>(arg1, arg2));
406
+ }
407
+
408
+ void
409
+ ShaderProgram::set_uniform (const char* name, int arg1, int arg2, int arg3)
410
+ {
411
+ self->set_uniform_value(name, new UniformValueT<int, 3>(arg1, arg2, arg3));
412
+ }
413
+
414
+ void
415
+ ShaderProgram::set_uniform (
416
+ const char* name, int arg1, int arg2, int arg3, int arg4)
417
+ {
418
+ self->set_uniform_value(
419
+ name, new UniformValueT<int, 4>(arg1, arg2, arg3, arg4));
420
+ }
421
+
422
+ template <typename T>
423
+ static UniformValue*
424
+ create_uniform_value (const T* args, size_t size)
425
+ {
426
+ switch (size)
427
+ {
428
+ case 1: return new UniformValueT<T, 1>(args, 1);
429
+ case 2: return new UniformValueT<T, 2>(args, 2);
430
+ case 3: return new UniformValueT<T, 3>(args, 3);
431
+ case 4: return new UniformValueT<T, 4>(args, 4);
432
+
433
+ default:
434
+ argument_error(__FILE__, __LINE__, "invalid 'size' value.");
435
+ }
436
+
437
+ return NULL;
438
+ }
439
+
440
+ void
441
+ ShaderProgram::set_uniform (const char* name, const int* args, size_t size)
442
+ {
443
+ self->set_uniform_value(name, create_uniform_value(args, size));
444
+ }
445
+
446
+ void
447
+ ShaderProgram::set_uniform (const char* name, float arg1)
448
+ {
449
+ self->set_uniform_value(name, new UniformValueT<float, 1>(arg1));
450
+ }
451
+
452
+ void
453
+ ShaderProgram::set_uniform (const char* name, float arg1, float arg2)
454
+ {
455
+ self->set_uniform_value(name, new UniformValueT<float, 2>(arg1, arg2));
456
+ }
457
+
458
+ void
459
+ ShaderProgram::set_uniform (const char* name, float arg1, float arg2, float arg3)
460
+ {
461
+ self->set_uniform_value(
462
+ name, new UniformValueT<float, 3>(arg1, arg2, arg3));
463
+ }
464
+
465
+ void
466
+ ShaderProgram::set_uniform (
467
+ const char* name, float arg1, float arg2, float arg3, float arg4)
468
+ {
469
+ self->set_uniform_value(
470
+ name, new UniformValueT<float, 4>(arg1, arg2, arg3, arg4));
471
+ }
472
+
473
+ void
474
+ ShaderProgram::set_uniform (const char* name, const float* args, size_t size)
475
+ {
476
+ self->set_uniform_value(name, create_uniform_value(args, size));
477
+ }
478
+
479
+ void
480
+ ShaderProgram::set_uniform (const char* name, const Coord2& vec2)
481
+ {
482
+ self->set_uniform_value(name, new UniformValueT<float, 2>(vec2.array, 2));
483
+ }
484
+
485
+ void
486
+ ShaderProgram::set_uniform (const char* name, const Coord3& vec3)
487
+ {
488
+ self->set_uniform_value(name, new UniformValueT<float, 3>(vec3.array, 3));
489
+ }
490
+
491
+ void
492
+ ShaderProgram::set_uniform (const char* name, const Coord4& vec4)
493
+ {
494
+ self->set_uniform_value(name, new UniformValueT<float, 4>(vec4.array, 4));
495
+ }
496
+
497
+ void
498
+ ShaderProgram::set_uniform (const char* name, const Texture& texture)
499
+ {
500
+ self->set_uniform_texture(name, new UniformTexture(texture));
501
+ }
502
+
503
+ GLuint
504
+ ShaderProgram::id () const
505
+ {
506
+ return self->id;
507
+ }
508
+
509
+ ShaderProgram::operator bool () const
510
+ {
511
+ return self->is_valid();
512
+ }
513
+
514
+ bool
515
+ ShaderProgram::operator ! () const
516
+ {
517
+ return !operator bool();
518
+ }
519
+
520
+ bool
521
+ operator == (const ShaderProgram& lhs, const ShaderProgram& rhs)
522
+ {
523
+ return (!lhs && !rhs) || lhs.self->id == rhs.self->id;
524
+ }
525
+
526
+ bool
527
+ operator != (const ShaderProgram& lhs, const ShaderProgram& rhs)
528
+ {
529
+ return !operator==(lhs, rhs);
530
+ }
531
+
532
+
533
+ }// Rays