File: Array.pod

package info (click to toggle)
libopengl-perl 0.7000%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 2,312 kB
  • sloc: perl: 10,177; ansic: 8,576; makefile: 113
file content (498 lines) | stat: -rwxr-xr-x 10,899 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
=head1 NAME

OpenGL::Array - Perl Array handling and conversion between Perl arrays and C array pointers.

=head1 SYNOPSIS

    use OpenGL qw(GL_FLOAT);

    my $array = OpenGL::Array->new(4, GL_FLOAT);
    my $c_ptr = $array->ptr(); # can be passed to OpenGL _c based functions
    $array->calc('col,27,+');
    my @val = $array->retrieve(0, 4);

=head1 DESCRIPTION

OpenGL::Array (OGA) objects provide Perl Array handling and conversion
between Perl arrays and C array pointers.

Due to the difference between how Perl and C handle pointers, all Perl
OpenGL (POGL) APIs that require pointers are suffixed with _c. OGAs
provide a means to convert Perl arrays into C pointers that can be
passed into these APIs.

Many POGL _c APIs also have a _s version to support SDL's packed
string APIs; OGA provides APIs to convert between C arrays and packed
strings.

POGL also provides many _p APIs that accept native Perl arrays, or in
some cases OGAs directly. In the case of VBOs, OGAs may be bound to
GPU buffers, automatically switching buffers at render time.

Note: Since OGAs are stored as typed C arrays, there is no
conversion/copy/casting when passing them to POGL APIs, resulting in
significant performance improvements over other non-compiled bindings
(SDL, PyOpenGL, etc).

=head1 CREATING OpenGL::Array OBJECTS

=over 4

=item C<new>

    my $array = OpenGL::Array->new($count,@types);

Creates an empty array object of $count rows made up data types @types.

=item C<new_list>

    my $array = OpenGL::Array->new_list($type,@data);

Creates and populates a uniform array object made up @data of type $type.

=item C<new_pointer>

    my $array = OpenGL::Array->new_pointer($type,ptr,$elements);

Creates an array object wrapper around a C pointer ptr of type $type
and array length $elements. Caches C pointer directly; does not copy
data.

Note: because OpenGL::Arrays store to direct memory addresses, it is
possible to assign to the array the pointer was obtained from and the
results will be available in the array created by new_pointer - and
vice versa (because they are viewing portions of the same memory).

=item C<new_scalar>

    my $str = pack 'C*', 1 .. 255;
    my $array = OpenGL::Array->new_scalar(GL_UNSIGNED_BYTE, $str, length($str));

Creates an array object from a perl scalar.

=item C<new_from_pointer>

    my $array1 = OpenGL::Array->new_list(GL_UNSIGNED_BYTE, 1..9);
    my $array2 = OpenGL::Array->new_from_pointer($array1->ptr(), 9);

Special case, creates a uniform GL_UNSIGNED_BYTE from a pointer.

=back

=head1 USING OpenGL::Array OBJECT'S C POINTERS

OpenGL::Array objects are Perl references; in order to use them in
OpenGL APIs that expect C pointers, you need to use the native
pointer:

      my $array = OpenGL::Array->new(4, GL_INT);
      glGetIntegerv_c(GL_VIEWPORT, $array->ptr);
      my @viewport = $array->retrieve(0, 4);

=head1 OpenGL::Array ACCESSORS

=over 4

=item C<assign>

    $array->assign($pos, @data);

Sets array data starting at element position $pos using @data.

=item C<assign_data>

    $array->assign_data($pos, $data);

Sets array data element position $pos using packed string $data.

=item C<retrieve>

    my @data = $array->retrieve($pos, $len);

Returns an array of $len elements from an array object.

=item C<retrieve_data>

    my $data = $array->retrieve_data($pos, $len);

Returns a packed string of length $len bytes from an array object.

=item C<elements>

    my $count = $array->elements();

Returns the element count from an array object.

=item C<ptr>

    ptr = $array->ptr(); # typically passed to opengl _c functions

Returns a C pointer to an array object.

Returns a C pointer to an array object.

=item C<offset>

    ptr = $array->offset($pos);

Returns a C pointer to the $pos element of an array object.

=item C<update_ptr>

    $array->update_pointer($ptr);

Points the existing OpenGL::Array to a different data pointer.

=back

=head1 BINDING TO VBOs

Helps abstract Vertex Array and VBO rendering.

# Requires GL_ARB_vertex_buffer_object extension and POGL 0.55_01 or newer

=over 4

=item C<bind>

    $array->bind($id);

Binds a GPU buffer to an array object.  If bound, glXxxPointer_p APIs
will call glBindBufferARB.

=item C<bound>

    my $id = $array->bound();

Return bound buffer ID, or 0 if not bound.

=back

=head1 AFFINE TRANSFORMS ON OpenGL::Array OBJECTS

Eventually, this API will abstract CPU vs GPU-based affine transforms
for the best performance.

=over 4

=item C<affine>

    $array->affine($xform);

    # $xform is an NxN OpenGL::Array object used to transform $array.

    #N must be one element wider than the width of the array.

=back

=head1 Calc: POPULATING AND MANIPULATING OpenGL::Array OBJECTS

=over 4

=item C<calc>

Used to populate or mathematically modify an POGL array. Uses Reverse
Polish Notation (RPN) for mathematical operations.  At the moment, any
array used with calc must be made of only of GL_FLOAT types.

    $array->calc($value);

Populates the array with $value.

    $array->calc(@values);

Populates each row of the array with @values, assuming rows have the
same width as the length of @values.  If the number of passed values
must be evenly divisible by the number of elements in the array.
The number of values becomes the number of "columns."  The number of
"rows" is the total number of elements of the array divided by the
columns.

    $array->calc(1.0, '3,*', '2,*,rand,+', '');

Resets the first column of each row to 1.0; multiplies the values in
the second column by 3; multiplies the third column by 2, then adds a
random number between 0 and 1; leaves the fourth column alone.  During
this particular calc operation there would be 4 columns.

C<calc> maintains a push/pop stack and a "register" for each column.

C<calc> also allows for other OpenGL::Arrays to be passed in.  If
multiple arrays are passed they must all have the same number of
elements.  Only the calling array will be operated on, but as each
element is visited, the values from the other arrays are pre-added to
the stack (in reverse order).

    $array->calc($array2, $array3, $array4, @values);

calc currently supports the following primitives:

=over 4

=item C<!>

Logical "Not" for End of Stack (S0) for the current column; becomes
1.0 if empty or 0. otherwise 1.0

=item C<->

Arithmetic Negation of S0

=item C<+>

Add S0 and Next on Stack (S1), pop operands and push result (Result)

=item C<*>

Multiply S0 and S1; Result

=item C</>

Divide S1 by S0; Result

=item C<%>

S1 Modulus S0; Result

=item C<=>

Test S0 equality to S1; pop operands and push non-zero (1.0) for true,
otherwise 0.0 (Boolean)

=item C<< > >>

Test if S0 Greater than S1; Boolean

=item C<< < >>

Test if S0 Lesser than S1; Boolean

=item C<?>

If S0 is true (non-zero), pop S0 and S1; otherwise pop s0-3, push s1

=item C<pop>

Pop s0

=item C<rand>

Push a random number from 0.0 to 1.0

=item C<dup>

Push a copy of S0

=item C<swap>

Swap values of S0 and S1

=item C<set>

Copy S0 to the column's Register

=item C<get>

Push the column's Register onto the column's Stack

=item C<store>

Pop S0, and copy the values from the matching row of the passed
OpenGL::Array at that index.  Values are copied into the current
column registers.

  my $o1 = OpenGL::Array->new_list(GL_FLOAT, 1, 2, 3,  4, 5, 6);
  my $o2 = OpenGL::Array->new_list(GL_FLOAT, 7, 8 ,9,  10, 11, 12);
  $o1->calc($o2, "1,store,get","","get");
  $o1->retreive(0,6) will be (7, 2, 9,  10, 5, 12)

=item C<load>

Pop S0, and set the values of the matching row of the passed
OpenGL::Array named at that index.  Values are copied from the current
column registers.

  my $o1 = OpenGL::Array->new_list(GL_FLOAT, 1, 2, 3,  4, 5, 6);
  my $o2 = OpenGL::Array->new_list(GL_FLOAT, 7, 8 ,9,  10, 11, 12);
  $o1->calc($o2, "set","", "set,1,load");
  $o2->retreive(0,6) will be (1, 0, 3,  5, 0, 6)

=item C<colget>

Pop S0, and push the column S0 value onto the current stack.

   $o = OpenGL::Array->new_list(GL_FLOAT, 1, 2, 3,  4, 5, 6);
   $o->calc('2,colget','','');
   # $o->retreive(0,6) will be (3, 2, 3, 6, 5, 6)

=item C<colset>

Pop S0, and set the column S0 value to the new top of the stack.

   $o = OpenGL::Array->new_list(GL_FLOAT, 1, 2, 3,  4, 5, 6);
   $o->calc('27,2,colset','','');
   # $o->retreive(0,6) will be (1, 2, 27,  4, 5, 27)

=item C<rowget>

Pop S0 and S1, and push the column S0 value from row S1 onto the current stack.

   $o = OpenGL::Array->new_list(GL_FLOAT, 1, 2, 3,  4, 5, 6);
   $o->calc('1,2,rowget','','');
   # $o->retreive(0,6) equiv (6, 2, 3,  6, 5, 6)

=item C<rowset>

Pop S0 and S1, and set the column S0 value of row S1 to the new top of the stack.

   $o = OpenGL::Array->new_list(GL_FLOAT, 1, 2, 3,  4, 5, 6);
   $o->calc('27,1,2,rowset','','');
   # $o->retreive(0,6) will be (1, 2, 3,  4, 5, 27)

=item C<end>

End processing; column unchanged

=item C<endif>

Pop S0, End if true; column unchanged

=item C<endrow>

End processing of current row; column unchanged

=item C<endrowif>

Pop S0, End processing of current row if true; column unchanged

=item C<return>

End processing; column value set to s0

=item C<returnif>

Pop S0, End if true; column value set to s0

=item C<returnrow>

End processing of current row; column value set to s0

=item C<returnrowif>

Pop S0, End processing of current row if true; column value set to s0

=item C<if>

alias to C<?>

=item C<or>

alias to C<+>

=item C<and>

alias to C<*>

=item C<inc>

Add 1 to S0

=item C<dec>

Subtract 1 from S0

=item C<sum>

Add and pop everything in stack; push result

=item C<avg>

Average and pop everything in stack; push result

=item C<abs>

Replace S0 with its absolute value

=item C<power>

Raise S1 to the power of S0; Result

=item C<min>

The lower of S0 and S1; Result

=item C<max>

The higher of S0 and S1; Result

=item C<sin>

Sine of S0 in Radians; Result

=item C<cos>

Cosine of S0; Result

=item C<tan>

Tangent of S0; Result

=item C<atan2>

ArcTangent of S1 over s0; Result

=item C<count>

Push the number of elements in the array

=item C<index>

Push the current element index (zero-based)

=item C<columns>

Push the number of columns in the array

=item C<column>

Push the current column index

=item C<rows>

Push the number of rows in the array

=item C<row>

Push the current row index

=item C<pi>

Push the the value of PI (but remember calc is just for floats)

=item C<dump>

Print a dump of the current stack to standard out.

    OpenGL::Array->new_list(GL_FLOAT,7)->calc("dup,dec,2,swap,10,4,set,dump");

Would print:

    -----------------(row: 0, col: 0)----
    Register: 4.0000000
    Stack  4: 7.0000000
    Stack  3: 2.0000000
    Stack  2: 6.0000000
    Stack  1: 10.0000000
    Stack  0: 4.0000000

=back

=back

=head1 AUTHOR

Bulk of documentation taken from http://graphcomp.com/pogl.cgi?v=0111s3p1&r=s3p6

Additions by Paul Seamons

=cut