rays 0.1.6 → 0.1.7

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