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
@@ -0,0 +1,171 @@
|
|
1
|
+
/*
|
2
|
+
* class Ashton::ParticleEmitter
|
3
|
+
*
|
4
|
+
*/
|
5
|
+
|
6
|
+
|
7
|
+
#ifndef ASHTON_PARTICLE_EMITTER_H
|
8
|
+
#define ASHTON_PARTICLE_EMITTER_H
|
9
|
+
|
10
|
+
#include "fast_math.h"
|
11
|
+
#include "common.h"
|
12
|
+
|
13
|
+
#define VERTICES_IN_PARTICLE 4
|
14
|
+
|
15
|
+
// A single particle.
|
16
|
+
typedef struct _particle
|
17
|
+
{
|
18
|
+
// State.
|
19
|
+
float x, y;
|
20
|
+
float center_x, center_y;
|
21
|
+
float velocity_x, velocity_y;
|
22
|
+
float angular_velocity;
|
23
|
+
|
24
|
+
Color_f color;
|
25
|
+
|
26
|
+
// Rate of change
|
27
|
+
float fade;
|
28
|
+
float scale;
|
29
|
+
float zoom;
|
30
|
+
float friction;
|
31
|
+
float angle;
|
32
|
+
|
33
|
+
// Time to die.
|
34
|
+
float time_to_live;
|
35
|
+
} Particle;
|
36
|
+
|
37
|
+
typedef struct _range
|
38
|
+
{
|
39
|
+
float min, max;
|
40
|
+
} Range;
|
41
|
+
|
42
|
+
typedef struct _vertex2d
|
43
|
+
{
|
44
|
+
float x, y;
|
45
|
+
} Vertex2d;
|
46
|
+
|
47
|
+
typedef struct _tex_info
|
48
|
+
{
|
49
|
+
uint id;
|
50
|
+
float left;
|
51
|
+
float right;
|
52
|
+
float top;
|
53
|
+
float bottom;
|
54
|
+
} TextureInfo;
|
55
|
+
|
56
|
+
// The Ashton::ParticleEmitter's own data, including particles.
|
57
|
+
typedef struct _particle_emitter
|
58
|
+
{
|
59
|
+
VALUE rb_image;
|
60
|
+
uint width; // Width of image.
|
61
|
+
uint height; // Height of image.
|
62
|
+
TextureInfo texture_info; // Texture coords and id.
|
63
|
+
|
64
|
+
VALUE rb_shader;
|
65
|
+
|
66
|
+
// Position of the emitter.
|
67
|
+
float x, y, z;
|
68
|
+
float gravity;
|
69
|
+
|
70
|
+
// Generating particles.
|
71
|
+
Range angular_velocity;
|
72
|
+
Range center_x, center_y;
|
73
|
+
Color_f color;
|
74
|
+
Range fade;
|
75
|
+
Range friction;
|
76
|
+
Range offset; // Distance from origin to spawn.
|
77
|
+
Range scale;
|
78
|
+
Range speed;
|
79
|
+
Range time_to_live;
|
80
|
+
Range zoom;
|
81
|
+
|
82
|
+
// When to emit.
|
83
|
+
Range interval;
|
84
|
+
float time_until_emit;
|
85
|
+
|
86
|
+
// Managing the particles themselves.
|
87
|
+
uint count; // Current number of active particles.
|
88
|
+
uint max_particles; // No more will be created if max hit.
|
89
|
+
uint next_particle_index; // Next place to create a new particle (either dead or oldest living).
|
90
|
+
Particle* particles;
|
91
|
+
|
92
|
+
// VBO and client-side data arrays.
|
93
|
+
uint vbo_id;
|
94
|
+
|
95
|
+
Color_i* color_array; // Color array.
|
96
|
+
ulong color_array_offset; // Offset to colours within VBO.
|
97
|
+
|
98
|
+
Vertex2d* texture_coords_array; // Tex coord array.
|
99
|
+
ulong texture_coords_array_offset; // Offset to texture coords within VBO.
|
100
|
+
|
101
|
+
Vertex2d* vertex_array; // Vertex array.
|
102
|
+
ulong vertex_array_offset; // Offset to vertices within VBO.
|
103
|
+
} ParticleEmitter;
|
104
|
+
|
105
|
+
|
106
|
+
void Init_Ashton_ParticleEmitter(VALUE module);
|
107
|
+
|
108
|
+
// Initialization
|
109
|
+
VALUE Ashton_ParticleEmitter_init(VALUE self, VALUE x, VALUE y, VALUE z, VALUE max_particles);
|
110
|
+
|
111
|
+
// Create an 'emitter' variable which points to our data.
|
112
|
+
#define EMITTER() \
|
113
|
+
ParticleEmitter* emitter; \
|
114
|
+
Data_Get_Struct(self, ParticleEmitter, emitter);
|
115
|
+
|
116
|
+
|
117
|
+
// Implementation of get/set functions .
|
118
|
+
#define GET_EMITTER_DATA(ATTRIBUTE_NAME, ATTRIBUTE, CAST) \
|
119
|
+
VALUE Ashton_ParticleEmitter_get_##ATTRIBUTE_NAME(VALUE self) \
|
120
|
+
{ \
|
121
|
+
EMITTER(); \
|
122
|
+
return CAST(emitter->ATTRIBUTE); \
|
123
|
+
}
|
124
|
+
|
125
|
+
#include "limits.h"
|
126
|
+
// BUG: Passing in Infinity seems to convert it to NaN!
|
127
|
+
#define SET_EMITTER_DATA(ATTRIBUTE_NAME, ATTRIBUTE, CAST) \
|
128
|
+
VALUE Ashton_ParticleEmitter_set_##ATTRIBUTE_NAME(VALUE self, VALUE value) \
|
129
|
+
{ \
|
130
|
+
EMITTER(); \
|
131
|
+
emitter->ATTRIBUTE = CAST(value); \
|
132
|
+
return value; \
|
133
|
+
}
|
134
|
+
|
135
|
+
#define GET_SET_EMITTER_DATA(ATTRIBUTE, CAST_TO_RUBY, CAST_TO_C) \
|
136
|
+
GET_EMITTER_DATA(ATTRIBUTE, ATTRIBUTE, CAST_TO_RUBY) \
|
137
|
+
SET_EMITTER_DATA(ATTRIBUTE, ATTRIBUTE, CAST_TO_C)
|
138
|
+
|
139
|
+
#define GET_SET_EMITTER_DATA_RANGE(ATTRIBUTE, CAST_TO_RUBY, CAST_TO_C) \
|
140
|
+
GET_EMITTER_DATA(ATTRIBUTE##_min, ATTRIBUTE.min, CAST_TO_RUBY) \
|
141
|
+
SET_EMITTER_DATA(ATTRIBUTE##_min, ATTRIBUTE.min, CAST_TO_C) \
|
142
|
+
GET_EMITTER_DATA(ATTRIBUTE##_max, ATTRIBUTE.max, CAST_TO_RUBY) \
|
143
|
+
SET_EMITTER_DATA(ATTRIBUTE##_max, ATTRIBUTE.max, CAST_TO_C)
|
144
|
+
|
145
|
+
|
146
|
+
// Define minimum and maximum get/set functions as methods.
|
147
|
+
|
148
|
+
// Define get/set functions as methods.
|
149
|
+
#define DEFINE_METHOD_GET_SET(ATTRIBUTE) \
|
150
|
+
rb_define_method(rb_cParticleEmitter, #ATTRIBUTE, Ashton_ParticleEmitter_get_##ATTRIBUTE, 0); \
|
151
|
+
rb_define_method(rb_cParticleEmitter, #ATTRIBUTE "=", Ashton_ParticleEmitter_set_##ATTRIBUTE, 1);
|
152
|
+
|
153
|
+
#define DEFINE_METHOD_GET_SET_RANGE(ATTRIBUTE) \
|
154
|
+
DEFINE_METHOD_GET_SET(ATTRIBUTE##_min); \
|
155
|
+
DEFINE_METHOD_GET_SET(ATTRIBUTE##_max);
|
156
|
+
|
157
|
+
|
158
|
+
VALUE Ashton_ParticleEmitter_get_color_argb(VALUE self);
|
159
|
+
VALUE Ashton_ParticleEmitter_set_color_argb(VALUE self, VALUE color);
|
160
|
+
|
161
|
+
// Methods
|
162
|
+
VALUE Ashton_ParticleEmitter_get_shader(VALUE self);
|
163
|
+
VALUE Ashton_ParticleEmitter_set_shader(VALUE self, VALUE shader);
|
164
|
+
VALUE Ashton_ParticleEmitter_get_image(VALUE self);
|
165
|
+
VALUE Ashton_ParticleEmitter_set_image(VALUE self, VALUE image);
|
166
|
+
VALUE Ashton_ParticleEmitter_draw(VALUE self);
|
167
|
+
VALUE Ashton_ParticleEmitter_emit(VALUE self);
|
168
|
+
VALUE Ashton_ParticleEmitter_update(VALUE self, VALUE delta);
|
169
|
+
|
170
|
+
#endif // ASHTON_PARTICLE_EMITTER_H
|
171
|
+
|
@@ -0,0 +1,237 @@
|
|
1
|
+
#include "pixel_cache.h"
|
2
|
+
|
3
|
+
VALUE rb_cPixelCache;
|
4
|
+
|
5
|
+
// Helpers
|
6
|
+
static void cache_texture(PixelCache* pixel_cache);
|
7
|
+
static Color_i get_pixel_color(PixelCache* pixel_cache, VALUE x, VALUE y);
|
8
|
+
static VALUE pixel_cache_allocate(VALUE klass);
|
9
|
+
static void pixel_cache_mark(PixelCache* pixel_cache);
|
10
|
+
static void pixel_cache_free(PixelCache* pixel_cache);
|
11
|
+
|
12
|
+
void Init_Ashton_PixelCache(VALUE module)
|
13
|
+
{
|
14
|
+
rb_cPixelCache = rb_define_class_under(module, "PixelCache", rb_cObject);
|
15
|
+
|
16
|
+
rb_define_alloc_func(rb_cPixelCache, pixel_cache_allocate);
|
17
|
+
|
18
|
+
rb_define_method(rb_cPixelCache, "initialize", Ashton_PixelCache_init, 1);
|
19
|
+
|
20
|
+
// Getters
|
21
|
+
rb_define_method(rb_cPixelCache, "owner", Ashton_PixelCache_get_owner, 0);
|
22
|
+
rb_define_method(rb_cPixelCache, "width", Ashton_PixelCache_get_width, 0);
|
23
|
+
rb_define_method(rb_cPixelCache, "height", Ashton_PixelCache_get_height, 0);
|
24
|
+
|
25
|
+
// Methods
|
26
|
+
rb_define_method(rb_cPixelCache, "[]", Ashton_PixelCache_get_pixel, 2);
|
27
|
+
rb_define_method(rb_cPixelCache, "rgba", Ashton_PixelCache_get_rgba_array, 2);
|
28
|
+
rb_define_method(rb_cPixelCache, "red", Ashton_PixelCache_get_red, 2);
|
29
|
+
rb_define_method(rb_cPixelCache, "green", Ashton_PixelCache_get_green, 2);
|
30
|
+
rb_define_method(rb_cPixelCache, "blue", Ashton_PixelCache_get_blue, 2);
|
31
|
+
rb_define_method(rb_cPixelCache, "alpha", Ashton_PixelCache_get_alpha, 2);
|
32
|
+
rb_define_method(rb_cPixelCache, "transparent?", Ashton_PixelCache_is_transparent, 2);
|
33
|
+
|
34
|
+
rb_define_method(rb_cPixelCache, "refresh", Ashton_PixelCache_refresh, 0);
|
35
|
+
rb_define_method(rb_cPixelCache, "to_blob", Ashton_PixelCache_to_blob, 0);
|
36
|
+
}
|
37
|
+
|
38
|
+
//
|
39
|
+
VALUE Ashton_PixelCache_get_width(VALUE self)
|
40
|
+
{
|
41
|
+
PIXEL_CACHE();
|
42
|
+
return UINT2NUM(pixel_cache->width);
|
43
|
+
}
|
44
|
+
|
45
|
+
//
|
46
|
+
VALUE Ashton_PixelCache_get_height(VALUE self)
|
47
|
+
{
|
48
|
+
PIXEL_CACHE();
|
49
|
+
return UINT2NUM(pixel_cache->height);
|
50
|
+
}
|
51
|
+
|
52
|
+
|
53
|
+
//
|
54
|
+
static VALUE pixel_cache_allocate(VALUE klass)
|
55
|
+
{
|
56
|
+
PixelCache* pixel_cache = ALLOC(PixelCache);
|
57
|
+
memset(pixel_cache, 0, sizeof(PixelCache));
|
58
|
+
|
59
|
+
return Data_Wrap_Struct(klass, pixel_cache_mark, pixel_cache_free, pixel_cache);
|
60
|
+
}
|
61
|
+
|
62
|
+
//
|
63
|
+
static void pixel_cache_mark(PixelCache* pixel_cache)
|
64
|
+
{
|
65
|
+
rb_gc_mark(pixel_cache->rb_owner);
|
66
|
+
}
|
67
|
+
|
68
|
+
//
|
69
|
+
static void pixel_cache_free(PixelCache* pixel_cache)
|
70
|
+
{
|
71
|
+
xfree(pixel_cache->data);
|
72
|
+
xfree(pixel_cache);
|
73
|
+
}
|
74
|
+
|
75
|
+
//
|
76
|
+
VALUE Ashton_PixelCache_init(VALUE self, VALUE owner)
|
77
|
+
{
|
78
|
+
PIXEL_CACHE();
|
79
|
+
|
80
|
+
pixel_cache->rb_owner = owner;
|
81
|
+
|
82
|
+
// Different behaviour depending on what the owning class is.
|
83
|
+
if(RTEST(rb_obj_is_kind_of(owner, rb_cTexture)))
|
84
|
+
{
|
85
|
+
// Ashton::Texture
|
86
|
+
pixel_cache->texture_id = NUM2UINT(rb_funcall(owner, rb_intern("id"), 0));
|
87
|
+
}
|
88
|
+
else if(RTEST(rb_obj_is_kind_of(owner, rb_cImage)))
|
89
|
+
{
|
90
|
+
// Gosu::Image
|
91
|
+
// TODO: this needs to be done completely differently, since the image is a sprite on a texture, 1024x1024.
|
92
|
+
VALUE tex_info = rb_funcall(owner, rb_intern("gl_tex_info"), 0);
|
93
|
+
pixel_cache->texture_id = NUM2UINT(rb_funcall(tex_info, rb_intern("tex_name"), 0));
|
94
|
+
}
|
95
|
+
else
|
96
|
+
{
|
97
|
+
rb_raise(rb_eTypeError, "Can only cache Gosu::Image or Ashton::Texture objects.");
|
98
|
+
}
|
99
|
+
|
100
|
+
pixel_cache->width = NUM2UINT(rb_funcall(owner, rb_intern("width"), 0));
|
101
|
+
pixel_cache->height = NUM2UINT(rb_funcall(owner, rb_intern("height"), 0));
|
102
|
+
pixel_cache->data = ALLOC_N(Color_i, pixel_cache->width * pixel_cache->height);
|
103
|
+
cache_texture(pixel_cache);
|
104
|
+
|
105
|
+
return Qnil;
|
106
|
+
}
|
107
|
+
|
108
|
+
// Make a copy of the pixel_cache texture in main memory.
|
109
|
+
static void cache_texture(PixelCache* pixel_cache)
|
110
|
+
{
|
111
|
+
glEnable(GL_TEXTURE_2D);
|
112
|
+
glBindTexture(GL_TEXTURE_2D, pixel_cache->texture_id);
|
113
|
+
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel_cache->data);
|
114
|
+
|
115
|
+
pixel_cache->is_cached = true;
|
116
|
+
}
|
117
|
+
|
118
|
+
// Get color of a single pixel.
|
119
|
+
static Color_i get_pixel_color(PixelCache* pixel_cache, VALUE x, VALUE y)
|
120
|
+
{
|
121
|
+
int _x = NUM2INT(x);
|
122
|
+
int _y = NUM2INT(y);
|
123
|
+
|
124
|
+
if(_x < 0 || _x >= (int)pixel_cache->width ||
|
125
|
+
_y < 0 || _y >= (int)pixel_cache->height)
|
126
|
+
{
|
127
|
+
Color_i color;
|
128
|
+
memset(&color, 0, sizeof(Color_i));
|
129
|
+
return color;
|
130
|
+
}
|
131
|
+
else
|
132
|
+
{
|
133
|
+
if(!pixel_cache->is_cached) cache_texture(pixel_cache);
|
134
|
+
|
135
|
+
return pixel_cache->data[_x + _y * pixel_cache->width];
|
136
|
+
}
|
137
|
+
}
|
138
|
+
|
139
|
+
VALUE Ashton_PixelCache_get_owner(VALUE self)
|
140
|
+
{
|
141
|
+
PIXEL_CACHE();
|
142
|
+
return pixel_cache->rb_owner;
|
143
|
+
}
|
144
|
+
|
145
|
+
//
|
146
|
+
VALUE Ashton_PixelCache_refresh(VALUE self)
|
147
|
+
{
|
148
|
+
PIXEL_CACHE();
|
149
|
+
// Lazy refresh - we take a new copy only when we access it next.
|
150
|
+
pixel_cache->is_cached = false;
|
151
|
+
return Qnil;
|
152
|
+
}
|
153
|
+
|
154
|
+
// Gosu:Color object.
|
155
|
+
VALUE Ashton_PixelCache_get_pixel(VALUE self, VALUE x, VALUE y)
|
156
|
+
{
|
157
|
+
PIXEL_CACHE();
|
158
|
+
|
159
|
+
Color_i rgba = get_pixel_color(pixel_cache, x, y);
|
160
|
+
|
161
|
+
VALUE color = rb_funcall(rb_cColor, rb_intern("new"), 1,
|
162
|
+
UINT2NUM((rgba.alpha << 24) +
|
163
|
+
(rgba.red << 16) +
|
164
|
+
(rgba.green << 8) +
|
165
|
+
rgba.blue));
|
166
|
+
|
167
|
+
return color;
|
168
|
+
}
|
169
|
+
|
170
|
+
// RGBA array [255, 255, 255, 255]
|
171
|
+
VALUE Ashton_PixelCache_get_rgba_array(VALUE self, VALUE x, VALUE y)
|
172
|
+
{
|
173
|
+
PIXEL_CACHE();
|
174
|
+
|
175
|
+
Color_i rgba = get_pixel_color(pixel_cache, x, y);
|
176
|
+
|
177
|
+
VALUE array = rb_ary_new();
|
178
|
+
rb_ary_push(array, UINT2NUM(rgba.red));
|
179
|
+
rb_ary_push(array, UINT2NUM(rgba.green));
|
180
|
+
rb_ary_push(array, UINT2NUM(rgba.blue));
|
181
|
+
rb_ary_push(array, UINT2NUM(rgba.alpha));
|
182
|
+
|
183
|
+
return array;
|
184
|
+
}
|
185
|
+
|
186
|
+
//
|
187
|
+
VALUE Ashton_PixelCache_get_red(VALUE self, VALUE x, VALUE y)
|
188
|
+
{
|
189
|
+
PIXEL_CACHE();
|
190
|
+
Color_i rgba = get_pixel_color(pixel_cache, x, y);
|
191
|
+
return UINT2NUM(rgba.red);
|
192
|
+
}
|
193
|
+
|
194
|
+
//
|
195
|
+
VALUE Ashton_PixelCache_get_green(VALUE self, VALUE x, VALUE y)
|
196
|
+
{
|
197
|
+
PIXEL_CACHE();
|
198
|
+
Color_i rgba = get_pixel_color(pixel_cache, x, y);
|
199
|
+
return UINT2NUM(rgba.green);
|
200
|
+
}
|
201
|
+
|
202
|
+
//
|
203
|
+
VALUE Ashton_PixelCache_get_blue(VALUE self, VALUE x, VALUE y)
|
204
|
+
{
|
205
|
+
PIXEL_CACHE();
|
206
|
+
Color_i rgba = get_pixel_color(pixel_cache, x, y);
|
207
|
+
return UINT2NUM(rgba.blue);
|
208
|
+
}
|
209
|
+
|
210
|
+
//
|
211
|
+
VALUE Ashton_PixelCache_get_alpha(VALUE self, VALUE x, VALUE y)
|
212
|
+
{
|
213
|
+
PIXEL_CACHE();
|
214
|
+
Color_i rgba = get_pixel_color(pixel_cache, x, y);
|
215
|
+
return UINT2NUM(rgba.alpha);
|
216
|
+
}
|
217
|
+
|
218
|
+
//
|
219
|
+
VALUE Ashton_PixelCache_is_transparent(VALUE self, VALUE x, VALUE y)
|
220
|
+
{
|
221
|
+
PIXEL_CACHE();
|
222
|
+
Color_i rgba = get_pixel_color(pixel_cache, x, y);
|
223
|
+
return (rgba.alpha == 0) ? Qtrue : Qfalse;
|
224
|
+
}
|
225
|
+
|
226
|
+
//
|
227
|
+
VALUE Ashton_PixelCache_to_blob(VALUE self)
|
228
|
+
{
|
229
|
+
PIXEL_CACHE();
|
230
|
+
|
231
|
+
uint size = sizeof(Color_i) * pixel_cache->width * pixel_cache->height;
|
232
|
+
VALUE blob = rb_str_new(NULL, size);
|
233
|
+
|
234
|
+
memcpy(RSTRING_PTR(blob), pixel_cache->data, size);
|
235
|
+
|
236
|
+
return blob;
|
237
|
+
}
|
@@ -0,0 +1,58 @@
|
|
1
|
+
/*
|
2
|
+
* class Ashton::PixelCache
|
3
|
+
*
|
4
|
+
*
|
5
|
+
*/
|
6
|
+
|
7
|
+
|
8
|
+
#ifndef ASHTON_PIXEL_CACHE_H
|
9
|
+
#define ASHTON_PIXEL_CACHE_H
|
10
|
+
|
11
|
+
#include <math.h>
|
12
|
+
|
13
|
+
#include "common.h"
|
14
|
+
|
15
|
+
typedef struct _pixel_cache
|
16
|
+
{
|
17
|
+
float x;
|
18
|
+
float y;
|
19
|
+
|
20
|
+
uint width;
|
21
|
+
uint height;
|
22
|
+
|
23
|
+
VALUE rb_owner; // Texture or Image object (held for marking purposes).
|
24
|
+
uint texture_id; // Direct access to the owner's texture.
|
25
|
+
|
26
|
+
Color_i* data; // The actual "blob" data.
|
27
|
+
|
28
|
+
bool is_cached; // If false, then the cache data needs updating.
|
29
|
+
bool is_created; // Has space for the cache ever been allocated?
|
30
|
+
} PixelCache;
|
31
|
+
|
32
|
+
#define PIXEL_CACHE() \
|
33
|
+
PixelCache* pixel_cache; \
|
34
|
+
Data_Get_Struct(self, PixelCache, pixel_cache);
|
35
|
+
|
36
|
+
void Init_Ashton_PixelCache(VALUE module);
|
37
|
+
|
38
|
+
// Creation and destruction.
|
39
|
+
VALUE Ashton_PixelCache_init(VALUE self, VALUE owner);
|
40
|
+
|
41
|
+
// Accessors
|
42
|
+
VALUE Ashton_PixelCache_get_owner(VALUE self);
|
43
|
+
VALUE Ashton_PixelCache_get_width(VALUE self);
|
44
|
+
VALUE Ashton_PixelCache_get_height(VALUE self);
|
45
|
+
|
46
|
+
// Methods.
|
47
|
+
VALUE Ashton_PixelCache_get_pixel(VALUE self, VALUE x, VALUE y);
|
48
|
+
VALUE Ashton_PixelCache_get_rgba_array(VALUE self, VALUE x, VALUE y);
|
49
|
+
VALUE Ashton_PixelCache_get_red(VALUE self, VALUE x, VALUE y);
|
50
|
+
VALUE Ashton_PixelCache_get_green(VALUE self, VALUE x, VALUE y);
|
51
|
+
VALUE Ashton_PixelCache_get_blue(VALUE self, VALUE x, VALUE y);
|
52
|
+
VALUE Ashton_PixelCache_get_alpha(VALUE self, VALUE x, VALUE y);
|
53
|
+
VALUE Ashton_PixelCache_is_transparent(VALUE self, VALUE x, VALUE y);
|
54
|
+
|
55
|
+
VALUE Ashton_PixelCache_refresh(VALUE self);
|
56
|
+
VALUE Ashton_PixelCache_to_blob(VALUE self);
|
57
|
+
|
58
|
+
#endif // ASHTON_PIXEL_CACHE_H
|