rays 0.1.25 → 0.1.26

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6f7cc20d72750eb7d8ff9364831172720065e9f0339f0f865760c56b31e515b
4
- data.tar.gz: dd31681766629607b2fa461ae12d6904d325c0b8babba803faaf0443b0472242
3
+ metadata.gz: f3672dd115183ebe4f339772f73bdce3e2997f77947e9352c3353a86ad547fa1
4
+ data.tar.gz: d0cb5875466280ef040c8fd64ecd0c1a7250e4a08a85afca847e0e07a2fdc050
5
5
  SHA512:
6
- metadata.gz: f72e8c4cf249c3c7646a8d627e941dca67e7ac29a35d907e0c9ceac7522e3cdfd0df45e9eec8253a92fb70f031d53b5660eab594e50adfe6b8d12e4cb56b9a4e
7
- data.tar.gz: e7f4017fd414def3b492173e6a61f53a9fc2fef18dbe409eb7be6e27840ecbe2a26af60f62d7d507dc6ba12bd740e7606da2871ea218db1e5e5b116a242f8a84
6
+ metadata.gz: 520908776f4610aab3af58c5d3fff9c2b9c8c27dfdb4b27d2116cdf7b49d5e2086403906e714ca2e4eefe30505ba52e76ce6d9a8475a6030a77431885c409d80
7
+ data.tar.gz: 0a54cd72a30dfb6931ab356f064f5da58f99f3adb1d42d7b490c70a460ca0b5bb47b2848ee84b2e8c844e1c65f4563de601e5138aa39e8ec4d60578f7957ce06
@@ -26,15 +26,51 @@ VALUE alloc(VALUE klass)
26
26
  }
27
27
 
28
28
  static
29
- VALUE canvas(VALUE self, VALUE x, VALUE y, VALUE width, VALUE height)
29
+ VALUE canvas(VALUE self)
30
30
  {
31
31
  CHECK;
32
+ check_arg_count(__FILE__, __LINE__, "Painter#canvas", argc, 4, 5, 6, 7);
32
33
 
33
- coord xx = to<coord>(x);
34
- coord yy = to<coord>(y);
35
- coord ww = to<coord>(width);
36
- coord hh = to<coord>(height);
37
- THIS->canvas(xx, yy, ww, hh);
34
+ switch (argc)
35
+ {
36
+ case 4:
37
+ THIS->canvas(
38
+ to<coord>(argv[0]),
39
+ to<coord>(argv[1]),
40
+ to<coord>(argv[2]),
41
+ to<coord>(argv[3]));
42
+ break;
43
+
44
+ case 5:
45
+ THIS->canvas(
46
+ to<coord>(argv[0]),
47
+ to<coord>(argv[1]),
48
+ to<coord>(argv[2]),
49
+ to<coord>(argv[3]),
50
+ to<float>(argv[4]));
51
+ break;
52
+
53
+ case 6:
54
+ THIS->canvas(
55
+ to<coord>(argv[0]),
56
+ to<coord>(argv[1]),
57
+ to<coord>(argv[2]),
58
+ to<coord>(argv[3]),
59
+ to<coord>(argv[4]),
60
+ to<coord>(argv[5]));
61
+ break;
62
+
63
+ case 7:
64
+ THIS->canvas(
65
+ to<coord>(argv[0]),
66
+ to<coord>(argv[1]),
67
+ to<coord>(argv[2]),
68
+ to<coord>(argv[3]),
69
+ to<coord>(argv[4]),
70
+ to<coord>(argv[5]),
71
+ to<float>(argv[6]));
72
+ break;
73
+ }
38
74
 
39
75
  return self;
40
76
  }
@@ -382,6 +418,21 @@ VALUE get_nsegment(VALUE self)
382
418
  return value(THIS->nsegment());
383
419
  }
384
420
 
421
+ static
422
+ VALUE set_blend_mode(VALUE self, VALUE mode)
423
+ {
424
+ CHECK;
425
+ THIS->set_blend_mode(to<Rays::BlendMode>(mode));
426
+ return self;
427
+ }
428
+
429
+ static
430
+ VALUE get_blend_mode(VALUE self)
431
+ {
432
+ CHECK;
433
+ return value(THIS->blend_mode());
434
+ }
435
+
385
436
  static
386
437
  VALUE set_clip(VALUE self)
387
438
  {
@@ -553,7 +604,7 @@ Init_painter ()
553
604
  cPainter = rb_define_class_under(mRays, "Painter", rb_cObject);
554
605
  rb_define_alloc_func(cPainter, alloc);
555
606
 
556
- rb_define_method(cPainter, "canvas", RUBY_METHOD_FUNC(canvas), 4);
607
+ rb_define_method(cPainter, "canvas", RUBY_METHOD_FUNC(canvas), -1);
557
608
  rb_define_method(cPainter, "bounds", RUBY_METHOD_FUNC(bounds), 0);
558
609
  rb_define_method(cPainter, "pixel_density", RUBY_METHOD_FUNC(pixel_density), 0);
559
610
 
@@ -589,6 +640,8 @@ Init_painter ()
589
640
  rb_define_method(cPainter, "miter_limit", RUBY_METHOD_FUNC(get_miter_limit), 0);
590
641
  rb_define_method(cPainter, "nsegment=", RUBY_METHOD_FUNC(set_nsegment), 1);
591
642
  rb_define_method(cPainter, "nsegment", RUBY_METHOD_FUNC(get_nsegment), 0);
643
+ rb_define_method(cPainter, "blend_mode=", RUBY_METHOD_FUNC(set_blend_mode), 1);
644
+ rb_define_method(cPainter, "blend_mode", RUBY_METHOD_FUNC(get_blend_mode), 0);
592
645
  rb_define_method(cPainter, "clip=", RUBY_METHOD_FUNC(set_clip), -1);
593
646
  rb_define_method(cPainter, "clip", RUBY_METHOD_FUNC(get_clip), 0);
594
647
  rb_define_method(cPainter, "no_clip", RUBY_METHOD_FUNC(no_clip), 0);
@@ -7,6 +7,7 @@
7
7
 
8
8
  RUCY_DEFINE_CONVERT_TO(Rays::CapType)
9
9
  RUCY_DEFINE_CONVERT_TO(Rays::JoinType)
10
+ RUCY_DEFINE_CONVERT_TO(Rays::BlendMode)
10
11
 
11
12
 
12
13
  template <typename T>
@@ -29,6 +30,18 @@ static std::vector<EnumType<Rays::JoinType>> JOIN_TYPES({
29
30
  {"JOIN_SQUARE", "SQUARE", Rays::JOIN_SQUARE},
30
31
  });
31
32
 
33
+ static std::vector<EnumType<Rays::BlendMode>> BLEND_MODES({
34
+ {"BLEND_NORMAL", "NORMAL", Rays::BLEND_NORMAL},
35
+ {"BLEND_ADD", "ADD", Rays::BLEND_ADD},
36
+ {"BLEND_SUBTRACT", "SUBTRACT", Rays::BLEND_SUBTRACT},
37
+ {"BLEND_LIGHTEST", "LIGHTEST", Rays::BLEND_LIGHTEST},
38
+ {"BLEND_DARKEST", "DARKEST", Rays::BLEND_DARKEST},
39
+ {"BLEND_EXCLUSION", "EXCLUSION", Rays::BLEND_EXCLUSION},
40
+ {"BLEND_MULTIPLY", "MULTIPLY", Rays::BLEND_MULTIPLY},
41
+ {"BLEND_SCREEN", "SCREEN", Rays::BLEND_SCREEN},
42
+ {"BLEND_REPLACE", "REPLACE", Rays::BLEND_REPLACE},
43
+ });
44
+
32
45
 
33
46
  static
34
47
  VALUE init(VALUE self)
@@ -60,6 +73,9 @@ Init_rays ()
60
73
 
61
74
  for (auto it = JOIN_TYPES.begin(); it != JOIN_TYPES.end(); ++it)
62
75
  mRays.define_const(it->name, it->type);
76
+
77
+ for (auto it = BLEND_MODES.begin(); it != BLEND_MODES.end(); ++it)
78
+ mRays.define_const(it->name, it->type);
63
79
  }
64
80
 
65
81
 
@@ -129,6 +145,37 @@ namespace Rucy
129
145
  }
130
146
 
131
147
 
148
+ template <> Rays::BlendMode
149
+ value_to<Rays::BlendMode> (int argc, const Value* argv, bool convert)
150
+ {
151
+ assert(argc > 0 && argv);
152
+
153
+ if (convert)
154
+ {
155
+ if (argv->is_s() || argv->is_sym())
156
+ {
157
+ const char* str = argv->c_str();
158
+ for (auto it = BLEND_MODES.begin(); it != BLEND_MODES.end(); ++it)
159
+ {
160
+ if (
161
+ strcasecmp(str, it->name) == 0 ||
162
+ strcasecmp(str, it->short_name) == 0)
163
+ {
164
+ return it->type;
165
+ }
166
+ }
167
+ argument_error(__FILE__, __LINE__, "invalid blend mode -- %s", str);
168
+ }
169
+ }
170
+
171
+ int type = value_to<int>(*argv, convert);
172
+ if (type < 0 || Rays::BLEND_MAX <= type)
173
+ argument_error(__FILE__, __LINE__, "invalid blend mode -- %d", type);
174
+
175
+ return (Rays::BlendMode) type;
176
+ }
177
+
178
+
132
179
  }// Rucy
133
180
 
134
181
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.25
1
+ 0.1.26
data/ext/rays/painter.cpp CHANGED
@@ -27,15 +27,51 @@ RUCY_DEF_ALLOC(alloc, klass)
27
27
  RUCY_END
28
28
 
29
29
  static
30
- RUCY_DEF4(canvas, x, y, width, height)
30
+ RUCY_DEFN(canvas)
31
31
  {
32
32
  CHECK;
33
+ check_arg_count(__FILE__, __LINE__, "Painter#canvas", argc, 4, 5, 6, 7);
33
34
 
34
- coord xx = to<coord>(x);
35
- coord yy = to<coord>(y);
36
- coord ww = to<coord>(width);
37
- coord hh = to<coord>(height);
38
- THIS->canvas(xx, yy, ww, hh);
35
+ switch (argc)
36
+ {
37
+ case 4:
38
+ THIS->canvas(
39
+ to<coord>(argv[0]),
40
+ to<coord>(argv[1]),
41
+ to<coord>(argv[2]),
42
+ to<coord>(argv[3]));
43
+ break;
44
+
45
+ case 5:
46
+ THIS->canvas(
47
+ to<coord>(argv[0]),
48
+ to<coord>(argv[1]),
49
+ to<coord>(argv[2]),
50
+ to<coord>(argv[3]),
51
+ to<float>(argv[4]));
52
+ break;
53
+
54
+ case 6:
55
+ THIS->canvas(
56
+ to<coord>(argv[0]),
57
+ to<coord>(argv[1]),
58
+ to<coord>(argv[2]),
59
+ to<coord>(argv[3]),
60
+ to<coord>(argv[4]),
61
+ to<coord>(argv[5]));
62
+ break;
63
+
64
+ case 7:
65
+ THIS->canvas(
66
+ to<coord>(argv[0]),
67
+ to<coord>(argv[1]),
68
+ to<coord>(argv[2]),
69
+ to<coord>(argv[3]),
70
+ to<coord>(argv[4]),
71
+ to<coord>(argv[5]),
72
+ to<float>(argv[6]));
73
+ break;
74
+ }
39
75
 
40
76
  return self;
41
77
  }
@@ -417,6 +453,23 @@ RUCY_DEF0(get_nsegment)
417
453
  }
418
454
  RUCY_END
419
455
 
456
+ static
457
+ RUCY_DEF1(set_blend_mode, mode)
458
+ {
459
+ CHECK;
460
+ THIS->set_blend_mode(to<Rays::BlendMode>(mode));
461
+ return self;
462
+ }
463
+ RUCY_END
464
+
465
+ static
466
+ RUCY_DEF0(get_blend_mode)
467
+ {
468
+ CHECK;
469
+ return value(THIS->blend_mode());
470
+ }
471
+ RUCY_END
472
+
420
473
  static
421
474
  RUCY_DEFN(set_clip)
422
475
  {
@@ -641,6 +694,8 @@ Init_painter ()
641
694
  cPainter.define_method("miter_limit", get_miter_limit);
642
695
  cPainter.define_method("nsegment=", set_nsegment);
643
696
  cPainter.define_method("nsegment", get_nsegment);
697
+ cPainter.define_method("blend_mode=", set_blend_mode);
698
+ cPainter.define_method("blend_mode", get_blend_mode);
644
699
  cPainter.define_method( "clip=", set_clip);
645
700
  cPainter.define_method( "clip", get_clip);
646
701
  cPainter.define_method("no_clip", no_clip);
data/ext/rays/rays.cpp CHANGED
@@ -7,6 +7,7 @@
7
7
 
8
8
  RUCY_DEFINE_CONVERT_TO(Rays::CapType)
9
9
  RUCY_DEFINE_CONVERT_TO(Rays::JoinType)
10
+ RUCY_DEFINE_CONVERT_TO(Rays::BlendMode)
10
11
 
11
12
 
12
13
  template <typename T>
@@ -29,6 +30,18 @@ static std::vector<EnumType<Rays::JoinType>> JOIN_TYPES({
29
30
  {"JOIN_SQUARE", "SQUARE", Rays::JOIN_SQUARE},
30
31
  });
31
32
 
33
+ static std::vector<EnumType<Rays::BlendMode>> BLEND_MODES({
34
+ {"BLEND_NORMAL", "NORMAL", Rays::BLEND_NORMAL},
35
+ {"BLEND_ADD", "ADD", Rays::BLEND_ADD},
36
+ {"BLEND_SUBTRACT", "SUBTRACT", Rays::BLEND_SUBTRACT},
37
+ {"BLEND_LIGHTEST", "LIGHTEST", Rays::BLEND_LIGHTEST},
38
+ {"BLEND_DARKEST", "DARKEST", Rays::BLEND_DARKEST},
39
+ {"BLEND_EXCLUSION", "EXCLUSION", Rays::BLEND_EXCLUSION},
40
+ {"BLEND_MULTIPLY", "MULTIPLY", Rays::BLEND_MULTIPLY},
41
+ {"BLEND_SCREEN", "SCREEN", Rays::BLEND_SCREEN},
42
+ {"BLEND_REPLACE", "REPLACE", Rays::BLEND_REPLACE},
43
+ });
44
+
32
45
 
33
46
  static
34
47
  RUCY_DEF0(init)
@@ -62,6 +75,9 @@ Init_rays ()
62
75
 
63
76
  for (auto it = JOIN_TYPES.begin(); it != JOIN_TYPES.end(); ++it)
64
77
  mRays.define_const(it->name, it->type);
78
+
79
+ for (auto it = BLEND_MODES.begin(); it != BLEND_MODES.end(); ++it)
80
+ mRays.define_const(it->name, it->type);
65
81
  }
66
82
 
67
83
 
@@ -131,6 +147,37 @@ namespace Rucy
131
147
  }
132
148
 
133
149
 
150
+ template <> Rays::BlendMode
151
+ value_to<Rays::BlendMode> (int argc, const Value* argv, bool convert)
152
+ {
153
+ assert(argc > 0 && argv);
154
+
155
+ if (convert)
156
+ {
157
+ if (argv->is_s() || argv->is_sym())
158
+ {
159
+ const char* str = argv->c_str();
160
+ for (auto it = BLEND_MODES.begin(); it != BLEND_MODES.end(); ++it)
161
+ {
162
+ if (
163
+ strcasecmp(str, it->name) == 0 ||
164
+ strcasecmp(str, it->short_name) == 0)
165
+ {
166
+ return it->type;
167
+ }
168
+ }
169
+ argument_error(__FILE__, __LINE__, "invalid blend mode -- %s", str);
170
+ }
171
+ }
172
+
173
+ int type = value_to<int>(*argv, convert);
174
+ if (type < 0 || Rays::BLEND_MAX <= type)
175
+ argument_error(__FILE__, __LINE__, "invalid blend mode -- %d", type);
176
+
177
+ return (Rays::BlendMode) type;
178
+ }
179
+
180
+
134
181
  }// Rucy
135
182
 
136
183
 
data/include/rays/defs.h CHANGED
@@ -56,6 +56,32 @@ namespace Rays
56
56
  };// JoinType
57
57
 
58
58
 
59
+ enum BlendMode
60
+ {
61
+
62
+ BLEND_NORMAL = 0,
63
+
64
+ BLEND_ADD,
65
+
66
+ BLEND_SUBTRACT,
67
+
68
+ BLEND_LIGHTEST,
69
+
70
+ BLEND_DARKEST,
71
+
72
+ BLEND_EXCLUSION,
73
+
74
+ BLEND_MULTIPLY,
75
+
76
+ BLEND_SCREEN,
77
+
78
+ BLEND_REPLACE,
79
+
80
+ BLEND_MAX
81
+
82
+ };// BlendMode
83
+
84
+
59
85
  }// Rays
60
86
 
61
87
 
@@ -174,7 +174,8 @@ namespace Rays
174
174
  //
175
175
  // states
176
176
  //
177
- void set_background (float red, float green, float blue, float alpha = 1, bool clear = true);
177
+ void set_background (
178
+ float red, float green, float blue, float alpha = 1, bool clear = true);
178
179
 
179
180
  void set_background (const Color& color, bool clear = true);
180
181
 
@@ -218,6 +219,10 @@ namespace Rays
218
219
 
219
220
  uint nsegment () const;
220
221
 
222
+ void set_blend_mode (BlendMode mode);
223
+
224
+ BlendMode blend_mode () const;
225
+
221
226
  void set_clip (coord x, coord y, coord width, coord height);
222
227
 
223
228
  void set_clip (const Bounds& bounds);
@@ -25,5 +25,7 @@ RUCY_DECLARE_CONVERT_TO(Rays::CapType)
25
25
 
26
26
  RUCY_DECLARE_CONVERT_TO(Rays::JoinType)
27
27
 
28
+ RUCY_DECLARE_CONVERT_TO(Rays::BlendMode)
29
+
28
30
 
29
31
  #endif//EOH
data/lib/rays/painter.rb CHANGED
@@ -108,9 +108,21 @@ module Rays
108
108
  square: JOIN_SQUARE
109
109
  }
110
110
 
111
+ const_symbol_accessor :blend_mode, **{
112
+ normal: BLEND_NORMAL,
113
+ add: BLEND_ADD,
114
+ subtract: BLEND_SUBTRACT,
115
+ lightest: BLEND_LIGHTEST,
116
+ darkest: BLEND_DARKEST,
117
+ exclusion: BLEND_EXCLUSION,
118
+ multiply: BLEND_MULTIPLY,
119
+ screen: BLEND_SCREEN,
120
+ replace: BLEND_REPLACE
121
+ }
122
+
111
123
  universal_accessor :background, :fill, :stroke, :color,
112
124
  :stroke_width, :stroke_cap, :stroke_join, :miter_limit,
113
- :nsegment, :shader, :clip, :font
125
+ :nsegment, :blend_mode, :shader, :clip, :font
114
126
 
115
127
  private
116
128
 
data/rays.gemspec CHANGED
@@ -28,8 +28,8 @@ Gem::Specification.new do |s|
28
28
  s.platform = Gem::Platform::RUBY
29
29
  s.required_ruby_version = '>= 2.6.0'
30
30
 
31
- s.add_runtime_dependency 'xot', '~> 0.1.25'
32
- s.add_runtime_dependency 'rucy', '~> 0.1.25'
31
+ s.add_runtime_dependency 'xot', '~> 0.1.26'
32
+ s.add_runtime_dependency 'rucy', '~> 0.1.26'
33
33
 
34
34
  s.files = `git ls-files`.split $/
35
35
  s.executables = s.files.grep(%r{^bin/}) {|f| File.basename f}
data/src/frame_buffer.cpp CHANGED
@@ -110,7 +110,7 @@ namespace Rays
110
110
 
111
111
  self->texture = texture;
112
112
 
113
- #if 0
113
+ #if 1
114
114
  int w = texture.reserved_width(), h = texture.reserved_height();
115
115
  if (
116
116
  w != self->render_buffer.width() ||
@@ -119,8 +119,7 @@ namespace Rays
119
119
  RenderBuffer rb = RenderBuffer(w, h);
120
120
 
121
121
  glFramebufferRenderbuffer(
122
- GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
123
- GL_RENDERBUFFER, rb.id());
122
+ GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb.id());
124
123
  OpenGL_check_error(__FILE__, __LINE__);
125
124
 
126
125
  self->render_buffer = rb;
data/src/painter.cpp CHANGED
@@ -56,6 +56,8 @@ namespace Rays
56
56
 
57
57
  uint nsegment;
58
58
 
59
+ BlendMode blend_mode;
60
+
59
61
  Bounds clip;
60
62
 
61
63
  Font font;
@@ -72,6 +74,7 @@ namespace Rays
72
74
  stroke_join = JOIN_DEFAULT;
73
75
  miter_limit = JOIN_DEFAULT_MITER_LIMIT;
74
76
  nsegment = 0;
77
+ blend_mode = BLEND_NORMAL;
75
78
  clip .reset(-1);
76
79
  font = default_font();
77
80
  shader = Shader();
@@ -107,7 +110,7 @@ namespace Rays
107
110
  return
108
111
  texture &&
109
112
  texcoord_min.x < texcoord_max.x &&
110
- texcoord_min.x < texcoord_max.y;
113
+ texcoord_min.y < texcoord_max.y;
111
114
  }
112
115
 
113
116
  bool operator ! () const
@@ -125,10 +128,14 @@ namespace Rays
125
128
 
126
129
  GLclampf color_clear[4];
127
130
 
131
+ GLboolean depth_test;
132
+ GLint depth_func;
133
+
128
134
  GLboolean scissor_test;
129
135
  GLint scissor_box[4];
130
136
 
131
137
  GLboolean blend;
138
+ GLint blend_equation_rgb, blend_equation_alpha;
132
139
  GLint blend_src_rgb, blend_src_alpha, blend_dst_rgb, blend_dst_alpha;
133
140
 
134
141
  GLint framebuffer_binding;
@@ -139,10 +146,15 @@ namespace Rays
139
146
 
140
147
  glGetFloatv(GL_COLOR_CLEAR_VALUE, color_clear);
141
148
 
149
+ glGetBooleanv(GL_DEPTH_TEST, &depth_test);
150
+ glGetIntegerv(GL_DEPTH_FUNC, &depth_func);
151
+
142
152
  glGetBooleanv(GL_SCISSOR_TEST, &scissor_test);
143
153
  glGetIntegerv(GL_SCISSOR_BOX, scissor_box);
144
154
 
145
155
  glGetBooleanv(GL_BLEND, &blend);
156
+ glGetIntegerv(GL_BLEND_EQUATION_RGB, &blend_equation_rgb);
157
+ glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blend_equation_alpha);
146
158
  glGetIntegerv(GL_BLEND_SRC_RGB, &blend_src_rgb);
147
159
  glGetIntegerv(GL_BLEND_SRC_ALPHA, &blend_src_alpha);
148
160
  glGetIntegerv(GL_BLEND_DST_RGB, &blend_dst_rgb);
@@ -158,10 +170,14 @@ namespace Rays
158
170
  glClearColor(
159
171
  color_clear[0], color_clear[1], color_clear[2], color_clear[3]);
160
172
 
173
+ enable(GL_DEPTH_TEST, depth_test);
174
+ glDepthFunc(depth_func);
175
+
161
176
  enable(GL_SCISSOR_TEST, scissor_test);
162
177
  glScissor(scissor_box[0], scissor_box[1], scissor_box[2], scissor_box[3]);
163
178
 
164
179
  enable(GL_BLEND, blend);
180
+ glBlendEquationSeparate(blend_equation_rgb, blend_equation_alpha);
165
181
  glBlendFuncSeparate(
166
182
  blend_src_rgb, blend_dst_rgb, blend_src_alpha, blend_dst_alpha);
167
183
 
@@ -566,7 +582,7 @@ namespace Rays
566
582
  Painter::canvas (
567
583
  coord x, coord y, coord width, coord height, float pixel_density)
568
584
  {
569
- canvas(Bounds(x, y, -100, width, height, 200), pixel_density);
585
+ canvas(x, y, 0, width, height, 0, pixel_density);
570
586
  }
571
587
 
572
588
  void
@@ -639,10 +655,14 @@ namespace Rays
639
655
  self->opengl_state.push();
640
656
 
641
657
  //glEnable(GL_CULL_FACE);
642
- glEnable(GL_BLEND);
643
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
658
+
659
+ glEnable(GL_DEPTH_TEST);
660
+ glDepthFunc(GL_LEQUAL);
644
661
  OpenGL_check_error(__FILE__, __LINE__);
645
662
 
663
+ glEnable(GL_BLEND);
664
+ set_blend_mode(self->state.blend_mode);
665
+
646
666
  FrameBuffer& fb = self->frame_buffer;
647
667
  if (fb) FrameBuffer_bind(fb.id());
648
668
 
@@ -656,16 +676,23 @@ namespace Rays
656
676
  coord x1 = vp.x, x2 = vp.x + vp.width;
657
677
  coord y1 = vp.y, y2 = vp.y + vp.height;
658
678
  coord z1 = vp.z, z2 = vp.z + vp.depth;
659
- if (z1 == 0 && z2 == 0) {z1 = -100; z2 = 200;}
679
+ if (z1 == 0 && z2 == 0) {z1 = -1000; z2 = 1000;}
660
680
  if (!fb) std::swap(y1, y2);
661
681
 
662
682
  self->position_matrix.reset(1);
663
683
  self->position_matrix *= to_rays(glm::ortho(x1, x2, y1, y2));
684
+
685
+ // map z to 0.0-1.0
686
+ self->position_matrix.scale(1, 1, 1.0 / (z2 - z1));
687
+ self->position_matrix.translate(0, 0, -z2);
688
+
664
689
  //self->position_matrix.translate(0.375f, 0.375f);
665
690
 
666
691
  self->update_clip();
667
692
 
668
693
  self->painting = true;
694
+
695
+ glClear(GL_DEPTH_BUFFER_BIT);
669
696
  }
670
697
 
671
698
  void
@@ -703,7 +730,7 @@ namespace Rays
703
730
 
704
731
  const Color& c = self->state.background;
705
732
  glClearColor(c.red, c.green, c.blue, c.alpha);
706
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
733
+ glClear(GL_COLOR_BUFFER_BIT);
707
734
  OpenGL_check_error(__FILE__, __LINE__);
708
735
  }
709
736
 
@@ -1293,6 +1320,72 @@ namespace Rays
1293
1320
  return self->state.nsegment;
1294
1321
  }
1295
1322
 
1323
+ void
1324
+ Painter::set_blend_mode (BlendMode mode)
1325
+ {
1326
+ self->state.blend_mode = mode;
1327
+ switch (mode)
1328
+ {
1329
+ case BLEND_NORMAL:
1330
+ glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
1331
+ glBlendFuncSeparate(
1332
+ GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
1333
+ break;
1334
+
1335
+ case BLEND_ADD:
1336
+ glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
1337
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE);
1338
+ break;
1339
+
1340
+ case BLEND_SUBTRACT:
1341
+ glBlendEquationSeparate(GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_ADD);
1342
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE);
1343
+ break;
1344
+
1345
+ case BLEND_LIGHTEST:
1346
+ glBlendEquationSeparate(GL_MAX, GL_FUNC_ADD);
1347
+ glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ONE);
1348
+ break;
1349
+
1350
+ case BLEND_DARKEST:
1351
+ glBlendEquationSeparate(GL_MIN, GL_FUNC_ADD);
1352
+ glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ONE);
1353
+ break;
1354
+
1355
+ case BLEND_EXCLUSION:
1356
+ glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
1357
+ glBlendFuncSeparate(
1358
+ GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_ONE, GL_ONE);
1359
+ break;
1360
+
1361
+ case BLEND_MULTIPLY:
1362
+ glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
1363
+ glBlendFuncSeparate(GL_ZERO, GL_SRC_COLOR, GL_ONE, GL_ONE);
1364
+ break;
1365
+
1366
+ case BLEND_SCREEN:
1367
+ glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
1368
+ glBlendFuncSeparate(GL_ONE_MINUS_DST_COLOR, GL_ONE, GL_ONE, GL_ONE);
1369
+ break;
1370
+
1371
+ case BLEND_REPLACE:
1372
+ glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
1373
+ glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO);
1374
+ break;
1375
+
1376
+ default:
1377
+ argument_error(__FILE__, __LINE__, "unknown blend mode");
1378
+ break;
1379
+ }
1380
+ OpenGL_check_error(__FILE__, __LINE__);
1381
+ }
1382
+
1383
+ BlendMode
1384
+ Painter::blend_mode () const
1385
+ {
1386
+ return self->state.blend_mode;
1387
+ }
1388
+
1296
1389
  void
1297
1390
  Painter::set_clip (coord x, coord y, coord width, coord height)
1298
1391
  {
@@ -1318,9 +1411,19 @@ namespace Rays
1318
1411
  return self->state.clip;
1319
1412
  }
1320
1413
 
1414
+ static bool
1415
+ has_same_font (const Font& font, const char* name, coord size)
1416
+ {
1417
+ return
1418
+ font.size() == size &&
1419
+ font.name() == (name ? name : default_font().name().c_str());
1420
+ }
1421
+
1321
1422
  void
1322
1423
  Painter::set_font (const char* name, coord size)
1323
1424
  {
1425
+ if (has_same_font(self->state.font, name, size)) return;
1426
+
1324
1427
  set_font(Font(name, size));
1325
1428
  }
1326
1429
 
@@ -54,8 +54,11 @@ namespace Rays
54
54
  #else
55
55
  GL_DEPTH_COMPONENT24,
56
56
  #endif
57
- width,
58
- height);
57
+ width_,
58
+ height_);
59
+ OpenGL_check_error(__FILE__, __LINE__);
60
+
61
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
59
62
  OpenGL_check_error(__FILE__, __LINE__);
60
63
 
61
64
  width = width_;
data/test/test_painter.rb CHANGED
@@ -18,6 +18,22 @@ class TestPainter < Test::Unit::TestCase
18
18
  Rays::Color.new(*args)
19
19
  end
20
20
 
21
+ def image(w = 16, h = 16, bg: 0, &block)
22
+ Rays::Image.new(w, h).paint {background bg}.paint(&block)
23
+ end
24
+
25
+ def assert_rgb(expected, actual)
26
+ (0..2).each do |i|
27
+ assert_in_epsilon expected[i], actual[i], 0.02
28
+ end
29
+ end
30
+
31
+ def assert_rgba(expected, actual)
32
+ (0..3).each do |i|
33
+ assert_in_epsilon expected[i], actual[i], 0.02
34
+ end
35
+ end
36
+
21
37
  def setup()
22
38
  Rays::Color.set_palette_color :rgb001, color(0, 0, 1)
23
39
  end
@@ -124,6 +140,19 @@ class TestPainter < Test::Unit::TestCase
124
140
  assert_equal 4, pa.miter_limit
125
141
  end
126
142
 
143
+ def test_blend_mode_accessor()
144
+ pa = painter
145
+ assert_equal :normal, pa.blend_mode
146
+ pa.blend_mode = :add
147
+ assert_equal :add, pa.blend_mode
148
+ pa.blend_mode :subtract
149
+ assert_equal :subtract, pa.blend_mode
150
+ pa.push blend_mode: :multiply do |_|
151
+ assert_equal :multiply, pa.blend_mode
152
+ end
153
+ assert_equal :subtract, pa.blend_mode
154
+ end
155
+
127
156
  def test_clip_accessor()
128
157
  pa = painter
129
158
  pa.clip = [1, 2, 3, 4]
@@ -182,6 +211,122 @@ class TestPainter < Test::Unit::TestCase
182
211
  assert_equal color(0, 1, 0), pa.fill
183
212
  end
184
213
 
214
+ def test_blend_mode_normal()
215
+ i = image do
216
+ blend_mode :normal
217
+ fill 0.1, 0.2, 0.3
218
+ rect 0, 0, 2
219
+ fill 0.4, 0.5, 0.6
220
+ rect 1, 0, 2
221
+ end
222
+ assert_rgb [0.1, 0.2, 0.3], i[0, 0]
223
+ assert_rgb [0.4, 0.5, 0.6], i[1, 0]
224
+ assert_rgb [0.4, 0.5, 0.6], i[2, 0]
225
+ end
226
+
227
+ def test_blend_mode_add()
228
+ i = image do
229
+ fill 0.1, 0.2, 0.3
230
+ rect 0, 0, 2
231
+ blend_mode :add
232
+ fill 0.4, 0.5, 0.6
233
+ rect 1, 0, 2
234
+ end
235
+ assert_rgb [0.1, 0.2, 0.3], i[0, 0]
236
+ assert_rgb [0.5, 0.7, 0.9], i[1, 0]
237
+ assert_rgb [0.4, 0.5, 0.6], i[2, 0]
238
+ end
239
+
240
+ def test_blend_mode_subtract()
241
+ i = image bg: 1 do
242
+ fill 0.4, 0.5, 0.6
243
+ rect 0, 0, 2
244
+ blend_mode :subtract
245
+ fill 0.1, 0.2, 0.3
246
+ rect 1, 0, 2
247
+ end
248
+ assert_rgb [0.4, 0.5, 0.6], i[0, 0]
249
+ assert_rgb [0.3, 0.3, 0.3], i[1, 0]
250
+ assert_rgb [0.9, 0.8, 0.7], i[2, 0]
251
+ end
252
+
253
+ def test_blend_mode_lightest()
254
+ i = image do
255
+ fill 0.4, 0.5, 0.6
256
+ rect 0, 0, 2
257
+ blend_mode :lightest
258
+ fill 0.1, 0.2, 0.3
259
+ rect 1, 0, 2
260
+ end
261
+ assert_rgb [0.4, 0.5, 0.6], i[0, 0]
262
+ assert_rgb [0.4, 0.5, 0.6], i[1, 0]
263
+ assert_rgb [0.1, 0.2, 0.3], i[2, 0]
264
+ end
265
+
266
+ def test_blend_mode_darkest()
267
+ i = image bg: 1 do
268
+ fill 0.1, 0.2, 0.3
269
+ rect 0, 0, 2
270
+ blend_mode :darkest
271
+ fill 0.4, 0.5, 0.6
272
+ rect 1, 0, 2
273
+ end
274
+ assert_rgb [0.1, 0.2, 0.3], i[0, 0]
275
+ assert_rgb [0.1, 0.2, 0.3], i[1, 0]
276
+ assert_rgb [0.4, 0.5, 0.6], i[2, 0]
277
+ end
278
+
279
+ def test_blend_mode_exclusion()
280
+ # no tests
281
+ end
282
+
283
+ def test_blend_mode_multiply()
284
+ i = image bg: 1 do
285
+ fill 0.2, 0.4, 0.6
286
+ rect 0, 0, 2
287
+ blend_mode :multiply
288
+ fill 0.5
289
+ rect 1, 0, 2
290
+ end
291
+ assert_rgb [0.2, 0.4, 0.6], i[0, 0]
292
+ assert_rgb [0.1, 0.2, 0.3], i[1, 0]
293
+ assert_rgb [0.5, 0.5, 0.5], i[2, 0]
294
+ end
295
+
296
+ def test_blend_mode_screen()
297
+ i = image bg: 0.8 do
298
+ fill 0.2, 0.4, 0.6
299
+ rect 0, 0, 2
300
+ blend_mode :screen
301
+ fill 0.5
302
+ rect 1, 0, 2
303
+ end
304
+ assert_rgb [0.2, 0.4, 0.6], i[0, 0]
305
+ assert_rgb [0.6, 0.7, 0.8], i[1, 0]
306
+ assert_rgb [0.9, 0.9, 0.9], i[2, 0]
307
+ end
308
+
309
+ def test_blend_mode_replace()
310
+ i = image bg: 1 do
311
+ fill 0.1, 0.2, 0.3, 0.4
312
+ rect 0, 0, 2
313
+ blend_mode :replace
314
+ fill 0.5, 0.6, 0.7, 0.8
315
+ rect 1, 0, 2
316
+ end
317
+ assert_rgba [0.5, 0.6, 0.7, 0.8], i[1, 0]
318
+ assert_rgba [0.5, 0.6, 0.7, 0.8], i[2, 0]
319
+ end
320
+
321
+ def test_blend_mode_invalid()
322
+ assert_raise(ArgumentError) do
323
+ image {blend_mode :invalid}
324
+ end
325
+ assert_raise(ArgumentError) do
326
+ image {blend_mode nil}
327
+ end
328
+ end
329
+
185
330
  def test_push()
186
331
  pa = painter
187
332
  pa.fill = [1, 0, 0]
@@ -99,4 +99,4 @@ class TestPainterShape < Test::Unit::TestCase
99
99
  assert_equal 0, img[99, 99].a
100
100
  end
101
101
 
102
- end# TestPainter
102
+ end# TestPainterShape
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.25
4
+ version: 0.1.26
5
5
  platform: ruby
6
6
  authors:
7
7
  - xordog
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-04 00:00:00.000000000 Z
11
+ date: 2022-07-23 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.25
19
+ version: 0.1.26
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.25
26
+ version: 0.1.26
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.25
33
+ version: 0.1.26
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.25
40
+ version: 0.1.26
41
41
  description: This library helps you to develop graphics application with OpenGL.
42
42
  email: xordog@gmail.com
43
43
  executables: []
@@ -252,7 +252,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
252
252
  - !ruby/object:Gem::Version
253
253
  version: '0'
254
254
  requirements: []
255
- rubygems_version: 3.2.32
255
+ rubygems_version: 3.2.33
256
256
  signing_key:
257
257
  specification_version: 4
258
258
  summary: A Drawing Engine using OpenGL.