OpenGL::Array - Perl Array handling and conversion between Perl arrays and C array pointers. |
OpenGL::Array - Perl Array handling and conversion between Perl arrays and C array pointers.
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);
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).
new
my $array = OpenGL::Array->new($count,@types);
Creates an empty array object of $count rows made up data types @types.
new_list
my $array = OpenGL::Array->new_list($type,@data);
Creates and populates a uniform array object made up @data of type $type.
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).
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.
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.
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);
assign
$array->assign($pos, @data);
Sets array data starting at element position $pos using @data.
assign_data
$array->assign_data($pos, $data);
Sets array data element position $pos using packed string $data.
retrieve
my @data = $array->retrieve($pos, $len);
Returns an array of $len elements from an array object.
retrieve_data
my $data = $array->retrieve_data($pos, $len);
Returns a packed string of length $len bytes from an array object.
elements
my $count = $array->elements();
Returns the element count from an array object.
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.
offset
ptr = $array->offset($pos);
Returns a C pointer to the $pos element of an array object.
update_ptr
$array->update_pointer($ptr);
Points the existing OpenGL::Array to a different data pointer.
Helps abstract Vertex Array and VBO rendering.
# Requires GL_ARB_vertex_buffer_object extension and POGL 0.55_01 or newer
bind
$array->bind($id);
Binds a GPU buffer to an array object. If bound, glXxxPointer_p APIs will call glBindBufferARB.
bound
my $id = $array->bound();
Return bound buffer ID, or 0 if not bound.
Eventually, this API will abstract CPU vs GPU-based affine transforms for the best performance.
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.
calc
$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.
calc
maintains a push/pop stack and a ``register'' for each column.
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 suports the following primitives:
!
-
+
/
%
=
>
<
?
pop
rand
dup
swap
set
get
store
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)
load
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)
colget
$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)
colset
$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)
rowget
$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)
rowset
$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)
end
endif
endrow
endrowif
return
returnif
returnrow
returnrowif
if
?
or
+
and
*
inc
dec
sum
avg
abs
power
min
max
sin
cos
tan
atan2
count
index
columns
column
rows
row
pi
dump
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
Bulk of documentation taken from http://graphcomp.com/pogl.cgi?v=0111s3p1&r=s3p6
Additions by Paul Seamons
OpenGL::Array - Perl Array handling and conversion between Perl arrays and C array pointers. |