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.
- checksums.yaml +4 -4
- data/.doc/ext/rays/exception.cpp +45 -0
- data/.doc/ext/rays/native.cpp +2 -0
- data/.doc/ext/rays/painter.cpp +7 -2
- 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/painter.cpp +7 -2
- 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/ios/bitmap.mm +18 -1
- data/src/opengl.cpp +21 -7
- data/src/opengl.h +5 -3
- data/src/osx/bitmap.mm +18 -1
- 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_image.rb +45 -10
- data/test/test_painter.rb +26 -4
- 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/shader.cpp
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#include "shader.h"
|
2
2
|
|
3
3
|
|
4
|
+
#include <regex>
|
4
5
|
#include "rays/exception.h"
|
5
6
|
#include "opengl.h"
|
6
7
|
#include "image.h"
|
@@ -12,54 +13,21 @@ namespace Rays
|
|
12
13
|
{
|
13
14
|
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
" vec4 pos = vec4(" ATTRIB_POSITION ", 1.0);"
|
31
|
-
" vec4 texcoord = vec4(" ATTRIB_TEXCOORD ", 1.0);"
|
32
|
-
VARYING_POSITION " = pos;"
|
33
|
-
VARYING_TEXCOORD " = " UNIFORM_TEXCOORD_MATRIX " * texcoord;"
|
34
|
-
VARYING_COLOR " = " ATTRIB_COLOR ";"
|
35
|
-
" gl_Position = " UNIFORM_POSITION_MATRIX " * pos;"
|
36
|
-
"}");
|
37
|
-
return SOURCE;
|
38
|
-
}
|
39
|
-
|
40
|
-
static ShaderSource
|
41
|
-
make_fragment_shader_source (const char* source)
|
42
|
-
{
|
43
|
-
static String SHARED_HEADER =
|
44
|
-
"#ifdef GL_ES\n"
|
45
|
-
"precision mediump float;\n"
|
46
|
-
"#endif\n"
|
47
|
-
"uniform sampler2D " UNIFORM_TEXTURE ";"
|
48
|
-
"uniform vec2 " UNIFORM_TEXTURE_SIZE ";"
|
49
|
-
"uniform vec2 " UNIFORM_TEXCOORD_MIN ";"
|
50
|
-
"uniform vec2 " UNIFORM_TEXCOORD_MAX ";"
|
51
|
-
"vec2 normalizeTexCoord(vec2 texcoord)"
|
52
|
-
"{"
|
53
|
-
" vec2 min = " UNIFORM_TEXCOORD_MIN ";"
|
54
|
-
" vec2 len = " UNIFORM_TEXCOORD_MAX " - min;"
|
55
|
-
" return (mod(texcoord - min, len) + min) / " UNIFORM_TEXTURE_SIZE ";"
|
56
|
-
"}"
|
57
|
-
"vec4 sampleTexture(vec2 texcoord)"
|
58
|
-
"{"
|
59
|
-
" return texture2D(" UNIFORM_TEXTURE ", normalizeTexCoord(texcoord));"
|
60
|
-
"}\n";
|
61
|
-
return ShaderSource(GL_FRAGMENT_SHADER, SHARED_HEADER + source);
|
62
|
-
}
|
16
|
+
#define A_POSITION (names.attribute_position_names[0])
|
17
|
+
#define A_TEXCOORD (names.attribute_texcoord_names[0])
|
18
|
+
#define A_COLOR (names.attribute_color_names[0])
|
19
|
+
#define V_POSITION (names.varying_position_name)
|
20
|
+
#define V_TEXCOORD (names.varying_texcoord_name)
|
21
|
+
#define V_COLOR (names.varying_color_name)
|
22
|
+
#define U_POSITION_MATRIX (names.uniform_position_matrix_names[0])
|
23
|
+
#define U_TEXCOORD_MATRIX (names.uniform_texcoord_matrix_names[0])
|
24
|
+
#define U_TEXCOORD_MIN (names.uniform_texcoord_min_names[0])
|
25
|
+
#define U_TEXCOORD_MAX (names.uniform_texcoord_max_names[0])
|
26
|
+
#define U_TEXCOORD_OFFSET (names.uniform_texcoord_offset_names[0])
|
27
|
+
#define U_TEXTURE (names.uniform_texture_names[0])
|
28
|
+
|
29
|
+
|
30
|
+
static ShaderEnv DEFAULT_ENV;
|
63
31
|
|
64
32
|
|
65
33
|
struct Shader::Data
|
@@ -67,23 +35,157 @@ namespace Rays
|
|
67
35
|
|
68
36
|
std::unique_ptr<ShaderProgram> program;
|
69
37
|
|
38
|
+
std::unique_ptr<ShaderEnv> env;
|
39
|
+
|
40
|
+
Data (
|
41
|
+
const char* fragment_shader_source,
|
42
|
+
const char* vertex_shader_source,
|
43
|
+
ShaderEnv* env_)
|
44
|
+
{
|
45
|
+
if (!fragment_shader_source) return;
|
46
|
+
|
47
|
+
if (env_)
|
48
|
+
this->env.reset(new ShaderEnv(*env_));
|
49
|
+
|
50
|
+
program.reset(new ShaderProgram(
|
51
|
+
make_vertex_shader_source(vertex_shader_source),
|
52
|
+
make_fragment_shader_source(fragment_shader_source),
|
53
|
+
env_ ? ShaderEnv_get_flags(*env_) : 0));
|
54
|
+
}
|
55
|
+
|
56
|
+
ShaderSource make_vertex_shader_source (const char* source)
|
57
|
+
{
|
58
|
+
if (source)
|
59
|
+
return ShaderSource(GL_VERTEX_SHADER, source);
|
60
|
+
else
|
61
|
+
{
|
62
|
+
return ShaderEnv_get_default_vertex_shader_source(
|
63
|
+
env ? env.get() : &DEFAULT_ENV);
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
ShaderSource make_fragment_shader_source (const char* source)
|
68
|
+
{
|
69
|
+
#ifdef IOS
|
70
|
+
static const String SHARED_HEADER = "precision mediump float;\n";
|
71
|
+
static const std::regex PRECISION(R"(^\s*precision\s+\w+p\s+float\s*;)");
|
72
|
+
|
73
|
+
if (!std::regex_search(source, PRECISION))
|
74
|
+
return ShaderSource(GL_FRAGMENT_SHADER, SHARED_HEADER + source);
|
75
|
+
else
|
76
|
+
return ShaderSource(GL_FRAGMENT_SHADER, source);
|
77
|
+
#else
|
78
|
+
return ShaderSource(GL_FRAGMENT_SHADER, source);
|
79
|
+
#endif
|
80
|
+
}
|
81
|
+
|
70
82
|
};// Shader::Data
|
71
83
|
|
72
84
|
|
85
|
+
static Shader
|
86
|
+
make_default_shader_for_shape ()
|
87
|
+
{
|
88
|
+
const ShaderBuiltinVariableNames& names =
|
89
|
+
ShaderEnv_get_builtin_variable_names(DEFAULT_ENV);
|
90
|
+
return Shader(
|
91
|
+
"varying vec4 " + V_COLOR + ";\n"
|
92
|
+
"void main ()\n"
|
93
|
+
"{\n"
|
94
|
+
" gl_FragColor = " + V_COLOR + ";\n"
|
95
|
+
"}\n");
|
96
|
+
}
|
97
|
+
|
98
|
+
static Shader
|
99
|
+
make_default_shader_for_texture ()
|
100
|
+
{
|
101
|
+
const ShaderBuiltinVariableNames& names =
|
102
|
+
ShaderEnv_get_builtin_variable_names(DEFAULT_ENV);
|
103
|
+
return Shader(
|
104
|
+
"varying vec4 " + V_TEXCOORD + ";\n"
|
105
|
+
"varying vec4 " + V_COLOR + ";\n"
|
106
|
+
"uniform vec3 " + U_TEXCOORD_MIN + ";\n"
|
107
|
+
"uniform vec3 " + U_TEXCOORD_MAX + ";\n"
|
108
|
+
"uniform sampler2D " + U_TEXTURE + ";\n"
|
109
|
+
"void main ()\n"
|
110
|
+
"{\n"
|
111
|
+
" vec2 min__ = " + U_TEXCOORD_MIN + ".xy;\n"
|
112
|
+
" vec2 len__ = " + U_TEXCOORD_MAX + ".xy - min__;\n"
|
113
|
+
" vec2 texcoord__ = mod(" + V_TEXCOORD + ".xy - min__, len__) + min__;\n"
|
114
|
+
" vec4 color__ = texture2D(" + U_TEXTURE + ", texcoord__);\n"
|
115
|
+
" gl_FragColor = " + V_COLOR + " * color__;\n"
|
116
|
+
"}\n");
|
117
|
+
}
|
118
|
+
|
119
|
+
static Shader
|
120
|
+
make_shader_for_text ()
|
121
|
+
{
|
122
|
+
const ShaderBuiltinVariableNames& names =
|
123
|
+
ShaderEnv_get_builtin_variable_names(DEFAULT_ENV);
|
124
|
+
return Shader(
|
125
|
+
"varying vec4 " + V_TEXCOORD + ";\n"
|
126
|
+
"varying vec4 " + V_COLOR + ";\n"
|
127
|
+
"uniform sampler2D " + U_TEXTURE + ";\n"
|
128
|
+
"void main ()\n"
|
129
|
+
"{\n"
|
130
|
+
" vec4 col__ = texture2D(" + U_TEXTURE + ", " + V_TEXCOORD + ".xy);\n"
|
131
|
+
#ifdef OSX
|
132
|
+
// restore premultiplied rgb values
|
133
|
+
" vec3 rgb__ = col__.a != 0.0 ? col__.rgb / col__.a : col__.rgb;\n"
|
134
|
+
" gl_FragColor = " + V_COLOR + " * vec4(rgb__, col__.a);\n"
|
135
|
+
#else
|
136
|
+
" gl_FragColor = " + V_COLOR + " * col__;\n"
|
137
|
+
#endif
|
138
|
+
"}\n");
|
139
|
+
}
|
140
|
+
|
73
141
|
const ShaderProgram*
|
74
142
|
Shader_get_program (const Shader& shader)
|
75
143
|
{
|
76
144
|
return shader.self->program ? shader.self->program.get() : NULL;
|
77
145
|
}
|
78
146
|
|
147
|
+
const ShaderBuiltinVariableNames&
|
148
|
+
Shader_get_builtin_variable_names (const Shader& shader)
|
149
|
+
{
|
150
|
+
return ShaderEnv_get_builtin_variable_names(
|
151
|
+
shader.self->env ? *shader.self->env : DEFAULT_ENV);
|
152
|
+
}
|
153
|
+
|
154
|
+
const Shader&
|
155
|
+
Shader_get_default_shader_for_shape ()
|
156
|
+
{
|
157
|
+
static const Shader SHADER = make_default_shader_for_shape();
|
158
|
+
return SHADER;
|
159
|
+
}
|
160
|
+
|
161
|
+
const Shader&
|
162
|
+
Shader_get_default_shader_for_texture ()
|
163
|
+
{
|
164
|
+
static const Shader SHADER = make_default_shader_for_texture();
|
165
|
+
return SHADER;
|
166
|
+
}
|
167
|
+
|
168
|
+
const Shader&
|
169
|
+
Shader_get_shader_for_text ()
|
170
|
+
{
|
171
|
+
static const Shader SHADER = make_shader_for_text();
|
172
|
+
return SHADER;
|
173
|
+
}
|
79
174
|
|
80
|
-
|
175
|
+
|
176
|
+
Shader::Shader (
|
177
|
+
const char* fragment_shader_source,
|
178
|
+
const char* vertex_shader_source)
|
179
|
+
: self(new Data(fragment_shader_source, vertex_shader_source, NULL))
|
81
180
|
{
|
82
|
-
|
181
|
+
}
|
83
182
|
|
84
|
-
|
85
|
-
|
86
|
-
|
183
|
+
Shader::Shader (
|
184
|
+
const char* fragment_shader_source,
|
185
|
+
const char* vertex_shader_source,
|
186
|
+
ShaderEnv env)
|
187
|
+
: self(new Data(fragment_shader_source, vertex_shader_source, &env))
|
188
|
+
{
|
87
189
|
}
|
88
190
|
|
89
191
|
Shader::~Shader ()
|
@@ -217,6 +319,22 @@ namespace Rays
|
|
217
319
|
self->program->set_uniform(name, Image_get_texture(texture));
|
218
320
|
}
|
219
321
|
|
322
|
+
const char*
|
323
|
+
Shader::vertex_shader_source () const
|
324
|
+
{
|
325
|
+
return self->program
|
326
|
+
? self->program->vertex_shader_source().source()
|
327
|
+
: NULL;
|
328
|
+
}
|
329
|
+
|
330
|
+
const char*
|
331
|
+
Shader::fragment_shader_source () const
|
332
|
+
{
|
333
|
+
return self->program
|
334
|
+
? self->program->fragment_shader_source().source()
|
335
|
+
: NULL;
|
336
|
+
}
|
337
|
+
|
220
338
|
Shader::operator bool () const
|
221
339
|
{
|
222
340
|
return self->program && *self->program;
|
@@ -241,4 +359,166 @@ namespace Rays
|
|
241
359
|
}
|
242
360
|
|
243
361
|
|
362
|
+
struct ShaderEnv::Data
|
363
|
+
{
|
364
|
+
|
365
|
+
ShaderBuiltinVariableNames names;
|
366
|
+
|
367
|
+
uint flags;
|
368
|
+
|
369
|
+
ShaderSource default_vertex_shader_source;
|
370
|
+
|
371
|
+
Data (const ShaderBuiltinVariableNames& names, uint flags)
|
372
|
+
: names(names), flags(flags)
|
373
|
+
{
|
374
|
+
}
|
375
|
+
|
376
|
+
String make_default_vertex_shader_source_code ()
|
377
|
+
{
|
378
|
+
return
|
379
|
+
"attribute vec3 " + A_POSITION + ";\n"
|
380
|
+
"attribute vec3 " + A_TEXCOORD + ";\n"
|
381
|
+
"attribute vec4 " + A_COLOR + ";\n"
|
382
|
+
"varying vec4 " + V_POSITION + ";\n"
|
383
|
+
"varying vec4 " + V_TEXCOORD + ";\n"
|
384
|
+
"varying vec4 " + V_COLOR + ";\n"
|
385
|
+
"uniform mat4 " + U_POSITION_MATRIX + ";\n"
|
386
|
+
"uniform mat4 " + U_TEXCOORD_MATRIX + ";\n"
|
387
|
+
"void main ()\n"
|
388
|
+
"{\n"
|
389
|
+
" vec4 pos__ = vec4(" + A_POSITION + ", 1.0);\n"
|
390
|
+
" vec4 texcoord__ = vec4(" + A_TEXCOORD + ", 1.0);\n"
|
391
|
+
" " + V_POSITION + " = pos__;\n"
|
392
|
+
" " + V_TEXCOORD + " = " + U_TEXCOORD_MATRIX + " * texcoord__;\n"
|
393
|
+
" " + V_COLOR + " = " + A_COLOR + ";\n"
|
394
|
+
" gl_Position = " + U_POSITION_MATRIX + " * pos__;\n"
|
395
|
+
"}\n";
|
396
|
+
}
|
397
|
+
|
398
|
+
};// ShaderEnv::Data
|
399
|
+
|
400
|
+
|
401
|
+
const ShaderBuiltinVariableNames&
|
402
|
+
ShaderEnv_get_builtin_variable_names (const ShaderEnv& env)
|
403
|
+
{
|
404
|
+
return env.self->names;
|
405
|
+
}
|
406
|
+
|
407
|
+
uint
|
408
|
+
ShaderEnv_get_flags (const ShaderEnv& env)
|
409
|
+
{
|
410
|
+
return env.self->flags;
|
411
|
+
}
|
412
|
+
|
413
|
+
const ShaderSource&
|
414
|
+
ShaderEnv_get_default_vertex_shader_source (ShaderEnv* env)
|
415
|
+
{
|
416
|
+
if (!env)
|
417
|
+
argument_error(__FILE__, __LINE__);
|
418
|
+
|
419
|
+
ShaderEnv::Data* self = env->self.get();
|
420
|
+
|
421
|
+
if (!self->default_vertex_shader_source)
|
422
|
+
{
|
423
|
+
self->default_vertex_shader_source = ShaderSource(
|
424
|
+
GL_VERTEX_SHADER, self->make_default_vertex_shader_source_code());
|
425
|
+
}
|
426
|
+
return self->default_vertex_shader_source;
|
427
|
+
}
|
428
|
+
|
429
|
+
|
430
|
+
ShaderEnv::ShaderEnv (
|
431
|
+
const NameList& a_position_names,
|
432
|
+
const NameList& a_texcoord_names,
|
433
|
+
const NameList& a_color_names,
|
434
|
+
const char* v_position_name,
|
435
|
+
const char* v_texcoord_name,
|
436
|
+
const char* v_color_name,
|
437
|
+
const NameList& u_position_matrix_names,
|
438
|
+
const NameList& u_texcoord_matrix_names,
|
439
|
+
const NameList& u_texcoord_min_names,
|
440
|
+
const NameList& u_texcoord_max_names,
|
441
|
+
const NameList& u_texcoord_offset_names,
|
442
|
+
const NameList& u_texture_names,
|
443
|
+
uint flags)
|
444
|
+
: self(new Data(
|
445
|
+
ShaderBuiltinVariableNames(
|
446
|
+
a_position_names, a_texcoord_names, a_color_names,
|
447
|
+
v_position_name, v_texcoord_name, v_color_name,
|
448
|
+
u_position_matrix_names, u_texcoord_matrix_names,
|
449
|
+
u_texcoord_min_names, u_texcoord_max_names, u_texcoord_offset_names,
|
450
|
+
u_texture_names),
|
451
|
+
flags))
|
452
|
+
{
|
453
|
+
}
|
454
|
+
|
455
|
+
|
456
|
+
static void
|
457
|
+
validate_name (const String& name, const char* for_variable)
|
458
|
+
{
|
459
|
+
assert(for_variable);
|
460
|
+
|
461
|
+
if (name.empty())
|
462
|
+
{
|
463
|
+
argument_error(
|
464
|
+
__FILE__, __LINE__,
|
465
|
+
"invalid variable name '%s' for '%s'", name.c_str(), for_variable);
|
466
|
+
}
|
467
|
+
}
|
468
|
+
|
469
|
+
static void
|
470
|
+
validate_names (
|
471
|
+
ShaderEnv::NameList* names,
|
472
|
+
const char* for_variable,
|
473
|
+
const char* default_name)
|
474
|
+
{
|
475
|
+
assert(names && for_variable && default_name);
|
476
|
+
|
477
|
+
if (names->empty()) names->emplace_back(default_name);
|
478
|
+
|
479
|
+
for (const auto& name : *names)
|
480
|
+
validate_name(name, for_variable);
|
481
|
+
}
|
482
|
+
|
483
|
+
ShaderBuiltinVariableNames::ShaderBuiltinVariableNames (
|
484
|
+
const ShaderEnv::NameList& a_position,
|
485
|
+
const ShaderEnv::NameList& a_texcoord,
|
486
|
+
const ShaderEnv::NameList& a_color,
|
487
|
+
const char* v_position,
|
488
|
+
const char* v_texcoord,
|
489
|
+
const char* v_color,
|
490
|
+
const ShaderEnv::NameList& u_position_matrix,
|
491
|
+
const ShaderEnv::NameList& u_texcoord_matrix,
|
492
|
+
const ShaderEnv::NameList& u_texcoord_min,
|
493
|
+
const ShaderEnv::NameList& u_texcoord_max,
|
494
|
+
const ShaderEnv::NameList& u_texcoord_offset,
|
495
|
+
const ShaderEnv::NameList& u_texture)
|
496
|
+
: attribute_position_names(a_position),
|
497
|
+
attribute_texcoord_names(a_texcoord),
|
498
|
+
attribute_color_names(a_color),
|
499
|
+
varying_position_name(v_position ? v_position : "v_Position"),
|
500
|
+
varying_texcoord_name(v_texcoord ? v_texcoord : "v_TexCoord"),
|
501
|
+
varying_color_name( v_color ? v_color : "v_Color"),
|
502
|
+
uniform_position_matrix_names(u_position_matrix),
|
503
|
+
uniform_texcoord_matrix_names(u_texcoord_matrix),
|
504
|
+
uniform_texcoord_min_names(u_texcoord_min),
|
505
|
+
uniform_texcoord_max_names(u_texcoord_max),
|
506
|
+
uniform_texcoord_offset_names(u_texcoord_offset),
|
507
|
+
uniform_texture_names(u_texture)
|
508
|
+
{
|
509
|
+
validate_names(&attribute_position_names, "attribute_position", "a_Position");
|
510
|
+
validate_names(&attribute_texcoord_names, "attribute_texcoord", "a_TexCoord");
|
511
|
+
validate_names(&attribute_color_names, "attribute_color", "a_Color");
|
512
|
+
validate_name(varying_position_name, "varying_position");
|
513
|
+
validate_name(varying_texcoord_name, "varying_texcoord");
|
514
|
+
validate_name(varying_color_name, "varying_color");
|
515
|
+
validate_names(&uniform_position_matrix_names, "uniform_position_matrix", "u_PositionMatrix");
|
516
|
+
validate_names(&uniform_texcoord_matrix_names, "uniform_texcoord_matrix", "u_TexCoordMatrix");
|
517
|
+
validate_names(&uniform_texcoord_min_names, "uniform_texcoord_min", "u_TexCoordMin");
|
518
|
+
validate_names(&uniform_texcoord_max_names, "uniform_texcoord_max", "u_TexCoordMax");
|
519
|
+
validate_names(&uniform_texcoord_offset_names, "uniform_texcoord_offset", "u_TexCoordOffset");
|
520
|
+
validate_names(&uniform_texture_names, "uniform_texture", "u_Texture");
|
521
|
+
}
|
522
|
+
|
523
|
+
|
244
524
|
}// Rays
|
data/src/shader.h
CHANGED
@@ -11,26 +11,65 @@ namespace Rays
|
|
11
11
|
{
|
12
12
|
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
#define UNIFORM_POSITION_MATRIX "u_PositionMatrix"
|
17
|
-
#define ATTRIB_TEXCOORD "a_TexCoord"
|
18
|
-
#define VARYING_TEXCOORD "v_TexCoord"
|
19
|
-
#define UNIFORM_TEXCOORD_MIN "u_TexCoordMin"
|
20
|
-
#define UNIFORM_TEXCOORD_MAX "u_TexCoordMax"
|
21
|
-
#define UNIFORM_TEXCOORD_MATRIX "u_TexCoordMatrix"
|
22
|
-
#define ATTRIB_COLOR "a_Color"
|
23
|
-
#define VARYING_COLOR "v_Color"
|
24
|
-
//#define UNIFORM_COLOR_MATRIX "u_ColorMatrix"
|
25
|
-
#define UNIFORM_TEXTURE "u_Texture"
|
26
|
-
#define UNIFORM_TEXTURE_SIZE "u_TextureSize"
|
14
|
+
class ShaderSource;
|
15
|
+
class ShaderProgram;
|
27
16
|
|
28
17
|
|
29
|
-
|
18
|
+
struct ShaderBuiltinVariableNames
|
19
|
+
{
|
20
|
+
|
21
|
+
ShaderEnv::NameList attribute_position_names;
|
22
|
+
ShaderEnv::NameList attribute_texcoord_names;
|
23
|
+
ShaderEnv::NameList attribute_color_names;
|
24
|
+
|
25
|
+
String varying_position_name;
|
26
|
+
String varying_texcoord_name;
|
27
|
+
String varying_color_name;
|
28
|
+
|
29
|
+
ShaderEnv::NameList uniform_position_matrix_names;
|
30
|
+
ShaderEnv::NameList uniform_texcoord_matrix_names;
|
31
|
+
ShaderEnv::NameList uniform_texcoord_min_names;
|
32
|
+
ShaderEnv::NameList uniform_texcoord_max_names;
|
33
|
+
ShaderEnv::NameList uniform_texcoord_offset_names;
|
34
|
+
ShaderEnv::NameList uniform_texture_names;
|
35
|
+
|
36
|
+
ShaderBuiltinVariableNames (
|
37
|
+
const ShaderEnv::NameList& attribute_position_names,
|
38
|
+
const ShaderEnv::NameList& attribute_texcoord_names,
|
39
|
+
const ShaderEnv::NameList& attribute_color_names,
|
40
|
+
const char* varying_position_name,
|
41
|
+
const char* varying_texcoord_name,
|
42
|
+
const char* varying_color_name,
|
43
|
+
const ShaderEnv::NameList& uniform_position_matrix_names,
|
44
|
+
const ShaderEnv::NameList& uniform_texcoord_matrix_names,
|
45
|
+
const ShaderEnv::NameList& uniform_texcoord_min_names,
|
46
|
+
const ShaderEnv::NameList& uniform_texcoord_max_names,
|
47
|
+
const ShaderEnv::NameList& uniform_texcoord_offset_names,
|
48
|
+
const ShaderEnv::NameList& uniform_texture_names);
|
49
|
+
|
50
|
+
};// ShaderBuiltinVariableNames
|
30
51
|
|
31
52
|
|
32
53
|
const ShaderProgram* Shader_get_program (const Shader& shader);
|
33
54
|
|
55
|
+
const ShaderBuiltinVariableNames& Shader_get_builtin_variable_names (
|
56
|
+
const Shader& shader);
|
57
|
+
|
58
|
+
const Shader& Shader_get_default_shader_for_shape ();
|
59
|
+
|
60
|
+
const Shader& Shader_get_default_shader_for_texture ();
|
61
|
+
|
62
|
+
const Shader& Shader_get_shader_for_text ();
|
63
|
+
|
64
|
+
|
65
|
+
const ShaderBuiltinVariableNames& ShaderEnv_get_builtin_variable_names (
|
66
|
+
const ShaderEnv& env);
|
67
|
+
|
68
|
+
uint ShaderEnv_get_flags (const ShaderEnv& env);
|
69
|
+
|
70
|
+
const ShaderSource& ShaderEnv_get_default_vertex_shader_source (
|
71
|
+
ShaderEnv* env);
|
72
|
+
|
34
73
|
|
35
74
|
}// Rays
|
36
75
|
|
data/src/shader_program.cpp
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
#include <vector>
|
6
6
|
#include <memory>
|
7
7
|
#include <algorithm>
|
8
|
+
#include "rays/shader.h"
|
8
9
|
#include "rays/exception.h"
|
9
10
|
#include "shader_source.h"
|
10
11
|
#include "texture.h"
|
@@ -35,7 +36,7 @@ namespace Rays
|
|
35
36
|
|
36
37
|
virtual ~UniformValue () {}
|
37
38
|
|
38
|
-
virtual
|
39
|
+
virtual bool apply (size_t index, GLint location) const = 0;
|
39
40
|
|
40
41
|
};// UniformValue
|
41
42
|
|
@@ -83,10 +84,10 @@ namespace Rays
|
|
83
84
|
array[i] = args[i];
|
84
85
|
}
|
85
86
|
|
86
|
-
|
87
|
+
bool apply (size_t index, GLint location) const
|
87
88
|
{
|
88
89
|
apply_value(location);
|
89
|
-
|
90
|
+
return !OpenGL_has_error();
|
90
91
|
}
|
91
92
|
|
92
93
|
void apply_value (GLint location) const;
|
@@ -149,18 +150,20 @@ namespace Rays
|
|
149
150
|
{
|
150
151
|
}
|
151
152
|
|
152
|
-
|
153
|
+
bool apply (size_t index, GLint location) const
|
153
154
|
{
|
154
|
-
if (!texture)
|
155
|
+
if (!texture)
|
156
|
+
shader_error(__FILE__, __LINE__, "invalid texture");
|
155
157
|
|
156
|
-
GLint
|
157
|
-
GLint
|
158
|
-
|
159
|
-
|
158
|
+
GLint unit = (GLint) (index + 1);// GL_TEXTURE0 is used by apply_builtin_uniforms()
|
159
|
+
GLint max = get_texture_unit_max();
|
160
|
+
if (unit >= max)
|
161
|
+
shader_error(__FILE__, __LINE__, "texture unit must be less than %d", max);
|
160
162
|
|
163
|
+
glActiveTexture(GL_TEXTURE0 + unit);
|
161
164
|
glBindTexture(GL_TEXTURE_2D, texture.id());
|
162
165
|
glUniform1i(location, unit);
|
163
|
-
|
166
|
+
return !OpenGL_has_error();
|
164
167
|
}
|
165
168
|
|
166
169
|
private:
|
@@ -205,15 +208,20 @@ namespace Rays
|
|
205
208
|
self->applied = false;
|
206
209
|
}
|
207
210
|
|
208
|
-
void apply (
|
211
|
+
void apply (
|
212
|
+
size_t index, const ShaderProgram& program,
|
213
|
+
bool ignore_no_uniform_location_error) const
|
209
214
|
{
|
210
215
|
if (!program || self->applied) return;
|
211
216
|
self->applied = true;
|
212
217
|
|
213
|
-
|
214
|
-
|
218
|
+
const char* name = self->name;
|
219
|
+
GLint location = glGetUniformLocation(program.id(), name);
|
220
|
+
if (location < 0 && !ignore_no_uniform_location_error)
|
221
|
+
shader_error(__FILE__, __LINE__, "uniform location '%s' not found", name);
|
215
222
|
|
216
|
-
self->value->apply(location)
|
223
|
+
if (!self->value->apply(index, location))
|
224
|
+
shader_error(__FILE__, __LINE__, "failed to apply uniform variable '%s'", name);
|
217
225
|
}
|
218
226
|
|
219
227
|
bool operator == (const Uniform& rhs) const
|
@@ -235,7 +243,9 @@ namespace Rays
|
|
235
243
|
struct ShaderProgram::Data
|
236
244
|
{
|
237
245
|
|
238
|
-
GLuint id
|
246
|
+
GLuint id = 0;
|
247
|
+
|
248
|
+
uint flags = 0;
|
239
249
|
|
240
250
|
ShaderSource vertex, fragment;
|
241
251
|
|
@@ -266,7 +276,7 @@ namespace Rays
|
|
266
276
|
void set_uniform_texture (const char* name, const UniformValue* value)
|
267
277
|
{
|
268
278
|
if (uniform_textures.size() >= (size_t) get_texture_unit_max())
|
269
|
-
|
279
|
+
shader_error(__FILE__, __LINE__, "too many texture units.");
|
270
280
|
|
271
281
|
set_uniform(&uniform_textures, name, value);
|
272
282
|
}
|
@@ -311,7 +321,14 @@ namespace Rays
|
|
311
321
|
GLint status = GL_FALSE;
|
312
322
|
glGetProgramiv(id, GL_LINK_STATUS, &status);
|
313
323
|
if (status == GL_FALSE)
|
314
|
-
|
324
|
+
shader_error(__FILE__, __LINE__, get_link_log().c_str());
|
325
|
+
|
326
|
+
glValidateProgram(id);
|
327
|
+
|
328
|
+
GLint validate = GL_FALSE;
|
329
|
+
glGetProgramiv(id, GL_VALIDATE_STATUS, &validate);
|
330
|
+
if (validate == GL_FALSE)
|
331
|
+
OpenGL_check_error(__FILE__, __LINE__, "shader program validation failed");
|
315
332
|
}
|
316
333
|
|
317
334
|
void attach_shader (const ShaderSource& source) const
|
@@ -343,17 +360,13 @@ namespace Rays
|
|
343
360
|
if (applied) return;
|
344
361
|
applied = true;
|
345
362
|
|
346
|
-
|
347
|
-
value.apply(program);
|
363
|
+
bool ignore_no_loc = flags & ShaderEnv::IGNORE_NO_UNIFORM_LOCATION_ERROR;
|
348
364
|
|
349
|
-
|
350
|
-
|
351
|
-
{
|
352
|
-
glActiveTexture(unit++);
|
353
|
-
texture.apply(program);
|
354
|
-
}
|
365
|
+
for (size_t i = 0; i < uniform_values.size(); ++i)
|
366
|
+
uniform_values[i].apply(i, program, ignore_no_loc);
|
355
367
|
|
356
|
-
|
368
|
+
for (size_t i = 0; i < uniform_textures.size(); ++i)
|
369
|
+
uniform_textures[i].apply(i, program, ignore_no_loc);
|
357
370
|
}
|
358
371
|
|
359
372
|
};// ShaderProgram::Data
|
@@ -383,10 +396,11 @@ namespace Rays
|
|
383
396
|
|
384
397
|
|
385
398
|
ShaderProgram::ShaderProgram (
|
386
|
-
const ShaderSource& vertex, const ShaderSource& fragment)
|
399
|
+
const ShaderSource& vertex, const ShaderSource& fragment, uint flags)
|
387
400
|
{
|
388
401
|
self->vertex = vertex;
|
389
402
|
self->fragment = fragment;
|
403
|
+
self->flags = flags;
|
390
404
|
}
|
391
405
|
|
392
406
|
ShaderProgram::~ShaderProgram ()
|
@@ -500,6 +514,18 @@ namespace Rays
|
|
500
514
|
self->set_uniform_texture(name, new UniformTexture(texture));
|
501
515
|
}
|
502
516
|
|
517
|
+
const ShaderSource&
|
518
|
+
ShaderProgram::vertex_shader_source () const
|
519
|
+
{
|
520
|
+
return self->vertex;
|
521
|
+
}
|
522
|
+
|
523
|
+
const ShaderSource&
|
524
|
+
ShaderProgram::fragment_shader_source () const
|
525
|
+
{
|
526
|
+
return self->fragment;
|
527
|
+
}
|
528
|
+
|
503
529
|
GLuint
|
504
530
|
ShaderProgram::id () const
|
505
531
|
{
|
data/src/shader_program.h
CHANGED
@@ -25,7 +25,10 @@ namespace Rays
|
|
25
25
|
|
26
26
|
public:
|
27
27
|
|
28
|
-
ShaderProgram (
|
28
|
+
ShaderProgram (
|
29
|
+
const ShaderSource& vertex,
|
30
|
+
const ShaderSource& fragment,
|
31
|
+
uint flags);
|
29
32
|
|
30
33
|
~ShaderProgram ();
|
31
34
|
|
@@ -59,6 +62,10 @@ namespace Rays
|
|
59
62
|
|
60
63
|
GLuint id () const;
|
61
64
|
|
65
|
+
const ShaderSource& vertex_shader_source () const;
|
66
|
+
|
67
|
+
const ShaderSource& fragment_shader_source () const;
|
68
|
+
|
62
69
|
operator bool () const;
|
63
70
|
|
64
71
|
bool operator ! () const;
|