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