danabr75-ashton 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG +0 -0
- data/LICENSE +21 -0
- data/README.md +95 -0
- data/Rakefile +42 -0
- data/examples/bloom_example.rb +59 -0
- data/examples/lighting_example.rb +127 -0
- data/examples/media/Earth.png +0 -0
- data/examples/media/LargeStar.png +0 -0
- data/examples/media/SmallStar.png +0 -0
- data/examples/media/Star.png +0 -0
- data/examples/media/Starfighter.bmp +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 +52 -0
- data/examples/pixelated_texture_example.rb +69 -0
- data/examples/radial_blur_example.rb +61 -0
- data/examples/shader_image_example.rb +75 -0
- data/examples/shockwave_example.rb +75 -0
- data/examples/stencil_shader_example.rb +104 -0
- data/examples/texture_render_example.rb +54 -0
- data/examples/tv_screen_and_static_example.rb +60 -0
- data/ext/ashton/GLee.c +18170 -0
- data/ext/ashton/GLee.h +17648 -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 +45 -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/vendor/gl/include/GL/GL.H +1526 -0
- data/ext/ashton/window.c +8 -0
- data/ext/ashton/window.h +16 -0
- data/lib/ashton.rb +38 -0
- data/lib/ashton/gosu_ext/color.rb +25 -0
- 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 +96 -0
- data/lib/ashton/gosu_ext/window.rb +79 -0
- data/lib/ashton/image_stub.rb +33 -0
- 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 +386 -0
- data/lib/ashton/shaders/bloom.frag +41 -0
- data/lib/ashton/shaders/color_inversion.frag +11 -0
- data/lib/ashton/shaders/contrast.frag +16 -0
- data/lib/ashton/shaders/default.frag +22 -0
- data/lib/ashton/shaders/default.vert +14 -0
- 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/shaders/include/noise2d.glsl +70 -0
- 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/shaders/pixelate.frag +48 -0
- data/lib/ashton/shaders/radial_blur.frag +63 -0
- data/lib/ashton/shaders/sepia.frag +26 -0
- data/lib/ashton/shaders/shockwave.frag +38 -0
- data/lib/ashton/shaders/signed_distance_field.frag +80 -0
- data/lib/ashton/shaders/static.frag +25 -0
- 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 +3 -0
- 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 +309 -0
data/ext/ashton/shader.c
ADDED
data/ext/ashton/shader.h
ADDED
@@ -0,0 +1,442 @@
|
|
1
|
+
#include "texture.h"
|
2
|
+
|
3
|
+
VALUE rb_cTexture;
|
4
|
+
|
5
|
+
// Helpers
|
6
|
+
static VALUE texture_allocate(VALUE klass);
|
7
|
+
static void texture_mark(Texture* texture);
|
8
|
+
static void texture_free(Texture* texture);
|
9
|
+
static void ensure_cache_exists(VALUE self, Texture* texture);
|
10
|
+
static void ensure_fbo_exists(Texture* texture);
|
11
|
+
|
12
|
+
void Init_Ashton_Texture(VALUE module)
|
13
|
+
{
|
14
|
+
rb_cTexture = rb_define_class_under(module, "Texture", rb_cObject);
|
15
|
+
|
16
|
+
rb_define_alloc_func(rb_cTexture, texture_allocate);
|
17
|
+
|
18
|
+
rb_define_protected_method(rb_cTexture, "initialize_", Ashton_Texture_init, 3);
|
19
|
+
rb_define_protected_method(rb_cTexture, "render_", Ashton_Texture_render, 0);
|
20
|
+
|
21
|
+
rb_define_method(rb_cTexture, "cache", Ashton_Texture_get_cache, 0);
|
22
|
+
|
23
|
+
rb_define_method(rb_cTexture, "width", Ashton_Texture_get_width, 0);
|
24
|
+
rb_define_method(rb_cTexture, "height", Ashton_Texture_get_height, 0);
|
25
|
+
rb_define_method(rb_cTexture, "fbo_id", Ashton_Texture_get_fbo_id, 0);
|
26
|
+
rb_define_method(rb_cTexture, "id", Ashton_Texture_get_id, 0);
|
27
|
+
|
28
|
+
rb_define_method(rb_cTexture, "[]", Ashton_Texture_get_pixel, 2);
|
29
|
+
rb_define_method(rb_cTexture, "rgba", Ashton_Texture_get_rgba_array, 2);
|
30
|
+
rb_define_method(rb_cTexture, "red", Ashton_Texture_get_red, 2);
|
31
|
+
rb_define_method(rb_cTexture, "green", Ashton_Texture_get_green, 2);
|
32
|
+
rb_define_method(rb_cTexture, "blue", Ashton_Texture_get_blue, 2);
|
33
|
+
rb_define_method(rb_cTexture, "alpha", Ashton_Texture_get_alpha, 2);
|
34
|
+
|
35
|
+
rb_define_method(rb_cTexture, "transparent?", Ashton_Texture_is_transparent, 2);
|
36
|
+
rb_define_method(rb_cTexture, "refresh_cache", Ashton_Texture_refresh_cache, 0);
|
37
|
+
rb_define_method(rb_cTexture, "to_blob", Ashton_Texture_to_blob, 0);
|
38
|
+
rb_define_method(rb_cTexture, "draw", Ashton_Texture_draw, -1);
|
39
|
+
}
|
40
|
+
|
41
|
+
//
|
42
|
+
VALUE Ashton_Texture_get_width(VALUE self)
|
43
|
+
{
|
44
|
+
TEXTURE();
|
45
|
+
return UINT2NUM(texture->width);
|
46
|
+
}
|
47
|
+
|
48
|
+
//
|
49
|
+
VALUE Ashton_Texture_get_height(VALUE self)
|
50
|
+
{
|
51
|
+
TEXTURE();
|
52
|
+
return UINT2NUM(texture->height);
|
53
|
+
}
|
54
|
+
|
55
|
+
//
|
56
|
+
static void ensure_fbo_exists(Texture* texture)
|
57
|
+
{
|
58
|
+
if(!texture->fbo_id)
|
59
|
+
{
|
60
|
+
glGenFramebuffersEXT(1, &texture->fbo_id);
|
61
|
+
|
62
|
+
// Bind our already existing texture to the FBO.
|
63
|
+
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, texture->fbo_id);
|
64
|
+
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
65
|
+
GL_TEXTURE_2D, texture->id, 0);
|
66
|
+
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
VALUE Ashton_Texture_get_fbo_id(VALUE self)
|
71
|
+
{
|
72
|
+
TEXTURE();
|
73
|
+
ensure_fbo_exists(texture);
|
74
|
+
return UINT2NUM(texture->fbo_id);
|
75
|
+
}
|
76
|
+
|
77
|
+
VALUE Ashton_Texture_get_id(VALUE self)
|
78
|
+
{
|
79
|
+
TEXTURE();
|
80
|
+
return UINT2NUM(texture->id);
|
81
|
+
}
|
82
|
+
|
83
|
+
//
|
84
|
+
VALUE Ashton_Texture_init(VALUE self, VALUE width, VALUE height, VALUE blob)
|
85
|
+
{
|
86
|
+
TEXTURE();
|
87
|
+
|
88
|
+
if(!GL_EXT_framebuffer_object)
|
89
|
+
{
|
90
|
+
rb_raise(rb_eRuntimeError, "Ashton::Texture requires GL_EXT_framebuffer_object, which is not supported by OpenGL");
|
91
|
+
}
|
92
|
+
|
93
|
+
texture->width = NUM2UINT(width);
|
94
|
+
texture->height = NUM2UINT(height);
|
95
|
+
|
96
|
+
texture->rb_cache = Qnil;
|
97
|
+
|
98
|
+
// Create the texture.
|
99
|
+
glGenTextures(1, &texture->id);
|
100
|
+
glBindTexture(GL_TEXTURE_2D, texture->id);
|
101
|
+
|
102
|
+
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
103
|
+
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
104
|
+
// MAG_FILTER set on each draw
|
105
|
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
106
|
+
|
107
|
+
// Create the texture, either undefined or based on RGBA blob data string.
|
108
|
+
char* data;
|
109
|
+
if(NIL_P(blob))
|
110
|
+
{
|
111
|
+
data = NULL; // Create an empty texture, that might be filled with junk.
|
112
|
+
}
|
113
|
+
else
|
114
|
+
{
|
115
|
+
data = StringValuePtr(blob); // Create from blob data.
|
116
|
+
}
|
117
|
+
|
118
|
+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texture->width,
|
119
|
+
texture->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
120
|
+
|
121
|
+
// Ensure the texture was created.
|
122
|
+
GLint created_width;
|
123
|
+
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &created_width);
|
124
|
+
if(created_width == 0) {
|
125
|
+
rb_raise(rb_eArgError, "Unable to create a texture of size %dx%d",
|
126
|
+
texture->width, texture->height);
|
127
|
+
}
|
128
|
+
|
129
|
+
// Be as lazy as possible in creating the actual FBO :)
|
130
|
+
|
131
|
+
return Qnil;
|
132
|
+
}
|
133
|
+
|
134
|
+
VALUE Ashton_Texture_render(VALUE self)
|
135
|
+
{
|
136
|
+
TEXTURE();
|
137
|
+
|
138
|
+
ensure_fbo_exists(texture);
|
139
|
+
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, texture->fbo_id);
|
140
|
+
|
141
|
+
return Qnil;
|
142
|
+
}
|
143
|
+
|
144
|
+
//
|
145
|
+
static VALUE texture_allocate(VALUE klass)
|
146
|
+
{
|
147
|
+
Texture* texture = ALLOC(Texture);
|
148
|
+
memset(texture, 0, sizeof(Texture));
|
149
|
+
|
150
|
+
return Data_Wrap_Struct(klass, texture_mark, texture_free, texture);
|
151
|
+
}
|
152
|
+
|
153
|
+
//
|
154
|
+
static void texture_mark(Texture* texture)
|
155
|
+
{
|
156
|
+
if(!NIL_P(texture->rb_cache)) rb_gc_mark(texture->rb_cache);
|
157
|
+
}
|
158
|
+
|
159
|
+
//
|
160
|
+
static void texture_free(Texture* texture)
|
161
|
+
{
|
162
|
+
// FBO might never have been created.
|
163
|
+
if(texture->fbo_id) glDeleteFramebuffersEXT(1, &texture->fbo_id);
|
164
|
+
|
165
|
+
glDeleteTextures(1, &texture->id);
|
166
|
+
xfree(texture);
|
167
|
+
}
|
168
|
+
|
169
|
+
//
|
170
|
+
void ensure_cache_exists(VALUE self, Texture* texture)
|
171
|
+
{
|
172
|
+
if(NIL_P(texture->rb_cache))
|
173
|
+
{
|
174
|
+
texture->rb_cache = rb_funcall(rb_cPixelCache, rb_intern("new"), 1, self);
|
175
|
+
}
|
176
|
+
}
|
177
|
+
|
178
|
+
// Returns the cache. Creates it if necessary.
|
179
|
+
VALUE Ashton_Texture_get_cache(VALUE self)
|
180
|
+
{
|
181
|
+
TEXTURE();
|
182
|
+
ensure_cache_exists(self, texture);
|
183
|
+
return texture->rb_cache;
|
184
|
+
}
|
185
|
+
|
186
|
+
//
|
187
|
+
VALUE Ashton_Texture_get_pixel(VALUE self, VALUE x, VALUE y)
|
188
|
+
{
|
189
|
+
TEXTURE();
|
190
|
+
ensure_cache_exists(self, texture);
|
191
|
+
return Ashton_PixelCache_get_pixel(texture->rb_cache, x, y);
|
192
|
+
}
|
193
|
+
|
194
|
+
VALUE Ashton_Texture_get_rgba_array(VALUE self, VALUE x, VALUE y)
|
195
|
+
{
|
196
|
+
TEXTURE();
|
197
|
+
ensure_cache_exists(self, texture);
|
198
|
+
return Ashton_PixelCache_get_rgba_array(texture->rb_cache, x, y);
|
199
|
+
}
|
200
|
+
|
201
|
+
//
|
202
|
+
VALUE Ashton_Texture_get_red(VALUE self, VALUE x, VALUE y)
|
203
|
+
{
|
204
|
+
TEXTURE();
|
205
|
+
ensure_cache_exists(self, texture);
|
206
|
+
return Ashton_PixelCache_get_red(texture->rb_cache, x, y);
|
207
|
+
}
|
208
|
+
|
209
|
+
//
|
210
|
+
VALUE Ashton_Texture_get_green(VALUE self, VALUE x, VALUE y)
|
211
|
+
{
|
212
|
+
TEXTURE();
|
213
|
+
ensure_cache_exists(self, texture);
|
214
|
+
return Ashton_PixelCache_get_green(texture->rb_cache, x, y);
|
215
|
+
}
|
216
|
+
|
217
|
+
//
|
218
|
+
VALUE Ashton_Texture_get_blue(VALUE self, VALUE x, VALUE y)
|
219
|
+
{
|
220
|
+
TEXTURE();
|
221
|
+
ensure_cache_exists(self, texture);
|
222
|
+
return Ashton_PixelCache_get_blue(texture->rb_cache, x, y);
|
223
|
+
}
|
224
|
+
|
225
|
+
//
|
226
|
+
VALUE Ashton_Texture_get_alpha(VALUE self, VALUE x, VALUE y)
|
227
|
+
{
|
228
|
+
TEXTURE();
|
229
|
+
ensure_cache_exists(self, texture);
|
230
|
+
return Ashton_PixelCache_get_alpha(texture->rb_cache, x, y);
|
231
|
+
}
|
232
|
+
|
233
|
+
//
|
234
|
+
VALUE Ashton_Texture_is_transparent(VALUE self, VALUE x, VALUE y)
|
235
|
+
{
|
236
|
+
TEXTURE();
|
237
|
+
ensure_cache_exists(self, texture);
|
238
|
+
return Ashton_PixelCache_is_transparent(texture->rb_cache, x, y);
|
239
|
+
}
|
240
|
+
|
241
|
+
VALUE Ashton_Texture_refresh_cache(VALUE self)
|
242
|
+
{
|
243
|
+
TEXTURE();
|
244
|
+
ensure_cache_exists(self, texture);
|
245
|
+
return Ashton_PixelCache_refresh(texture->rb_cache);
|
246
|
+
}
|
247
|
+
|
248
|
+
VALUE Ashton_Texture_to_blob(VALUE self)
|
249
|
+
{
|
250
|
+
TEXTURE();
|
251
|
+
ensure_cache_exists(self, texture);
|
252
|
+
return Ashton_PixelCache_to_blob(texture->rb_cache);
|
253
|
+
}
|
254
|
+
|
255
|
+
// ----------------------------------------
|
256
|
+
static VALUE draw_block(VALUE yield_value, VALUE parameters, int argc, VALUE argv[])
|
257
|
+
{
|
258
|
+
VALUE self = rb_ary_entry(parameters, 0);
|
259
|
+
float x = (float)NUM2DBL(rb_ary_entry(parameters, 1));
|
260
|
+
float y = (float)NUM2DBL(rb_ary_entry(parameters, 2));
|
261
|
+
VALUE blend_mode = rb_ary_entry(parameters, 3);
|
262
|
+
VALUE color = rb_ary_entry(parameters, 4);
|
263
|
+
VALUE shader = rb_ary_entry(parameters, 5);
|
264
|
+
VALUE multitexture = rb_ary_entry(parameters, 6);
|
265
|
+
VALUE pixelated = rb_ary_entry(parameters, 7);
|
266
|
+
|
267
|
+
TEXTURE(); // Uses 'self' value, so can't be at start of function.
|
268
|
+
|
269
|
+
if(!NIL_P(shader))
|
270
|
+
{
|
271
|
+
VALUE options = rb_hash_new();
|
272
|
+
rb_hash_aset(options, SYMBOL("required"), Qfalse);
|
273
|
+
|
274
|
+
VALUE location = rb_funcall(shader, rb_intern("send"), 3, SYMBOL("uniform_location"), SYMBOL("texture_enabled"), options);
|
275
|
+
if(FIX2INT(location) != -1)
|
276
|
+
{
|
277
|
+
rb_funcall(shader, rb_intern("send"), 3, SYMBOL("set_uniform"), location, Qtrue);
|
278
|
+
}
|
279
|
+
rb_funcall(shader, rb_intern("color="), 1, color);
|
280
|
+
}
|
281
|
+
|
282
|
+
glEnable(GL_BLEND);
|
283
|
+
glEnable(GL_TEXTURE_2D);
|
284
|
+
glBindTexture(GL_TEXTURE_2D, texture->id);
|
285
|
+
|
286
|
+
// Pixelate or smooth, depending on preference.
|
287
|
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
288
|
+
RTEST(pixelated) ? GL_NEAREST : GL_LINEAR);
|
289
|
+
|
290
|
+
// Set blending mode.
|
291
|
+
// Don't need an 'else' clause, since we checked before.
|
292
|
+
ID blend_id = SYM2ID(blend_mode);
|
293
|
+
if(blend_id == rb_intern(DRAW_MODE_ALPHA_BLEND))
|
294
|
+
{
|
295
|
+
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
296
|
+
}
|
297
|
+
else if(blend_id == rb_intern(DRAW_MODE_ADD))
|
298
|
+
{
|
299
|
+
glBlendFunc(GL_ONE, GL_ONE);
|
300
|
+
}
|
301
|
+
else if(blend_id == rb_intern(DRAW_MODE_MULTIPLY))
|
302
|
+
{
|
303
|
+
glBlendFunc(GL_DST_COLOR, GL_ZERO);
|
304
|
+
}
|
305
|
+
else if(blend_id == rb_intern(DRAW_MODE_REPLACE))
|
306
|
+
{
|
307
|
+
glBlendFunc(GL_ONE, GL_ZERO);
|
308
|
+
}
|
309
|
+
|
310
|
+
// Enable multitexturing.
|
311
|
+
if(!NIL_P(multitexture))
|
312
|
+
{
|
313
|
+
uint texture_id = NUM2UINT(rb_funcall(multitexture, rb_intern("id"), 0));
|
314
|
+
glActiveTexture(GL_TEXTURE1);
|
315
|
+
glBindTexture(GL_TEXTURE_2D, texture_id);
|
316
|
+
}
|
317
|
+
|
318
|
+
glBegin(GL_QUADS);
|
319
|
+
glTexCoord2d(0.0, 0.0);
|
320
|
+
glMultiTexCoord2d(GL_TEXTURE1, 0.0, 0.0);
|
321
|
+
glVertex2d(x, y + texture->height); // BL
|
322
|
+
|
323
|
+
glTexCoord2d(0.0, 1.0);
|
324
|
+
glMultiTexCoord2d(GL_TEXTURE1, 0.0, 1.0);
|
325
|
+
glVertex2d(x, y); // TL
|
326
|
+
|
327
|
+
glTexCoord2d(1.0, 1.0);
|
328
|
+
glMultiTexCoord2d(GL_TEXTURE1, 1.0, 1.0);
|
329
|
+
glVertex2d(x + texture->width, y); // TR
|
330
|
+
|
331
|
+
glTexCoord2d(1.0, 0.0);
|
332
|
+
glMultiTexCoord2d(GL_TEXTURE1, 1.0, 0.0);
|
333
|
+
glVertex2d(x + texture->width, y + texture->height); // BR
|
334
|
+
glEnd();
|
335
|
+
|
336
|
+
// Disable multitexturing.
|
337
|
+
if(!NIL_P(multitexture))
|
338
|
+
{
|
339
|
+
glBindTexture(GL_TEXTURE_2D, 0);
|
340
|
+
glActiveTexture(GL_TEXTURE0);
|
341
|
+
}
|
342
|
+
|
343
|
+
return Qnil;
|
344
|
+
}
|
345
|
+
|
346
|
+
// ----------------------------------------
|
347
|
+
VALUE Ashton_Texture_draw(int argc, VALUE argv[], VALUE self)
|
348
|
+
{
|
349
|
+
// TEXTURE(); // This isn't actually needed in this function.
|
350
|
+
|
351
|
+
VALUE x, y, z, options;
|
352
|
+
VALUE shader, blend_mode, color, multitexture, pixelated;
|
353
|
+
|
354
|
+
if(rb_scan_args(argc, argv, "31", &x, &y, &z, &options) == 4)
|
355
|
+
{
|
356
|
+
// Get :shader
|
357
|
+
shader = rb_hash_aref(options, SYMBOL("shader"));
|
358
|
+
if(!NIL_P(shader) && !rb_obj_is_kind_of(shader, rb_cShader))
|
359
|
+
{
|
360
|
+
rb_raise(rb_eTypeError, "Expected :shader option of type Ashton::Shader");
|
361
|
+
}
|
362
|
+
|
363
|
+
// Get draw :mode
|
364
|
+
blend_mode = rb_hash_aref(options, SYMBOL("mode"));
|
365
|
+
if(NIL_P(blend_mode))
|
366
|
+
{
|
367
|
+
blend_mode = SYMBOL(DRAW_MODE_ALPHA_BLEND);
|
368
|
+
}
|
369
|
+
else
|
370
|
+
{
|
371
|
+
Check_Type(blend_mode, T_SYMBOL);
|
372
|
+
|
373
|
+
ID blend_id = SYM2ID(blend_mode);
|
374
|
+
if(!(blend_id == rb_intern(DRAW_MODE_ALPHA_BLEND) ||
|
375
|
+
blend_id == rb_intern(DRAW_MODE_ADD) ||
|
376
|
+
blend_id == rb_intern(DRAW_MODE_MULTIPLY) ||
|
377
|
+
blend_id == rb_intern(DRAW_MODE_REPLACE)))
|
378
|
+
{
|
379
|
+
rb_raise(rb_eArgError, "Unsupported draw :mode, :%s", rb_id2name(blend_id));
|
380
|
+
}
|
381
|
+
}
|
382
|
+
|
383
|
+
// Get :color
|
384
|
+
color = rb_hash_aref(options, SYMBOL("color"));
|
385
|
+
if(NIL_P(color))
|
386
|
+
{
|
387
|
+
color = UINT2NUM(0xffffffff);
|
388
|
+
}
|
389
|
+
else if(!rb_obj_is_kind_of(color, rb_cColor))
|
390
|
+
{
|
391
|
+
rb_raise(rb_eTypeError, "Expecting :color to be a Gosu::Color");
|
392
|
+
}
|
393
|
+
|
394
|
+
// Get :multitexture
|
395
|
+
multitexture = rb_hash_aref(options, SYMBOL("multitexture"));
|
396
|
+
if(!NIL_P(multitexture) && !rb_obj_is_kind_of(multitexture, rb_cTexture))
|
397
|
+
{
|
398
|
+
rb_raise(rb_eTypeError, "Expected :multitexture option of type Ashton::Texture");
|
399
|
+
}
|
400
|
+
|
401
|
+
// Get :pixelated
|
402
|
+
pixelated = rb_hash_aref(options, SYMBOL("pixelated"));
|
403
|
+
if(NIL_P(pixelated))
|
404
|
+
{
|
405
|
+
pixelated = rb_funcall(rb_cTexture, rb_intern("pixelated?"), 0);
|
406
|
+
}
|
407
|
+
}
|
408
|
+
else
|
409
|
+
{
|
410
|
+
shader = multitexture = Qnil;
|
411
|
+
blend_mode = SYMBOL(DRAW_MODE_ALPHA_BLEND);
|
412
|
+
color = UINT2NUM(0xffffffff);
|
413
|
+
pixelated = rb_funcall(rb_cTexture, rb_intern("pixelated?"), 0);
|
414
|
+
}
|
415
|
+
|
416
|
+
// Enable the shader, if provided.
|
417
|
+
if(!NIL_P(shader)) rb_funcall(shader, rb_intern("enable"), 1, z);
|
418
|
+
|
419
|
+
// Create a GL block to do the actual drawing.
|
420
|
+
VALUE window = rb_gv_get("$window");
|
421
|
+
|
422
|
+
VALUE block_argv[1];
|
423
|
+
block_argv[0] = z;
|
424
|
+
|
425
|
+
VALUE parameters = rb_ary_new();
|
426
|
+
rb_ary_push(parameters, self);
|
427
|
+
rb_ary_push(parameters, x);
|
428
|
+
rb_ary_push(parameters, y);
|
429
|
+
rb_ary_push(parameters, blend_mode);
|
430
|
+
rb_ary_push(parameters, color);
|
431
|
+
rb_ary_push(parameters, shader);
|
432
|
+
rb_ary_push(parameters, multitexture);
|
433
|
+
rb_ary_push(parameters, pixelated);
|
434
|
+
|
435
|
+
rb_block_call(window, rb_intern("gl"), 1, block_argv,
|
436
|
+
RUBY_METHOD_FUNC(draw_block), parameters);
|
437
|
+
|
438
|
+
// Disable the shader, if provided.
|
439
|
+
if(!NIL_P(shader)) rb_funcall(shader, rb_intern("disable"), 1, z);
|
440
|
+
|
441
|
+
return Qnil;
|
442
|
+
}
|