rays 0.1.27 → 0.1.29

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/.doc/ext/rays/exception.cpp +45 -0
  3. data/.doc/ext/rays/native.cpp +2 -0
  4. data/.doc/ext/rays/painter.cpp +7 -2
  5. data/.doc/ext/rays/shader.cpp +100 -6
  6. data/VERSION +1 -1
  7. data/ext/rays/defs.h +1 -0
  8. data/ext/rays/exception.cpp +45 -0
  9. data/ext/rays/native.cpp +2 -0
  10. data/ext/rays/painter.cpp +7 -2
  11. data/ext/rays/shader.cpp +101 -5
  12. data/include/rays/exception.h +11 -0
  13. data/include/rays/ruby/bitmap.h +0 -1
  14. data/include/rays/ruby/bounds.h +0 -2
  15. data/include/rays/ruby/camera.h +0 -1
  16. data/include/rays/ruby/color.h +0 -2
  17. data/include/rays/ruby/color_space.h +0 -1
  18. data/include/rays/ruby/defs.h +30 -0
  19. data/include/rays/ruby/exception.h +28 -0
  20. data/include/rays/ruby/font.h +0 -1
  21. data/include/rays/ruby/image.h +0 -1
  22. data/include/rays/ruby/matrix.h +0 -1
  23. data/include/rays/ruby/painter.h +0 -1
  24. data/include/rays/ruby/point.h +0 -2
  25. data/include/rays/ruby/polygon.h +0 -1
  26. data/include/rays/ruby/polyline.h +0 -1
  27. data/include/rays/ruby/rays.h +0 -1
  28. data/include/rays/ruby/shader.h +0 -1
  29. data/include/rays/ruby.h +2 -0
  30. data/include/rays/shader.h +48 -1
  31. data/lib/rays/painter.rb +6 -5
  32. data/lib/rays/point.rb +1 -0
  33. data/lib/rays/shader.rb +18 -5
  34. data/rays.gemspec +2 -2
  35. data/src/exception.cpp +13 -0
  36. data/src/image.cpp +6 -4
  37. data/src/ios/bitmap.mm +18 -1
  38. data/src/opengl.cpp +21 -7
  39. data/src/opengl.h +5 -3
  40. data/src/osx/bitmap.mm +18 -1
  41. data/src/osx/font.mm +0 -2
  42. data/src/osx/opengl.mm +17 -2
  43. data/src/painter.cpp +196 -125
  44. data/src/shader.cpp +333 -53
  45. data/src/shader.h +53 -14
  46. data/src/shader_program.cpp +53 -27
  47. data/src/shader_program.h +8 -1
  48. data/src/shader_source.cpp +2 -2
  49. data/src/texture.cpp +75 -63
  50. data/test/test_image.rb +45 -10
  51. data/test/test_painter.rb +26 -4
  52. data/test/test_point.rb +6 -5
  53. data/test/test_rays.rb +2 -2
  54. data/test/test_shader.rb +151 -14
  55. metadata +11 -6
data/src/painter.cpp CHANGED
@@ -6,6 +6,7 @@
6
6
  #include <memory>
7
7
  #include <vector>
8
8
  #include <algorithm>
9
+ #include <functional>
9
10
  #include <glm/gtc/matrix_transform.hpp>
10
11
  #include "rays/exception.h"
11
12
  #include "rays/point.h"
@@ -93,7 +94,7 @@ namespace Rays
93
94
 
94
95
  const Texture& texture;
95
96
 
96
- Coord2 texcoord_min, texcoord_max;
97
+ Point texcoord_min, texcoord_max;
97
98
 
98
99
  TextureInfo (
99
100
  const Texture& texture,
@@ -236,33 +237,6 @@ namespace Rays
236
237
  return GL_FLOAT;
237
238
  }
238
239
 
239
- static const Shader&
240
- get_default_shader_for_shape ()
241
- {
242
- static const Shader SHADER(
243
- "varying vec4 " VARYING_COLOR ";"
244
- "void main ()"
245
- "{"
246
- " gl_FragColor = v_Color;"
247
- "}");
248
- return SHADER;
249
- }
250
-
251
- static const Shader&
252
- get_default_shader_for_texture ()
253
- {
254
- static const Shader SHADER(
255
- "varying vec4 " VARYING_TEXCOORD ";"
256
- "varying vec4 " VARYING_COLOR ";"
257
- "vec4 sampleTexture(vec2);"
258
- "void main ()"
259
- "{"
260
- " vec4 color = sampleTexture(" VARYING_TEXCOORD ".xy);"
261
- " gl_FragColor = v_Color * color;"
262
- "}");
263
- return SHADER;
264
- }
265
-
266
240
 
267
241
  struct Painter::Data
268
242
  {
@@ -338,7 +312,7 @@ namespace Rays
338
312
  const Coord3* points, size_t npoints,
339
313
  const uint* indices = NULL, size_t nindices = 0,
340
314
  const Coord3* texcoords = NULL,
341
- const Shader& default_shader = get_default_shader_for_shape(),
315
+ const Shader& default_shader = Shader_get_default_shader_for_shape(),
342
316
  const TextureInfo* texinfo = NULL)
343
317
  {
344
318
  if (!points || npoints <= 0)
@@ -347,143 +321,240 @@ namespace Rays
347
321
  if (!painting)
348
322
  invalid_state_error(__FILE__, __LINE__, "'painting' should be true.");
349
323
 
350
- if (!indices || nindices <= 0)
351
- {
352
- default_indices.resize(npoints);
353
- indices = default_indices.get();
354
- nindices = npoints;
355
- }
356
-
357
- if (!texcoords)
358
- texcoords = points;
359
-
360
- const ShaderProgram* program = Shader_get_program(state.shader);
361
- if (!program || !*program)
362
- {
363
- program = Shader_get_program(default_shader);
364
- if (!program || !*program) return;
365
- }
324
+ const Shader& shader = state.shader ? state.shader : default_shader;
325
+ const ShaderProgram* program = Shader_get_program(shader);
326
+ if (!program || !*program) return;
366
327
 
367
328
  ShaderProgram_activate(*program);
368
- apply_builtin_uniforms(*program, texinfo);
369
329
 
370
- GLint a_position = glGetAttribLocation(program->id(), ATTRIB_POSITION);
371
- GLint a_texcoord = glGetAttribLocation(program->id(), ATTRIB_TEXCOORD);
372
- GLint a_color = glGetAttribLocation(program->id(), ATTRIB_COLOR);
373
- if (a_position < 0 || a_texcoord < 0 || a_color < 0)
374
- opengl_error(__FILE__, __LINE__);
375
-
376
- setup_vertices(
377
- points, npoints, texcoords, color, a_position, a_texcoord, a_color);
378
- //activate_texture(texture);
379
-
380
- glDrawElements(mode, (GLsizei) nindices, GL_UNSIGNED_INT, indices);
381
- OpenGL_check_error(__FILE__, __LINE__);
382
-
383
- //deactivate_texture(texture);
384
- cleanup_vertices(a_position, a_texcoord);
330
+ const auto& names = Shader_get_builtin_variable_names(shader);
331
+ apply_builtin_uniforms(*program, names, texinfo);
332
+ apply_attributes(*program, names, points, npoints, texcoords, color, [&]() {
333
+ draw_indices(mode, indices, nindices, npoints);
334
+ });
385
335
 
386
336
  ShaderProgram_deactivate();
387
337
  }
388
338
 
389
339
  private:
390
340
 
341
+ typedef std::vector<GLint> LocationList;
342
+
391
343
  void apply_builtin_uniforms (
392
- const ShaderProgram& program, const TextureInfo* texinfo)
344
+ const ShaderProgram& program, const ShaderBuiltinVariableNames& names,
345
+ const TextureInfo* texinfo)
393
346
  {
394
- GLint pos_matrix_loc =
395
- glGetUniformLocation(program.id(), UNIFORM_POSITION_MATRIX);
396
- if (pos_matrix_loc >= 0)
347
+ const Texture* texture = texinfo ? &texinfo->texture : NULL;
348
+
349
+ Matrix texcoord_matrix(1);
350
+ if (texture && *texture)
397
351
  {
398
- glUniformMatrix4fv(
399
- pos_matrix_loc, 1, GL_FALSE, position_matrix.array);
400
- OpenGL_check_error(__FILE__, __LINE__);
352
+ texcoord_matrix.scale(
353
+ 1.0 / texture->reserved_width(),
354
+ 1.0 / texture->reserved_height());
401
355
  }
402
356
 
403
- GLint texcoord_matrix_loc =
404
- glGetUniformLocation(program.id(), UNIFORM_TEXCOORD_MATRIX);
405
- if (texcoord_matrix_loc >= 0)
357
+ for (const auto& name : names.uniform_position_matrix_names)
406
358
  {
407
- static const Matrix TEXCOORD_MATRIX(1);
408
- glUniformMatrix4fv(
409
- texcoord_matrix_loc, 1, GL_FALSE, TEXCOORD_MATRIX.array);
410
- OpenGL_check_error(__FILE__, __LINE__);
359
+ apply_uniform(program, name, [&](GLint loc) {
360
+ glUniformMatrix4fv(loc, 1, GL_FALSE, position_matrix.array);
361
+ });
362
+ }
363
+ for (const auto& name : names.uniform_texcoord_matrix_names)
364
+ {
365
+ apply_uniform(program, name, [&](GLint loc) {
366
+ glUniformMatrix4fv(loc, 1, GL_FALSE, texcoord_matrix.array);
367
+ });
411
368
  }
412
369
 
413
- apply_texture_uniforms(program, texinfo);
414
- }
370
+ if (!texinfo || !texture || !*texture) return;
415
371
 
416
- void apply_texture_uniforms (
417
- const ShaderProgram& program, const TextureInfo* texinfo)
418
- {
419
- if (!texinfo || !*texinfo) return;
372
+ for (const auto& name : names.uniform_texcoord_min_names)
373
+ {
374
+ apply_uniform(program, name, [&](GLint loc) {
375
+ Point min = texcoord_matrix * texinfo->texcoord_min;
376
+ glUniform3fv(loc, 1, min.array);
377
+ });
378
+ }
379
+ for (const auto& name : names.uniform_texcoord_max_names)
380
+ {
381
+ apply_uniform(program, name, [&](GLint loc) {
382
+ Point max = texcoord_matrix * texinfo->texcoord_max;
383
+ glUniform3fv(loc, 1, max.array);
384
+ });
385
+ }
386
+ for (const auto& name : names.uniform_texcoord_offset_names)
387
+ {
388
+ apply_uniform(program, name, [&](GLint loc) {
389
+ Point offset(1.0 / texture->width(), 1.0 / texture->height());
390
+ glUniform3fv(loc, 1, offset.array);
391
+ });
392
+ }
393
+ for (const auto& name : names.uniform_texture_names)
394
+ {
395
+ apply_uniform(program, name, [&](GLint loc) {
396
+ glActiveTexture(GL_TEXTURE0);
397
+ OpenGL_check_error(__FILE__, __LINE__);
420
398
 
421
- const Texture& texture = texinfo->texture;
399
+ glBindTexture(GL_TEXTURE_2D, texture->id());
400
+ OpenGL_check_error(__FILE__, __LINE__);
422
401
 
423
- GLint texture_loc =
424
- glGetUniformLocation(program.id(), UNIFORM_TEXTURE);
425
- if (texture_loc >= 0)
426
- {
427
- glActiveTexture(GL_TEXTURE0);
428
- glBindTexture(GL_TEXTURE_2D, texture.id());
402
+ glUniform1i(loc, 0);
403
+ });
404
+ }
405
+ }
429
406
 
430
- glUniform1i(texture_loc, 0);
431
- OpenGL_check_error(__FILE__, __LINE__);
407
+ void apply_attributes (
408
+ const ShaderProgram& program, const ShaderBuiltinVariableNames& names,
409
+ const Coord3* points, size_t npoints, const Coord3* texcoords, const Color& color,
410
+ std::function<void()> draw_fun)
411
+ {
412
+ assert(points && npoints > 0);
413
+
414
+ std::vector<GLuint> buffers;
415
+ LocationList locations;
416
+
417
+ apply_attribute(
418
+ &buffers, &locations,
419
+ program, names.attribute_position_names,
420
+ points, npoints);
421
+
422
+ apply_attribute(
423
+ &buffers, &locations,
424
+ program, names.attribute_texcoord_names,
425
+ texcoords ? texcoords : points, npoints);
426
+
427
+ #if defined(GL_VERSION_2_1) && !defined(GL_VERSION_3_0)
428
+ // to fix that GL 2.1 with glVertexAttrib4fv() draws nothing
429
+ // with specific glsl 'attribute' name.
430
+ std::vector<Color> colors(npoints, color);
431
+ apply_attribute(
432
+ &buffers, &locations,
433
+ program, names.attribute_color_names,
434
+ (const Coord4*) &colors[0], npoints);
435
+ #else
436
+ for (const auto& name : names.attribute_color_names)
437
+ {
438
+ apply_attribute(NULL, program, name, [&](GLint loc) {
439
+ glVertexAttrib4fv(loc, color.array);
440
+ });
432
441
  }
442
+ #endif
433
443
 
434
- GLint size_loc =
435
- glGetUniformLocation(program.id(), UNIFORM_TEXTURE_SIZE);
436
- if (size_loc >= 0)
444
+ draw_fun();
445
+
446
+ for (auto loc : locations)
437
447
  {
438
- glUniform2f(
439
- size_loc, texture.reserved_width(), texture.reserved_height());
448
+ glDisableVertexAttribArray(loc);
440
449
  OpenGL_check_error(__FILE__, __LINE__);
441
450
  }
442
451
 
443
- GLint min_loc =
444
- glGetUniformLocation(program.id(), UNIFORM_TEXCOORD_MIN);
445
- if (min_loc >= 0)
452
+ glDeleteBuffers((GLsizei) buffers.size(), &buffers[0]);
453
+ OpenGL_check_error(__FILE__, __LINE__);
454
+ }
455
+
456
+ template <typename CoordN>
457
+ void apply_attribute(
458
+ auto* buffers, LocationList* locations,
459
+ const ShaderProgram& program, const auto& names,
460
+ const CoordN* values, size_t nvalues)
461
+ {
462
+ assert(buffers);
463
+
464
+ GLuint buffer = 0;
465
+ for (const auto& name : names)
446
466
  {
447
- glUniform2fv(min_loc, 1, texinfo->texcoord_min.array);
448
- OpenGL_check_error(__FILE__, __LINE__);
467
+ apply_attribute(locations, program, name, [&](GLint loc) {
468
+ if (buffer == 0)
469
+ {
470
+ buffer = create_and_bind_coordn_buffer(values, nvalues);
471
+ buffers->push_back(buffer);
472
+ }
473
+
474
+ glEnableVertexAttribArray(loc);
475
+ OpenGL_check_error(__FILE__, __LINE__, "loc: %d %s\n", loc, name.c_str());
476
+
477
+ glVertexAttribPointer(
478
+ loc, CoordN::SIZE, get_gl_type<coord>(),
479
+ GL_FALSE, sizeof(CoordN), NULL);
480
+ });
449
481
  }
450
482
 
451
- GLint max_loc =
452
- glGetUniformLocation(program.id(), UNIFORM_TEXCOORD_MAX);
453
- if (max_loc >= 0)
483
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
484
+ OpenGL_check_error(__FILE__, __LINE__);
485
+ }
486
+
487
+ void apply_attribute (
488
+ LocationList* locations, const ShaderProgram& program, const char* name,
489
+ std::function<void(GLint)> apply)
490
+ {
491
+ GLint loc = glGetAttribLocation(program.id(), name);
492
+ if (loc < 0) return;
493
+
494
+ apply(loc);
495
+ OpenGL_check_error(__FILE__, __LINE__);
496
+
497
+ if (locations) locations->push_back(loc);
498
+ }
499
+
500
+ void apply_uniform (
501
+ const ShaderProgram& program, const char* name,
502
+ std::function<void(GLint)> apply)
503
+ {
504
+ GLint loc = glGetUniformLocation(program.id(), name);
505
+ if (loc < 0) return;
506
+
507
+ apply(loc);
508
+ OpenGL_check_error(__FILE__, __LINE__);
509
+ }
510
+
511
+ void draw_indices (
512
+ GLenum mode, const uint* indices, size_t nindices, size_t npoints)
513
+ {
514
+ if (!indices || nindices <= 0)
454
515
  {
455
- glUniform2fv(max_loc, 1, texinfo->texcoord_max.array);
456
- OpenGL_check_error(__FILE__, __LINE__);
516
+ default_indices.resize(npoints);
517
+ indices = default_indices.get();
518
+ nindices = npoints;
457
519
  }
520
+
521
+ GLuint buffer = create_buffer();
522
+ size_t size = sizeof(uint) * nindices;
523
+
524
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
525
+ OpenGL_check_error(__FILE__, __LINE__);
526
+
527
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, indices, GL_STREAM_DRAW);
528
+ OpenGL_check_error(__FILE__, __LINE__);
529
+
530
+ glDrawElements(mode, (GLsizei) nindices, GL_UNSIGNED_INT, NULL);
531
+ OpenGL_check_error(__FILE__, __LINE__);
532
+
533
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
534
+ OpenGL_check_error(__FILE__, __LINE__);
458
535
  }
459
536
 
460
- void setup_vertices (
461
- const Coord3* points, size_t npoints,
462
- const Coord3* texcoords, const Color& color,
463
- GLuint a_position, GLuint a_texcoord, GLuint a_color)
537
+ template <typename CoordN>
538
+ GLuint create_and_bind_coordn_buffer (const CoordN* values, size_t nvalues)
464
539
  {
465
- assert(points && npoints >= 0 && texcoords);
540
+ GLuint id = create_buffer();
541
+ size_t size = sizeof(CoordN) * nvalues;
466
542
 
467
- glEnableVertexAttribArray(a_position);
468
- glVertexAttribPointer(
469
- a_position, Coord3::SIZE, get_gl_type<coord>(),
470
- GL_FALSE, sizeof(Coord3), points);
543
+ glBindBuffer(GL_ARRAY_BUFFER, id);
471
544
  OpenGL_check_error(__FILE__, __LINE__);
472
545
 
473
- glEnableVertexAttribArray(a_texcoord);
474
- glVertexAttribPointer(
475
- a_texcoord, Coord3::SIZE, get_gl_type<coord>(),
476
- GL_FALSE, sizeof(Coord3), texcoords);
546
+ glBufferData(GL_ARRAY_BUFFER, size, values, GL_STREAM_DRAW);
477
547
  OpenGL_check_error(__FILE__, __LINE__);
478
548
 
479
- glVertexAttrib4fv(a_color, color.array);
549
+ return id;
480
550
  }
481
551
 
482
- void cleanup_vertices (GLint a_position, GLint a_texcoord)
552
+ GLuint create_buffer ()
483
553
  {
484
- glDisableVertexAttribArray(a_position);
485
- glDisableVertexAttribArray(a_texcoord);
554
+ GLuint id;
555
+ glGenBuffers(1, &id);
486
556
  OpenGL_check_error(__FILE__, __LINE__);
557
+ return id;
487
558
  }
488
559
 
489
560
  void activate_texture (const Texture* texture)
@@ -530,7 +601,7 @@ namespace Rays
530
601
  const Coord3* points, size_t npoints,
531
602
  const uint* indices = NULL, size_t nindices = 0,
532
603
  const Coord3* texcoords = NULL,
533
- const Shader& default_shader = get_default_shader_for_shape(),
604
+ const Shader& default_shader = Shader_get_default_shader_for_shape(),
534
605
  const TextureInfo* texinfo = NULL)
535
606
  {
536
607
  assert(painter);
@@ -958,7 +1029,7 @@ namespace Rays
958
1029
  TextureInfo texinfo(texture, src_x, src_y, src_x + src_w, src_y + src_h);
959
1030
 
960
1031
  if (!shader)
961
- shader = &get_default_shader_for_texture();
1032
+ shader = &Shader_get_default_shader_for_texture();
962
1033
 
963
1034
  draw_polygon(
964
1035
  painter, MODES, 0, 0, false, nostroke, points, 4, NULL, 0, texcoords,
@@ -1135,7 +1206,7 @@ namespace Rays
1135
1206
  painter, self->text_image,
1136
1207
  0, 0, str_w, str_h,
1137
1208
  x, y, str_w, str_h,
1138
- true, &get_default_shader_for_texture());
1209
+ true, &Shader_get_shader_for_text());
1139
1210
 
1140
1211
  debug_draw_text(painter, font, x, y, str_w / density, str_h / density);
1141
1212
  }