texplay 0.2.983pre2-i386-mingw32 → 0.3.0-i386-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +41 -49
- data/examples/common.rb +13 -2
- data/examples/example_alpha_blend.rb +1 -3
- data/examples/example_bezier.rb +1 -2
- data/examples/example_blank.rb +1 -3
- data/examples/example_cache.rb +1 -3
- data/examples/example_color_transform.rb +1 -3
- data/examples/example_color_transform_circle.rb +1 -3
- data/examples/example_darken.rb +1 -4
- data/examples/example_dup.rb +1 -4
- data/examples/example_each.rb +1 -4
- data/examples/example_effect.rb +1 -2
- data/examples/example_fill.rb +1 -2
- data/examples/example_fill_old.rb +1 -2
- data/examples/example_fluent.rb +1 -3
- data/examples/example_font.rb +1 -3
- data/examples/example_gen_eval.rb +1 -2
- data/examples/example_hash_arguments.rb +1 -2
- data/examples/example_ippa.rb +1 -3
- data/examples/example_light.rb +1 -3
- data/examples/example_light_multiply.rb +1 -3
- data/examples/example_lsystem.rb +1 -1
- data/examples/example_melt.rb +1 -3
- data/examples/example_meyet.rb +1 -3
- data/examples/example_polyline.rb +1 -2
- data/examples/example_scale.rb +1 -3
- data/examples/example_select.rb +1 -3
- data/examples/example_select2.rb +1 -4
- data/examples/example_simple.rb +1 -3
- data/examples/example_splice.rb +2 -4
- data/examples/example_sync.rb +1 -2
- data/examples/example_tiles.rb +1 -3
- data/examples/example_trace.rb +1 -2
- data/examples/example_transparent.rb +1 -3
- data/examples/example_transparent2.rb +1 -3
- data/examples/example_transparent3.rb +1 -3
- data/examples/example_turtle.rb +1 -2
- data/examples/example_weird.rb +1 -2
- data/examples/example_window_render_to_image.rb +41 -0
- data/examples/example_window_to_blob.rb +2 -5
- data/ext/texplay/actions.c +1006 -0
- data/ext/texplay/actions.h +60 -0
- data/ext/texplay/bindings.c +1186 -0
- data/ext/texplay/bindings.h +46 -0
- data/ext/texplay/cache.c +118 -0
- data/ext/texplay/cache.h +24 -0
- data/ext/texplay/compat.h +27 -0
- data/ext/texplay/extconf.rb +28 -0
- data/ext/texplay/gen_eval.c +211 -0
- data/ext/texplay/gen_eval.h +20 -0
- data/ext/texplay/graphics_utils.c +1244 -0
- data/ext/texplay/graphics_utils.h +22 -0
- data/ext/texplay/object2module.c +171 -0
- data/ext/texplay/object2module.h +11 -0
- data/ext/texplay/texplay.c +216 -0
- data/ext/texplay/texplay.h +148 -0
- data/ext/texplay/utils.c +887 -0
- data/ext/texplay/utils.h +153 -0
- data/lib/1.8/texplay.so +0 -0
- data/lib/1.9/texplay.so +0 -0
- data/lib/texplay.rb +271 -165
- data/lib/texplay/c_function_docs.rb +189 -0
- data/lib/texplay/version.rb +1 -1
- metadata +33 -21
- data/examples/example_window_to_texture.rb +0 -55
- data/lib/texplay/patches.rb +0 -4
data/ext/texplay/utils.h
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
#ifndef GUARD_UTILS_H
|
2
|
+
#define GUARD_UTILS_H
|
3
|
+
|
4
|
+
|
5
|
+
/* for use with get_image_local, and set_image_local */
|
6
|
+
#define DRAW_OFFSET 0
|
7
|
+
#define LAZY_BOUNDS 1
|
8
|
+
#define IMAGE_COLOR 2
|
9
|
+
#define USER_DEFAULTS 3
|
10
|
+
|
11
|
+
/* shared global */
|
12
|
+
extern const rgba not_a_color_v;
|
13
|
+
|
14
|
+
/* color and pixel related functions */
|
15
|
+
rgba find_color_from_string(char * try_color);
|
16
|
+
bool cmp_color(rgba color1, rgba color2);
|
17
|
+
bool cmp_color_with_tolerance(rgba color1, rgba color2, float tolerance);
|
18
|
+
void color_copy(float * source, float * dest);
|
19
|
+
rgba get_pixel_color(texture_info * tex, int x, int y) ;
|
20
|
+
float* get_pixel_data(texture_info * tex, int x, int y);
|
21
|
+
void set_pixel_color(rgba * pixel_color, texture_info * tex, int x, int y);
|
22
|
+
void zero_color(float * tex);
|
23
|
+
bool not_a_color(rgba color1);
|
24
|
+
bool is_a_color(rgba color1);
|
25
|
+
VALUE convert_rgba_to_rb_color(rgba * pix);
|
26
|
+
rgba convert_rb_color_to_rgba(VALUE cval);
|
27
|
+
VALUE gosu_color_class();
|
28
|
+
bool is_gosu_color(VALUE try_color);
|
29
|
+
bool is_rb_raw_color(VALUE cval);
|
30
|
+
bool not_rb_raw_color(VALUE cval);
|
31
|
+
rgba convert_gosu_to_rgba_color(VALUE gcolor);
|
32
|
+
VALUE convert_rgba_to_gosu_color(rgba * pix);
|
33
|
+
|
34
|
+
|
35
|
+
VALUE save_rgba_to_image_local_color(VALUE image, rgba color);
|
36
|
+
rgba convert_image_local_color_to_rgba(VALUE image);
|
37
|
+
|
38
|
+
|
39
|
+
/* string/symbol related functions */
|
40
|
+
char* lowercase(char*);
|
41
|
+
char* sym2string(VALUE);
|
42
|
+
VALUE string2sym(char*);
|
43
|
+
|
44
|
+
/* is it a hash? */
|
45
|
+
bool is_a_hash(VALUE try_hash);
|
46
|
+
|
47
|
+
/* is an array? */
|
48
|
+
bool is_an_array(VALUE try_array);
|
49
|
+
|
50
|
+
/* is a num? */
|
51
|
+
bool is_a_num(VALUE try_num);
|
52
|
+
|
53
|
+
/* helpful C wrapper for rb_hash_aref */
|
54
|
+
VALUE get_from_hash(VALUE hash, char * sym);
|
55
|
+
|
56
|
+
/* a wrapper for rb_hash_aset */
|
57
|
+
VALUE set_hash_value(VALUE hash, char * sym, VALUE val);
|
58
|
+
|
59
|
+
/* a wrapper for rb_hash_delete */
|
60
|
+
VALUE delete_from_hash(VALUE hash, char * sym);
|
61
|
+
|
62
|
+
/* does the hash key 'sym' map to value 'val'? */
|
63
|
+
bool hash_value_is(VALUE hash, char * sym, VALUE val);
|
64
|
+
|
65
|
+
/* determine whether (1) hash is a T_HASH (2) the sym exists in the hash */
|
66
|
+
bool has_optional_hash_arg(VALUE hash, char * sym);
|
67
|
+
|
68
|
+
|
69
|
+
/* helpful C wrapper for rb_array_store */
|
70
|
+
VALUE set_array_value(VALUE array, int index, VALUE val);
|
71
|
+
|
72
|
+
/* helpful C wrapper for rb_array_entry */
|
73
|
+
VALUE get_from_array(VALUE array, int index);
|
74
|
+
|
75
|
+
/* set the lazy_bounds ivar for an image */
|
76
|
+
VALUE set_ivar_array(VALUE obj, char * ivar, int argc, ...);
|
77
|
+
|
78
|
+
/* initialize lazy_bounds */
|
79
|
+
void init_lazy_bounds(VALUE image);
|
80
|
+
|
81
|
+
/* initialize the image_local var array */
|
82
|
+
VALUE init_image_local(VALUE image);
|
83
|
+
|
84
|
+
/* return an image local variable */
|
85
|
+
VALUE get_image_local(VALUE image, int name);
|
86
|
+
|
87
|
+
/* set an image local variable */
|
88
|
+
void set_image_local(VALUE image, int name, VALUE val);
|
89
|
+
|
90
|
+
/* error checking functions */
|
91
|
+
void check_mask(VALUE mask);
|
92
|
+
|
93
|
+
void check_image(VALUE image);
|
94
|
+
|
95
|
+
/* is try_image a Gosu::Image ? */
|
96
|
+
bool is_gosu_image(VALUE try_image);
|
97
|
+
|
98
|
+
|
99
|
+
/* make boundaries sane */
|
100
|
+
void constrain_boundaries(int * x0, int * y0, int * x1, int * y1, int width, int height);
|
101
|
+
|
102
|
+
/* line clipping */
|
103
|
+
void cohen_sutherland_clip (int * x0, int * y0,int * x1, int * y1, int xmin, int ymin,
|
104
|
+
int xmax, int ymax);
|
105
|
+
|
106
|
+
/* check if point is bound by rect and inner thickness */
|
107
|
+
bool bound_by_rect_and_inner(int x, int y, int x0, int y0, int x1, int y1, int inner);
|
108
|
+
|
109
|
+
/* check if point is bound by rect */
|
110
|
+
bool bound_by_rect(int x, int y, int x0, int y0, int x1, int y1);
|
111
|
+
|
112
|
+
/* calculate the array offset for a given pixel */
|
113
|
+
int calc_pixel_offset(texture_info * tex, int x, int y);
|
114
|
+
|
115
|
+
/* calculate the array offset for a given pixel in an action context */
|
116
|
+
int calc_pixel_offset_for_action(action_struct * cur, texture_info * tex, int x, int y);
|
117
|
+
|
118
|
+
/* return a pointer to a new texture */
|
119
|
+
float* allocate_texture(int width, int height);
|
120
|
+
|
121
|
+
/* other function prototypes, get info for a texture */
|
122
|
+
void get_texture_info(VALUE image, texture_info * tex);
|
123
|
+
|
124
|
+
/* ensure gl_tex_info returns non nil */
|
125
|
+
VALUE check_for_texture_info(VALUE image);
|
126
|
+
|
127
|
+
/* responsible for syncing a subimage to gl */
|
128
|
+
void sync_to_gl(int tex_name, int x_offset, int y_offset, int width, int height, void * sub);
|
129
|
+
|
130
|
+
/* create a subtexture and sync to gl */
|
131
|
+
void create_subtexture_and_sync_to_gl(image_bounds * img_bounds, texture_info * tex);
|
132
|
+
|
133
|
+
float * get_image_chunk(texture_info * tex, int xmin, int ymin, int xmax, int ymax);
|
134
|
+
|
135
|
+
rgba get_pixel_color_from_chunk(float * chunk, int width, int height, int x, int y);
|
136
|
+
|
137
|
+
/* from Texture.cpp in Gosu Graphics folder */
|
138
|
+
unsigned max_quad_size(void);
|
139
|
+
|
140
|
+
/* point utils */
|
141
|
+
bool is_a_point(VALUE try_point);
|
142
|
+
VALUE point_x(VALUE point);
|
143
|
+
VALUE point_y(VALUE point);
|
144
|
+
|
145
|
+
/* mathematical utils, used by bezier curves */
|
146
|
+
double power(float base, int exp);
|
147
|
+
unsigned fact(int n);
|
148
|
+
unsigned comb(int n, int k);
|
149
|
+
unsigned perm(int n, int r);
|
150
|
+
|
151
|
+
double bernstein(int n, int k, float u);
|
152
|
+
|
153
|
+
#endif
|
data/lib/1.8/texplay.so
CHANGED
Binary file
|
data/lib/1.9/texplay.so
CHANGED
Binary file
|
data/lib/texplay.rb
CHANGED
@@ -1,225 +1,331 @@
|
|
1
1
|
|
2
2
|
# (C) John Mair 2009, under the MIT licence
|
3
3
|
|
4
|
-
|
5
|
-
require 'rubygems'
|
6
|
-
rescue LoadError
|
7
|
-
end
|
8
|
-
|
9
|
-
direc = File.dirname(__FILE__)
|
4
|
+
direc = File.expand_path(File.dirname(__FILE__))
|
10
5
|
|
11
6
|
# include gosu first
|
12
7
|
require 'rbconfig'
|
13
8
|
require 'gosu'
|
14
9
|
require "#{direc}/texplay/version"
|
15
|
-
require "#{direc}/texplay/patches"
|
16
10
|
|
17
11
|
module TexPlay
|
18
|
-
|
19
|
-
def on_setup(&block)
|
20
|
-
raise "need a block" if !block
|
21
|
-
|
22
|
-
@__init_procs__ ||= []
|
23
|
-
@__init_procs__.push(block)
|
24
|
-
end
|
25
|
-
|
26
|
-
def setup(receiver)
|
27
|
-
if @__init_procs__ then
|
28
|
-
@__init_procs__.each do |init_proc|
|
29
|
-
receiver.instance_eval(&init_proc)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def create_image(window, width, height, options={})
|
35
|
-
options = {
|
36
|
-
:color => :alpha,
|
37
|
-
:caching => false,
|
38
|
-
}.merge!(options)
|
12
|
+
RENDER_CLEAR_COLOR = Gosu::Color.new(255, 0, 0, 0)
|
39
13
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
14
|
+
class << self
|
15
|
+
def on_setup(&block)
|
16
|
+
raise "need a block" if !block
|
17
|
+
|
18
|
+
@__init_procs__ ||= []
|
19
|
+
@__init_procs__.push(block)
|
20
|
+
end
|
44
21
|
|
45
|
-
|
22
|
+
def setup(receiver)
|
23
|
+
if @__init_procs__ then
|
24
|
+
@__init_procs__.each do |init_proc|
|
25
|
+
receiver.instance_eval(&init_proc)
|
46
26
|
end
|
27
|
+
end
|
28
|
+
end
|
47
29
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
:caching => @options[:caching],
|
54
|
-
:tileable => false,
|
55
|
-
}.merge!(options)
|
30
|
+
def create_image(window, width, height, options={})
|
31
|
+
options = {
|
32
|
+
:color => :alpha,
|
33
|
+
:caching => false,
|
34
|
+
}.merge!(options)
|
56
35
|
|
57
|
-
|
36
|
+
raise ArgumentError, "Height and width must be positive" if height <= 0 or width <= 0
|
37
|
+
|
38
|
+
img = Gosu::Image.new(window, EmptyImageStub.new(width, height), :caching => options[:caching])
|
39
|
+
img.rect 0, 0, img.width - 1, img.height - 1, :color => options[:color], :fill => true
|
58
40
|
|
59
|
-
|
60
|
-
|
61
|
-
raise ArgumentError, "Blob data is not of the correct size (expected #{expected_size} but received #{blob_data.size} bytes)"
|
62
|
-
end
|
41
|
+
img
|
42
|
+
end
|
63
43
|
|
64
|
-
|
65
|
-
end
|
44
|
+
alias_method :create_blank_image, :create_image
|
66
45
|
|
67
|
-
|
68
|
-
|
69
|
-
|
46
|
+
# Image can be :tileable, but it will break if it is tileable AND gets modified after creation.
|
47
|
+
def from_blob(window, blob_data, width, height, options={})
|
48
|
+
options = {
|
49
|
+
:caching => @options[:caching],
|
50
|
+
:tileable => false,
|
51
|
+
}.merge!(options)
|
70
52
|
|
71
|
-
|
72
|
-
@options
|
73
|
-
end
|
53
|
+
raise ArgumentError, "Height and width must be positive (received #{width}x#{height})" if height <= 0 or width <= 0
|
74
54
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
}
|
80
|
-
end
|
55
|
+
expected_size = height * width * 4
|
56
|
+
if blob_data.size != expected_size
|
57
|
+
raise ArgumentError, "Blob data is not of the correct size (expected #{expected_size} but received #{blob_data.size} bytes)"
|
58
|
+
end
|
81
59
|
|
82
|
-
|
83
|
-
set_defaults
|
84
|
-
end
|
60
|
+
Gosu::Image.new(window, ImageStub.new(blob_data, width, height), options[:tileable], :caching => options[:caching])
|
85
61
|
end
|
86
62
|
|
87
|
-
|
88
|
-
|
89
|
-
Green = [0, 1, 0, 1]
|
90
|
-
Blue = [0, 0, 1, 1]
|
91
|
-
Black = [0, 0, 0, 1]
|
92
|
-
White = [1, 1, 1, 1]
|
93
|
-
Grey = [0.5, 0.5, 0.5, 1]
|
94
|
-
Alpha = [0, 0, 0, 0]
|
95
|
-
Purple = [1, 0, 1, 1]
|
96
|
-
Yellow = [1, 1, 0, 1]
|
97
|
-
Cyan = [0, 1, 1, 1]
|
98
|
-
Orange = [1, 0.5, 0, 1]
|
99
|
-
Brown = [0.39, 0.26, 0.13, 1]
|
100
|
-
Turquoise = [1, 0.6, 0.8, 1]
|
101
|
-
Tyrian = [0.4, 0.007, 0.235, 1]
|
63
|
+
def set_options(options = {})
|
64
|
+
@options.merge!(options)
|
102
65
|
end
|
103
|
-
include Colors
|
104
66
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
def clear(options = {})
|
109
|
-
options = {
|
110
|
-
:color => :alpha,
|
111
|
-
:fill => true
|
112
|
-
}.merge!(options)
|
67
|
+
def get_options
|
68
|
+
@options
|
69
|
+
end
|
113
70
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
71
|
+
# default values defined here
|
72
|
+
def set_defaults
|
73
|
+
@options = {
|
74
|
+
:caching => true
|
118
75
|
}
|
119
76
|
end
|
120
|
-
|
121
|
-
end
|
122
77
|
|
123
|
-
|
124
|
-
|
78
|
+
def init
|
79
|
+
set_defaults
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
module Colors
|
84
|
+
Red = [1, 0, 0, 1]
|
85
|
+
Green = [0, 1, 0, 1]
|
86
|
+
Blue = [0, 0, 1, 1]
|
87
|
+
Black = [0, 0, 0, 1]
|
88
|
+
White = [1, 1, 1, 1]
|
89
|
+
Grey = [0.5, 0.5, 0.5, 1]
|
90
|
+
Alpha = [0, 0, 0, 0]
|
91
|
+
Purple = [1, 0, 1, 1]
|
92
|
+
Yellow = [1, 1, 0, 1]
|
93
|
+
Cyan = [0, 1, 1, 1]
|
94
|
+
Orange = [1, 0.5, 0, 1]
|
95
|
+
Brown = [0.39, 0.26, 0.13, 1]
|
96
|
+
Turquoise = [1, 0.6, 0.8, 1]
|
97
|
+
Tyrian = [0.4, 0.007, 0.235, 1]
|
98
|
+
end
|
99
|
+
include Colors
|
100
|
+
|
101
|
+
# extra instance methods defined in Ruby
|
102
|
+
|
103
|
+
# Clear an image.
|
104
|
+
#
|
105
|
+
# @option options :color (:alpha) Colour of the image.
|
106
|
+
# @return [Gosu::Image]
|
107
|
+
def clear(options = {})
|
108
|
+
options = {
|
109
|
+
:color => :alpha,
|
110
|
+
:fill => true
|
111
|
+
}.merge!(options)
|
112
|
+
|
113
|
+
capture {
|
114
|
+
rect 0, 0, width - 1, height - 1, options
|
115
|
+
|
116
|
+
self
|
117
|
+
}
|
118
|
+
end
|
119
|
+
|
120
|
+
# Used internally to create images from raw binary (blob) data (TexPlay::from_blob).
|
121
|
+
#
|
122
|
+
# This object duck-types an RMagick image (#rows, #columns, #to_blob), so that Gosu will import it.
|
123
|
+
class ImageStub
|
124
|
+
# @return [Integer]
|
125
125
|
attr_reader :rows, :columns
|
126
|
-
|
126
|
+
|
127
|
+
# The first pixel in the blob will be at the top left hand corner of the created image, since that is the orientation
|
128
|
+
# of Gosu images.
|
129
|
+
#
|
130
|
+
# @param [String] blob_data Raw data string to import. Must be RGBA ordered, (4 * width * height) bytes in length.
|
131
|
+
# @param [Integer] width Number of pixels wide.
|
132
|
+
# @param [Integer] height Number of pixels high.
|
127
133
|
def initialize(blob_data, width, height)
|
128
|
-
|
134
|
+
@data, @columns, @rows = blob_data, width, height
|
129
135
|
end
|
130
|
-
|
136
|
+
|
137
|
+
# @return [String]
|
131
138
|
def to_blob
|
132
|
-
|
139
|
+
@data
|
133
140
|
end
|
134
|
-
end
|
135
|
-
|
136
|
-
# Used to create blank images.
|
137
|
-
#
|
138
|
-
|
141
|
+
end
|
142
|
+
|
143
|
+
# Used internally to create blank images (red/blue/green/alpha all 0) (TexPlay::create_image).
|
144
|
+
#
|
145
|
+
# Credit to philomory for this class.
|
146
|
+
class EmptyImageStub < ImageStub
|
147
|
+
# @param width (see ImageStub#initialize)
|
148
|
+
# @param height (see ImageStub#initialize)
|
139
149
|
def initialize(width, height)
|
140
|
-
|
150
|
+
super("\0" * (width * height * 4), width, height)
|
141
151
|
end
|
152
|
+
end
|
142
153
|
end
|
143
154
|
|
144
155
|
# bring in user-defined extensions to TexPlay
|
145
|
-
direc = File.dirname(__FILE__)
|
146
156
|
dlext = Config::CONFIG['DLEXT']
|
147
157
|
begin
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
158
|
+
if RUBY_VERSION && RUBY_VERSION =~ /1.9/
|
159
|
+
require "#{direc}/1.9/texplay.#{dlext}"
|
160
|
+
else
|
161
|
+
require "#{direc}/1.8/texplay.#{dlext}"
|
162
|
+
end
|
153
163
|
rescue LoadError => e
|
154
|
-
|
164
|
+
require "#{direc}/texplay.#{dlext}"
|
155
165
|
end
|
156
|
-
|
166
|
+
|
157
167
|
require "#{direc}/texplay-contrib"
|
158
168
|
|
159
169
|
# monkey patching the Gosu::Image class to add image manipulation functionality
|
160
170
|
module Gosu
|
161
|
-
|
171
|
+
class Image
|
172
|
+
|
173
|
+
# bring in the TexPlay image manipulation methods
|
174
|
+
include TexPlay
|
175
|
+
|
176
|
+
attr_reader :__window__
|
177
|
+
protected :__window__
|
178
|
+
|
179
|
+
class << self
|
180
|
+
alias_method :original_new, :new
|
162
181
|
|
163
|
-
|
164
|
-
include TexPlay
|
182
|
+
def new(*args, &block)
|
165
183
|
|
166
|
-
|
184
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
185
|
+
# invoke old behaviour
|
186
|
+
obj = original_new(*args, &block)
|
187
|
+
|
188
|
+
prepare_image(obj, args.first, options)
|
189
|
+
end
|
190
|
+
|
191
|
+
alias_method :original_from_text, :from_text
|
192
|
+
|
193
|
+
def from_text(*args, &block)
|
194
|
+
|
195
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
196
|
+
# invoke old behaviour
|
197
|
+
obj = original_from_text(*args, &block)
|
198
|
+
|
199
|
+
prepare_image(obj, args.first, options)
|
200
|
+
end
|
201
|
+
|
202
|
+
def prepare_image(obj, window, options={})
|
203
|
+
options = {
|
204
|
+
:caching => TexPlay.get_options[:caching]
|
205
|
+
}.merge!(options)
|
167
206
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
options = args.last.is_a?(Hash) ? args.pop : {}
|
174
|
-
# invoke old behaviour
|
175
|
-
obj = original_new(*args, &block)
|
176
|
-
|
177
|
-
prepare_image(obj, args.first, options)
|
178
|
-
end
|
179
|
-
|
180
|
-
alias_method :original_from_text, :from_text
|
181
|
-
|
182
|
-
def from_text(*args, &block)
|
183
|
-
|
184
|
-
options = args.last.is_a?(Hash) ? args.pop : {}
|
185
|
-
# invoke old behaviour
|
186
|
-
obj = original_from_text(*args, &block)
|
187
|
-
|
188
|
-
prepare_image(obj, args.first, options)
|
189
|
-
end
|
190
|
-
|
191
|
-
def prepare_image(obj, window, options={})
|
192
|
-
options = {
|
193
|
-
:caching => TexPlay.get_options[:caching]
|
194
|
-
}.merge!(options)
|
195
|
-
|
196
|
-
# refresh the TexPlay image cache
|
197
|
-
if obj.width <= (TexPlay::TP_MAX_QUAD_SIZE) &&
|
198
|
-
obj.height <= (TexPlay::TP_MAX_QUAD_SIZE) && obj.quad_cached? then
|
199
|
-
obj.refresh_cache if options[:caching]
|
200
|
-
end
|
201
|
-
|
202
|
-
# run custom setup
|
203
|
-
TexPlay.setup(obj)
|
204
|
-
|
205
|
-
obj.instance_variable_set(:@__window__, window)
|
206
|
-
|
207
|
-
obj
|
208
|
-
end
|
209
|
-
|
210
|
-
private :prepare_image
|
207
|
+
# refresh the TexPlay image cache
|
208
|
+
if obj.width <= (TexPlay::TP_MAX_QUAD_SIZE) &&
|
209
|
+
obj.height <= (TexPlay::TP_MAX_QUAD_SIZE) && obj.quad_cached? then
|
210
|
+
obj.refresh_cache if options[:caching]
|
211
211
|
end
|
212
|
+
|
213
|
+
# run custom setup
|
214
|
+
TexPlay.setup(obj)
|
215
|
+
|
216
|
+
obj.instance_variable_set(:@__window__, window)
|
217
|
+
|
218
|
+
obj
|
219
|
+
end
|
220
|
+
|
221
|
+
private :prepare_image
|
222
|
+
end
|
223
|
+
|
224
|
+
alias_method :rows, :height
|
225
|
+
alias_method :columns, :width
|
226
|
+
end
|
227
|
+
|
228
|
+
class Window
|
229
|
+
# Render directly into an existing image, optionally only to a specific region of that image.
|
230
|
+
#
|
231
|
+
# Since this operation utilises the window's back buffer, the image (or clipped area, if specified) cannot be larger than the
|
232
|
+
# window itself. Larger images can be rendered to only in separate sections using :clip_to areas, each no larger
|
233
|
+
# than the window).
|
234
|
+
#
|
235
|
+
# @note *Warning!* This operation will corrupt an area of the screen, at the bottom left corner, equal in size to the image rendered to (or the clipped area), so should be performed in #draw _before_ any other rendering.
|
236
|
+
#
|
237
|
+
# @note The final alpha of the image will be 255, regardless of what it started with or what is drawn onto it.
|
238
|
+
#
|
239
|
+
# @example
|
240
|
+
# class Gosu
|
241
|
+
# class Window
|
242
|
+
# def draw
|
243
|
+
# # Always render images before regular drawing to the screen.
|
244
|
+
# unless @rendered_image
|
245
|
+
# @rendered_image = TexPlay.create_image(self, 300, 300, :color => :blue)
|
246
|
+
# render_to_image(@rendered_image) do
|
247
|
+
# @an_image.draw 0, 0, 0
|
248
|
+
# @another_image.draw 130, 0, 0
|
249
|
+
# draw_line(0, 0, Color.new(255, 0, 0, 0), 100, 100, Color.new(255, 0, 0, 0), 0)
|
250
|
+
# @font.draw("Hello world!", 0, 50, 0)
|
251
|
+
# end
|
252
|
+
# end
|
253
|
+
#
|
254
|
+
# # Perform regular screen rendering.
|
255
|
+
# @rendered_image.draw 0, 0
|
256
|
+
# end
|
257
|
+
# end
|
258
|
+
# end
|
259
|
+
#
|
260
|
+
#
|
261
|
+
# @param [Gosu::Image] image Existing image to render onto.
|
262
|
+
# @option options [Array<Integer>] :clip_to ([0, 0, image.width, image.height]) Area of the image to render into. This area cannot be larger than the window, though the image may be.
|
263
|
+
# @return [Gosu::Image] The image that has been rendered to.
|
264
|
+
# @yield to a block that renders to the image.
|
265
|
+
def render_to_image(image, options = {})
|
266
|
+
raise ArgumentError, "image parameter must be a Gosu::Image to be rendered to" unless image.is_a? Gosu::Image
|
267
|
+
raise ArgumentError, "rendering block required" unless block_given?
|
268
|
+
|
269
|
+
options = {
|
270
|
+
:clip_to => [0, 0, image.width, image.height],
|
271
|
+
}.merge! options
|
272
|
+
|
273
|
+
texture_info = image.gl_tex_info
|
274
|
+
tex_name = texture_info.tex_name
|
275
|
+
x_offset = (texture_info.left * Gosu::MAX_TEXTURE_SIZE).to_i
|
276
|
+
y_offset = (texture_info.top * Gosu::MAX_TEXTURE_SIZE).to_i
|
277
|
+
|
278
|
+
raise ArgumentError, ":clip_to rectangle must contain exactly 4 elements" unless options[:clip_to].size == 4
|
279
|
+
|
280
|
+
left, top, width, height = *(options[:clip_to].map {|n| n.to_i })
|
281
|
+
|
282
|
+
raise ArgumentError, ":clip_to rectangle cannot be wider or taller than the window" unless width <= self.width and height <= self.height
|
283
|
+
raise ArgumentError, ":clip_to rectangle width and height must be positive" unless width > 0 and height > 0
|
212
284
|
|
213
|
-
|
214
|
-
|
285
|
+
right = left + width - 1
|
286
|
+
bottom = top + height - 1
|
287
|
+
|
288
|
+
unless (0...image.width).include? left and (0...image.width).include? right and
|
289
|
+
(0...image.height).include? top and (0...image.height).include? bottom
|
290
|
+
raise ArgumentError, ":clip_to rectangle out of bounds of the image"
|
291
|
+
end
|
292
|
+
|
293
|
+
# Since to_texture copies an inverted copy of the screen, what the user renders needs to be inverted first.
|
294
|
+
scale(1, -1) do
|
295
|
+
translate(-left, -top - self.height) do
|
296
|
+
# TODO: Once Gosu is fixed, we can just pass width/height to clip_to
|
297
|
+
clip_to(left, top, width, height) do
|
298
|
+
# Draw over the background (which is assumed to be blank) with the original image texture,
|
299
|
+
# to get us to the base image.
|
300
|
+
image.draw(0, 0, 0)
|
301
|
+
flush
|
302
|
+
|
303
|
+
# Allow the user to overwrite the texture.
|
304
|
+
yield
|
305
|
+
end
|
306
|
+
|
307
|
+
# Copy the modified texture back from the screen buffer to the image.
|
308
|
+
to_texture(tex_name, x_offset + left, y_offset + top, 0, 0, width, height)
|
309
|
+
|
310
|
+
# Clear the clipped zone to black again, ready for the regular screen drawing.
|
311
|
+
# Quad can be a pixel out, so just make sure with a slightly larger shape.
|
312
|
+
draw_quad(left - 2, top - 2, TexPlay::RENDER_CLEAR_COLOR,
|
313
|
+
right + 2, top - 2, TexPlay::RENDER_CLEAR_COLOR,
|
314
|
+
right + 2, bottom + 2, TexPlay::RENDER_CLEAR_COLOR,
|
315
|
+
left - 2, bottom + 2, TexPlay::RENDER_CLEAR_COLOR)
|
215
316
|
end
|
317
|
+
end
|
318
|
+
|
319
|
+
image
|
320
|
+
end
|
321
|
+
end
|
216
322
|
end
|
217
323
|
|
218
324
|
# a bug in ruby 1.8.6 rb_eval_string() means i must define this here (rather than in texplay.c)
|
219
325
|
class Proc
|
220
|
-
|
221
|
-
|
222
|
-
|
326
|
+
def __context__
|
327
|
+
eval('self', self.binding)
|
328
|
+
end
|
223
329
|
end
|
224
330
|
|
225
331
|
|