rays 0.1.27 → 0.1.29

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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.doc/ext/rays/exception.cpp +45 -0
  3. data/.doc/ext/rays/native.cpp +2 -0
  4. data/.doc/ext/rays/painter.cpp +7 -2
  5. data/.doc/ext/rays/shader.cpp +100 -6
  6. data/VERSION +1 -1
  7. data/ext/rays/defs.h +1 -0
  8. data/ext/rays/exception.cpp +45 -0
  9. data/ext/rays/native.cpp +2 -0
  10. data/ext/rays/painter.cpp +7 -2
  11. data/ext/rays/shader.cpp +101 -5
  12. data/include/rays/exception.h +11 -0
  13. data/include/rays/ruby/bitmap.h +0 -1
  14. data/include/rays/ruby/bounds.h +0 -2
  15. data/include/rays/ruby/camera.h +0 -1
  16. data/include/rays/ruby/color.h +0 -2
  17. data/include/rays/ruby/color_space.h +0 -1
  18. data/include/rays/ruby/defs.h +30 -0
  19. data/include/rays/ruby/exception.h +28 -0
  20. data/include/rays/ruby/font.h +0 -1
  21. data/include/rays/ruby/image.h +0 -1
  22. data/include/rays/ruby/matrix.h +0 -1
  23. data/include/rays/ruby/painter.h +0 -1
  24. data/include/rays/ruby/point.h +0 -2
  25. data/include/rays/ruby/polygon.h +0 -1
  26. data/include/rays/ruby/polyline.h +0 -1
  27. data/include/rays/ruby/rays.h +0 -1
  28. data/include/rays/ruby/shader.h +0 -1
  29. data/include/rays/ruby.h +2 -0
  30. data/include/rays/shader.h +48 -1
  31. data/lib/rays/painter.rb +6 -5
  32. data/lib/rays/point.rb +1 -0
  33. data/lib/rays/shader.rb +18 -5
  34. data/rays.gemspec +2 -2
  35. data/src/exception.cpp +13 -0
  36. data/src/image.cpp +6 -4
  37. data/src/ios/bitmap.mm +18 -1
  38. data/src/opengl.cpp +21 -7
  39. data/src/opengl.h +5 -3
  40. data/src/osx/bitmap.mm +18 -1
  41. data/src/osx/font.mm +0 -2
  42. data/src/osx/opengl.mm +17 -2
  43. data/src/painter.cpp +196 -125
  44. data/src/shader.cpp +333 -53
  45. data/src/shader.h +53 -14
  46. data/src/shader_program.cpp +53 -27
  47. data/src/shader_program.h +8 -1
  48. data/src/shader_source.cpp +2 -2
  49. data/src/texture.cpp +75 -63
  50. data/test/test_image.rb +45 -10
  51. data/test/test_painter.rb +26 -4
  52. data/test/test_point.rb +6 -5
  53. data/test/test_rays.rb +2 -2
  54. data/test/test_shader.rb +151 -14
  55. metadata +11 -6
@@ -42,7 +42,7 @@ namespace Rays
42
42
  GLint status = GL_FALSE;
43
43
  glGetShaderiv(id, GL_COMPILE_STATUS, &status);
44
44
  if (status == GL_FALSE)
45
- opengl_error(__FILE__, __LINE__, get_compile_log().c_str());
45
+ shader_error(__FILE__, __LINE__, get_compile_log().c_str());
46
46
 
47
47
  type = type_;
48
48
  source = source_;
@@ -98,7 +98,7 @@ namespace Rays
98
98
  const char*
99
99
  ShaderSource::source () const
100
100
  {
101
- return self->source;
101
+ return self->is_valid() ? self->source.c_str() : NULL;
102
102
  }
103
103
 
104
104
  GLenum
data/src/texture.cpp CHANGED
@@ -82,38 +82,6 @@ namespace Rays
82
82
  return n;
83
83
  }
84
84
 
85
- static void
86
- setup_texture (Texture::Data* self, const void* pixels = NULL)
87
- {
88
- assert(self && !self->has_id());
89
-
90
- if (self->context)
91
- invalid_state_error(__FILE__, __LINE__);
92
-
93
- self->context = OpenGL_get_context();
94
- if (!self->context)
95
- opengl_error(__FILE__, __LINE__);
96
-
97
- glGenTextures(1, &self->id);
98
- glBindTexture(GL_TEXTURE_2D, self->id);
99
- if (glIsTexture(self->id) == GL_FALSE)
100
- opengl_error(__FILE__, __LINE__, "failed to create texture.");
101
-
102
- //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
103
- //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
104
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
105
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);//GL_LINEAR);
106
-
107
- GLenum format, type;
108
- ColorSpace_get_gl_format_and_type(&format, &type, self->color_space);
109
-
110
- glTexImage2D(
111
- GL_TEXTURE_2D, 0, format, self->width_pow2, self->height_pow2, 0,
112
- format, type, pixels);
113
-
114
- OpenGL_check_error(__FILE__, __LINE__);
115
- }
116
-
117
85
  template <int BytesPerPixel>
118
86
  static inline void
119
87
  copy_pixel (uchar* dest, const uchar* src)
@@ -179,7 +147,9 @@ namespace Rays
179
147
  static void
180
148
  copy_bitmap (Bitmap* dest, const Bitmap& src)
181
149
  {
182
- if (!dest || !src)
150
+ assert(dest);
151
+
152
+ if (!src)
183
153
  argument_error(__FILE__, __LINE__);
184
154
 
185
155
  int width = std::min(src.width(), dest->width());
@@ -196,51 +166,91 @@ namespace Rays
196
166
  }
197
167
  }
198
168
 
199
-
200
- Texture::Texture ()
169
+ static std::shared_ptr<Bitmap>
170
+ resize_bitmap (const Bitmap& bitmap, int width, int height)
201
171
  {
172
+ std::shared_ptr<Bitmap> bmp(
173
+ new Bitmap(width, height, bitmap.color_space()));
174
+ if (!*bmp)
175
+ rays_error(__FILE__, __LINE__);
176
+
177
+ copy_bitmap(bmp.get(), bitmap);
178
+ return bmp;
202
179
  }
203
180
 
204
- Texture::Texture (int width, int height, const ColorSpace& cs)
181
+ static void
182
+ setup_texture (
183
+ Texture::Data* self, int width, int height, const ColorSpace& cs,
184
+ const Bitmap* bitmap = NULL)
205
185
  {
206
- if (width <= 0 || height <= 0 || !cs)
207
- argument_error(__FILE__, __LINE__);
186
+ assert(self && !self->has_id());
187
+
188
+ if (self->context)
189
+ invalid_state_error(__FILE__, __LINE__);
190
+
191
+ self->context = OpenGL_get_context();
192
+ if (!self->context)
193
+ opengl_error(__FILE__, __LINE__);
194
+
195
+ glGenTextures(1, &self->id);
196
+ glBindTexture(GL_TEXTURE_2D, self->id);
197
+ if (glIsTexture(self->id) == GL_FALSE)
198
+ opengl_error(__FILE__, __LINE__, "failed to create texture.");
199
+
200
+ //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
201
+ //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
202
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
203
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);//GL_LINEAR);
204
+
205
+ GLenum format, type;
206
+ ColorSpace_get_gl_format_and_type(&format, &type, cs);
207
+
208
+ // create non-power-of-two texture
209
+ glTexImage2D(
210
+ GL_TEXTURE_2D, 0, format, width, height, 0, format, type,
211
+ bitmap ? bitmap->pixels() : NULL);
212
+ if (OpenGL_has_error())
213
+ {
214
+ // create power-of-two texture
215
+ int width_pow2 = min_pow2(width);
216
+ int height_pow2 = min_pow2(height);
217
+
218
+ glTexImage2D(
219
+ GL_TEXTURE_2D, 0, format, width_pow2, height_pow2, 0, format, type,
220
+ bitmap ? resize_bitmap(*bitmap, width_pow2, height_pow2)->pixels() : NULL);
221
+ OpenGL_check_error(__FILE__, __LINE__);
222
+
223
+ self->width_pow2 = width_pow2;
224
+ self->height_pow2 = height_pow2;
225
+ }
208
226
 
209
227
  self->width = width;
210
228
  self->height = height;
211
- self->width_pow2 = min_pow2(width);
212
- self->height_pow2 = min_pow2(height);
213
229
  self->color_space = cs;
214
230
  self->modified = true;
231
+ }
215
232
 
216
- setup_texture(self.get());
233
+
234
+ Texture::Texture ()
235
+ {
217
236
  }
218
237
 
219
- Texture::Texture (const Bitmap& bitmap)
238
+ Texture::Texture (int width, int height, const ColorSpace& cs)
220
239
  {
221
- if (!bitmap)
240
+ if (width <= 0 || height <= 0 || !cs)
222
241
  argument_error(__FILE__, __LINE__);
223
242
 
224
- self->width = bitmap.width();
225
- self->height = bitmap.height();
226
- self->width_pow2 = min_pow2(self->width);
227
- self->height_pow2 = min_pow2(self->height);
228
- self->color_space = bitmap.color_space();
229
- self->modified = true;
230
-
231
- Bitmap bmp = bitmap;
232
- if (
233
- self->width_pow2 != self->width ||
234
- self->height_pow2 != self->height)
235
- {
236
- bmp = Bitmap(self->width_pow2, self->height_pow2, self->color_space);
237
- if (!bmp)
238
- rays_error(__FILE__, __LINE__);
243
+ setup_texture(self.get(), width, height, cs);
244
+ }
239
245
 
240
- copy_bitmap(&bmp, bitmap);
241
- }
246
+ Texture::Texture (const Bitmap& bitmap)
247
+ {
248
+ if (!bitmap)
249
+ argument_error(__FILE__, __LINE__);
242
250
 
243
- setup_texture(self.get(), bmp.pixels());
251
+ setup_texture(
252
+ self.get(), bitmap.width(), bitmap.height(), bitmap.color_space(),
253
+ &bitmap);
244
254
  }
245
255
 
246
256
  Texture::~Texture ()
@@ -256,7 +266,8 @@ namespace Rays
256
266
  int
257
267
  Texture::reserved_width () const
258
268
  {
259
- return self->width_pow2;
269
+ int w = self->width_pow2;
270
+ return w > 0 ? w : self->width;
260
271
  }
261
272
 
262
273
  int
@@ -268,7 +279,8 @@ namespace Rays
268
279
  int
269
280
  Texture::reserved_height () const
270
281
  {
271
- return self->height_pow2;
282
+ int h = self->height_pow2;
283
+ return h > 0 ? h : self->height;
272
284
  }
273
285
 
274
286
  const ColorSpace&
data/test/test_image.rb CHANGED
@@ -6,11 +6,12 @@ require_relative 'helper'
6
6
 
7
7
  class TestImage < Test::Unit::TestCase
8
8
 
9
- W = 10
10
- H = 10
9
+ def image(*args)
10
+ Rays::Image.new(*args)
11
+ end
11
12
 
12
- def image(w = W, h = H, *args)
13
- Rays::Image.new w, h, *args
13
+ def load(path)
14
+ Rays::Image.load path
14
15
  end
15
16
 
16
17
  def color(r = 0, g = 0, b = 0, a = 0)
@@ -22,12 +23,12 @@ class TestImage < Test::Unit::TestCase
22
23
  end
23
24
 
24
25
  def test_initialize()
25
- assert_equal W, image.width
26
- assert_equal H, image.height
26
+ assert_equal 10, image(10, 20).width
27
+ assert_equal 10, image(20, 10).height
27
28
  end
28
29
 
29
30
  def test_dup()
30
- o = image
31
+ o = image 10, 10
31
32
  assert_equal color(0, 0, 0, 0), o[0, 0]
32
33
  o[0, 0] = color(1, 0, 0, 0)
33
34
  assert_equal color(1, 0, 0, 0), o[0, 0]
@@ -39,12 +40,12 @@ class TestImage < Test::Unit::TestCase
39
40
  end
40
41
 
41
42
  def test_bitmap()
42
- assert_equal W, image.bitmap.width
43
- assert_equal H, image.bitmap.height
43
+ assert_equal 10, image(10, 20).bitmap.width
44
+ assert_equal 10, image(20, 10).bitmap.height
44
45
  end
45
46
 
46
47
  def test_painter()
47
- pa = image.painter
48
+ pa = image(10, 10).painter
48
49
  assert_equal color(0, 0, 0, 0), pa.background
49
50
  assert_equal color(1, 1, 1, 1), pa.fill
50
51
  assert_equal color(1, 1, 1, 0), pa.stroke
@@ -73,4 +74,38 @@ class TestImage < Test::Unit::TestCase
73
74
  assert drawn {|p| p.text "a"}
74
75
  end
75
76
 
77
+ def test_save_load()
78
+ def get_image_type(filename)
79
+ `file #{filename}`.match(/#{filename}: ([^,]+),/)[1]
80
+ end
81
+
82
+ img = image(10, 10).paint {fill 1, 0, 0; ellipse 0, 0, 10}
83
+ pixels = img.bitmap.to_a
84
+ paths = %w[png jpg jpeg gif bmp tif tiff].map {|ext| "#{__dir__}/testimage.#{ext}"}
85
+
86
+ png, jpg, jpeg, gif, bmp, tif, tiff = paths
87
+
88
+ paths.each {|path| img.save path}
89
+
90
+ assert_equal 'PNG image data', get_image_type(png)
91
+ assert_equal 'JPEG image data', get_image_type(jpg)
92
+ assert_equal 'JPEG image data', get_image_type(jpeg)
93
+ assert_equal 'GIF image data', get_image_type(gif)
94
+ assert_equal 'PC bitmap', get_image_type(bmp)
95
+ assert_equal 'TIFF image data', get_image_type(tif)
96
+ assert_equal 'TIFF image data', get_image_type(tiff)
97
+
98
+ assert_equal pixels, load(png) .then {|o| o.bitmap.to_a}
99
+ assert_equal [10, 10], load(jpg) .then {|o| [o.width, o.height]}
100
+ assert_equal [10, 10], load(jpeg).then {|o| [o.width, o.height]}
101
+ assert_equal pixels, load(gif) .then {|o| o.bitmap.to_a}
102
+ assert_equal [10, 10], load(bmp) .then {|o| [o.width, o.height]}
103
+ assert_equal pixels, load(tif) .then {|o| o.bitmap.to_a}
104
+ assert_equal pixels, load(tiff).then {|o| o.bitmap.to_a}
105
+
106
+ paths.each {|path| File.delete path}
107
+
108
+ assert_raise(ArgumentError) {img.save 'testimage.unknown'}
109
+ end
110
+
76
111
  end# TestImage
data/test/test_painter.rb CHANGED
@@ -19,18 +19,24 @@ class TestPainter < Test::Unit::TestCase
19
19
  end
20
20
 
21
21
  def image(w = 16, h = 16, bg: 0, &block)
22
- Rays::Image.new(w, h).paint {background bg}.paint(&block)
22
+ Rays::Image.new(w, h)
23
+ .paint {background bg}
24
+ .tap {|img| img.paint(&block) if block}
25
+ end
26
+
27
+ def assert_gray(expected, actual)
28
+ assert_in_epsilon expected, actual, 0.02
23
29
  end
24
30
 
25
31
  def assert_rgb(expected, actual)
26
32
  (0..2).each do |i|
27
- assert_in_epsilon expected[i], actual[i], 0.02
33
+ assert_gray expected[i], actual[i]
28
34
  end
29
35
  end
30
36
 
31
37
  def assert_rgba(expected, actual)
32
38
  (0..3).each do |i|
33
- assert_in_epsilon expected[i], actual[i], 0.02
39
+ assert_gray expected[i], actual[i]
34
40
  end
35
41
  end
36
42
 
@@ -369,7 +375,23 @@ class TestPainter < Test::Unit::TestCase
369
375
  end
370
376
 
371
377
  def test_shader()
372
- img = Rays::Image.new(10, 10).paint {
378
+ image.paint do |pa|
379
+ assert_nil pa.shader
380
+
381
+ pa.shader = Rays::Shader.new "void main() {gl_FragColor = vec4(0.0);}"
382
+ assert_instance_of Rays::Shader, pa.shader
383
+
384
+ pa.shader = nil
385
+ assert_nil pa.shader
386
+
387
+ pa.shader = "void main() {gl_FragColor = vec4(0.0);}"
388
+ assert_instance_of Rays::Shader, pa.shader
389
+
390
+ pa.no_shader
391
+ assert_nil pa.shader
392
+ end
393
+
394
+ img = image.paint {
373
395
  shader "void main() {gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);}"
374
396
  fill 1, 0, 0
375
397
  rect bounds
data/test/test_point.rb CHANGED
@@ -112,13 +112,14 @@ class TestPoint < Test::Unit::TestCase
112
112
 
113
113
  def test_to_a()
114
114
  o = point 1, 2, 3
115
- assert_equal [1, 2], o.to_a
116
- assert_equal [1], o.to_a(1)
117
- assert_equal [1, 2], o.to_a(2)
118
- assert_equal [1, 2, 3], o.to_a(3)
115
+ assert_equal [1, 2], o.to_a
116
+ assert_equal [1], o.to_a(1)
117
+ assert_equal [1, 2], o.to_a(2)
118
+ assert_equal [1, 2, 3], o.to_a(3)
119
+ assert_equal [1, 2, 3, 1], o.to_a(4)
119
120
  assert_raise(ArgumentError) {o.to_a(-1)}
120
121
  assert_raise(ArgumentError) {o.to_a(0)}
121
- assert_raise(ArgumentError) {o.to_a(4)}
122
+ assert_raise(ArgumentError) {o.to_a(5)}
122
123
  end
123
124
 
124
125
  def test_index()
data/test/test_rays.rb CHANGED
@@ -9,9 +9,9 @@ require_relative 'helper'
9
9
  class TestRays < Test::Unit::TestCase
10
10
 
11
11
  def test_init!()
12
- assert_raise(Rucy::NativeError) {Rays.fin!}
12
+ assert_raise(Rays::RaysError) {Rays.fin!}
13
13
  assert Rays.init!
14
- assert_raise(Rucy::NativeError) {Rays.init!}
14
+ assert_raise(Rays::RaysError) {Rays.init!}
15
15
  assert Rays.fin!
16
16
  end
17
17
 
data/test/test_shader.rb CHANGED
@@ -6,32 +6,169 @@ require_relative 'helper'
6
6
 
7
7
  class TestShader < Test::Unit::TestCase
8
8
 
9
- def shader(src)
10
- Rays::Shader.new src
9
+ def shader(*a, **k)
10
+ Rays::Shader.new(*a, **k)
11
11
  end
12
12
 
13
- def img(w = 10, h = 10, &block)
14
- Rays::Image.new w, h
13
+ def image(w = 10, h = 10, &block)
14
+ Rays::Image.new(w, h).tap {|i| i.paint(&block) if block}
15
15
  end
16
16
 
17
17
  def color(*args)
18
18
  Rays::Color.new(*args)
19
19
  end
20
20
 
21
+ def vshader()
22
+ "void main() {gl_Position = vec4(0.0, 0.0, 0.0, 1.0);}"
23
+ end
24
+
25
+ def fshader()
26
+ "void main() {gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}"
27
+ end
28
+
29
+ def draw_shader(
30
+ fragment_shader_source, fill: 1, options: {}, uniforms: {}, &block)
31
+
32
+ image.tap do |img|
33
+ img.paint do |p|
34
+ p.shader shader(fragment_shader_source, **options.merge(uniforms))
35
+ block.call p.shader if block
36
+ p.fill(*fill)
37
+ p.stroke nil
38
+ p.rect img.bounds.move_to(0, 0)
39
+ end
40
+ end
41
+ end
42
+
21
43
  def test_initialize()
22
- assert_raise(Rucy::NativeError) {shader "foo"}
23
- assert_raise(ArgumentError) {shader}
24
- #assert_raise(TypeError) {shader nil}
25
- assert shader("void main() {gl_FragColor = vec4(1, 0, 0, 1);}")
44
+ assert shader(fshader)
45
+ assert shader(fshader, vshader)
46
+
47
+ assert_raise(Rays::ShaderError) {shader "foo"}
48
+ assert_raise(Rays::ShaderError) {shader "foo", vshader}
49
+ assert_raise(Rays::ShaderError) {shader fshader, "foo"}
50
+ assert_raise(Rays::ShaderError) {shader vshader}
51
+ assert_raise(Rays::ShaderError) {shader fshader, fshader}
52
+ assert_raise(ArgumentError) {shader nil}
26
53
  end
27
54
 
28
55
  def test_shader()
29
- i = img.paint do
30
- shader "void main () {gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}"
31
- fill 0, 1, 0, 1
32
- rect(*bounds.move_to(0, 0).to_a)
33
- end
34
- assert_equal color(1, 0, 0, 1), i[0, 0]
56
+ assert_equal color(1, 0, 0, 1), draw_shader(<<~END, fill: [0, 1, 0, 1])[0, 0]
57
+ void main() {gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}
58
+ END
59
+ end
60
+
61
+ def test_uniform_int()
62
+ draw = -> (type, color_string, &b) {
63
+ draw_shader(<<~END) {|shader| b.call shader}[0, 0].to_a
64
+ uniform #{type} v;
65
+ float f(int value, int div) {
66
+ return float(value) / float(div);
67
+ }
68
+ void main() {
69
+ gl_FragColor = vec4(#{color_string});
70
+ }
71
+ END
72
+ }
73
+ assert_equal [1, 0, 0, 1], draw['int', 'f(v, 1), 0.0, 0.0, 1.0'] {|sh| sh.uniform :v, 1}
74
+ assert_equal [1, 0, 0, 1], draw['int', 'f(v, 1), 0.0, 0.0, 1.0'] {|sh| sh.uniform :v, [1]}
75
+ assert_equal [1, 1, 0, 1], draw['ivec2', 'f(v.x, 1), f(v.y, 2), 0.0, 1.0'] {|sh| sh.uniform :v, 1, 2}
76
+ assert_equal [1, 1, 0, 1], draw['ivec2', 'f(v.x, 1), f(v.y, 2), 0.0, 1.0'] {|sh| sh.uniform :v, [1, 2]}
77
+ assert_equal [1, 1, 1, 1], draw['ivec3', 'f(v.x, 1), f(v.y, 2), f(v.z, 3), 1.0'] {|sh| sh.uniform :v, 1, 2, 3}
78
+ assert_equal [1, 1, 1, 1], draw['ivec3', 'f(v.x, 1), f(v.y, 2), f(v.z, 3), 1.0'] {|sh| sh.uniform :v, [1, 2, 3]}
79
+ assert_equal [1, 1, 1, 1], draw['ivec4', 'f(v.x, 1), f(v.y, 2), f(v.z, 3), f(v.w, 4)'] {|sh| sh.uniform :v, 1, 2, 3, 4}
80
+ assert_equal [1, 1, 1, 1], draw['ivec4', 'f(v.x, 1), f(v.y, 2), f(v.z, 3), f(v.w, 4)'] {|sh| sh.uniform :v, [1, 2, 3, 4]}
81
+ end
82
+
83
+ def test_uniform_float()
84
+ draw = -> (type, color_string, &b) {
85
+ draw_shader(<<~END) {|shader| b.call shader}[0, 0].to_a
86
+ uniform #{type} v;
87
+ float f(float value, int div) {
88
+ return value / float(div);
89
+ }
90
+ void main() {
91
+ gl_FragColor = vec4(#{color_string});
92
+ }
93
+ END
94
+ }
95
+ assert_equal [1, 0, 0, 1], draw['float', 'f(v, 1), 0.0, 0.0, 1.0'] {|sh| sh.uniform :v, 1.0}
96
+ assert_equal [1, 0, 0, 1], draw['float', 'f(v, 1), 0.0, 0.0, 1.0'] {|sh| sh.uniform :v, [1.0]}
97
+ assert_equal [1, 1, 0, 1], draw['vec2', 'f(v.x, 1), f(v.y, 2), 0.0, 1.0'] {|sh| sh.uniform :v, 1.0, 2.0}
98
+ assert_equal [1, 1, 0, 1], draw['vec2', 'f(v.x, 1), f(v.y, 2), 0.0, 1.0'] {|sh| sh.uniform :v, [1.0, 2.0]}
99
+ assert_equal [1, 1, 1, 1], draw['vec3', 'f(v.x, 1), f(v.y, 2), f(v.z, 3), 1.0'] {|sh| sh.uniform :v, 1.0, 2.0, 3.0}
100
+ assert_equal [1, 1, 1, 1], draw['vec3', 'f(v.x, 1), f(v.y, 2), f(v.z, 3), 1.0'] {|sh| sh.uniform :v, [1.0, 2.0, 3.0]}
101
+ assert_equal [1, 1, 1, 1], draw['vec4', 'f(v.x, 1), f(v.y, 2), f(v.z, 3), f(v.w, 4)'] {|sh| sh.uniform :v, 1.0, 2.0, 3.0, 4.0}
102
+ assert_equal [1, 1, 1, 1], draw['vec4', 'f(v.x, 1), f(v.y, 2), f(v.z, 3), f(v.w, 4)'] {|sh| sh.uniform :v, [1.0, 2.0, 3.0, 4.0]}
103
+ end
104
+
105
+ def test_uniform_texture()
106
+ r, g, b = [[1, 0, 0], [0, 1, 0], [0, 0, 1]].map {|c| image {fill c; rect 10}}
107
+ assert_equal color(1, 1, 1, 1), draw_shader(<<~END, uniforms: {tex0: r, tex1: g, tex2: b})[0, 0]
108
+ uniform sampler2D tex0, tex1, tex2;
109
+ varying vec4 v_TexCoord;
110
+ void main() {
111
+ gl_FragColor = vec4(
112
+ texture2D(tex0, v_TexCoord.xy).r,
113
+ texture2D(tex1, v_TexCoord.xy).g,
114
+ texture2D(tex2, v_TexCoord.xy).b,
115
+ 1.0);
116
+ }
117
+ END
118
+ end
119
+
120
+ def test_uniform_error()
121
+ ignore = -> bool {{ignore_no_uniform_location_error: bool}}
122
+
123
+ assert_raise(Rays::ShaderError) {draw_shader 'void main() {}', uniforms: {val: 1.0}}
124
+ assert_raise(Rays::ShaderError) {draw_shader 'void main() {}', options: ignore[false], uniforms: {val: 1.0}}
125
+ assert_nothing_raised {draw_shader 'void main() {}', options: ignore[true], uniforms: {val: 1.0}}
126
+ end
127
+
128
+ def test_shader_source()
129
+ assert_equal vshader, shader(fshader, vshader).vertex_shader_source
130
+ assert_equal fshader, shader(fshader, vshader).fragment_shader_source
131
+
132
+ assert_true shader(fshader).vertex_shader_source.then {|source|
133
+ %w[
134
+ a_Position a_TexCoord a_Color
135
+ v_Position v_TexCoord v_Color
136
+ u_PositionMatrix u_TexCoordMatrix
137
+ ].all? {|name| source.include? name}
138
+ }
139
+ end
140
+
141
+ def test_shader_env()
142
+ env = {
143
+ attribute_position: 'aP',
144
+ attribute_texcoord: ['aTC', 'aTC2'],
145
+ attribute_color: [],
146
+ varying_position: 'vP',
147
+ varying_texcoord: nil,
148
+ #varying_color: define nothing
149
+ uniform_position_matrix: nil,
150
+ #uniform_texcoord_matrix: define nothing
151
+ }
152
+ assert_true shader(fshader, nil, env).vertex_shader_source.then {|source|
153
+ %w[
154
+ aP
155
+ aTC
156
+ a_Color
157
+ vP
158
+ v_TexCoord
159
+ v_Color
160
+ u_PositionMatrix
161
+ u_TexCoordMatrix
162
+ ].all? {|name| source.include? name}
163
+ }
164
+
165
+ assert_raise(ArgumentError) {shader(fshader, nil, {attribute_color: ''})}
166
+ assert_raise(ArgumentError) {shader(fshader, nil, {attribute_color: ['']})}
167
+ assert_raise(ArgumentError) {shader(fshader, nil, {attribute_color: [nil]})}
168
+ assert_raise(ArgumentError) {shader(fshader, nil, {attribute_color: ['C', '']})}
169
+ assert_raise(ArgumentError) {shader(fshader, nil, {attribute_color: ['C', nil]})}
170
+
171
+ assert_raise(ArgumentError) {shader(fshader, nil, {varying_color: ''})}
35
172
  end
36
173
 
37
174
  end# TestShader
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rays
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.27
4
+ version: 0.1.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - xordog
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-29 00:00:00.000000000 Z
11
+ date: 2022-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: xot
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.27
19
+ version: 0.1.29
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.27
26
+ version: 0.1.29
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rucy
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.1.27
33
+ version: 0.1.29
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.1.27
40
+ version: 0.1.29
41
41
  description: This library helps you to develop graphics application with OpenGL.
42
42
  email: xordog@gmail.com
43
43
  executables: []
@@ -50,6 +50,7 @@ extra_rdoc_files:
50
50
  - ".doc/ext/rays/color.cpp"
51
51
  - ".doc/ext/rays/color_space.cpp"
52
52
  - ".doc/ext/rays/defs.cpp"
53
+ - ".doc/ext/rays/exception.cpp"
53
54
  - ".doc/ext/rays/font.cpp"
54
55
  - ".doc/ext/rays/image.cpp"
55
56
  - ".doc/ext/rays/matrix.cpp"
@@ -69,6 +70,7 @@ files:
69
70
  - ".doc/ext/rays/color.cpp"
70
71
  - ".doc/ext/rays/color_space.cpp"
71
72
  - ".doc/ext/rays/defs.cpp"
73
+ - ".doc/ext/rays/exception.cpp"
72
74
  - ".doc/ext/rays/font.cpp"
73
75
  - ".doc/ext/rays/image.cpp"
74
76
  - ".doc/ext/rays/matrix.cpp"
@@ -92,6 +94,7 @@ files:
92
94
  - ext/rays/color_space.cpp
93
95
  - ext/rays/defs.cpp
94
96
  - ext/rays/defs.h
97
+ - ext/rays/exception.cpp
95
98
  - ext/rays/extconf.rb
96
99
  - ext/rays/font.cpp
97
100
  - ext/rays/image.cpp
@@ -131,6 +134,8 @@ files:
131
134
  - include/rays/ruby/camera.h
132
135
  - include/rays/ruby/color.h
133
136
  - include/rays/ruby/color_space.h
137
+ - include/rays/ruby/defs.h
138
+ - include/rays/ruby/exception.h
134
139
  - include/rays/ruby/font.h
135
140
  - include/rays/ruby/image.h
136
141
  - include/rays/ruby/matrix.h