rays 0.1.28 → 0.1.29

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) 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/shader.cpp +100 -6
  5. data/VERSION +1 -1
  6. data/ext/rays/defs.h +1 -0
  7. data/ext/rays/exception.cpp +45 -0
  8. data/ext/rays/native.cpp +2 -0
  9. data/ext/rays/shader.cpp +101 -5
  10. data/include/rays/exception.h +11 -0
  11. data/include/rays/ruby/bitmap.h +0 -1
  12. data/include/rays/ruby/bounds.h +0 -2
  13. data/include/rays/ruby/camera.h +0 -1
  14. data/include/rays/ruby/color.h +0 -2
  15. data/include/rays/ruby/color_space.h +0 -1
  16. data/include/rays/ruby/defs.h +30 -0
  17. data/include/rays/ruby/exception.h +28 -0
  18. data/include/rays/ruby/font.h +0 -1
  19. data/include/rays/ruby/image.h +0 -1
  20. data/include/rays/ruby/matrix.h +0 -1
  21. data/include/rays/ruby/painter.h +0 -1
  22. data/include/rays/ruby/point.h +0 -2
  23. data/include/rays/ruby/polygon.h +0 -1
  24. data/include/rays/ruby/polyline.h +0 -1
  25. data/include/rays/ruby/rays.h +0 -1
  26. data/include/rays/ruby/shader.h +0 -1
  27. data/include/rays/ruby.h +2 -0
  28. data/include/rays/shader.h +48 -1
  29. data/lib/rays/painter.rb +6 -5
  30. data/lib/rays/point.rb +1 -0
  31. data/lib/rays/shader.rb +18 -5
  32. data/rays.gemspec +2 -2
  33. data/src/exception.cpp +13 -0
  34. data/src/image.cpp +6 -4
  35. data/src/opengl.cpp +21 -7
  36. data/src/opengl.h +5 -3
  37. data/src/osx/font.mm +0 -2
  38. data/src/osx/opengl.mm +17 -2
  39. data/src/painter.cpp +196 -125
  40. data/src/shader.cpp +333 -53
  41. data/src/shader.h +53 -14
  42. data/src/shader_program.cpp +53 -27
  43. data/src/shader_program.h +8 -1
  44. data/src/shader_source.cpp +2 -2
  45. data/src/texture.cpp +75 -63
  46. data/test/test_point.rb +6 -5
  47. data/test/test_rays.rb +2 -2
  48. data/test/test_shader.rb +151 -14
  49. 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
  }