texplay 0.2.981 → 0.2.983pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +8 -0
- data/README.markdown +1 -1
- data/Rakefile +13 -4
- data/examples/example_blank.rb +19 -2
- data/examples/example_select.rb +25 -17
- data/examples/example_select2.rb +28 -0
- data/examples/example_splice.rb +2 -2
- data/examples/example_tiles.rb +1 -1
- data/examples/example_window_to_blob.rb +39 -0
- data/ext/texplay/bindings.c +20 -0
- data/ext/texplay/graphics_utils.c +8 -3
- data/ext/texplay/texplay.c +120 -100
- data/ext/texplay/utils.c +1 -1
- data/lib/texplay.rb +34 -12
- data/lib/texplay/patches.rb +4 -0
- data/lib/texplay/version.rb +1 -1
- data/spec/image_spec.rb +7 -0
- data/spec/texplay_spec.rb +80 -0
- metadata +16 -9
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
*27/9/10
|
2
|
+
version 0.2.983pre1
|
3
|
+
* added Window#to_blob(x,y,width,height), grab a screenshot region
|
4
|
+
*24/9/10
|
5
|
+
version 0.2.982pre1
|
6
|
+
* added :default drawing mode (equivalent to :mode => nil)
|
7
|
+
* changed Linux texture size to 512
|
8
|
+
|
1
9
|
16/8/10
|
2
10
|
version 0.2.981
|
3
11
|
* oops, added :caching => false to TexPlay#dup
|
data/README.markdown
CHANGED
data/Rakefile
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
$LOAD_PATH.unshift File.join(File.expand_path(__FILE__), '..')
|
1
2
|
|
2
3
|
require 'rake/clean'
|
3
4
|
require 'rake/gempackagetask'
|
@@ -27,8 +28,8 @@ specification = Gem::Specification.new do |s|
|
|
27
28
|
|
28
29
|
s.extensions = ["ext/texplay/extconf.rb"]
|
29
30
|
s.files = ["Rakefile", "README.markdown", "CHANGELOG",
|
30
|
-
"lib/texplay.rb", "lib/texplay-contrib.rb", "lib/texplay/version.rb"] +
|
31
|
-
FileList["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c", "examples/*.rb", "examples/media/*"].to_a
|
31
|
+
"lib/texplay.rb", "lib/texplay-contrib.rb", "lib/texplay/version.rb", "lib/texplay/patches.rb"] +
|
32
|
+
FileList["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c", "examples/*.rb", "examples/media/*", "spec/*.rb"].to_a
|
32
33
|
end
|
33
34
|
|
34
35
|
# Rake::ExtensionTask.new('texplay', specification) do |ext|
|
@@ -57,12 +58,20 @@ end
|
|
57
58
|
# s.has_rdoc = false
|
58
59
|
|
59
60
|
# s.files = ["Rakefile", "README.markdown", "CHANGELOG",
|
60
|
-
# "lib/texplay.rb", "lib/texplay-contrib.rb",
|
61
|
+
# "lib/texplay.rb", "lib/texplay-contrib.rb",
|
62
|
+
# "lib/texplay/version.rb",
|
63
|
+
# "lib/texplay/patches.rb",
|
64
|
+
# "lib/1.8/texplay.so",
|
61
65
|
# "lib/1.9/texplay.so"] +
|
62
|
-
# FileList["examples/*.rb", "examples/media/*"].to_a
|
66
|
+
# FileList["examples/*.rb", "examples/media/*", "spec/*.rb"].to_a
|
63
67
|
# end
|
64
68
|
|
65
69
|
Rake::GemPackageTask.new(specification) do |package|
|
66
70
|
package.need_zip = false
|
67
71
|
package.need_tar = false
|
68
72
|
end
|
73
|
+
|
74
|
+
desc "Run rspec 2.0"
|
75
|
+
task :rspec do
|
76
|
+
system "rspec spec/**/*_spec.rb"
|
77
|
+
end
|
data/examples/example_blank.rb
CHANGED
@@ -7,11 +7,28 @@ require 'texplay'
|
|
7
7
|
class W < Gosu::Window
|
8
8
|
def initialize
|
9
9
|
super(500, 500, false, 20)
|
10
|
-
@img = TexPlay.create_image(self,
|
10
|
+
@img = TexPlay.create_image(self, 50, 50, :color => Gosu::Color::BLUE)
|
11
|
+
@img2 = TexPlay.create_image(self, 50, 50, :color => Gosu::Color::RED)
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
def update
|
16
|
+
|
11
17
|
end
|
12
18
|
|
13
19
|
def draw
|
14
|
-
@img.draw
|
20
|
+
@img.draw 0, 0,1
|
21
|
+
@img2.draw 100, 100,1
|
22
|
+
if button_down?(Gosu::KbEscape)
|
23
|
+
# self.flush
|
24
|
+
@blob = self.to_blob(0,self.height - 70, 50, 50)
|
25
|
+
if @blob
|
26
|
+
@img3 = TexPlay.from_blob(self, @blob,50, 50 )
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
@img3.draw rand(300), rand(300), 1 if @img3
|
31
|
+
500000.times {}
|
15
32
|
end
|
16
33
|
|
17
34
|
end
|
data/examples/example_select.rb
CHANGED
@@ -5,26 +5,34 @@ require 'texplay'
|
|
5
5
|
|
6
6
|
|
7
7
|
class W < Gosu::Window
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
8
|
+
def initialize
|
9
|
+
super(500, 500, false, 20)
|
10
|
+
|
11
|
+
# draw a filled rect with left region blue, and right region red
|
12
|
+
# at top and yellow at bottom
|
13
|
+
@img = TexPlay.create_image(self, 500, 500, :color => Gosu::Color::BLUE)
|
14
|
+
@img.rect 250,0, 500, 500, :color => :red, :fill => true
|
15
|
+
@img.rect 250, 250, 500, 500, :color => :yellow, :fill => true
|
16
|
+
|
17
|
+
# base rect is green on left and purple on right
|
18
|
+
@base = TexPlay.create_image(self, 500, 500, :color => :green)
|
19
|
+
@base.rect 250,0, 500, 500, :color => :purple, :fill => true
|
20
|
+
|
21
|
+
# splice @img into @base, and select the yellow part of @img to
|
22
|
+
# go into the purple part of @base
|
23
|
+
# a combination of source_select
|
24
|
+
# and dest_select - filtering both source and destination pixels
|
25
|
+
@base.splice @img, 0, 0, :dest_select => :purple, :source_select => :yellow
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
def draw
|
30
|
+
@base.draw 0, 0,1
|
31
|
+
end
|
18
32
|
|
19
|
-
end
|
20
|
-
|
21
|
-
def draw
|
22
|
-
@img.draw 100, 50,1
|
23
|
-
end
|
24
|
-
|
25
33
|
end
|
26
34
|
|
27
35
|
|
28
36
|
w = W.new
|
29
37
|
w.show
|
30
|
-
|
38
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
require 'common'
|
4
|
+
require 'gosu'
|
5
|
+
require 'texplay'
|
6
|
+
require 'benchmark'
|
7
|
+
|
8
|
+
|
9
|
+
class W < Gosu::Window
|
10
|
+
def initialize
|
11
|
+
super(500, 500, false, 20)
|
12
|
+
@img = Gosu::Image.new(self, "#{Common::MEDIA}/sunset.png")
|
13
|
+
@maria = Gosu::Image.new(self, "#{Common::MEDIA}/maria.png")
|
14
|
+
@img.rect 0,0, @img.width - 1, @img.height - 1
|
15
|
+
@img.splice @maria, 0, 0, :tolerance => 0.70, :source_select => [:brown,:yellow], :crop => [200, 50, 500, 800]
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
def draw
|
20
|
+
@img.draw 0, 0,1
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
w = W.new
|
27
|
+
w.show
|
28
|
+
|
data/examples/example_splice.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
|
2
2
|
require 'rubygems'
|
3
|
-
require 'common'
|
3
|
+
require './common'
|
4
4
|
require 'texplay'
|
5
5
|
|
6
6
|
|
@@ -10,7 +10,7 @@ class W < Gosu::Window
|
|
10
10
|
@img = Gosu::Image.new(self, "#{Common::MEDIA}/texplay.png")
|
11
11
|
@gosu = Gosu::Image.new(self, "#{Common::MEDIA}/gosu.png")
|
12
12
|
|
13
|
-
@img.splice @gosu, 140,20, :alpha_blend => true
|
13
|
+
@img.splice @gosu, 140,20, :alpha_blend => true, :mode => :default
|
14
14
|
@img.rect 140,20, 160, 180, :color => [1,1,1,0.5], :alpha_blend => true, :fill => true
|
15
15
|
|
16
16
|
@img.splice @gosu, 50,20, :chroma_key => :alpha
|
data/examples/example_tiles.rb
CHANGED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'common'
|
3
|
+
require 'gosu'
|
4
|
+
require 'texplay'
|
5
|
+
|
6
|
+
|
7
|
+
class W < Gosu::Window
|
8
|
+
def initialize
|
9
|
+
super(500, 500, false, 20)
|
10
|
+
@img = TexPlay.create_image(self, 50, 50, :color => Gosu::Color::BLUE)
|
11
|
+
@img2 = TexPlay.create_image(self, 50, 50, :color => Gosu::Color::RED)
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
def update
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
def draw
|
20
|
+
@img.draw 0, 0,1
|
21
|
+
@img2.draw 100, 100,1
|
22
|
+
if button_down?(Gosu::KbEscape)
|
23
|
+
# self.flush
|
24
|
+
@blob = self.to_blob(0,self.height - 70, 50, 50)
|
25
|
+
if @blob
|
26
|
+
@img3 = TexPlay.from_blob(self, @blob,50, 50 )
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
@img3.draw rand(300), rand(300), 1 if @img3
|
31
|
+
500000.times {}
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
w = W.new
|
38
|
+
w.show
|
39
|
+
|
data/ext/texplay/bindings.c
CHANGED
@@ -112,6 +112,24 @@ M_refresh_cache_all(VALUE self)
|
|
112
112
|
return Qnil;
|
113
113
|
}
|
114
114
|
|
115
|
+
/* VALUE */
|
116
|
+
/* M_screenshot(VALUE self, VALUE x, VALUE y, VALUE width, VALUE width) */
|
117
|
+
/* { */
|
118
|
+
/* texture_info tex; */
|
119
|
+
/* int sidelength; */
|
120
|
+
/* int rb_x = FIX2INT(x); */
|
121
|
+
/* int rb_y = FIX2INT(y); */
|
122
|
+
/* int rb_width = FIX2INT(width); */
|
123
|
+
/* int rb_height = FIX2INT(height); */
|
124
|
+
|
125
|
+
/* VALUE blob = rb_str_new(NULL, 4 * rb_width * rb_height); */
|
126
|
+
|
127
|
+
/* glReadPixels(rb_x, rb_y, rb_width, rb_height, GL_RGBA, GL_UNSIGNED_BYTE, RSTRING_PTR(blob)); */
|
128
|
+
|
129
|
+
/* return blob; */
|
130
|
+
/* } */
|
131
|
+
|
132
|
+
|
115
133
|
/* creates a blank image */
|
116
134
|
/* VALUE */
|
117
135
|
/* M_create_blank(VALUE self, VALUE window, VALUE width, VALUE height) */
|
@@ -347,6 +365,8 @@ get_image_chunk_with_size(char * data, texture_info * tex, char * blob)
|
|
347
365
|
}
|
348
366
|
}
|
349
367
|
|
368
|
+
|
369
|
+
|
350
370
|
VALUE
|
351
371
|
m_to_blob(VALUE self)
|
352
372
|
{
|
@@ -169,7 +169,7 @@ skip_pixel(rgba source_color, action_struct * payload, texture_info * tex, int x
|
|
169
169
|
color_match = true;
|
170
170
|
break;
|
171
171
|
}
|
172
|
-
|
172
|
+
if (!color_match) return true;
|
173
173
|
}
|
174
174
|
}
|
175
175
|
|
@@ -230,7 +230,7 @@ set_pixel_color_with_style(action_struct * payload, texture_info * tex, int x, i
|
|
230
230
|
if(payload->pen.has_color_control_proc)
|
231
231
|
blended_pixel = exec_color_control_proc(payload, tex, x, y, blended_pixel);
|
232
232
|
|
233
|
-
/* should skip this pixel? */
|
233
|
+
/* should skip this pixel? color selection */
|
234
234
|
if (skip_pixel(blended_pixel, payload, tex, x, y))
|
235
235
|
return;
|
236
236
|
|
@@ -489,7 +489,12 @@ prepare_drawing_mode(action_struct * cur)
|
|
489
489
|
|
490
490
|
Check_Type(draw_mode, T_SYMBOL);
|
491
491
|
|
492
|
-
if(draw_mode == string2sym("
|
492
|
+
if(draw_mode == string2sym("default")) {
|
493
|
+
cur->pen.has_drawing_mode = false;
|
494
|
+
|
495
|
+
return;
|
496
|
+
}
|
497
|
+
else if(draw_mode == string2sym("clear"))
|
493
498
|
cur->pen.drawing_mode = clear;
|
494
499
|
|
495
500
|
else if(draw_mode == string2sym("copy"))
|
data/ext/texplay/texplay.c
CHANGED
@@ -24,145 +24,165 @@
|
|
24
24
|
/** constructor for TPPoint class **/
|
25
25
|
static VALUE m_init_TPPoint(int argc, VALUE * argv, VALUE self);
|
26
26
|
static void monkey_patch_gosu(void);
|
27
|
+
static VALUE gosu_window(void);
|
27
28
|
|
28
29
|
void
|
29
30
|
Init_texplay() {
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
32
|
+
VALUE jm_Module = rb_define_module("TexPlay");
|
33
|
+
VALUE TPPoint = rb_define_class_under(jm_Module, "TPPoint", rb_cObject);
|
34
|
+
|
35
|
+
/** define basic point class TPPoint **/
|
36
|
+
rb_attr(TPPoint, rb_intern("x"), 1, 1, Qtrue);
|
37
|
+
rb_attr(TPPoint, rb_intern("y"), 1, 1, Qtrue);
|
38
|
+
rb_define_method(TPPoint, "initialize", m_init_TPPoint, -1);
|
39
|
+
/** end of TPPoint definition **/
|
40
|
+
|
41
|
+
/* TexPlay methods */
|
42
|
+
rb_define_method(jm_Module, "paint", m_paint, -1);
|
43
|
+
rb_define_method(jm_Module, "get_pixel", m_getpixel, -1);
|
44
|
+
rb_define_method(jm_Module, "circle", m_circle, -1);
|
45
|
+
rb_define_method(jm_Module, "line", m_line, -1);
|
46
|
+
rb_define_method(jm_Module, "rect", m_rect, -1);
|
47
|
+
rb_define_method(jm_Module, "pixel", m_pixel, -1);
|
48
|
+
rb_define_method(jm_Module, "fill", m_flood_fill, -1);
|
49
|
+
rb_define_method(jm_Module, "bezier", m_bezier, -1);
|
50
|
+
rb_define_method(jm_Module, "polyline", m_polyline, -1);
|
51
|
+
rb_define_method(jm_Module, "ngon", m_ngon, -1);
|
51
52
|
|
52
|
-
|
53
|
+
rb_define_method(jm_Module, "splice", m_splice, -1);
|
53
54
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
55
|
+
rb_define_method(jm_Module, "color", m_color, -1);
|
56
|
+
rb_define_method(jm_Module, "offset", m_offset, -1);
|
57
|
+
rb_define_method(jm_Module, "method_missing", m_missing, -1);
|
58
|
+
rb_define_method(jm_Module, "quad_cached?", m_quad_cached, 0);
|
58
59
|
|
59
|
-
|
60
|
+
rb_define_method(jm_Module, "each", m_each, -1);
|
60
61
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
62
|
+
/* needs to be updated, not yet done **/
|
63
|
+
/* rb_define_method(jm_Module, "bitmask", m_bitmask, -1); */
|
64
|
+
/* rb_define_method(jm_Module, "leftshift", m_lshift, -1); */
|
65
|
+
/* rb_define_method(jm_Module, "rightshift", m_rshift, -1); */
|
66
|
+
/* rb_define_method(jm_Module, "[]=", m_special_pixel, -1); */
|
67
|
+
|
68
|
+
rb_define_method(jm_Module, "dup", m_dup_image, 0);
|
69
|
+
rb_define_method(jm_Module, "clone", m_clone_image, 0);
|
70
|
+
rb_define_method(jm_Module, "to_blob", m_to_blob, 0);
|
71
|
+
rb_define_method(jm_Module, "force_sync", m_force_sync, 1);
|
72
|
+
rb_define_method(jm_Module, "set_options", m_user_set_options, 1);
|
73
|
+
rb_define_method(jm_Module, "get_options", m_get_options, 0);
|
74
|
+
rb_define_method(jm_Module, "delete_options", m_user_delete_options, 0);
|
75
|
+
|
76
|
+
rb_define_method(jm_Module, "refresh_cache", m_cache_refresh, 0);
|
76
77
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
78
|
+
/* a constant containing the sidelength of largest allowable quad */
|
79
|
+
rb_define_const(jm_Module, "TP_MAX_QUAD_SIZE", INT2FIX(max_quad_size() - 2));
|
80
|
+
|
81
|
+
/* singleton method for creating & removing macros */
|
82
|
+
rb_define_singleton_method(jm_Module, "create_macro", M_create_macro, 1);
|
83
|
+
rb_define_singleton_method(jm_Module, "remove_macro", M_remove_macro, 1);
|
84
|
+
rb_define_singleton_method(jm_Module, "refresh_cache_all", M_refresh_cache_all, 0);
|
85
|
+
/* rb_define_singleton_method(jm_Module, "create_blank_image", M_create_blank, 3); */
|
86
|
+
|
87
|
+
/** aliases; must be made on singleton class because we're using class methods **/
|
88
|
+
rb_define_method(jm_Module, "box", m_rect, -1);
|
89
|
+
rb_define_method(jm_Module, "colour", m_color, -1);
|
90
|
+
rb_define_method(jm_Module, "composite", m_splice, -1);
|
91
|
+
rb_define_method(jm_Module, "set_pixel", m_pixel, -1);
|
92
|
+
rb_define_method(jm_Module, "[]", m_getpixel, -1);
|
93
|
+
rb_define_method(jm_Module, "cache", m_cache_refresh, 0);
|
94
|
+
/** end of aliases **/
|
95
|
+
|
96
|
+
/** associated with gen_eval **/
|
97
|
+
rb_define_method(rb_cObject, "gen_eval", rb_gen_eval, -1);
|
98
|
+
rb_define_method(rb_cObject, "capture", rb_capture, 0);
|
98
99
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
100
|
+
rb_define_method(rb_cObject, "to_module", rb_to_module , 0);
|
101
|
+
rb_define_method(rb_cObject, "reset_tbls", rb_reset_tbls , 0);
|
102
|
+
rb_define_method(rb_cObject, "gen_extend", rb_gen_extend, -1);
|
103
|
+
rb_define_method(rb_cModule, "gen_include", rb_gen_include, -1);
|
103
104
|
|
104
|
-
|
105
|
-
|
105
|
+
rb_define_alias(rb_cObject, "gen_eval_with", "gen_eval");
|
106
|
+
/** end of gen_eval defs **/
|
106
107
|
|
107
108
|
|
108
|
-
|
109
|
+
/** basic setup **/
|
109
110
|
|
110
|
-
|
111
|
-
|
111
|
+
/* seed the random number generator */
|
112
|
+
srand(time(NULL));
|
112
113
|
|
113
|
-
|
114
|
-
|
114
|
+
monkey_patch_gosu();
|
115
|
+
/** end basic setup **/
|
115
116
|
}
|
116
117
|
|
117
118
|
/** constructor for TPPoint class **/
|
118
119
|
static VALUE
|
119
120
|
m_init_TPPoint(int argc, VALUE * argv, VALUE self)
|
120
121
|
{
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
}
|
130
|
-
else
|
131
|
-
rb_raise(rb_eArgError, "must provide two numbers");
|
122
|
+
if(argc == 0) {
|
123
|
+
rb_iv_set(self, "@x", INT2FIX(0));
|
124
|
+
rb_iv_set(self, "@y", INT2FIX(0));
|
125
|
+
}
|
126
|
+
else if(argc == 2){
|
127
|
+
if(is_a_num(argv[0]) && is_a_num(argv[1])) {
|
128
|
+
rb_iv_set(self, "@x", argv[0]);
|
129
|
+
rb_iv_set(self, "@y", argv[1]);
|
132
130
|
}
|
133
131
|
else
|
134
|
-
|
132
|
+
rb_raise(rb_eArgError, "must provide two numbers");
|
133
|
+
}
|
134
|
+
else
|
135
|
+
rb_raise(rb_eArgError, "please provide x and y args only");
|
135
136
|
|
136
|
-
|
137
|
+
return Qnil;
|
137
138
|
|
138
139
|
}
|
139
140
|
/** end constructor for TPPoint **/
|
140
141
|
|
141
142
|
|
142
143
|
static VALUE
|
143
|
-
gosu_window_to_blob(VALUE self)
|
144
|
+
gosu_window_to_blob(VALUE self, VALUE x, VALUE y, VALUE width, VALUE height)
|
144
145
|
{
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
blob = rb_str_new(NULL, 4 * width * height);
|
152
|
-
|
153
|
-
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, RSTRING_PTR(blob));
|
146
|
+
int rb_x = FIX2INT(x);
|
147
|
+
int rb_y = FIX2INT(y);
|
148
|
+
int rb_width = FIX2INT(width);
|
149
|
+
int rb_height = FIX2INT(height);
|
150
|
+
int window_height = FIX2INT(rb_funcall(self, rb_intern("height"), 0));
|
154
151
|
|
155
|
-
|
152
|
+
VALUE blob = rb_str_new(NULL, 4 * rb_width * rb_height);
|
153
|
+
|
154
|
+
glFinish();
|
155
|
+
rb_funcall(self, rb_intern("flush"), 0);
|
156
|
+
|
157
|
+
glReadPixels(rb_x, rb_y, rb_width, rb_height, GL_RGBA,
|
158
|
+
GL_UNSIGNED_BYTE, RSTRING_PTR(blob));
|
159
|
+
|
160
|
+
return blob;
|
156
161
|
}
|
157
162
|
|
158
163
|
static void
|
159
164
|
monkey_patch_gosu(void)
|
160
165
|
{
|
166
|
+
rb_define_method(gosu_window(), "to_blob", gosu_window_to_blob, 4);
|
167
|
+
}
|
168
|
+
|
169
|
+
static VALUE
|
170
|
+
gosu_window(void)
|
171
|
+
{
|
172
|
+
static VALUE GosuWindow = 0;
|
173
|
+
|
174
|
+
if (!GosuWindow) {
|
161
175
|
VALUE Gosu = rb_const_get(rb_cObject, rb_intern("Gosu"));
|
162
|
-
|
176
|
+
GosuWindow = rb_const_get(Gosu, rb_intern("Window"));
|
177
|
+
}
|
178
|
+
|
179
|
+
return GosuWindow;
|
180
|
+
}
|
163
181
|
|
164
|
-
|
165
|
-
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
|
166
186
|
|
167
187
|
|
168
188
|
|
data/ext/texplay/utils.c
CHANGED
data/lib/texplay.rb
CHANGED
@@ -12,6 +12,7 @@ direc = File.dirname(__FILE__)
|
|
12
12
|
require 'rbconfig'
|
13
13
|
require 'gosu'
|
14
14
|
require "#{direc}/texplay/version"
|
15
|
+
require "#{direc}/texplay/patches"
|
15
16
|
|
16
17
|
module TexPlay
|
17
18
|
class << self
|
@@ -35,6 +36,8 @@ module TexPlay
|
|
35
36
|
:color => :alpha,
|
36
37
|
:caching => false,
|
37
38
|
}.merge!(options)
|
39
|
+
|
40
|
+
raise ArgumentError, "Height and width must be positive" if height <= 0 or width <= 0
|
38
41
|
|
39
42
|
img = Gosu::Image.new(window, EmptyImageStub.new(width, height), :caching => options[:caching])
|
40
43
|
img.rect 0, 0, img.width - 1, img.height - 1, :color => options[:color], :fill => true
|
@@ -44,6 +47,23 @@ module TexPlay
|
|
44
47
|
|
45
48
|
alias_method :create_blank_image, :create_image
|
46
49
|
|
50
|
+
# Image can be :tileable, but it will break if it is tileable AND gets modified after creation.
|
51
|
+
def from_blob(window, blob_data, width, height, options={})
|
52
|
+
options = {
|
53
|
+
:caching => @options[:caching],
|
54
|
+
:tileable => false,
|
55
|
+
}.merge!(options)
|
56
|
+
|
57
|
+
raise ArgumentError, "Height and width must be positive (received #{width}x#{height})" if height <= 0 or width <= 0
|
58
|
+
|
59
|
+
expected_size = height * width * 4
|
60
|
+
if blob_data.size != expected_size
|
61
|
+
raise ArgumentError, "Blob data is not of the correct size (expected #{expected_size} but received #{blob_data.size} bytes)"
|
62
|
+
end
|
63
|
+
|
64
|
+
Gosu::Image.new(window, ImageStub.new(blob_data, width, height), options[:tileable], :caching => options[:caching])
|
65
|
+
end
|
66
|
+
|
47
67
|
def set_options(options = {})
|
48
68
|
@options.merge!(options)
|
49
69
|
end
|
@@ -100,22 +120,24 @@ module TexPlay
|
|
100
120
|
|
101
121
|
end
|
102
122
|
|
103
|
-
#
|
104
|
-
class
|
105
|
-
|
106
|
-
@w, @h = w, h
|
107
|
-
end
|
123
|
+
# Used to create images from blob data.
|
124
|
+
class ImageStub
|
125
|
+
attr_reader :rows, :columns
|
108
126
|
|
109
|
-
def
|
110
|
-
|
127
|
+
def initialize(blob_data, width, height)
|
128
|
+
@data, @columns, @rows = blob_data, width, height
|
111
129
|
end
|
112
130
|
|
113
|
-
def
|
114
|
-
@
|
131
|
+
def to_blob
|
132
|
+
@data
|
115
133
|
end
|
116
|
-
|
117
|
-
|
118
|
-
|
134
|
+
end
|
135
|
+
|
136
|
+
# Used to create blank images.
|
137
|
+
# credit to philomory for this class
|
138
|
+
class EmptyImageStub < ImageStub
|
139
|
+
def initialize(width, height)
|
140
|
+
super("\0" * (width * height * 4), width, height)
|
119
141
|
end
|
120
142
|
end
|
121
143
|
|
data/lib/texplay/version.rb
CHANGED
data/spec/image_spec.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
$LOAD_PATH.unshift File.join(File.expand_path(__FILE__), '..', 'lib','texplay')
|
2
|
+
|
3
|
+
require 'texplay'
|
4
|
+
|
5
|
+
describe TexPlay do
|
6
|
+
before :each do
|
7
|
+
@window = Gosu::Window.new(640, 480, false)
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#create_image" do
|
11
|
+
it "should create a blank image of the correct size" do
|
12
|
+
width, height = 30, 10
|
13
|
+
image = described_class.create_image(@window, width, height)
|
14
|
+
|
15
|
+
image.width.should == width
|
16
|
+
image.height.should == height
|
17
|
+
|
18
|
+
width.times do |x|
|
19
|
+
height.times do |y|
|
20
|
+
image.get_pixel(x, y).should == [0.0, 0.0, 0.0, 0.0]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should create a coloured image of the correct size" do
|
26
|
+
width, height = 10, 30
|
27
|
+
color = [1.0, 1.0, 0.0, 1.0]
|
28
|
+
image = described_class.create_image(@window, width, height, :color => color)
|
29
|
+
|
30
|
+
image.width.should == width
|
31
|
+
image.height.should == height
|
32
|
+
|
33
|
+
width.times do |x|
|
34
|
+
height.times do |y|
|
35
|
+
image.get_pixel(x, y).should == color
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should raise an error if an image dimension is 0 or less" do
|
41
|
+
lambda { described_class.create_image(@window, 0, 0)}.should raise_error ArgumentError
|
42
|
+
end
|
43
|
+
|
44
|
+
# TODO: Should probably be an ArgumentError.
|
45
|
+
it "should raise an error if the image would be too large" do
|
46
|
+
too_big = TexPlay::TP_MAX_QUAD_SIZE + 1
|
47
|
+
[[too_big, 5], [10, too_big], [too_big, too_big]].each do |width, height|
|
48
|
+
lambda { described_class.create_image(@window, width, height)}.should raise_error Exception
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#from_blob" do
|
54
|
+
it "should create an image with the requested pixel data and size" do
|
55
|
+
# 4 x 3, with columns of red, blue, green, transparent.
|
56
|
+
gosu_colors = [[255, 0, 0, 255], [0, 255, 0, 255], [0, 0, 255, 255], [0, 0, 0, 0]]
|
57
|
+
texplay_colors = gosu_colors.map {|a| a.map {|c| c / 255.0 } }
|
58
|
+
width, height = gosu_colors.size, 3
|
59
|
+
|
60
|
+
image = described_class.from_blob(@window, (gosu_colors * height).flatten.pack('C*'), width, height)
|
61
|
+
|
62
|
+
image.width.should == width
|
63
|
+
image.height.should == height
|
64
|
+
|
65
|
+
texplay_colors.each_with_index do |color, x|
|
66
|
+
3.times do |y|
|
67
|
+
image.get_pixel(x, y).should == color
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should raise an error if the image size is not correct for the blob data" do
|
73
|
+
lambda { described_class.from_blob(@window, [1, 1, 1, 1].pack("C*"), 2, 1) }.should raise_error ArgumentError
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should raise an error if an image dimension is 0 or less" do
|
77
|
+
lambda { described_class.from_blob(@window, '', 0, 0) }.should raise_error ArgumentError
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: texplay
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: -1037985743
|
5
|
+
prerelease: true
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 983pre1
|
10
|
+
version: 0.2.983pre1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- John Mair (banisterfiend)
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-09-27 00:00:00 +13:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -49,6 +49,7 @@ files:
|
|
49
49
|
- lib/texplay.rb
|
50
50
|
- lib/texplay-contrib.rb
|
51
51
|
- lib/texplay/version.rb
|
52
|
+
- lib/texplay/patches.rb
|
52
53
|
- ext/texplay/extconf.rb
|
53
54
|
- ext/texplay/actions.h
|
54
55
|
- ext/texplay/bindings.h
|
@@ -94,6 +95,7 @@ files:
|
|
94
95
|
- examples/example_polyline.rb
|
95
96
|
- examples/example_scale.rb
|
96
97
|
- examples/example_select.rb
|
98
|
+
- examples/example_select2.rb
|
97
99
|
- examples/example_simple.rb
|
98
100
|
- examples/example_splice.rb
|
99
101
|
- examples/example_sync.rb
|
@@ -104,6 +106,7 @@ files:
|
|
104
106
|
- examples/example_transparent3.rb
|
105
107
|
- examples/example_turtle.rb
|
106
108
|
- examples/example_weird.rb
|
109
|
+
- examples/example_window_to_blob.rb
|
107
110
|
- examples/media/bird.png
|
108
111
|
- examples/media/body.png
|
109
112
|
- examples/media/empty2.png
|
@@ -118,6 +121,8 @@ files:
|
|
118
121
|
- examples/media/sand1.png
|
119
122
|
- examples/media/sunset.png
|
120
123
|
- examples/media/texplay.png
|
124
|
+
- spec/image_spec.rb
|
125
|
+
- spec/texplay_spec.rb
|
121
126
|
has_rdoc: true
|
122
127
|
homepage: http://banisterfiend.wordpress.com/2008/08/23/texplay-an-image-manipulation-tool-for-ruby-and-gosu/
|
123
128
|
licenses: []
|
@@ -139,12 +144,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
139
144
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
145
|
none: false
|
141
146
|
requirements:
|
142
|
-
- - "
|
147
|
+
- - ">"
|
143
148
|
- !ruby/object:Gem::Version
|
144
|
-
hash:
|
149
|
+
hash: 25
|
145
150
|
segments:
|
146
|
-
-
|
147
|
-
|
151
|
+
- 1
|
152
|
+
- 3
|
153
|
+
- 1
|
154
|
+
version: 1.3.1
|
148
155
|
requirements: []
|
149
156
|
|
150
157
|
rubyforge_project:
|