rays 0.1.28 → 0.1.29
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.doc/ext/rays/exception.cpp +45 -0
- data/.doc/ext/rays/native.cpp +2 -0
- data/.doc/ext/rays/shader.cpp +100 -6
- data/VERSION +1 -1
- data/ext/rays/defs.h +1 -0
- data/ext/rays/exception.cpp +45 -0
- data/ext/rays/native.cpp +2 -0
- data/ext/rays/shader.cpp +101 -5
- data/include/rays/exception.h +11 -0
- data/include/rays/ruby/bitmap.h +0 -1
- data/include/rays/ruby/bounds.h +0 -2
- data/include/rays/ruby/camera.h +0 -1
- data/include/rays/ruby/color.h +0 -2
- data/include/rays/ruby/color_space.h +0 -1
- data/include/rays/ruby/defs.h +30 -0
- data/include/rays/ruby/exception.h +28 -0
- data/include/rays/ruby/font.h +0 -1
- data/include/rays/ruby/image.h +0 -1
- data/include/rays/ruby/matrix.h +0 -1
- data/include/rays/ruby/painter.h +0 -1
- data/include/rays/ruby/point.h +0 -2
- data/include/rays/ruby/polygon.h +0 -1
- data/include/rays/ruby/polyline.h +0 -1
- data/include/rays/ruby/rays.h +0 -1
- data/include/rays/ruby/shader.h +0 -1
- data/include/rays/ruby.h +2 -0
- data/include/rays/shader.h +48 -1
- data/lib/rays/painter.rb +6 -5
- data/lib/rays/point.rb +1 -0
- data/lib/rays/shader.rb +18 -5
- data/rays.gemspec +2 -2
- data/src/exception.cpp +13 -0
- data/src/image.cpp +6 -4
- data/src/opengl.cpp +21 -7
- data/src/opengl.h +5 -3
- data/src/osx/font.mm +0 -2
- data/src/osx/opengl.mm +17 -2
- data/src/painter.cpp +196 -125
- data/src/shader.cpp +333 -53
- data/src/shader.h +53 -14
- data/src/shader_program.cpp +53 -27
- data/src/shader_program.h +8 -1
- data/src/shader_source.cpp +2 -2
- data/src/texture.cpp +75 -63
- data/test/test_point.rb +6 -5
- data/test/test_rays.rb +2 -2
- data/test/test_shader.rb +151 -14
- 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
|
-
|
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 =
|
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
|
-
|
351
|
-
|
352
|
-
|
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
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
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
|
344
|
+
const ShaderProgram& program, const ShaderBuiltinVariableNames& names,
|
345
|
+
const TextureInfo* texinfo)
|
393
346
|
{
|
394
|
-
|
395
|
-
|
396
|
-
|
347
|
+
const Texture* texture = texinfo ? &texinfo->texture : NULL;
|
348
|
+
|
349
|
+
Matrix texcoord_matrix(1);
|
350
|
+
if (texture && *texture)
|
397
351
|
{
|
398
|
-
|
399
|
-
|
400
|
-
|
352
|
+
texcoord_matrix.scale(
|
353
|
+
1.0 / texture->reserved_width(),
|
354
|
+
1.0 / texture->reserved_height());
|
401
355
|
}
|
402
356
|
|
403
|
-
|
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
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
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
|
-
|
414
|
-
}
|
370
|
+
if (!texinfo || !texture || !*texture) return;
|
415
371
|
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
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
|
-
|
399
|
+
glBindTexture(GL_TEXTURE_2D, texture->id());
|
400
|
+
OpenGL_check_error(__FILE__, __LINE__);
|
422
401
|
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
glActiveTexture(GL_TEXTURE0);
|
428
|
-
glBindTexture(GL_TEXTURE_2D, texture.id());
|
402
|
+
glUniform1i(loc, 0);
|
403
|
+
});
|
404
|
+
}
|
405
|
+
}
|
429
406
|
|
430
|
-
|
431
|
-
|
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
|
-
|
435
|
-
|
436
|
-
|
444
|
+
draw_fun();
|
445
|
+
|
446
|
+
for (auto loc : locations)
|
437
447
|
{
|
438
|
-
|
439
|
-
size_loc, texture.reserved_width(), texture.reserved_height());
|
448
|
+
glDisableVertexAttribArray(loc);
|
440
449
|
OpenGL_check_error(__FILE__, __LINE__);
|
441
450
|
}
|
442
451
|
|
443
|
-
|
444
|
-
|
445
|
-
|
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
|
-
|
448
|
-
|
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
|
-
|
452
|
-
|
453
|
-
|
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
|
-
|
456
|
-
|
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
|
-
|
461
|
-
|
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
|
-
|
540
|
+
GLuint id = create_buffer();
|
541
|
+
size_t size = sizeof(CoordN) * nvalues;
|
466
542
|
|
467
|
-
|
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
|
-
|
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
|
-
|
549
|
+
return id;
|
480
550
|
}
|
481
551
|
|
482
|
-
|
552
|
+
GLuint create_buffer ()
|
483
553
|
{
|
484
|
-
|
485
|
-
|
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 =
|
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 = &
|
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, &
|
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
|
}
|