line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# Copyright (c) 2016 Timm Murray |
2
|
|
|
|
|
|
|
# All rights reserved. |
3
|
|
|
|
|
|
|
# |
4
|
|
|
|
|
|
|
# Redistribution and use in source and binary forms, with or without |
5
|
|
|
|
|
|
|
# modification, are permitted provided that the following conditions are met: |
6
|
|
|
|
|
|
|
# |
7
|
|
|
|
|
|
|
# * Redistributions of source code must retain the above copyright notice, |
8
|
|
|
|
|
|
|
# this list of conditions and the following disclaimer. |
9
|
|
|
|
|
|
|
# * Redistributions in binary form must reproduce the above copyright |
10
|
|
|
|
|
|
|
# notice, this list of conditions and the following disclaimer in the |
11
|
|
|
|
|
|
|
# documentation and/or other materials provided with the distribution. |
12
|
|
|
|
|
|
|
# |
13
|
|
|
|
|
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
14
|
|
|
|
|
|
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
15
|
|
|
|
|
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
16
|
|
|
|
|
|
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
17
|
|
|
|
|
|
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
18
|
|
|
|
|
|
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
19
|
|
|
|
|
|
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
20
|
|
|
|
|
|
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
21
|
|
|
|
|
|
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
22
|
|
|
|
|
|
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
23
|
|
|
|
|
|
|
# POSSIBILITY OF SUCH DAMAGE. |
24
|
|
|
|
|
|
|
package Graphics::GVG::OpenGLRenderer; |
25
|
|
|
|
|
|
|
$Graphics::GVG::OpenGLRenderer::VERSION = '0.2'; |
26
|
|
|
|
|
|
|
# ABSTRACT: Turn a GVG file into OpenGL code |
27
|
1
|
|
|
1
|
|
638
|
use strict; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
23
|
|
28
|
1
|
|
|
1
|
|
2
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
19
|
|
29
|
1
|
|
|
1
|
|
491
|
use Moose; |
|
1
|
|
|
|
|
284841
|
|
|
1
|
|
|
|
|
6
|
|
30
|
1
|
|
|
1
|
|
5336
|
use namespace::autoclean; |
|
1
|
|
|
|
|
5311
|
|
|
1
|
|
|
|
|
4
|
|
31
|
1
|
|
|
1
|
|
420
|
use Data::UUID; |
|
1
|
|
|
|
|
495
|
|
|
1
|
|
|
|
|
50
|
|
32
|
1
|
|
|
1
|
|
444
|
use Imager::Color; |
|
1
|
|
|
|
|
31680
|
|
|
1
|
|
|
|
|
33
|
|
33
|
1
|
|
|
1
|
|
583
|
use Math::Trig 'pi'; |
|
1
|
|
|
|
|
8848
|
|
|
1
|
|
|
|
|
1336
|
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
has [qw{ circle_segments ellipse_segments }] => ( |
36
|
|
|
|
|
|
|
is => 'rw', |
37
|
|
|
|
|
|
|
isa => 'Int', |
38
|
|
|
|
|
|
|
default => 40, |
39
|
|
|
|
|
|
|
); |
40
|
|
|
|
|
|
|
has '_glow_count' => ( |
41
|
|
|
|
|
|
|
traits => ['Counter'], |
42
|
|
|
|
|
|
|
is => 'ro', |
43
|
|
|
|
|
|
|
isa => 'Int', |
44
|
|
|
|
|
|
|
default => 0, |
45
|
|
|
|
|
|
|
handles => { |
46
|
|
|
|
|
|
|
'_increment_glow' => 'inc', |
47
|
|
|
|
|
|
|
'_decrement_glow' => 'dec', |
48
|
|
|
|
|
|
|
}, |
49
|
|
|
|
|
|
|
); |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
sub make_drawer_obj |
53
|
|
|
|
|
|
|
{ |
54
|
0
|
|
|
0
|
1
|
|
my ($self, $ast) = @_; |
55
|
|
|
|
|
|
|
|
56
|
0
|
|
|
|
|
|
my ($code, $drawer_pack) = $self->make_code( $ast ); |
57
|
0
|
0
|
|
|
|
|
eval $code or die $@; |
58
|
|
|
|
|
|
|
|
59
|
0
|
|
|
|
|
|
my $obj = $drawer_pack->new; |
60
|
0
|
|
|
|
|
|
return $obj; |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
sub make_code |
64
|
|
|
|
|
|
|
{ |
65
|
0
|
|
|
0
|
1
|
|
my ($self, $ast) = @_; |
66
|
0
|
|
|
|
|
|
my $drawer_pack = $self->_make_pack; |
67
|
0
|
|
|
|
|
|
my $code = $self->_make_pack_code( $drawer_pack, $ast ); |
68
|
0
|
|
|
|
|
|
return ($code, $drawer_pack); |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
sub _make_pack |
72
|
|
|
|
|
|
|
{ |
73
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
74
|
0
|
|
|
|
|
|
my $uuid = Data::UUID->new->create_hex; |
75
|
0
|
|
|
|
|
|
my $pack = __PACKAGE__ . '::' . $uuid; |
76
|
0
|
|
|
|
|
|
return $pack; |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
sub _make_pack_code |
80
|
|
|
|
|
|
|
{ |
81
|
0
|
|
|
0
|
|
|
my ($self, $pack, $ast) = @_; |
82
|
|
|
|
|
|
|
|
83
|
0
|
|
|
|
|
|
my $code = 'package ' . $pack . ';'; |
84
|
0
|
|
|
|
|
|
$code .= q! |
85
|
|
|
|
|
|
|
use strict; |
86
|
|
|
|
|
|
|
use warnings; |
87
|
|
|
|
|
|
|
use OpenGL qw(:all); |
88
|
|
|
|
|
|
|
!; |
89
|
0
|
|
|
|
|
|
$code .= q! |
90
|
|
|
|
|
|
|
sub new |
91
|
|
|
|
|
|
|
{ |
92
|
|
|
|
|
|
|
my ($class) = @_; |
93
|
|
|
|
|
|
|
my $self = {}; |
94
|
|
|
|
|
|
|
bless $self => $class; |
95
|
|
|
|
|
|
|
return $self; |
96
|
|
|
|
|
|
|
} |
97
|
|
|
|
|
|
|
!; |
98
|
|
|
|
|
|
|
|
99
|
0
|
|
|
|
|
|
$code .= 'sub draw {'; |
100
|
0
|
|
|
|
|
|
$code .= $self->_make_draw_code( $ast ); |
101
|
0
|
|
|
|
|
|
$code .= 'return; }'; |
102
|
|
|
|
|
|
|
|
103
|
0
|
|
|
|
|
|
$code .= '1;'; |
104
|
0
|
|
|
|
|
|
return $code; |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
sub _make_draw_code |
108
|
|
|
|
|
|
|
{ |
109
|
0
|
|
|
0
|
|
|
my ($self, $ast) = @_; |
110
|
|
|
|
|
|
|
my $code = join( "\n", map { |
111
|
0
|
|
|
|
|
|
my $ret = ''; |
112
|
0
|
0
|
|
|
|
|
if(! ref $_ ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
113
|
0
|
|
|
|
|
|
warn "Not a ref, don't know what to do with '$_'\n"; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
elsif( $_->isa( 'Graphics::GVG::AST::Line' ) ) { |
116
|
0
|
|
|
|
|
|
$ret = $self->_make_code_line( $_ ); |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
elsif( $_->isa( 'Graphics::GVG::AST::Rect' ) ) { |
119
|
0
|
|
|
|
|
|
$ret = $self->_make_code_rect( $_ ); |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
elsif( $_->isa( 'Graphics::GVG::AST::Polygon' ) ) { |
122
|
0
|
|
|
|
|
|
$ret = $self->_make_code_poly( $_ ); |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
elsif( $_->isa( 'Graphics::GVG::AST::Circle' ) ) { |
125
|
0
|
|
|
|
|
|
$ret = $self->_make_code_circle( $_ ); |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
elsif( $_->isa( 'Graphics::GVG::AST::Ellipse' ) ) { |
128
|
0
|
|
|
|
|
|
$ret = $self->_make_code_ellipse( $_ ); |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
elsif( $_->isa( 'Graphics::GVG::AST::Glow' ) ) { |
131
|
0
|
|
|
|
|
|
$self->_increment_glow; |
132
|
0
|
|
|
|
|
|
$ret = $self->_make_draw_code( $_ ); |
133
|
0
|
|
|
|
|
|
$self->_decrement_glow; |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
else { |
136
|
0
|
|
|
|
|
|
warn "Don't know what to do with " . ref($_) . "\n"; |
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
|
139
|
0
|
|
|
|
|
|
$ret; |
140
|
0
|
|
|
|
|
|
} @{ $ast->commands }); |
|
0
|
|
|
|
|
|
|
141
|
0
|
|
|
|
|
|
return $code; |
142
|
|
|
|
|
|
|
} |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
sub _make_code_line |
145
|
|
|
|
|
|
|
{ |
146
|
0
|
|
|
0
|
|
|
my ($self, $cmd) = @_; |
147
|
0
|
|
|
|
|
|
my $x1 = $cmd->x1; |
148
|
0
|
|
|
|
|
|
my $y1 = $cmd->y1; |
149
|
0
|
|
|
|
|
|
my $x2 = $cmd->x2; |
150
|
0
|
|
|
|
|
|
my $y2 = $cmd->y2; |
151
|
0
|
|
|
|
|
|
my $color = $cmd->color; |
152
|
0
|
|
|
|
|
|
my ($red, $green, $blue, $alpha) = $self->_int_to_opengl_color( $color ); |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
my $make_line_sub = sub { |
155
|
0
|
|
|
0
|
|
|
my ($width, $red, $green, $blue, $alpha) = @_; |
156
|
0
|
|
|
|
|
|
my $code = qq! |
157
|
|
|
|
|
|
|
glLineWidth( $width ); |
158
|
|
|
|
|
|
|
glColor4ub( $red, $green, $blue, $alpha ); |
159
|
|
|
|
|
|
|
glBegin( GL_LINES ); |
160
|
|
|
|
|
|
|
glVertex2f( $x1, $y1 ); |
161
|
|
|
|
|
|
|
glVertex2f( $x2, $y2 ); |
162
|
|
|
|
|
|
|
glEnd(); |
163
|
|
|
|
|
|
|
!; |
164
|
0
|
|
|
|
|
|
return $code; |
165
|
0
|
|
|
|
|
|
}; |
166
|
|
|
|
|
|
|
|
167
|
0
|
|
|
|
|
|
my $code = ''; |
168
|
0
|
0
|
|
|
|
|
if( $self->_glow_count > 0 ) { |
169
|
|
|
|
|
|
|
# TODO not really getting the effect I was hoping for. Play around |
170
|
|
|
|
|
|
|
# with it later. |
171
|
0
|
|
|
|
|
|
my @colors1 = $self->_brighten( 2.0, $red, $green, $blue, $alpha ); |
172
|
0
|
|
|
|
|
|
my @colors2 = ($red, $green, $blue, $alpha); |
173
|
0
|
|
|
|
|
|
my @colors3 = $self->_brighten( 0.7, $red, $green, $blue, $alpha ); |
174
|
0
|
|
|
|
|
|
$code = $make_line_sub->( 5.0, @colors3 ); |
175
|
0
|
|
|
|
|
|
$code .= $make_line_sub->( 2.0, @colors2 ); |
176
|
|
|
|
|
|
|
#$code .= $make_line_sub->( 1.0, @colors1 ); |
177
|
|
|
|
|
|
|
} |
178
|
|
|
|
|
|
|
else { |
179
|
0
|
|
|
|
|
|
$code = $make_line_sub->( 1.0, $red, $green, $blue, $alpha ); |
180
|
|
|
|
|
|
|
} |
181
|
|
|
|
|
|
|
|
182
|
0
|
|
|
|
|
|
return $code; |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
sub _make_code_rect |
186
|
|
|
|
|
|
|
{ |
187
|
0
|
|
|
0
|
|
|
my ($self, $cmd) = @_; |
188
|
0
|
|
|
|
|
|
my $x = $cmd->x; |
189
|
0
|
|
|
|
|
|
my $y = $cmd->y; |
190
|
0
|
|
|
|
|
|
my $width = $cmd->width; |
191
|
0
|
|
|
|
|
|
my $height = $cmd->height; |
192
|
0
|
|
|
|
|
|
my $color = $cmd->color; |
193
|
0
|
|
|
|
|
|
my ($red, $green, $blue, $alpha) = $self->_int_to_opengl_color( $color ); |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
my $make_rect_sub = sub { |
196
|
0
|
|
|
0
|
|
|
my ($width, $red, $green, $blue, $alpha) = @_; |
197
|
0
|
|
|
|
|
|
my $far_x = $x + $width; |
198
|
0
|
|
|
|
|
|
my $far_y = $y + $height; |
199
|
0
|
|
|
|
|
|
my $code = qq! |
200
|
|
|
|
|
|
|
glLineWidth( $width ); |
201
|
|
|
|
|
|
|
glColor4ub( $red, $green, $blue, $alpha ); |
202
|
|
|
|
|
|
|
glBegin( GL_LINES ); |
203
|
|
|
|
|
|
|
glVertex2f( $x, $y ); |
204
|
|
|
|
|
|
|
glVertex2f( $far_x, $y ); |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
glVertex2f( $far_x, $y ); |
207
|
|
|
|
|
|
|
glVertex2f( $far_x, $far_y ); |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
glVertex2f( $far_x, $far_y ); |
210
|
|
|
|
|
|
|
glVertex2f( $x, $far_y ); |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
glVertex2f( $x, $far_y ); |
213
|
|
|
|
|
|
|
glVertex2f( $x, $y ); |
214
|
|
|
|
|
|
|
glEnd(); |
215
|
|
|
|
|
|
|
!; |
216
|
0
|
|
|
|
|
|
return $code; |
217
|
0
|
|
|
|
|
|
}; |
218
|
|
|
|
|
|
|
|
219
|
0
|
|
|
|
|
|
my $code = ''; |
220
|
0
|
0
|
|
|
|
|
if( $self->_glow_count > 0 ) { |
221
|
|
|
|
|
|
|
# TODO |
222
|
0
|
|
|
|
|
|
$code = $make_rect_sub->( 1.0, $red, $green, $blue, $alpha ); |
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
else { |
225
|
0
|
|
|
|
|
|
$code = $make_rect_sub->( 1.0, $red, $green, $blue, $alpha ); |
226
|
|
|
|
|
|
|
} |
227
|
|
|
|
|
|
|
|
228
|
0
|
|
|
|
|
|
return $code; |
229
|
|
|
|
|
|
|
} |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
sub _make_code_circle |
232
|
|
|
|
|
|
|
{ |
233
|
0
|
|
|
0
|
|
|
my ($self, $cmd) = @_; |
234
|
0
|
|
|
|
|
|
my $cx = $cmd->cx; |
235
|
0
|
|
|
|
|
|
my $cy = $cmd->cy; |
236
|
0
|
|
|
|
|
|
my $r = $cmd->r; |
237
|
0
|
|
|
|
|
|
my $color = $cmd->color; |
238
|
|
|
|
|
|
|
|
239
|
0
|
|
|
|
|
|
my $poly = Graphics::GVG::AST::Polygon->new({ |
240
|
|
|
|
|
|
|
cx => $cx, |
241
|
|
|
|
|
|
|
cy => $cy, |
242
|
|
|
|
|
|
|
r => $r, |
243
|
|
|
|
|
|
|
sides => $self->circle_segments, |
244
|
|
|
|
|
|
|
rotate => 0, |
245
|
|
|
|
|
|
|
color => $cmd->color, |
246
|
|
|
|
|
|
|
}); |
247
|
|
|
|
|
|
|
|
248
|
0
|
|
|
|
|
|
return $self->_make_code_poly( $poly ); |
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
sub _make_code_ellipse |
252
|
|
|
|
|
|
|
{ |
253
|
0
|
|
|
0
|
|
|
my ($self, $cmd) = @_; |
254
|
0
|
|
|
|
|
|
my $cx = $cmd->cx; |
255
|
0
|
|
|
|
|
|
my $cy = $cmd->cy; |
256
|
0
|
|
|
|
|
|
my $rx = $cmd->rx; |
257
|
0
|
|
|
|
|
|
my $ry = $cmd->ry; |
258
|
0
|
|
|
|
|
|
my $color = $cmd->color; |
259
|
0
|
|
|
|
|
|
my $num_segments = $self->ellipse_segments; |
260
|
0
|
|
|
|
|
|
my ($red, $green, $blue, $alpha) = $self->_int_to_opengl_color( $color ); |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
# See: |
263
|
|
|
|
|
|
|
# http://stackoverflow.com/questions/5886628/effecient-way-to-draw-ellipse-with-opengl-or-d3d |
264
|
|
|
|
|
|
|
my $make_cmd_sub = sub { |
265
|
0
|
|
|
0
|
|
|
my ($width, $red, $green, $blue, $alpha) = @_; |
266
|
0
|
|
|
|
|
|
my $theta = 2 * pi / $num_segments; |
267
|
0
|
|
|
|
|
|
my $c = cos( $theta ); |
268
|
0
|
|
|
|
|
|
my $s = sin( $theta ); |
269
|
0
|
|
|
|
|
|
my $t; |
270
|
|
|
|
|
|
|
|
271
|
0
|
|
|
|
|
|
my $x = 1; |
272
|
0
|
|
|
|
|
|
my $y = 0; |
273
|
|
|
|
|
|
|
|
274
|
0
|
|
|
|
|
|
my $code = qq! |
275
|
|
|
|
|
|
|
glLineWidth( $width ); |
276
|
|
|
|
|
|
|
glColor4ub( $red, $green, $blue, $alpha ); |
277
|
|
|
|
|
|
|
glBegin(GL_LINE_LOOP); |
278
|
|
|
|
|
|
|
!; |
279
|
0
|
|
|
|
|
|
foreach my $i (0 .. $num_segments) { |
280
|
0
|
|
|
|
|
|
my $set_x = $x * $rx + $cx; |
281
|
0
|
|
|
|
|
|
my $set_y = $y * $ry + $cy; |
282
|
0
|
|
|
|
|
|
$code .= qq! |
283
|
|
|
|
|
|
|
glVertex2f( $set_x, $set_y ); |
284
|
|
|
|
|
|
|
!; |
285
|
|
|
|
|
|
|
|
286
|
0
|
|
|
|
|
|
$t = $x; |
287
|
0
|
|
|
|
|
|
$x = $c * $x - $s * $y; |
288
|
0
|
|
|
|
|
|
$y = $s * $t + $c * $y; |
289
|
|
|
|
|
|
|
} |
290
|
|
|
|
|
|
|
|
291
|
0
|
|
|
|
|
|
$code .= q! |
292
|
|
|
|
|
|
|
glEnd(); |
293
|
|
|
|
|
|
|
!; |
294
|
0
|
|
|
|
|
|
return $code; |
295
|
0
|
|
|
|
|
|
}; |
296
|
|
|
|
|
|
|
|
297
|
0
|
|
|
|
|
|
my $code = ''; |
298
|
0
|
0
|
|
|
|
|
if( $self->_glow_count > 0 ) { |
299
|
|
|
|
|
|
|
# TODO |
300
|
0
|
|
|
|
|
|
$code = $make_cmd_sub->( 1.0, $red, $green, $blue, $alpha ); |
301
|
|
|
|
|
|
|
} |
302
|
|
|
|
|
|
|
else { |
303
|
0
|
|
|
|
|
|
$code = $make_cmd_sub->( 1.0, $red, $green, $blue, $alpha ); |
304
|
|
|
|
|
|
|
} |
305
|
0
|
|
|
|
|
|
return $code; |
306
|
|
|
|
|
|
|
} |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
sub _make_code_poly |
309
|
|
|
|
|
|
|
{ |
310
|
0
|
|
|
0
|
|
|
my ($self, $cmd) = @_; |
311
|
0
|
|
|
|
|
|
my @coords = @{ $cmd->coords }; |
|
0
|
|
|
|
|
|
|
312
|
0
|
|
|
|
|
|
my $color = $cmd->color; |
313
|
0
|
|
|
|
|
|
my ($red, $green, $blue, $alpha) = $self->_int_to_opengl_color( $color ); |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
my $make_code_sub = sub { |
316
|
0
|
|
|
0
|
|
|
my ($width, $red, $green, $blue, $alpha) = @_; |
317
|
0
|
|
|
|
|
|
my $code = qq! |
318
|
|
|
|
|
|
|
glLineWidth( $width ); |
319
|
|
|
|
|
|
|
glColor4ub( $red, $green, $blue, $alpha ); |
320
|
|
|
|
|
|
|
glBegin( GL_LINES ); |
321
|
|
|
|
|
|
|
!; |
322
|
|
|
|
|
|
|
|
323
|
0
|
|
|
|
|
|
foreach my $i (0 .. $#coords - 1) { |
324
|
0
|
|
|
|
|
|
my $x1 = $coords[$i][0]; |
325
|
0
|
|
|
|
|
|
my $y1 = $coords[$i][1]; |
326
|
0
|
|
|
|
|
|
my $x2 = $coords[$i+1][0]; |
327
|
0
|
|
|
|
|
|
my $y2 = $coords[$i+1][1]; |
328
|
|
|
|
|
|
|
|
329
|
0
|
|
|
|
|
|
$code .= qq! |
330
|
|
|
|
|
|
|
glVertex2f( $x1, $y1 ); |
331
|
|
|
|
|
|
|
glVertex2f( $x2, $y2 ); |
332
|
|
|
|
|
|
|
!; |
333
|
|
|
|
|
|
|
} |
334
|
0
|
|
|
|
|
|
$code .= qq! |
335
|
|
|
|
|
|
|
glVertex2f( $coords[-1][0], $coords[-1][1] ); |
336
|
|
|
|
|
|
|
glVertex2f( $coords[0][0], $coords[0][1] ); |
337
|
|
|
|
|
|
|
glEnd(); |
338
|
|
|
|
|
|
|
!; |
339
|
0
|
|
|
|
|
|
return $code; |
340
|
0
|
|
|
|
|
|
}; |
341
|
|
|
|
|
|
|
|
342
|
0
|
|
|
|
|
|
my $code = ''; |
343
|
0
|
0
|
|
|
|
|
if( $self->_glow_count > 0 ) { |
344
|
|
|
|
|
|
|
# TODO |
345
|
0
|
|
|
|
|
|
$code = $make_code_sub->( 1.0, $red, $green, $blue, $alpha ); |
346
|
|
|
|
|
|
|
} |
347
|
|
|
|
|
|
|
else { |
348
|
0
|
|
|
|
|
|
$code = $make_code_sub->( 1.0, $red, $green, $blue, $alpha ); |
349
|
|
|
|
|
|
|
} |
350
|
|
|
|
|
|
|
|
351
|
0
|
|
|
|
|
|
return $code; |
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
sub _int_to_opengl_color |
355
|
|
|
|
|
|
|
{ |
356
|
0
|
|
|
0
|
|
|
my ($self, $color) = @_; |
357
|
0
|
|
|
|
|
|
my $red = ($color >> 24) & 0xFF; |
358
|
0
|
|
|
|
|
|
my $green = ($color >> 16) & 0xFF; |
359
|
0
|
|
|
|
|
|
my $blue = ($color >> 8) & 0xFF; |
360
|
0
|
|
|
|
|
|
my $alpha = $color & 0xFF; |
361
|
0
|
|
|
|
|
|
return ($red, $green, $blue, $alpha); |
362
|
|
|
|
|
|
|
} |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
sub _brighten |
365
|
|
|
|
|
|
|
{ |
366
|
0
|
|
|
0
|
|
|
my ($self, $multiplier, $red, $green, $blue, $alpha) = @_; |
367
|
0
|
|
|
|
|
|
my $color = Imager::Color->new( $red, $green, $blue, $alpha ); |
368
|
0
|
|
|
|
|
|
my ($h, $s, $v, $new_alpha) = $color->hsv; |
369
|
|
|
|
|
|
|
|
370
|
0
|
|
|
|
|
|
$v *= $multiplier; |
371
|
0
|
0
|
|
|
|
|
$v = 1.0 if $v > 1.0; |
372
|
|
|
|
|
|
|
|
373
|
0
|
|
|
|
|
|
my $hsv_color = Imager::Color->new( |
374
|
|
|
|
|
|
|
hue => $h, |
375
|
|
|
|
|
|
|
v => $v, |
376
|
|
|
|
|
|
|
s => $s, |
377
|
|
|
|
|
|
|
alpha => $new_alpha, |
378
|
|
|
|
|
|
|
); |
379
|
0
|
|
|
|
|
|
return $hsv_color->rgba; |
380
|
|
|
|
|
|
|
} |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
|
383
|
1
|
|
|
1
|
|
8
|
no Moose; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
13
|
|
384
|
|
|
|
|
|
|
__PACKAGE__->meta->make_immutable; |
385
|
|
|
|
|
|
|
1; |
386
|
|
|
|
|
|
|
__END__ |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
=head1 NAME |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
Graphics::GVG::OpenGLRenderer - Take a GVG file and turn it into Perl/OpenGL code |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
=head1 DESCRIPTION |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
=head1 ATTRIBUTES |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
=head2 circle_segments / ellipse_segments |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
In OpenGL, circles aren't really circles. They're polygons with a large number |
400
|
|
|
|
|
|
|
of sides, which blur together enough to look like a circle. |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
These attributes control how many sides those polygons will have. A circle or |
403
|
|
|
|
|
|
|
ellipse that appears larger on the screen will need to be rendered with a |
404
|
|
|
|
|
|
|
larger number of sides to maintain the illusion. |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
The default is 40 for both. |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
=head1 METHODS |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
=head2 make_drawer_obj |
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
my $opengl = $renderer->make_drawer_obj( $ast ); |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
Given an L<Graphics::GVG::AST> object, generates a new Perl object that, when |
415
|
|
|
|
|
|
|
you call its C<draw()> method, will output the GVG description to OpenGL. |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
The package will be uniquely created under C<Graphics::GVG::OpenGLRenderer>. |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
=head2 make_code |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
my $pack_code = $renderer->make_code( $ast ); |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
Given an L<Graphics::GVG::AST> object, returns the code that can be used to |
424
|
|
|
|
|
|
|
create the same kind of Perl object made by C<make_drawer_obj()>. |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
=head1 LICENSE |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
Copyright (c) 2016 Timm Murray |
429
|
|
|
|
|
|
|
All rights reserved. |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without |
432
|
|
|
|
|
|
|
modification, are permitted provided that the following conditions are met: |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
* Redistributions of source code must retain the above copyright notice, |
435
|
|
|
|
|
|
|
this list of conditions and the following disclaimer. |
436
|
|
|
|
|
|
|
* Redistributions in binary form must reproduce the above copyright |
437
|
|
|
|
|
|
|
notice, this list of conditions and the following disclaimer in the |
438
|
|
|
|
|
|
|
documentation and/or other materials provided with the distribution. |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
441
|
|
|
|
|
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
442
|
|
|
|
|
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
443
|
|
|
|
|
|
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
444
|
|
|
|
|
|
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
445
|
|
|
|
|
|
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
446
|
|
|
|
|
|
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
447
|
|
|
|
|
|
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
448
|
|
|
|
|
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
449
|
|
|
|
|
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
450
|
|
|
|
|
|
|
POSSIBILITY OF SUCH DAMAGE. |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
=cut |