Array(3)
๐ธ NAME ๐ธ
OpenGL::Array โ aka the Array(3) page from the User Contributed Perl Documentation โ is Perl Array handling and conversion between Perl arrays and C array pointers. Slay, bestie, that's the whole vibe ๐
โจ 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 (OGA) objects provide Perl Array handling and conversion between Perl arrays and C array pointers. It's giving bridge between two worlds, no cap ๐ซถ
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). Literally iconic. ๐ฅ
๐ 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. Empty but full of potential, bestie โจ
๐ new_list ๐
my $array = OpenGL::Array->new_list($type,@data);
Creates and populates a uniform array object made up @data of type $type. Populate and serve ๐
๐ 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: becauseOpenGL::Arraysstore 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 bynew_pointer- and vice versa (because they are viewing portions of the same memory). Same memory, different outfit, iykyk ๐ฆ
๐ 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. Cute little scalar-to-array glow-up ๐ธ
๐ 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. Special case deserves special treatment, periodt ๐
๐ฅ 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 trick: grab the native pointer, hand it over, collect your data ๐ซ
๐ OpenGL::Array ACCESSORS ๐
๐ assign ๐
$array->assign($pos, @data);
Sets array data starting at element position $pos using @data. Drop the data in, starting at $pos ๐
๐ assign_data ๐
$array->assign_data($pos, $data);
Sets array data element position $pos using packed string $data. Packed-string realness โจ
๐ retrieve ๐
my @data = $array->retrieve($pos, $len);
Returns an array of $len elements from an array object. Gimme the data, bestie ๐ซถ
๐ retrieve_data ๐
my $data = $array->retrieve_data($pos, $len);
Returns a packed string of length $len bytes from an array object. Packed and ready ๐
๐ elements ๐
my $count = $array->elements();
Returns the element count from an array object. Counting era ๐ข
๐ 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 bestie, it really says it twice ๐๐
๐ offset ๐
ptr = $array->offset($pos);
Returns a C pointer to the $pos element of an array object. Pointer, but make it offset โจ
๐ update_ptr ๐
$array->update_pointer($ptr);
Points the existing OpenGL::Array to a different data pointer. Same array, new pointer, main character energy ๐
๐ธ BINDING TO VBOs ๐ธ
Helps abstract Vertex Array and VBO rendering. Very demure, very abstract ๐
๐จ # 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 and gagged, GPU edition ๐ญ๐ฅ
๐ bound ๐
my $id = $array->bound();
Return bound buffer ID, or 0 if not bound. Zero means unbothered, unbounded, free ๐
๐ง AFFINE TRANSFORMS ON OpenGL::Array OBJECTS ๐ง
Eventually, this API will abstract CPU vs GPU-based affine transforms for the best performance. Future slay in progress โจ
๐ฆ 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.
Affine transform bestie, with the exact $xform facts kept intact: it's an NxN OpenGL::Array object used to transform $array, and #N must be one element wider than the width of the array ๐๐ฆ
๐งฎ Calc: POPULATING AND MANIPULATING OpenGL::Array OBJECTS ๐งฎ
โจ "calc" โจ
okay so calc is the one that populates or mathematically modifies an POGL array, and it uses Reverse Polish Notation (RPN) for the math. Right now, any array you use 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. 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 these primitives, bestie:
!โ Logical "Not" for End of Stack (S0) for the current column; becomes1.0if empty or0., otherwise1.0.-โ Arithmetic Negation ofS0.+โ AddS0and Next on Stack (S1), pop operands and push result (Result).*โ MultiplyS0andS1;Result./โ DivideS1byS0;Result.%โS1ModulusS0;Result.=โ TestS0equality toS1; pop operands and push non-zero (1.0) for true, otherwise0.0(Boolean).>โ Test ifS0Greater thanS1;Boolean.<โ Test ifS0Lesser thanS1;Boolean.?โ IfS0is true (non-zero), popS0andS1; otherwise pops0-3, pushs1.popโ Pops0.randโ Push a random number from0.0to1.0.dupโ Push a copy ofS0.swapโ Swap values ofS0andS1.setโ CopyS0to the column's Register.getโ Push the column's Register onto the column's Stack.storeโ PopS0, and copy the values from the matching row of the passedOpenGL::Arrayat 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โ PopS0, and set the values of the matching row of the passedOpenGL::Arraynamed 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โ PopS0, and push the columnS0value 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โ PopS0, and set the columnS0value 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โ PopS0andS1, and push the columnS0value from rowS1onto 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โ PopS0andS1, and set the columnS0value of rowS1to 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โ PopS0, End if true; column unchanged.endrowโ End processing of current row; column unchanged.endrowifโ PopS0, End processing of current row if true; column unchanged.returnโ End processing; column value set tos0.returnifโ PopS0, End if true; column value set tos0.returnrowโ End processing of current row; column value set tos0.returnrowifโ PopS0, End processing of current row if true; column value set tos0.ifโ alias to?.orโ alias to+.andโ alias to*.incโ Add1toS0.decโ Subtract1fromS0.sumโ Add and pop everything in stack; push result.avgโ Average and pop everything in stack; push result.absโ ReplaceS0with its absolute value.powerโ RaiseS1to the power ofS0;Result.minโ The lower ofS0andS1;Result.maxโ The higher ofS0andS1;Result.sinโ Sine ofS0in Radians;Result.cosโ Cosine ofS0;Result.tanโ Tangent ofS0;Result.atan2โ ArcTangent ofS1overs0;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.
okay that's the whole page, bestie ๐ โ source/version is perl v5.32.1, dated 2024-01-25, and the page is Array(3). periodt. ๐ซถโจ
๐ฆ where this page comes from
- epel 9: perl-OpenGL 0.7000-26.el9 ยท GPL+ or Artistic
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms