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