rays 0.1.11 → 0.1.16
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 +5 -5
- data/.doc/ext/rays/bitmap.cpp +22 -76
- data/.doc/ext/rays/bounds.cpp +95 -125
- data/.doc/ext/rays/camera.cpp +88 -0
- data/.doc/ext/rays/color.cpp +223 -45
- data/.doc/ext/rays/color_space.cpp +146 -46
- data/.doc/ext/rays/defs.cpp +183 -0
- data/.doc/ext/rays/font.cpp +69 -21
- data/.doc/ext/rays/image.cpp +26 -37
- data/.doc/ext/rays/matrix.cpp +186 -29
- data/.doc/ext/rays/native.cpp +14 -8
- data/.doc/ext/rays/noise.cpp +53 -0
- data/.doc/ext/rays/painter.cpp +187 -292
- data/.doc/ext/rays/point.cpp +96 -77
- data/.doc/ext/rays/polygon.cpp +313 -0
- data/.doc/ext/rays/polygon_line.cpp +96 -0
- data/.doc/ext/rays/polyline.cpp +167 -0
- data/.doc/ext/rays/rays.cpp +103 -12
- data/.doc/ext/rays/shader.cpp +83 -9
- data/LICENSE +21 -0
- data/README.md +1 -1
- data/Rakefile +24 -9
- data/VERSION +1 -1
- data/ext/rays/bitmap.cpp +22 -80
- data/ext/rays/bounds.cpp +100 -128
- data/ext/rays/camera.cpp +94 -0
- data/ext/rays/color.cpp +231 -51
- data/ext/rays/color_space.cpp +149 -47
- data/ext/rays/defs.cpp +183 -0
- data/ext/rays/defs.h +26 -2
- data/ext/rays/extconf.rb +2 -3
- data/ext/rays/font.cpp +74 -24
- data/ext/rays/image.cpp +28 -40
- data/ext/rays/matrix.cpp +198 -30
- data/ext/rays/native.cpp +14 -8
- data/ext/rays/noise.cpp +55 -0
- data/ext/rays/painter.cpp +203 -298
- data/ext/rays/point.cpp +105 -81
- data/ext/rays/polygon.cpp +329 -0
- data/ext/rays/polygon_line.cpp +99 -0
- data/ext/rays/polyline.cpp +176 -0
- data/ext/rays/rays.cpp +103 -13
- data/ext/rays/shader.cpp +84 -9
- data/include/rays.h +10 -2
- data/include/rays/bitmap.h +14 -26
- data/include/rays/bounds.h +21 -4
- data/include/rays/camera.h +49 -0
- data/include/rays/color.h +25 -14
- data/include/rays/color_space.h +15 -10
- data/include/rays/coord.h +114 -0
- data/include/rays/debug.h +22 -0
- data/include/rays/defs.h +36 -0
- data/include/rays/exception.h +6 -2
- data/include/rays/font.h +4 -4
- data/include/rays/image.h +12 -18
- data/include/rays/matrix.h +50 -24
- data/include/rays/noise.h +42 -0
- data/include/rays/opengl.h +2 -50
- data/include/rays/painter.h +89 -93
- data/include/rays/point.h +44 -51
- data/include/rays/polygon.h +198 -0
- data/include/rays/polyline.h +71 -0
- data/include/rays/rays.h +3 -0
- data/include/rays/ruby.h +7 -1
- data/include/rays/ruby/bounds.h +1 -1
- data/include/rays/ruby/camera.h +41 -0
- data/include/rays/ruby/color.h +1 -1
- data/include/rays/ruby/color_space.h +1 -1
- data/include/rays/ruby/font.h +1 -1
- data/include/rays/ruby/matrix.h +1 -1
- data/include/rays/ruby/point.h +1 -1
- data/include/rays/ruby/polygon.h +52 -0
- data/include/rays/ruby/polyline.h +41 -0
- data/include/rays/ruby/rays.h +8 -0
- data/include/rays/ruby/shader.h +1 -1
- data/include/rays/shader.h +36 -8
- data/lib/rays.rb +7 -2
- data/lib/rays/bitmap.rb +0 -15
- data/lib/rays/bounds.rb +17 -23
- data/lib/rays/camera.rb +21 -0
- data/lib/rays/color.rb +20 -47
- data/lib/rays/color_space.rb +13 -13
- data/lib/rays/image.rb +3 -7
- data/lib/rays/matrix.rb +28 -0
- data/lib/rays/module.rb +4 -19
- data/lib/rays/painter.rb +78 -93
- data/lib/rays/point.rb +13 -21
- data/lib/rays/polygon.rb +58 -0
- data/lib/rays/polygon_line.rb +36 -0
- data/lib/rays/polyline.rb +32 -0
- data/lib/rays/shader.rb +20 -1
- data/rays.gemspec +5 -7
- data/src/bitmap.h +36 -0
- data/src/bounds.cpp +74 -11
- data/src/color.cpp +58 -23
- data/src/color_space.cpp +52 -34
- data/src/color_space.h +22 -0
- data/src/coord.cpp +170 -0
- data/src/coord.h +35 -0
- data/src/font.cpp +118 -0
- data/src/font.h +64 -0
- data/src/frame_buffer.cpp +37 -71
- data/src/frame_buffer.h +4 -4
- data/src/image.cpp +172 -98
- data/src/image.h +25 -0
- data/src/ios/bitmap.h +21 -0
- data/src/ios/bitmap.mm +129 -110
- data/src/ios/camera.mm +236 -0
- data/src/ios/font.mm +50 -62
- data/src/ios/helper.h +2 -2
- data/src/ios/opengl.mm +19 -4
- data/src/ios/rays.mm +3 -0
- data/src/matrix.cpp +111 -26
- data/src/matrix.h +30 -0
- data/src/noise.cpp +74 -0
- data/src/opengl.cpp +9 -27
- data/src/opengl.h +37 -0
- data/src/osx/bitmap.h +21 -0
- data/src/osx/bitmap.mm +129 -110
- data/src/osx/camera.mm +236 -0
- data/src/osx/font.mm +49 -62
- data/src/osx/helper.h +2 -2
- data/src/osx/opengl.mm +19 -83
- data/src/osx/rays.mm +3 -0
- data/src/painter.cpp +845 -671
- data/src/painter.h +24 -0
- data/src/point.cpp +140 -119
- data/src/polygon.cpp +1266 -0
- data/src/polygon.h +32 -0
- data/src/polyline.cpp +160 -0
- data/src/polyline.h +69 -0
- data/src/render_buffer.cpp +11 -4
- data/src/render_buffer.h +2 -2
- data/src/shader.cpp +163 -106
- data/src/shader.h +38 -0
- data/src/shader_program.cpp +533 -0
- data/src/{program.h → shader_program.h} +28 -16
- data/src/shader_source.cpp +140 -0
- data/src/shader_source.h +52 -0
- data/src/texture.cpp +136 -160
- data/src/texture.h +65 -0
- data/src/win32/bitmap.cpp +62 -52
- data/src/win32/font.cpp +11 -13
- data/src/win32/font.h +24 -0
- data/src/win32/gdi.h +6 -6
- data/test/helper.rb +0 -3
- data/test/test_bitmap.rb +31 -7
- data/test/test_bounds.rb +36 -0
- data/test/test_color.rb +59 -19
- data/test/test_color_space.rb +95 -0
- data/test/test_font.rb +5 -0
- data/test/test_image.rb +24 -20
- data/test/test_matrix.rb +106 -0
- data/test/test_painter.rb +157 -51
- data/test/test_painter_shape.rb +102 -0
- data/test/test_point.rb +29 -0
- data/test/test_polygon.rb +234 -0
- data/test/test_polygon_line.rb +167 -0
- data/test/test_polyline.rb +171 -0
- data/test/test_shader.rb +9 -9
- metadata +102 -70
- data/.doc/ext/rays/texture.cpp +0 -138
- data/ext/rays/texture.cpp +0 -149
- data/include/rays/ruby/texture.h +0 -41
- data/include/rays/texture.h +0 -71
- data/lib/rays/texture.rb +0 -24
- data/src/program.cpp +0 -648
- data/test/test_texture.rb +0 -27
data/src/osx/rays.mm
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
|
5
5
|
#import <Foundation/Foundation.h>
|
6
6
|
#include "rays/exception.h"
|
7
|
+
#include "../opengl.h"
|
7
8
|
|
8
9
|
|
9
10
|
namespace Rays
|
@@ -27,6 +28,8 @@ namespace Rays
|
|
27
28
|
rays_error(__FILE__, __LINE__, "Rays::init(): already initialized.");
|
28
29
|
|
29
30
|
global::pool = [[NSAutoreleasePool alloc] init];
|
31
|
+
|
32
|
+
OpenGL_set_context(get_offscreen_context());
|
30
33
|
}
|
31
34
|
|
32
35
|
void
|
data/src/painter.cpp
CHANGED
@@ -1,22 +1,28 @@
|
|
1
|
-
#include "
|
1
|
+
#include "painter.h"
|
2
2
|
|
3
3
|
|
4
4
|
#include <math.h>
|
5
|
-
#include <
|
5
|
+
#include <assert.h>
|
6
|
+
#include <memory>
|
7
|
+
#include <vector>
|
6
8
|
#include <algorithm>
|
7
|
-
#include <
|
9
|
+
#include <glm/gtc/matrix_transform.hpp>
|
8
10
|
#include "rays/exception.h"
|
9
11
|
#include "rays/point.h"
|
10
12
|
#include "rays/bounds.h"
|
11
13
|
#include "rays/color.h"
|
12
|
-
#include "rays/
|
13
|
-
#include "
|
14
|
-
#include "
|
15
|
-
#include "
|
16
|
-
#include "
|
17
|
-
#include "
|
14
|
+
#include "rays/debug.h"
|
15
|
+
#include "opengl.h"
|
16
|
+
#include "matrix.h"
|
17
|
+
#include "polygon.h"
|
18
|
+
#include "bitmap.h"
|
19
|
+
#include "texture.h"
|
20
|
+
#include "image.h"
|
21
|
+
#include "font.h"
|
18
22
|
#include "frame_buffer.h"
|
19
|
-
#include "
|
23
|
+
#include "shader.h"
|
24
|
+
#include "shader_program.h"
|
25
|
+
#include "shader_source.h"
|
20
26
|
|
21
27
|
|
22
28
|
namespace Rays
|
@@ -35,152 +41,528 @@ namespace Rays
|
|
35
41
|
};// ColorType
|
36
42
|
|
37
43
|
|
38
|
-
|
44
|
+
struct State
|
45
|
+
{
|
39
46
|
|
40
|
-
|
47
|
+
Color background, colors[2];
|
41
48
|
|
49
|
+
coord stroke_width;
|
42
50
|
|
43
|
-
|
44
|
-
{
|
51
|
+
CapType stroke_cap;
|
45
52
|
|
46
|
-
|
53
|
+
JoinType stroke_join;
|
47
54
|
|
48
|
-
|
55
|
+
coord miter_limit;
|
56
|
+
|
57
|
+
uint nsegment;
|
58
|
+
|
59
|
+
Bounds clip;
|
49
60
|
|
50
61
|
Font font;
|
51
62
|
|
63
|
+
Shader shader;
|
64
|
+
|
52
65
|
void init ()
|
53
66
|
{
|
54
|
-
clip .reset(-1);
|
55
67
|
background .reset(0, 0);
|
56
68
|
colors[FILL] .reset(1, 1);
|
57
69
|
colors[STROKE] .reset(1, 0);
|
70
|
+
stroke_width = 0;
|
71
|
+
stroke_cap = CAP_DEFAULT;
|
72
|
+
stroke_join = JOIN_DEFAULT;
|
73
|
+
miter_limit = JOIN_DEFAULT_MITER_LIMIT;
|
74
|
+
nsegment = 0;
|
75
|
+
clip .reset(-1);
|
58
76
|
font = default_font();
|
77
|
+
shader = Shader();
|
78
|
+
}
|
79
|
+
|
80
|
+
bool has_color ()
|
81
|
+
{
|
82
|
+
return colors[FILL] || colors[STROKE];
|
59
83
|
}
|
60
84
|
|
61
|
-
};//
|
85
|
+
};// State
|
62
86
|
|
63
87
|
|
64
|
-
struct
|
88
|
+
struct TextureInfo
|
65
89
|
{
|
66
90
|
|
67
|
-
|
91
|
+
const Texture& texture;
|
68
92
|
|
69
|
-
|
93
|
+
Coord2 texcoord_min, texcoord_max;
|
70
94
|
|
71
|
-
|
95
|
+
TextureInfo (
|
96
|
+
const Texture& texture,
|
97
|
+
coord x_min, coord y_min,
|
98
|
+
coord x_max, coord y_max)
|
99
|
+
: texture(texture)
|
100
|
+
{
|
101
|
+
texcoord_min.reset(x_min, y_min);
|
102
|
+
texcoord_max.reset(x_max, y_max);
|
103
|
+
}
|
72
104
|
|
73
|
-
|
105
|
+
operator bool () const
|
106
|
+
{
|
107
|
+
return
|
108
|
+
texture &&
|
109
|
+
texcoord_min.x < texcoord_max.x &&
|
110
|
+
texcoord_min.x < texcoord_max.y;
|
111
|
+
}
|
74
112
|
|
75
|
-
bool
|
113
|
+
bool operator ! () const
|
114
|
+
{
|
115
|
+
return !operator bool();
|
116
|
+
}
|
76
117
|
|
77
|
-
|
118
|
+
};// TextureInfo
|
78
119
|
|
79
|
-
GLuint current_texture;
|
80
120
|
|
81
|
-
|
121
|
+
struct OpenGLState
|
122
|
+
{
|
123
|
+
|
124
|
+
GLint viewport[4];
|
125
|
+
|
126
|
+
GLclampf color_clear[4];
|
127
|
+
|
128
|
+
GLboolean scissor_test;
|
129
|
+
GLint scissor_box[4];
|
130
|
+
|
131
|
+
GLboolean blend;
|
132
|
+
GLint blend_src_factor, blend_dst_factor;
|
133
|
+
|
134
|
+
GLint framebuffer_binding;
|
135
|
+
|
136
|
+
void push ()
|
137
|
+
{
|
138
|
+
glGetIntegerv(GL_VIEWPORT, viewport);
|
139
|
+
|
140
|
+
glGetFloatv(GL_COLOR_CLEAR_VALUE, color_clear);
|
141
|
+
|
142
|
+
glGetBooleanv(GL_SCISSOR_TEST, &scissor_test);
|
143
|
+
glGetIntegerv(GL_SCISSOR_BOX, scissor_box);
|
144
|
+
|
145
|
+
glGetBooleanv(GL_BLEND, &blend);
|
146
|
+
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blend_src_factor);
|
147
|
+
glGetIntegerv(GL_BLEND_DST_ALPHA, &blend_dst_factor);
|
148
|
+
|
149
|
+
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &framebuffer_binding);
|
150
|
+
}
|
151
|
+
|
152
|
+
void pop ()
|
153
|
+
{
|
154
|
+
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
155
|
+
|
156
|
+
glClearColor(
|
157
|
+
color_clear[0], color_clear[1], color_clear[2], color_clear[3]);
|
158
|
+
|
159
|
+
enable(GL_SCISSOR_TEST, scissor_test);
|
160
|
+
glScissor(scissor_box[0], scissor_box[1], scissor_box[2], scissor_box[3]);
|
161
|
+
|
162
|
+
enable(GL_BLEND, blend);
|
163
|
+
glBlendFunc(blend_src_factor, blend_dst_factor);
|
164
|
+
|
165
|
+
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_binding);
|
166
|
+
}
|
167
|
+
|
168
|
+
private:
|
169
|
+
|
170
|
+
void enable(GLenum type, GLboolean value)
|
171
|
+
{
|
172
|
+
if (value)
|
173
|
+
glEnable(type);
|
174
|
+
else
|
175
|
+
glDisable(type);
|
176
|
+
}
|
177
|
+
|
178
|
+
};// OpenGLState
|
179
|
+
|
180
|
+
|
181
|
+
class DefaultIndices
|
182
|
+
{
|
183
|
+
|
184
|
+
public:
|
185
|
+
|
186
|
+
void resize (size_t size)
|
187
|
+
{
|
188
|
+
indices.reserve(size);
|
189
|
+
while (indices.size() < size)
|
190
|
+
indices.emplace_back(indices.size());
|
191
|
+
}
|
192
|
+
|
193
|
+
void clear ()
|
194
|
+
{
|
195
|
+
decltype(indices)().swap(indices);
|
196
|
+
}
|
197
|
+
|
198
|
+
const uint* get () const
|
199
|
+
{
|
200
|
+
return &indices[0];
|
201
|
+
}
|
202
|
+
|
203
|
+
private:
|
204
|
+
|
205
|
+
std::vector<uint> indices;
|
206
|
+
|
207
|
+
};// DefaultIndices
|
208
|
+
|
209
|
+
|
210
|
+
template <typename COORD>
|
211
|
+
static GLenum get_gl_type ();
|
212
|
+
|
213
|
+
template <>
|
214
|
+
GLenum
|
215
|
+
get_gl_type<float> ()
|
216
|
+
{
|
217
|
+
return GL_FLOAT;
|
218
|
+
}
|
219
|
+
|
220
|
+
static const Shader&
|
221
|
+
get_default_shader_for_shape ()
|
222
|
+
{
|
223
|
+
static const Shader SHADER(
|
224
|
+
"varying vec4 " VARYING_COLOR ";"
|
225
|
+
"void main ()"
|
226
|
+
"{"
|
227
|
+
" gl_FragColor = v_Color;"
|
228
|
+
"}");
|
229
|
+
return SHADER;
|
230
|
+
}
|
231
|
+
|
232
|
+
static const Shader&
|
233
|
+
get_default_shader_for_color_texture ()
|
234
|
+
{
|
235
|
+
static const Shader SHADER(
|
236
|
+
"varying vec4 " VARYING_TEXCOORD ";"
|
237
|
+
"varying vec4 " VARYING_COLOR ";"
|
238
|
+
"vec4 sampleTexture(vec2);"
|
239
|
+
"void main ()"
|
240
|
+
"{"
|
241
|
+
" vec4 color = sampleTexture(" VARYING_TEXCOORD ".xy);"
|
242
|
+
" gl_FragColor = v_Color * color;"
|
243
|
+
"}");
|
244
|
+
return SHADER;
|
245
|
+
}
|
246
|
+
|
247
|
+
static const Shader&
|
248
|
+
get_default_shader_for_alpha_texture ()
|
249
|
+
{
|
250
|
+
static const Shader SHADER(
|
251
|
+
"varying vec4 " VARYING_TEXCOORD ";"
|
252
|
+
"varying vec4 " VARYING_COLOR ";"
|
253
|
+
"vec4 sampleTexture(vec2);"
|
254
|
+
"void main ()"
|
255
|
+
"{"
|
256
|
+
" vec4 color = sampleTexture(" VARYING_TEXCOORD ".xy);"
|
257
|
+
" gl_FragColor = vec4(v_Color.rgb, color.a);"
|
258
|
+
"}");
|
259
|
+
return SHADER;
|
260
|
+
}
|
261
|
+
|
262
|
+
|
263
|
+
struct Painter::Data
|
264
|
+
{
|
265
|
+
|
266
|
+
bool painting = false;
|
267
|
+
|
268
|
+
float pixel_density = 1;
|
269
|
+
|
270
|
+
Bounds viewport;
|
271
|
+
|
272
|
+
State state;
|
273
|
+
|
274
|
+
std::vector<State> state_stack;
|
275
|
+
|
276
|
+
Matrix position_matrix;
|
277
|
+
|
278
|
+
std::vector<Matrix> position_matrix_stack;
|
82
279
|
|
83
280
|
FrameBuffer frame_buffer;
|
84
281
|
|
85
|
-
|
282
|
+
Image text_image;
|
283
|
+
|
284
|
+
OpenGLState opengl_state;
|
86
285
|
|
87
|
-
|
286
|
+
DefaultIndices default_indices;
|
88
287
|
|
89
288
|
Data ()
|
90
|
-
: painting(false), prev_matrix_mode(0), current_texture(0),
|
91
|
-
text_image(1, 1, GRAY, true), scale_factor(1)
|
92
289
|
{
|
93
|
-
|
290
|
+
state.init();
|
291
|
+
}
|
292
|
+
|
293
|
+
void set_pixel_density (float density)
|
294
|
+
{
|
295
|
+
if (density <= 0)
|
296
|
+
argument_error(__FILE__, __LINE__, "invalid pixel_density.");
|
297
|
+
|
298
|
+
this->pixel_density = density;
|
299
|
+
text_image = Image();
|
94
300
|
}
|
95
301
|
|
96
302
|
void update_clip ()
|
97
303
|
{
|
98
|
-
|
304
|
+
const Bounds& clip = state.clip;
|
305
|
+
if (clip)
|
99
306
|
{
|
307
|
+
coord y = frame_buffer ? clip.y : viewport.h - (clip.y + clip.h);
|
100
308
|
glEnable(GL_SCISSOR_TEST);
|
101
309
|
glScissor(
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
310
|
+
pixel_density * clip.x,
|
311
|
+
pixel_density * y,
|
312
|
+
pixel_density * clip.width,
|
313
|
+
pixel_density * clip.height);
|
106
314
|
}
|
107
315
|
else
|
108
316
|
{
|
109
317
|
glDisable(GL_SCISSOR_TEST);
|
110
318
|
}
|
111
319
|
|
112
|
-
|
320
|
+
OpenGL_check_error(__FILE__, __LINE__);
|
113
321
|
}
|
114
322
|
|
115
|
-
bool
|
323
|
+
bool get_color (Color* color, ColorType type)
|
116
324
|
{
|
117
|
-
const Color& c =
|
118
|
-
if (c
|
325
|
+
const Color& c = state.colors[type];
|
326
|
+
if (!c) return false;
|
119
327
|
|
120
|
-
|
328
|
+
*color = c;
|
121
329
|
return true;
|
122
330
|
}
|
123
331
|
|
124
|
-
void
|
125
|
-
GLenum mode,
|
126
|
-
|
127
|
-
|
128
|
-
const
|
332
|
+
void draw_polygon (
|
333
|
+
GLenum mode, const Color& color,
|
334
|
+
const Coord3* points, size_t npoints,
|
335
|
+
const uint* indices = NULL, size_t nindices = 0,
|
336
|
+
const Coord3* texcoords = NULL,
|
337
|
+
const Shader& default_shader = get_default_shader_for_shape(),
|
338
|
+
const TextureInfo* texinfo = NULL)
|
129
339
|
{
|
130
|
-
if (
|
340
|
+
if (!points || npoints <= 0)
|
131
341
|
argument_error(__FILE__, __LINE__);
|
132
342
|
|
133
343
|
if (!painting)
|
134
344
|
invalid_state_error(__FILE__, __LINE__, "'painting' should be true.");
|
135
345
|
|
136
|
-
|
346
|
+
if (!indices || nindices <= 0)
|
347
|
+
{
|
348
|
+
default_indices.resize(npoints);
|
349
|
+
indices = default_indices.get();
|
350
|
+
nindices = npoints;
|
351
|
+
}
|
137
352
|
|
138
|
-
if (
|
353
|
+
if (!texcoords)
|
354
|
+
texcoords = points;
|
355
|
+
|
356
|
+
const ShaderProgram* program = Shader_get_program(state.shader);
|
357
|
+
if (!program || !*program)
|
139
358
|
{
|
359
|
+
program = Shader_get_program(default_shader);
|
360
|
+
if (!program || !*program) return;
|
361
|
+
}
|
362
|
+
|
363
|
+
ShaderProgram_activate(*program);
|
364
|
+
apply_builtin_uniforms(*program, texinfo);
|
365
|
+
|
366
|
+
GLint a_position = glGetAttribLocation(program->id(), ATTRIB_POSITION);
|
367
|
+
GLint a_texcoord = glGetAttribLocation(program->id(), ATTRIB_TEXCOORD);
|
368
|
+
GLint a_color = glGetAttribLocation(program->id(), ATTRIB_COLOR);
|
369
|
+
if (a_position < 0 || a_texcoord < 0 || a_color < 0)
|
370
|
+
opengl_error(__FILE__, __LINE__);
|
371
|
+
|
372
|
+
setup_vertices(
|
373
|
+
points, npoints, texcoords, color, a_position, a_texcoord, a_color);
|
374
|
+
//activate_texture(texture);
|
375
|
+
|
376
|
+
glDrawElements(mode, (GLsizei) nindices, GL_UNSIGNED_INT, indices);
|
377
|
+
OpenGL_check_error(__FILE__, __LINE__);
|
378
|
+
|
379
|
+
//deactivate_texture(texture);
|
380
|
+
cleanup_vertices(a_position, a_texcoord);
|
381
|
+
|
382
|
+
ShaderProgram_deactivate();
|
383
|
+
}
|
384
|
+
|
385
|
+
private:
|
386
|
+
|
387
|
+
void apply_builtin_uniforms (
|
388
|
+
const ShaderProgram& program, const TextureInfo* texinfo)
|
389
|
+
{
|
390
|
+
GLint pos_matrix_loc =
|
391
|
+
glGetUniformLocation(program.id(), UNIFORM_POSITION_MATRIX);
|
392
|
+
if (pos_matrix_loc >= 0)
|
393
|
+
{
|
394
|
+
glUniformMatrix4fv(
|
395
|
+
pos_matrix_loc, 1, GL_FALSE, position_matrix.array);
|
396
|
+
OpenGL_check_error(__FILE__, __LINE__);
|
397
|
+
}
|
398
|
+
|
399
|
+
GLint texcoord_matrix_loc =
|
400
|
+
glGetUniformLocation(program.id(), UNIFORM_TEXCOORD_MATRIX);
|
401
|
+
if (texcoord_matrix_loc >= 0)
|
402
|
+
{
|
403
|
+
static const Matrix TEXCOORD_MATRIX(1);
|
404
|
+
glUniformMatrix4fv(
|
405
|
+
texcoord_matrix_loc, 1, GL_FALSE, TEXCOORD_MATRIX.array);
|
406
|
+
OpenGL_check_error(__FILE__, __LINE__);
|
407
|
+
}
|
408
|
+
|
409
|
+
apply_texture_uniforms(program, texinfo);
|
410
|
+
}
|
411
|
+
|
412
|
+
void apply_texture_uniforms (
|
413
|
+
const ShaderProgram& program, const TextureInfo* texinfo)
|
414
|
+
{
|
415
|
+
if (!texinfo || !*texinfo) return;
|
416
|
+
|
417
|
+
const Texture& texture = texinfo->texture;
|
418
|
+
|
419
|
+
GLint texture_loc =
|
420
|
+
glGetUniformLocation(program.id(), UNIFORM_TEXTURE);
|
421
|
+
if (texture_loc >= 0)
|
422
|
+
{
|
423
|
+
glActiveTexture(GL_TEXTURE0);
|
424
|
+
glBindTexture(GL_TEXTURE_2D, texture.id());
|
425
|
+
|
426
|
+
glUniform1i(texture_loc, 0);
|
427
|
+
OpenGL_check_error(__FILE__, __LINE__);
|
428
|
+
}
|
429
|
+
|
430
|
+
GLint size_loc =
|
431
|
+
glGetUniformLocation(program.id(), UNIFORM_TEXTURE_SIZE);
|
432
|
+
if (size_loc >= 0)
|
433
|
+
{
|
434
|
+
glUniform2f(
|
435
|
+
size_loc, texture.reserved_width(), texture.reserved_height());
|
436
|
+
OpenGL_check_error(__FILE__, __LINE__);
|
437
|
+
}
|
438
|
+
|
439
|
+
GLint min_loc =
|
440
|
+
glGetUniformLocation(program.id(), UNIFORM_TEXCOORD_MIN);
|
441
|
+
if (min_loc >= 0)
|
442
|
+
{
|
443
|
+
glUniform2fv(min_loc, 1, texinfo->texcoord_min.array);
|
444
|
+
OpenGL_check_error(__FILE__, __LINE__);
|
445
|
+
}
|
446
|
+
|
447
|
+
GLint max_loc =
|
448
|
+
glGetUniformLocation(program.id(), UNIFORM_TEXCOORD_MAX);
|
449
|
+
if (max_loc >= 0)
|
450
|
+
{
|
451
|
+
glUniform2fv(max_loc, 1, texinfo->texcoord_max.array);
|
452
|
+
OpenGL_check_error(__FILE__, __LINE__);
|
453
|
+
}
|
454
|
+
}
|
455
|
+
|
456
|
+
void setup_vertices (
|
457
|
+
const Coord3* points, size_t npoints,
|
458
|
+
const Coord3* texcoords, const Color& color,
|
459
|
+
GLuint a_position, GLuint a_texcoord, GLuint a_color)
|
460
|
+
{
|
461
|
+
assert(points && npoints >= 0 && texcoords);
|
462
|
+
|
463
|
+
glEnableVertexAttribArray(a_position);
|
464
|
+
glVertexAttribPointer(
|
465
|
+
a_position, Coord3::SIZE, get_gl_type<coord>(),
|
466
|
+
GL_FALSE, sizeof(Coord3), points);
|
467
|
+
OpenGL_check_error(__FILE__, __LINE__);
|
468
|
+
|
469
|
+
glEnableVertexAttribArray(a_texcoord);
|
470
|
+
glVertexAttribPointer(
|
471
|
+
a_texcoord, Coord3::SIZE, get_gl_type<coord>(),
|
472
|
+
GL_FALSE, sizeof(Coord3), texcoords);
|
473
|
+
OpenGL_check_error(__FILE__, __LINE__);
|
474
|
+
|
475
|
+
glVertexAttrib4fv(a_color, color.array);
|
476
|
+
}
|
477
|
+
|
478
|
+
void cleanup_vertices (GLint a_position, GLint a_texcoord)
|
479
|
+
{
|
480
|
+
glDisableVertexAttribArray(a_position);
|
481
|
+
glDisableVertexAttribArray(a_texcoord);
|
482
|
+
OpenGL_check_error(__FILE__, __LINE__);
|
483
|
+
}
|
484
|
+
|
485
|
+
void activate_texture (const Texture* texture)
|
486
|
+
{
|
487
|
+
if (!texture)
|
488
|
+
{
|
489
|
+
glDisable(GL_TEXTURE_2D);
|
490
|
+
return;
|
491
|
+
}
|
492
|
+
|
140
493
|
if (!*texture)
|
141
494
|
argument_error(__FILE__, __LINE__, "invalid texture.");
|
142
495
|
|
143
496
|
GLuint id = texture->id();
|
144
|
-
if (id !=
|
145
|
-
{
|
497
|
+
if (id != get_current_texture_id())
|
146
498
|
glBindTexture(GL_TEXTURE_2D, id);
|
147
|
-
current_texture = id;
|
148
|
-
}
|
149
499
|
|
150
500
|
glEnable(GL_TEXTURE_2D);
|
501
|
+
}
|
151
502
|
|
152
|
-
|
153
|
-
|
503
|
+
GLuint get_current_texture_id ()
|
504
|
+
{
|
505
|
+
GLint id = 0;
|
506
|
+
glGetIntegerv(GL_TEXTURE_BINDING_2D, &id);
|
507
|
+
return (GLuint) id;
|
154
508
|
}
|
155
|
-
|
509
|
+
|
510
|
+
void deactivate_texture (const Texture* texture)
|
156
511
|
{
|
512
|
+
if (!texture) return;
|
513
|
+
|
157
514
|
glDisable(GL_TEXTURE_2D);
|
158
|
-
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
159
515
|
}
|
160
516
|
|
161
|
-
|
162
|
-
glVertexPointer(vertex_size, GL_FLOAT, 0, vertices);
|
517
|
+
};// Painter::Data
|
163
518
|
|
164
|
-
glDrawElements(mode, nindices, GL_UNSIGNED_INT, indices);
|
165
519
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
520
|
+
static void
|
521
|
+
draw_polygon (
|
522
|
+
Painter* painter,
|
523
|
+
const GLenum* modes,
|
524
|
+
coord offset_x, coord offset_y,
|
525
|
+
bool nofill, bool nostroke,
|
526
|
+
const Coord3* points, size_t npoints,
|
527
|
+
const uint* indices = NULL, size_t nindices = 0,
|
528
|
+
const Coord3* texcoords = NULL,
|
529
|
+
const Shader& default_shader = get_default_shader_for_shape(),
|
530
|
+
const TextureInfo* texinfo = NULL)
|
531
|
+
{
|
532
|
+
assert(painter);
|
533
|
+
|
534
|
+
bool offset = offset_x != 0 || offset_y != 0;
|
535
|
+
if (offset)
|
536
|
+
{
|
537
|
+
painter->push_matrix();
|
538
|
+
painter->translate(offset_x, offset_y);
|
172
539
|
}
|
173
540
|
|
174
|
-
|
541
|
+
Color color;
|
542
|
+
for (int type = COLOR_TYPE_BEGIN; type < COLOR_TYPE_END; ++type)
|
543
|
+
{
|
544
|
+
if ((nofill && type == FILL) || (nostroke && type == STROKE))
|
545
|
+
continue;
|
546
|
+
|
547
|
+
if (!painter->self->get_color(&color, (ColorType) type))
|
548
|
+
continue;
|
549
|
+
|
550
|
+
painter->self->draw_polygon(
|
551
|
+
modes[type], color, points, npoints, indices, nindices, texcoords,
|
552
|
+
default_shader, texinfo);
|
553
|
+
}
|
175
554
|
|
555
|
+
if (offset)
|
556
|
+
painter->pop_matrix();
|
557
|
+
}
|
176
558
|
|
177
559
|
void
|
178
|
-
|
560
|
+
Painter_draw_polygon (
|
561
|
+
Painter* painter, GLenum mode, const Color& color,
|
562
|
+
const Coord3* points, size_t npoints,
|
563
|
+
const uint* indices, size_t nindices)
|
179
564
|
{
|
180
|
-
|
181
|
-
argument_error(__FILE__, __LINE__, "invalid texture.");
|
182
|
-
|
183
|
-
painter->self->scale_factor = factor;
|
565
|
+
painter->self->draw_polygon(mode, color, points, npoints, indices, nindices);
|
184
566
|
}
|
185
567
|
|
186
568
|
|
@@ -193,53 +575,57 @@ namespace Rays
|
|
193
575
|
}
|
194
576
|
|
195
577
|
void
|
196
|
-
Painter::canvas (
|
578
|
+
Painter::canvas (
|
579
|
+
coord x, coord y, coord width, coord height, float pixel_density)
|
197
580
|
{
|
198
|
-
canvas(Bounds(x, y, -100, width, height, 200));
|
581
|
+
canvas(Bounds(x, y, -100, width, height, 200), pixel_density);
|
199
582
|
}
|
200
583
|
|
201
584
|
void
|
202
|
-
Painter::canvas (
|
585
|
+
Painter::canvas (
|
586
|
+
coord x, coord y, coord z, coord width, coord height, coord depth,
|
587
|
+
float pixel_density)
|
203
588
|
{
|
204
|
-
canvas(Bounds(x, y, z, width, height, depth));
|
589
|
+
canvas(Bounds(x, y, z, width, height, depth), pixel_density);
|
205
590
|
}
|
206
591
|
|
207
592
|
void
|
208
|
-
Painter::canvas (const Bounds&
|
593
|
+
Painter::canvas (const Bounds& viewport, float pixel_density)
|
209
594
|
{
|
210
|
-
if (!
|
595
|
+
if (!viewport)
|
211
596
|
argument_error(__FILE__, __LINE__);
|
212
597
|
|
213
598
|
if (self->painting)
|
214
|
-
invalid_state_error(__FILE__, __LINE__, "
|
599
|
+
invalid_state_error(__FILE__, __LINE__, "painting flag should be false.");
|
215
600
|
|
216
|
-
self->viewport =
|
601
|
+
self->viewport = viewport;
|
602
|
+
self->set_pixel_density(pixel_density);
|
217
603
|
}
|
218
604
|
|
219
605
|
void
|
220
|
-
Painter::bind (const
|
606
|
+
Painter::bind (const Image& image)
|
221
607
|
{
|
222
|
-
if (!
|
223
|
-
argument_error(__FILE__, __LINE__, "invalid
|
608
|
+
if (!image)
|
609
|
+
argument_error(__FILE__, __LINE__, "invalid image.");
|
224
610
|
|
225
611
|
if (self->painting)
|
226
|
-
invalid_state_error(__FILE__, __LINE__, "
|
612
|
+
invalid_state_error(__FILE__, __LINE__, "painting flag should be false.");
|
227
613
|
|
228
|
-
FrameBuffer fb(
|
614
|
+
FrameBuffer fb(Image_get_texture(image));
|
229
615
|
if (!fb)
|
230
616
|
rays_error(__FILE__, __LINE__, "invalid frame buffer.");
|
231
617
|
|
232
618
|
unbind();
|
233
619
|
|
234
620
|
self->frame_buffer = fb;
|
235
|
-
canvas(0, 0,
|
621
|
+
canvas(0, 0, image.width(), image.height(), image.pixel_density());
|
236
622
|
}
|
237
623
|
|
238
624
|
void
|
239
625
|
Painter::unbind ()
|
240
626
|
{
|
241
627
|
if (self->painting)
|
242
|
-
invalid_state_error(__FILE__, __LINE__, "
|
628
|
+
invalid_state_error(__FILE__, __LINE__, "painting flag should be true.");
|
243
629
|
|
244
630
|
self->frame_buffer = FrameBuffer();
|
245
631
|
}
|
@@ -250,104 +636,74 @@ namespace Rays
|
|
250
636
|
return self->viewport;
|
251
637
|
}
|
252
638
|
|
639
|
+
float
|
640
|
+
Painter::pixel_density () const
|
641
|
+
{
|
642
|
+
return self->pixel_density;
|
643
|
+
}
|
253
644
|
|
254
645
|
void
|
255
646
|
Painter::begin ()
|
256
647
|
{
|
257
648
|
if (self->painting)
|
258
|
-
invalid_state_error(__FILE__, __LINE__, "
|
649
|
+
invalid_state_error(__FILE__, __LINE__, "painting flag should be false.");
|
259
650
|
|
260
|
-
|
261
|
-
if (fb) bind_frame_buffer(fb.id());
|
651
|
+
self->opengl_state.push();
|
262
652
|
|
263
|
-
|
264
|
-
|
653
|
+
//glEnable(GL_CULL_FACE);
|
654
|
+
glEnable(GL_BLEND);
|
655
|
+
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
|
656
|
+
OpenGL_check_error(__FILE__, __LINE__);
|
657
|
+
|
658
|
+
FrameBuffer& fb = self->frame_buffer;
|
659
|
+
if (fb) FrameBuffer_bind(fb.id());
|
265
660
|
|
266
661
|
const Bounds& vp = self->viewport;
|
267
|
-
float
|
662
|
+
float density = self->pixel_density;
|
268
663
|
glViewport(
|
269
|
-
(int) vp.x,
|
270
|
-
(int) vp.width
|
664
|
+
(int) (vp.x * density), (int) (vp.y * density),
|
665
|
+
(int) (vp.width * density), (int) (vp.height * density));
|
666
|
+
OpenGL_check_error(__FILE__, __LINE__);
|
271
667
|
|
272
668
|
coord x1 = vp.x, x2 = vp.x + vp.width;
|
273
669
|
coord y1 = vp.y, y2 = vp.y + vp.height;
|
274
670
|
coord z1 = vp.z, z2 = vp.z + vp.depth;
|
275
671
|
if (z1 == 0 && z2 == 0) {z1 = -100; z2 = 200;}
|
276
|
-
if (!fb)
|
277
|
-
|
278
|
-
glGetIntegerv(GL_MATRIX_MODE, (GLint*) &self->prev_matrix_mode);
|
279
|
-
|
280
|
-
glMatrixMode(GL_PROJECTION);
|
281
|
-
glPushMatrix();
|
282
|
-
glLoadIdentity();
|
283
|
-
glOrtho(x1, x2, y1, y2, z1, z2);
|
672
|
+
if (!fb) std::swap(y1, y2);
|
284
673
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
glTranslatef(0.375f, 0.375f, 0);
|
674
|
+
self->position_matrix.reset(1);
|
675
|
+
self->position_matrix *= to_rays(glm::ortho(x1, x2, y1, y2));
|
676
|
+
//self->position_matrix.translate(0.375f, 0.375f);
|
289
677
|
|
290
|
-
|
291
|
-
glPushMatrix();
|
292
|
-
glLoadIdentity();
|
293
|
-
|
294
|
-
#ifndef IOS
|
295
|
-
glMatrixMode(GL_COLOR);
|
296
|
-
glPushMatrix();
|
297
|
-
glLoadIdentity();
|
298
|
-
#endif
|
299
|
-
|
300
|
-
glMatrixMode(GL_MODELVIEW);
|
301
|
-
|
302
|
-
//glEnable(GL_CULL_FACE);
|
303
|
-
glEnable(GL_BLEND);
|
304
|
-
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
305
|
-
|
306
|
-
check_error(__FILE__, __LINE__);
|
678
|
+
self->update_clip();
|
307
679
|
|
308
680
|
self->painting = true;
|
309
|
-
|
310
|
-
no_clip();
|
311
681
|
}
|
312
682
|
|
313
683
|
void
|
314
684
|
Painter::end ()
|
315
685
|
{
|
316
686
|
if (!self->painting)
|
317
|
-
invalid_state_error(__FILE__, __LINE__, "
|
318
|
-
|
319
|
-
self->painting = false;
|
320
|
-
|
321
|
-
glDisable(GL_BLEND);
|
322
|
-
glDisable(GL_CULL_FACE);
|
323
|
-
|
324
|
-
glMatrixMode(GL_PROJECTION);
|
325
|
-
glPopMatrix();
|
326
|
-
|
327
|
-
glMatrixMode(GL_MODELVIEW);
|
328
|
-
glPopMatrix();
|
687
|
+
invalid_state_error(__FILE__, __LINE__, "painting flag should be true.");
|
329
688
|
|
330
|
-
|
331
|
-
|
689
|
+
if (!self->state_stack.empty())
|
690
|
+
invalid_state_error(__FILE__, __LINE__, "state stack is not empty.");
|
332
691
|
|
333
|
-
|
334
|
-
|
335
|
-
glPopMatrix();
|
336
|
-
#endif
|
692
|
+
if (!self->position_matrix_stack.empty())
|
693
|
+
invalid_state_error(__FILE__, __LINE__, "position matrix stack is not empty.");
|
337
694
|
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
pop_attr();
|
695
|
+
self->painting = false;
|
696
|
+
self->opengl_state.pop();
|
697
|
+
self->default_indices.clear();
|
342
698
|
|
343
|
-
|
699
|
+
glFinish();
|
344
700
|
|
345
701
|
if (self->frame_buffer)
|
346
702
|
{
|
347
|
-
|
703
|
+
FrameBuffer_unbind();
|
348
704
|
|
349
705
|
Texture& tex = self->frame_buffer.texture();
|
350
|
-
if (tex) tex.
|
706
|
+
if (tex) tex.set_modified();
|
351
707
|
}
|
352
708
|
}
|
353
709
|
|
@@ -355,388 +711,243 @@ namespace Rays
|
|
355
711
|
Painter::clear ()
|
356
712
|
{
|
357
713
|
if (!self->painting)
|
358
|
-
invalid_state_error(__FILE__, __LINE__, "
|
714
|
+
invalid_state_error(__FILE__, __LINE__, "painting flag should be true.");
|
359
715
|
|
360
|
-
const Color& c = self->
|
716
|
+
const Color& c = self->state.background;
|
361
717
|
glClearColor(c.red, c.green, c.blue, c.alpha);
|
362
718
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
363
|
-
|
364
|
-
check_error(__FILE__, __LINE__);
|
719
|
+
OpenGL_check_error(__FILE__, __LINE__);
|
365
720
|
}
|
366
721
|
|
367
|
-
void
|
368
|
-
|
722
|
+
static inline void
|
723
|
+
debug_draw_triangulation (
|
724
|
+
Painter* painter, const Polygon& polygon, const Color& color)
|
369
725
|
{
|
370
|
-
|
371
|
-
|
372
|
-
0, 1
|
373
|
-
};
|
726
|
+
#ifdef _DEBUG
|
727
|
+
assert(painter);
|
374
728
|
|
375
|
-
|
729
|
+
Color invert_color(
|
730
|
+
1.f - color.red,
|
731
|
+
1.f - color.green,
|
732
|
+
1.f - color.blue);
|
376
733
|
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
if (!pself->use_color(STROKE))
|
381
|
-
return;
|
382
|
-
|
383
|
-
coord vertices[] =
|
734
|
+
Polygon::TrianglePointList triangles;
|
735
|
+
if (Polygon_triangulate(&triangles, polygon))
|
384
736
|
{
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
void
|
393
|
-
Painter::line (const Point& p1, const Point& p2)
|
394
|
-
{
|
395
|
-
line(p1.x, p1.y, p2.x, p2.y);
|
737
|
+
for (size_t i = 0; i < triangles.size(); i += 3)
|
738
|
+
{
|
739
|
+
painter->self->draw_polygon(
|
740
|
+
GL_LINE_LOOP, invert_color, &triangles[i], 3);
|
741
|
+
}
|
742
|
+
}
|
743
|
+
#endif
|
396
744
|
}
|
397
745
|
|
398
746
|
void
|
399
|
-
Painter::
|
747
|
+
Painter::polygon (const Polygon& polygon)
|
400
748
|
{
|
401
|
-
|
402
|
-
|
403
|
-
if (!pself->painting)
|
404
|
-
invalid_state_error(__FILE__, __LINE__, "self->painting should be true.");
|
749
|
+
if (!self->painting)
|
750
|
+
invalid_state_error(__FILE__, __LINE__, "painting flag should be true.");
|
405
751
|
|
406
|
-
if (!
|
752
|
+
if (!self->state.has_color())
|
407
753
|
return;
|
408
754
|
|
409
|
-
|
410
|
-
for (size_t i = 0; i < size; ++i)
|
411
|
-
indices[i] = (uint) i;
|
412
|
-
|
413
|
-
pself->draw_shape(GL_LINES, (int) size, indices.get(), 2, (coord*) points);
|
414
|
-
}
|
415
|
-
|
416
|
-
void
|
417
|
-
Painter::lines (const Coord3* points, size_t size)
|
418
|
-
{
|
419
|
-
Data* pself = self.get();
|
420
|
-
|
421
|
-
if (!pself->painting)
|
422
|
-
invalid_state_error(__FILE__, __LINE__, "self->painting should be true.");
|
423
|
-
|
424
|
-
if (!pself->use_color(STROKE))
|
425
|
-
return;
|
755
|
+
Color color;
|
426
756
|
|
427
|
-
|
428
|
-
boost::scoped_array<Coord2> vertices(new Coord2[size]);
|
429
|
-
for (size_t i = 0; i < size; ++i)
|
757
|
+
if (self->get_color(&color, FILL))
|
430
758
|
{
|
431
|
-
|
432
|
-
|
759
|
+
Polygon_fill(polygon, this, color);
|
760
|
+
debug_draw_triangulation(this, polygon, color);
|
433
761
|
}
|
434
762
|
|
435
|
-
|
436
|
-
|
763
|
+
if (self->get_color(&color, STROKE))
|
764
|
+
Polygon_stroke(polygon, this, color);
|
437
765
|
}
|
438
766
|
|
439
767
|
void
|
440
|
-
Painter::
|
768
|
+
Painter::line (coord x1, coord y1, coord x2, coord y2)
|
441
769
|
{
|
442
|
-
|
443
|
-
|
444
|
-
if (!pself->painting)
|
445
|
-
invalid_state_error(__FILE__, __LINE__, "self->painting should be true.");
|
446
|
-
|
447
|
-
GLenum modes[] = {GL_TRIANGLE_FAN, GL_LINE_LOOP};
|
448
|
-
boost::scoped_array<uint> indices;
|
449
|
-
|
450
|
-
for (int type = COLOR_TYPE_BEGIN; type < COLOR_TYPE_END; ++type)
|
451
|
-
{
|
452
|
-
if (!pself->use_color((ColorType) type)) continue;
|
453
|
-
|
454
|
-
if (!indices.get())
|
455
|
-
{
|
456
|
-
indices.reset(new uint[size]);
|
457
|
-
for (size_t i = 0; i < size; ++i)
|
458
|
-
indices[i] = (uint) i;
|
459
|
-
}
|
460
|
-
|
461
|
-
pself->draw_shape(
|
462
|
-
modes[type], (int) size, indices.get(), 2, (coord*) points);
|
463
|
-
}
|
770
|
+
polygon(create_line(x1, y1, x2, y2));
|
464
771
|
}
|
465
772
|
|
466
773
|
void
|
467
|
-
Painter::
|
774
|
+
Painter::line (const Point& p1, const Point& p2)
|
468
775
|
{
|
469
|
-
|
470
|
-
|
471
|
-
if (!pself->painting)
|
472
|
-
invalid_state_error(__FILE__, __LINE__, "self->painting should be true.");
|
473
|
-
|
474
|
-
GLenum modes[] = {GL_TRIANGLE_FAN, GL_LINE_LOOP};
|
475
|
-
boost::scoped_array<uint> indices;
|
476
|
-
boost::scoped_array<Coord2> vertices;
|
477
|
-
|
478
|
-
for (int type = COLOR_TYPE_BEGIN; type < COLOR_TYPE_END; ++type)
|
479
|
-
{
|
480
|
-
if (!pself->use_color((ColorType) type)) continue;
|
481
|
-
|
482
|
-
if (!indices.get())
|
483
|
-
{
|
484
|
-
indices.reset(new uint[size]);
|
485
|
-
for (size_t i = 0; i < size; ++i)
|
486
|
-
indices[i] = (uint) i;
|
487
|
-
}
|
776
|
+
polygon(create_line(p1, p2));
|
777
|
+
}
|
488
778
|
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
}
|
779
|
+
void
|
780
|
+
Painter::line (const Point* points, size_t size, bool loop)
|
781
|
+
{
|
782
|
+
polygon(create_line(points, size, loop));
|
783
|
+
}
|
495
784
|
|
496
|
-
|
497
|
-
|
498
|
-
|
785
|
+
void
|
786
|
+
Painter::line (const Polyline& polyline)
|
787
|
+
{
|
788
|
+
polygon(create_line(polyline));
|
499
789
|
}
|
500
790
|
|
501
791
|
void
|
502
792
|
Painter::rect (coord x, coord y, coord width, coord height, coord round)
|
503
793
|
{
|
504
|
-
|
794
|
+
polygon(create_rect(x, y, width, height, round, nsegment()));
|
505
795
|
}
|
506
796
|
|
507
797
|
void
|
508
798
|
Painter::rect (
|
509
799
|
coord x, coord y, coord width, coord height,
|
510
|
-
coord
|
800
|
+
coord round_left_top, coord round_right_top,
|
801
|
+
coord round_left_bottom, coord round_right_bottom)
|
511
802
|
{
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
Data* pself = self.get();
|
519
|
-
|
520
|
-
if (!pself->painting)
|
521
|
-
invalid_state_error(__FILE__, __LINE__, "self->painting should be true.");
|
522
|
-
|
523
|
-
if (width <= 0 || height <= 0) return;
|
524
|
-
|
525
|
-
coord x2 = x + width - 1;
|
526
|
-
coord y2 = y + height - 1;
|
527
|
-
|
528
|
-
for (int type = COLOR_TYPE_BEGIN; type < COLOR_TYPE_END; ++type)
|
529
|
-
{
|
530
|
-
if (!pself->use_color((ColorType) type)) continue;
|
531
|
-
|
532
|
-
coord xx = x2 + 1 - type;
|
533
|
-
coord yy = y2 + 1 - type;
|
534
|
-
coord vertices[] =
|
535
|
-
{
|
536
|
-
x, y,
|
537
|
-
x, yy,
|
538
|
-
xx, yy,
|
539
|
-
xx, y
|
540
|
-
};
|
541
|
-
|
542
|
-
pself->draw_shape(MODES[type], 4, INDICES, 2, vertices);
|
543
|
-
}
|
803
|
+
polygon(create_rect(
|
804
|
+
x, y, width, height,
|
805
|
+
round_left_top, round_right_top,
|
806
|
+
round_left_bottom, round_right_bottom,
|
807
|
+
nsegment()));
|
544
808
|
}
|
545
809
|
|
546
810
|
void
|
547
811
|
Painter::rect (const Bounds& bounds, coord round)
|
548
812
|
{
|
549
|
-
|
550
|
-
bounds.x, bounds.y, bounds.width, bounds.height,
|
551
|
-
round);
|
813
|
+
polygon(create_rect(bounds, round, nsegment()));
|
552
814
|
}
|
553
815
|
|
554
816
|
void
|
555
|
-
Painter::rect (
|
817
|
+
Painter::rect (
|
818
|
+
const Bounds& bounds,
|
819
|
+
coord round_left_top, coord round_right_top,
|
820
|
+
coord round_left_bottom, coord round_right_bottom)
|
556
821
|
{
|
557
|
-
|
558
|
-
bounds
|
559
|
-
|
822
|
+
polygon(create_rect(
|
823
|
+
bounds,
|
824
|
+
round_left_top, round_right_top,
|
825
|
+
round_left_bottom, round_right_bottom,
|
826
|
+
nsegment()));
|
560
827
|
}
|
561
828
|
|
562
|
-
|
563
|
-
|
564
|
-
Painter* painter,
|
829
|
+
void
|
830
|
+
Painter::ellipse (
|
565
831
|
coord x, coord y, coord width, coord height,
|
566
|
-
|
567
|
-
|
832
|
+
const Point& hole_size,
|
833
|
+
float angle_from, float angle_to)
|
568
834
|
{
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
Painter::Data* pself = painter->self.get();
|
573
|
-
|
574
|
-
if (!pself->painting)
|
575
|
-
invalid_state_error(__FILE__, __LINE__, "self->painting should be true.");
|
576
|
-
|
577
|
-
if (height == 0) height = width;
|
578
|
-
if (nsegment <= 0) nsegment = Painter::ELLIPSE_NSEGMENT;
|
579
|
-
|
580
|
-
coord radius_x = width / 2;
|
581
|
-
coord radius_y = height / 2;
|
582
|
-
coord radius_x_min = radius_x * radius_min;
|
583
|
-
coord radius_y_min = radius_y * radius_min;
|
584
|
-
float from = angle_from / 360.f;
|
585
|
-
float to = angle_to / 360.f;
|
586
|
-
bool hole = radius_min != 0;
|
587
|
-
int nvertices = hole ? nsegment * 2 : nsegment;
|
588
|
-
GLenum modes[] =
|
589
|
-
{
|
590
|
-
(GLenum) (hole ? GL_TRIANGLE_STRIP : GL_TRIANGLE_FAN),
|
591
|
-
GL_LINE_LOOP
|
592
|
-
};
|
593
|
-
boost::scoped_array<uint> indices;
|
594
|
-
boost::scoped_array<Coord2> vertices;
|
595
|
-
|
596
|
-
x += radius_x;
|
597
|
-
y += radius_y;
|
598
|
-
|
599
|
-
for (int type = COLOR_TYPE_BEGIN; type < COLOR_TYPE_END; ++type)
|
600
|
-
{
|
601
|
-
if (!pself->use_color((ColorType) type)) continue;
|
602
|
-
|
603
|
-
if (!indices.get())
|
604
|
-
{
|
605
|
-
indices.reset(new uint[nvertices]);
|
606
|
-
for (int i = 0; i < nvertices; ++i)
|
607
|
-
indices[i] = i;
|
608
|
-
}
|
609
|
-
|
610
|
-
if (!vertices.get())
|
611
|
-
vertices.reset(new Coord2[nvertices]);
|
612
|
-
|
613
|
-
Coord2* vertex = vertices.get();
|
614
|
-
assert(vertex);
|
615
|
-
|
616
|
-
for (uint seg = 0; seg < nsegment; ++seg, ++vertex)
|
617
|
-
{
|
618
|
-
float pos = (float) seg / (float) nsegment;
|
619
|
-
float radian = (from + (to - from) * pos) * PI_2;
|
620
|
-
float xx = cos(radian);
|
621
|
-
float yy = -sin(radian);
|
622
|
-
|
623
|
-
if (hole)
|
624
|
-
vertex->reset(x + xx * radius_x_min, y + yy * radius_y_min);
|
625
|
-
vertex ->reset(x + xx * radius_x, y + yy * radius_y);
|
626
|
-
}
|
835
|
+
polygon(create_ellipse(
|
836
|
+
x, y, width, height, hole_size, angle_from, angle_to, nsegment()));
|
837
|
+
}
|
627
838
|
|
628
|
-
|
629
|
-
|
839
|
+
void
|
840
|
+
Painter::ellipse (
|
841
|
+
const Bounds& bounds,
|
842
|
+
const Point& hole_size,
|
843
|
+
float angle_from, float angle_to)
|
844
|
+
{
|
845
|
+
polygon(create_ellipse(
|
846
|
+
bounds, hole_size, angle_from, angle_to, nsegment()));
|
630
847
|
}
|
631
848
|
|
632
849
|
void
|
633
850
|
Painter::ellipse (
|
634
|
-
|
635
|
-
|
851
|
+
const Point& center, const Point& radius, const Point& hole_radius,
|
852
|
+
float angle_from, float angle_to)
|
636
853
|
{
|
637
|
-
|
854
|
+
polygon(create_ellipse(
|
855
|
+
center, radius, hole_radius, angle_from, angle_to, nsegment()));
|
638
856
|
}
|
639
857
|
|
640
858
|
void
|
641
|
-
Painter::
|
859
|
+
Painter::curve (
|
860
|
+
coord x1, coord y1, coord x2, coord y2,
|
861
|
+
coord x3, coord y3, coord x4, coord y4,
|
862
|
+
bool loop)
|
642
863
|
{
|
643
|
-
|
644
|
-
bounds.x, bounds.y, bounds.width, bounds.height, radius_min, nsegment);
|
864
|
+
polygon(create_curve(x1, y1, x2, y2, x3, y3, x4, y4, loop));
|
645
865
|
}
|
646
866
|
|
647
867
|
void
|
648
|
-
Painter::
|
649
|
-
const Point&
|
868
|
+
Painter::curve (
|
869
|
+
const Point& p1, const Point& p2, const Point& p3, const Point& p4,
|
870
|
+
bool loop)
|
650
871
|
{
|
651
|
-
|
652
|
-
center.x - radius, center.y - radius, radius * 2, radius * 2,
|
653
|
-
radius_min, nsegment);
|
872
|
+
polygon(create_curve(p1, p2, p3, p4, loop));
|
654
873
|
}
|
655
874
|
|
656
875
|
void
|
657
|
-
Painter::
|
658
|
-
coord x, coord y, coord width, coord height,
|
659
|
-
float angle_from, float angle_to, coord radius_min, uint nsegment)
|
876
|
+
Painter::curve (const Point* points, size_t size, bool loop)
|
660
877
|
{
|
661
|
-
|
662
|
-
this, x, y, width, height, angle_from, angle_to, radius_min, nsegment);
|
878
|
+
polygon(create_curve(points, size, loop));
|
663
879
|
}
|
664
880
|
|
665
881
|
void
|
666
|
-
Painter::
|
667
|
-
|
668
|
-
|
882
|
+
Painter::bezier (
|
883
|
+
coord x1, coord y1, coord x2, coord y2,
|
884
|
+
coord x3, coord y3, coord x4, coord y4,
|
885
|
+
bool loop)
|
886
|
+
{
|
887
|
+
polygon(create_bezier(x1, y1, x2, y2, x3, y3, x4, y4, loop));
|
888
|
+
}
|
889
|
+
|
890
|
+
void
|
891
|
+
Painter::bezier (
|
892
|
+
const Point& p1, const Point& p2, const Point& p3, const Point& p4,
|
893
|
+
bool loop)
|
669
894
|
{
|
670
|
-
|
671
|
-
bounds.x, bounds.y, bounds.width, bounds.height,
|
672
|
-
angle_from, angle_to, radius_min, nsegment);
|
895
|
+
polygon(create_bezier(p1, p2, p3, p4, loop));
|
673
896
|
}
|
674
897
|
|
675
898
|
void
|
676
|
-
Painter::
|
677
|
-
const Point& center, coord radius,
|
678
|
-
float angle_from, float angle_to, coord radius_min, uint nsegment)
|
899
|
+
Painter::bezier (const Point* points, size_t size, bool loop)
|
679
900
|
{
|
680
|
-
|
681
|
-
center.x, center.y, radius * 2, radius * 2,
|
682
|
-
angle_from, angle_to, radius_min, nsegment);
|
901
|
+
polygon(create_bezier(points, size, loop));
|
683
902
|
}
|
684
903
|
|
685
904
|
static void
|
686
905
|
draw_image (
|
687
|
-
Painter* painter, const
|
688
|
-
|
689
|
-
coord
|
690
|
-
bool nostroke = false)
|
906
|
+
Painter* painter, const Image& image,
|
907
|
+
coord src_x, coord src_y, coord src_w, coord src_h,
|
908
|
+
coord dst_x, coord dst_y, coord dst_w, coord dst_h,
|
909
|
+
bool nostroke = false, const Shader* shader = NULL)
|
691
910
|
{
|
692
911
|
static const GLenum MODES[] = {GL_TRIANGLE_FAN, GL_LINE_LOOP};
|
693
|
-
static const uint INDICES[] =
|
694
|
-
{
|
695
|
-
0, 1, 2, 3
|
696
|
-
};
|
697
912
|
|
698
|
-
assert(
|
913
|
+
assert(painter && image);
|
699
914
|
|
700
|
-
|
701
|
-
argument_error(__FILE__, __LINE__);
|
915
|
+
Painter::Data* self = painter->self.get();
|
702
916
|
|
703
|
-
|
917
|
+
if (!self->painting)
|
918
|
+
invalid_state_error(__FILE__, __LINE__, "painting flag should be true.");
|
704
919
|
|
705
|
-
if (!
|
706
|
-
|
920
|
+
if (!self->state.has_color())
|
921
|
+
return;
|
707
922
|
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
{
|
712
|
-
x, y,
|
713
|
-
x, y2,
|
714
|
-
x2, y2,
|
715
|
-
x2, y
|
716
|
-
};
|
923
|
+
const Texture& texture = Image_get_texture(image);
|
924
|
+
if (!texture)
|
925
|
+
invalid_state_error(__FILE__, __LINE__);
|
717
926
|
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
{
|
724
|
-
continue;
|
725
|
-
}
|
927
|
+
float density = image.pixel_density();
|
928
|
+
src_x *= density;
|
929
|
+
src_y *= density;
|
930
|
+
src_w *= density;
|
931
|
+
src_h *= density;
|
726
932
|
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
933
|
+
Point points[4], texcoords[4];
|
934
|
+
points[0] .reset(dst_x, dst_y);
|
935
|
+
points[1] .reset(dst_x, dst_y + dst_h);
|
936
|
+
points[2] .reset(dst_x + dst_w, dst_y + dst_h);
|
937
|
+
points[3] .reset(dst_x + dst_w, dst_y);
|
938
|
+
texcoords[0].reset(src_x, src_y);
|
939
|
+
texcoords[1].reset(src_x, src_y + src_h);
|
940
|
+
texcoords[2].reset(src_x + src_w, src_y + src_h);
|
941
|
+
texcoords[3].reset(src_x + src_w, src_y);
|
942
|
+
|
943
|
+
TextureInfo texinfo(texture, src_x, src_y, src_x + src_w, src_y + src_h);
|
944
|
+
|
945
|
+
if (!shader)
|
946
|
+
shader = &get_default_shader_for_color_texture();
|
947
|
+
|
948
|
+
draw_polygon(
|
949
|
+
painter, MODES, 0, 0, false, nostroke, points, 4, NULL, 0, texcoords,
|
950
|
+
*shader, &texinfo);
|
740
951
|
}
|
741
952
|
|
742
953
|
void
|
@@ -745,14 +956,10 @@ namespace Rays
|
|
745
956
|
if (!image_)
|
746
957
|
argument_error(__FILE__, __LINE__);
|
747
958
|
|
748
|
-
const Texture& tex = image_.texture();
|
749
|
-
if (!tex)
|
750
|
-
argument_error(__FILE__, __LINE__);
|
751
|
-
|
752
959
|
draw_image(
|
753
|
-
this,
|
754
|
-
0, 0,
|
755
|
-
x, y,
|
960
|
+
this, image_,
|
961
|
+
0, 0, image_.width(), image_.height(),
|
962
|
+
x, y, image_.width(), image_.height());
|
756
963
|
}
|
757
964
|
|
758
965
|
void
|
@@ -768,14 +975,10 @@ namespace Rays
|
|
768
975
|
if (!image_)
|
769
976
|
argument_error(__FILE__, __LINE__);
|
770
977
|
|
771
|
-
const Texture& tex = image_.texture();
|
772
|
-
if (!tex)
|
773
|
-
argument_error(__FILE__, __LINE__);
|
774
|
-
|
775
978
|
draw_image(
|
776
|
-
this,
|
777
|
-
0, 0,
|
778
|
-
x, y, width,
|
979
|
+
this, image_,
|
980
|
+
0, 0, image_.width(), image_.height(),
|
981
|
+
x, y, width, height);
|
779
982
|
}
|
780
983
|
|
781
984
|
void
|
@@ -788,191 +991,185 @@ namespace Rays
|
|
788
991
|
void
|
789
992
|
Painter::image (
|
790
993
|
const Image& image_,
|
791
|
-
coord
|
792
|
-
coord
|
994
|
+
coord src_x, coord src_y, coord src_width, coord src_height,
|
995
|
+
coord dst_x, coord dst_y)
|
793
996
|
{
|
794
997
|
if (!image_)
|
795
998
|
argument_error(__FILE__, __LINE__);
|
796
999
|
|
797
|
-
const Texture& tex = image_.texture();
|
798
|
-
if (!tex)
|
799
|
-
argument_error(__FILE__, __LINE__);
|
800
|
-
|
801
|
-
coord dest_width = tex.width(), dest_height = tex.height();
|
802
|
-
float s = tex.s_max() / dest_width, t = tex.t_max() / dest_height;
|
803
1000
|
draw_image(
|
804
|
-
this,
|
805
|
-
|
806
|
-
|
1001
|
+
this, image_,
|
1002
|
+
src_x, src_y, src_width, src_height,
|
1003
|
+
dst_x, dst_y, image_.width(), image_.height());
|
807
1004
|
}
|
808
1005
|
|
809
1006
|
void
|
810
1007
|
Painter::image (
|
811
|
-
const Image& image_, const Bounds& src_bounds, const Point&
|
1008
|
+
const Image& image_, const Bounds& src_bounds, const Point& dst_position)
|
812
1009
|
{
|
813
1010
|
image(
|
814
1011
|
image_,
|
815
1012
|
src_bounds.x, src_bounds.y, src_bounds.width, src_bounds.height,
|
816
|
-
|
1013
|
+
dst_position.x, dst_position.y);
|
817
1014
|
}
|
818
1015
|
|
819
1016
|
void
|
820
1017
|
Painter::image (
|
821
1018
|
const Image& image_,
|
822
|
-
coord
|
823
|
-
coord
|
1019
|
+
coord src_x, coord src_y, coord src_width, coord src_height,
|
1020
|
+
coord dst_x, coord dst_y, coord dst_width, coord dst_height)
|
824
1021
|
{
|
825
1022
|
if (!image_)
|
826
1023
|
argument_error(__FILE__, __LINE__);
|
827
1024
|
|
828
|
-
const Texture& tex = image_.texture();
|
829
|
-
if (!tex)
|
830
|
-
argument_error(__FILE__, __LINE__);
|
831
|
-
|
832
|
-
float s = tex.s_max() / tex.width();
|
833
|
-
float t = tex.t_max() / tex.height();
|
834
1025
|
draw_image(
|
835
|
-
this,
|
836
|
-
|
837
|
-
|
1026
|
+
this, image_,
|
1027
|
+
src_x, src_y, src_width, src_height,
|
1028
|
+
dst_x, dst_y, dst_width, dst_height);
|
838
1029
|
}
|
839
1030
|
|
840
1031
|
void
|
841
1032
|
Painter::image (
|
842
|
-
const Image& image_, const Bounds& src_bounds, const Bounds&
|
1033
|
+
const Image& image_, const Bounds& src_bounds, const Bounds& dst_bounds)
|
843
1034
|
{
|
844
1035
|
image(
|
845
1036
|
image_,
|
846
|
-
|
847
|
-
|
1037
|
+
src_bounds.x, src_bounds.y, src_bounds.width, src_bounds.height,
|
1038
|
+
dst_bounds.x, dst_bounds.y, dst_bounds.width, dst_bounds.height);
|
1039
|
+
}
|
1040
|
+
|
1041
|
+
static inline void
|
1042
|
+
debug_draw_text (
|
1043
|
+
Painter* painter, const Font& font,
|
1044
|
+
coord x, coord y, coord str_width, coord str_height)
|
1045
|
+
{
|
1046
|
+
#if 0
|
1047
|
+
save_image(painter->self->text_image, "/tmp/font.png");
|
1048
|
+
|
1049
|
+
painter->push_state();
|
1050
|
+
{
|
1051
|
+
coord asc, desc, lead;
|
1052
|
+
font.get_height(&asc, &desc, &lead);
|
1053
|
+
//printf("%f %f %f %f \n", str_height, asc, desc, lead);
|
1054
|
+
|
1055
|
+
painter->set_stroke(0.5, 0.5, 1);
|
1056
|
+
painter->no_fill();
|
1057
|
+
painter->rect(x - 1, y - 1, str_width + 2, str_height + 2);
|
1058
|
+
|
1059
|
+
coord yy = y;
|
1060
|
+
painter->set_stroke(1, 0.5, 0.5, 0.4);
|
1061
|
+
painter->rect(x, yy, str_width, asc);//str_height);
|
1062
|
+
|
1063
|
+
yy += asc;
|
1064
|
+
painter->set_stroke(1, 1, 0.5, 0.4);
|
1065
|
+
painter->rect(x, yy, str_width, desc);
|
1066
|
+
|
1067
|
+
yy += desc;
|
1068
|
+
painter->set_stroke(1, 0.5, 1, 0.4);
|
1069
|
+
painter->rect(x, yy, str_width, lead);
|
1070
|
+
}
|
1071
|
+
painter->pop_state();
|
1072
|
+
#endif
|
848
1073
|
}
|
849
1074
|
|
850
1075
|
static void
|
851
1076
|
draw_text (
|
852
|
-
Painter* painter, const
|
853
|
-
coord x, coord y, coord width, coord height
|
854
|
-
const Font& font)
|
1077
|
+
Painter* painter, const Font& font,
|
1078
|
+
const char* str, coord x, coord y, coord width = 0, coord height = 0)
|
855
1079
|
{
|
856
|
-
assert(str && *str != '\0'
|
1080
|
+
assert(painter && font && str && *str != '\0');
|
857
1081
|
|
858
|
-
|
859
|
-
argument_error(__FILE__, __LINE__);
|
1082
|
+
Painter::Data* self = painter->self.get();
|
860
1083
|
|
861
|
-
if (!
|
862
|
-
invalid_state_error(__FILE__, __LINE__, "
|
1084
|
+
if (!self->painting)
|
1085
|
+
invalid_state_error(__FILE__, __LINE__, "painting flag should be true.");
|
863
1086
|
|
864
|
-
|
865
|
-
|
866
|
-
int tex_h = ceil(str_height);
|
1087
|
+
if (!self->state.has_color())
|
1088
|
+
return;
|
867
1089
|
|
1090
|
+
float density = self->pixel_density;
|
1091
|
+
coord str_w = Font_get_width(font, density, str);
|
1092
|
+
coord str_h = Font_get_height(font, density);
|
1093
|
+
int tex_w = ceil(str_w);
|
1094
|
+
int tex_h = ceil(str_h);
|
1095
|
+
const Texture& texture = Image_get_texture(self->text_image);
|
868
1096
|
if (
|
869
|
-
|
870
|
-
|
1097
|
+
texture.width() < tex_w ||
|
1098
|
+
texture.height() < tex_h ||
|
1099
|
+
self->text_image.pixel_density() != density)
|
871
1100
|
{
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
self->text_image.color_space(),
|
876
|
-
self->text_image.alpha_only());
|
1101
|
+
int bmp_w = std::max(texture.width(), tex_w);
|
1102
|
+
int bmp_h = std::max(texture.height(), tex_h);
|
1103
|
+
self->text_image = Image(Bitmap(bmp_w, bmp_h, ALPHA), density);
|
877
1104
|
}
|
878
1105
|
|
879
1106
|
if (!self->text_image)
|
880
1107
|
invalid_state_error(__FILE__, __LINE__);
|
881
1108
|
|
882
|
-
|
1109
|
+
assert(self->text_image.pixel_density() == density);
|
883
1110
|
|
884
|
-
|
885
|
-
|
886
|
-
rays_error(__FILE__, __LINE__, "text_image's texture is invalid.");
|
1111
|
+
Bitmap_draw_string(
|
1112
|
+
&self->text_image.bitmap(), Font_get_raw(font, density), str, 0, 0);
|
887
1113
|
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
{
|
893
|
-
coord asc, desc, lead;
|
894
|
-
font.get_height(&asc, &desc, &lead);
|
895
|
-
//printf("%f %f %f %f \n", str_height, asc, desc, lead);
|
896
|
-
|
897
|
-
painter->set_stroke(0.5, 0.5, 1);
|
898
|
-
painter->no_fill();
|
899
|
-
painter->rect(x - 1, y - 1, str_width + 2, str_height + 2);
|
900
|
-
|
901
|
-
coord yy = y;
|
902
|
-
painter->set_stroke(1, 0.5, 0.5, 0.4);
|
903
|
-
painter->rect(x, yy, str_width, asc);//str_height);
|
904
|
-
|
905
|
-
yy += asc;
|
906
|
-
painter->set_stroke(1, 1, 0.5, 0.4);
|
907
|
-
painter->rect(x, yy, str_width, desc);
|
908
|
-
|
909
|
-
yy += desc;
|
910
|
-
painter->set_stroke(1, 0.5, 1, 0.4);
|
911
|
-
painter->rect(x, yy, str_width, lead);
|
912
|
-
}
|
913
|
-
painter->pop_attr();
|
914
|
-
#endif
|
1114
|
+
str_w /= density;
|
1115
|
+
str_h /= density;
|
1116
|
+
if (width == 0) width = str_w;
|
1117
|
+
if (height == 0) height = str_h;
|
915
1118
|
|
916
1119
|
draw_image(
|
917
|
-
painter,
|
918
|
-
0, 0,
|
919
|
-
x, y,
|
920
|
-
true);
|
1120
|
+
painter, self->text_image,
|
1121
|
+
0, 0, str_w, str_h,
|
1122
|
+
x, y, str_w, str_h,
|
1123
|
+
true, &get_default_shader_for_alpha_texture());
|
1124
|
+
|
1125
|
+
debug_draw_text(painter, font, x, y, str_w / density, str_h / density);
|
921
1126
|
}
|
922
1127
|
|
923
1128
|
void
|
924
|
-
Painter::text (const char* str, coord x, coord y
|
1129
|
+
Painter::text (const char* str, coord x, coord y)
|
925
1130
|
{
|
926
1131
|
if (!str)
|
927
1132
|
argument_error(__FILE__, __LINE__);
|
928
1133
|
|
929
1134
|
if (*str == '\0') return;
|
930
1135
|
|
931
|
-
|
932
|
-
if (
|
933
|
-
|
1136
|
+
const Font& font = self->state.font;
|
1137
|
+
if (!font)
|
1138
|
+
invalid_state_error(__FILE__, __LINE__);
|
934
1139
|
|
935
|
-
|
936
|
-
w = ceil(w);
|
937
|
-
h = ceil(h);
|
938
|
-
draw_text(this, str, w, h, x, y, w, h, *font);
|
1140
|
+
draw_text(this, font, str, x, y);
|
939
1141
|
}
|
940
1142
|
|
941
1143
|
void
|
942
|
-
Painter::text (const char* str, const Point& position
|
1144
|
+
Painter::text (const char* str, const Point& position)
|
943
1145
|
{
|
944
|
-
text(str, position.x, position.y
|
1146
|
+
text(str, position.x, position.y);
|
945
1147
|
}
|
946
1148
|
|
947
1149
|
void
|
948
|
-
Painter::text (
|
949
|
-
const char* str, coord x, coord y, coord width, coord height,
|
950
|
-
const Font* font)
|
1150
|
+
Painter::text (const char* str, coord x, coord y, coord width, coord height)
|
951
1151
|
{
|
952
1152
|
if (!str)
|
953
1153
|
argument_error(__FILE__, __LINE__);
|
954
1154
|
|
955
|
-
if (*str == '\0') return;
|
1155
|
+
if (*str == '\0' || width == 0 || height == 0) return;
|
956
1156
|
|
957
|
-
|
958
|
-
if (
|
959
|
-
|
1157
|
+
const Font& font = self->state.font;
|
1158
|
+
if (!font)
|
1159
|
+
invalid_state_error(__FILE__, __LINE__);
|
960
1160
|
|
961
|
-
|
962
|
-
w = ceil(w);
|
963
|
-
h = ceil(h);
|
964
|
-
draw_text(this, str, w, h, x, y, width, height, *font);
|
1161
|
+
draw_text(this, font, str, x, y, width, height);
|
965
1162
|
}
|
966
1163
|
|
967
1164
|
void
|
968
|
-
Painter::text (const char* str, const Bounds& bounds
|
1165
|
+
Painter::text (const char* str, const Bounds& bounds)
|
969
1166
|
{
|
970
|
-
text(str, bounds.x, bounds.y, bounds.width, bounds.height
|
1167
|
+
text(str, bounds.x, bounds.y, bounds.width, bounds.height);
|
971
1168
|
}
|
972
1169
|
|
973
|
-
|
974
1170
|
void
|
975
|
-
Painter::set_background (
|
1171
|
+
Painter::set_background (
|
1172
|
+
float red, float green, float blue, float alpha, bool clear)
|
976
1173
|
{
|
977
1174
|
set_background(Color(red, green, blue, alpha), clear);
|
978
1175
|
}
|
@@ -980,7 +1177,7 @@ namespace Rays
|
|
980
1177
|
void
|
981
1178
|
Painter::set_background (const Color& color, bool clear)
|
982
1179
|
{
|
983
|
-
self->
|
1180
|
+
self->state.background = color;
|
984
1181
|
|
985
1182
|
if (self->painting && clear) this->clear();
|
986
1183
|
}
|
@@ -996,7 +1193,7 @@ namespace Rays
|
|
996
1193
|
const Color&
|
997
1194
|
Painter::background () const
|
998
1195
|
{
|
999
|
-
return self->
|
1196
|
+
return self->state.background;
|
1000
1197
|
}
|
1001
1198
|
|
1002
1199
|
void
|
@@ -1008,19 +1205,19 @@ namespace Rays
|
|
1008
1205
|
void
|
1009
1206
|
Painter::set_fill (const Color& color)
|
1010
1207
|
{
|
1011
|
-
self->
|
1208
|
+
self->state.colors[FILL] = color;
|
1012
1209
|
}
|
1013
1210
|
|
1014
1211
|
void
|
1015
1212
|
Painter::no_fill ()
|
1016
1213
|
{
|
1017
|
-
self->
|
1214
|
+
self->state.colors[FILL].alpha = 0;
|
1018
1215
|
}
|
1019
1216
|
|
1020
1217
|
const Color&
|
1021
1218
|
Painter::fill () const
|
1022
1219
|
{
|
1023
|
-
return self->
|
1220
|
+
return self->state.colors[FILL];
|
1024
1221
|
}
|
1025
1222
|
|
1026
1223
|
void
|
@@ -1032,217 +1229,200 @@ namespace Rays
|
|
1032
1229
|
void
|
1033
1230
|
Painter::set_stroke (const Color& color)
|
1034
1231
|
{
|
1035
|
-
self->
|
1232
|
+
self->state.colors[STROKE] = color;
|
1036
1233
|
}
|
1037
1234
|
|
1038
1235
|
void
|
1039
1236
|
Painter::no_stroke ()
|
1040
1237
|
{
|
1041
|
-
self->
|
1238
|
+
self->state.colors[STROKE].alpha = 0;
|
1042
1239
|
}
|
1043
1240
|
|
1044
1241
|
const Color&
|
1045
1242
|
Painter::stroke () const
|
1046
1243
|
{
|
1047
|
-
return self->
|
1244
|
+
return self->state.colors[STROKE];
|
1048
1245
|
}
|
1049
1246
|
|
1050
1247
|
void
|
1051
|
-
Painter::
|
1248
|
+
Painter::set_stroke_width (coord width)
|
1052
1249
|
{
|
1053
|
-
|
1250
|
+
self->state.stroke_width = width;
|
1054
1251
|
}
|
1055
1252
|
|
1056
|
-
|
1057
|
-
Painter::
|
1253
|
+
coord
|
1254
|
+
Painter::stroke_width () const
|
1058
1255
|
{
|
1059
|
-
self->
|
1060
|
-
self->update_clip();
|
1256
|
+
return self->state.stroke_width;
|
1061
1257
|
}
|
1062
1258
|
|
1063
1259
|
void
|
1064
|
-
Painter::
|
1065
|
-
{
|
1066
|
-
set_clip(0, 0, -1, -1);
|
1067
|
-
}
|
1068
|
-
|
1069
|
-
const Bounds&
|
1070
|
-
Painter::clip () const
|
1260
|
+
Painter::set_stroke_cap (CapType cap)
|
1071
1261
|
{
|
1072
|
-
|
1262
|
+
self->state.stroke_cap = cap;
|
1073
1263
|
}
|
1074
1264
|
|
1075
|
-
|
1076
|
-
Painter::
|
1265
|
+
CapType
|
1266
|
+
Painter::stroke_cap () const
|
1077
1267
|
{
|
1078
|
-
|
1268
|
+
return self->state.stroke_cap;
|
1079
1269
|
}
|
1080
1270
|
|
1081
1271
|
void
|
1082
|
-
Painter::
|
1272
|
+
Painter::set_stroke_join (JoinType join)
|
1083
1273
|
{
|
1084
|
-
self->
|
1274
|
+
self->state.stroke_join = join;
|
1085
1275
|
}
|
1086
1276
|
|
1087
|
-
|
1088
|
-
Painter::
|
1277
|
+
JoinType
|
1278
|
+
Painter::stroke_join () const
|
1089
1279
|
{
|
1090
|
-
return self->
|
1280
|
+
return self->state.stroke_join;
|
1091
1281
|
}
|
1092
1282
|
|
1093
1283
|
void
|
1094
|
-
Painter::
|
1284
|
+
Painter::set_miter_limit (coord limit)
|
1095
1285
|
{
|
1096
|
-
self->
|
1286
|
+
self->state.miter_limit = limit;
|
1097
1287
|
}
|
1098
1288
|
|
1099
|
-
|
1100
|
-
Painter::
|
1289
|
+
coord
|
1290
|
+
Painter::miter_limit () const
|
1101
1291
|
{
|
1102
|
-
|
1103
|
-
rays_error(__FILE__, __LINE__, "attrs_stack is empty.");
|
1104
|
-
|
1105
|
-
self->attrs = self->attrs_stack.back();
|
1106
|
-
self->attrs_stack.pop_back();
|
1107
|
-
self->update_clip();
|
1292
|
+
return self->state.miter_limit;
|
1108
1293
|
}
|
1109
1294
|
|
1110
|
-
|
1111
1295
|
void
|
1112
|
-
Painter::
|
1296
|
+
Painter::set_nsegment (int nsegment)
|
1113
1297
|
{
|
1114
|
-
|
1298
|
+
if (nsegment < 0) nsegment = 0;
|
1299
|
+
self->state.nsegment = nsegment;
|
1115
1300
|
}
|
1116
1301
|
|
1117
|
-
|
1118
|
-
Painter::
|
1302
|
+
uint
|
1303
|
+
Painter::nsegment () const
|
1119
1304
|
{
|
1120
|
-
self->
|
1305
|
+
return self->state.nsegment;
|
1121
1306
|
}
|
1122
1307
|
|
1123
1308
|
void
|
1124
|
-
Painter::
|
1309
|
+
Painter::set_clip (coord x, coord y, coord width, coord height)
|
1125
1310
|
{
|
1126
|
-
|
1311
|
+
set_clip(Bounds(x, y, width, height));
|
1127
1312
|
}
|
1128
1313
|
|
1129
1314
|
void
|
1130
|
-
Painter::
|
1315
|
+
Painter::set_clip (const Bounds& bounds)
|
1131
1316
|
{
|
1132
|
-
self->
|
1317
|
+
self->state.clip = bounds;
|
1318
|
+
self->update_clip();
|
1133
1319
|
}
|
1134
1320
|
|
1135
1321
|
void
|
1136
|
-
Painter::
|
1322
|
+
Painter::no_clip ()
|
1137
1323
|
{
|
1138
|
-
|
1324
|
+
set_clip(0, 0, -1, -1);
|
1139
1325
|
}
|
1140
1326
|
|
1141
|
-
|
1142
|
-
Painter::
|
1327
|
+
const Bounds&
|
1328
|
+
Painter::clip () const
|
1143
1329
|
{
|
1144
|
-
self->
|
1330
|
+
return self->state.clip;
|
1145
1331
|
}
|
1146
1332
|
|
1147
1333
|
void
|
1148
|
-
Painter::
|
1334
|
+
Painter::set_font (const char* name, coord size)
|
1149
1335
|
{
|
1150
|
-
|
1336
|
+
set_font(Font(name, size));
|
1151
1337
|
}
|
1152
1338
|
|
1153
1339
|
void
|
1154
|
-
Painter::
|
1340
|
+
Painter::set_font (const Font& font)
|
1155
1341
|
{
|
1156
|
-
self->
|
1342
|
+
self->state.font = font;
|
1157
1343
|
}
|
1158
1344
|
|
1159
|
-
|
1160
|
-
Painter::
|
1345
|
+
const Font&
|
1346
|
+
Painter::font () const
|
1161
1347
|
{
|
1162
|
-
self->
|
1348
|
+
return self->state.font;
|
1163
1349
|
}
|
1164
1350
|
|
1165
1351
|
void
|
1166
|
-
Painter::
|
1352
|
+
Painter::set_shader (const Shader& shader)
|
1167
1353
|
{
|
1168
|
-
self->
|
1354
|
+
self->state.shader = shader;
|
1169
1355
|
}
|
1170
1356
|
|
1171
1357
|
void
|
1172
|
-
Painter::
|
1358
|
+
Painter::no_shader ()
|
1173
1359
|
{
|
1174
|
-
self->
|
1360
|
+
self->state.shader = Shader();
|
1175
1361
|
}
|
1176
1362
|
|
1177
|
-
|
1178
|
-
Painter::
|
1363
|
+
const Shader&
|
1364
|
+
Painter::shader () const
|
1179
1365
|
{
|
1180
|
-
self->
|
1366
|
+
return self->state.shader;
|
1181
1367
|
}
|
1182
1368
|
|
1183
1369
|
void
|
1184
|
-
Painter::
|
1370
|
+
Painter::push_state ()
|
1185
1371
|
{
|
1186
|
-
self->
|
1372
|
+
self->state_stack.emplace_back(self->state);
|
1187
1373
|
}
|
1188
1374
|
|
1189
1375
|
void
|
1190
|
-
Painter::
|
1376
|
+
Painter::pop_state ()
|
1191
1377
|
{
|
1192
|
-
self->
|
1193
|
-
|
1378
|
+
if (self->state_stack.empty())
|
1379
|
+
invalid_state_error(__FILE__, __LINE__, "state stack underflow.");
|
1194
1380
|
|
1381
|
+
self->state = self->state_stack.back();
|
1382
|
+
self->state_stack.pop_back();
|
1383
|
+
self->update_clip();
|
1384
|
+
}
|
1195
1385
|
|
1196
1386
|
void
|
1197
1387
|
Painter::translate (coord x, coord y, coord z)
|
1198
1388
|
{
|
1199
|
-
|
1389
|
+
self->position_matrix.translate(x, y, z);
|
1200
1390
|
}
|
1201
1391
|
|
1202
1392
|
void
|
1203
1393
|
Painter::translate (const Point& value)
|
1204
1394
|
{
|
1205
|
-
translate(value
|
1395
|
+
self->position_matrix.translate(value);
|
1206
1396
|
}
|
1207
1397
|
|
1208
1398
|
void
|
1209
1399
|
Painter::scale (coord x, coord y, coord z)
|
1210
1400
|
{
|
1211
|
-
|
1401
|
+
self->position_matrix.scale(x, y, z);
|
1212
1402
|
}
|
1213
1403
|
|
1214
1404
|
void
|
1215
1405
|
Painter::scale (const Point& value)
|
1216
1406
|
{
|
1217
|
-
scale(value
|
1407
|
+
self->position_matrix.scale(value);
|
1218
1408
|
}
|
1219
1409
|
|
1220
1410
|
void
|
1221
|
-
Painter::rotate (float
|
1411
|
+
Painter::rotate (float degree, coord x, coord y, coord z)
|
1222
1412
|
{
|
1223
|
-
|
1413
|
+
self->position_matrix.rotate(degree, x, y, z);
|
1224
1414
|
}
|
1225
1415
|
|
1226
1416
|
void
|
1227
|
-
Painter::rotate (float angle, const Point&
|
1417
|
+
Painter::rotate (float angle, const Point& normalized_axis)
|
1228
1418
|
{
|
1229
|
-
rotate(angle,
|
1419
|
+
self->position_matrix.rotate(angle, normalized_axis);
|
1230
1420
|
}
|
1231
1421
|
|
1232
1422
|
void
|
1233
1423
|
Painter::set_matrix (float value)
|
1234
1424
|
{
|
1235
|
-
|
1236
|
-
{
|
1237
|
-
glLoadIdentity();
|
1238
|
-
return;
|
1239
|
-
}
|
1240
|
-
|
1241
|
-
set_matrix(
|
1242
|
-
value, 0, 0, 0,
|
1243
|
-
0, value, 0, 0,
|
1244
|
-
0, 0, value, 0,
|
1245
|
-
0, 0, 0, value);
|
1425
|
+
self->position_matrix.reset(value);
|
1246
1426
|
}
|
1247
1427
|
|
1248
1428
|
void
|
@@ -1252,52 +1432,46 @@ namespace Rays
|
|
1252
1432
|
float c1, float c2, float c3, float c4,
|
1253
1433
|
float d1, float d2, float d3, float d4)
|
1254
1434
|
{
|
1255
|
-
|
1435
|
+
self->position_matrix.reset(
|
1256
1436
|
a1, a2, a3, a4,
|
1257
1437
|
b1, b2, b3, b4,
|
1258
1438
|
c1, c2, c3, c4,
|
1259
|
-
d1, d2, d3, d4
|
1260
|
-
};
|
1261
|
-
set_matrix(array);
|
1439
|
+
d1, d2, d3, d4);
|
1262
1440
|
}
|
1263
1441
|
|
1264
1442
|
void
|
1265
|
-
Painter::set_matrix (const
|
1443
|
+
Painter::set_matrix (const coord* elements, size_t size)
|
1266
1444
|
{
|
1267
|
-
|
1268
|
-
argument_error(__FILE__, __LINE__);
|
1269
|
-
|
1270
|
-
glLoadMatrixf(elements);
|
1445
|
+
self->position_matrix.reset(elements, size);
|
1271
1446
|
}
|
1272
1447
|
|
1273
1448
|
void
|
1274
1449
|
Painter::set_matrix (const Matrix& matrix)
|
1275
1450
|
{
|
1276
|
-
|
1451
|
+
self->position_matrix = matrix;
|
1277
1452
|
}
|
1278
1453
|
|
1279
1454
|
const Matrix&
|
1280
1455
|
Painter::matrix () const
|
1281
1456
|
{
|
1282
|
-
|
1283
|
-
check_error(__FILE__, __LINE__);
|
1284
|
-
return self->matrix_tmp;
|
1457
|
+
return self->position_matrix;
|
1285
1458
|
}
|
1286
1459
|
|
1287
1460
|
void
|
1288
1461
|
Painter::push_matrix ()
|
1289
1462
|
{
|
1290
|
-
|
1291
|
-
check_error(__FILE__, __LINE__);
|
1463
|
+
self->position_matrix_stack.emplace_back(self->position_matrix);
|
1292
1464
|
}
|
1293
1465
|
|
1294
1466
|
void
|
1295
1467
|
Painter::pop_matrix ()
|
1296
1468
|
{
|
1297
|
-
|
1298
|
-
|
1299
|
-
}
|
1469
|
+
if (self->position_matrix_stack.empty())
|
1470
|
+
invalid_state_error(__FILE__, __LINE__, "matrix stack underflow.");
|
1300
1471
|
|
1472
|
+
self->position_matrix = self->position_matrix_stack.back();
|
1473
|
+
self->position_matrix_stack.pop_back();
|
1474
|
+
}
|
1301
1475
|
|
1302
1476
|
Painter::operator bool () const
|
1303
1477
|
{
|