rays 0.1.25 → 0.1.26

Sign up to get free protection for your applications and to get access to all the features.
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.