Initial Commit
This commit is contained in:
498
database/perl/vendor/lib/OpenGL/Array.pod
vendored
Normal file
498
database/perl/vendor/lib/OpenGL/Array.pod
vendored
Normal file
@@ -0,0 +1,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 suports 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
|
||||
46
database/perl/vendor/lib/OpenGL/Config.pm
vendored
Normal file
46
database/perl/vendor/lib/OpenGL/Config.pm
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
# This is the Perl OpenGL build configuration file.
|
||||
# It contains the final OpenGL build arguements from
|
||||
# the configuration process. Access the values by
|
||||
# use OpenGL::Config which defines the variable
|
||||
# $OpenGL::Config containing the hash arguments from
|
||||
# the WriteMakefile() call.
|
||||
#
|
||||
$OpenGL::Config = {
|
||||
'AUTHOR' => 'Chris Marshall <chm at cpan dot org>',
|
||||
'DEFINE' => '-DHAVE_VER -DGL_VERSION_USED=1.1 -DIS_STRAWBERRY -DHAVE_FREEGLUT -DHAVE_GL -DHAVE_GLU -DHAVE_GLU32 -DHAVE_OPENGL32',
|
||||
'EXE_FILES' => [],
|
||||
'INC' => undef,
|
||||
'LDFROM' => '$(OBJECT) -lopengl32 -lglu32 -lglut',
|
||||
'LIBS' => undef,
|
||||
'META_MERGE' => {
|
||||
'abstract' => 'Perl bindings to the OpenGL API, GLU, and GLUT/FreeGLUT',
|
||||
'resources' => {
|
||||
'bugtracker' => 'http://sourceforge.net/tracker/?group_id=562483&atid=2281758',
|
||||
'homepage' => 'http://sourceforge.net/projects/pogl/',
|
||||
'repository' => 'git://pogl.git.sourceforge.net/gitroot/pogl/pogl'
|
||||
}
|
||||
},
|
||||
'NAME' => 'OpenGL',
|
||||
'OBJECT' => '$(BASEEXT)$(OBJ_EXT) gl_util$(OBJ_EXT) pogl_const$(OBJ_EXT) pogl_gl_top$(OBJ_EXT) pogl_glu$(OBJ_EXT) pogl_rpn$(OBJ_EXT) pogl_matrix$(OBJ_EXT) pogl_glut$(OBJ_EXT) pogl_gl_Accu_GetM$(OBJ_EXT) pogl_gl_GetP_Pass$(OBJ_EXT) pogl_gl_Mult_Prog$(OBJ_EXT) pogl_gl_Pixe_Ver2$(OBJ_EXT) pogl_gl_Prog_Clam$(OBJ_EXT) pogl_gl_Tex2_Draw$(OBJ_EXT) pogl_gl_Ver3_Tex1$(OBJ_EXT) pogl_gl_Vert_Multi$(OBJ_EXT)',
|
||||
'OPTIMIZE' => undef,
|
||||
'PM' => {
|
||||
'Array.pod' => '$(INST_LIBDIR)/OpenGL/Array.pod',
|
||||
'Config.pm' => '$(INST_LIBDIR)/OpenGL/Config.pm',
|
||||
'OpenGL.pm' => '$(INST_LIBDIR)/OpenGL.pm',
|
||||
'OpenGL.pod' => '$(INST_LIBDIR)/OpenGL.pod',
|
||||
'Tessellation.pod' => '$(INST_LIBDIR)/OpenGL/Tessellation.pod'
|
||||
},
|
||||
'PREREQ_PM' => {
|
||||
'Test::More' => 0
|
||||
},
|
||||
'VERSION_FROM' => 'OpenGL.pm',
|
||||
'XSPROTOARG' => '-noprototypes',
|
||||
'clean' => {
|
||||
'FILES' => 'Config.pm utils/glversion.txt utils/glversion.exe utils/glversion.o'
|
||||
},
|
||||
'dynamic_lib' => {}
|
||||
};
|
||||
|
||||
1;
|
||||
__END__
|
||||
817
database/perl/vendor/lib/OpenGL/Tessellation.pod
vendored
Normal file
817
database/perl/vendor/lib/OpenGL/Tessellation.pod
vendored
Normal file
@@ -0,0 +1,817 @@
|
||||
=head1 NAME
|
||||
|
||||
OpenGL::Tessellation - discussion of tessellation in POGL
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
# somewhere in your drawing routine or drawlist compilation
|
||||
|
||||
my $tess = gluNewTess();
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_BEGIN, 'DEFAULT');
|
||||
gluTessCallback($tess, GLU_TESS_END, 'DEFAULT');
|
||||
gluTessCallback($tess, GLU_TESS_VERTEX, 'DEFAULT');
|
||||
gluTessCallback($tess, GLU_TESS_COMBINE, 'DEFAULT');
|
||||
gluTessCallback($tess, GLU_TESS_ERROR, 'DEFAULT');
|
||||
gluTessCallback($tess, GLU_TESS_EDGE_FLAG, 'DEFAULT');
|
||||
|
||||
gluTessBeginPolygon($tess);
|
||||
gluTessBeginContour($tess);
|
||||
|
||||
gluTessVertex_p($tess, 0, 200, 0);
|
||||
gluTessVertex_p($tess, 150, -200, 0);
|
||||
gluTessVertex_p($tess, 0, -100, 0);
|
||||
gluTessVertex_p($tess, -150, -200, 0);
|
||||
|
||||
gluTessEndContour($tess);
|
||||
gluTessEndPolygon($tess);
|
||||
|
||||
gluDeleteTess($tess);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
OpenGL rendering hardware typically does not have support for drawing
|
||||
concave polygons or drawing polygons with windows. OpenGL provides
|
||||
glu extentions that allow for translating concave polygon vertices
|
||||
into triangles that can be rendered quickly on GL hardware. The
|
||||
OpenGL red book chapter 11 has the full discussion of Tessellators and
|
||||
the OpenGL functions (http://glprogramming.com/red/chapter11.html, or
|
||||
use your favorite search engine and search for "opengl gluNewTess").
|
||||
It is a good idea to read that chapter before reading the rest of this
|
||||
document.
|
||||
|
||||
As much as possible, the POGL implementation of the tessellation
|
||||
functions tries to remain faithful to the OpenGL specification. Where
|
||||
it doesn't match exactly, POGL follows the spirit of the specification,
|
||||
but offloads what it can to c based implementations.
|
||||
|
||||
Tessellation functions are safe to call during drawlist creation. It
|
||||
is advisable to use drawlists, or to store the generated polygon data
|
||||
into OpenGL::Array objects as these methods offer faster redraws.
|
||||
|
||||
=head1 FUNCTIONS
|
||||
|
||||
=over 4
|
||||
|
||||
=item C<gluNewTess>
|
||||
|
||||
my $tess = gluNewTess();
|
||||
|
||||
Returns a reference that can be passed to the remaining tesselation
|
||||
functions.
|
||||
|
||||
Note: this isn't the c-reference returned by the normal gluNewTess() c
|
||||
function, it is a struct which contains that reference as well as
|
||||
other members allowing callbacks to interface cleanly with the perl
|
||||
code. This means that if you have loaded other c-libraries that use
|
||||
standard opengl tessellation, you will not be able to use this perl
|
||||
reference directly.
|
||||
|
||||
The POGL implementation of gluNewTess() allows for two additional
|
||||
parameters to be passed. The first is a boolean value indicating that
|
||||
default c callbacks and perl callbacks should be passed rgba color
|
||||
data. The second is a boolean value indicating that xyz normal data
|
||||
should be passed. Eventually one additional flag indicating that
|
||||
texture data should be passed will be added as well.
|
||||
|
||||
my $tess = gluNewTess();
|
||||
# gluTessVertex_p should be passed only x,y,z vertex data
|
||||
# as in gluTessVertex_p($tess, $x, $y, $z);
|
||||
|
||||
my $tess = gluNewTess('do_colors');
|
||||
# gluTessVertex_p should be passed x,y,z AND r,g,b,a vertex data
|
||||
# as in gluTessVertex_p($tess, $x, $y, $z, $r, $g, $b, $a);
|
||||
|
||||
my $tess = gluNewTess('do_colors', 'do_normals');
|
||||
# gluTessVertex_p should be passed x,y,z AND r,g,b,a AND nx,ny,nz vertex data
|
||||
# as in gluTessVertex_p($tess, $x, $y, $z, $r, $g, $b, $a, $nx, $ny, $nz);
|
||||
|
||||
my $tess = gluNewTess(undef, 'do_normals');
|
||||
# gluTessVertex_p should be passed x,y,z AND nx,ny,nz vertex data (no colors)
|
||||
# as in gluTessVertex_p($tess, $x, $y, $z, $nx, $ny, $nz);
|
||||
|
||||
Any true value can be passed in place of 'do_colors' and 'do_normals'
|
||||
though using 'do_colors' and 'do_normals' acts as documentation.
|
||||
|
||||
Behavior in these modes will be discussed further for functions to
|
||||
which they apply.
|
||||
|
||||
=item C<gluDeleteTess>
|
||||
|
||||
gluDeleteTess($tess);
|
||||
|
||||
This deletes the tessellation structure and frees up any remaining
|
||||
associated memory.
|
||||
|
||||
=item C<gluTessCallback>
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_BEGIN, 'DEFAULT');
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_BEGIN, \&glBegin);
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_BEGIN, sub { my $enum = shift; glBegin($enum) });
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_BEGIN); # unsets current handler
|
||||
|
||||
Registers handlers for each of the tessellation callback types. Takes
|
||||
a tessellation reference generated by gluNewTess, a type, and a
|
||||
coderef or the word 'DEFAULT'. If the word 'DEFAULT' is passed, a
|
||||
default c-level callback will be installed (which will be discussed
|
||||
for each callback). If no 3rd argument is given, then any handler
|
||||
currently set will be removed. Valid callback types are
|
||||
|
||||
GLU_TESS_BEGIN
|
||||
GLU_TESS_END
|
||||
GLU_TESS_VERTEX
|
||||
GLU_TESS_COMBINE
|
||||
GLU_TESS_ERROR
|
||||
GLU_TESS_EDGE_FLAG
|
||||
|
||||
GLU_TESS_BEGIN_DATA
|
||||
GLU_TESS_END_DATA
|
||||
GLU_TESS_VERTEX_DATA
|
||||
GLU_TESS_COMBINE_DATA
|
||||
GLU_TESS_ERROR_DATA
|
||||
GLU_TESS_EDGE_FLAG_DATA
|
||||
|
||||
These types and their passed parameters will be discussed in the
|
||||
CALLBACKS section.
|
||||
|
||||
The types ending with "_DATA" are similar to their non-_DATA
|
||||
counterpart, but when called are passed the option $polygon_data that
|
||||
can be set during gluTessBeginPolygon.
|
||||
|
||||
=item C<gluTessBeginPolygon>
|
||||
|
||||
gluTessBeginPolygon($tess);
|
||||
|
||||
gluTessBeginPolygon($tess, $polygon_data);
|
||||
|
||||
Begins the tessellation transaction. It must eventually be
|
||||
ended with a gluTessEndPolygon before the tessellator will normally
|
||||
begin work.
|
||||
|
||||
An optional second argument can be passed which can be any perl
|
||||
scalar or reference. If a callback is registered using a type ending
|
||||
in _DATA, this perl scalar or reference will be passed as an additional
|
||||
argument to that callback.
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_END_DATA, sub {
|
||||
my $polygon_data = shift;
|
||||
glEnd();
|
||||
print "glEnd: (".($polygon_data->[2] eq 8 ? "YES" : "NO").")\n";
|
||||
});
|
||||
|
||||
gluTessBeginPoly($tess, [6,7,8]); # arrayref will be passed to _DATA callbacks
|
||||
|
||||
A sample Object Oriented tesselation sample listed at the end of this
|
||||
document makes use of this "opaque" polygon data.
|
||||
|
||||
=item C<gluTessEndPolygon>
|
||||
|
||||
gluTessEndPolygon($tess);
|
||||
|
||||
Finishes the tessellation transaction, which normally will immediately
|
||||
fire the necessary callbacks generated by the tessellation process.
|
||||
Once finished, it cleans up any accumulated temporary vertice data.
|
||||
|
||||
=item C<gluTessBeginContour>
|
||||
|
||||
gluTessBeginContour($tess);
|
||||
|
||||
Starts a new contour of the tessellation of the current polygon.
|
||||
Please read the OpenGL documentation, and red book chapter on
|
||||
tessellation for more help on when to use different contours. Should
|
||||
eventually be followed by a gluTessEndContour call.
|
||||
|
||||
(At a high level, tessellated polygons may have windows and multiple
|
||||
separate portions. Each inner and outer border of these portions
|
||||
should be represented by a different contour.)
|
||||
|
||||
=item C<gluTessVertex_p>
|
||||
|
||||
gluTessVertex_p($tess, $x, $y, $z);
|
||||
|
||||
gluTessVertex_p($tess, $x, $y, $z, $vertex_data);
|
||||
|
||||
Adds a vertex to the current contour of the current polygon being
|
||||
tessellated.
|
||||
|
||||
If the vertex callback type is set to GLU_TESS_VERTEX, the optional
|
||||
$vertex_data argument will be passed to the vertex callback, and to
|
||||
the combine callback (if GLU_TESS_VERTEX_DATA is used, then the
|
||||
$polygon_data passed to gluTessBeginPolygon will be passed instead).
|
||||
This optional opaque vertex data can be any perl scalar or reference
|
||||
and can be used to pass useful information along during the
|
||||
tessellation process.
|
||||
|
||||
If the 'do_colors' or 'do_normals' parameters were passed to gluNewTess,
|
||||
then those additional properties MUST be passed as additional arguments.
|
||||
|
||||
# my $tess = gluNewTess('do_colors');
|
||||
gluTessVertex_p($tess, $x, $y, $z, $r, $g, $b, $a);
|
||||
gluTessVertex_p($tess, $x, $y, $z, $r, $g, $b, $a, $vertex_data);
|
||||
|
||||
# my $tess = gluNewTess('do_colors', 'do_normals');
|
||||
gluTessVertex_p($tess, $x, $y, $z, $r, $g, $b, $a, $nx, $ny, $nz);
|
||||
gluTessVertex_p($tess, $x, $y, $z, $r, $g, $b, $a, $nx, $ny, $nz, $vertex_data);
|
||||
|
||||
# my $tess = gluNewTess(undef, 'do_normals');
|
||||
gluTessVertex_p($tess, $x, $y, $z, $nx, $ny, $nz);
|
||||
gluTessVertex_p($tess, $x, $y, $z, $nx, $ny, $nz, $vertex_data);
|
||||
|
||||
=back
|
||||
|
||||
=head1 CALLBACKS
|
||||
|
||||
All of the callbacks support a 'DEFAULT' handler that can be installed
|
||||
by passing the word 'DEFAULT' in place of the callback code reference.
|
||||
The DEFAULT c implementations are there to avoid needing to round trip
|
||||
out to perl. The defaults employed are described for each of the
|
||||
callback types.
|
||||
|
||||
With the exception of the COMBINE callback, return values from
|
||||
callbacks are discarded.
|
||||
|
||||
=over 4
|
||||
|
||||
=item C<GLU_TESS_BEGIN>
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_BEGIN, 'DEFAULT');
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_BEGIN, \&glBegin);
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_BEGIN, sub {
|
||||
my $enum = shift;
|
||||
glBegin($enum);
|
||||
});
|
||||
|
||||
The 'DEFAULT' option installs a c-handler that calls the glBegin c
|
||||
function directly without round-tripping out to perl.
|
||||
|
||||
If $polygon_data was set during gluTessBeginPolygon, it is discarded.
|
||||
|
||||
=item C<GLU_TESS_BEGIN_DATA>
|
||||
|
||||
Similar to GLU_TESS_BEGIN but will be passed optional $polygon_data
|
||||
set in gluTessBeginPolygon if any. The 'DEFAULT' handler will ignore
|
||||
this data.
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_BEGIN_DATA, sub {
|
||||
my ($enum, $polygon_data) = @_;
|
||||
glBegin($enum);
|
||||
print "glBegin - and I received polygon_data\n" if $polygon_data;
|
||||
});
|
||||
|
||||
=item C<GLU_TESS_END>
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_END, 'DEFAULT');
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_END, \&glEnd);
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_END, sub { glEnd() });
|
||||
|
||||
The 'DEFAULT' option installs a c-handler that calls the glEnd c
|
||||
function directly without round-tripping out to perl.
|
||||
|
||||
If $polygon_data was set during gluTessBeginPolygon, it is discarded.
|
||||
|
||||
=item C<GLU_TESS_END_DATA>
|
||||
|
||||
Similar to GLU_TESS_END but will be passed optional $polygon_data set
|
||||
in gluTessBeginPolygon if any. The 'DEFAULT' handler will ignore this
|
||||
data.
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_END_DATA, sub {
|
||||
my ($polygon_data) = @_;
|
||||
glEnd();
|
||||
print "glEnd - and I received polygon_data\n" if $polygon_data;
|
||||
});
|
||||
|
||||
=item C<GLU_TESS_VERTEX>
|
||||
|
||||
The GLU_TESS_VERTEX callback handler has slightly different
|
||||
behavior depending on how gluNewTess was called. The optional behaviors
|
||||
allow for sane default processing of colors and normals without needing
|
||||
to roundtrip out to perl.
|
||||
|
||||
my $tess = gluNewTess();
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_VERTEX, 'DEFAULT');
|
||||
|
||||
# the following will break if vertex_data is passed to gluTessVertex_p
|
||||
gluTessCallback($tess, GLU_TESS_VERTEX, \&glVertex3f);
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_VERTEX, sub {
|
||||
my ($x, $y, $z) = @_;
|
||||
glVertex3f($x, $y, $z);
|
||||
});
|
||||
|
||||
# you can also pass vertex_data to gluTessVertex_p
|
||||
gluTessCallback($tess, GLU_TESS_VERTEX, sub {
|
||||
my ($x, $y, $z, $vertex_data) = @_;
|
||||
glVertex3f($x, $y, $z);
|
||||
print "glVertex - and I received vertex_data\n" if $vertex_data;
|
||||
});
|
||||
|
||||
The 'DEFAULT' option installs a c-handler that calls the glVertex c
|
||||
function directly without round-tripping out to perl. The DEFAULT
|
||||
handler discards any polygon_data or vertex_data.
|
||||
|
||||
IF $vertex_data was set during gluTessVertex_p it will be passed as the final
|
||||
argument.
|
||||
|
||||
If gluNewTess was passed 'do_colors' then the GLU_TESS_VERTEX callback
|
||||
will also be passed the rgba information. The 'DEFAULT' option
|
||||
will pass the color information to glColor4f before calling glVertex3f.
|
||||
|
||||
my $tess = gluNewTess('do_colors');
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_VERTEX, sub {
|
||||
my ($x, $y, $z, $r, $g, $b, $a, $vertex_data) = @_;
|
||||
glColor4f($r, $g, $b, $a);
|
||||
glVertex3f($x, $y, $z);
|
||||
});
|
||||
|
||||
If gluNewTess was passed 'do_normals' then the GLU_TESS_VERTEX callback
|
||||
will also be passed the normal x,y,z information. The 'DEFAULT' option
|
||||
will pass the normal information to glNormal3f before calling glVertex3f.
|
||||
|
||||
my $tess = gluNewTess('do_colors', 'do_normals');
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_VERTEX, sub {
|
||||
my ($x, $y, $z, $r, $g, $b, $a, $nx, $ny, $nz, $vertex_data) = @_;
|
||||
glColor4f($r, $g, $b, $a);
|
||||
glNormalf($nx, $ny, $nz);
|
||||
glVertex3f($x, $y, $z);
|
||||
});
|
||||
|
||||
# OR
|
||||
|
||||
my $tess = gluNewTess(undef, 'do_normals');
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_VERTEX, sub {
|
||||
my ($x, $y, $z, $nx, $ny, $nz, $vertex_data) = @_;
|
||||
glNormalf($nx, $ny, $nz);
|
||||
glVertex3f($x, $y, $z);
|
||||
});
|
||||
|
||||
In all cases, any optional vertex_data will be passed as the final argument.
|
||||
|
||||
=item C<GLU_TESS_VERTEX_DATA>
|
||||
|
||||
Similar to GLU_TESS_VERTEX but will be passed optional $polygon_data
|
||||
set in gluTessBeginPolygon (if any) rather than the optional
|
||||
$vertex_data passed to gluTessVertex_p. The 'DEFAULT' handler will
|
||||
ignore this data.
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_VERTEX_DATA, sub {
|
||||
my ($x, $y, $z, $vertex_data) = @_;
|
||||
glVertex3f($x, $y, $z);
|
||||
print "glVertex - and I received vertex_data\n" if $vertex_data;
|
||||
});
|
||||
|
||||
=item C<GLU_TESS_COMBINE>
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_COMBINE, 'DEFAULT');
|
||||
# works with gluTessCallback($tess, GLU_TESS_VERTEX, 'DEFAULT');
|
||||
|
||||
|
||||
# OR
|
||||
|
||||
|
||||
# the following callback is valid for gluNewTess() (no do_colors or do_normals)
|
||||
# using gluTessVertex_p($tess, $x, $y, $z);
|
||||
my $tess = gluNewTess();
|
||||
gluTessCallback($tess, GLU_TESS_COMBINE, sub {
|
||||
my ($x, $y, $z, # new vertex location
|
||||
$v0, $v1, $v2, $v3, # border vertex arrayrefs
|
||||
$w0, $w1, $w2, $w3, # border vertex weights
|
||||
$polygon_data) = @_; # optional data passed to gluTessBeginPolygon
|
||||
return ($x, $y, $z);
|
||||
});
|
||||
# works with gluTessCallback($tess, GLU_TESS_VERTEX, 'DEFAULT');
|
||||
|
||||
|
||||
# OR
|
||||
|
||||
|
||||
# the following callback is valid for gluNewTess() when vertex data is passed
|
||||
# using gluTessVertex_p($tess, $x, $y, $z, [$r, $g, $b, $a]);
|
||||
# The DEFAULT callback cannot automatically proceess this type of data
|
||||
# but passing data to a custom handler this way could handle any arbitrary data passed to it
|
||||
my $tess = gluNewTess();
|
||||
use constant _r => 0;
|
||||
use constant _g => 1;
|
||||
use constant _b => 2;
|
||||
use constant _a => 3;
|
||||
gluTessCallback($tess, GLU_TESS_COMBINE, sub {
|
||||
my ($x, $y, $z, # new vertex location
|
||||
$v0, $v1, $v2, $v3, # border vertex arrayrefs
|
||||
$w0, $w1, $w2, $w3, # border vertex weights
|
||||
$polygon_data) = @_; # optional data passed to gluTessBeginPolygon
|
||||
|
||||
# $v0 will contain [$x, $y, $z, [$r, $g, $b, $a]]
|
||||
my @rgba = map {$_->[3]} $v0, $v1, $v2, $v3;
|
||||
|
||||
# generate a point with color weighted from the surrounding vertices
|
||||
# then return that color information in the same way we received it (an rgba arrayref)
|
||||
return (
|
||||
$x, $y, $z,
|
||||
[$w0*$rgba[0]->[_r] + $w1*$rgba[1]->[_r] + $w2*$rgba[2]->[_r] + $w3*$rgba[3]->[_r],
|
||||
$w0*$rgba[0]->[_g] + $w1*$rgba[1]->[_g] + $w2*$rgba[2]->[_g] + $w3*$rgba[3]->[_g],
|
||||
$w0*$rgba[0]->[_b] + $w1*$rgba[1]->[_b] + $w2*$rgba[2]->[_b] + $w3*$rgba[3]->[_b],
|
||||
$w0*$rgba[0]->[_a] + $w1*$rgba[1]->[_a] + $w2*$rgba[2]->[_a] + $w3*$rgba[3]->[_a]],
|
||||
);
|
||||
});
|
||||
# works with gluTessCallback($tess, GLU_TESS_VERTEX, sub {
|
||||
# my ($x, $y, $z, $rgba) = @_;
|
||||
# glColor4f(@$rgba);
|
||||
# glVertex3f($x, $y, $z);
|
||||
# });
|
||||
|
||||
|
||||
# OR
|
||||
|
||||
|
||||
# the following callback is valid for gluNewTess('do_colors')
|
||||
# using gluTessVertex_p($tess, $x, $y, $z, $r, $g, $b, $a);
|
||||
# the DEFAULT callback COULD automatically proceess this type of data as well if additional vertex data is not passed
|
||||
my $tess = gluNewTess('do_colors');
|
||||
use constant _r => 3;
|
||||
use constant _g => 4;
|
||||
use constant _b => 5;
|
||||
use constant _a => 6;
|
||||
gluTessCallback($tess, GLU_TESS_COMBINE, sub {
|
||||
my ($x, $y, $z, # new vertex location
|
||||
$v0, $v1, $v2, $v3, # border vertex arrayrefs
|
||||
$w0, $w1, $w2, $w3, # border vertex weights
|
||||
$polygon_data) = @_; # optional data passed to gluTessBeginPolygon
|
||||
|
||||
# $v0 will contain [$x, $y, $z, $r, $g, $b, $a]
|
||||
|
||||
return ( # generate a point with color weighted from the surrounding vertices
|
||||
$x, $y, $z,
|
||||
$w0*$v0->[_r] + $w1*$v1->[_r] + $w2*$v2->[_r] + $w3*$v3->[_r],
|
||||
$w0*$v0->[_g] + $w1*$v1->[_g] + $w2*$v2->[_g] + $w3*$v3->[_g],
|
||||
$w0*$v0->[_b] + $w1*$v1->[_b] + $w2*$v2->[_b] + $w3*$v3->[_b],
|
||||
$w0*$v0->[_a] + $w1*$v1->[_a] + $w2*$v2->[_a] + $w3*$v3->[_a],
|
||||
($v0->[7] || $v1->[7] || $v2->[7] || $v3->[7]), # if we received vertex data - return some for the new vertex
|
||||
);
|
||||
});
|
||||
# works with gluTessCallback($tess, GLU_TESS_VERTEX, 'DEFAULT');
|
||||
# OR
|
||||
# works with gluTessCallback($tess, GLU_TESS_VERTEX, sub {
|
||||
# my ($x, $y, $z, $r, $g, $b, $a, $vertex_data) = @_;
|
||||
# glColor4f($r, $g, $b, $a);
|
||||
# glVertex3f($x, $y, $z);
|
||||
# });
|
||||
|
||||
The combine callback is called if the tessellator decides a new vertex
|
||||
is needed. This will happen with self intersecting polygons. In this
|
||||
case, the COMBINE callback can be used to interpolate appropriate
|
||||
values for normals, and colors, or for any desired information.
|
||||
|
||||
The combine callback will be passed the following:
|
||||
|
||||
=over 4
|
||||
|
||||
=item C<$x, $y, $z>
|
||||
|
||||
The x y and z coordinates of the new vertex being created.
|
||||
|
||||
=item C<$v0, $v1, $v2, $v3>
|
||||
|
||||
Arrayrefs of vertex information for the vertices bordering this
|
||||
new vertex (the ones that caused the new vertex to be created).
|
||||
|
||||
By default if gluNewTess() is called, these arrayrefs will be passed:
|
||||
|
||||
my ($x, $y, $z, $vertex_data) = @$v0;
|
||||
# received from gluTessVertex_p($tess, $x, $y, $z, $vertex_data);
|
||||
|
||||
If gluNewTess('do_colors') is called, the following will be passed:
|
||||
|
||||
my ($x, $y, $z, $r, $g, $b, $a, $vertex_data) = @$v0;
|
||||
# received from gluTessVertex_p($tess, $x, $y, $z, $r, $g, $b, $a, $vertex_data);
|
||||
|
||||
If gluNewTess('do_colors', 'do_normals') is called, the following will be passed:
|
||||
|
||||
my ($x, $y, $z, $r, $g, $b, $a, $nx, $ny, $nz, $vertex_data) = @$v0;
|
||||
# received from gluTessVertex_p($tess, $x, $y, $z, $r, $g, $b, $a, $nx, $ny, $nz, $vertex_data);
|
||||
|
||||
If gluNewTess(undef, 'do_normals') is called, the following will be passed:
|
||||
|
||||
my ($x, $y, $z, $nx, $ny, $nz, $vertex_data) = @$v0;
|
||||
# received from gluTessVertex_p($tess, $x, $y, $z, $nx, $ny, $nz, $vertex_data);
|
||||
|
||||
In all cases, the data returned by the COMBINE callback should be in the same
|
||||
format that each of the vertices are in when passed into the COMBINE callback.
|
||||
|
||||
=item C<$w0, $w1, $w2, $w3>
|
||||
|
||||
Weights of the participating vertices (weight $w0 corresponds to vertex $v0).
|
||||
|
||||
=item C<optional $polygon_data>
|
||||
|
||||
Any optional data passed to gluTessBeginPolygon. Normally this would
|
||||
only be passed to GLU_TESS_COMBINE_DATA, but GLU_TESS_COMBINE_DATA
|
||||
and GLU_TESS_COMBINE share the same code implementation.
|
||||
|
||||
=back
|
||||
|
||||
=item C<GLU_TESS_COMBINE_DATA>
|
||||
|
||||
Identical in function to the GLU_TESS_COMBINE handler. They
|
||||
use the same callback implementation.
|
||||
|
||||
=item C<GLU_TESS_ERROR>
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_ERROR, 'DEFAULT');
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_ERROR, \&glEdgeFlag);
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_ERROR, sub {
|
||||
my $errno = shift;
|
||||
my $err = gluErrorString($errno);
|
||||
warn "Received a glu tess error ($errno - $err)\n";
|
||||
});
|
||||
|
||||
The 'DEFAULT' option installs a c-handler that warns with the
|
||||
appropriate gluErrorString.
|
||||
|
||||
If $polygon_data was set during gluTessBeginPolygon, it is discarded.
|
||||
|
||||
=item C<GLU_TESS_ERROR_DATA>
|
||||
|
||||
Similar to GLU_TESS_ERROR but will be passed optional $polygon_data
|
||||
set in gluTessBeginPolygon if any. The 'DEFAULT' handler will ignore
|
||||
this data.
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_ERROR_DATA, sub {
|
||||
my ($errno, $polygon_data) = @_;
|
||||
my $err = gluErrorString($errno);
|
||||
warn "Received a glu tess error ($errno - $err)\n";
|
||||
warn "And I received polygon_data\n" if $polygon_data;
|
||||
});
|
||||
|
||||
=item C<GLU_TESS_EDGE_FLAG>
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_EDGE_FLAG, 'DEFAULT');
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_EDGE_FLAG, \&glEdgeFlag);
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_EDGE_FLAG, sub {
|
||||
my ($flag) = @_;
|
||||
glEdgeFlag($flag);
|
||||
});
|
||||
|
||||
The 'DEFAULT' option installs a c-handler that calls the glEdgeFlag c
|
||||
function directly without round-tripping out to perl.
|
||||
|
||||
If $polygon_data was set during gluTessBeginPolygon, it is discarded.
|
||||
|
||||
=item C<GLU_TESS_EDGE_FLAG_DATA>
|
||||
|
||||
Similar to GLU_TESS_EDGE_FLAG but will be passed $polygon_data set in
|
||||
gluTessBeginPolygon if any. The 'DEFAULT' handler will ignore this
|
||||
data.
|
||||
|
||||
gluTessCallback($tess, GLU_TESS_EDGE_FLAG_DATA, sub {
|
||||
my ($flag, $polygon_data) = @_;
|
||||
glEdgeFlag($flag);
|
||||
print "glEdgeFlag - and I received polygon_data\n" if $polygon_data;
|
||||
});
|
||||
|
||||
=back
|
||||
|
||||
=head1 Example: Basic Arrowhead
|
||||
|
||||
use OpenGL qw(:all);
|
||||
|
||||
glutInit();
|
||||
glutInitWindowSize(501, 501);
|
||||
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
|
||||
glutCreateWindow("Tessellation");
|
||||
glMatrixMode(GL_PROJECTION());
|
||||
glLoadIdentity();
|
||||
glOrtho(-250,250,-250,250,-1.0,1.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
my $view_triangles = 1; # set to zero to show polygon
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) if $view_triangles;
|
||||
|
||||
glutDisplayFunc(sub {
|
||||
glColor3f(1,1,1);
|
||||
|
||||
my $tess = gluNewTess();
|
||||
gluTessCallback($tess, GLU_TESS_BEGIN, 'DEFAULT');
|
||||
gluTessCallback($tess, GLU_TESS_END, 'DEFAULT');
|
||||
gluTessCallback($tess, GLU_TESS_VERTEX, 'DEFAULT');
|
||||
gluTessCallback($tess, GLU_TESS_COMBINE, 'DEFAULT');
|
||||
gluTessCallback($tess, GLU_TESS_ERROR, 'DEFAULT');
|
||||
gluTessCallback($tess, GLU_TESS_EDGE_FLAG, 'DEFAULT') if ! $view_triangles;
|
||||
gluTessBeginPolygon($tess);
|
||||
gluTessBeginContour($tess);
|
||||
|
||||
gluTessVertex_p($tess, 0, 200, 0);
|
||||
gluTessVertex_p($tess, 150, -200, 0);
|
||||
gluTessVertex_p($tess, 0, -100, 0);
|
||||
gluTessVertex_p($tess, -150, -200, 0);
|
||||
|
||||
gluTessEndContour($tess);
|
||||
gluTessEndPolygon($tess);
|
||||
gluDeleteTess($tess);
|
||||
|
||||
glutSwapBuffers();
|
||||
});
|
||||
|
||||
glutMainLoop();
|
||||
|
||||
=head1 Example: Multiple contours
|
||||
|
||||
use OpenGL qw(:all);
|
||||
|
||||
glutInit();
|
||||
glutInitWindowSize(501, 501);
|
||||
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
|
||||
glutCreateWindow("Tessellation");
|
||||
glMatrixMode(GL_PROJECTION());
|
||||
glLoadIdentity();
|
||||
glOrtho(-250,250,-250,250,-1.0,1.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
my $view_triangles = 1; # set to zero to show polygon
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) if $view_triangles;
|
||||
|
||||
glutDisplayFunc(sub {
|
||||
glColor3f(1,1,1);
|
||||
my $v = [[[125,0,0], [150,150,0], [0,125,0], [-150,150,0],
|
||||
[-125,0,0], [-150,-150,0], [0,-125,0], [150,-150,0], [125,0,0]],
|
||||
[[75,0,0], [100,100,0], [0,75,0], [-100,100,0],
|
||||
[-75,0,0], [-100,-100,0], [0,-75,0], [100,-100,0], [75,0,0]]
|
||||
];
|
||||
|
||||
my $tess = gluNewTess();
|
||||
gluTessCallback($tess, GLU_TESS_BEGIN, 'DEFAULT');
|
||||
gluTessCallback($tess, GLU_TESS_END, 'DEFAULT');
|
||||
gluTessCallback($tess, GLU_TESS_VERTEX, 'DEFAULT');
|
||||
gluTessCallback($tess, GLU_TESS_COMBINE, 'DEFAULT');
|
||||
gluTessCallback($tess, GLU_TESS_ERROR, 'DEFAULT');
|
||||
gluTessCallback($tess, GLU_TESS_EDGE_FLAG, 'DEFAULT') if ! $view_triangles;
|
||||
gluTessBeginPolygon($tess);
|
||||
foreach (@$v) {
|
||||
gluTessBeginContour($tess);
|
||||
foreach (@$_) {
|
||||
gluTessVertex_p($tess, @$_);
|
||||
}
|
||||
gluTessEndContour($tess);
|
||||
}
|
||||
gluTessEndPolygon($tess);
|
||||
gluDeleteTess($tess);
|
||||
|
||||
glutSwapBuffers();
|
||||
});
|
||||
|
||||
glutMainLoop();
|
||||
|
||||
=head1 Example: Sample OO Tessellation interface using polygon_data
|
||||
|
||||
|
||||
use OpenGL qw(:all);
|
||||
|
||||
glutInit();
|
||||
glutInitWindowSize(501, 501);
|
||||
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
|
||||
glutCreateWindow("Tessellation");
|
||||
glMatrixMode(GL_PROJECTION());
|
||||
glLoadIdentity();
|
||||
glOrtho(-250,250,-250,250,-1.0,1.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
my $view_triangles = 0;
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) if $view_triangles;
|
||||
|
||||
glutDisplayFunc(sub {
|
||||
glColor3f(1,1,1);
|
||||
my $v = [[[125,0,0], [150,150,0, 0,1,0], [0,125,0], [-150,150,0, 1,0,0],
|
||||
[-125,0,0], [-150,-150,0, 0,0,1], [0,-125,0], [150,-150,0, 1,1,0], [125,0,0]],
|
||||
[[75,0,0], [100,100,0], [0,75,0], [-100,100,0],
|
||||
[-75,0,0], [-100,-100,0], [0,-75,0], [100,-100,0], [75,0,0]]
|
||||
];
|
||||
|
||||
OpenGL::Tess->new(do_colors => 1, no_edge_flag => $view_triangles)->draw_contours(@$v);
|
||||
|
||||
glutSwapBuffers();
|
||||
});
|
||||
|
||||
glutMainLoop();
|
||||
|
||||
###----------------------------------------------------------------###
|
||||
|
||||
|
||||
package OpenGL::Tess;
|
||||
|
||||
# Sample object oriented Tessellator
|
||||
# OpenGL::Tess->new(do_colors => 1, no_edge_flag => $view_triangles)->draw_contours(@$v);
|
||||
|
||||
use strict;
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = bless {@_}, $class;
|
||||
my $tess = $self->{'_tess'} = OpenGL::gluNewTess($self->do_colors);
|
||||
for my $cb (qw(begin end vertex combine error edge_flag)) {
|
||||
my $enum = OpenGL->can("GLU_TESS_\U${cb}_DATA") || die "Couldn't find callback for $cb";
|
||||
my $name = "_$cb";
|
||||
OpenGL::gluTessCallback($tess, $enum->(), sub { $_[-1]->$name(@_) });
|
||||
}
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub DESTROY {
|
||||
my $tess = shift->{'_tess'};
|
||||
OpenGL::gluDeleteTess($tess) if $tess;
|
||||
}
|
||||
|
||||
sub tess {
|
||||
my $self = shift;
|
||||
return $self->{'_tess'} || die "Missing tess";
|
||||
}
|
||||
|
||||
sub do_colors { shift->{'do_colors'} }
|
||||
|
||||
sub begin_polygon {
|
||||
my $self = shift;
|
||||
my $tess = $self->tess;
|
||||
# self will be passed as last arg ([-1]) to all callbacks as opaque polygon data
|
||||
return OpenGL::gluTessBeginPolygon($tess, $self);
|
||||
}
|
||||
|
||||
sub end_polygon { OpenGL::gluTessEndPolygon( shift->tess) }
|
||||
sub begin_contour { OpenGL::gluTessBeginContour(shift->tess) }
|
||||
sub end_contour { OpenGL::gluTessEndContour( shift->tess) }
|
||||
|
||||
sub draw_contours {
|
||||
my $self = shift;
|
||||
$self->begin_polygon;
|
||||
foreach my $c (@_) {
|
||||
$self->begin_contour;
|
||||
$self->add_vertex(@$_) for @$c;
|
||||
$self->end_contour;
|
||||
}
|
||||
$self->end_polygon;
|
||||
}
|
||||
|
||||
sub add_vertex {
|
||||
my $self = shift;
|
||||
die 'Usage $self->add_vertex($x,$y,$z)' if @_ < 3;
|
||||
if ($self->do_colors) {
|
||||
push @_, 1 for @_ .. 6;
|
||||
OpenGL::gluTessVertex_p($self->tess, @_[0..6]);
|
||||
} else {
|
||||
OpenGL::gluTessVertex_p($self->tess, @_[0..3]);
|
||||
}
|
||||
}
|
||||
|
||||
sub _begin {
|
||||
my ($self, $enum) = @_;
|
||||
OpenGL::glBegin($enum);
|
||||
}
|
||||
|
||||
sub _end { OpenGL::glEnd() }
|
||||
|
||||
sub _vertex {
|
||||
my ($self, $x, $y, $z, $r, $g, $b, $a) = @_;
|
||||
OpenGL::glColor4f($r, $g, $b, $a) if $self->do_colors;
|
||||
OpenGL::glVertex3f($x, $y, $z);
|
||||
}
|
||||
|
||||
sub _edge_flag {
|
||||
my ($self, $flag) = @_;
|
||||
return if $self->{'no_edge_flag'};
|
||||
OpenGL::glEdgeFlag($flag);
|
||||
}
|
||||
|
||||
sub _error {
|
||||
my ($self, $errno) = @_;
|
||||
warn __PACKAGE__ ." error: ".OpenGL::gluErrorString($errno);
|
||||
}
|
||||
|
||||
sub _combine {
|
||||
my ($self, $x, $y, $z, $v0, $v1, $v2, $v3, $w0, $w1, $w2, $w3) = @_;
|
||||
return ($x, $y, $z) if !$self->do_colors;
|
||||
return ($x, $y, $z,
|
||||
$w0*$v0->[3] + $w1*$v1->[3] + $w2*$v2->[3] + $w3*$v3->[3],
|
||||
$w0*$v0->[4] + $w1*$v1->[4] + $w2*$v2->[4] + $w3*$v3->[4],
|
||||
$w0*$v0->[5] + $w1*$v1->[5] + $w2*$v2->[5] + $w3*$v3->[5],
|
||||
$w0*$v0->[6] + $w1*$v1->[6] + $w2*$v2->[6] + $w3*$v3->[6]);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Paul Seamons - paul AT seamons dot com - 2011
|
||||
|
||||
=cut
|
||||
Reference in New Issue
Block a user