ashton 0.0.1alpha → 0.0.2alpha
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +21 -21
- data/README.md +95 -68
- data/Rakefile +41 -23
- data/examples/bloom_example.rb +59 -0
- data/examples/lighting_example.rb +127 -0
- data/examples/media/SmallStar.png +0 -0
- data/examples/media/Starfighter.png +0 -0
- data/examples/media/simple.png +0 -0
- data/examples/noise_example.rb +94 -0
- data/examples/outline_example.rb +86 -0
- data/examples/particle_emitter_example.rb +114 -0
- data/examples/pixelate_example.rb +51 -49
- data/examples/pixelated_texture_example.rb +69 -0
- data/examples/radial_blur_example.rb +60 -62
- data/examples/shader_image_example.rb +74 -41
- data/examples/{shockwave2_example.rb → shockwave_example.rb} +74 -75
- data/examples/stencil_shader_example.rb +104 -0
- data/examples/{framebuffer_example.rb → texture_render_example.rb} +53 -49
- data/examples/{tv_screen_and_noise_example.rb → tv_screen_and_static_example.rb} +59 -59
- data/ext/ashton/GLee.c +18170 -0
- data/ext/ashton/GLee.h +17647 -0
- data/ext/ashton/ashton.c +42 -0
- data/ext/ashton/ashton.h +31 -0
- data/ext/ashton/color.c +45 -0
- data/ext/ashton/color.h +25 -0
- data/ext/ashton/common.h +41 -0
- data/ext/ashton/extconf.rb +42 -0
- data/ext/ashton/fast_math.c +30 -0
- data/ext/ashton/fast_math.h +30 -0
- data/ext/ashton/font.c +8 -0
- data/ext/ashton/font.h +16 -0
- data/ext/ashton/gosu.c +18 -0
- data/ext/ashton/gosu.h +19 -0
- data/ext/ashton/image.c +8 -0
- data/ext/ashton/image.h +16 -0
- data/ext/ashton/particle_emitter.c +788 -0
- data/ext/ashton/particle_emitter.h +171 -0
- data/ext/ashton/pixel_cache.c +237 -0
- data/ext/ashton/pixel_cache.h +58 -0
- data/ext/ashton/shader.c +9 -0
- data/ext/ashton/shader.h +16 -0
- data/ext/ashton/texture.c +442 -0
- data/ext/ashton/texture.h +63 -0
- data/ext/ashton/window.c +8 -0
- data/ext/ashton/window.h +16 -0
- data/lib/ashton.rb +38 -26
- data/lib/ashton/1.9/ashton.so +0 -0
- data/lib/ashton/gosu_ext/color.rb +24 -11
- data/lib/ashton/gosu_ext/font.rb +58 -0
- data/lib/ashton/gosu_ext/gosu_module.rb +16 -0
- data/lib/ashton/gosu_ext/image.rb +95 -31
- data/lib/ashton/gosu_ext/window.rb +78 -35
- data/lib/ashton/image_stub.rb +32 -36
- data/lib/ashton/lighting/light_source.rb +146 -0
- data/lib/ashton/lighting/manager.rb +98 -0
- data/lib/ashton/mixins/version_checking.rb +23 -0
- data/lib/ashton/particle_emitter.rb +87 -0
- data/lib/ashton/pixel_cache.rb +24 -0
- data/lib/ashton/shader.rb +353 -35
- data/lib/ashton/shaders/bloom.frag +41 -0
- data/lib/ashton/shaders/color_inversion.frag +11 -0
- data/lib/ashton/{post_process → shaders}/contrast.frag +16 -16
- data/lib/ashton/{shader → shaders}/default.frag +22 -19
- data/lib/ashton/{shader → shaders}/default.vert +13 -13
- data/lib/ashton/shaders/fade.frag +14 -0
- data/lib/ashton/shaders/grayscale.frag +15 -0
- data/lib/ashton/shaders/include/classicnoise2d.glsl +113 -0
- data/lib/ashton/shaders/include/classicnoise3d.glsl +177 -0
- data/lib/ashton/shaders/include/classicnoise4d.glsl +302 -0
- data/lib/ashton/{include/simplex.glsl → shaders/include/noise2d.glsl} +70 -63
- data/lib/ashton/shaders/include/noise3d.glsl +102 -0
- data/lib/ashton/shaders/include/noise4d.glsl +128 -0
- data/lib/ashton/shaders/include/rand.glsl +5 -0
- data/lib/ashton/shaders/lighting/distort.frag +57 -0
- data/lib/ashton/shaders/lighting/draw_shadows.frag +60 -0
- data/lib/ashton/shaders/lighting/shadow_blur.frag +60 -0
- data/lib/ashton/shaders/mezzotint.frag +22 -0
- data/lib/ashton/shaders/multitexture2.vert +19 -0
- data/lib/ashton/shaders/outline.frag +45 -0
- data/lib/ashton/{post_process → shaders}/pixelate.frag +48 -48
- data/lib/ashton/shaders/radial_blur.frag +63 -0
- data/lib/ashton/shaders/sepia.frag +26 -0
- data/lib/ashton/{post_process/shockwave2.frag → shaders/shockwave.frag} +38 -35
- data/lib/ashton/shaders/signed_distance_field.frag +80 -0
- data/lib/ashton/{post_process/noise.frag → shaders/static.frag} +25 -27
- data/lib/ashton/shaders/stencil.frag +27 -0
- data/lib/ashton/shaders/tv_screen.frag +23 -0
- data/lib/ashton/signed_distance_field.rb +151 -0
- data/lib/ashton/texture.rb +186 -0
- data/lib/ashton/version.rb +2 -2
- data/lib/ashton/window_buffer.rb +16 -0
- data/spec/ashton/ashton_spec.rb +22 -0
- data/spec/ashton/gosu_ext/color_spec.rb +34 -0
- data/spec/ashton/gosu_ext/font_spec.rb +57 -0
- data/spec/ashton/gosu_ext/gosu_spec.rb +11 -0
- data/spec/ashton/gosu_ext/image_spec.rb +66 -0
- data/spec/ashton/gosu_ext/window_spec.rb +71 -0
- data/spec/ashton/image_stub_spec.rb +46 -0
- data/spec/ashton/particle_emitter_spec.rb +123 -0
- data/spec/ashton/pixel_cache_spec.rb +153 -0
- data/spec/ashton/shader_spec.rb +152 -0
- data/spec/ashton/signed_distance_field_spec.rb +163 -0
- data/spec/ashton/texture_spec.rb +347 -0
- data/spec/helper.rb +12 -0
- metadata +159 -28
- data/examples/output/README.txt +0 -1
- data/lib/ashton/base_shader.rb +0 -172
- data/lib/ashton/framebuffer.rb +0 -183
- data/lib/ashton/post_process.rb +0 -83
- data/lib/ashton/post_process/default.vert +0 -9
- data/lib/ashton/post_process/fade.frag +0 -11
- data/lib/ashton/post_process/mezzotint.frag +0 -24
- data/lib/ashton/post_process/radial_blur.frag +0 -31
- data/lib/ashton/post_process/sepia.frag +0 -19
- data/lib/ashton/post_process/shockwave.frag +0 -40
- data/lib/ashton/post_process/tv_screen.frag +0 -32
data/lib/ashton/image_stub.rb
CHANGED
@@ -1,37 +1,33 @@
|
|
1
|
-
module Ashton
|
2
|
-
# Used internally to create images from raw binary (blob) data.
|
3
|
-
#
|
4
|
-
# This object duck-types an RMagick image (#rows, #columns, #to_blob), so that Gosu will import it.
|
5
|
-
class ImageStub
|
6
|
-
|
7
|
-
# @return [Integer]
|
8
|
-
attr_reader :rows
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
# @param [
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
#raise ArgumentError if (width > TexPlay::TP_MAX_QUAD_SIZE || height > TexPlay::TP_MAX_QUAD_SIZE)
|
34
|
-
super('\0' * (width * height * 4), width, height)
|
35
|
-
end
|
36
|
-
end
|
1
|
+
module Ashton
|
2
|
+
# Used internally to create images from raw binary (blob) data.
|
3
|
+
#
|
4
|
+
# This object duck-types an RMagick image (#rows, #columns, #to_blob), so that Gosu will import it.
|
5
|
+
class ImageStub
|
6
|
+
|
7
|
+
# @return [Integer]
|
8
|
+
attr_reader :rows
|
9
|
+
# @return [Integer]
|
10
|
+
attr_reader :columns
|
11
|
+
|
12
|
+
# The first pixel in the blob will be at the top left hand corner of the created image, since that is the orientation
|
13
|
+
# of Gosu images.
|
14
|
+
#
|
15
|
+
# @param [String] blob_data Raw data string to import. Must be RGBA ordered, (4 * width * height) bytes in length.
|
16
|
+
# @param [Integer] width Number of pixels wide.
|
17
|
+
# @param [Integer] height Number of pixels high.
|
18
|
+
def initialize(blob_data, width, height)
|
19
|
+
raise ArgumentError, "Width must be >= 1 pixel" unless width > 0
|
20
|
+
raise ArgumentError, "Height must be >= 1 pixel" unless height > 0
|
21
|
+
|
22
|
+
expected_size = width * height * 4
|
23
|
+
raise ArgumentError, "Expected blob to be #{expected_size} bytes" unless blob_data.size == expected_size
|
24
|
+
|
25
|
+
@data, @columns, @rows = blob_data, width, height
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [String]
|
29
|
+
def to_blob
|
30
|
+
@data
|
31
|
+
end
|
32
|
+
end
|
37
33
|
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
module Ashton
|
2
|
+
module Lighting
|
3
|
+
# Based on Catalin Zima's shader based dynamic shadows system.
|
4
|
+
# http://www.catalinzima.com/2010/07/my-technique-for-the-shader-based-dynamic-2d-shadows/
|
5
|
+
class LightSource
|
6
|
+
include Mixins::VersionChecking
|
7
|
+
|
8
|
+
# PIXEL_BUFFER_EXTENSION = "GL_EXT_pixel_buffer_object"
|
9
|
+
|
10
|
+
class << self
|
11
|
+
attr_accessor :distort_shader, :draw_shadows_shader, :blur_shader
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :radius
|
15
|
+
attr_accessor :x, :y, :z, :color
|
16
|
+
|
17
|
+
def width; @radius * 2 end
|
18
|
+
def height; @radius * 2 end
|
19
|
+
|
20
|
+
def initialize(x, y, z, radius, options = {})
|
21
|
+
#check_opengl_extension PIXEL_BUFFER_EXTENSION
|
22
|
+
|
23
|
+
@x, @y, @z, @radius = x, y, z, radius.to_i
|
24
|
+
@color = options[:color] || Gosu::Color::WHITE
|
25
|
+
|
26
|
+
@shadow_casters = Ashton::Texture.new width, height
|
27
|
+
@shadow_map = Ashton::Texture.new 2, height
|
28
|
+
@shadows = Ashton::Texture.new width, height
|
29
|
+
@blurred = Ashton::Texture.new width, height
|
30
|
+
|
31
|
+
load_shaders
|
32
|
+
end
|
33
|
+
|
34
|
+
public
|
35
|
+
# Only need to render shadows again if anything has actually changed!
|
36
|
+
def render_shadows(&block)
|
37
|
+
raise "block required" unless block_given?
|
38
|
+
|
39
|
+
render_shadow_casters &block
|
40
|
+
|
41
|
+
# Distort the shadow casters and reduce into a a 2-pixel wide shadow-map of the blockages.
|
42
|
+
LightSource.distort_shader.enable { distort }
|
43
|
+
|
44
|
+
# Render the shadows themselves, before blurring.
|
45
|
+
LightLightSource.draw_shadows_shader.enable { draw_shadows }
|
46
|
+
|
47
|
+
# Finally blur it up and apply the radial lighting.
|
48
|
+
LightSource.blur_shader.enable { blur }
|
49
|
+
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
def render_shadow_casters
|
55
|
+
raise "block required" unless block_given?
|
56
|
+
# Get a copy of the shadow-casting objects in out light-zone.
|
57
|
+
@shadow_casters.render do |buffer|
|
58
|
+
buffer.clear
|
59
|
+
$window.translate @radius - @x, @radius - @y do
|
60
|
+
yield
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
protected
|
66
|
+
def distort
|
67
|
+
LightSource.distort_shader.texture_width = width
|
68
|
+
@shadow_map.render do
|
69
|
+
$window.scale 1.0 / radius, 1 do
|
70
|
+
@shadow_casters.draw 0, 0, 0
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
protected
|
76
|
+
def draw_shadows
|
77
|
+
LightSource.draw_shadows_shader.texture_width = width
|
78
|
+
@shadows.render do
|
79
|
+
# Not actually drawing anything from the shadow map buffer.
|
80
|
+
# It is just a data input to what will be drawn.
|
81
|
+
$window.scale radius, 1 do
|
82
|
+
@shadow_map.draw 0, 0, 0
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
protected
|
88
|
+
def blur
|
89
|
+
LightSource.blur_shader.texture_width = width
|
90
|
+
@blurred.render do
|
91
|
+
@shadows.draw 0, 0, 0
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
public
|
96
|
+
def draw(options = {})
|
97
|
+
options = {
|
98
|
+
mode: :add,
|
99
|
+
color: @color,
|
100
|
+
}.merge! options
|
101
|
+
|
102
|
+
@blurred.draw @x - @radius, @y - @radius, @z, options
|
103
|
+
@shadow_casters.draw @x - @radius, @y - @radius, @z, options
|
104
|
+
nil
|
105
|
+
end
|
106
|
+
|
107
|
+
public
|
108
|
+
# Draw some quadrant lines (for debugging).
|
109
|
+
def draw_debug
|
110
|
+
color = @color.dup
|
111
|
+
color.alpha = 75
|
112
|
+
|
113
|
+
$window.translate -@radius, -@radius do
|
114
|
+
$window.draw_line x, y, color, x + width, y, color, z
|
115
|
+
$window.draw_line x + width, y, color, x + width, y + height, color, z
|
116
|
+
$window.draw_line x + width, y + height, color, x, y + height, color, z
|
117
|
+
$window.draw_line x, y + height, color, x, y, color, z
|
118
|
+
|
119
|
+
$window.draw_line x, y, color, x + width, y + height, color, z
|
120
|
+
$window.draw_line x, y + height, color, x + width, y, color, z
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
protected
|
125
|
+
def load_shaders
|
126
|
+
LightSource.distort_shader ||= Ashton::Shader.new fragment: :"lighting/distort"
|
127
|
+
|
128
|
+
LightSource.draw_shadows_shader ||= Ashton::Shader.new fragment: :"lighting/draw_shadows"
|
129
|
+
|
130
|
+
LightSource.blur_shader ||= Ashton::Shader.new fragment: :"lighting/shadow_blur"
|
131
|
+
|
132
|
+
nil
|
133
|
+
end
|
134
|
+
|
135
|
+
protected
|
136
|
+
# Used for debugging purposes only.
|
137
|
+
def save_buffers
|
138
|
+
# Only save once. for purposes of this example only.
|
139
|
+
@shadow_casters.to_image.save "output/shadow_casters_#{x}_#{y}.png"
|
140
|
+
@shadow_map.to_image.save "output/shadow_map_#{x}_#{y}.png"
|
141
|
+
@shadows.to_image.save "output/shadows_#{x}_#{y}.png"
|
142
|
+
@blurred.to_image.save "output/blurred_#{x}_#{y}.png"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Ashton
|
4
|
+
module Lighting
|
5
|
+
# Based on Catalin Zima's shader based dynamic shadows system.
|
6
|
+
# http://www.catalinzima.com/2010/07/my-technique-for-the-shader-based-dynamic-2d-shadows/
|
7
|
+
class Manager
|
8
|
+
include Enumerable
|
9
|
+
|
10
|
+
attr_accessor :camera_x, :camera_y, :z
|
11
|
+
|
12
|
+
def each(&block); @lights.each &block end
|
13
|
+
def size; @lights.size end
|
14
|
+
def empty?; @lights.empty? end
|
15
|
+
def width; @shadows.width end
|
16
|
+
def height; @shadows.height end
|
17
|
+
|
18
|
+
def initialize(options = {})
|
19
|
+
options = {
|
20
|
+
width: $window.width,
|
21
|
+
height: $window.height,
|
22
|
+
camera_x: 0,
|
23
|
+
camera_y: 0,
|
24
|
+
z: 0,
|
25
|
+
}.merge! options
|
26
|
+
|
27
|
+
@camera_x, @camera_y = options[:camera_x], options[:camera_y]
|
28
|
+
@z = options[:z]
|
29
|
+
|
30
|
+
@lights = Set.new
|
31
|
+
@shadows = Ashton::Texture.new options[:width], options[:height]
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param light [Ashton::LightSource]
|
35
|
+
# @return [Ashton::LightSource]
|
36
|
+
def add(light)
|
37
|
+
raise TypeError unless light.is_a? LightSource
|
38
|
+
|
39
|
+
@lights << light
|
40
|
+
light
|
41
|
+
end
|
42
|
+
alias_method :<<, :add
|
43
|
+
|
44
|
+
def remove(light)
|
45
|
+
@lights -= [light]
|
46
|
+
light
|
47
|
+
end
|
48
|
+
|
49
|
+
# @see Ashton::LightSource#new
|
50
|
+
#
|
51
|
+
# @return [Ashton::LightSource]
|
52
|
+
def create_light(*args)
|
53
|
+
add LightSource.new(*args)
|
54
|
+
end
|
55
|
+
|
56
|
+
def draw(options = {})
|
57
|
+
options = {
|
58
|
+
mode: :multiply,
|
59
|
+
}.merge! options
|
60
|
+
|
61
|
+
@shadows.draw @camera_x, @camera_y, @z, options
|
62
|
+
end
|
63
|
+
|
64
|
+
def update_shadow_casters(&block)
|
65
|
+
raise ArgumentError, "Requires block" unless block_given?
|
66
|
+
|
67
|
+
unless empty?
|
68
|
+
# TODO: Need to only render to lights that are on-screen.
|
69
|
+
@lights.each do |light|
|
70
|
+
light.send :render_shadow_casters, &block
|
71
|
+
end
|
72
|
+
|
73
|
+
# Use each shader on every light, to save setting and un-setting shaders (a bit faster, depending on number of light sources).
|
74
|
+
LightSource.distort_shader.enable do
|
75
|
+
@lights.each {|light| light.send :distort }
|
76
|
+
end
|
77
|
+
|
78
|
+
LightSource.draw_shadows_shader.enable do
|
79
|
+
@lights.each {|light| light.send :draw_shadows }
|
80
|
+
end
|
81
|
+
|
82
|
+
LightSource.blur_shader.enable do
|
83
|
+
@lights.each {|light| light.send :blur }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
@shadows.render do |buffer|
|
88
|
+
buffer.clear
|
89
|
+
$window.translate -@camera_x, -@camera_y do
|
90
|
+
@lights.each {|light| light.draw } unless empty?
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
nil
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Ashton
|
2
|
+
module Mixins
|
3
|
+
module VersionChecking
|
4
|
+
# Check if a specific OpenGL version is supported on this machine.
|
5
|
+
#
|
6
|
+
# @raise NotSupportedError
|
7
|
+
def check_opengl_version(version)
|
8
|
+
unless GL.version_supported? version
|
9
|
+
raise NotSupportedError, "OpenGL #{version} required to utilise #{self.class}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Check if a specific OpenGL extension is supported on this machine.
|
14
|
+
#
|
15
|
+
# @raise NotSupportedError
|
16
|
+
def check_opengl_extension(extension)
|
17
|
+
unless GL.extension_supported? extension
|
18
|
+
raise NotSupportedError, "OpenGL extension #{extension} required to utilise #{self.class}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Ashton
|
2
|
+
class ParticleEmitter
|
3
|
+
def empty?; count == 0 end
|
4
|
+
|
5
|
+
DEFAULT_MAX_PARTICLES = 1000
|
6
|
+
DEFAULT_COLOR = Gosu::Color::WHITE
|
7
|
+
RANGED_ATTRIBUTES = [
|
8
|
+
:angular_velocity, :center_x, :center_y,
|
9
|
+
:fade, :friction, :interval,
|
10
|
+
:offset, :scale, :speed, :time_to_live, :zoom
|
11
|
+
]
|
12
|
+
|
13
|
+
def initialize(x, y, z, options = {})
|
14
|
+
# I'm MUCH too lazy to implement a huge options hash manager in C, especially on a constructor.
|
15
|
+
max_particles = options[:max_particles] || DEFAULT_MAX_PARTICLES
|
16
|
+
initialize_ x, y, z, max_particles
|
17
|
+
|
18
|
+
self.shader = options[:shader]
|
19
|
+
self.image = options[:image] || $window.pixel
|
20
|
+
|
21
|
+
self.gravity = options[:gravity] || 0.0
|
22
|
+
self.color = options[:color] || DEFAULT_COLOR
|
23
|
+
|
24
|
+
self.angular_velocity = options[:angular_velocity] || 0.0
|
25
|
+
self.center_x = options[:center_x] || 0.5
|
26
|
+
self.center_y = options[:center_y] || 0.5
|
27
|
+
self.fade = options[:fade] || 0.0
|
28
|
+
self.friction = options[:friction] || 0.0
|
29
|
+
self.interval = options[:interval] || Float::INFINITY
|
30
|
+
self.offset = options[:offset] || 0.0
|
31
|
+
self.scale = options[:scale] || 1.0
|
32
|
+
self.speed = options[:speed] || 0.0
|
33
|
+
self.time_to_live = options[:time_to_live] || Float::INFINITY
|
34
|
+
self.zoom = options[:zoom] || 0.0
|
35
|
+
end
|
36
|
+
|
37
|
+
# Gosu::Color
|
38
|
+
def color
|
39
|
+
Gosu::Color.new color_argb
|
40
|
+
end
|
41
|
+
|
42
|
+
# [Gosu::Color, Integer, Array<Float>]
|
43
|
+
def color=(value)
|
44
|
+
case value
|
45
|
+
when Integer
|
46
|
+
self.color_argb = value
|
47
|
+
when Gosu::Color
|
48
|
+
self.color_argb = value.to_i
|
49
|
+
when Array
|
50
|
+
self.color_argb = Gosu::Color.from_opengl value
|
51
|
+
else
|
52
|
+
raise TypeError, "Expected argb integer, rgba opengl float array or Gosu::Color"
|
53
|
+
end
|
54
|
+
|
55
|
+
value
|
56
|
+
end
|
57
|
+
|
58
|
+
RANGED_ATTRIBUTES.each do |attr|
|
59
|
+
# Returns a Range.
|
60
|
+
define_method attr do
|
61
|
+
send("#{attr}_min")..send("#{attr}_max")
|
62
|
+
end
|
63
|
+
|
64
|
+
# Can be set as a Range or as a single number.
|
65
|
+
define_method "#{attr}=" do |value|
|
66
|
+
min, max = case value
|
67
|
+
when Numeric
|
68
|
+
[value, value]
|
69
|
+
when Range
|
70
|
+
[value.min, value.max]
|
71
|
+
else
|
72
|
+
raise TypeError, "Expecting Numeric or Range, not #{value.class}"
|
73
|
+
end
|
74
|
+
|
75
|
+
send "#{attr}_min=", min
|
76
|
+
send "#{attr}_max=", max
|
77
|
+
|
78
|
+
value
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# @!method draw()
|
83
|
+
|
84
|
+
# @!method update(delta)
|
85
|
+
# @param delta (Float) number of seconds to run the simulation for.
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Ashton
|
2
|
+
class PixelCache
|
3
|
+
# Docs here.
|
4
|
+
|
5
|
+
public
|
6
|
+
# Convert the current contents of the cache into a Gosu::Image
|
7
|
+
#
|
8
|
+
# @option options :caching [Boolean] (true) TexPlay behaviour.
|
9
|
+
# @option options :tileable [Boolean] (false) Standard Gosu behaviour.
|
10
|
+
def to_image(options = {})
|
11
|
+
options = {
|
12
|
+
tileable: false,
|
13
|
+
}.merge! options
|
14
|
+
|
15
|
+
# Create a new Image from the flipped pixel data.
|
16
|
+
stub = ImageStub.new to_blob, width, height
|
17
|
+
if defined? TexPlay
|
18
|
+
Gosu::Image.new $window, stub, options[:tileable], options
|
19
|
+
else
|
20
|
+
Gosu::Image.new $window, stub, options[:tileable]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|