rays 0.1.1

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.
Files changed (66) hide show
  1. data/ChangeLog +8 -0
  2. data/README +4 -0
  3. data/Rakefile +72 -0
  4. data/VERSION +1 -0
  5. data/ext/rays/bitmap.cpp +322 -0
  6. data/ext/rays/extconf.rb +61 -0
  7. data/ext/rays/font.cpp +125 -0
  8. data/ext/rays/image.cpp +166 -0
  9. data/ext/rays/native.cpp +24 -0
  10. data/ext/rays/painter.cpp +573 -0
  11. data/ext/rays/rays.cpp +61 -0
  12. data/ext/rays/rays.h +39 -0
  13. data/ext/rays/texture.cpp +130 -0
  14. data/include/rays.h +20 -0
  15. data/include/rays/bitmap.h +80 -0
  16. data/include/rays/colorspace.h +101 -0
  17. data/include/rays/defs.h +33 -0
  18. data/include/rays/font.h +49 -0
  19. data/include/rays/helpers.h +37 -0
  20. data/include/rays/image.h +68 -0
  21. data/include/rays/opengl.h +15 -0
  22. data/include/rays/painter.h +179 -0
  23. data/include/rays/rays.h +19 -0
  24. data/include/rays/ruby.h +15 -0
  25. data/include/rays/ruby/bitmap.h +39 -0
  26. data/include/rays/ruby/font.h +39 -0
  27. data/include/rays/ruby/image.h +39 -0
  28. data/include/rays/ruby/painter.h +39 -0
  29. data/include/rays/ruby/rays.h +21 -0
  30. data/include/rays/ruby/texture.h +39 -0
  31. data/include/rays/texture.h +56 -0
  32. data/include/rays/transform.h +35 -0
  33. data/lib/rays.rb +9 -0
  34. data/lib/rays/autoinit.rb +10 -0
  35. data/lib/rays/bitmap.rb +25 -0
  36. data/lib/rays/image.rb +15 -0
  37. data/lib/rays/module.rb +30 -0
  38. data/lib/rays/painter.rb +99 -0
  39. data/lib/rays/texture.rb +15 -0
  40. data/rays.gemspec +54 -0
  41. data/src/cocoa/bitmap.mm +286 -0
  42. data/src/cocoa/font.mm +193 -0
  43. data/src/cocoa/helpers.h +26 -0
  44. data/src/cocoa/helpers.mm +25 -0
  45. data/src/cocoa/rays.mm +40 -0
  46. data/src/colorspace.cpp +183 -0
  47. data/src/helpers.cpp +22 -0
  48. data/src/image.cpp +133 -0
  49. data/src/painter.cpp +769 -0
  50. data/src/texture.cpp +360 -0
  51. data/src/transform.cpp +88 -0
  52. data/src/win32/bitmap.cpp +212 -0
  53. data/src/win32/font.cpp +99 -0
  54. data/src/win32/gdi.cpp +771 -0
  55. data/src/win32/gdi.h +226 -0
  56. data/src/win32/rays.cpp +36 -0
  57. data/support.rb +58 -0
  58. data/task/ext.rake +41 -0
  59. data/task/gem.rake +33 -0
  60. data/task/git.rake +22 -0
  61. data/task/lib.rake +54 -0
  62. data/test/helpers.rb +15 -0
  63. data/test/test_painter.rb +11 -0
  64. data/test/test_rays.rb +19 -0
  65. data/test/test_texture.rb +11 -0
  66. metadata +153 -0
data/src/texture.cpp ADDED
@@ -0,0 +1,360 @@
1
+ #include "rays/texture.h"
2
+
3
+
4
+ #include <boost/scoped_array.hpp>
5
+ #include <rays/bitmap.h>
6
+
7
+
8
+ namespace Rays
9
+ {
10
+
11
+
12
+ struct Texture::Data
13
+ {
14
+
15
+ Bitmap bitmap;
16
+
17
+ int id, width, height;
18
+
19
+ Data ()
20
+ : id(-1), width(0), height(0)
21
+ {
22
+ }
23
+
24
+ ~Data ()
25
+ {
26
+ clear();
27
+ }
28
+
29
+ void clear ()
30
+ {
31
+ if (id >= 0)
32
+ {
33
+ GLenum id_ = id;
34
+ glDeleteTextures(1, &id_);
35
+ }
36
+
37
+ bitmap = Bitmap();
38
+ id = -1;
39
+ width = height = 0;
40
+ }
41
+
42
+ };// Texture::Data
43
+
44
+
45
+ static bool
46
+ get_component_type (GLenum* result, ColorSpace cs)
47
+ {
48
+ if (!result || !cs) return false;
49
+
50
+ if (cs.is_float())
51
+ *result = GL_FLOAT;
52
+ else
53
+ {
54
+ switch (cs.bpc())
55
+ {
56
+ case 8: *result = GL_UNSIGNED_BYTE; break;
57
+ case 16: *result = GL_UNSIGNED_SHORT; break;
58
+ case 32: *result = GL_UNSIGNED_INT; break;
59
+ default: return false;
60
+ }
61
+ }
62
+ return true;
63
+ }
64
+
65
+ static bool
66
+ create_texture (Texture::Data* self, GLenum format)
67
+ {
68
+ if (!self || !self->bitmap) return false;
69
+
70
+ GLenum type;
71
+ if (!get_component_type(&type, self->bitmap.color_space()))
72
+ return false;
73
+
74
+ GLuint id = 0;
75
+ glGenTextures(1, &id);
76
+ glBindTexture(GL_TEXTURE_2D, id);
77
+ if (glIsTexture(id) == GL_FALSE)
78
+ return false;
79
+
80
+ self->id = id;
81
+
82
+ glTexImage2D(
83
+ GL_TEXTURE_2D, 0, format, self->bitmap.width(), self->bitmap.height(), 0,
84
+ format, type, self->bitmap.data());
85
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);//GL_LINEAR);
86
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);//GL_LINEAR);
87
+
88
+ return true;
89
+ }
90
+
91
+ static int
92
+ min_pow2 (int num)
93
+ {
94
+ int n = 1;
95
+ while (n < num) n *= 2;
96
+ return n;
97
+ }
98
+
99
+ static bool
100
+ colorspace_for_alphabitmap (ColorSpace* result, ColorSpace cs)
101
+ {
102
+ if (!result || !cs) return false;
103
+
104
+ *result = COLORSPACE_UNKNOWN;
105
+
106
+ if (cs.is_float())
107
+ *result = GRAY_float;
108
+ else
109
+ {
110
+ switch (cs.bpc())
111
+ {
112
+ case 8: *result = GRAY_8; break;
113
+ case 16: *result = GRAY_16; break;
114
+ case 24: *result = GRAY_24; break;
115
+ case 32: *result = GRAY_32; break;
116
+ default: return false;
117
+ }
118
+ }
119
+
120
+ return true;
121
+ }
122
+
123
+ template <int BytesPerPixel>
124
+ static inline void
125
+ copy_pixel (uchar* dest, const uchar* src)
126
+ {
127
+ *dest = *src;
128
+ copy_pixel<BytesPerPixel - 1>(dest + 1, src + 1);
129
+ }
130
+
131
+ template <>
132
+ inline void
133
+ copy_pixel<1> (uchar* dest, const uchar* src)
134
+ {
135
+ *dest = *src;
136
+ }
137
+
138
+ template <>
139
+ inline void
140
+ copy_pixel<2> (uchar* dest, const uchar* src)
141
+ {
142
+ assert(sizeof(ushort) == 2);
143
+ *(ushort*) dest = *(ushort*) src;
144
+ }
145
+
146
+ template <>
147
+ inline void
148
+ copy_pixel<4> (uchar* dest, const uchar* src)
149
+ {
150
+ assert(sizeof(ulong) == 4);
151
+ *(ulong*) dest = *(ulong*) src;
152
+ }
153
+
154
+ template <int BytesPerPixel>
155
+ static inline void
156
+ copy_pixels (
157
+ size_t width,
158
+ uchar* dest, size_t dest_offset, const uchar* src, size_t src_offset)
159
+ {
160
+ if (!dest || !src || dest_offset <= 0 || src_offset <= 0)
161
+ return;
162
+
163
+ while (width--)
164
+ {
165
+ copy_pixel<BytesPerPixel>(dest, src);
166
+ dest += dest_offset;
167
+ src += src_offset;
168
+ }
169
+ }
170
+
171
+ static inline void
172
+ copy_pixels (
173
+ size_t Bpp, size_t width,
174
+ uchar* dest, size_t dest_offset, const uchar* src, size_t src_offset)
175
+ {
176
+ switch (Bpp)
177
+ {
178
+ case 1: copy_pixels<1>(width, dest, dest_offset, src, src_offset); break;
179
+ case 2: copy_pixels<2>(width, dest, dest_offset, src, src_offset); break;
180
+ case 3: copy_pixels<3>(width, dest, dest_offset, src, src_offset); break;
181
+ case 4: copy_pixels<4>(width, dest, dest_offset, src, src_offset); break;
182
+ }
183
+ }
184
+
185
+ static bool
186
+ copy_bitmap (Bitmap* dest, const Bitmap& src, int src_offset = 0)
187
+ {
188
+ if (!dest || !src || src_offset < 0)
189
+ return false;
190
+
191
+ int src_Bpp = src.color_space().Bpp();
192
+ int src_Bpc = src.color_space().Bpc();
193
+ int dest_Bpp = dest->color_space().Bpp();
194
+
195
+ if (src_offset >= (src_Bpp / src_Bpc))
196
+ return false;
197
+
198
+ for (int y = 0; y < dest->height(); ++y)
199
+ {
200
+ const uchar* s = src. at<uchar>(0, y) + src_offset * src_Bpc;
201
+ uchar* d = dest->at<uchar>(0, y);
202
+ copy_pixels(src_Bpp, dest->width(), d, dest_Bpp, s, src_Bpp);
203
+ }
204
+
205
+ return true;
206
+ }
207
+
208
+ static bool
209
+ create_alpha_texture (Texture::Data* self)
210
+ {
211
+ if (!self || !self->bitmap) return false;
212
+
213
+ ColorSpace cs = self->bitmap.color_space();
214
+ int width_pow2 = min_pow2(self->width);
215
+ int height_pow2 = min_pow2(self->height);
216
+
217
+ if (
218
+ width_pow2 != self->width ||
219
+ height_pow2 != self->height ||
220
+ cs.is_rgb() ||
221
+ cs.is_bgr())
222
+ {
223
+ ColorSpace newcs;
224
+ if (!colorspace_for_alphabitmap(&newcs, cs))
225
+ return false;
226
+
227
+ Bitmap bmp(width_pow2, height_pow2, newcs);
228
+ if (!bmp) return false;
229
+
230
+ if (!copy_bitmap(&bmp, self->bitmap, cs.alpha_pos()))
231
+ return false;
232
+
233
+ self->bitmap = bmp;
234
+ cs = self->bitmap.color_space();
235
+ }
236
+
237
+ if (!self->bitmap.color_space().is_gray())
238
+ return false;
239
+
240
+ return create_texture(self, GL_ALPHA);
241
+ }
242
+
243
+ static bool
244
+ create_color_texture (Texture::Data* self)
245
+ {
246
+ if (!self || !self->bitmap) return false;
247
+
248
+ int width_pow2 = min_pow2(self->width);
249
+ int height_pow2 = min_pow2(self->height);
250
+
251
+ if (
252
+ width_pow2 != self->width ||
253
+ height_pow2 != self->height)
254
+ {
255
+ Bitmap bmp(
256
+ width_pow2, height_pow2, self->bitmap.color_space());
257
+ if (!bmp) return false;
258
+
259
+ if (!copy_bitmap(&bmp, self->bitmap))
260
+ return false;
261
+
262
+ self->bitmap = bmp;
263
+ }
264
+
265
+ ColorSpace cs = self->bitmap.color_space();
266
+
267
+ bool alpha = cs.has_alpha();
268
+ if (cs.is_rgb())
269
+ return create_texture(self, alpha ? GL_RGBA : GL_RGB);
270
+ else if (cs.is_bgr())
271
+ return create_texture(self, alpha ? GL_BGRA : GL_BGR);
272
+ else if (cs.is_gray())
273
+ return create_texture(self, GL_LUMINANCE);
274
+ else
275
+ return false;
276
+ }
277
+
278
+ static bool
279
+ setup_texture (
280
+ Texture::Data* self, const Bitmap& bitmap, bool alphaonly = false)
281
+ {
282
+ if (!self || !bitmap) return false;
283
+
284
+ self->clear();
285
+
286
+ self->bitmap = bitmap;
287
+ if (!self->bitmap) return false;
288
+
289
+ self->width = self->bitmap.width();
290
+ self->height = self->bitmap.height();
291
+
292
+ if (alphaonly)
293
+ return create_alpha_texture(self);
294
+ else
295
+ return create_color_texture(self);
296
+ }
297
+
298
+
299
+ Texture::Texture ()
300
+ {
301
+ }
302
+
303
+ Texture::Texture (const Bitmap& bitmap, bool alphaonly)
304
+ {
305
+ setup_texture(self.get(), bitmap, alphaonly);
306
+ }
307
+
308
+ Texture::~Texture ()
309
+ {
310
+ }
311
+
312
+ GLuint
313
+ Texture::id () const
314
+ {
315
+ return self->id;
316
+ }
317
+
318
+ int
319
+ Texture::width () const
320
+ {
321
+ return self->width;
322
+ }
323
+
324
+ int
325
+ Texture::height () const
326
+ {
327
+ return self->height;
328
+ }
329
+
330
+ float
331
+ Texture::s_max () const
332
+ {
333
+ return (float) self->width / (float) self->bitmap.width();
334
+ }
335
+
336
+ float
337
+ Texture::t_max () const
338
+ {
339
+ return (float) self->height / (float) self->bitmap.height();
340
+ }
341
+
342
+ const Bitmap&
343
+ Texture::bitmap () const
344
+ {
345
+ return self->bitmap;
346
+ }
347
+
348
+ Texture::operator bool () const
349
+ {
350
+ return self->id >= 0 && self->width > 0 && self->height > 0;
351
+ }
352
+
353
+ bool
354
+ Texture::operator ! () const
355
+ {
356
+ return !operator bool();
357
+ }
358
+
359
+
360
+ }// Rays
data/src/transform.cpp ADDED
@@ -0,0 +1,88 @@
1
+ #include "rays/painter.h"
2
+
3
+
4
+ #include "rays/opengl.h"
5
+
6
+
7
+ namespace Rays
8
+ {
9
+
10
+
11
+ static bool
12
+ is_error ()
13
+ {
14
+ GLenum e = glGetError();
15
+ return e == GL_INVALID_OPERATION;
16
+ }
17
+
18
+ static bool
19
+ is_error (GLenum error)
20
+ {
21
+ GLenum e = glGetError();
22
+ return e == GL_INVALID_OPERATION || e == error;
23
+ }
24
+
25
+
26
+ bool
27
+ translate (coord x, coord y, coord z)
28
+ {
29
+ glTranslatef(x, y, z);
30
+ return !is_error();
31
+ }
32
+
33
+ bool
34
+ scale (coord x, coord y, coord z)
35
+ {
36
+ glScalef(x, y, z);
37
+ return !is_error();
38
+ }
39
+
40
+ bool
41
+ rotate (float angle, coord x, coord y, coord z)
42
+ {
43
+ glRotatef(angle, x, y, z);
44
+ return !is_error();
45
+ }
46
+
47
+
48
+ bool
49
+ set_matrix (coord value)
50
+ {
51
+ glLoadIdentity();
52
+ if (is_error()) return false;
53
+ if (value == 1) return true;
54
+ return scale(value, value, value);
55
+ }
56
+
57
+ bool
58
+ set_matrix (const coord* elements, size_t size)
59
+ {
60
+ if (!elements || size != 16) return false;
61
+ glLoadMatrixf(elements);
62
+ return !is_error();
63
+ }
64
+
65
+ bool
66
+ get_matrix (coord* elements, size_t size)
67
+ {
68
+ if (!elements || size != 16) return false;
69
+ glGetFloatv(GL_MODELVIEW_MATRIX, elements);
70
+ return !is_error(GL_INVALID_ENUM);
71
+ }
72
+
73
+ bool
74
+ push_matrix ()
75
+ {
76
+ glPushMatrix();
77
+ return !is_error(GL_STACK_OVERFLOW);
78
+ }
79
+
80
+ bool
81
+ pop_matrix ()
82
+ {
83
+ glPopMatrix();
84
+ return !is_error(GL_STACK_UNDERFLOW);
85
+ }
86
+
87
+
88
+ }// Rays
@@ -0,0 +1,212 @@
1
+ #include "rays/bitmap.h"
2
+
3
+
4
+ #include "gdi.h"
5
+
6
+
7
+ namespace Rays
8
+ {
9
+
10
+
11
+ struct Bitmap::Data
12
+ {
13
+
14
+ int width, height, pitch;
15
+
16
+ ColorSpace colorspace;
17
+
18
+ void* pixels;
19
+
20
+ Win32::MemoryDC memdc;
21
+
22
+ bool dirty;
23
+
24
+ Data ()
25
+ : pixels(NULL), dirty(true)
26
+ {
27
+ }
28
+
29
+ };// Window::Data
30
+
31
+
32
+ static bool
33
+ init_bitmap_pixels (Bitmap* bmp)
34
+ {
35
+ if (!*bmp) return false;
36
+
37
+ memset(bmp->data(), 0, bmp->size());
38
+
39
+ if (!bmp->color_space().has_alpha())
40
+ return true;
41
+
42
+ int Bpp = bmp->color_space().Bpp();
43
+ for (int y = 0; y < bmp->height(); ++y)
44
+ {
45
+ unsigned char* p =
46
+ bmp->at<unsigned char>(0, y) + bmp->color_space().alpha_pos();
47
+ int w = bmp->width();
48
+ while (w--)
49
+ {
50
+ *p = 255;
51
+ p += Bpp;
52
+ }
53
+ }
54
+
55
+ return true;
56
+ }
57
+
58
+ static bool
59
+ setup (Bitmap* bmp, int w, int h, const ColorSpace& cs, HDC hdc = NULL)
60
+ {
61
+ if (w <= 0 || h <= 0 || !cs || !bmp || *bmp)
62
+ return false;
63
+
64
+ Bitmap::Data* self = bmp->self.get();
65
+
66
+ self->width = w;
67
+ self->height = h;
68
+ self->colorspace = cs;
69
+ self->pitch = self->width * self->colorspace.Bpp();
70
+
71
+ int padding = 4 - self->pitch % 4;
72
+ if (padding < 4) self->pitch += padding;
73
+
74
+ BITMAPINFO bmpinfo;
75
+ memset(&bmpinfo, 0, sizeof(bmpinfo));
76
+
77
+ BITMAPINFOHEADER& header = bmpinfo.bmiHeader;
78
+ header.biSize = sizeof(BITMAPINFOHEADER);
79
+ header.biWidth = self->width;
80
+ header.biHeight = self->height;
81
+ header.biPlanes = 1;
82
+ header.biBitCount = self->colorspace.bpp();
83
+ header.biCompression = BI_RGB;
84
+
85
+ Win32::DC dc = hdc ? Win32::DC(hdc) : Win32::screen_dc();
86
+
87
+ HBITMAP hbmp = CreateDIBSection(
88
+ dc.handle(), &bmpinfo, DIB_RGB_COLORS, (void**) &self->pixels, NULL, 0);
89
+ if (!hbmp) return false;
90
+
91
+ self->memdc = Win32::MemoryDC(dc.handle(), Win32::Bitmap(hbmp, true));
92
+ if (!self->memdc) return false;
93
+
94
+ return init_bitmap_pixels(bmp);
95
+ }
96
+
97
+
98
+ Bitmap::Bitmap ()
99
+ {
100
+ }
101
+
102
+ Bitmap::Bitmap (int width, int height, const ColorSpace& cs)
103
+ {
104
+ setup(this, width, height, cs);
105
+ }
106
+
107
+ Bitmap::~Bitmap ()
108
+ {
109
+ }
110
+
111
+ int
112
+ Bitmap::width () const
113
+ {
114
+ return self->width;
115
+ }
116
+
117
+ int
118
+ Bitmap::height () const
119
+ {
120
+ return self->height;
121
+ }
122
+
123
+ const ColorSpace&
124
+ Bitmap::color_space () const
125
+ {
126
+ return self->colorspace;
127
+ }
128
+
129
+ int
130
+ Bitmap::pitch () const
131
+ {
132
+ return self->pitch;
133
+ }
134
+
135
+ size_t
136
+ Bitmap::size () const
137
+ {
138
+ return pitch() * height();
139
+ }
140
+
141
+ bool
142
+ Bitmap::dirty () const
143
+ {
144
+ return self->dirty;
145
+ }
146
+
147
+ void
148
+ Bitmap::set_dirty (bool b)
149
+ {
150
+ self->dirty = b;
151
+ }
152
+
153
+ void*
154
+ Bitmap::data ()
155
+ {
156
+ return self->pixels;
157
+ }
158
+
159
+ const void*
160
+ Bitmap::data () const
161
+ {
162
+ return const_cast<Bitmap*>(this)->data();
163
+ }
164
+
165
+ Bitmap::operator bool () const
166
+ {
167
+ return
168
+ self &&
169
+ self->width > 0 && self->height > 0 && self->pitch > 0 &&
170
+ self->colorspace && self->pixels && self->memdc;
171
+ }
172
+
173
+ bool
174
+ Bitmap::operator ! () const
175
+ {
176
+ return !operator bool();
177
+ }
178
+
179
+
180
+ bool
181
+ load_bitmap (Bitmap* bitmap, const char* path)
182
+ {
183
+ return false;
184
+ }
185
+
186
+ bool
187
+ save_bitmap (const Bitmap& bitmap, const char* path)
188
+ {
189
+ return false;
190
+ }
191
+
192
+
193
+ bool draw_string (
194
+ HDC, coord, const char*, coord, coord, const Font&);
195
+
196
+ bool
197
+ draw_string (
198
+ Bitmap* bmp, const char* str, coord x, coord y, const Font& font)
199
+ {
200
+ if (!bmp || !*bmp || !str || !font) return false;
201
+
202
+ if (*str == '\0') return true;
203
+
204
+ if (!draw_string(bmp->self->memdc.handle(), bmp->height(), str, x, y, font))
205
+ return false;
206
+
207
+ bmp->set_dirty();
208
+ return true;
209
+ }
210
+
211
+
212
+ }// Rays