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
data/src/painter.cpp CHANGED
@@ -1,53 +1,45 @@
1
+
2
+
1
3
  #include "rays/painter.h"
2
4
 
3
5
 
4
6
  #include <math.h>
5
7
  #include <list>
6
8
  #include <algorithm>
7
- #include <rays/point.h>
8
- #include <rays/bounds.h>
9
- #include <rays/color.h>
10
- #include <rays/matrix.h>
11
- #include <rays/font.h>
12
- #include <rays/bitmap.h>
13
- #include <rays/texture.h>
14
- #include <rays/image.h>
9
+ #include <boost/scoped_array.hpp>
10
+ #include "rays/exception.h"
11
+ #include "rays/point.h"
12
+ #include "rays/bounds.h"
13
+ #include "rays/color.h"
14
+ #include "rays/matrix.h"
15
+ #include "rays/font.h"
16
+ #include "rays/bitmap.h"
17
+ #include "rays/texture.h"
18
+ #include "rays/image.h"
19
+ #include "rays/shader.h"
20
+ #include "frame_buffer.h"
21
+ #include "program.h"
15
22
 
16
23
 
17
24
  namespace Rays
18
25
  {
19
26
 
20
27
 
21
- enum ColorOrder
28
+ enum ColorType
22
29
  {
23
30
 
24
- FILL = 0, STROKE
25
-
26
- };// ColorOrder
31
+ FILL = 0,
32
+ STROKE,
27
33
 
34
+ COLOR_TYPE_LAST,
35
+ COLOR_TYPE_FIRST = 0
28
36
 
29
- static const float PI = 3.141592653589793238462643383279f;
30
-
31
- static const float PI_2 = PI * 2;
37
+ };// ColorType
32
38
 
33
39
 
34
- static void
35
- clear_error ()
36
- {
37
- glGetError();
38
- }
39
-
40
- static bool
41
- is_error ()
42
- {
43
- return glGetError() != GL_NO_ERROR;
44
- }
40
+ static const float PI = 3.141592653589793238462643383279f;
45
41
 
46
- static bool
47
- is_error (GLenum error)
48
- {
49
- return glGetError() == error;
50
- }
42
+ static const float PI_2 = PI * 2;
51
43
 
52
44
 
53
45
  struct Attributes
@@ -61,16 +53,29 @@ namespace Rays
61
53
 
62
54
  void init ()
63
55
  {
64
- clip .set(-1);
65
- background .set(0, 0);
66
- colors[FILL] .set(0, 0);
67
- colors[STROKE] .set(0, 0);
56
+ clip .reset(-1);
57
+ background .reset(0, 0);
58
+ colors[FILL] .reset(1, 1);
59
+ colors[STROKE] .reset(1, 0);
68
60
  font = default_font();
69
61
  }
70
62
 
71
63
  };// Attributes
72
64
 
73
65
 
66
+ struct coord2 {
67
+
68
+ coord x, y;
69
+
70
+ void reset (coord x_, coord y_)
71
+ {
72
+ x = x_;
73
+ y = y_;
74
+ }
75
+
76
+ };// coord2
77
+
78
+
74
79
  struct Painter::Data
75
80
  {
76
81
 
@@ -78,35 +83,28 @@ namespace Rays
78
83
 
79
84
  Attributes attrs;
80
85
 
86
+ Program program;
87
+
81
88
  std::list<Attributes> attrs_stack;
82
89
 
83
- bool painting, drawing;
90
+ bool painting;
84
91
 
85
- Image textimage;
92
+ GLuint current_texture;
93
+
94
+ Image text_image;
95
+
96
+ FrameBuffer frame_buffer;
86
97
 
87
98
  mutable Matrix matrix_tmp;
88
99
 
89
100
  Data ()
90
- : painting(false), drawing(false), textimage(1, 1, GRAY, true)
101
+ : painting(false), current_texture(0), text_image(1, 1, GRAY, true)
91
102
  {
92
103
  attrs.init();
93
104
  }
94
105
 
95
- bool use_color (size_t i)
106
+ void update_clip ()
96
107
  {
97
- clear_error();
98
-
99
- const Color& col = attrs.colors[i];
100
- if (col.alpha <= 0) return false;
101
-
102
- glColor4fv(col.array());
103
- return !is_error();
104
- }
105
-
106
- bool update_clip ()
107
- {
108
- clear_error();
109
-
110
108
  if (attrs.clip)
111
109
  {
112
110
  glEnable(GL_SCISSOR_TEST);
@@ -121,7 +119,71 @@ namespace Rays
121
119
  glDisable(GL_SCISSOR_TEST);
122
120
  }
123
121
 
124
- return !is_error();
122
+ check_error(__FILE__, __LINE__);
123
+ }
124
+
125
+ GLuint frame_buffer_id () const
126
+ {
127
+ return frame_buffer ? frame_buffer.id() : 0;
128
+ }
129
+
130
+ bool use_color (ColorType type)
131
+ {
132
+ const Color& c = attrs.colors[type];
133
+ if (c.alpha <= 0) return false;
134
+
135
+ glColor4f(c.red, c.green, c.blue, c.alpha);
136
+ return true;
137
+ }
138
+
139
+ void draw_shape (
140
+ GLenum mode,
141
+ int nindices, const uint* indices,
142
+ int vertex_size, const coord* vertices,
143
+ const coord* tex_coords = NULL, const Texture* texture = NULL)
144
+ {
145
+ if (nindices <= 0 || !indices || !vertices)
146
+ argument_error(__FILE__, __LINE__);
147
+
148
+ if (!painting)
149
+ invalid_state_error(__FILE__, __LINE__, "'painting' should be true.");
150
+
151
+ bool use_texture = texture && tex_coords;
152
+
153
+ if (use_texture)
154
+ {
155
+ if (!*texture)
156
+ argument_error(__FILE__, __LINE__, "invalid texture.");
157
+
158
+ GLuint id = texture->id();
159
+ if (id != current_texture)
160
+ {
161
+ glBindTexture(GL_TEXTURE_2D, id);
162
+ current_texture = id;
163
+ }
164
+
165
+ glEnable(GL_TEXTURE_2D);
166
+
167
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
168
+ glTexCoordPointer(2, GL_FLOAT, 0, tex_coords);
169
+ }
170
+ else
171
+ {
172
+ glDisable(GL_TEXTURE_2D);
173
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
174
+ }
175
+
176
+ glEnableClientState(GL_VERTEX_ARRAY);
177
+ glVertexPointer(vertex_size, GL_FLOAT, 0, vertices);
178
+
179
+ glDrawElements(mode, nindices, GL_UNSIGNED_INT, indices);
180
+
181
+ glDisableClientState(GL_VERTEX_ARRAY);
182
+ if (use_texture)
183
+ {
184
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
185
+ glDisable(GL_TEXTURE_2D);
186
+ }
125
187
  }
126
188
 
127
189
  };// Painter::Data
@@ -135,142 +197,261 @@ namespace Rays
135
197
  {
136
198
  }
137
199
 
138
- bool
200
+ void
139
201
  Painter::canvas (coord x, coord y, coord width, coord height)
140
202
  {
141
- return canvas(Bounds(x, y, -100, width, height, 200));
203
+ canvas(Bounds(x, y, -100, width, height, 200));
142
204
  }
143
205
 
144
- bool
206
+ void
145
207
  Painter::canvas (coord x, coord y, coord z, coord width, coord height, coord depth)
146
208
  {
147
- return canvas(Bounds(x, y, z, width, height, depth));
209
+ canvas(Bounds(x, y, z, width, height, depth));
148
210
  }
149
211
 
150
- bool
212
+ void
151
213
  Painter::canvas (const Bounds& bounds)
152
214
  {
153
- if (self->painting || !bounds) return false;
215
+ if (!bounds)
216
+ argument_error(__FILE__, __LINE__);
217
+
218
+ if (self->painting)
219
+ invalid_state_error(__FILE__, __LINE__, "self->painting should be false.");
220
+
221
+ self->viewport = bounds;
222
+ }
223
+
224
+ void
225
+ Painter::bind (const Texture& texture)
226
+ {
227
+ if (!texture)
228
+ argument_error(__FILE__, __LINE__, "invalid texture.");
229
+
230
+ if (self->painting)
231
+ invalid_state_error(__FILE__, __LINE__, "self->painting should be false.");
232
+
233
+ FrameBuffer fb(texture);
234
+ if (!fb)
235
+ rays_error(__FILE__, __LINE__, "invalid frame buffer.");
236
+
237
+ unbind();
238
+
239
+ self->frame_buffer = fb;
240
+ canvas(0, 0, fb.width(), fb.height());
241
+ }
242
+
243
+ void
244
+ Painter::unbind ()
245
+ {
246
+ if (self->painting)
247
+ invalid_state_error(__FILE__, __LINE__, "self->painting should be true.");
248
+
249
+ self->frame_buffer = FrameBuffer();
250
+ }
251
+
252
+ const Bounds&
253
+ Painter::bounds () const
254
+ {
255
+ return self->viewport;
256
+ }
257
+
258
+
259
+ void
260
+ Painter::begin ()
261
+ {
262
+ if (self->painting)
263
+ invalid_state_error(__FILE__, __LINE__, "self->painting should be false.");
264
+
265
+ GLuint fb = self->frame_buffer_id();
266
+ bind_frame_buffer(fb);
267
+
268
+ push_attr();
269
+ push_shader();
154
270
 
155
- const Bounds& b = self->viewport = bounds;
271
+ const Bounds& vp = self->viewport;
272
+ glViewport((int) vp.x, (int)vp.y, (int) vp.width, (int) vp.height);
156
273
 
157
- glViewport((int) b.x, (int) b.y, (int) b.width, (int) b.height);
274
+ coord x1 = vp.x, x2 = vp.x + vp.width;
275
+ coord y1 = vp.y, y2 = vp.y + vp.height;
276
+ coord z1 = vp.z, z2 = vp.z + vp.depth;
277
+ if (z1 == 0 && z2 == 0) {z1 = -100; z2 = 200;}
278
+ if (fb == 0) std::swap(y1, y2);
158
279
 
159
280
  glMatrixMode(GL_PROJECTION);
281
+ glPushMatrix();
160
282
  glLoadIdentity();
161
- glOrtho(b.x, b.x + b.width, b.y + b.height, b.y, b.z, b.z + b.depth);
283
+ glOrtho(x1, x2, y1, y2, z1, z2);
162
284
 
163
285
  glMatrixMode(GL_MODELVIEW);
286
+ glPushMatrix();
164
287
  glLoadIdentity();
165
288
  glTranslatef(0.375f, 0.375f, 0);
166
289
 
167
- return true;
168
- }
290
+ glMatrixMode(GL_TEXTURE);
291
+ glPushMatrix();
292
+ glLoadIdentity();
169
293
 
170
- bool
171
- Painter::begin ()
172
- {
173
- if (self->painting) return false;
294
+ #ifndef IOS
295
+ glMatrixMode(GL_COLOR);
296
+ glPushMatrix();
297
+ glLoadIdentity();
298
+ #endif
174
299
 
175
- push_attrs();
300
+ glMatrixMode(GL_MODELVIEW);
176
301
 
177
- glEnable(GL_CULL_FACE);
302
+ //glEnable(GL_CULL_FACE);
178
303
  glEnable(GL_BLEND);
179
304
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
180
305
 
306
+ check_error(__FILE__, __LINE__);
307
+
181
308
  self->painting = true;
182
309
 
183
310
  no_clip();
184
- clear();
185
-
186
- return push_matrix();
187
311
  }
188
312
 
189
- bool
313
+ void
190
314
  Painter::end ()
191
315
  {
192
- if (!self->painting) return false;
193
-
194
- pop_matrix();
316
+ if (!self->painting)
317
+ invalid_state_error(__FILE__, __LINE__, "self->painting should be true.");
195
318
 
196
319
  self->painting = false;
197
320
 
198
321
  glDisable(GL_BLEND);
199
322
  glDisable(GL_CULL_FACE);
200
323
 
201
- return pop_attrs();
324
+ glMatrixMode(GL_PROJECTION);
325
+ glPopMatrix();
326
+
327
+ glMatrixMode(GL_MODELVIEW);
328
+ glPopMatrix();
329
+
330
+ glMatrixMode(GL_TEXTURE);
331
+ glPopMatrix();
332
+
333
+ #ifndef IOS
334
+ glMatrixMode(GL_COLOR);
335
+ glPopMatrix();
336
+ #endif
337
+
338
+ pop_shader();
339
+ pop_attr();
340
+
341
+ //glFinish();
342
+
343
+ unbind_frame_buffer();
344
+
345
+ Texture& tex = self->frame_buffer.texture();
346
+ if (tex) tex.set_dirty(true);
202
347
  }
203
348
 
349
+ void
350
+ Painter::clear ()
351
+ {
352
+ if (!self->painting)
353
+ invalid_state_error(__FILE__, __LINE__, "self->painting should be true.");
204
354
 
205
- bool
355
+ const Color& c = self->attrs.background;
356
+ glClearColor(c.red, c.green, c.blue, c.alpha);
357
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
358
+
359
+ check_error(__FILE__, __LINE__);
360
+ }
361
+
362
+ void
206
363
  Painter::line (coord x1, coord y1, coord x2, coord y2)
207
364
  {
208
- if (!self->painting || !self->use_color(STROKE))
209
- return true;
365
+ static const uint INDICES[] =
366
+ {
367
+ 0, 1
368
+ };
369
+
370
+ Data* pself = self.get();
371
+
372
+ if (!pself->painting)
373
+ invalid_state_error(__FILE__, __LINE__, "self->painting should be true.");
210
374
 
211
- if (!begin_shape(LINES)) return false;
212
- bool ret =
213
- add_vertex(x1, y1) &&
214
- add_vertex(x2, y2);
215
- if (!end_shape()) return false;
375
+ if (!pself->use_color(STROKE))
376
+ return;
216
377
 
217
- return ret;
378
+ coord vertices[] =
379
+ {
380
+ x1, y1,
381
+ x2, y2
382
+ };
383
+
384
+ pself->draw_shape(GL_LINES, 2, INDICES, 2, vertices);
218
385
  }
219
386
 
220
- bool
387
+ void
221
388
  Painter::line (const Point& p1, const Point& p2)
222
389
  {
223
- return line(p1.x, p1.y, p2.x, p2.y);
390
+ line(p1.x, p1.y, p2.x, p2.y);
224
391
  }
225
392
 
226
- bool
393
+ void
227
394
  Painter::rect (coord x, coord y, coord width, coord height)
228
395
  {
229
- static const ShapeType TYPES[] = {QUADS, LINE_LOOP};
396
+ static const GLenum MODES[] = {GL_TRIANGLE_FAN, GL_LINE_LOOP};
397
+ static const uint INDICES[] =
398
+ {
399
+ 0, 1, 2, 3
400
+ };
401
+
402
+ Data* pself = self.get();
230
403
 
231
- if (!self->painting) return false;
404
+ if (!pself->painting)
405
+ invalid_state_error(__FILE__, __LINE__, "self->painting should be true.");
232
406
 
233
- if (width <= 0 || height <= 0) return true;
407
+ if (width <= 0 || height <= 0) return;
234
408
 
235
409
  coord x2 = x + width - 1;
236
410
  coord y2 = y + height - 1;
237
411
 
238
- bool ret = true;
239
- for (int i = 0; i < 2; ++i)
412
+ for (int type = COLOR_TYPE_FIRST; type < COLOR_TYPE_LAST; ++type)
240
413
  {
241
- if (!self->use_color(i)) continue;
242
-
243
- if (!begin_shape(TYPES[i])) return false;
244
- coord xx = x2 + 1 - i;
245
- coord yy = y2 + 1 - i;
246
- ret &=
247
- add_vertex(x, y) &&
248
- add_vertex(x, yy) &&
249
- add_vertex(xx, yy) &&
250
- add_vertex(xx, y);
251
- if (!end_shape()) return false;
252
- }
414
+ if (!pself->use_color((ColorType) type)) continue;
415
+
416
+ coord xx = x2 + 1 - type;
417
+ coord yy = y2 + 1 - type;
418
+ coord vertices[] =
419
+ {
420
+ x, y,
421
+ x, yy,
422
+ xx, yy,
423
+ xx, y
424
+ };
253
425
 
254
- return ret;
426
+ pself->draw_shape(MODES[type], 4, INDICES, 2, vertices);
427
+ }
255
428
  }
256
429
 
257
- bool
430
+ void
258
431
  Painter::rect (const Bounds& bounds)
259
432
  {
260
- return rect(bounds.x, bounds.y, bounds.width, bounds.height);
433
+ rect(bounds.x, bounds.y, bounds.width, bounds.height);
261
434
  }
262
435
 
263
- static bool
436
+ static const uint ELLIPSE_NSEGMENT = 32;
437
+
438
+ static void
264
439
  draw_ellipse (
265
440
  Painter* painter,
266
441
  coord x, coord y, coord width, coord height,
267
442
  float angle_from, float angle_to, coord radius_min,
268
443
  uint nsegment)
269
444
  {
270
- if (!painter || !painter->self->painting)
271
- return false;
445
+ if (!painter)
446
+ argument_error(__FILE__, __LINE__);
272
447
 
273
- if (height == 0) height = width;
448
+ Painter::Data* pself = painter->self.get();
449
+
450
+ if (!pself->painting)
451
+ invalid_state_error(__FILE__, __LINE__, "self->painting should be true.");
452
+
453
+ if (height == 0) height = width;
454
+ if (nsegment <= 0) nsegment = ELLIPSE_NSEGMENT;
274
455
 
275
456
  coord radius_x = width / 2;
276
457
  coord radius_y = height / 2;
@@ -279,245 +460,274 @@ namespace Rays
279
460
  float from = angle_from / 360.f;
280
461
  float to = angle_to / 360.f;
281
462
  bool hole = radius_min != 0;
282
- ShapeType types[] =
463
+ int nvertices = hole ? nsegment * 2 : nsegment + 1;
464
+ GLenum modes[] =
283
465
  {
284
- hole ? TRIANGLE_STRIP : TRIANGLE_FAN,
285
- LINE_LOOP
466
+ (GLenum) (hole ? GL_TRIANGLE_STRIP : GL_TRIANGLE_FAN),
467
+ GL_LINE_LOOP
286
468
  };
469
+ boost::scoped_array<uint> indices;
470
+ boost::scoped_array<coord2> vertices;
287
471
 
288
472
  x += radius_x;
289
473
  y += radius_y;
290
474
 
291
- bool ret = true;
292
- for (int i = 0; i < 2; ++i)
475
+ for (int type = COLOR_TYPE_FIRST; type < COLOR_TYPE_LAST; ++type)
293
476
  {
294
- if (!painter->self->use_color(i)) continue;
477
+ if (!pself->use_color((ColorType) type)) continue;
478
+
479
+ if (!indices.get())
480
+ {
481
+ indices.reset(new uint[nvertices]);
482
+ for (int i = 0; i < nvertices; ++i)
483
+ indices[i] = i;
484
+ }
485
+
486
+ if (!vertices.get())
487
+ vertices.reset(new coord2[nvertices]);
295
488
 
296
- if (!painter->begin_shape(types[i])) return false;
489
+ coord2* vertex = vertices.get();
490
+ assert(vertex);
297
491
 
298
492
  if (!hole)
299
- ret &= painter->add_vertex(x, y);
493
+ {
494
+ vertex->reset(x, y);
495
+ ++vertex;
496
+ }
300
497
 
301
- for (int seg = 0; seg <= (int) nsegment; ++seg)
498
+ for (int seg = 0; seg <= (int) nsegment; ++seg, ++vertex)
302
499
  {
303
500
  float pos = (float) seg / (float) nsegment;
304
501
  float radian = (from + (to - from) * pos) * PI_2;
305
502
  float xx = cos(radian);
306
503
  float yy = -sin(radian);
504
+
307
505
  if (hole)
308
- ret &= painter->add_vertex(x + xx * radius_x_min, y + yy * radius_y_min);
309
- ret &= painter->add_vertex(x + xx * radius_x, y + yy * radius_y);
506
+ vertex->reset(x + xx * radius_x_min, y + yy * radius_y_min);
507
+ vertex ->reset(x + xx * radius_x, y + yy * radius_y);
310
508
  }
311
509
 
312
- if (!painter->end_shape()) return false;
510
+ pself->draw_shape(modes[type], nvertices, indices.get(), 2, (coord*) vertices.get());
313
511
  }
314
-
315
- return ret;
316
512
  }
317
513
 
318
- static const uint ELLIPSE_NSEGMENT = 32;
319
-
320
- bool
514
+ void
321
515
  Painter::ellipse (
322
516
  coord x, coord y, coord width, coord height,
323
517
  coord radius_min, uint nsegment)
324
518
  {
325
- if (nsegment <= 0) nsegment = ELLIPSE_NSEGMENT;
326
- return draw_ellipse(
327
- this, x, y, width, height, 0, 360, radius_min, nsegment);
519
+ draw_ellipse(this, x, y, width, height, 0, 360, radius_min, nsegment);
328
520
  }
329
521
 
330
- bool
522
+ void
331
523
  Painter::ellipse (const Bounds& bounds, coord radius_min, uint nsegment)
332
524
  {
333
- return ellipse(
525
+ ellipse(
334
526
  bounds.x, bounds.y, bounds.width, bounds.height, radius_min, nsegment);
335
527
  }
336
528
 
337
- bool
529
+ void
338
530
  Painter::ellipse (
339
531
  const Point& center, coord radius, coord radius_min, uint nsegment)
340
532
  {
341
- return ellipse(
342
- center.x, center.y, radius * 2, radius * 2, radius_min, nsegment);
533
+ ellipse(center.x, center.y, radius * 2, radius * 2, radius_min, nsegment);
343
534
  }
344
535
 
345
- bool
536
+ void
346
537
  Painter::arc (
347
538
  coord x, coord y, coord width, coord height,
348
539
  float angle_from, float angle_to, coord radius_min, uint nsegment)
349
540
  {
350
- if (nsegment <= 0) nsegment = ELLIPSE_NSEGMENT;
351
- return draw_ellipse(
541
+ draw_ellipse(
352
542
  this, x, y, width, height, angle_from, angle_to, radius_min, nsegment);
353
543
  }
354
544
 
355
- bool
545
+ void
356
546
  Painter::arc (
357
547
  const Bounds& bounds,
358
548
  float angle_from, float angle_to, coord radius_min, uint nsegment)
359
549
  {
360
- return arc(
550
+ arc(
361
551
  bounds.x, bounds.y, bounds.width, bounds.height,
362
552
  angle_from, angle_to, radius_min, nsegment);
363
553
  }
364
554
 
365
- bool
555
+ void
366
556
  Painter::arc (
367
557
  const Point& center, coord radius,
368
558
  float angle_from, float angle_to, coord radius_min, uint nsegment)
369
559
  {
370
- return arc(
560
+ arc(
371
561
  center.x, center.y, radius * 2, radius * 2,
372
562
  angle_from, angle_to, radius_min, nsegment);
373
563
  }
374
564
 
375
- static bool
565
+ static void
376
566
  draw_image (
377
567
  Painter* painter, const Texture& tex,
378
568
  float s_min, float t_min, float s_max, float t_max,
379
569
  coord x, coord y, coord width, coord height,
380
570
  bool nostroke = false)
381
571
  {
382
- static const ShapeType TYPES[] = {QUADS, LINE_LOOP};
572
+ static const GLenum MODES[] = {GL_TRIANGLE_FAN, GL_LINE_LOOP};
573
+ static const uint INDICES[] =
574
+ {
575
+ 0, 1, 2, 3
576
+ };
383
577
 
384
578
  assert(tex);
385
579
 
386
- if (!painter || !painter->self->painting)
387
- return false;
580
+ if (!painter)
581
+ argument_error(__FILE__, __LINE__);
582
+
583
+ Painter::Data* pself = painter->self.get();
584
+
585
+ if (!pself->painting)
586
+ invalid_state_error(__FILE__, __LINE__, "self->painting should be true.");
388
587
 
389
588
  coord x2 = x + width - 1;
390
589
  coord y2 = y + height - 1;
590
+ coord vertices[] =
591
+ {
592
+ x, y,
593
+ x, y2,
594
+ x2, y2,
595
+ x2, y
596
+ };
391
597
 
392
- glEnable(GL_TEXTURE_2D);
393
- painter->set_texture(tex);
394
-
395
- bool ret = true;
396
- for (int i = 0; i < 2; ++i)
598
+ for (int type = COLOR_TYPE_FIRST; type < COLOR_TYPE_LAST; ++type)
397
599
  {
398
600
  if (
399
- (nostroke && TYPES[i] == LINE_LOOP) ||
400
- !painter->self->use_color(i))
601
+ (nostroke && type == STROKE) ||
602
+ !pself->use_color((ColorType) type))
401
603
  {
402
604
  continue;
403
605
  }
404
606
 
405
- if (!painter->begin_shape(TYPES[i])) return false;
406
- ret &=
407
- painter->add_vertex(x, y, s_min, t_min) &&
408
- painter->add_vertex(x, y2, s_min, t_max) &&
409
- painter->add_vertex(x2, y2, s_max, t_max) &&
410
- painter->add_vertex(x2, y, s_max, t_min);
411
- if (!painter->end_shape()) return false;
607
+ if (type == FILL)
608
+ {
609
+ coord tex_coords[] = {
610
+ s_min, t_min,
611
+ s_min, t_max,
612
+ s_max, t_max,
613
+ s_max, t_min
614
+ };
615
+ pself->draw_shape(MODES[type], 4, INDICES, 2, vertices, tex_coords, &tex);
616
+ }
617
+ else
618
+ pself->draw_shape(MODES[type], 4, INDICES, 2, vertices);
412
619
  }
413
-
414
- painter->no_texture();
415
- glDisable(GL_TEXTURE_2D);
416
-
417
- return ret;
418
620
  }
419
621
 
420
- bool
622
+ void
421
623
  Painter::image (const Image& image_, coord x, coord y)
422
624
  {
423
- if (!image_) return false;
625
+ if (!image_)
626
+ argument_error(__FILE__, __LINE__);
424
627
 
425
628
  const Texture& tex = image_.texture();
426
- if (!tex) return false;
629
+ if (!tex)
630
+ argument_error(__FILE__, __LINE__);
427
631
 
428
- return draw_image(
632
+ draw_image(
429
633
  this, tex,
430
634
  0, 0, tex.s_max(), tex.t_max(),
431
635
  x, y, tex.width(), tex.height());
432
636
  }
433
637
 
434
- bool
638
+ void
435
639
  Painter::image (const Image& image_, const Point& position)
436
640
  {
437
- return image(image_, position.x, position.y);
641
+ image(image_, position.x, position.y);
438
642
  }
439
643
 
440
- bool
644
+ void
441
645
  Painter::image (
442
646
  const Image& image_, coord x, coord y, coord width, coord height)
443
647
  {
444
- if (!image_) return false;
648
+ if (!image_)
649
+ argument_error(__FILE__, __LINE__);
445
650
 
446
651
  const Texture& tex = image_.texture();
447
- if (!tex) return false;
652
+ if (!tex)
653
+ argument_error(__FILE__, __LINE__);
448
654
 
449
- return draw_image(
655
+ draw_image(
450
656
  this, tex,
451
657
  0, 0, tex.s_max(), tex.t_max(),
452
658
  x, y, width, height);
453
659
  }
454
660
 
455
- bool
661
+ void
456
662
  Painter::image (
457
663
  const Image& image_, const Bounds& bounds)
458
664
  {
459
- return image(image_, bounds.x, bounds.y, bounds.width, bounds.height);
665
+ image(image_, bounds.x, bounds.y, bounds.width, bounds.height);
460
666
  }
461
667
 
462
- bool
668
+ void
463
669
  Painter::image (
464
670
  const Image& image_,
465
671
  coord src_x, coord src_y, coord src_width, coord src_height,
466
672
  coord dest_x, coord dest_y)
467
673
  {
468
- if (!image_) return false;
674
+ if (!image_)
675
+ argument_error(__FILE__, __LINE__);
469
676
 
470
677
  const Texture& tex = image_.texture();
471
- if (!tex) return false;
678
+ if (!tex)
679
+ argument_error(__FILE__, __LINE__);
472
680
 
473
681
  coord dest_width = tex.width(), dest_height = tex.height();
474
682
  float s = tex.s_max() / dest_width, t = tex.t_max() / dest_height;
475
- return draw_image(
683
+ draw_image(
476
684
  this, tex,
477
685
  src_x * s, src_y * t, src_width * s, src_height * t,
478
686
  dest_x, dest_y, dest_width, dest_height);
479
687
  }
480
688
 
481
- bool
689
+ void
482
690
  Painter::image (
483
691
  const Image& image_, const Bounds& src_bounds, const Point& dest_position)
484
692
  {
485
- return image(
693
+ image(
486
694
  image_,
487
695
  src_bounds.x, src_bounds.y, src_bounds.width, src_bounds.height,
488
696
  dest_position.x, dest_position.y);
489
697
  }
490
698
 
491
- bool
699
+ void
492
700
  Painter::image (
493
701
  const Image& image_,
494
702
  coord src_x, coord src_y, coord src_width, coord src_height,
495
703
  coord dest_x, coord dest_y, coord dest_width, coord dest_height)
496
704
  {
497
- if (!image_) return false;
705
+ if (!image_)
706
+ argument_error(__FILE__, __LINE__);
498
707
 
499
708
  const Texture& tex = image_.texture();
500
- if (!tex) return false;
709
+ if (!tex)
710
+ argument_error(__FILE__, __LINE__);
501
711
 
502
712
  float s = tex.s_max() / tex.width();
503
713
  float t = tex.t_max() / tex.height();
504
- return draw_image(
714
+ draw_image(
505
715
  this, tex,
506
716
  src_x * s, src_y * t, src_width * s, src_height * t,
507
717
  dest_x, dest_y, dest_width, dest_height);
508
718
  }
509
719
 
510
- bool
720
+ void
511
721
  Painter::image (
512
722
  const Image& image_, const Bounds& src_bounds, const Bounds& dest_bounds)
513
723
  {
514
- return image(
724
+ image(
515
725
  image_,
516
726
  src_bounds.x, src_bounds.y, src_bounds.width, src_bounds.height,
517
727
  dest_bounds.x, dest_bounds.y, dest_bounds.width, dest_bounds.height);
518
728
  }
519
729
 
520
- static bool
730
+ static void
521
731
  draw_text (
522
732
  Painter* painter, const char* str, coord str_width, coord str_height,
523
733
  coord x, coord y, coord width, coord height,
@@ -525,39 +735,43 @@ namespace Rays
525
735
  {
526
736
  assert(str && *str != '\0' && font);
527
737
 
528
- if (!painter || !painter->self->painting)
529
- return false;
738
+ if (!painter)
739
+ argument_error(__FILE__, __LINE__);
740
+
741
+ if (!painter->self->painting)
742
+ invalid_state_error(__FILE__, __LINE__, "self->painting should be true.");
530
743
 
531
744
  Painter::Data* self = painter->self.get();
532
745
  int tex_w = ceil(str_width);
533
746
  int tex_h = ceil(str_height);
534
747
 
535
748
  if (
536
- self->textimage.width() < tex_w ||
537
- self->textimage.height() < tex_h)
749
+ self->text_image.width() < tex_w ||
750
+ self->text_image.height() < tex_h)
538
751
  {
539
- self->textimage = Image(
540
- std::max(self->textimage.width(), tex_w),
541
- std::max(self->textimage.height(), tex_h),
542
- self->textimage.color_space(),
543
- self->textimage.alpha_texture());
752
+ self->text_image = Image(
753
+ std::max(self->text_image.width(), tex_w),
754
+ std::max(self->text_image.height(), tex_h),
755
+ self->text_image.color_space(),
756
+ self->text_image.alpha_only());
544
757
  }
545
758
 
546
- if (!self->textimage) return false;
759
+ if (!self->text_image)
760
+ invalid_state_error(__FILE__, __LINE__);
547
761
 
548
- if (!draw_string(&self->textimage.bitmap(), str, 0, 0, font))
549
- return false;
762
+ draw_string(&self->text_image.bitmap(), str, 0, 0, font);
550
763
 
551
- const Texture& tex = self->textimage.texture();
552
- if (!tex) return false;
764
+ const Texture& tex = self->text_image.texture();
765
+ if (!tex)
766
+ rays_error(__FILE__, __LINE__, "text_image's texture is invalid.");
553
767
 
554
768
  #ifdef DEBUG
555
- save_image(self->textimage, "/Users/snori/font.png");
769
+ save_image(self->text_image, "/Users/snori/font.png");
556
770
 
557
- painter->push_attrs();
771
+ painter->push_attr();
558
772
  {
559
773
  coord asc, desc, lead;
560
- font.get_height(NULL, &asc, &desc, &lead);
774
+ font.get_height(&asc, &desc, &lead);
561
775
  //printf("%f %f %f %f \n", str_height, asc, desc, lead);
562
776
 
563
777
  painter->set_stroke(0.5, 0.5, 1);
@@ -576,100 +790,87 @@ namespace Rays
576
790
  painter->set_stroke(1, 0.5, 1, 0.4);
577
791
  painter->rect(x, yy, str_width, lead);
578
792
  }
579
- painter->pop_attrs();
793
+ painter->pop_attr();
580
794
  #endif
581
795
 
582
- bool ret = draw_image(
796
+ draw_image(
583
797
  painter, tex,
584
798
  0, 0, tex.s(str_width - 1), tex.t(str_height - 1),
585
799
  x, y, width, height,
586
800
  true);
587
-
588
- return ret;
589
801
  }
590
802
 
591
- bool
803
+ void
592
804
  Painter::text (const char* str, coord x, coord y, const Font* font)
593
805
  {
594
- if (!str) return false;
806
+ if (!str)
807
+ argument_error(__FILE__, __LINE__);
595
808
 
596
- if (*str == '\0') return true;
809
+ if (*str == '\0') return;
597
810
 
598
811
  if (!font) font = &self->attrs.font;
599
- if (!*font) return false;
600
-
601
- coord w = 0, h = 0;
602
- if (!font->get_width(&w, str) || !font->get_height(&h))
603
- return false;
812
+ if (!*font)
813
+ argument_error(__FILE__, __LINE__);
604
814
 
815
+ coord w = font->get_width(str), h = font->get_height();
605
816
  w = ceil(w);
606
817
  h = ceil(h);
607
- return draw_text(this, str, w, h, x, y, w, h, *font);
818
+ draw_text(this, str, w, h, x, y, w, h, *font);
608
819
  }
609
820
 
610
- bool
821
+ void
611
822
  Painter::text (const char* str, const Point& position, const Font* font)
612
823
  {
613
- return text(str, position.x, position.y, font);
824
+ text(str, position.x, position.y, font);
614
825
  }
615
826
 
616
- bool
827
+ void
617
828
  Painter::text (
618
829
  const char* str, coord x, coord y, coord width, coord height,
619
830
  const Font* font)
620
831
  {
621
- if (!str) return false;
832
+ if (!str)
833
+ argument_error(__FILE__, __LINE__);
622
834
 
623
- if (*str == '\0') return true;
835
+ if (*str == '\0') return;
624
836
 
625
837
  if (!font) font = &self->attrs.font;
626
- if (!*font) return false;
627
-
628
- coord w = 0, h = 0;
629
- if (!font->get_width(&w, str) || !font->get_height(&h))
630
- return false;
838
+ if (!*font)
839
+ argument_error(__FILE__, __LINE__);
631
840
 
841
+ coord w = font->get_width(str), h = font->get_height();
632
842
  w = ceil(w);
633
843
  h = ceil(h);
634
- return draw_text(this, str, w, h, x, y, width, height, *font);
844
+ draw_text(this, str, w, h, x, y, width, height, *font);
635
845
  }
636
846
 
637
- bool
847
+ void
638
848
  Painter::text (const char* str, const Bounds& bounds, const Font* font)
639
849
  {
640
- return text(str, bounds.x, bounds.y, bounds.width, bounds.height, font);
850
+ text(str, bounds.x, bounds.y, bounds.width, bounds.height, font);
641
851
  }
642
852
 
643
- bool
644
- Painter::clear ()
645
- {
646
- if (!self->painting) return false;
647
853
 
648
- const Color& c = self->attrs.background;
649
- glClearColor(c.red, c.green, c.blue, c.alpha);
650
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
651
- return true;
652
- }
653
-
654
- bool
655
- Painter::set_background (float red, float green, float blue, float alpha)
854
+ void
855
+ Painter::set_background (float red, float green, float blue, float alpha, bool clear)
656
856
  {
657
- self->attrs.background.set(red, green, blue, alpha);
658
- return true;
857
+ set_background(Color(red, green, blue, alpha), clear);
659
858
  }
660
859
 
661
- bool
662
- Painter::set_background (const Color& color)
860
+ void
861
+ Painter::set_background (const Color& color, bool clear)
663
862
  {
664
863
  self->attrs.background = color;
665
- return true;
864
+
865
+ if (self->painting && clear) this->clear();
666
866
  }
667
867
 
668
- bool
669
- Painter::no_background ()
868
+ void
869
+ Painter::no_background (bool clear)
670
870
  {
671
- self->attrs.background.alpha = 0;
672
- return true;
871
+ Color c = background();
872
+ c.alpha = 0;
873
+ set_background(c, clear);
673
874
  }
674
875
 
675
876
  const Color&
@@ -678,25 +879,22 @@ namespace Rays
678
879
  return self->attrs.background;
679
880
  }
680
881
 
681
- bool
882
+ void
682
883
  Painter::set_fill (float red, float green, float blue, float alpha)
683
884
  {
684
- self->attrs.colors[FILL].set(red, green, blue, alpha);
685
- return true;
885
+ set_fill(Color(red, green, blue, alpha));
686
886
  }
687
887
 
688
- bool
888
+ void
689
889
  Painter::set_fill (const Color& color)
690
890
  {
691
891
  self->attrs.colors[FILL] = color;
692
- return true;
693
892
  }
694
893
 
695
- bool
894
+ void
696
895
  Painter::no_fill ()
697
896
  {
698
897
  self->attrs.colors[FILL].alpha = 0;
699
- return true;
700
898
  }
701
899
 
702
900
  const Color&
@@ -705,25 +903,22 @@ namespace Rays
705
903
  return self->attrs.colors[FILL];
706
904
  }
707
905
 
708
- bool
906
+ void
709
907
  Painter::set_stroke (float red, float green, float blue, float alpha)
710
908
  {
711
- self->attrs.colors[STROKE].set(red, green, blue, alpha);
712
- return true;
909
+ set_stroke(Color(red, green, blue, alpha));
713
910
  }
714
911
 
715
- bool
912
+ void
716
913
  Painter::set_stroke (const Color& color)
717
914
  {
718
915
  self->attrs.colors[STROKE] = color;
719
- return true;
720
916
  }
721
917
 
722
- bool
918
+ void
723
919
  Painter::no_stroke ()
724
920
  {
725
921
  self->attrs.colors[STROKE].alpha = 0;
726
- return true;
727
922
  }
728
923
 
729
924
  const Color&
@@ -732,25 +927,23 @@ namespace Rays
732
927
  return self->attrs.colors[STROKE];
733
928
  }
734
929
 
735
- bool
930
+ void
736
931
  Painter::set_clip (coord x, coord y, coord width, coord height)
737
932
  {
738
- return set_clip(Bounds(x, y, width, height));
933
+ set_clip(Bounds(x, y, width, height));
739
934
  }
740
935
 
741
- bool
936
+ void
742
937
  Painter::set_clip (const Bounds& bounds)
743
938
  {
744
- if (bounds == self->attrs.clip) return true;
745
-
746
939
  self->attrs.clip = bounds;
747
- return self->update_clip();
940
+ self->update_clip();
748
941
  }
749
942
 
750
- bool
943
+ void
751
944
  Painter::no_clip ()
752
945
  {
753
- return set_clip(0, 0, -1, -1);
946
+ set_clip(0, 0, -1, -1);
754
947
  }
755
948
 
756
949
  const Bounds&
@@ -759,11 +952,16 @@ namespace Rays
759
952
  return self->attrs.clip;
760
953
  }
761
954
 
762
- bool
955
+ void
956
+ Painter::set_font (const char* name, coord size)
957
+ {
958
+ set_font(Font(name, size));
959
+ }
960
+
961
+ void
763
962
  Painter::set_font (const Font& font)
764
963
  {
765
964
  self->attrs.font = font;
766
- return true;
767
965
  }
768
966
 
769
967
  const Font&
@@ -772,236 +970,212 @@ namespace Rays
772
970
  return self->attrs.font;
773
971
  }
774
972
 
775
- bool
776
- Painter::push_attrs ()
973
+ void
974
+ Painter::push_attr ()
777
975
  {
778
- //glPushAttrib(GL_ALL_ATTRIB_BITS);
779
976
  self->attrs_stack.push_back(self->attrs);
780
- return true;
781
977
  }
782
978
 
783
- bool
784
- Painter::pop_attrs ()
979
+ void
980
+ Painter::pop_attr ()
785
981
  {
786
- if (self->attrs_stack.empty()) return false;
982
+ if (self->attrs_stack.empty())
983
+ rays_error(__FILE__, __LINE__, "attrs_stack is empty.");
787
984
 
788
985
  self->attrs = self->attrs_stack.back();
789
986
  self->attrs_stack.pop_back();
790
987
  self->update_clip();
791
-
792
- //glPopAttrib();
793
- return true;
794
988
  }
795
989
 
796
990
 
797
- bool
798
- Painter::translate (coord x, coord y, coord z)
991
+ void
992
+ Painter::attach (const Shader& shader)
799
993
  {
800
- glTranslatef(x, y, z);
801
- return !is_error();
994
+ self->program.attach(shader);
802
995
  }
803
996
 
804
- bool
805
- Painter::translate (const Point& value)
997
+ void
998
+ Painter::detach (const Shader& shader)
806
999
  {
807
- return translate(value.x, value.y, value.z);
1000
+ self->program.detach(shader);
808
1001
  }
809
1002
 
810
- bool
811
- Painter::scale (coord x, coord y, coord z)
1003
+ void
1004
+ Painter::set_uniform (const char* name, int arg1)
812
1005
  {
813
- glScalef(x, y, z);
814
- return !is_error();
1006
+ self->program.set_uniform(name, arg1);
815
1007
  }
816
1008
 
817
- bool
818
- Painter::scale (const Point& value)
1009
+ void
1010
+ Painter::set_uniform (const char* name, int arg1, int arg2)
819
1011
  {
820
- return scale(value.x, value.y, value.z);
1012
+ self->program.set_uniform(name, arg1, arg2);
821
1013
  }
822
1014
 
823
- bool
824
- Painter::rotate (float angle, coord x, coord y, coord z)
1015
+ void
1016
+ Painter::set_uniform (const char* name, int arg1, int arg2, int arg3)
825
1017
  {
826
- glRotatef(angle, x, y, z);
827
- return !is_error();
1018
+ self->program.set_uniform(name, arg1, arg2, arg3);
828
1019
  }
829
1020
 
830
- bool
831
- Painter::rotate (float angle, const Point& center)
1021
+ void
1022
+ Painter::set_uniform (const char* name, int arg1, int arg2, int arg3, int arg4)
832
1023
  {
833
- return rotate(angle, center.x, center.y, center.z);
1024
+ self->program.set_uniform(name, arg1, arg2, arg3, arg4);
834
1025
  }
835
1026
 
836
- bool
837
- Painter::set_matrix (float value)
1027
+ void
1028
+ Painter::set_uniform (const char* name, const int* args, size_t size)
838
1029
  {
839
- if (value == 1)
840
- {
841
- glLoadIdentity();
842
- return !is_error();
843
- }
844
-
845
- return set_matrix(
846
- value, 0, 0, 0,
847
- 0, value, 0, 0,
848
- 0, 0, value, 0,
849
- 0, 0, 0, value);
1030
+ self->program.set_uniform(name, args, size);
850
1031
  }
851
1032
 
852
- bool
853
- Painter::set_matrix (
854
- float a1, float a2, float a3, float a4,
855
- float b1, float b2, float b3, float b4,
856
- float c1, float c2, float c3, float c4,
857
- float d1, float d2, float d3, float d4)
1033
+ void
1034
+ Painter::set_uniform (const char* name, float arg1)
858
1035
  {
859
- float array[] = {
860
- a1, a2, a3, a4,
861
- b1, b2, b3, b4,
862
- c1, c2, c3, c4,
863
- d1, d2, d3, d4
864
- };
865
- return set_matrix(array);
1036
+ self->program.set_uniform(name, arg1);
866
1037
  }
867
1038
 
868
- bool
869
- Painter::set_matrix (const float* elements)
1039
+ void
1040
+ Painter::set_uniform (const char* name, float arg1, float arg2)
870
1041
  {
871
- if (!elements) return false;
872
- glLoadMatrixf(elements);
873
- return !is_error();
1042
+ self->program.set_uniform(name, arg1, arg2);
874
1043
  }
875
1044
 
876
- bool
877
- Painter::set_matrix (const Matrix& matrix)
1045
+ void
1046
+ Painter::set_uniform (const char* name, float arg1, float arg2, float arg3)
878
1047
  {
879
- return set_matrix(matrix.array());
1048
+ self->program.set_uniform(name, arg1, arg2, arg3);
880
1049
  }
881
1050
 
882
- const Matrix&
883
- Painter::matrix () const
1051
+ void
1052
+ Painter::set_uniform (const char* name, float arg1, float arg2, float arg3, float arg4)
884
1053
  {
885
- glGetFloatv(GL_MODELVIEW_MATRIX, self->matrix_tmp.array());
886
- if (is_error(GL_INVALID_ENUM)) self->matrix_tmp.set(0);
887
- return self->matrix_tmp;
1054
+ self->program.set_uniform(name, arg1, arg2, arg3, arg4);
888
1055
  }
889
1056
 
890
- bool
891
- Painter::push_matrix ()
1057
+ void
1058
+ Painter::set_uniform (const char* name, const float* args, size_t size)
892
1059
  {
893
- glPushMatrix();
894
- return !is_error(GL_STACK_OVERFLOW);
1060
+ self->program.set_uniform(name, args, size);
895
1061
  }
896
1062
 
897
- bool
898
- Painter::pop_matrix ()
1063
+ void
1064
+ Painter::push_shader ()
899
1065
  {
900
- glPopMatrix();
901
- return !is_error(GL_STACK_UNDERFLOW);
1066
+ self->program.push();
902
1067
  }
903
1068
 
904
-
905
- bool
906
- Painter::begin_shape (ShapeType type)
1069
+ void
1070
+ Painter::pop_shader ()
907
1071
  {
908
- if (!self->painting || self->drawing)
909
- return false;
1072
+ self->program.pop();
1073
+ }
910
1074
 
911
- glBegin(type);
912
1075
 
913
- self->drawing = true;
914
- return true;
1076
+ void
1077
+ Painter::translate (coord x, coord y, coord z)
1078
+ {
1079
+ glTranslatef(x, y, z);
915
1080
  }
916
1081
 
917
- bool
918
- Painter::end_shape ()
1082
+ void
1083
+ Painter::translate (const Point& value)
919
1084
  {
920
- if (!self->painting || !self->drawing)
921
- return false;
922
-
923
- glEnd();
924
-
925
- self->drawing = false;
926
- return true;
1085
+ translate(value.x, value.y, value.z);
927
1086
  }
928
1087
 
929
- bool
930
- Painter::set_color (float red, float green, float blue, float alpha)
1088
+ void
1089
+ Painter::scale (coord x, coord y, coord z)
931
1090
  {
932
- if (!self->drawing) return false;
933
-
934
- glColor4f(red, green, blue, alpha);
935
- return true;
1091
+ glScalef(x, y, z);
936
1092
  }
937
1093
 
938
- bool
939
- Painter::set_color (const Color& color)
1094
+ void
1095
+ Painter::scale (const Point& value)
940
1096
  {
941
- if (!self->drawing) return false;
942
-
943
- glColor4fv(color.array());
944
- return true;
1097
+ scale(value.x, value.y, value.z);
945
1098
  }
946
1099
 
947
- bool
948
- Painter::set_texture (const Texture& tex)
1100
+ void
1101
+ Painter::rotate (float angle, coord x, coord y, coord z)
949
1102
  {
950
- if (!self->drawing) return false;
1103
+ glRotatef(angle, x, y, z);
1104
+ }
951
1105
 
952
- glBindTexture(GL_TEXTURE_2D, tex ? tex.id() : 0);
953
- return true;
1106
+ void
1107
+ Painter::rotate (float angle, const Point& center)
1108
+ {
1109
+ rotate(angle, center.x, center.y, center.z);
954
1110
  }
955
1111
 
956
- bool
957
- Painter::no_texture ()
1112
+ void
1113
+ Painter::set_matrix (float value)
958
1114
  {
959
- if (!self->drawing) return false;
1115
+ if (value == 1)
1116
+ {
1117
+ glLoadIdentity();
1118
+ return;
1119
+ }
960
1120
 
961
- glBindTexture(GL_TEXTURE_2D, 0);
962
- return true;
1121
+ set_matrix(
1122
+ value, 0, 0, 0,
1123
+ 0, value, 0, 0,
1124
+ 0, 0, value, 0,
1125
+ 0, 0, 0, value);
963
1126
  }
964
1127
 
965
- bool
966
- Painter::add_vertex (coord x, coord y)
1128
+ void
1129
+ Painter::set_matrix (
1130
+ float a1, float a2, float a3, float a4,
1131
+ float b1, float b2, float b3, float b4,
1132
+ float c1, float c2, float c3, float c4,
1133
+ float d1, float d2, float d3, float d4)
967
1134
  {
968
- return add_vertex(x, y, 0);
1135
+ float array[] = {
1136
+ a1, a2, a3, a4,
1137
+ b1, b2, b3, b4,
1138
+ c1, c2, c3, c4,
1139
+ d1, d2, d3, d4
1140
+ };
1141
+ set_matrix(array);
969
1142
  }
970
1143
 
971
- bool
972
- Painter::add_vertex (coord x, coord y, coord z)
1144
+ void
1145
+ Painter::set_matrix (const float* elements)
973
1146
  {
974
- if (!self->drawing) return false;
1147
+ if (!elements)
1148
+ argument_error(__FILE__, __LINE__);
975
1149
 
976
- glVertex3f(x, y, z);
977
- return true;
1150
+ glLoadMatrixf(elements);
978
1151
  }
979
1152
 
980
- bool
981
- Painter::add_vertex (const Point& pos)
1153
+ void
1154
+ Painter::set_matrix (const Matrix& matrix)
982
1155
  {
983
- return add_vertex(pos.x, pos.y, pos.z);
1156
+ set_matrix(matrix.array);
984
1157
  }
985
1158
 
986
- bool
987
- Painter::add_vertex (coord x, coord y, coord tex_s, coord tex_t)
1159
+ const Matrix&
1160
+ Painter::matrix () const
988
1161
  {
989
- return add_vertex(x, y, 0, tex_s, tex_t);
1162
+ glGetFloatv(GL_MODELVIEW_MATRIX, self->matrix_tmp.array);
1163
+ check_error(__FILE__, __LINE__);
1164
+ return self->matrix_tmp;
990
1165
  }
991
1166
 
992
- bool
993
- Painter::add_vertex (coord x, coord y, coord z, coord tex_s, coord tex_t)
1167
+ void
1168
+ Painter::push_matrix ()
994
1169
  {
995
- if (!self->drawing) return false;
996
-
997
- glTexCoord2f(tex_s, tex_t);
998
- return add_vertex(x, y, z);
1170
+ glPushMatrix();
1171
+ check_error(__FILE__, __LINE__);
999
1172
  }
1000
1173
 
1001
- bool
1002
- Painter::add_vertex (const Point& pos, coord tex_s, coord tex_t)
1174
+ void
1175
+ Painter::pop_matrix ()
1003
1176
  {
1004
- return add_vertex(pos.x, pos.y, pos.z, tex_s, tex_t);
1177
+ glPopMatrix();
1178
+ check_error(__FILE__, __LINE__);
1005
1179
  }
1006
1180
 
1007
1181