rays 0.1.6 → 0.1.7

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 (113) hide show
  1. checksums.yaml +7 -0
  2. data/.doc/ext/rays/bitmap.cpp +70 -233
  3. data/.doc/ext/rays/bounds.cpp +339 -57
  4. data/.doc/ext/rays/color.cpp +58 -48
  5. data/.doc/ext/rays/color_space.cpp +174 -0
  6. data/.doc/ext/rays/font.cpp +31 -53
  7. data/.doc/ext/rays/image.cpp +64 -67
  8. data/.doc/ext/rays/matrix.cpp +22 -50
  9. data/.doc/ext/rays/native.cpp +9 -2
  10. data/.doc/ext/rays/painter.cpp +276 -259
  11. data/.doc/ext/rays/point.cpp +186 -52
  12. data/.doc/ext/rays/rays.cpp +25 -20
  13. data/.doc/ext/rays/shader.cpp +61 -0
  14. data/.doc/ext/rays/texture.cpp +47 -59
  15. data/{README → README.md} +0 -0
  16. data/Rakefile +6 -5
  17. data/VERSION +1 -1
  18. data/ext/rays/bitmap.cpp +88 -248
  19. data/ext/rays/bounds.cpp +437 -141
  20. data/ext/rays/color.cpp +79 -69
  21. data/ext/rays/color_space.cpp +185 -0
  22. data/ext/rays/extconf.rb +14 -63
  23. data/ext/rays/font.cpp +44 -65
  24. data/ext/rays/image.cpp +82 -81
  25. data/ext/rays/matrix.cpp +32 -60
  26. data/ext/rays/native.cpp +9 -2
  27. data/ext/rays/painter.cpp +345 -321
  28. data/ext/rays/point.cpp +212 -69
  29. data/ext/rays/rays.cpp +29 -23
  30. data/ext/rays/shader.cpp +63 -0
  31. data/ext/rays/texture.cpp +64 -74
  32. data/include/rays/bitmap.h +21 -12
  33. data/include/rays/bounds.h +67 -9
  34. data/include/rays/color.h +23 -7
  35. data/include/rays/{colorspace.h → color_space.h} +6 -3
  36. data/include/rays/exception.h +17 -11
  37. data/include/rays/font.h +4 -3
  38. data/include/rays/image.h +11 -6
  39. data/include/rays/matrix.h +15 -12
  40. data/include/rays/opengl.h +54 -1
  41. data/include/rays/painter.h +98 -108
  42. data/include/rays/point.h +45 -5
  43. data/include/rays/rays.h +2 -2
  44. data/include/rays/ruby/bitmap.h +2 -16
  45. data/include/rays/ruby/bounds.h +4 -16
  46. data/include/rays/ruby/color.h +3 -16
  47. data/include/rays/ruby/color_space.h +27 -0
  48. data/include/rays/ruby/font.h +2 -16
  49. data/include/rays/ruby/image.h +2 -16
  50. data/include/rays/ruby/matrix.h +2 -16
  51. data/include/rays/ruby/painter.h +2 -16
  52. data/include/rays/ruby/point.h +3 -16
  53. data/include/rays/ruby/shader.h +27 -0
  54. data/include/rays/ruby/texture.h +2 -16
  55. data/include/rays/ruby.h +1 -0
  56. data/include/rays/shader.h +48 -0
  57. data/include/rays/texture.h +13 -2
  58. data/include/rays.h +2 -1
  59. data/lib/rays/bitmap.rb +20 -11
  60. data/lib/rays/bounds.rb +29 -68
  61. data/lib/rays/color.rb +39 -0
  62. data/lib/rays/color_space.rb +33 -0
  63. data/lib/rays/font.rb +29 -0
  64. data/lib/rays/image.rb +22 -0
  65. data/lib/rays/module.rb +11 -7
  66. data/lib/rays/painter.rb +103 -40
  67. data/lib/rays/point.rb +19 -36
  68. data/lib/rays/shader.rb +13 -0
  69. data/lib/rays/texture.rb +9 -0
  70. data/lib/rays.rb +4 -0
  71. data/rays.gemspec +3 -4
  72. data/src/bounds.cpp +272 -63
  73. data/src/color.cpp +168 -21
  74. data/src/{colorspace.cpp → color_space.cpp} +38 -1
  75. data/src/exception.cpp +24 -15
  76. data/src/frame_buffer.cpp +275 -0
  77. data/src/frame_buffer.h +79 -0
  78. data/src/image.cpp +80 -36
  79. data/src/ios/bitmap.mm +340 -0
  80. data/src/ios/font.mm +206 -0
  81. data/src/{cocoa → ios}/helper.h +2 -2
  82. data/src/{cocoa → ios}/helper.mm +0 -0
  83. data/src/ios/opengl.mm +21 -0
  84. data/src/ios/program.cpp +122 -0
  85. data/src/{cocoa → ios}/rays.mm +8 -7
  86. data/src/matrix.cpp +10 -22
  87. data/src/opengl.cpp +64 -0
  88. data/src/{cocoa → osx}/bitmap.mm +121 -70
  89. data/src/{cocoa → osx}/font.mm +32 -24
  90. data/src/osx/helper.h +26 -0
  91. data/src/osx/helper.mm +25 -0
  92. data/src/osx/opengl.mm +103 -0
  93. data/src/osx/rays.mm +43 -0
  94. data/src/painter.cpp +596 -422
  95. data/src/point.cpp +154 -11
  96. data/src/program.cpp +513 -0
  97. data/src/program.h +73 -0
  98. data/src/render_buffer.cpp +120 -0
  99. data/src/render_buffer.h +47 -0
  100. data/src/shader.cpp +117 -0
  101. data/src/texture.cpp +104 -134
  102. data/test/helper.rb +10 -3
  103. data/test/test_bitmap.rb +18 -0
  104. data/test/test_bounds.rb +81 -35
  105. data/test/test_color.rb +29 -2
  106. data/test/test_image.rb +63 -0
  107. data/test/test_painter.rb +120 -0
  108. data/test/test_point.rb +30 -9
  109. data/test/test_shader.rb +37 -0
  110. data/test/test_texture.rb +18 -0
  111. metadata +75 -58
  112. data/.gitignore +0 -14
  113. data/ChangeLog +0 -8
@@ -1,7 +1,9 @@
1
- #include "rays/colorspace.h"
1
+ #include "rays/color_space.h"
2
2
 
3
3
 
4
+ #include <assert.h>
4
5
  #include <xot/util.h>
6
+ #include "rays/exception.h"
5
7
 
6
8
 
7
9
  namespace Rays
@@ -168,6 +170,41 @@ namespace Rays
168
170
  return premult;
169
171
  }
170
172
 
173
+ void
174
+ ColorSpace::get_gl_enums (GLenum* format, GLenum* type, bool alpha_only) const
175
+ {
176
+ if (!format && !type)
177
+ argument_error(__FILE__, __LINE__);
178
+
179
+ if (!*this)
180
+ invalid_state_error(__FILE__, __LINE__);
181
+
182
+ if (format)
183
+ {
184
+ if (is_rgb()) *format = has_alpha() ? GL_RGBA : GL_RGB;
185
+ #ifndef IOS
186
+ else if (is_bgr()) *format = has_alpha() ? GL_BGRA : GL_BGR;
187
+ #endif
188
+ else if (is_gray()) *format = alpha_only ? GL_ALPHA : GL_LUMINANCE;
189
+ else rays_error(__FILE__, __LINE__, "invalid color space.");
190
+ }
191
+
192
+ if (type)
193
+ {
194
+ if (is_float())
195
+ *type = GL_FLOAT;
196
+ else switch (bpc())
197
+ {
198
+ case 8: *type = GL_UNSIGNED_BYTE; break;
199
+ case 16: *type = GL_UNSIGNED_SHORT; break;
200
+ #ifndef IOS
201
+ case 32: *type = GL_UNSIGNED_INT; break;
202
+ #endif
203
+ default: rays_error(__FILE__, __LINE__, "invalid bpc.");
204
+ }
205
+ }
206
+ }
207
+
171
208
  ColorSpace::operator bool () const
172
209
  {
173
210
  return FIRST <= (int) type_ && (int) type_ <= LAST;
data/src/exception.cpp CHANGED
@@ -1,34 +1,43 @@
1
1
  #include "rays/exception.h"
2
2
 
3
3
 
4
+ #include "xot/string.h"
5
+
6
+
4
7
  namespace Rays
5
8
  {
6
9
 
7
10
 
8
- RaysException::RaysException (const char* format, ...)
9
- : Super("")
11
+ RaysError::RaysError (const char* str)
12
+ : Super(str)
10
13
  {
11
- XOT_STRINGF(format, s);
12
- text = s;
13
14
  }
14
15
 
15
- RaysException::~RaysException () throw()
16
- {
17
- }
18
16
 
19
- const char*
20
- RaysException::what () const throw()
17
+ OpenGLError::OpenGLError (const char* str)
18
+ : Super(str)
21
19
  {
22
- return text.c_str();
23
20
  }
24
21
 
25
22
 
26
- void
27
- rays_error (const char* format, ...)
23
+ namespace ErrorFunctions
28
24
  {
29
- XOT_STRINGF(format, s);
30
- throw RaysException(s.c_str());
31
- }
25
+
26
+ void
27
+ rays_error (const char* file, int line, const char* format, ...)
28
+ {
29
+ XOT_STRINGF(format, s);
30
+ throw RaysError(Xot::error_text(file, line, s));
31
+ }
32
+
33
+ void
34
+ opengl_error (const char* file, int line, const char* format, ...)
35
+ {
36
+ XOT_STRINGF(format, s);
37
+ throw OpenGLError(Xot::error_text(file, line, s));
38
+ }
39
+
40
+ }// ErrorFunctions
32
41
 
33
42
 
34
43
  }// Rays
@@ -0,0 +1,275 @@
1
+ #include "frame_buffer.h"
2
+
3
+
4
+ #include <vector>
5
+ #include "rays/exception.h"
6
+ #include "rays/texture.h"
7
+ #include "rays/opengl.h"
8
+ #include "render_buffer.h"
9
+
10
+
11
+ namespace Rays
12
+ {
13
+
14
+
15
+ struct FrameBuffer::Data
16
+ {
17
+
18
+ int id;
19
+
20
+ Texture texture;
21
+
22
+ RenderBuffer render_buffer;
23
+
24
+ Data ()
25
+ : id(-1)
26
+ {
27
+ }
28
+
29
+ ~Data ()
30
+ {
31
+ clear();
32
+ }
33
+
34
+ void create ()
35
+ {
36
+ if (is_valid()) return;
37
+
38
+ GLuint id_ = 0;
39
+ glGenFramebuffers(1, &id_);
40
+ check_error(__FILE__, __LINE__);
41
+
42
+ id = id_;
43
+ }
44
+
45
+ void clear ()
46
+ {
47
+ texture = Texture();
48
+ render_buffer = RenderBuffer();
49
+
50
+ if (id >= 0)
51
+ {
52
+ GLenum id_ = id;
53
+ glDeleteFramebuffers(1, &id_);
54
+ check_error(__FILE__, __LINE__);
55
+ }
56
+
57
+ id = -1;
58
+ }
59
+
60
+ bool is_valid () const
61
+ {
62
+ return id >= 0;
63
+ }
64
+
65
+ };// FrameBuffer::Data
66
+
67
+
68
+ FrameBuffer::FrameBuffer ()
69
+ {
70
+ }
71
+
72
+ FrameBuffer::FrameBuffer (const Texture& texture)
73
+ {
74
+ attach(texture);
75
+ }
76
+
77
+ FrameBuffer::~FrameBuffer ()
78
+ {
79
+ }
80
+
81
+ static String
82
+ get_error_status_name (GLenum status)
83
+ {
84
+ switch (status)
85
+ {
86
+ #ifdef IOS
87
+ case GL_FRAMEBUFFER_UNSUPPORTED_OES: return "GL_FRAMEBUFFER_UNSUPPORTED_OES";
88
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES: return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES";
89
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES: return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES";
90
+ case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES: return "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES";
91
+ case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES: return "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES";
92
+ #else
93
+ case GL_FRAMEBUFFER_UNDEFINED: return "GL_FRAMEBUFFER_UNDEFINED";
94
+ case GL_FRAMEBUFFER_UNSUPPORTED: return "GL_FRAMEBUFFER_UNSUPPORTED";
95
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
96
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
97
+ case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: return "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER";
98
+ case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: return "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER";
99
+ case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: return "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE";
100
+ //case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: return "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS";
101
+ #endif
102
+ }
103
+ return "UNKNOWN STATUS";
104
+ }
105
+
106
+ void
107
+ FrameBuffer::attach (const Texture& texture)
108
+ {
109
+ if (!texture)
110
+ argument_error(__FILE__, __LINE__, "FrameBuffer::attach(): invalid texture.");
111
+
112
+ self->create();
113
+
114
+ FrameBufferBinder binder(id());
115
+
116
+ glFramebufferTexture2D(
117
+ GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
118
+ GL_TEXTURE_2D, texture.id(), 0);
119
+ check_error(__FILE__, __LINE__);
120
+
121
+ self->texture = texture;
122
+
123
+ #if 0
124
+ int w = texture.width(), h = texture.height();
125
+ if (
126
+ w != self->render_buffer.width() ||
127
+ h != self->render_buffer.height())
128
+ {
129
+ RenderBuffer rb = RenderBuffer(w, h);
130
+
131
+ glFramebufferRenderbuffer(
132
+ GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
133
+ GL_RENDERBUFFER, rb.id());
134
+ check_error(__FILE__, __LINE__);
135
+
136
+ self->render_buffer = rb;
137
+ }
138
+ #endif
139
+
140
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
141
+ if (status != GL_FRAMEBUFFER_COMPLETE)
142
+ {
143
+ opengl_error(__FILE__, __LINE__,
144
+ "frame buffer status is %s", get_error_status_name(status).c_str());
145
+ }
146
+ }
147
+
148
+ GLuint
149
+ FrameBuffer::id () const
150
+ {
151
+ return self->id;
152
+ }
153
+
154
+ int
155
+ FrameBuffer::width () const
156
+ {
157
+ return self->texture.width();
158
+ }
159
+
160
+ int
161
+ FrameBuffer::height () const
162
+ {
163
+ return self->texture.height();
164
+ }
165
+
166
+ Texture&
167
+ FrameBuffer::texture ()
168
+ {
169
+ return self->texture;
170
+ }
171
+
172
+ const Texture&
173
+ FrameBuffer::texture () const
174
+ {
175
+ return const_cast<FrameBuffer*>(this)->texture();
176
+ }
177
+
178
+ FrameBuffer::operator bool () const
179
+ {
180
+ if (!self || !self->is_valid())
181
+ return false;
182
+
183
+ const Texture& t = self->texture;
184
+ if (!t)
185
+ return false;
186
+
187
+ const RenderBuffer& r = self->render_buffer;
188
+ if (r && (t.width() != r.width() || t.height() != r.height()))
189
+ return false;
190
+
191
+ return true;
192
+ }
193
+
194
+ bool
195
+ FrameBuffer::operator ! () const
196
+ {
197
+ return !operator bool();
198
+ }
199
+
200
+
201
+ FrameBufferBinder::FrameBufferBinder (GLuint id)
202
+ : id(id)
203
+ {
204
+ bind_frame_buffer(id);
205
+ }
206
+
207
+ FrameBufferBinder::~FrameBufferBinder ()
208
+ {
209
+ unbind_frame_buffer();
210
+ }
211
+
212
+ GLuint
213
+ FrameBufferBinder::current () const
214
+ {
215
+ return id;
216
+ }
217
+
218
+
219
+ struct FrameBufferID
220
+ {
221
+
222
+ GLuint draw, read;
223
+
224
+ FrameBufferID ()
225
+ : draw(0), read(0)
226
+ {
227
+ }
228
+
229
+ FrameBufferID (GLuint draw, GLuint read)
230
+ : draw(draw), read(read)
231
+ {
232
+ }
233
+
234
+ };// FrameBufferID
235
+
236
+ static std::vector<FrameBufferID> frame_buffer_bind_stack;
237
+
238
+
239
+ static void
240
+ bind_frame_buffer (GLuint draw, GLuint read)
241
+ {
242
+ FrameBufferID id;
243
+ glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*) &id.draw);
244
+ glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, (GLint*) &id.read);
245
+ check_error(__FILE__, __LINE__);
246
+
247
+ frame_buffer_bind_stack.push_back(id);
248
+
249
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, draw);
250
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, read);
251
+ check_error(__FILE__, __LINE__);
252
+ }
253
+
254
+ void
255
+ bind_frame_buffer (GLuint id)
256
+ {
257
+ bind_frame_buffer(id, id);
258
+ }
259
+
260
+ void
261
+ unbind_frame_buffer ()
262
+ {
263
+ if (frame_buffer_bind_stack.empty())
264
+ rays_error(__FILE__, __LINE__, "frame_buffer_bind_stack is empty.");
265
+
266
+ FrameBufferID id = frame_buffer_bind_stack.back();
267
+ frame_buffer_bind_stack.pop_back();
268
+
269
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, id.draw);
270
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, id.read);
271
+ check_error(__FILE__, __LINE__);
272
+ }
273
+
274
+
275
+ }// Rays
@@ -0,0 +1,79 @@
1
+ // -*- c++ -*-
2
+ #pragma once
3
+ #ifndef __RAYS_FRAME_BUFFER_H__
4
+ #define __RAYS_FRAME_BUFFER_H__
5
+
6
+
7
+ #include <xot/pimpl.h>
8
+ #include <rays/defs.h>
9
+ #include <rays/opengl.h>
10
+
11
+
12
+ namespace Rays
13
+ {
14
+
15
+
16
+ class Texture;
17
+
18
+
19
+ class FrameBuffer
20
+ {
21
+
22
+ public:
23
+
24
+ FrameBuffer ();
25
+
26
+ FrameBuffer (const Texture& texture);
27
+
28
+ ~FrameBuffer ();
29
+
30
+ void attach (const Texture& texture);
31
+
32
+ GLuint id () const;
33
+
34
+ int width () const;
35
+
36
+ int height () const;
37
+
38
+ Texture& texture ();
39
+
40
+ const Texture& texture () const;
41
+
42
+ operator bool () const;
43
+
44
+ bool operator ! () const;
45
+
46
+ struct Data;
47
+
48
+ Xot::PImpl<Data, true> self;
49
+
50
+ };// FrameBuffer
51
+
52
+
53
+ class FrameBufferBinder
54
+ {
55
+
56
+ public:
57
+
58
+ FrameBufferBinder (GLuint id);
59
+
60
+ ~FrameBufferBinder ();
61
+
62
+ GLuint current () const;
63
+
64
+ private:
65
+
66
+ GLuint id;
67
+
68
+ };// FrameBufferBinder
69
+
70
+
71
+ void bind_frame_buffer (GLuint id);
72
+
73
+ void unbind_frame_buffer ();
74
+
75
+
76
+ }// Rays
77
+
78
+
79
+ #endif//EOH
data/src/image.cpp CHANGED
@@ -1,8 +1,9 @@
1
1
  #include "rays/image.h"
2
2
 
3
3
 
4
- #include <rays/bitmap.h>
5
- #include <rays/texture.h>
4
+ #include "rays/exception.h"
5
+ #include "rays/bitmap.h"
6
+ #include "rays/texture.h"
6
7
 
7
8
 
8
9
  namespace Rays
@@ -12,14 +13,18 @@ namespace Rays
12
13
  struct Image::Data
13
14
  {
14
15
 
15
- Bitmap bitmap;
16
+ int width, height;
16
17
 
17
- bool alphatex;
18
+ ColorSpace color_space;
19
+
20
+ bool alpha_only;
21
+
22
+ mutable Bitmap bitmap;
18
23
 
19
24
  mutable Texture texture;
20
25
 
21
26
  Data ()
22
- : alphatex(false)
27
+ : width(0), height(0), alpha_only(false)
23
28
  {
24
29
  }
25
30
 
@@ -30,51 +35,81 @@ namespace Rays
30
35
  {
31
36
  }
32
37
 
33
- Image::Image (
34
- int width, int height, const ColorSpace& cs,
35
- bool alphatex)
38
+ Image::Image (int width, int height, const ColorSpace& cs, bool alpha_only)
36
39
  {
37
- self->bitmap = Bitmap(width, height, cs);
38
- self->alphatex = alphatex;
40
+ self->width = width;
41
+ self->height = height;
42
+ self->color_space = cs;
43
+ self->alpha_only = alpha_only;
39
44
  }
40
45
 
41
- Image::Image (const Bitmap& bitmap, bool alphatex)
46
+ Image::Image (const Bitmap& bitmap, bool alpha_only)
42
47
  {
43
- self->bitmap = bitmap;
44
- self->alphatex = alphatex;
48
+ self->width = bitmap.width();
49
+ self->height = bitmap.height();
50
+ self->color_space = bitmap.color_space();
51
+ self->alpha_only = alpha_only;
52
+ self->bitmap = bitmap;
45
53
  }
46
54
 
47
55
  Image::~Image ()
48
56
  {
49
57
  }
50
58
 
59
+ Image
60
+ Image::copy () const
61
+ {
62
+ return Image(width(), height(), color_space(), alpha_only());
63
+ }
64
+
65
+ Painter
66
+ Image::painter ()
67
+ {
68
+ Painter p;
69
+ p.bind(texture());
70
+ return p;
71
+ }
72
+
51
73
  int
52
74
  Image::width () const
53
75
  {
54
- return self->bitmap.width();
76
+ return self->width;
55
77
  }
56
78
 
57
79
  int
58
80
  Image::height () const
59
81
  {
60
- return self->bitmap.height();
82
+ return self->height;
61
83
  }
62
84
 
63
85
  const ColorSpace&
64
86
  Image::color_space () const
65
87
  {
66
- return self->bitmap.color_space();
88
+ return self->color_space;
67
89
  }
68
90
 
69
91
  bool
70
- Image::alpha_texture () const
92
+ Image::alpha_only () const
71
93
  {
72
- return self->alphatex;
94
+ return self->alpha_only;
73
95
  }
74
96
 
75
97
  Bitmap&
76
98
  Image::bitmap ()
77
99
  {
100
+ if (!self->bitmap)
101
+ {
102
+ if (self->texture)
103
+ self->bitmap = Bitmap(self->texture);
104
+ else
105
+ self->bitmap = Bitmap(self->width, self->height, self->color_space);
106
+ }
107
+ else if (self->texture && !self->bitmap.dirty() && self->texture.dirty())
108
+ self->bitmap = Bitmap(self->texture);
109
+
110
+ if (self->bitmap) self->bitmap.set_dirty(false);
111
+ if (self->texture) self->texture.set_dirty(false);
112
+
78
113
  return self->bitmap;
79
114
  }
80
115
 
@@ -87,13 +122,27 @@ namespace Rays
87
122
  Texture&
88
123
  Image::texture ()
89
124
  {
90
- if (
91
- self->bitmap &&
92
- (!self->texture || self->bitmap.dirty()))
125
+ if (!self->texture)
93
126
  {
94
- self->texture = Texture(self->bitmap, self->alphatex);
95
- self->bitmap.set_dirty(false);
127
+ if (self->bitmap)
128
+ self->texture = Texture(self->bitmap, self->alpha_only);
129
+ else
130
+ {
131
+ self->texture = Texture(
132
+ self->width, self->height, self->color_space, self->alpha_only);
133
+
134
+ Painter p;
135
+ p.bind(self->texture);
136
+ p.begin();
137
+ p.clear();
138
+ p.end();
139
+ }
96
140
  }
141
+ else if (self->bitmap && !self->texture.dirty() && self->bitmap.dirty())
142
+ self->texture = Texture(self->bitmap, self->alpha_only);
143
+
144
+ if (self->bitmap) self->bitmap.set_dirty(false);
145
+ if (self->texture) self->texture.set_dirty(false);
97
146
 
98
147
  return self->texture;
99
148
  }
@@ -106,7 +155,7 @@ namespace Rays
106
155
 
107
156
  Image::operator bool () const
108
157
  {
109
- return !!self->bitmap;
158
+ return self->width > 0 && self->height > 0 && self->color_space;
110
159
  }
111
160
 
112
161
  bool
@@ -116,23 +165,18 @@ namespace Rays
116
165
  }
117
166
 
118
167
 
119
- bool
120
- load_image (Image* image, const char* path, bool alphatex)
168
+ Image
169
+ load_image (const char* path, bool alphatex)
121
170
  {
122
- if (!image || !path) return false;
123
-
124
- Bitmap bitmap;
125
- if (!load_bitmap(&bitmap, path))
126
- return false;
127
-
128
- *image = Image(bitmap, alphatex);
129
- return *image;
171
+ return Image(load_bitmap(path), alphatex);
130
172
  }
131
173
 
132
- bool
174
+ void
133
175
  save_image (const Image& image, const char* path)
134
176
  {
135
- if (!image || !path) return false;
177
+ if (!image)
178
+ argument_error(__FILE__, __LINE__);
179
+
136
180
  return save_bitmap(image.bitmap(), path);
137
181
  }
138
182