ray 0.1.1 → 0.2.0
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.
- data/README.md +9 -6
- data/Rakefile +1 -5
- data/ext/audio.c +25 -19
- data/ext/audio_source.c +67 -39
- data/ext/color.c +19 -19
- data/ext/drawable.c +190 -31
- data/ext/extconf.rb +16 -14
- data/ext/gl.c +310 -30
- data/ext/gl_buffer.c +223 -2
- data/ext/gl_index_buffer.c +11 -0
- data/ext/gl_int_array.c +24 -22
- data/ext/gl_vertex.c +84 -49
- data/ext/image.c +115 -51
- data/ext/image_target.c +58 -10
- data/ext/input.c +73 -6
- data/ext/mo.c +583 -0
- data/ext/mo.h +189 -0
- data/ext/music.c +9 -8
- data/ext/pixel_bus.c +349 -0
- data/ext/polygon.c +68 -45
- data/ext/ray.c +1 -0
- data/ext/ray.h +19 -1
- data/ext/rect.c +9 -47
- data/ext/say.h +1 -2
- data/ext/say_all.h +6 -0
- data/ext/say_audio.h +3 -0
- data/ext/say_audio_context.c +1 -4
- data/ext/say_basic_type.c +24 -0
- data/ext/say_basic_type.h +4 -0
- data/ext/say_buffer.c +217 -88
- data/ext/say_buffer.h +20 -5
- data/ext/say_buffer_renderer.c +10 -7
- data/ext/say_buffer_renderer.h +1 -1
- data/ext/say_buffer_slice.c +70 -76
- data/ext/say_context.c +109 -22
- data/ext/say_context.h +14 -0
- data/ext/say_drawable.c +113 -25
- data/ext/say_drawable.h +23 -2
- data/ext/say_error.c +7 -2
- data/ext/say_font.c +30 -27
- data/ext/say_font.h +3 -6
- data/ext/say_get_proc.c +35 -0
- data/ext/say_image.c +102 -27
- data/ext/say_image.h +11 -4
- data/ext/say_image_target.c +88 -34
- data/ext/say_image_target.h +3 -2
- data/ext/say_index_buffer.c +31 -19
- data/ext/say_index_buffer.h +4 -2
- data/ext/say_index_buffer_slice.c +78 -70
- data/ext/say_music.c +4 -2
- data/ext/say_osx.h +3 -2
- data/ext/say_osx_context.h +37 -4
- data/ext/say_osx_window.h +32 -37
- data/ext/say_pixel_bus.c +163 -0
- data/ext/say_pixel_bus.h +44 -0
- data/ext/say_polygon.c +2 -2
- data/ext/say_shader.c +66 -62
- data/ext/say_shader.h +2 -0
- data/ext/say_sprite.c +1 -2
- data/ext/say_target.c +14 -23
- data/ext/say_target.h +3 -1
- data/ext/say_text.c +45 -7
- data/ext/say_text.h +12 -3
- data/ext/say_thread.c +13 -6
- data/ext/say_thread.h +1 -1
- data/ext/say_thread_variable.c +5 -5
- data/ext/say_vertex_type.c +79 -41
- data/ext/say_vertex_type.h +6 -2
- data/ext/say_view.c +10 -31
- data/ext/say_view.h +1 -5
- data/ext/say_win.h +2 -2
- data/ext/say_win_context.h +49 -11
- data/ext/say_win_window.h +30 -27
- data/ext/say_window.c +3 -3
- data/ext/say_x11.h +3 -1
- data/ext/say_x11_context.h +64 -10
- data/ext/say_x11_window.h +22 -17
- data/ext/shader.c +9 -0
- data/ext/sprite.c +7 -1
- data/ext/target.c +80 -28
- data/ext/text.c +43 -1
- data/ext/view.c +53 -1
- data/ext/window.c +4 -0
- data/lib/ray/animation_list.rb +17 -2
- data/lib/ray/audio_source.rb +11 -0
- data/lib/ray/color.rb +14 -0
- data/lib/ray/drawable.rb +23 -0
- data/lib/ray/dsl/event.rb +1 -9
- data/lib/ray/dsl/event_runner.rb +3 -4
- data/lib/ray/dsl/matcher.rb +20 -1
- data/lib/ray/effect.rb +116 -0
- data/lib/ray/effect/black_and_white.rb +38 -0
- data/lib/ray/effect/color_inversion.rb +16 -0
- data/lib/ray/effect/generator.rb +145 -0
- data/lib/ray/effect/grayscale.rb +32 -0
- data/lib/ray/game.rb +25 -5
- data/lib/ray/gl/vertex.rb +105 -26
- data/lib/ray/helper.rb +5 -0
- data/lib/ray/image.rb +54 -13
- data/lib/ray/image_target.rb +7 -0
- data/lib/ray/matrix.rb +26 -0
- data/lib/ray/music.rb +4 -0
- data/lib/ray/pixel_bus.rb +22 -0
- data/lib/ray/polygon.rb +17 -0
- data/lib/ray/pp.rb +28 -0
- data/lib/ray/ray.rb +7 -1
- data/lib/ray/rect.rb +7 -13
- data/lib/ray/scene.rb +24 -5
- data/lib/ray/scene_list.rb +9 -0
- data/lib/ray/shader.rb +11 -2
- data/lib/ray/sound.rb +4 -0
- data/lib/ray/sprite.rb +23 -62
- data/lib/ray/target.rb +25 -0
- data/lib/ray/text.rb +10 -0
- data/lib/ray/turtle.rb +9 -3
- data/lib/ray/vector.rb +18 -0
- data/lib/ray/vertex.rb +6 -0
- data/lib/ray/view.rb +22 -0
- data/samples/animation/sprite_motion.rb +0 -60
- data/samples/audio/{spacial.rb → spatial.rb} +1 -1
- data/samples/buffer/buffer.rb +1 -0
- data/samples/buffer/index_buffer.rb +2 -0
- data/samples/cptn_ruby/cptn_ruby.rb +6 -7
- data/samples/effects/effect.rb +39 -0
- data/samples/effects/grayscale.rb +27 -0
- data/samples/opengl/image.rb +7 -5
- data/samples/opengl/instancing.rb +159 -0
- data/samples/opengl/instancing.rbc +3231 -0
- data/samples/opengl/obj_loader.rb +9 -8
- data/samples/opengl/shader.rb +1 -3
- data/samples/shaders/geometry.rb +108 -38
- data/samples/shaders/geometry.rbc +2074 -0
- data/samples/shaders/shape.rb +2 -2
- data/samples/starfighter/starfighter.rb +5 -5
- data/samples/window/get_pixel.rb +1 -1
- data/test/animation_list_test.rb +18 -4
- data/test/drawable_test.rb +70 -1
- data/test/effect_generator_test.rb +63 -0
- data/test/effect_test.rb +61 -0
- data/test/game_test.rb +18 -0
- data/test/gl_buffer_test.rb +43 -1
- data/test/gl_index_buffer_test.rb +5 -0
- data/test/gl_vertex_test.rb +28 -1
- data/test/image_test.rb +5 -5
- data/test/input_test.rb +49 -0
- data/test/pixel_bus_test.rb +28 -0
- data/test/rect_test.rb +4 -0
- data/{samples/_media → test/res}/Beep.wav +0 -0
- data/samples/_media/CptnRuby Gem.png b/data/test/res/CptnRuby → Gem.png +0 -0
- data/samples/_media/CptnRuby Map.txt b/data/test/res/CptnRuby → Map.txt +0 -0
- data/samples/_media/CptnRuby Tileset.png b/data/test/res/CptnRuby → Tileset.png +0 -0
- data/{samples/_media → test/res}/CptnRuby.png +0 -0
- data/{samples/_media → test/res}/Space.png +0 -0
- data/{samples/_media → test/res}/Star.png +0 -0
- data/{samples/_media → test/res}/Starfighter.png +0 -0
- data/test/res/cube.obj +28 -0
- data/test/res/light3d.c +2 -2
- data/test/res/stone.png +0 -0
- data/test/scene_test.rb +3 -0
- data/test/sprite_test.rb +10 -0
- data/test/text_test.rb +31 -2
- data/test/view_test.rb +13 -1
- metadata +38 -17
- data/ext/say_array.c +0 -124
- data/ext/say_array.h +0 -34
- data/ext/say_table.c +0 -86
- data/ext/say_table.h +0 -24
data/ext/text.c
CHANGED
@@ -17,13 +17,19 @@ say_text *ray_rb2text(VALUE obj) {
|
|
17
17
|
static
|
18
18
|
VALUE ray_text_alloc(VALUE self) {
|
19
19
|
say_text *text = say_text_create();
|
20
|
-
|
20
|
+
VALUE rb = Data_Wrap_Struct(self, NULL, say_text_free, text);
|
21
|
+
|
22
|
+
say_drawable_set_shader_proc(text->drawable, ray_drawable_shader_proc);
|
23
|
+
say_drawable_set_other_data(text->drawable, (void*)rb);
|
24
|
+
|
25
|
+
return rb;
|
21
26
|
}
|
22
27
|
|
23
28
|
static
|
24
29
|
VALUE ray_text_init_copy(VALUE self, VALUE orig) {
|
25
30
|
say_text_copy(ray_rb2text(self), ray_rb2text(orig));
|
26
31
|
rb_iv_set(self, "@font", rb_iv_get(orig, "@font"));
|
32
|
+
ray_drawable_copy_attr(self, orig);
|
27
33
|
return self;
|
28
34
|
}
|
29
35
|
|
@@ -131,6 +137,39 @@ VALUE ray_text_rect(VALUE self) {
|
|
131
137
|
return ray_rect2rb(say_text_get_rect(ray_rb2text(self)));
|
132
138
|
}
|
133
139
|
|
140
|
+
/*
|
141
|
+
* @return [Ray::Vector2, nil] Auto-centering ratio. Nil when disabled.
|
142
|
+
*/
|
143
|
+
static
|
144
|
+
VALUE ray_text_auto_center(VALUE self) {
|
145
|
+
say_text *text = ray_rb2text(self);
|
146
|
+
|
147
|
+
if (say_text_auto_center(text))
|
148
|
+
return ray_vector2_to_rb(say_text_get_auto_center_ratio(text));
|
149
|
+
else
|
150
|
+
return Qnil;
|
151
|
+
}
|
152
|
+
|
153
|
+
/*
|
154
|
+
* @overload auto_center=(val)
|
155
|
+
* Sets the auto centering ratio. It's a vector2 containing values between 0
|
156
|
+
* and 1 (typically, at least) to determine the center of the text when it is
|
157
|
+
* resized. (0.5, 1), for example, would set the origin to (middle, bottom).
|
158
|
+
*
|
159
|
+
* @param [Ray::Vector2, nil] val New auto centering ratio. If nil, disables
|
160
|
+
* auto-centering.
|
161
|
+
*/
|
162
|
+
static
|
163
|
+
VALUE ray_text_set_auto_center(VALUE self, VALUE center) {
|
164
|
+
say_text *text = ray_rb2text(self);
|
165
|
+
|
166
|
+
if (NIL_P(center))
|
167
|
+
say_text_disable_auto_center(text);
|
168
|
+
else
|
169
|
+
say_text_enable_auto_center(text, ray_convert_to_vector2(center));
|
170
|
+
|
171
|
+
return center;
|
172
|
+
}
|
134
173
|
|
135
174
|
void Init_ray_text() {
|
136
175
|
ray_cText = rb_define_class_under(ray_mRay, "Text", ray_cDrawable);
|
@@ -155,6 +194,9 @@ void Init_ray_text() {
|
|
155
194
|
|
156
195
|
rb_define_method(ray_cText, "rect", ray_text_rect, 0);
|
157
196
|
|
197
|
+
rb_define_method(ray_cText, "auto_center", ray_text_auto_center, 0);
|
198
|
+
rb_define_method(ray_cText, "auto_center=", ray_text_set_auto_center, 1);
|
199
|
+
|
158
200
|
rb_define_const(ray_cText, "Normal", INT2FIX(SAY_TEXT_NORMAL));
|
159
201
|
rb_define_const(ray_cText, "Bold", INT2FIX(SAY_TEXT_BOLD));
|
160
202
|
rb_define_const(ray_cText, "Italic", INT2FIX(SAY_TEXT_ITALIC));
|
data/ext/view.c
CHANGED
@@ -63,11 +63,19 @@ VALUE ray_view_init_copy(VALUE self, VALUE orig) {
|
|
63
63
|
return self;
|
64
64
|
}
|
65
65
|
|
66
|
+
/*
|
67
|
+
* @see view=
|
68
|
+
*/
|
66
69
|
static
|
67
70
|
VALUE ray_view_size(VALUE self) {
|
68
71
|
return ray_vector2_to_rb(say_view_get_size(ray_rb2view(self)));
|
69
72
|
}
|
70
73
|
|
74
|
+
/*
|
75
|
+
* @overload size=(val)
|
76
|
+
* Sets the size of the visible world
|
77
|
+
* @param [Ray::Vector2] val
|
78
|
+
*/
|
71
79
|
static
|
72
80
|
VALUE ray_view_set_size(VALUE self, VALUE val) {
|
73
81
|
rb_check_frozen(self);
|
@@ -75,11 +83,19 @@ VALUE ray_view_set_size(VALUE self, VALUE val) {
|
|
75
83
|
return val;
|
76
84
|
}
|
77
85
|
|
86
|
+
/*
|
87
|
+
* @see center=
|
88
|
+
*/
|
78
89
|
static
|
79
90
|
VALUE ray_view_center(VALUE self) {
|
80
91
|
return ray_vector2_to_rb(say_view_get_center(ray_rb2view(self)));
|
81
92
|
}
|
82
93
|
|
94
|
+
/*
|
95
|
+
* @overload center=(center)
|
96
|
+
* Sets the center of the world
|
97
|
+
* @param [Ray::Vector2] center
|
98
|
+
*/
|
83
99
|
static
|
84
100
|
VALUE ray_view_set_center(VALUE self, VALUE val) {
|
85
101
|
rb_check_frozen(self);
|
@@ -87,11 +103,23 @@ VALUE ray_view_set_center(VALUE self, VALUE val) {
|
|
87
103
|
return val;
|
88
104
|
}
|
89
105
|
|
106
|
+
/*
|
107
|
+
* @see viewport=
|
108
|
+
*/
|
90
109
|
static
|
91
110
|
VALUE ray_view_viewport(VALUE self) {
|
92
111
|
return ray_rect2rb(say_view_get_viewport(ray_rb2view(self)));
|
93
112
|
}
|
94
113
|
|
114
|
+
/*
|
115
|
+
* @overload viewport=(rect)
|
116
|
+
* Sets the region of the world where rendering will be done
|
117
|
+
*
|
118
|
+
* All the components of the rects are values between 0 and 1, allowing to use
|
119
|
+
* the same rect for two targets of different size
|
120
|
+
*
|
121
|
+
* @param [Ray::Rect] rect
|
122
|
+
*/
|
95
123
|
static
|
96
124
|
VALUE ray_view_set_viewport(VALUE self, VALUE val) {
|
97
125
|
rb_check_frozen(self);
|
@@ -99,18 +127,42 @@ VALUE ray_view_set_viewport(VALUE self, VALUE val) {
|
|
99
127
|
return val;
|
100
128
|
}
|
101
129
|
|
130
|
+
/*
|
131
|
+
* @see matrix=
|
132
|
+
*/
|
102
133
|
static
|
103
134
|
VALUE ray_view_matrix(VALUE self) {
|
104
135
|
return ray_matrix2rb(say_view_get_matrix(ray_rb2view(self)));
|
105
136
|
}
|
106
137
|
|
138
|
+
/*
|
139
|
+
* @overload matrix=(mat)
|
140
|
+
* Sets the projection matrix
|
141
|
+
*
|
142
|
+
* Setting the projection matrix causes the center and the size of the view to
|
143
|
+
* be ignored. Passing nil would cancel this.
|
144
|
+
*
|
145
|
+
* @param [Ray::Matrix, nil] mat New matrix
|
146
|
+
*/
|
107
147
|
static
|
108
148
|
VALUE ray_view_set_matrix(VALUE self, VALUE val) {
|
109
149
|
rb_check_frozen(self);
|
110
|
-
|
150
|
+
|
151
|
+
if (NIL_P(val))
|
152
|
+
say_view_set_matrix(ray_rb2view(self), NULL);
|
153
|
+
else
|
154
|
+
say_view_set_matrix(ray_rb2view(self), ray_rb2matrix(val));
|
155
|
+
|
111
156
|
return val;
|
112
157
|
}
|
113
158
|
|
159
|
+
/*
|
160
|
+
* Document-class: Ray::View
|
161
|
+
*
|
162
|
+
* A view is a way to apply some transformations to all the drawables at once,
|
163
|
+
* by defining a projection. It also determines the region of the screen where
|
164
|
+
* the view will draw.
|
165
|
+
*/
|
114
166
|
void Init_ray_view() {
|
115
167
|
ray_cView = rb_define_class_under(ray_mRay, "View", rb_cObject);
|
116
168
|
rb_define_alloc_func(ray_cView, ray_view_alloc);
|
data/ext/window.c
CHANGED
@@ -52,6 +52,10 @@ VALUE ray_window_open(int argc, VALUE *argv, VALUE self) {
|
|
52
52
|
|
53
53
|
say_vector2 c_size = ray_convert_to_vector2(size);
|
54
54
|
|
55
|
+
#ifdef SAY_OSX
|
56
|
+
say_osx_flip_pool();
|
57
|
+
#endif
|
58
|
+
|
55
59
|
if (!say_window_open(window, c_size.x, c_size.y,
|
56
60
|
StringValuePtr(title), flags)) {
|
57
61
|
rb_raise(rb_eRuntimeError, "%s", say_error_get_last());
|
data/lib/ray/animation_list.rb
CHANGED
@@ -10,6 +10,7 @@ module Ray
|
|
10
10
|
#
|
11
11
|
class AnimationList
|
12
12
|
include Enumerable
|
13
|
+
include Ray::PP
|
13
14
|
|
14
15
|
def initialize
|
15
16
|
@animations = []
|
@@ -26,10 +27,15 @@ module Ray
|
|
26
27
|
self
|
27
28
|
end
|
28
29
|
|
29
|
-
# Updates all the animations
|
30
|
+
# Updates all the animations
|
30
31
|
def update
|
32
|
+
@animations.each(&:update)
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
# Removes animations that are no more in use
|
37
|
+
def remove_unused
|
31
38
|
@animations.reject! do |anim|
|
32
|
-
anim.update
|
33
39
|
!anim.running? && !anim.paused?
|
34
40
|
end
|
35
41
|
|
@@ -43,8 +49,17 @@ module Ray
|
|
43
49
|
self
|
44
50
|
end
|
45
51
|
|
52
|
+
# @return [Array<Ray::Animation>]
|
53
|
+
attr_reader :animations
|
54
|
+
|
55
|
+
alias to_a animations
|
56
|
+
|
46
57
|
def inspect
|
47
58
|
"#{self.class}#{@animations.inspect}"
|
48
59
|
end
|
60
|
+
|
61
|
+
def pretty_print(q)
|
62
|
+
pretty_print_attributes q, ["animations"]
|
63
|
+
end
|
49
64
|
end
|
50
65
|
end
|
data/lib/ray/color.rb
CHANGED
@@ -49,6 +49,20 @@ module Ray
|
|
49
49
|
"RGBA(#{r}, #{g}, #{b}, #{a})"
|
50
50
|
end
|
51
51
|
|
52
|
+
def pretty_print(q)
|
53
|
+
q.text("RGB#{'A' if a != 255}(")
|
54
|
+
q.pp r
|
55
|
+
q.text ", "
|
56
|
+
q.pp g
|
57
|
+
q.text ", "
|
58
|
+
q.pp b
|
59
|
+
if a != 255
|
60
|
+
q.text ", "
|
61
|
+
q.pp a
|
62
|
+
end
|
63
|
+
q.text ")"
|
64
|
+
end
|
65
|
+
|
52
66
|
# @param [Ray::Color] color Another color.
|
53
67
|
# @return [Ray::Color] Sum of two colors, adding component pairs.
|
54
68
|
def +(color)
|
data/lib/ray/drawable.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
module Ray
|
2
2
|
class Drawable
|
3
|
+
include Ray::PP
|
4
|
+
|
5
|
+
# @group Transformations
|
6
|
+
|
3
7
|
def y
|
4
8
|
pos.y
|
5
9
|
end
|
@@ -32,6 +36,25 @@ module Ray
|
|
32
36
|
self.scale = [scale_x, val]
|
33
37
|
end
|
34
38
|
|
39
|
+
# @endgroup
|
40
|
+
|
41
|
+
def pretty_print(q, other_attributes = [])
|
42
|
+
# Note: This doesn't use %w[...] arrays because YARD can't parse them
|
43
|
+
attributes = [
|
44
|
+
"origin", "pos", "z", "scale", "angle",
|
45
|
+
"matrix", "matrix_proc",
|
46
|
+
"shader", "shader_attributes",
|
47
|
+
"vertex_count", "index_count", "changed?", "textured?",
|
48
|
+
"blend_mode"
|
49
|
+
]
|
50
|
+
|
51
|
+
pretty_print_attributes q, attributes + other_attributes
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return [Hash, nil] Attributes passed to the shader when the object is
|
55
|
+
# drawn.
|
56
|
+
attr_accessor :shader_attributes
|
57
|
+
|
35
58
|
alias zoom scale
|
36
59
|
alias zoom= scale=
|
37
60
|
|
data/lib/ray/dsl/event.rb
CHANGED
@@ -1,14 +1,6 @@
|
|
1
1
|
module Ray
|
2
2
|
module DSL
|
3
3
|
# Used internally to store event when raise_event is called.
|
4
|
-
|
5
|
-
def initialize(type, args)
|
6
|
-
@type = type
|
7
|
-
@args = args
|
8
|
-
end
|
9
|
-
|
10
|
-
attr_reader :type
|
11
|
-
attr_reader :args
|
12
|
-
end
|
4
|
+
Event = Struct.new(:type, :args)
|
13
5
|
end
|
14
6
|
end
|
data/lib/ray/dsl/event_runner.rb
CHANGED
@@ -7,7 +7,6 @@ module Ray
|
|
7
7
|
class EventRunner
|
8
8
|
def initialize
|
9
9
|
@handlers = []
|
10
|
-
@event_list = []
|
11
10
|
@next_events = []
|
12
11
|
|
13
12
|
@event_groups = Hash.new { |h, k| h[k] = true }
|
@@ -16,13 +15,13 @@ module Ray
|
|
16
15
|
|
17
16
|
# Sends all the known events to our listeners.
|
18
17
|
def run
|
19
|
-
|
18
|
+
event_list = @next_events
|
20
19
|
@next_events = []
|
21
20
|
|
22
21
|
handlers = @handlers.select { |o| group_enabled?(o.group) }
|
23
22
|
|
24
|
-
|
25
|
-
handlers.
|
23
|
+
event_list.each do |ev|
|
24
|
+
handlers.each { |o| o.call(ev) if o.match?(ev) }
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
data/lib/ray/dsl/matcher.rb
CHANGED
@@ -1,4 +1,9 @@
|
|
1
1
|
module Ray
|
2
|
+
class NoKeyError < StandardError
|
3
|
+
def initialize(key)
|
4
|
+
super "key #{key} doesn't exist"
|
5
|
+
end
|
6
|
+
end
|
2
7
|
# This is the module including all of your matchers as private methods,
|
3
8
|
# allowing you to use them when you call on.
|
4
9
|
module Matchers
|
@@ -177,8 +182,17 @@ module Ray
|
|
177
182
|
end
|
178
183
|
end
|
179
184
|
|
185
|
+
# A Key object can be used as a matcher to check if a key has been pressed or
|
186
|
+
# released:
|
187
|
+
#
|
188
|
+
# on :key_press, Key.new(:+) do
|
189
|
+
# # work
|
190
|
+
# end
|
191
|
+
#
|
192
|
+
# @see KeyMod
|
180
193
|
class Key
|
181
194
|
def initialize(name)
|
195
|
+
raise NoKeyError, name unless Keys[name]
|
182
196
|
@symbol = name.to_sym
|
183
197
|
end
|
184
198
|
|
@@ -199,13 +213,18 @@ module Ray
|
|
199
213
|
end
|
200
214
|
end
|
201
215
|
|
216
|
+
# A KeyMod object can be used as a matcher to check if some modifiers are held
|
217
|
+
# when a key is pressed.
|
218
|
+
#
|
219
|
+
# @see KeyMod
|
202
220
|
class KeyMod
|
203
221
|
def initialize(name)
|
222
|
+
raise NoKeyError, name unless Mod[name]
|
204
223
|
@symbol = name.to_sym
|
205
224
|
end
|
206
225
|
|
207
226
|
def to_a
|
208
|
-
|
227
|
+
Mod[@symbol]
|
209
228
|
end
|
210
229
|
|
211
230
|
def to_sym
|
data/lib/ray/effect.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
module Ray
|
2
|
+
# Effects are used to generate fragment shaders automatically. They represent
|
3
|
+
# one of the transformations applied to the color.
|
4
|
+
#
|
5
|
+
# Effects must generate a structure to store arguments passed to the effect
|
6
|
+
# (structure generation being done through a DSL), and a function to apply the
|
7
|
+
# effect (a call to the #code method returns )
|
8
|
+
class Effect
|
9
|
+
# @overload effect_name(name)
|
10
|
+
# Sets the name of the effect
|
11
|
+
# @param [String] value
|
12
|
+
#
|
13
|
+
# @overload effect_name
|
14
|
+
# @return [String] Name of the effect
|
15
|
+
def self.effect_name(value = nil)
|
16
|
+
if value
|
17
|
+
@name = value
|
18
|
+
|
19
|
+
klass = self
|
20
|
+
Ray::Helper.send :define_method, @name do |*args|
|
21
|
+
klass.new(*args)
|
22
|
+
end
|
23
|
+
else
|
24
|
+
@name
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Adds an attribute to the shader. It is an element of the struct
|
29
|
+
#
|
30
|
+
# @param [String] name Name of the attribute
|
31
|
+
# @param [String] type Type of the attribute. Arrays are written using this
|
32
|
+
# notation: type[count].
|
33
|
+
def self.attribute(name, type)
|
34
|
+
attributes[name] = type
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [Hash] All the attributes of the struct, matched with their type.
|
38
|
+
def self.attributes
|
39
|
+
@attributes ||= {}
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [String] Name of the effect
|
43
|
+
def name
|
44
|
+
self.class.effect_name
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [String] GLSL code of the struct.
|
48
|
+
def struct
|
49
|
+
str = "struct ray_#{self.class.effect_name} {\n"
|
50
|
+
str << " bool enabled;\n"
|
51
|
+
|
52
|
+
self.class.attributes.each do |name, type|
|
53
|
+
if type =~ /\A(\w+)\[(\d+)\]\z/
|
54
|
+
str << " #$1 #{name}[#$2];\n"
|
55
|
+
else
|
56
|
+
str << " #{type} #{name};\n"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
str << "};\n"
|
61
|
+
end
|
62
|
+
|
63
|
+
# @abstract
|
64
|
+
#
|
65
|
+
# @return [String] Code that must be written *before* the definiton of the
|
66
|
+
# structure. Just returns an empty string by default.
|
67
|
+
def header
|
68
|
+
""
|
69
|
+
end
|
70
|
+
|
71
|
+
# @abstract
|
72
|
+
#
|
73
|
+
# @return [String]
|
74
|
+
# Code of the function. This must contain the header of the function.
|
75
|
+
# The name of the function is the name of the effect prepended by
|
76
|
+
# "do_". It is passed a ray_#{effect_name} structure and the color, and is
|
77
|
+
# expected to return the changed color.
|
78
|
+
#
|
79
|
+
# @example
|
80
|
+
# def code
|
81
|
+
# return %{
|
82
|
+
# vec4 do_some_effect(ray_some_effect arg, vec4 color) {
|
83
|
+
# /* Do magic here. */
|
84
|
+
# }
|
85
|
+
# }
|
86
|
+
# end
|
87
|
+
def code
|
88
|
+
raise NotImplementedError
|
89
|
+
end
|
90
|
+
|
91
|
+
# @abstract
|
92
|
+
#
|
93
|
+
# @return [Hash] Default value for each attribute.
|
94
|
+
def defaults
|
95
|
+
{}
|
96
|
+
end
|
97
|
+
|
98
|
+
# Apply the defaults to a shader.
|
99
|
+
# @param [Ray::Shader] shader
|
100
|
+
def apply_defaults(shader)
|
101
|
+
effect_name = self.class.effect_name
|
102
|
+
|
103
|
+
shader["#{effect_name}.enabled"] = true
|
104
|
+
|
105
|
+
defaults.each do |name, value|
|
106
|
+
shader["#{effect_name}.#{name}"] = value
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
require 'ray/effect/generator'
|
113
|
+
|
114
|
+
require 'ray/effect/grayscale'
|
115
|
+
require 'ray/effect/color_inversion'
|
116
|
+
require 'ray/effect/black_and_white'
|