texplay 0.4.3-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemtest +0 -0
- data/CHANGELOG +222 -0
- data/README.markdown +48 -0
- data/Rakefile +16 -0
- data/examples/common.rb +18 -0
- data/examples/example_alpha_blend.rb +29 -0
- data/examples/example_bezier.rb +41 -0
- data/examples/example_blank.rb +37 -0
- data/examples/example_cache.rb +21 -0
- data/examples/example_color_control.rb +69 -0
- data/examples/example_color_transform.rb +62 -0
- data/examples/example_color_transform_circle.rb +34 -0
- data/examples/example_darken.rb +24 -0
- data/examples/example_dup.rb +73 -0
- data/examples/example_each.rb +39 -0
- data/examples/example_effect.rb +34 -0
- data/examples/example_fill.rb +43 -0
- data/examples/example_fill_old.rb +48 -0
- data/examples/example_fluent.rb +29 -0
- data/examples/example_font.rb +31 -0
- data/examples/example_hash_arguments.rb +46 -0
- data/examples/example_ippa.rb +23 -0
- data/examples/example_light.rb +75 -0
- data/examples/example_light_multiply.rb +18 -0
- data/examples/example_lsystem.rb +61 -0
- data/examples/example_melt.rb +25 -0
- data/examples/example_meyet.rb +62 -0
- data/examples/example_polyline.rb +42 -0
- data/examples/example_scale.rb +27 -0
- data/examples/example_select.rb +36 -0
- data/examples/example_select2.rb +25 -0
- data/examples/example_simple.rb +46 -0
- data/examples/example_splice.rb +26 -0
- data/examples/example_sync.rb +59 -0
- data/examples/example_tiles.rb +41 -0
- data/examples/example_trace.rb +22 -0
- data/examples/example_transparent.rb +28 -0
- data/examples/example_transparent2.rb +24 -0
- data/examples/example_transparent3.rb +20 -0
- data/examples/example_turtle.rb +39 -0
- data/examples/example_weird.rb +22 -0
- data/examples/example_window_render_to_image.rb +41 -0
- data/examples/example_window_to_blob.rb +35 -0
- data/examples/media/bird.png +0 -0
- data/examples/media/body.png +0 -0
- data/examples/media/empty2.png +0 -0
- data/examples/media/face.png +0 -0
- data/examples/media/gob.png +0 -0
- data/examples/media/gosu.png +0 -0
- data/examples/media/green.png +0 -0
- data/examples/media/logo.png +0 -0
- data/examples/media/maria.png +0 -0
- data/examples/media/object.png +0 -0
- data/examples/media/rose.bmp +0 -0
- data/examples/media/sand1.png +0 -0
- data/examples/media/sunset.png +0 -0
- data/examples/media/texplay.png +0 -0
- data/ext/texplay/actions.c +1006 -0
- data/ext/texplay/actions.h +60 -0
- data/ext/texplay/bindings.c +1125 -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 +38 -0
- data/ext/texplay/graphics_utils.c +1313 -0
- data/ext/texplay/graphics_utils.h +22 -0
- data/ext/texplay/texplay.c +201 -0
- data/ext/texplay/texplay.h +153 -0
- data/ext/texplay/utils.c +891 -0
- data/ext/texplay/utils.h +153 -0
- data/ext/texplay/vendor/freeglut/include/GL/freeglut.h +22 -0
- data/ext/texplay/vendor/freeglut/include/GL/freeglut_ext.h +236 -0
- data/ext/texplay/vendor/freeglut/include/GL/freeglut_std.h +628 -0
- data/ext/texplay/vendor/freeglut/include/GL/glut.h +21 -0
- data/lib/texplay-contrib.rb +147 -0
- data/lib/texplay.rb +347 -0
- data/lib/texplay/1.8/texplay.so +0 -0
- data/lib/texplay/1.9/texplay.so +0 -0
- data/lib/texplay/alone.rb +20 -0
- data/lib/texplay/c_function_docs.rb +178 -0
- data/lib/texplay/live.rb +84 -0
- data/lib/texplay/version.rb +3 -0
- data/live/live.rb +85 -0
- data/test/image_spec.rb +45 -0
- data/test/texplay_spec.rb +144 -0
- metadata +179 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
#ifndef __GLUT_H__
|
2
|
+
#define __GLUT_H__
|
3
|
+
|
4
|
+
/*
|
5
|
+
* glut.h
|
6
|
+
*
|
7
|
+
* The freeglut library include file
|
8
|
+
*
|
9
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
10
|
+
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
11
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
12
|
+
* PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
13
|
+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
14
|
+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
15
|
+
*/
|
16
|
+
|
17
|
+
#include "freeglut_std.h"
|
18
|
+
|
19
|
+
/*** END OF FILE ***/
|
20
|
+
|
21
|
+
#endif /* __GLUT_H__ */
|
@@ -0,0 +1,147 @@
|
|
1
|
+
# to bring in String#each_char for 1.8
|
2
|
+
if RUBY_VERSION =~ /1.8/
|
3
|
+
require 'jcode'
|
4
|
+
end
|
5
|
+
|
6
|
+
# setup will be executed straight after Gosu::Image instantiation
|
7
|
+
TexPlay::on_setup do
|
8
|
+
@turtle_pos = TexPlay::TPPoint.new(width / 2, height / 2 )
|
9
|
+
@turtle_angle = 0
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
TexPlay::create_macro(:move_to) do |x, y|
|
14
|
+
@turtle_pos.x = x
|
15
|
+
@turtle_pos.y = y
|
16
|
+
end
|
17
|
+
|
18
|
+
TexPlay::create_macro(:move_rel) do |dx, dy|
|
19
|
+
@turtle_pos.x += dx
|
20
|
+
@turtle_pos.y += dy
|
21
|
+
end
|
22
|
+
|
23
|
+
TexPlay::create_macro(:line_to) do |x, y, *other|
|
24
|
+
line(@turtle_pos.x, @turtle_pos.y, x, y, *other)
|
25
|
+
@turtle_pos.x, @turtle_pos.y = x, y
|
26
|
+
end
|
27
|
+
|
28
|
+
TexPlay::create_macro(:line_rel) do |dx, dy, *other|
|
29
|
+
x = @turtle_pos.x + dx
|
30
|
+
y = @turtle_pos.y + dy
|
31
|
+
|
32
|
+
line(@turtle_pos.x, @turtle_pos.y, x, y, *other)
|
33
|
+
|
34
|
+
@turtle_pos.x, @turtle_pos.y = x, y
|
35
|
+
end
|
36
|
+
|
37
|
+
TexPlay::create_macro(:turn_to) do |a|
|
38
|
+
@turtle_angle = a
|
39
|
+
end
|
40
|
+
|
41
|
+
TexPlay::create_macro(:turn) do |da|
|
42
|
+
@turtle_angle += da
|
43
|
+
end
|
44
|
+
|
45
|
+
TexPlay::create_macro(:forward) do |dist, *other|
|
46
|
+
visible = other.shift
|
47
|
+
|
48
|
+
radians_per_degree = 0.0174532925199433
|
49
|
+
|
50
|
+
x = @turtle_pos.x + dist * Math::cos(radians_per_degree * @turtle_angle)
|
51
|
+
y = @turtle_pos.y + dist * Math::sin(radians_per_degree * @turtle_angle)
|
52
|
+
|
53
|
+
if(visible) then
|
54
|
+
line_to(x, y, *other)
|
55
|
+
else
|
56
|
+
move_to(x, y)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# L-System code
|
61
|
+
# adding LSystem class to TexPlay module
|
62
|
+
class TexPlay::LSystem
|
63
|
+
def initialize(&block)
|
64
|
+
@rules = {}
|
65
|
+
|
66
|
+
instance_eval(&block) if block
|
67
|
+
end
|
68
|
+
|
69
|
+
def rule(new_rule)
|
70
|
+
@rules.merge!(new_rule)
|
71
|
+
end
|
72
|
+
|
73
|
+
def atom(new_atom)
|
74
|
+
@atom = new_atom
|
75
|
+
end
|
76
|
+
|
77
|
+
def angle(new_angle=nil)
|
78
|
+
return @angle if !new_angle
|
79
|
+
@angle = new_angle
|
80
|
+
end
|
81
|
+
|
82
|
+
def produce_string(order)
|
83
|
+
order = order[:order]
|
84
|
+
string = @atom.dup
|
85
|
+
|
86
|
+
order.times do
|
87
|
+
i = 0
|
88
|
+
while(i < string.length)
|
89
|
+
sub = @rules[string[i, 1]]
|
90
|
+
|
91
|
+
string[i] = sub if sub
|
92
|
+
|
93
|
+
i += sub ? sub.length : 1
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
string
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# L-System macro
|
102
|
+
TexPlay::create_macro(:lsystem) do |x, y, system, options|
|
103
|
+
theta = system.angle
|
104
|
+
turtle_stack = []
|
105
|
+
move_to(x, y)
|
106
|
+
line_length = options[:line_length] || 1
|
107
|
+
|
108
|
+
system.produce_string(options).each_char do |v|
|
109
|
+
|
110
|
+
case v
|
111
|
+
when "F"
|
112
|
+
forward(line_length, true)
|
113
|
+
when "+"
|
114
|
+
turn(theta)
|
115
|
+
when "-"
|
116
|
+
turn(-theta)
|
117
|
+
when "["
|
118
|
+
turtle_stack.push([@turtle_pos.dup, @turtle_angle])
|
119
|
+
when "]"
|
120
|
+
@turtle_pos, @turtle_angle = turtle_stack.pop
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Scaling
|
126
|
+
# uses nearest-neighbour
|
127
|
+
TexPlay::create_macro(:splice_and_scale) do |img, cx, cy, *options|
|
128
|
+
options = options.first ? options.first : {}
|
129
|
+
|
130
|
+
options = {
|
131
|
+
:color_control => proc do |c1, c2, x, y|
|
132
|
+
factor = options[:factor] || 1
|
133
|
+
factor_x = options[:factor_x] || factor
|
134
|
+
factor_y = options[:factor_y] || factor
|
135
|
+
|
136
|
+
x = factor_x * (x - cx) + cx
|
137
|
+
y = factor_y * (y - cy) + cy
|
138
|
+
|
139
|
+
rect x, y, x + factor_x, y + factor_y, :color => c2, :fill => true
|
140
|
+
:none
|
141
|
+
end
|
142
|
+
}.merge!(options)
|
143
|
+
|
144
|
+
splice img, cx, cy, options
|
145
|
+
|
146
|
+
self
|
147
|
+
end
|
data/lib/texplay.rb
ADDED
@@ -0,0 +1,347 @@
|
|
1
|
+
|
2
|
+
# (C) John Mair 2009, under the MIT licence
|
3
|
+
|
4
|
+
direc = File.expand_path(File.dirname(__FILE__))
|
5
|
+
|
6
|
+
# include gosu first
|
7
|
+
require 'gosu'
|
8
|
+
require "#{direc}/texplay/version"
|
9
|
+
|
10
|
+
begin
|
11
|
+
RUBY_VERSION =~ /(\d+\.\d+)/
|
12
|
+
require "#{direc}/texplay/#{$1}/texplay.so"
|
13
|
+
rescue LoadError
|
14
|
+
require "#{direc}/texplay/texplay.so"
|
15
|
+
end
|
16
|
+
|
17
|
+
module TexPlay
|
18
|
+
RENDER_CLEAR_COLOR = Gosu::Color.new(255, 0, 0, 0)
|
19
|
+
|
20
|
+
class << self
|
21
|
+
def on_setup(&block)
|
22
|
+
raise "need a block" if !block
|
23
|
+
@__init_procs__ ||= []
|
24
|
+
@__init_procs__.push(block)
|
25
|
+
end
|
26
|
+
|
27
|
+
def setup(receiver)
|
28
|
+
if @__init_procs__
|
29
|
+
@__init_procs__.each do |init_proc|
|
30
|
+
receiver.instance_eval(&init_proc)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def create_image(window, width, height, options={})
|
36
|
+
options = {
|
37
|
+
:color => :alpha,
|
38
|
+
:caching => false,
|
39
|
+
}.merge!(options)
|
40
|
+
|
41
|
+
raise ArgumentError, "Height and width must be positive" if height <= 0 or width <= 0
|
42
|
+
|
43
|
+
img = Gosu::Image.new(window, EmptyImageStub.new(width, height), :caching => options[:caching])
|
44
|
+
|
45
|
+
# this should be a major speedup (avoids both a cache and a sync
|
46
|
+
# if color is alpha (default)
|
47
|
+
if options[:color] != :alpha
|
48
|
+
img.rect 0, 0, img.width - 1, img.height - 1, :color => options[:color], :fill => true
|
49
|
+
end
|
50
|
+
|
51
|
+
img
|
52
|
+
end
|
53
|
+
|
54
|
+
alias_method :create_blank_image, :create_image
|
55
|
+
|
56
|
+
# Image can be :tileable, but it will break if it is tileable AND gets modified after creation.
|
57
|
+
def from_blob(window, blob_data, width, height, options={})
|
58
|
+
options = {
|
59
|
+
:caching => false,
|
60
|
+
:tileable => false,
|
61
|
+
}.merge!(options)
|
62
|
+
|
63
|
+
raise ArgumentError, "Height and width must be positive (received #{width}x#{height})" if height <= 0 or width <= 0
|
64
|
+
|
65
|
+
expected_size = height * width * 4
|
66
|
+
if blob_data.size != expected_size
|
67
|
+
raise ArgumentError, "Blob data is not of the correct size (expected #{expected_size} but received #{blob_data.size} bytes)"
|
68
|
+
end
|
69
|
+
|
70
|
+
Gosu::Image.new(window, ImageStub.new(blob_data, width, height), options[:tileable], :caching => options[:caching])
|
71
|
+
end
|
72
|
+
|
73
|
+
def set_options(options = {})
|
74
|
+
@options.merge!(options)
|
75
|
+
end
|
76
|
+
|
77
|
+
def get_options
|
78
|
+
@options
|
79
|
+
end
|
80
|
+
|
81
|
+
# default values defined here
|
82
|
+
def set_defaults
|
83
|
+
@options = {
|
84
|
+
:caching => :lazy
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
def init
|
89
|
+
set_defaults
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
module Colors
|
94
|
+
Red = [1, 0, 0, 1]
|
95
|
+
Green = [0, 1, 0, 1]
|
96
|
+
Blue = [0, 0, 1, 1]
|
97
|
+
Black = [0, 0, 0, 1]
|
98
|
+
White = [1, 1, 1, 1]
|
99
|
+
Grey = [0.5, 0.5, 0.5, 1]
|
100
|
+
Alpha = [0, 0, 0, 0]
|
101
|
+
Purple = [1, 0, 1, 1]
|
102
|
+
Yellow = [1, 1, 0, 1]
|
103
|
+
Cyan = [0, 1, 1, 1]
|
104
|
+
Orange = [1, 0.5, 0, 1]
|
105
|
+
Brown = [0.39, 0.26, 0.13, 1]
|
106
|
+
Turquoise = [1, 0.6, 0.8, 1]
|
107
|
+
Tyrian = [0.4, 0.007, 0.235, 1]
|
108
|
+
end
|
109
|
+
include Colors
|
110
|
+
|
111
|
+
# extra instance methods defined in Ruby
|
112
|
+
|
113
|
+
# Clear an image.
|
114
|
+
#
|
115
|
+
# @option options :color (:alpha) Colour of the image.
|
116
|
+
# @return [Gosu::Image]
|
117
|
+
def clear(options = {})
|
118
|
+
options = {
|
119
|
+
:color => :alpha,
|
120
|
+
:fill => true
|
121
|
+
}.merge!(options)
|
122
|
+
|
123
|
+
rect 0, 0, width - 1, height - 1, options
|
124
|
+
end
|
125
|
+
|
126
|
+
# Used internally to create images from raw binary (blob) data (TexPlay::from_blob).
|
127
|
+
#
|
128
|
+
# This object duck-types an RMagick image (#rows, #columns, #to_blob), so that Gosu will import it.
|
129
|
+
class ImageStub
|
130
|
+
|
131
|
+
# @return [Integer]
|
132
|
+
attr_reader :rows, :columns
|
133
|
+
|
134
|
+
# The first pixel in the blob will be at the top left hand corner of the created image, since that is the orientation
|
135
|
+
# of Gosu images.
|
136
|
+
#
|
137
|
+
# @param [String] blob_data Raw data string to import. Must be RGBA ordered, (4 * width * height) bytes in length.
|
138
|
+
# @param [Integer] width Number of pixels wide.
|
139
|
+
# @param [Integer] height Number of pixels high.
|
140
|
+
def initialize(blob_data, width, height)
|
141
|
+
@data, @columns, @rows = blob_data, width, height
|
142
|
+
end
|
143
|
+
|
144
|
+
# @return [String]
|
145
|
+
def to_blob
|
146
|
+
@data
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# Used internally to create blank images (red/blue/green/alpha all 0) (TexPlay::create_image).
|
151
|
+
#
|
152
|
+
# Credit to philomory for this class.
|
153
|
+
class EmptyImageStub < ImageStub
|
154
|
+
# @param width (see ImageStub#initialize)
|
155
|
+
# @param height (see ImageStub#initialize)
|
156
|
+
def initialize(width, height)
|
157
|
+
raise ArgumentError if (width > TexPlay::TP_MAX_QUAD_SIZE || height > TexPlay::TP_MAX_QUAD_SIZE)
|
158
|
+
super("\0" * (width * height * 4), width, height)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
require "#{direc}/texplay-contrib"
|
164
|
+
|
165
|
+
# monkey patching the Gosu::Image class to add image manipulation functionality
|
166
|
+
module Gosu
|
167
|
+
class Image
|
168
|
+
|
169
|
+
# bring in the TexPlay image manipulation methods
|
170
|
+
include TexPlay
|
171
|
+
|
172
|
+
attr_reader :__window__
|
173
|
+
protected :__window__
|
174
|
+
|
175
|
+
class << self
|
176
|
+
alias_method :original_new, :new
|
177
|
+
|
178
|
+
def new(*args, &block)
|
179
|
+
|
180
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
181
|
+
# invoke old behaviour
|
182
|
+
obj = original_new(*args, &block)
|
183
|
+
|
184
|
+
prepare_image(obj, args.first, options)
|
185
|
+
end
|
186
|
+
|
187
|
+
alias_method :original_from_text, :from_text
|
188
|
+
|
189
|
+
def from_text(*args, &block)
|
190
|
+
|
191
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
192
|
+
# invoke old behaviour
|
193
|
+
obj = original_from_text(*args, &block)
|
194
|
+
|
195
|
+
prepare_image(obj, args.first, options)
|
196
|
+
end
|
197
|
+
|
198
|
+
def prepare_image(obj, window, options={})
|
199
|
+
options = {
|
200
|
+
:caching => TexPlay.get_options[:caching]
|
201
|
+
}.merge!(options)
|
202
|
+
|
203
|
+
caching_mode = options[:caching]
|
204
|
+
|
205
|
+
# we can't manipulate large images, so skip them.
|
206
|
+
if obj.width <= (TexPlay::TP_MAX_QUAD_SIZE) &&
|
207
|
+
obj.height <= (TexPlay::TP_MAX_QUAD_SIZE)
|
208
|
+
|
209
|
+
if caching_mode
|
210
|
+
if caching_mode == :lazy
|
211
|
+
|
212
|
+
# only cache if quad already cached (to refresh old data)
|
213
|
+
# otherwise cache lazily at point of first TexPlay call
|
214
|
+
obj.refresh_cache if obj.quad_cached?
|
215
|
+
|
216
|
+
else
|
217
|
+
|
218
|
+
# force a cache - this obviates the need for a
|
219
|
+
# potentialy expensive runtime cache of the image by
|
220
|
+
# moving the cache to load-time
|
221
|
+
obj.refresh_cache
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# run custom setup
|
227
|
+
TexPlay.setup(obj)
|
228
|
+
|
229
|
+
obj.instance_variable_set(:@__window__, window)
|
230
|
+
|
231
|
+
obj
|
232
|
+
end
|
233
|
+
|
234
|
+
private :prepare_image
|
235
|
+
end
|
236
|
+
|
237
|
+
alias_method :rows, :height
|
238
|
+
alias_method :columns, :width
|
239
|
+
end
|
240
|
+
|
241
|
+
class Window
|
242
|
+
# Render directly into an existing image, optionally only to a specific region of that image.
|
243
|
+
#
|
244
|
+
# Since this operation utilises the window's back buffer, the image (or clipped area, if specified) cannot be larger than the
|
245
|
+
# window itself. Larger images can be rendered to only in separate sections using :clip_to areas, each no larger
|
246
|
+
# than the window).
|
247
|
+
#
|
248
|
+
# @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.
|
249
|
+
#
|
250
|
+
# @note The final alpha of the image will be 255, regardless of what it started with or what is drawn onto it.
|
251
|
+
#
|
252
|
+
# @example
|
253
|
+
# class Gosu
|
254
|
+
# class Window
|
255
|
+
# def draw
|
256
|
+
# # Always render images before regular drawing to the screen.
|
257
|
+
# unless @rendered_image
|
258
|
+
# @rendered_image = TexPlay.create_image(self, 300, 300, :color => :blue)
|
259
|
+
# render_to_image(@rendered_image) do
|
260
|
+
# @an_image.draw 0, 0, 0
|
261
|
+
# @another_image.draw 130, 0, 0
|
262
|
+
# draw_line(0, 0, Color.new(255, 0, 0, 0), 100, 100, Color.new(255, 0, 0, 0), 0)
|
263
|
+
# @font.draw("Hello world!", 0, 50, 0)
|
264
|
+
# end
|
265
|
+
# end
|
266
|
+
#
|
267
|
+
# # Perform regular screen rendering.
|
268
|
+
# @rendered_image.draw 0, 0
|
269
|
+
# end
|
270
|
+
# end
|
271
|
+
# end
|
272
|
+
#
|
273
|
+
#
|
274
|
+
# @param [Gosu::Image] image Existing image to render onto.
|
275
|
+
# @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.
|
276
|
+
# @return [Gosu::Image] The image that has been rendered to.
|
277
|
+
# @yield to a block that renders to the image.
|
278
|
+
def render_to_image(image, options = {})
|
279
|
+
raise ArgumentError, "image parameter must be a Gosu::Image to be rendered to" unless image.is_a? Gosu::Image
|
280
|
+
raise ArgumentError, "rendering block required" unless block_given?
|
281
|
+
|
282
|
+
options = {
|
283
|
+
:clip_to => [0, 0, image.width, image.height],
|
284
|
+
}.merge! options
|
285
|
+
|
286
|
+
texture_info = image.gl_tex_info
|
287
|
+
tex_name = texture_info.tex_name
|
288
|
+
x_offset = (texture_info.left * Gosu::MAX_TEXTURE_SIZE).to_i
|
289
|
+
y_offset = (texture_info.top * Gosu::MAX_TEXTURE_SIZE).to_i
|
290
|
+
|
291
|
+
raise ArgumentError, ":clip_to rectangle must contain exactly 4 elements" unless options[:clip_to].size == 4
|
292
|
+
|
293
|
+
left, top, width, height = *(options[:clip_to].map {|n| n.to_i })
|
294
|
+
|
295
|
+
raise ArgumentError, ":clip_to rectangle cannot be wider or taller than the window" unless width <= self.width and height <= self.height
|
296
|
+
raise ArgumentError, ":clip_to rectangle width and height must be positive" unless width > 0 and height > 0
|
297
|
+
|
298
|
+
right = left + width - 1
|
299
|
+
bottom = top + height - 1
|
300
|
+
|
301
|
+
unless (0...image.width).include? left and (0...image.width).include? right and
|
302
|
+
(0...image.height).include? top and (0...image.height).include? bottom
|
303
|
+
raise ArgumentError, ":clip_to rectangle out of bounds of the image"
|
304
|
+
end
|
305
|
+
|
306
|
+
# Since to_texture copies an inverted copy of the screen, what the user renders needs to be inverted first.
|
307
|
+
scale(1, -1) do
|
308
|
+
translate(-left, -top - self.height) do
|
309
|
+
# TODO: Once Gosu is fixed, we can just pass width/height to clip_to
|
310
|
+
clip_to(left, top, width, height) do
|
311
|
+
# Draw over the background (which is assumed to be blank) with the original image texture,
|
312
|
+
# to get us to the base image.
|
313
|
+
image.draw(0, 0, 0)
|
314
|
+
flush
|
315
|
+
|
316
|
+
# Allow the user to overwrite the texture.
|
317
|
+
yield
|
318
|
+
end
|
319
|
+
|
320
|
+
# Copy the modified texture back from the screen buffer to the image.
|
321
|
+
to_texture(tex_name, x_offset + left, y_offset + top, 0, 0, width, height)
|
322
|
+
|
323
|
+
# Clear the clipped zone to black again, ready for the regular screen drawing.
|
324
|
+
# Quad can be a pixel out, so just make sure with a slightly larger shape.
|
325
|
+
draw_quad(left - 2, top - 2, TexPlay::RENDER_CLEAR_COLOR,
|
326
|
+
right + 2, top - 2, TexPlay::RENDER_CLEAR_COLOR,
|
327
|
+
right + 2, bottom + 2, TexPlay::RENDER_CLEAR_COLOR,
|
328
|
+
left - 2, bottom + 2, TexPlay::RENDER_CLEAR_COLOR)
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
image
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
# a bug in ruby 1.8.6 rb_eval_string() means i must define this here (rather than in texplay.c)
|
338
|
+
class Proc
|
339
|
+
def __context__
|
340
|
+
eval('self', self.binding)
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
|
345
|
+
# initialize TP (at the moment just setting some default settings)
|
346
|
+
TexPlay.init
|
347
|
+
|