rays 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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