ashton 0.0.1alpha → 0.0.2alpha
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/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
|
@@ -1,27 +1,25 @@
|
|
|
1
|
-
#version 110
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
uniform
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
uniform
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
vec4
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
gl_FragColor = color + in_Intensity * influence * noise;
|
|
27
|
-
}
|
|
1
|
+
#version 110
|
|
2
|
+
|
|
3
|
+
#include <rand>
|
|
4
|
+
|
|
5
|
+
// Rather poor quality noise generation, but better than nothing and sort of looks like TV static a bit.
|
|
6
|
+
|
|
7
|
+
uniform sampler2D in_Texture;
|
|
8
|
+
|
|
9
|
+
uniform int in_WindowWidth; // Not used.
|
|
10
|
+
uniform int in_WindowHeight; // Not used.
|
|
11
|
+
|
|
12
|
+
uniform float in_Intensity;
|
|
13
|
+
uniform float in_T;
|
|
14
|
+
|
|
15
|
+
varying vec2 var_TexCoord;
|
|
16
|
+
|
|
17
|
+
void main() {
|
|
18
|
+
vec4 color = texture2D(in_Texture, var_TexCoord);
|
|
19
|
+
|
|
20
|
+
vec4 influence = min(color, 1.0 - color);
|
|
21
|
+
|
|
22
|
+
float noise = 1.0 - 2.0 * rand(var_TexCoord + float(in_T));
|
|
23
|
+
|
|
24
|
+
gl_FragColor = color + in_Intensity * influence * noise;
|
|
25
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#version 110
|
|
2
|
+
|
|
3
|
+
// Use a stencil texture to selectively draw. Drawing of the image will occur
|
|
4
|
+
// where the stencil is transparent (or only where the stencil is opaque if
|
|
5
|
+
// inverted).
|
|
6
|
+
//
|
|
7
|
+
// Partial transparency in the stencil will allow the image to be drawn
|
|
8
|
+
// partially too.
|
|
9
|
+
|
|
10
|
+
varying vec4 var_Color;
|
|
11
|
+
varying vec2 var_TexCoord0; // The texture/image to draw.
|
|
12
|
+
varying vec2 var_TexCoord1; // The stencil (multitexture).
|
|
13
|
+
|
|
14
|
+
uniform sampler2D in_Texture0; // The texture/image to draw.
|
|
15
|
+
uniform sampler2D in_Texture1; // The stencil (multitexture).
|
|
16
|
+
uniform bool in_Inverted; // true to draw in opaque areas / false to draw in transparent areas.
|
|
17
|
+
|
|
18
|
+
void main()
|
|
19
|
+
{
|
|
20
|
+
vec4 texColor = texture2D(in_Texture0, var_TexCoord0);
|
|
21
|
+
vec4 maskColor = texture2D(in_Texture1, var_TexCoord1);
|
|
22
|
+
|
|
23
|
+
// Only draw the texture where the stencil is transparent (unless inverted).
|
|
24
|
+
float mask_alpha = in_Inverted ? (1.0 - maskColor.a) : maskColor.a;
|
|
25
|
+
|
|
26
|
+
gl_FragColor = vec4(texColor.r, texColor.g, texColor.b, texColor.a - mask_alpha);
|
|
27
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#version 110
|
|
2
|
+
|
|
3
|
+
uniform sampler2D in_Texture;
|
|
4
|
+
|
|
5
|
+
uniform float in_ColumnWidth; // In pixels.
|
|
6
|
+
uniform int in_WindowWidth;
|
|
7
|
+
uniform int in_WindowHeight; // Not used in this shader.
|
|
8
|
+
|
|
9
|
+
varying vec2 var_TexCoord;
|
|
10
|
+
|
|
11
|
+
void main()
|
|
12
|
+
{
|
|
13
|
+
vec3 color = texture2D(in_Texture, var_TexCoord).rgb;
|
|
14
|
+
|
|
15
|
+
gl_FragColor = vec4(color * 0.25, 1.0);
|
|
16
|
+
|
|
17
|
+
float column_index = var_TexCoord.x * float(in_WindowWidth) / in_ColumnWidth;
|
|
18
|
+
|
|
19
|
+
int c = int(mod(column_index, 3.0));
|
|
20
|
+
if(c == 0) { gl_FragColor.r = color.r; }
|
|
21
|
+
else if(c == 1) { gl_FragColor.g = color.g; }
|
|
22
|
+
else if(c == 2) { gl_FragColor.b = color.b; }
|
|
23
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
module Ashton
|
|
2
|
+
class SignedDistanceField
|
|
3
|
+
ZERO_DISTANCE = 128 # color channel containing 0 => -128, 128 => 0, 129 => +1, 255 => +128
|
|
4
|
+
|
|
5
|
+
attr_reader :width, :height
|
|
6
|
+
|
|
7
|
+
# Creates a Signed Distance Field based on a given image.
|
|
8
|
+
# When drawing into the SDF, drawing should ONLY have alpha of 0 (clear) or 255 (solid)
|
|
9
|
+
#
|
|
10
|
+
# @param width [Integer]
|
|
11
|
+
# @param height [Integer]
|
|
12
|
+
# @param max_distance [Integer] Maximum distance to measure.
|
|
13
|
+
# @option options :step_size [Integer] (1) pixels to step out.
|
|
14
|
+
# @option options :scale [Integer] (1) Scale relative to the image.
|
|
15
|
+
def initialize(width, height, max_distance, options = {}, &block)
|
|
16
|
+
options = {
|
|
17
|
+
scale: 1,
|
|
18
|
+
step_size: 1,
|
|
19
|
+
}.merge! options
|
|
20
|
+
|
|
21
|
+
@width, @height = width, height
|
|
22
|
+
@scale = options[:scale].to_f
|
|
23
|
+
|
|
24
|
+
@shader = Shader.new fragment: :signed_distance_field, uniforms: {
|
|
25
|
+
max_distance: max_distance.ceil,
|
|
26
|
+
step_size: options[:step_size].floor, # One pixel.
|
|
27
|
+
texture_size: [width, height].map(&:to_f),
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@field = Texture.new (width / @scale).ceil, (height / @scale).ceil
|
|
31
|
+
@mask = Texture.new @field.width, @field.height
|
|
32
|
+
|
|
33
|
+
if block_given?
|
|
34
|
+
render_field &block
|
|
35
|
+
else
|
|
36
|
+
@field.clear color: Gosu::Color.rgb(*([ZERO_DISTANCE + max_distance] * 3))
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Is the position clear for a given radius around it.
|
|
41
|
+
def position_clear?(x, y, radius)
|
|
42
|
+
sample_distance(x, y) >= radius
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# If positive, distance, in pixels, to the nearest opaque pixel.
|
|
46
|
+
# If negative, distance in pixels to the nearest transparent pixel.
|
|
47
|
+
def sample_distance(x, y)
|
|
48
|
+
x = [[x, width - 1].min, 0].max
|
|
49
|
+
y = [[y, height - 1].min, 0].max
|
|
50
|
+
# Could be checking any of red/blue/green.
|
|
51
|
+
@field.red((x / @scale).round, (y / @scale).round) - ZERO_DISTANCE
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Gets the gradient of the field at a given point.
|
|
55
|
+
# @return [Float, Float] gradient_x, gradient_y
|
|
56
|
+
def sample_gradient(x, y)
|
|
57
|
+
d0 = sample_distance x, y - 1
|
|
58
|
+
d1 = sample_distance x - 1, y
|
|
59
|
+
d2 = sample_distance x + 1, y
|
|
60
|
+
d3 = sample_distance x, y + 1
|
|
61
|
+
|
|
62
|
+
[(d2 - d1) / @scale, (d3 - d0) / @scale]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Get the normal at a given point.
|
|
66
|
+
# @return [Float, Float] normal_x, normal_y
|
|
67
|
+
def sample_normal(x, y)
|
|
68
|
+
gradient_x, gradient_y = sample_gradient x, y
|
|
69
|
+
length = Gosu::distance 0, 0, gradient_x, gradient_y
|
|
70
|
+
if length == 0
|
|
71
|
+
[0, 0] # This could be NaN in edge cases.
|
|
72
|
+
else
|
|
73
|
+
[gradient_x / length, gradient_y / length]
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Does the point x1, x2 have line of sight to x2, y2 (that is, no solid in the way).
|
|
78
|
+
def line_of_sight?(x1, y1, x2, y2)
|
|
79
|
+
!line_of_sight_blocked_at(x1, y1, x2, y2)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Returns blocking position, else nil if line of sight isn't blocked.
|
|
83
|
+
def line_of_sight_blocked_at(x1, y1, x2, y2)
|
|
84
|
+
distance_to_travel = Gosu::distance x1, y1, x2, y2
|
|
85
|
+
distance_x, distance_y = x2 - x1, y2 - y1
|
|
86
|
+
distance_travelled = 0
|
|
87
|
+
x, y = x1, y1
|
|
88
|
+
|
|
89
|
+
loop do
|
|
90
|
+
distance = sample_distance x, y
|
|
91
|
+
|
|
92
|
+
# Blocked?
|
|
93
|
+
return [x, y] if distance <= 0
|
|
94
|
+
|
|
95
|
+
distance_travelled += distance
|
|
96
|
+
|
|
97
|
+
# Got to destination in the clear.
|
|
98
|
+
return nil if distance_travelled >= distance_to_travel
|
|
99
|
+
|
|
100
|
+
lerp = distance_travelled.fdiv distance_to_travel
|
|
101
|
+
x = x1 + distance_x * lerp
|
|
102
|
+
y = y1 + distance_y * lerp
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Update the SDF should the image have changed.
|
|
107
|
+
# Draw the mask in the passed block.
|
|
108
|
+
def render_field
|
|
109
|
+
raise ArgumentError, "Block required" unless block_given?
|
|
110
|
+
|
|
111
|
+
@mask.render do
|
|
112
|
+
@mask.clear
|
|
113
|
+
$window.scale 1.0 / @scale do
|
|
114
|
+
yield self
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
@shader.enable do
|
|
119
|
+
@field.render do
|
|
120
|
+
@mask.draw 0, 0, 0
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
nil
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Draw the field, usually for debugging purposes.
|
|
128
|
+
# @see Ashton::Texture#draw
|
|
129
|
+
def draw(x, y, z, options = {})
|
|
130
|
+
options = {
|
|
131
|
+
mode: :add,
|
|
132
|
+
}.merge! options
|
|
133
|
+
|
|
134
|
+
$window.scale @scale do
|
|
135
|
+
@field.draw x, y, z, options
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
nil
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Convert into a nested array of sample values.
|
|
142
|
+
# @return [Array<Array<Integer>>]
|
|
143
|
+
def to_a
|
|
144
|
+
width.times.map do |x|
|
|
145
|
+
height.times.map do |y|
|
|
146
|
+
sample_distance x, y
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
module Ashton
|
|
2
|
+
class Texture
|
|
3
|
+
include Mixins::VersionChecking
|
|
4
|
+
|
|
5
|
+
DEFAULT_DRAW_COLOR = Gosu::Color::WHITE
|
|
6
|
+
VALID_DRAW_MODES = [:alpha_blend, :add, :multiply, :replace]
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
# [Boolean] Whether or not to pixelate (rather than smooth) on #draw
|
|
10
|
+
attr_writer :pixelated
|
|
11
|
+
# [Boolean] Whether or not to pixelate (rather than smooth) on #draw. Set true when Gosu::enable_undocumented_retrofication called.
|
|
12
|
+
def pixelated?; @pixelated end
|
|
13
|
+
end
|
|
14
|
+
self.pixelated = false
|
|
15
|
+
|
|
16
|
+
# [Boolean] Is this texture being rendered to currently?
|
|
17
|
+
def rendering?; @rendering end
|
|
18
|
+
|
|
19
|
+
# @overload initialize(image)
|
|
20
|
+
# Create a texture from a Gosu::Image
|
|
21
|
+
#
|
|
22
|
+
# @see Image#to_texture
|
|
23
|
+
# @param image [Gosu::Image]
|
|
24
|
+
#
|
|
25
|
+
# @overload initialize(blob, width, height)
|
|
26
|
+
# Create a texture from a binary blob.
|
|
27
|
+
#
|
|
28
|
+
# @param blob [String]
|
|
29
|
+
# @param width [Integer]
|
|
30
|
+
# @param height [Integer]
|
|
31
|
+
#
|
|
32
|
+
# @overload initialize(width, height)
|
|
33
|
+
# Create a blank (transparent) texture.
|
|
34
|
+
#
|
|
35
|
+
# @param width [Integer]
|
|
36
|
+
# @param height [Integer]
|
|
37
|
+
def initialize(*args)
|
|
38
|
+
case args.size
|
|
39
|
+
when 1
|
|
40
|
+
# Create from Gosu::Image
|
|
41
|
+
image = args[0]
|
|
42
|
+
raise TypeError, "Expected Gosu::Image" unless image.is_a? Gosu::Image
|
|
43
|
+
initialize_ image.width, image.height, nil
|
|
44
|
+
|
|
45
|
+
render do
|
|
46
|
+
# TODO: Ideally we'd draw the image in replacement mode, but Gosu doesn't support that.
|
|
47
|
+
$window.gl do
|
|
48
|
+
info = image.gl_tex_info
|
|
49
|
+
glEnable GL_TEXTURE_2D
|
|
50
|
+
glBindTexture GL_TEXTURE_2D, info.tex_name
|
|
51
|
+
glEnable GL_BLEND
|
|
52
|
+
glBlendFunc GL_ONE, GL_ZERO
|
|
53
|
+
|
|
54
|
+
glBegin GL_QUADS do
|
|
55
|
+
glTexCoord2d info.left, info.top
|
|
56
|
+
glVertex2d 0, height # BL
|
|
57
|
+
|
|
58
|
+
glTexCoord2d info.left, info.bottom
|
|
59
|
+
glVertex2d 0, 0 # TL
|
|
60
|
+
|
|
61
|
+
glTexCoord2d info.right, info.bottom
|
|
62
|
+
glVertex2d width, 0 # TR
|
|
63
|
+
|
|
64
|
+
glTexCoord2d info.right, info.top
|
|
65
|
+
glVertex2d width, height # BR
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
when 2
|
|
71
|
+
# Create blank image.
|
|
72
|
+
width, height = *args
|
|
73
|
+
initialize_ width, height, nil
|
|
74
|
+
clear
|
|
75
|
+
|
|
76
|
+
when 3
|
|
77
|
+
# Create from blob - create a Gosu image first.
|
|
78
|
+
blob, width, height = *args
|
|
79
|
+
raise ArgumentError, "Blob data is not of expected size" if blob.length != width * height * 4
|
|
80
|
+
initialize_ width, height, blob
|
|
81
|
+
|
|
82
|
+
else
|
|
83
|
+
raise ArgumentError, "Expected 1, 2 or 3 parameters."
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
@rendering = false
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
public
|
|
90
|
+
# Clears the buffer, optionally to a specific color.
|
|
91
|
+
#
|
|
92
|
+
# @option options :color [Gosu::Color, Array<Float>] (transparent)
|
|
93
|
+
def clear(options = {})
|
|
94
|
+
options = {
|
|
95
|
+
color: [0.0, 0.0, 0.0, 0.0],
|
|
96
|
+
}.merge! options
|
|
97
|
+
|
|
98
|
+
color = options[:color]
|
|
99
|
+
color = color.to_opengl if color.is_a? Gosu::Color
|
|
100
|
+
|
|
101
|
+
glBindFramebufferEXT GL_FRAMEBUFFER_EXT, fbo_id unless rendering?
|
|
102
|
+
|
|
103
|
+
glDisable GL_BLEND # Need to replace the alpha too.
|
|
104
|
+
glClearColor *color
|
|
105
|
+
glClear GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
|
|
106
|
+
glEnable GL_BLEND
|
|
107
|
+
|
|
108
|
+
glBindFramebufferEXT GL_FRAMEBUFFER_EXT, 0 unless rendering?
|
|
109
|
+
|
|
110
|
+
nil
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
public
|
|
114
|
+
# Enable the texture to use (e.g. to draw or convert it).
|
|
115
|
+
def render
|
|
116
|
+
raise ArgumentError, "Block required" unless block_given?
|
|
117
|
+
raise Error, "Can't nest rendering" if rendering?
|
|
118
|
+
|
|
119
|
+
$window.flush # Ensure that any drawing _before_ the render block is drawn to screen, rather than into the buffer.
|
|
120
|
+
|
|
121
|
+
render_
|
|
122
|
+
|
|
123
|
+
@rendering = true
|
|
124
|
+
|
|
125
|
+
# Project onto the texture itself, using Gosu (inverted) coordinates.
|
|
126
|
+
glPushMatrix
|
|
127
|
+
glMatrixMode GL_PROJECTION
|
|
128
|
+
glLoadIdentity
|
|
129
|
+
glViewport 0, 0, width, height
|
|
130
|
+
glOrtho 0, width, height, 0, -1, 1
|
|
131
|
+
|
|
132
|
+
begin
|
|
133
|
+
yield self
|
|
134
|
+
ensure
|
|
135
|
+
$window.flush # Force all the drawing to draw now!
|
|
136
|
+
glBindFramebufferEXT GL_FRAMEBUFFER_EXT, 0
|
|
137
|
+
|
|
138
|
+
@rendering = false
|
|
139
|
+
|
|
140
|
+
glPopMatrix
|
|
141
|
+
|
|
142
|
+
cache.refresh # Force lazy reloading of the cache.
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
self
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# @!method draw(x, y, z, options = {})
|
|
149
|
+
# Draw the Texture.
|
|
150
|
+
#
|
|
151
|
+
# This is not as versatile as converting the Texture into a Gosu::Image and then
|
|
152
|
+
# drawing it, but it is many times faster, so use it when you are updating the buffer
|
|
153
|
+
# every frame, rather than just composing an image.
|
|
154
|
+
#
|
|
155
|
+
# Drawing in Gosu orientation will be flipped in standard OpenGL and visa versa.
|
|
156
|
+
#
|
|
157
|
+
# @param x [Number] Top left corner x.
|
|
158
|
+
# @param y [Number] Top left corner y.
|
|
159
|
+
# @param z [Number] Z-order (can be nil to draw immediately)
|
|
160
|
+
#
|
|
161
|
+
# @option options :shader [Ashton::Shader] Shader to apply to drawing.
|
|
162
|
+
# @option options :color [Gosu::Color] (Gosu::Color::WHITE) Color to apply to the drawing.
|
|
163
|
+
# @option options :mode [Symbol] (:alpha_blend) :alpha_blend, :add, :multiply, :replace
|
|
164
|
+
# @option options :multitexture [Texture] A texture to be used in a multi-texturing shader.
|
|
165
|
+
# @option options :pixelated [Boolean] (true if Gosu::enable_undocumented_retrofication ever called) Pixelate, rather than smooth, when zoomed out.
|
|
166
|
+
|
|
167
|
+
public
|
|
168
|
+
# Convert the current contents of the buffer into a Gosu::Image
|
|
169
|
+
#
|
|
170
|
+
# @option options :caching [Boolean] (true) TexPlay behaviour.
|
|
171
|
+
# @option options :tileable [Boolean] (false) Standard Gosu behaviour.
|
|
172
|
+
# @option options :rect [Array<Integer>] ([0, 0, width, height]) Rectangular area of buffer to use to create the image [x, y, w, h]
|
|
173
|
+
def to_image(*args)
|
|
174
|
+
cache.to_image *args
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def dup
|
|
178
|
+
# Create a new texture and draw self into it.
|
|
179
|
+
new_texture = Texture.new width, height
|
|
180
|
+
new_texture.render do
|
|
181
|
+
draw 0, 0, 0, mode: :replace
|
|
182
|
+
end
|
|
183
|
+
new_texture
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
data/lib/ashton/version.rb
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
module Ashton
|
|
2
|
-
VERSION = "0.0.
|
|
1
|
+
module Ashton
|
|
2
|
+
VERSION = "0.0.2alpha"
|
|
3
3
|
end
|