Array(3pm) | User Contributed Perl Documentation | Array(3pm) |
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).
my $array = OpenGL::Array->new($count,@types);
Creates an empty array object of $count rows made up data types @types.
my $array = OpenGL::Array->new_list($type,@data);
Creates and populates a uniform array object made up @data of type $type.
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).
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.
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);
$array->assign($pos, @data);
Sets array data starting at element position $pos using @data.
$array->assign_data($pos, $data);
Sets array data element position $pos using packed string $data.
my @data = $array->retrieve($pos, $len);
Returns an array of $len elements from an array object.
my $data = $array->retrieve_data($pos, $len);
Returns a packed string of length $len bytes from an array object.
my $count = $array->elements();
Returns the element count from an array object.
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.
ptr = $array->offset($pos);
Returns a C pointer to the $pos element of an array object.
$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
$array->bind($id);
Binds a GPU buffer to an array object. If bound, glXxxPointer_p APIs will call glBindBufferARB.
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.
$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.
$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 supports the following primitives:
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)
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)
$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)
$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)
$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)
$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)
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
2020-11-09 | perl v5.32.0 |