rays 0.3.10 → 0.3.11
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/polygon.cpp +1 -1
- data/.github/workflows/release-gem.yml +1 -1
- data/.github/workflows/test.yml +4 -4
- data/ChangeLog.md +7 -0
- data/Gemfile.lock +6 -5
- data/VERSION +1 -1
- data/ext/rays/polygon.cpp +1 -1
- data/rays.gemspec +2 -2
- data/src/bitmap.h +4 -0
- data/src/color_space.cpp +1 -41
- data/src/image.cpp +0 -1
- data/src/ios/bitmap.mm +5 -32
- data/src/ios/rays.mm +3 -3
- data/src/opengl/bitmap.cpp +41 -0
- data/src/opengl/color_space.cpp +51 -0
- data/src/{color_space.h → opengl/color_space.h} +2 -2
- data/src/{frame_buffer.cpp → opengl/frame_buffer.cpp} +1 -1
- data/src/{frame_buffer.h → opengl/frame_buffer.h} +2 -2
- data/src/{ios → opengl/ios}/opengl.mm +3 -3
- data/src/{opengl.h → opengl/opengl.h} +2 -6
- data/src/{osx → opengl/osx}/opengl.mm +3 -3
- data/src/opengl/painter.cpp +756 -0
- data/src/{render_buffer.h → opengl/render_buffer.h} +2 -2
- data/src/{sdl → opengl/sdl}/opengl.cpp +4 -3
- data/src/{shader.cpp → opengl/shader.cpp} +1 -2
- data/src/{shader.h → opengl/shader.h} +2 -2
- data/src/{shader_program.cpp → opengl/shader_program.cpp} +3 -3
- data/src/{shader_program.h → opengl/shader_program.h} +2 -2
- data/src/{shader_source.h → opengl/shader_source.h} +2 -2
- data/src/{texture.cpp → opengl/texture.cpp} +2 -3
- data/src/opengl/texture.h +21 -0
- data/src/{win32 → opengl/win32}/opengl.cpp +4 -3
- data/src/osx/bitmap.mm +5 -33
- data/src/osx/rays.mm +3 -3
- data/src/painter.cpp +21 -905
- data/src/painter.h +210 -11
- data/src/polygon.cpp +38 -13
- data/src/renderer.h +22 -0
- data/src/sdl/bitmap.cpp +5 -33
- data/src/sdl/rays.cpp +3 -3
- data/src/texture.h +0 -3
- data/src/win32/bitmap.cpp +6 -34
- data/src/win32/rays.cpp +3 -3
- metadata +29 -24
- /data/src/{opengl.cpp → opengl/opengl.cpp} +0 -0
- /data/src/{render_buffer.cpp → opengl/render_buffer.cpp} +0 -0
- /data/src/{shader_source.cpp → opengl/shader_source.cpp} +0 -0
data/src/painter.cpp
CHANGED
|
@@ -1,654 +1,29 @@
|
|
|
1
1
|
#include "painter.h"
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
#include <math.h>
|
|
5
4
|
#include <string.h>
|
|
6
5
|
#include <assert.h>
|
|
7
|
-
#include <memory>
|
|
8
|
-
#include <vector>
|
|
9
|
-
#include <algorithm>
|
|
10
|
-
#include <functional>
|
|
11
6
|
#include "rays/exception.h"
|
|
12
7
|
#include "rays/debug.h"
|
|
13
|
-
#include "rays/point.h"
|
|
14
|
-
#include "rays/bounds.h"
|
|
15
|
-
#include "rays/color.h"
|
|
16
|
-
#include "opengl.h"
|
|
17
|
-
#include "glm.h"
|
|
18
|
-
#include "matrix.h"
|
|
19
8
|
#include "polygon.h"
|
|
20
|
-
#include "bitmap.h"
|
|
21
|
-
#include "texture.h"
|
|
22
9
|
#include "image.h"
|
|
23
|
-
#include "font.h"
|
|
24
|
-
#include "frame_buffer.h"
|
|
25
|
-
#include "shader.h"
|
|
26
|
-
#include "shader_program.h"
|
|
27
|
-
#include "shader_source.h"
|
|
28
10
|
|
|
29
11
|
|
|
30
12
|
namespace Rays
|
|
31
13
|
{
|
|
32
14
|
|
|
33
15
|
|
|
34
|
-
enum ColorType
|
|
35
|
-
{
|
|
36
|
-
|
|
37
|
-
FILL = 0,
|
|
38
|
-
STROKE,
|
|
39
|
-
|
|
40
|
-
COLOR_TYPE_MAX
|
|
41
|
-
|
|
42
|
-
};// ColorType
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
struct State
|
|
46
|
-
{
|
|
47
|
-
|
|
48
|
-
Color background, colors[COLOR_TYPE_MAX];
|
|
49
|
-
|
|
50
|
-
bool nocolors[COLOR_TYPE_MAX];
|
|
51
|
-
|
|
52
|
-
coord stroke_width;
|
|
53
|
-
|
|
54
|
-
float stroke_outset;
|
|
55
|
-
|
|
56
|
-
CapType stroke_cap;
|
|
57
|
-
|
|
58
|
-
JoinType stroke_join;
|
|
59
|
-
|
|
60
|
-
coord miter_limit;
|
|
61
|
-
|
|
62
|
-
uint nsegment;
|
|
63
|
-
|
|
64
|
-
coord line_height;
|
|
65
|
-
|
|
66
|
-
BlendMode blend_mode;
|
|
67
|
-
|
|
68
|
-
Bounds clip;
|
|
69
|
-
|
|
70
|
-
Font font;
|
|
71
|
-
|
|
72
|
-
Image texture;
|
|
73
|
-
|
|
74
|
-
TexCoordMode texcoord_mode;
|
|
75
|
-
|
|
76
|
-
TexCoordWrap texcoord_wrap;
|
|
77
|
-
|
|
78
|
-
Shader shader;
|
|
79
|
-
|
|
80
|
-
void init ()
|
|
81
|
-
{
|
|
82
|
-
background .reset(0, 0);
|
|
83
|
-
colors[FILL] .reset(1, 1);
|
|
84
|
-
colors[STROKE] .reset(1, 0);
|
|
85
|
-
nocolors[FILL] = false;
|
|
86
|
-
nocolors[STROKE] = true;
|
|
87
|
-
stroke_width = 0;
|
|
88
|
-
stroke_outset = 0;
|
|
89
|
-
stroke_cap = CAP_DEFAULT;
|
|
90
|
-
stroke_join = JOIN_DEFAULT;
|
|
91
|
-
miter_limit = JOIN_DEFAULT_MITER_LIMIT;
|
|
92
|
-
nsegment = 0;
|
|
93
|
-
line_height = -1;
|
|
94
|
-
blend_mode = BLEND_NORMAL;
|
|
95
|
-
clip .reset(-1);
|
|
96
|
-
font = get_default_font();
|
|
97
|
-
texture = Image();
|
|
98
|
-
texcoord_mode = TEXCOORD_IMAGE;
|
|
99
|
-
texcoord_wrap = TEXCOORD_CLAMP;
|
|
100
|
-
shader = Shader();
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
bool get_color (Color* color, ColorType type) const
|
|
104
|
-
{
|
|
105
|
-
const Color& c = colors[type];
|
|
106
|
-
if (blend_mode == BLEND_REPLACE ? nocolors[type] : !c)
|
|
107
|
-
return false;
|
|
108
|
-
|
|
109
|
-
*color = c;
|
|
110
|
-
return true;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
bool has_color () const
|
|
114
|
-
{
|
|
115
|
-
if (blend_mode == BLEND_REPLACE)
|
|
116
|
-
return !nocolors[FILL] || !nocolors[STROKE];
|
|
117
|
-
else
|
|
118
|
-
return colors[FILL] || colors[STROKE];
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
};// State
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
struct TextureInfo
|
|
125
|
-
{
|
|
126
|
-
|
|
127
|
-
const Texture& texture;
|
|
128
|
-
|
|
129
|
-
Point min, max;
|
|
130
|
-
|
|
131
|
-
TextureInfo (
|
|
132
|
-
const Texture& texture,
|
|
133
|
-
coord x_min, coord y_min,
|
|
134
|
-
coord x_max, coord y_max)
|
|
135
|
-
: texture(texture)
|
|
136
|
-
{
|
|
137
|
-
min.reset(x_min, y_min);
|
|
138
|
-
max.reset(x_max, y_max);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
operator bool () const
|
|
142
|
-
{
|
|
143
|
-
return
|
|
144
|
-
texture &&
|
|
145
|
-
min.x < max.x &&
|
|
146
|
-
min.y < max.y;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
bool operator ! () const
|
|
150
|
-
{
|
|
151
|
-
return !operator bool();
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
};// TextureInfo
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
struct OpenGLState
|
|
158
|
-
{
|
|
159
|
-
|
|
160
|
-
GLint viewport[4];
|
|
161
|
-
|
|
162
|
-
GLclampf color_clear[4];
|
|
163
|
-
|
|
164
|
-
GLboolean depth_test;
|
|
165
|
-
GLint depth_func;
|
|
166
|
-
|
|
167
|
-
GLboolean scissor_test;
|
|
168
|
-
GLint scissor_box[4];
|
|
169
|
-
|
|
170
|
-
GLboolean blend;
|
|
171
|
-
GLint blend_equation_rgb, blend_equation_alpha;
|
|
172
|
-
GLint blend_src_rgb, blend_src_alpha, blend_dst_rgb, blend_dst_alpha;
|
|
173
|
-
|
|
174
|
-
GLint framebuffer_binding;
|
|
175
|
-
|
|
176
|
-
void push ()
|
|
177
|
-
{
|
|
178
|
-
glGetIntegerv(GL_VIEWPORT, viewport);
|
|
179
|
-
|
|
180
|
-
glGetFloatv(GL_COLOR_CLEAR_VALUE, color_clear);
|
|
181
|
-
|
|
182
|
-
glGetBooleanv(GL_DEPTH_TEST, &depth_test);
|
|
183
|
-
glGetIntegerv(GL_DEPTH_FUNC, &depth_func);
|
|
184
|
-
|
|
185
|
-
glGetBooleanv(GL_SCISSOR_TEST, &scissor_test);
|
|
186
|
-
glGetIntegerv(GL_SCISSOR_BOX, scissor_box);
|
|
187
|
-
|
|
188
|
-
glGetBooleanv(GL_BLEND, &blend);
|
|
189
|
-
glGetIntegerv(GL_BLEND_EQUATION_RGB, &blend_equation_rgb);
|
|
190
|
-
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blend_equation_alpha);
|
|
191
|
-
glGetIntegerv(GL_BLEND_SRC_RGB, &blend_src_rgb);
|
|
192
|
-
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blend_src_alpha);
|
|
193
|
-
glGetIntegerv(GL_BLEND_DST_RGB, &blend_dst_rgb);
|
|
194
|
-
glGetIntegerv(GL_BLEND_DST_ALPHA, &blend_dst_alpha);
|
|
195
|
-
|
|
196
|
-
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &framebuffer_binding);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
void pop ()
|
|
200
|
-
{
|
|
201
|
-
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
|
202
|
-
|
|
203
|
-
glClearColor(
|
|
204
|
-
color_clear[0], color_clear[1], color_clear[2], color_clear[3]);
|
|
205
|
-
|
|
206
|
-
enable(GL_DEPTH_TEST, depth_test);
|
|
207
|
-
glDepthFunc(depth_func);
|
|
208
|
-
|
|
209
|
-
enable(GL_SCISSOR_TEST, scissor_test);
|
|
210
|
-
glScissor(scissor_box[0], scissor_box[1], scissor_box[2], scissor_box[3]);
|
|
211
|
-
|
|
212
|
-
enable(GL_BLEND, blend);
|
|
213
|
-
glBlendEquationSeparate(blend_equation_rgb, blend_equation_alpha);
|
|
214
|
-
glBlendFuncSeparate(
|
|
215
|
-
blend_src_rgb, blend_dst_rgb, blend_src_alpha, blend_dst_alpha);
|
|
216
|
-
|
|
217
|
-
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_binding);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
private:
|
|
221
|
-
|
|
222
|
-
void enable(GLenum type, GLboolean value)
|
|
223
|
-
{
|
|
224
|
-
if (value)
|
|
225
|
-
glEnable(type);
|
|
226
|
-
else
|
|
227
|
-
glDisable(type);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
};// OpenGLState
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
class DefaultIndices
|
|
234
|
-
{
|
|
235
|
-
|
|
236
|
-
public:
|
|
237
|
-
|
|
238
|
-
void resize (size_t size)
|
|
239
|
-
{
|
|
240
|
-
indices.reserve(size);
|
|
241
|
-
while (indices.size() < size)
|
|
242
|
-
indices.emplace_back(indices.size());
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
void clear ()
|
|
246
|
-
{
|
|
247
|
-
decltype(indices)().swap(indices);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
const uint* get () const
|
|
251
|
-
{
|
|
252
|
-
return &indices[0];
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
private:
|
|
256
|
-
|
|
257
|
-
std::vector<uint> indices;
|
|
258
|
-
|
|
259
|
-
};// DefaultIndices
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
template <typename COORD>
|
|
263
|
-
static GLenum get_gl_type ();
|
|
264
|
-
|
|
265
|
-
template <>
|
|
266
|
-
GLenum
|
|
267
|
-
get_gl_type<float> ()
|
|
268
|
-
{
|
|
269
|
-
return GL_FLOAT;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
struct Painter::Data
|
|
274
|
-
{
|
|
275
|
-
|
|
276
|
-
bool painting = false;
|
|
277
|
-
|
|
278
|
-
float pixel_density = 1;
|
|
279
|
-
|
|
280
|
-
Bounds viewport;
|
|
281
|
-
|
|
282
|
-
State state;
|
|
283
|
-
|
|
284
|
-
std::vector<State> state_stack;
|
|
285
|
-
|
|
286
|
-
Matrix position_matrix;
|
|
287
|
-
|
|
288
|
-
std::vector<Matrix> position_matrix_stack;
|
|
289
|
-
|
|
290
|
-
FrameBuffer frame_buffer;
|
|
291
|
-
|
|
292
|
-
Image text_image;
|
|
293
|
-
|
|
294
|
-
OpenGLState opengl_state;
|
|
295
|
-
|
|
296
|
-
DefaultIndices default_indices;
|
|
297
|
-
|
|
298
|
-
Data ()
|
|
299
|
-
{
|
|
300
|
-
state.init();
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
void set_pixel_density (float density)
|
|
304
|
-
{
|
|
305
|
-
if (density <= 0)
|
|
306
|
-
argument_error(__FILE__, __LINE__, "invalid pixel_density.");
|
|
307
|
-
|
|
308
|
-
this->pixel_density = density;
|
|
309
|
-
text_image = Image();
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
void update_clip ()
|
|
313
|
-
{
|
|
314
|
-
const Bounds& clip = state.clip;
|
|
315
|
-
if (clip)
|
|
316
|
-
{
|
|
317
|
-
coord y = frame_buffer ? clip.y : viewport.h - (clip.y + clip.h);
|
|
318
|
-
glEnable(GL_SCISSOR_TEST);
|
|
319
|
-
glScissor(
|
|
320
|
-
pixel_density * clip.x,
|
|
321
|
-
pixel_density * y,
|
|
322
|
-
pixel_density * clip.width,
|
|
323
|
-
pixel_density * clip.height);
|
|
324
|
-
}
|
|
325
|
-
else
|
|
326
|
-
{
|
|
327
|
-
glDisable(GL_SCISSOR_TEST);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
OpenGL_check_error(__FILE__, __LINE__);
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
void draw (
|
|
334
|
-
GLenum mode, const Color* color,
|
|
335
|
-
const Coord3* points, size_t npoints,
|
|
336
|
-
const uint* indices = NULL, size_t nindices = 0,
|
|
337
|
-
const Color* colors = NULL,
|
|
338
|
-
const Coord3* texcoords = NULL,
|
|
339
|
-
const TextureInfo* texinfo = NULL,
|
|
340
|
-
const Shader* shader = NULL)
|
|
341
|
-
{
|
|
342
|
-
if (!points)
|
|
343
|
-
argument_error(__FILE__, __LINE__);
|
|
344
|
-
if (npoints <= 0)
|
|
345
|
-
argument_error(__FILE__, __LINE__);
|
|
346
|
-
|
|
347
|
-
if (!painting)
|
|
348
|
-
invalid_state_error(__FILE__, __LINE__, "'painting' should be true.");
|
|
349
|
-
|
|
350
|
-
std::unique_ptr<TextureInfo> ptexinfo;
|
|
351
|
-
texinfo = setup_texinfo(texinfo, ptexinfo);
|
|
352
|
-
shader = setup_shader(shader, texinfo);
|
|
353
|
-
|
|
354
|
-
const ShaderProgram* program = Shader_get_program(*shader);
|
|
355
|
-
if (!program || !*program) return;
|
|
356
|
-
|
|
357
|
-
ShaderProgram_activate(*program);
|
|
358
|
-
|
|
359
|
-
const auto& names = Shader_get_builtin_variable_names(*shader);
|
|
360
|
-
apply_builtin_uniforms(*program, names, texinfo);
|
|
361
|
-
apply_attributes(*program, names, points, npoints, texcoords, color, colors);
|
|
362
|
-
draw_indices(mode, indices, nindices, npoints);
|
|
363
|
-
cleanup();
|
|
364
|
-
|
|
365
|
-
ShaderProgram_deactivate();
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
private:
|
|
369
|
-
|
|
370
|
-
std::vector<GLint> locations;
|
|
371
|
-
|
|
372
|
-
std::vector<GLuint> buffers;
|
|
373
|
-
|
|
374
|
-
const TextureInfo* setup_texinfo (const TextureInfo* texinfo, auto& ptr)
|
|
375
|
-
{
|
|
376
|
-
if (texinfo) return texinfo;
|
|
377
|
-
|
|
378
|
-
const Texture* tex =
|
|
379
|
-
state.texture ? &Image_get_texture(state.texture) : NULL;
|
|
380
|
-
if (!tex) return NULL;
|
|
381
|
-
|
|
382
|
-
ptr.reset(new TextureInfo(*tex, 0, 0, tex->width(), tex->height()));
|
|
383
|
-
return ptr.get();
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
const Shader* setup_shader (const Shader* shader, bool for_texture)
|
|
387
|
-
{
|
|
388
|
-
if (state.shader) return &state.shader;
|
|
389
|
-
if (shader) return shader;
|
|
390
|
-
return for_texture
|
|
391
|
-
? &Shader_get_default_shader_for_texture(state.texcoord_wrap)
|
|
392
|
-
: &Shader_get_default_shader_for_shape();
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
void apply_builtin_uniforms (
|
|
396
|
-
const ShaderProgram& program, const ShaderBuiltinVariableNames& names,
|
|
397
|
-
const TextureInfo* texinfo)
|
|
398
|
-
{
|
|
399
|
-
const Texture* texture = texinfo ? &texinfo->texture : NULL;
|
|
400
|
-
|
|
401
|
-
Matrix texcoord_matrix(1);
|
|
402
|
-
if (texture && *texture)
|
|
403
|
-
{
|
|
404
|
-
bool normal = state.texcoord_mode == TEXCOORD_NORMAL;
|
|
405
|
-
texcoord_matrix.scale(
|
|
406
|
-
(normal ? texture->width() : 1.0) / texture->reserved_width(),
|
|
407
|
-
(normal ? texture->height() : 1.0) / texture->reserved_height());
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
for (const auto& name : names.uniform_position_matrix_names)
|
|
411
|
-
{
|
|
412
|
-
apply_uniform(program, name, [&](GLint loc) {
|
|
413
|
-
glUniformMatrix4fv(loc, 1, GL_FALSE, position_matrix.array);
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
for (const auto& name : names.uniform_texcoord_matrix_names)
|
|
417
|
-
{
|
|
418
|
-
apply_uniform(program, name, [&](GLint loc) {
|
|
419
|
-
glUniformMatrix4fv(loc, 1, GL_FALSE, texcoord_matrix.array);
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
if (!texinfo || !texture || !*texture) return;
|
|
424
|
-
|
|
425
|
-
coord tw = texture->reserved_width();
|
|
426
|
-
coord th = texture->reserved_height();
|
|
427
|
-
Point min(texinfo->min.x / tw, texinfo->min.y / th);
|
|
428
|
-
Point max(texinfo->max.x / tw, texinfo->max.y / th);
|
|
429
|
-
Point offset( 1 / tw, 1 / th);
|
|
430
|
-
|
|
431
|
-
for (const auto& name : names.uniform_texcoord_min_names)
|
|
432
|
-
{
|
|
433
|
-
apply_uniform(program, name, [&](GLint loc) {
|
|
434
|
-
glUniform3fv(loc, 1, min.array);
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
for (const auto& name : names.uniform_texcoord_max_names)
|
|
438
|
-
{
|
|
439
|
-
apply_uniform(program, name, [&](GLint loc) {
|
|
440
|
-
glUniform3fv(loc, 1, max.array);
|
|
441
|
-
});
|
|
442
|
-
}
|
|
443
|
-
for (const auto& name : names.uniform_texcoord_offset_names)
|
|
444
|
-
{
|
|
445
|
-
apply_uniform(program, name, [&](GLint loc) {
|
|
446
|
-
glUniform3fv(loc, 1, offset.array);
|
|
447
|
-
});
|
|
448
|
-
}
|
|
449
|
-
for (const auto& name : names.uniform_texture_names)
|
|
450
|
-
{
|
|
451
|
-
apply_uniform(program, name, [&](GLint loc) {
|
|
452
|
-
glActiveTexture(GL_TEXTURE0);
|
|
453
|
-
OpenGL_check_error(__FILE__, __LINE__);
|
|
454
|
-
|
|
455
|
-
glBindTexture(GL_TEXTURE_2D, texture->id());
|
|
456
|
-
OpenGL_check_error(__FILE__, __LINE__);
|
|
457
|
-
|
|
458
|
-
glUniform1i(loc, 0);
|
|
459
|
-
});
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
void apply_attributes (
|
|
464
|
-
const ShaderProgram& program, const ShaderBuiltinVariableNames& names,
|
|
465
|
-
const Coord3* points, size_t npoints, const Coord3* texcoords,
|
|
466
|
-
const Color* color, const Color* colors)
|
|
467
|
-
{
|
|
468
|
-
assert(npoints > 0);
|
|
469
|
-
assert(!!color != !!colors);
|
|
470
|
-
|
|
471
|
-
apply_attribute(
|
|
472
|
-
program, names.attribute_position_names,
|
|
473
|
-
points, npoints);
|
|
474
|
-
|
|
475
|
-
apply_attribute(
|
|
476
|
-
program, names.attribute_texcoord_names,
|
|
477
|
-
texcoords ? texcoords : points, npoints);
|
|
478
|
-
|
|
479
|
-
if (colors)
|
|
480
|
-
{
|
|
481
|
-
apply_attribute(
|
|
482
|
-
program, names.attribute_color_names,
|
|
483
|
-
colors, npoints);
|
|
484
|
-
}
|
|
485
|
-
else if (color)
|
|
486
|
-
{
|
|
487
|
-
#if defined(GL_VERSION_2_1) && !defined(GL_VERSION_3_0)
|
|
488
|
-
// to fix that GL 2.1 with glVertexAttrib4fv() draws nothing
|
|
489
|
-
// with specific glsl 'attribute' name.
|
|
490
|
-
std::vector<Color> colors_(npoints, *color);
|
|
491
|
-
apply_attribute(
|
|
492
|
-
program, names.attribute_color_names,
|
|
493
|
-
(const Coord4*) &colors_[0], npoints);
|
|
494
|
-
#else
|
|
495
|
-
for (const auto& name : names.attribute_color_names)
|
|
496
|
-
{
|
|
497
|
-
apply_attribute(program, name, [&](GLint loc) {
|
|
498
|
-
glVertexAttrib4fv(loc, color->array);
|
|
499
|
-
});
|
|
500
|
-
}
|
|
501
|
-
#endif
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
template <typename CoordN>
|
|
506
|
-
void apply_attribute(
|
|
507
|
-
const ShaderProgram& program, const auto& names,
|
|
508
|
-
const CoordN* values, size_t nvalues)
|
|
509
|
-
{
|
|
510
|
-
GLuint buffer = 0;
|
|
511
|
-
for (const auto& name : names)
|
|
512
|
-
{
|
|
513
|
-
#ifndef IOS
|
|
514
|
-
if (buffer == 0)
|
|
515
|
-
{
|
|
516
|
-
buffer = create_and_bind_buffer(
|
|
517
|
-
GL_ARRAY_BUFFER, values, sizeof(CoordN) * nvalues);
|
|
518
|
-
values = 0;
|
|
519
|
-
}
|
|
520
|
-
#endif
|
|
521
|
-
|
|
522
|
-
apply_attribute(program, name, [&](GLint loc) {
|
|
523
|
-
glEnableVertexAttribArray(loc);
|
|
524
|
-
OpenGL_check_error(
|
|
525
|
-
__FILE__, __LINE__, "loc: %d %s\n", loc, name.c_str());
|
|
526
|
-
|
|
527
|
-
glVertexAttribPointer(
|
|
528
|
-
loc, CoordN::SIZE, get_gl_type<coord>(), GL_FALSE, 0, values);
|
|
529
|
-
|
|
530
|
-
locations.push_back(loc);
|
|
531
|
-
});
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
535
|
-
OpenGL_check_error(__FILE__, __LINE__);
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
void apply_attribute (
|
|
539
|
-
const ShaderProgram& program, const char* name,
|
|
540
|
-
std::function<void(GLint)> apply_fun)
|
|
541
|
-
{
|
|
542
|
-
GLint loc = glGetAttribLocation(program.id(), name);
|
|
543
|
-
if (loc < 0) return;
|
|
544
|
-
|
|
545
|
-
apply_fun(loc);
|
|
546
|
-
OpenGL_check_error(__FILE__, __LINE__);
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
void apply_uniform (
|
|
550
|
-
const ShaderProgram& program, const char* name,
|
|
551
|
-
std::function<void(GLint)> apply_fun)
|
|
552
|
-
{
|
|
553
|
-
GLint loc = glGetUniformLocation(program.id(), name);
|
|
554
|
-
if (loc < 0) return;
|
|
555
|
-
|
|
556
|
-
apply_fun(loc);
|
|
557
|
-
OpenGL_check_error(__FILE__, __LINE__);
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
void draw_indices (
|
|
561
|
-
GLenum mode, const uint* indices, size_t nindices, size_t npoints)
|
|
562
|
-
{
|
|
563
|
-
if (!indices || nindices <= 0)
|
|
564
|
-
{
|
|
565
|
-
default_indices.resize(npoints);
|
|
566
|
-
indices = default_indices.get();
|
|
567
|
-
nindices = npoints;
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
#ifdef IOS
|
|
571
|
-
glDrawElements(mode, (GLsizei) nindices, GL_UNSIGNED_INT, indices);
|
|
572
|
-
OpenGL_check_error(__FILE__, __LINE__);
|
|
573
|
-
#else
|
|
574
|
-
create_and_bind_buffer(
|
|
575
|
-
GL_ELEMENT_ARRAY_BUFFER, indices, sizeof(uint) * nindices);
|
|
576
|
-
|
|
577
|
-
glDrawElements(mode, (GLsizei) nindices, GL_UNSIGNED_INT, 0);
|
|
578
|
-
OpenGL_check_error(__FILE__, __LINE__);
|
|
579
|
-
|
|
580
|
-
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
581
|
-
OpenGL_check_error(__FILE__, __LINE__);
|
|
582
|
-
#endif
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
GLuint create_and_bind_buffer (
|
|
586
|
-
GLenum target, const void* data, GLsizeiptr size)
|
|
587
|
-
{
|
|
588
|
-
GLuint id = 0;
|
|
589
|
-
glGenBuffers(1, &id);
|
|
590
|
-
OpenGL_check_error(__FILE__, __LINE__);
|
|
591
|
-
|
|
592
|
-
buffers.push_back(id);
|
|
593
|
-
|
|
594
|
-
glBindBuffer(target, id);
|
|
595
|
-
OpenGL_check_error(__FILE__, __LINE__);
|
|
596
|
-
|
|
597
|
-
glBufferData(target, size, data, GL_STREAM_DRAW);
|
|
598
|
-
OpenGL_check_error(__FILE__, __LINE__);
|
|
599
|
-
|
|
600
|
-
return id;
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
void cleanup ()
|
|
604
|
-
{
|
|
605
|
-
for (auto loc : locations)
|
|
606
|
-
{
|
|
607
|
-
glDisableVertexAttribArray(loc);
|
|
608
|
-
OpenGL_check_error(__FILE__, __LINE__);
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
if (!buffers.empty())
|
|
612
|
-
{
|
|
613
|
-
glDeleteBuffers((GLsizei) buffers.size(), &buffers[0]);
|
|
614
|
-
OpenGL_check_error(__FILE__, __LINE__);
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
locations.clear();
|
|
618
|
-
buffers.clear();
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
};// Painter::Data
|
|
622
|
-
|
|
623
|
-
|
|
624
16
|
void
|
|
625
|
-
|
|
626
|
-
Painter* painter, GLenum mode, const Color& color,
|
|
627
|
-
const Coord3* points, size_t npoints,
|
|
628
|
-
const uint* indices, size_t nindices,
|
|
629
|
-
const Coord3* texcoords)
|
|
17
|
+
Painter::Data::set_pixel_density (float density)
|
|
630
18
|
{
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
}
|
|
19
|
+
if (density <= 0)
|
|
20
|
+
argument_error(__FILE__, __LINE__, "invalid pixel_density.");
|
|
634
21
|
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
Painter* painter, GLenum mode,
|
|
638
|
-
const Coord3* points, size_t npoints,
|
|
639
|
-
const uint* indices, size_t nindices,
|
|
640
|
-
const Color* colors,
|
|
641
|
-
const Coord3* texcoords)
|
|
642
|
-
{
|
|
643
|
-
painter->self->draw(
|
|
644
|
-
mode, NULL, points, npoints, indices, nindices, colors, texcoords);
|
|
22
|
+
this->pixel_density = density;
|
|
23
|
+
text_image = Image();
|
|
645
24
|
}
|
|
646
25
|
|
|
647
26
|
|
|
648
|
-
Painter::Painter ()
|
|
649
|
-
{
|
|
650
|
-
}
|
|
651
|
-
|
|
652
27
|
Painter::~Painter ()
|
|
653
28
|
{
|
|
654
29
|
}
|
|
@@ -681,34 +56,6 @@ namespace Rays
|
|
|
681
56
|
self->set_pixel_density(pixel_density);
|
|
682
57
|
}
|
|
683
58
|
|
|
684
|
-
void
|
|
685
|
-
Painter::bind (const Image& image)
|
|
686
|
-
{
|
|
687
|
-
if (!image)
|
|
688
|
-
argument_error(__FILE__, __LINE__, "invalid image.");
|
|
689
|
-
|
|
690
|
-
if (self->painting)
|
|
691
|
-
invalid_state_error(__FILE__, __LINE__, "painting flag should be false.");
|
|
692
|
-
|
|
693
|
-
FrameBuffer fb(Image_get_texture(image));
|
|
694
|
-
if (!fb)
|
|
695
|
-
rays_error(__FILE__, __LINE__, "invalid frame buffer.");
|
|
696
|
-
|
|
697
|
-
unbind();
|
|
698
|
-
|
|
699
|
-
self->frame_buffer = fb;
|
|
700
|
-
canvas(0, 0, image.width(), image.height(), image.pixel_density());
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
void
|
|
704
|
-
Painter::unbind ()
|
|
705
|
-
{
|
|
706
|
-
if (self->painting)
|
|
707
|
-
invalid_state_error(__FILE__, __LINE__, "painting flag should be true.");
|
|
708
|
-
|
|
709
|
-
self->frame_buffer = FrameBuffer();
|
|
710
|
-
}
|
|
711
|
-
|
|
712
59
|
const Bounds&
|
|
713
60
|
Painter::bounds () const
|
|
714
61
|
{
|
|
@@ -721,101 +68,12 @@ namespace Rays
|
|
|
721
68
|
return self->pixel_density;
|
|
722
69
|
}
|
|
723
70
|
|
|
724
|
-
void
|
|
725
|
-
Painter::begin ()
|
|
726
|
-
{
|
|
727
|
-
if (self->painting)
|
|
728
|
-
invalid_state_error(__FILE__, __LINE__, "painting flag should be false.");
|
|
729
|
-
|
|
730
|
-
self->opengl_state.push();
|
|
731
|
-
|
|
732
|
-
//glEnable(GL_CULL_FACE);
|
|
733
|
-
|
|
734
|
-
glEnable(GL_DEPTH_TEST);
|
|
735
|
-
glDepthFunc(GL_LEQUAL);
|
|
736
|
-
OpenGL_check_error(__FILE__, __LINE__);
|
|
737
|
-
|
|
738
|
-
glEnable(GL_BLEND);
|
|
739
|
-
set_blend_mode(self->state.blend_mode);
|
|
740
|
-
|
|
741
|
-
FrameBuffer& fb = self->frame_buffer;
|
|
742
|
-
if (fb)
|
|
743
|
-
{
|
|
744
|
-
FrameBuffer_bind(fb.id());
|
|
745
|
-
|
|
746
|
-
Texture& tex = fb.texture();
|
|
747
|
-
if (tex) tex.set_modified();
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
const Bounds& vp = self->viewport;
|
|
751
|
-
float density = self->pixel_density;
|
|
752
|
-
glViewport(
|
|
753
|
-
(int) (vp.x * density), (int) (vp.y * density),
|
|
754
|
-
(int) (vp.width * density), (int) (vp.height * density));
|
|
755
|
-
OpenGL_check_error(__FILE__, __LINE__);
|
|
756
|
-
|
|
757
|
-
coord x1 = vp.x, x2 = vp.x + vp.width;
|
|
758
|
-
coord y1 = vp.y, y2 = vp.y + vp.height;
|
|
759
|
-
coord z1 = vp.z, z2 = vp.z + vp.depth;
|
|
760
|
-
if (z1 == 0 && z2 == 0) {z1 = -1000; z2 = 1000;}
|
|
761
|
-
if (!fb) std::swap(y1, y2);
|
|
762
|
-
|
|
763
|
-
self->position_matrix.reset(1);
|
|
764
|
-
self->position_matrix *= to_rays(glm::ortho(x1, x2, y1, y2));
|
|
765
|
-
|
|
766
|
-
// map z to 0.0-1.0
|
|
767
|
-
self->position_matrix.scale(1, 1, 1.0 / (z2 - z1));
|
|
768
|
-
self->position_matrix.translate(0, 0, -z2);
|
|
769
|
-
|
|
770
|
-
//self->position_matrix.translate(0.375f, 0.375f);
|
|
771
|
-
|
|
772
|
-
self->update_clip();
|
|
773
|
-
|
|
774
|
-
self->painting = true;
|
|
775
|
-
|
|
776
|
-
glClear(GL_DEPTH_BUFFER_BIT);
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
void
|
|
780
|
-
Painter::end ()
|
|
781
|
-
{
|
|
782
|
-
if (!self->painting)
|
|
783
|
-
invalid_state_error(__FILE__, __LINE__, "painting flag should be true.");
|
|
784
|
-
|
|
785
|
-
if (!self->state_stack.empty())
|
|
786
|
-
invalid_state_error(__FILE__, __LINE__, "state stack is not empty.");
|
|
787
|
-
|
|
788
|
-
if (!self->position_matrix_stack.empty())
|
|
789
|
-
invalid_state_error(__FILE__, __LINE__, "position matrix stack is not empty.");
|
|
790
|
-
|
|
791
|
-
self->painting = false;
|
|
792
|
-
self->opengl_state.pop();
|
|
793
|
-
self->default_indices.clear();
|
|
794
|
-
|
|
795
|
-
glFinish();
|
|
796
|
-
|
|
797
|
-
if (self->frame_buffer)
|
|
798
|
-
FrameBuffer_unbind();
|
|
799
|
-
}
|
|
800
|
-
|
|
801
71
|
bool
|
|
802
72
|
Painter::painting () const
|
|
803
73
|
{
|
|
804
74
|
return self->painting;
|
|
805
75
|
}
|
|
806
76
|
|
|
807
|
-
void
|
|
808
|
-
Painter::clear ()
|
|
809
|
-
{
|
|
810
|
-
if (!self->painting)
|
|
811
|
-
invalid_state_error(__FILE__, __LINE__, "painting flag should be true.");
|
|
812
|
-
|
|
813
|
-
const Color& c = self->state.background;
|
|
814
|
-
glClearColor(c.red, c.green, c.blue, c.alpha);
|
|
815
|
-
glClear(GL_COLOR_BUFFER_BIT);
|
|
816
|
-
OpenGL_check_error(__FILE__, __LINE__);
|
|
817
|
-
}
|
|
818
|
-
|
|
819
77
|
static inline void
|
|
820
78
|
debug_draw_triangulation (
|
|
821
79
|
Painter* painter, const Polygon& polygon, const Color& color)
|
|
@@ -832,7 +90,7 @@ namespace Rays
|
|
|
832
90
|
if (Polygon_triangulate(&triangles, polygon))
|
|
833
91
|
{
|
|
834
92
|
for (size_t i = 0; i < triangles.size(); i += 3)
|
|
835
|
-
painter
|
|
93
|
+
Painter_draw(painter, MODE_LINE_LOOP, &invert_color, &triangles[i], 3);
|
|
836
94
|
}
|
|
837
95
|
#endif
|
|
838
96
|
}
|
|
@@ -1065,15 +323,15 @@ namespace Rays
|
|
|
1065
323
|
polygon(create_bezier(points, size, loop, nsegment()));
|
|
1066
324
|
}
|
|
1067
325
|
|
|
1068
|
-
|
|
1069
|
-
|
|
326
|
+
void
|
|
327
|
+
Painter_draw_image (
|
|
1070
328
|
Painter* painter, const Image& image,
|
|
1071
329
|
coord src_x, coord src_y, coord src_w, coord src_h,
|
|
1072
330
|
coord dst_x, coord dst_y, coord dst_w, coord dst_h,
|
|
1073
|
-
bool nofill
|
|
1074
|
-
const Shader* shader
|
|
331
|
+
bool nofill, bool nostroke,
|
|
332
|
+
const Shader* shader)
|
|
1075
333
|
{
|
|
1076
|
-
static const
|
|
334
|
+
static const PrimitiveMode MODES[] = {MODE_TRIANGLE_FAN, MODE_LINE_LOOP};
|
|
1077
335
|
|
|
1078
336
|
assert(painter && image);
|
|
1079
337
|
|
|
@@ -1116,8 +374,8 @@ namespace Rays
|
|
|
1116
374
|
if (!painter->self->state.get_color(&color, (ColorType) type))
|
|
1117
375
|
continue;
|
|
1118
376
|
|
|
1119
|
-
|
|
1120
|
-
MODES[type], &color, points, 4, NULL, 0, NULL, texcoords,
|
|
377
|
+
Painter_draw(
|
|
378
|
+
painter, MODES[type], &color, points, 4, NULL, 0, NULL, texcoords,
|
|
1121
379
|
&texinfo, shader);
|
|
1122
380
|
}
|
|
1123
381
|
}
|
|
@@ -1128,7 +386,7 @@ namespace Rays
|
|
|
1128
386
|
if (!image_)
|
|
1129
387
|
argument_error(__FILE__, __LINE__);
|
|
1130
388
|
|
|
1131
|
-
|
|
389
|
+
Painter_draw_image(
|
|
1132
390
|
this, image_,
|
|
1133
391
|
0, 0, image_.width(), image_.height(),
|
|
1134
392
|
x, y, image_.width(), image_.height());
|
|
@@ -1147,7 +405,7 @@ namespace Rays
|
|
|
1147
405
|
if (!image_)
|
|
1148
406
|
argument_error(__FILE__, __LINE__);
|
|
1149
407
|
|
|
1150
|
-
|
|
408
|
+
Painter_draw_image(
|
|
1151
409
|
this, image_,
|
|
1152
410
|
0, 0, image_.width(), image_.height(),
|
|
1153
411
|
x, y, width, height);
|
|
@@ -1169,7 +427,7 @@ namespace Rays
|
|
|
1169
427
|
if (!image_)
|
|
1170
428
|
argument_error(__FILE__, __LINE__);
|
|
1171
429
|
|
|
1172
|
-
|
|
430
|
+
Painter_draw_image(
|
|
1173
431
|
this, image_,
|
|
1174
432
|
src_x, src_y, src_width, src_height,
|
|
1175
433
|
dst_x, dst_y, image_.width(), image_.height());
|
|
@@ -1194,7 +452,7 @@ namespace Rays
|
|
|
1194
452
|
if (!image_)
|
|
1195
453
|
argument_error(__FILE__, __LINE__);
|
|
1196
454
|
|
|
1197
|
-
|
|
455
|
+
Painter_draw_image(
|
|
1198
456
|
this, image_,
|
|
1199
457
|
src_x, src_y, src_width, src_height,
|
|
1200
458
|
dst_x, dst_y, dst_width, dst_height);
|
|
@@ -1210,88 +468,6 @@ namespace Rays
|
|
|
1210
468
|
dst_bounds.x, dst_bounds.y, dst_bounds.width, dst_bounds.height);
|
|
1211
469
|
}
|
|
1212
470
|
|
|
1213
|
-
static inline void
|
|
1214
|
-
debug_draw_line (
|
|
1215
|
-
Painter* painter, const Font& font,
|
|
1216
|
-
coord x, coord y, coord str_width, coord str_height)
|
|
1217
|
-
{
|
|
1218
|
-
#if 0
|
|
1219
|
-
painter->self->text_image.save("/tmp/font.png");
|
|
1220
|
-
|
|
1221
|
-
painter->push_state();
|
|
1222
|
-
{
|
|
1223
|
-
coord asc, desc, lead;
|
|
1224
|
-
font.get_height(&asc, &desc, &lead);
|
|
1225
|
-
//printf("%f %f %f %f \n", str_height, asc, desc, lead);
|
|
1226
|
-
|
|
1227
|
-
painter->set_stroke(0.5, 0.5, 1);
|
|
1228
|
-
painter->no_fill();
|
|
1229
|
-
painter->rect(x - 1, y - 1, str_width + 2, str_height + 2);
|
|
1230
|
-
|
|
1231
|
-
coord yy = y;
|
|
1232
|
-
painter->set_stroke(1, 0.5, 0.5, 0.4);
|
|
1233
|
-
painter->rect(x, yy, str_width, asc);//str_height);
|
|
1234
|
-
|
|
1235
|
-
yy += asc;
|
|
1236
|
-
painter->set_stroke(1, 1, 0.5, 0.4);
|
|
1237
|
-
painter->rect(x, yy, str_width, desc);
|
|
1238
|
-
|
|
1239
|
-
yy += desc;
|
|
1240
|
-
painter->set_stroke(1, 0.5, 1, 0.4);
|
|
1241
|
-
painter->rect(x, yy, str_width, lead);
|
|
1242
|
-
}
|
|
1243
|
-
painter->pop_state();
|
|
1244
|
-
#endif
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
|
-
static void
|
|
1248
|
-
draw_line (
|
|
1249
|
-
Painter* painter, const Font& font,
|
|
1250
|
-
const char* line, coord x, coord y, coord width = 0, coord height = 0)
|
|
1251
|
-
{
|
|
1252
|
-
assert(painter && font && line && *line != '\0');
|
|
1253
|
-
|
|
1254
|
-
Painter::Data* self = painter->self.get();
|
|
1255
|
-
|
|
1256
|
-
float density = self->pixel_density;
|
|
1257
|
-
const RawFont& rawfont = Font_get_raw(font, density);
|
|
1258
|
-
coord str_w = rawfont.get_width(line);
|
|
1259
|
-
coord str_h = rawfont.get_height();
|
|
1260
|
-
int tex_w = ceil(str_w);
|
|
1261
|
-
int tex_h = ceil(str_h);
|
|
1262
|
-
const Texture& texture = Image_get_texture(self->text_image);
|
|
1263
|
-
if (
|
|
1264
|
-
texture.width() < tex_w ||
|
|
1265
|
-
texture.height() < tex_h ||
|
|
1266
|
-
self->text_image.pixel_density() != density)
|
|
1267
|
-
{
|
|
1268
|
-
int bmp_w = std::max(texture.width(), tex_w);
|
|
1269
|
-
int bmp_h = std::max(texture.height(), tex_h);
|
|
1270
|
-
self->text_image = Image(Bitmap(bmp_w, bmp_h), density);
|
|
1271
|
-
}
|
|
1272
|
-
|
|
1273
|
-
if (!self->text_image)
|
|
1274
|
-
invalid_state_error(__FILE__, __LINE__);
|
|
1275
|
-
|
|
1276
|
-
assert(self->text_image.pixel_density() == density);
|
|
1277
|
-
|
|
1278
|
-
Bitmap_draw_string(
|
|
1279
|
-
&self->text_image.bitmap(), rawfont, line, 0, 0, font.smooth());
|
|
1280
|
-
|
|
1281
|
-
str_w /= density;
|
|
1282
|
-
str_h /= density;
|
|
1283
|
-
if (width == 0) width = str_w;
|
|
1284
|
-
if (height == 0) height = str_h;
|
|
1285
|
-
|
|
1286
|
-
draw_image(
|
|
1287
|
-
painter, self->text_image,
|
|
1288
|
-
0, 0, str_w, str_h,
|
|
1289
|
-
x, y, str_w, str_h,
|
|
1290
|
-
false, true, &Shader_get_shader_for_text());
|
|
1291
|
-
|
|
1292
|
-
debug_draw_line(painter, font, x, y, str_w / density, str_h / density);
|
|
1293
|
-
}
|
|
1294
|
-
|
|
1295
471
|
static void
|
|
1296
472
|
draw_text (
|
|
1297
473
|
Painter* painter, const Font& font,
|
|
@@ -1308,7 +484,7 @@ namespace Rays
|
|
|
1308
484
|
return;
|
|
1309
485
|
|
|
1310
486
|
if (!strchr(str, '\n'))
|
|
1311
|
-
|
|
487
|
+
Painter_draw_text_line(painter, font, str, x, y, width, height);
|
|
1312
488
|
else
|
|
1313
489
|
{
|
|
1314
490
|
coord line_height = painter->line_height();
|
|
@@ -1317,7 +493,7 @@ namespace Rays
|
|
|
1317
493
|
split(&lines, str, '\n');
|
|
1318
494
|
for (const auto& line : lines)
|
|
1319
495
|
{
|
|
1320
|
-
|
|
496
|
+
Painter_draw_text_line(painter, font, line.c_str(), x, y, width, height);
|
|
1321
497
|
y += line_height;
|
|
1322
498
|
}
|
|
1323
499
|
}
|
|
@@ -1534,66 +710,6 @@ namespace Rays
|
|
|
1534
710
|
return height;
|
|
1535
711
|
}
|
|
1536
712
|
|
|
1537
|
-
void
|
|
1538
|
-
Painter::set_blend_mode (BlendMode mode)
|
|
1539
|
-
{
|
|
1540
|
-
self->state.blend_mode = mode;
|
|
1541
|
-
switch (mode)
|
|
1542
|
-
{
|
|
1543
|
-
case BLEND_NORMAL:
|
|
1544
|
-
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
|
|
1545
|
-
glBlendFuncSeparate(
|
|
1546
|
-
GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
|
|
1547
|
-
break;
|
|
1548
|
-
|
|
1549
|
-
case BLEND_ADD:
|
|
1550
|
-
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
|
|
1551
|
-
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE);
|
|
1552
|
-
break;
|
|
1553
|
-
|
|
1554
|
-
case BLEND_SUBTRACT:
|
|
1555
|
-
glBlendEquationSeparate(GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_ADD);
|
|
1556
|
-
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE);
|
|
1557
|
-
break;
|
|
1558
|
-
|
|
1559
|
-
case BLEND_LIGHTEST:
|
|
1560
|
-
glBlendEquationSeparate(GL_MAX, GL_FUNC_ADD);
|
|
1561
|
-
glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ONE);
|
|
1562
|
-
break;
|
|
1563
|
-
|
|
1564
|
-
case BLEND_DARKEST:
|
|
1565
|
-
glBlendEquationSeparate(GL_MIN, GL_FUNC_ADD);
|
|
1566
|
-
glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ONE);
|
|
1567
|
-
break;
|
|
1568
|
-
|
|
1569
|
-
case BLEND_EXCLUSION:
|
|
1570
|
-
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
|
|
1571
|
-
glBlendFuncSeparate(
|
|
1572
|
-
GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_ONE, GL_ONE);
|
|
1573
|
-
break;
|
|
1574
|
-
|
|
1575
|
-
case BLEND_MULTIPLY:
|
|
1576
|
-
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
|
|
1577
|
-
glBlendFuncSeparate(GL_ZERO, GL_SRC_COLOR, GL_ONE, GL_ONE);
|
|
1578
|
-
break;
|
|
1579
|
-
|
|
1580
|
-
case BLEND_SCREEN:
|
|
1581
|
-
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
|
|
1582
|
-
glBlendFuncSeparate(GL_ONE_MINUS_DST_COLOR, GL_ONE, GL_ONE, GL_ONE);
|
|
1583
|
-
break;
|
|
1584
|
-
|
|
1585
|
-
case BLEND_REPLACE:
|
|
1586
|
-
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
|
|
1587
|
-
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO);
|
|
1588
|
-
break;
|
|
1589
|
-
|
|
1590
|
-
default:
|
|
1591
|
-
argument_error(__FILE__, __LINE__, "unknown blend mode");
|
|
1592
|
-
break;
|
|
1593
|
-
}
|
|
1594
|
-
OpenGL_check_error(__FILE__, __LINE__);
|
|
1595
|
-
}
|
|
1596
|
-
|
|
1597
713
|
BlendMode
|
|
1598
714
|
Painter::blend_mode () const
|
|
1599
715
|
{
|
|
@@ -1610,7 +726,7 @@ namespace Rays
|
|
|
1610
726
|
Painter::set_clip (const Bounds& bounds)
|
|
1611
727
|
{
|
|
1612
728
|
self->state.clip = bounds;
|
|
1613
|
-
|
|
729
|
+
Painter_update_clip(this);
|
|
1614
730
|
}
|
|
1615
731
|
|
|
1616
732
|
void
|
|
@@ -1728,7 +844,7 @@ namespace Rays
|
|
|
1728
844
|
|
|
1729
845
|
self->state = self->state_stack.back();
|
|
1730
846
|
self->state_stack.pop_back();
|
|
1731
|
-
|
|
847
|
+
Painter_update_clip(this);
|
|
1732
848
|
}
|
|
1733
849
|
|
|
1734
850
|
void
|