OpenGL::Array(3pm)

๐Ÿ“ฆ
version 0.7004 ยท 2 versions
, in debian trixie, ubuntu resolute

โœจ NAME โœจ

OpenGL::Array โ€” Perl Array handling and conversion between Perl arrays and C array pointers. And yeah bestie, this is the OpenGL::Array(3pm) page from User Contributed Perl Documentation โ€” no cap, we're doing the whole thing. ๐Ÿ’–

๐ŸŽ€ 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);

๐Ÿ’… DESCRIPTION ๐Ÿ’…

OpenGL::Array (aka OGA) objects are all about Perl Array handling and conversion between Perl arrays and C array pointers. Slay. โœจ

Because Perl and C handle pointers <em>completely</em> differently, all Perl OpenGL (POGL) APIs that need pointers get the _c suffix. OGAs are the little bridge that turns Perl arrays into C pointers you can pass into those APIs. ๐Ÿซถ

A lot of POGL _c APIs also have a _s version for SDL's packed string APIs; OGA gives you APIs to convert between C arrays and packed strings. ๐Ÿ’–

POGL also has many _p APIs that take native Perl arrays, or sometimes OGAs directly. With VBOs, OGAs can be bound to GPU buffers and will automatically switch buffers at render time. ๐Ÿ”ฅ

Note, bestie: since OGAs are stored as typed C arrays, there's no conversion/copy/casting when you pass them to POGL APIs. That means significant performance improvements over other non-compiled bindings like SDL, PyOpenGL, etc. Periodt. ๐Ÿ’…

๐Ÿ› ๏ธ CREATING OpenGL::Array OBJECTS ๐Ÿ› ๏ธ

โœจ new โœจ

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

Creates an empty array object of $count rows made up data types @types. Cute and empty, ready for data. ๐ŸŽ€

๐ŸŒธ new_list ๐ŸŒธ

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

Creates and populates a uniform array object made up @data of type $type. One type, all the data, iconic. ๐Ÿ’–

๐Ÿฆ‹ 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 the 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). So yeah, they're literally sharing the same brain cell. ๐Ÿง โœจ

๐Ÿ“ 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. Simple as that, bestie. ๐Ÿ’…

๐ŸŒˆ 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. Very niche, very valid. ๐Ÿ‘‘

๐Ÿซถ 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);

That's the whole vibe: make the array, grab the pointer, let OpenGL do its thing. ๐Ÿ’–

๐ŸŒˆ OpenGL::Array ACCESSORS ๐ŸŒˆ

๐Ÿ’… assign ๐Ÿ’…

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

Sets array data starting at element position $pos using @data. Put the data exactly where you want it. ๐ŸŽ€

โœจ assign_data โœจ

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

Sets array data element position $pos using packed string $data. Packed string girlies rise. ๐Ÿฆ‹

๐ŸŒธ retrieve ๐ŸŒธ

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

Returns an array of $len elements from an array object. Get those elements back, bestie. ๐Ÿ’–

๐Ÿ“ retrieve_data ๐Ÿ“

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

Returns a packed string of length $len bytes from an array object. Packed string on the way out too. โœจ

๐Ÿ‘‘ elements ๐Ÿ‘‘

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

Returns the element count from an array object. How many elements? This many. ๐Ÿ’…

๐ŸŽ€ 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.

Yes, she said it twice. Both times true. ๐Ÿ˜ญ๐Ÿ’–

๐Ÿฆ‹ offset ๐Ÿฆ‹

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

Returns a C pointer to the $pos element of an array object. Skip to the element you want, pointer style. โœจ

๐ŸŒˆ update_ptr ๐ŸŒˆ

$array->update_pointer($ptr);

Points the existing OpenGL::Array to a different data pointer. New pointer, same array object, slay. ๐Ÿ”ฅ

๐Ÿ”ฅ BINDING TO VBOs ๐Ÿ”ฅ

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. GPU buffer said yes to the array. ๐Ÿ‘‘

โœจ bound โœจ

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

Return bound buffer ID, or 0 if not bound. Zero means single, bestie. ๐Ÿ’…

๐Ÿ‘‘ AFFINE TRANSFORMS ON OpenGL::Array OBJECTS ๐Ÿ‘‘

Eventually, this API will abstract CPU vs GPU-based affine transforms for the best performance. Future goals, current vibes. โœจ

๐ŸŽ€ 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: POPULATING AND MANIPULATING OpenGL::Array OBJECTS

okay bestie, this is the calc era and it's giving math but make it RPN โœจ. calc is used to populate or mathematically modify a POGL array. It uses Reverse Polish Notation (RPN) for mathematical operations. At the moment, any array used with calc must be made of only GL_FLOAT types. no cap.

$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. slay.

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: the whole toolbox ๐Ÿ’…

  • ! โ€” Logical "Not" for End of Stack (S0) for the current column; becomes 1.0 if empty or 0. otherwise 1.0.
  • - โ€” Arithmetic Negation of S0.
  • + โ€” Add S0 and Next on Stack (S1), pop operands and push result (Result).
  • * โ€” Multiply S0 and S1; Result.
  • / โ€” Divide S1 by S0; Result.
  • % โ€” S1 Modulus S0; Result.
  • = โ€” Test S0 equality to S1; pop operands and push non-zero (1.0) for true, otherwise 0.0 (Boolean).
  • > โ€” Test if S0 Greater than S1; Boolean.
  • < โ€” Test if S0 Lesser than S1; Boolean.
  • ? โ€” If S0 is true (non-zero), pop S0 and S1; otherwise pop s0-3, push s1.
  • pop โ€” Pop s0.
  • rand โ€” Push a random number from 0.0 to 1.0.
  • dup โ€” Push a copy of S0.
  • swap โ€” Swap values of S0 and S1.
  • set โ€” Copy S0 to the column's Register.
  • get โ€” Push the column's Register onto the column's Stack.
  • 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)
  • 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)
  • 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)
  • 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)
  • 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)
  • 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)
  • end โ€” End processing; column unchanged.
  • endif โ€” Pop S0, End if true; column unchanged.
  • endrow โ€” End processing of current row; column unchanged.
  • endrowif โ€” Pop S0, End processing of current row if true; column unchanged.
  • return โ€” End processing; column value set to s0.
  • returnif โ€” Pop S0, End if true; column value set to s0.
  • returnrow โ€” End processing of current row; column value set to s0.
  • returnrowif โ€” Pop S0, End processing of current row if true; column value set to s0.
  • if โ€” alias to ?.
  • or โ€” alias to +.
  • and โ€” alias to *.
  • inc โ€” Add 1 to S0.
  • dec โ€” Subtract 1 from S0.
  • sum โ€” Add and pop everything in stack; push result.
  • avg โ€” Average and pop everything in stack; push result.
  • abs โ€” Replace S0 with its absolute value.
  • power โ€” Raise S1 to the power of S0; Result.
  • min โ€” The lower of S0 and S1; Result.
  • max โ€” The higher of S0 and S1; Result.
  • sin โ€” Sine of S0 in Radians; Result.
  • cos โ€” Cosine of S0; Result.
  • tan โ€” Tangent of S0; Result.
  • atan2 โ€” ArcTangent of S1 over s0; Result.
  • count โ€” Push the number of elements in the array.
  • index โ€” Push the current element index (zero-based).
  • columns โ€” Push the number of columns in the array.
  • column โ€” Push the current column index.
  • rows โ€” Push the number of rows in the array.
  • row โ€” Push the current row index.
  • pi โ€” Push the the value of PI (but remember calc is just for floats).
  • 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

๐Ÿ‘‘ AUTHOR

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

Additions by Paul Seamons


and that's the whole vibe bestie ๐Ÿ’– this page is OpenGL::Array(3pm), from perl v5.40.1, dated 2025-03-21. periodt โœจ๐Ÿฆ‹

๐Ÿ“ฆ where this page comes from