texplay 0.2.983pre2 → 0.3.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/Rakefile +48 -56
- 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/utils.c +0 -5
- data/lib/texplay.rb +271 -165
- data/lib/texplay/c_function_docs.rb +189 -0
- data/lib/texplay/version.rb +1 -1
- metadata +13 -19
- data/examples/example_window_to_texture.rb +0 -55
- data/lib/texplay/patches.rb +0 -4
data/examples/example_trace.rb
CHANGED
data/examples/example_turtle.rb
CHANGED
data/examples/example_weird.rb
CHANGED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(File.expand_path(__FILE__))
|
|
2
|
+
require 'common'
|
|
3
|
+
|
|
4
|
+
class W < Gosu::Window
|
|
5
|
+
def initialize
|
|
6
|
+
super(500, 500, false)
|
|
7
|
+
self.caption = "Press <escape> to render to texture"
|
|
8
|
+
|
|
9
|
+
@picture = Gosu::Image.new(self, "#{Common::MEDIA}/maria.png")
|
|
10
|
+
@block_image = TexPlay.create_image(self, 10, 10, :color => Gosu::Color::RED)
|
|
11
|
+
@rendered_image = TexPlay.create_image(self, Gosu::MAX_TEXTURE_SIZE - 2, Gosu::MAX_TEXTURE_SIZE - 2, :color => :purple)
|
|
12
|
+
|
|
13
|
+
@display = false
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def update
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def draw
|
|
21
|
+
# Render the image once.
|
|
22
|
+
if button_down?(Gosu::KbEscape) and not @display
|
|
23
|
+
|
|
24
|
+
render_to_image(@rendered_image, :clip_to => [40, 20, 440, 320]) do
|
|
25
|
+
@picture.draw 0, 0, 1
|
|
26
|
+
1000.times { @block_image.draw rand(250), rand(250), 1, 1, 1, Gosu::Color.new(rand(255), rand(255), rand(255), rand(255)) }
|
|
27
|
+
(0..width).step(5) {|x| draw_line 0, 0, Gosu::Color.new(255, 0, 0, 0), x, width, Gosu::Color.new(255, 0, 0, 0), 1 }
|
|
28
|
+
end
|
|
29
|
+
@display = true
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Display it indefinitely after that.
|
|
33
|
+
@rendered_image.draw(10, 10, 0) if @display
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
w = W.new
|
|
40
|
+
w.show
|
|
41
|
+
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(File.expand_path(__FILE__))
|
|
1
2
|
require 'common'
|
|
2
|
-
require 'gosu'
|
|
3
|
-
require 'texplay'
|
|
4
|
-
|
|
5
3
|
|
|
6
4
|
class W < Gosu::Window
|
|
7
5
|
def initialize
|
|
@@ -16,10 +14,9 @@ class W < Gosu::Window
|
|
|
16
14
|
end
|
|
17
15
|
|
|
18
16
|
def draw
|
|
19
|
-
|
|
17
|
+
@img.draw 0, 0,1
|
|
20
18
|
@img2.draw 100, 100,1
|
|
21
19
|
if button_down?(Gosu::KbEscape)
|
|
22
|
-
# self.flush
|
|
23
20
|
@blob = self.to_blob(0,self.height - 70, 50, 50)
|
|
24
21
|
if @blob
|
|
25
22
|
@img3 = TexPlay.from_blob(self, @blob,50, 50 )
|
data/ext/texplay/utils.c
CHANGED
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
|
|