NAME

OpenGL::Sandbox::V1 - Various OpenGL tools and utilities that depend on the OpenGL 1.x API

VERSION

version 0.042

DESCRIPTION

This module is seperate from OpenGL::Sandbox in order to keep the OpenGL API dependencies less tangled. Everything specific to OpenGL 1.x that I would have otherwise included in OpenGL::Sandbox is located here, instead. The main OpenGL::Sandbox module can automatically load this module using the import tag of -V1. After doing so, all these additional symbols are made available from the main OpenGL::Sandbox module.

EXPORTABLE FUNCTIONS

WINDOW FUNCTIONS

next_frame

Loading OpenGL::Sandbox::V1 causes the "next_frame" in OpenGL::Sandbox function to also call

glLoadIdentity();

This is excluded by default since glLoadIdentity isn't applicable to newer GL programs.

MATRIX FUNCTIONS

load_identity

Alias for glLoadIdentity

setup_projection

The default OpenGL context projects with a lower-left of (-1,-1) and upper-right of (1,1), with near and far clipping planes of (-1 .. 1). This isn't terribly useful.

setup_projection( %opts )

This function assists with setting up a coordinate system (either glOrtho or glFrustum) where the aspect ratio of the screen is preserved, and the Z coordinate is pre-translated to something in front of the near clipping plane.

That last bit is hard to describe, but consider that you want a 3D frustum where the left edge of the screen is (-10,0,0) and right edge of the screen is (10,0,0), and the top is at something that matches the aspect ration (like say, (0,.6,0)) and near clipping plane is at z = -10. For that, simply call

setup_projection( left => -10, right => 10, near => 1, z => 11 );

(near must be greater than zero, and 1 is a good choice. So set Z = Near + 10). If you had tried the similar

glFrustum(-10, 10, -.6, .6, 1, 1000);
glTranslate(0,0,-10);

the left and right edges wouldn't be where you wanted after the call to glTranslate. This method corrects for that.

Options:

left, right, top, bottom, width, height

The edges of the screen at the near clipping plane. Missing values will be calculated from others (such as left from width and right) and as a last resort, the aspect ratio of the viewport. (and viewport defaults to same dimensions as screen) If nothing is given, it starts with a bottom of -1 and top of 1 and the rest from viewport aspect ratio.

near, far

The near and far clipping plane. The near clipping plane is the pre-translation value passed to glOrtho or glFrustum. The default far is 1000. The default near is 1 for furstum and -1 for ortho.

ortho

If true, calls glOrtho. Else calls glFrustum.

x, y, z

Coordinates of the desired origin, after setting up the ortho/frustum.

apect

Override the aspect ratio used to calculate default width/height.

mirror_x, mirror_y

Set these (boolean) to flip the orientation of that axis. If only one axis is flipped, then this also updates the value of glFrontFace to GL_CW. Else it sets the value of glFrontFace to GL_CCW (the default).

local_matrix

local_matrix { ... };

Wrap a block of code with glPushMatrix/glPopMatrix. This wrapper also checks the matrix stack depth before and after the call, warns if they don't match, and performs any missing glPopMatrix calls.

scale

scale $xyz;
scale $x, $y; # z=1
scale $x, $y, $z;

Scale all axes (one argument), the x and y axes (2 arguments), or a normal call to glScale (3 arguments).

trans

trans $x, $y;
trans $x, $y, $z;

Translate by x,y or x,y,z. $z defaults to 0 if not supplied.

trans_scale

trans_scale $x, $y, $x, $s;       # scale each by $s
trans_scale $x, $y, $x, $sx, $sy; # $sz=1
trans_scale $x, $y, $x, $sx, $sy, $sz;

Combination of "trans" then "scale".

rotate

rotate $degrees, $x, $y, $z;
rotate x => $degrees;
rotate y => $degrees;
rotate z => $degrees;

Normal call to glRotated, or x/y/z notation to rotate around that axis.

mirror

mirror 'x';  # glScale(-1, 0, 0)
mirror 'y';  # glScale(0, -1, 0)
mirror 'xyz'; # glScale(-1, -1, -1)

Use glScale to invert one more more axes.

local_gl

local_gl { ... };

Like local_matrix, but also calls glPushAttrib/glPopAttrib. This is expensive, and should probably only be used for debugging.

GEOMETRY PLOTTING

lines

lines { ... };

Wraps code with glBegin(GL_LINES); ... glEnd();, and also temporarily disables GL_TEXTURE_2D.

line_strip

line_strip { ... };

Wraps code with glBegin(GL_LINE_STRIP); ... glEnd();, and also temporarily disables GL_TEXTURE_2D.

quads

quads { ... };  # wraps code with glBegin(GL_QUADS); ... glEnd();

quad_strip

quad_strip { ... }; # wraps code with glBegin(GL_QUAD_STRIP); ... glEnd();

triangles

triangles { ... }; # wraps code with glBegin(GL_TRIANGLES); ... glEnd();

triangle_strip

triangle_strip { ... }; # wraps code with glBegin(GL_TRIANGLE_STRIP); ... glEnd();

triangle_fan

triangle_fan { ... }; # wraps code with glBegin(GL_TRIANGLE_FAN); ... glEnd();

vertex

vertex $x, $y;
vertex $x, $y, $z;
vertex $x, $y, $z, $w;

Call one of glVertex${N} based on number of arguments.

plot_xy

plot_xy(
   $geom_mode,  # optional, i.e. GL_TRIANGLES or undef
   $x0, $y0,  # Shortcut for many glVertex2d calls
   $x1, $y1,
   ...
   $xN, $yN,
);

If $geom_mode is not undef or zero, this makes a call to glBegin and glEnd around the calls to glVertex2d.

plot_xyz

plot_xyz(
   $geom_mode,
   $x0, $y0, $z0,
   $x1, $y1, $z1,
   ...
   $xN, $yN, $zN,
);

Like above, but call glVertex3d.

plot_st_xy

plot_st_xy(
   $geom_mode,
   $s0, $t0,  $x0, $y0,
   $s1, $t1,  $x1, $y1,
   ...
   $sN, $tN,  $xN, $yN,
);

Like above, but calls both glTexCoord2d and glVertex2d.

plot_st_xyz

plot_st_xyz(
   $geom_mode,
   $s0, $t0,   $x0, $y0, $z0,
   $s1, $t1,   $x1, $y1, $z1,
   ...
   $sN, $tN,   $xN, $yN, $zN,
);

Like above, but call both glTexCoord2d and glVertex3d.

plot_norm_st_xyz

plot_norm_st_xyz(
   $geom_mode,
   $nx0, $ny0, $nz0,   $s0, $t0,   $x0, $y0, $z0,
   $nx0, $ny0, $nz0,   $s1, $t1,   $x1, $y1, $z1,
   ...
   $nx0, $ny0, $nz0,   $sN, $tN,   $xN, $yN, $zN,
);

Like above, but calls each of glNormal3d, glTexCoord2d, glVertex3d.

plot_rect

plot_rect(x0,y0, x1,y1)

plot_rect3

plot_rect3(x0,y0,z0, x1,y1,z1)

cylinder

cylinder($base_radius, $top_radius, $height, $radial_slices, $stacks);

Plot a cylinder along the Z axis with the specified dimensions. Shortcut for "cylinder" in OpenGL::Sandbox::V1::Quadric on the default_quadric. That quadric determines whether normals or texture coordinates get generated.

sphere

sphere($radius, $radial_slices, $stacks);

Plot a sphere around the origin with specified dimensions. Shortcut for "sphere" in OpenGL::Sandbox::V1::Quadric on the default_quadric.

disk

disk($inner_rad, $outer_rad, $slices, $stacks);

Plot a disk on XY plane around the Z axis with specified inner and outer radius. Shortcut for "disk" in OpenGL::Sandbox::V1::Quadric on the default_quadric.

partial_disk

partial_disk($inner_rad, $outer_rad, $slices, $loops, $start_angle, $sweep_degrees);

Plot a wedge of a disk around the Z axis. Shortcut for "disk" in OpenGL::Sandbox::V1::Quadric on the default_quadric.

DISPLAY LISTS

compile_list

my $list= compile_list { ... };

Constructs a displaylist by compiling the code in the block.

call_list

call_list($list, sub { ... });

If the variable $list contains a compiled displaylist, this calls that list. Else it creates a new list, assigns it to the variable $list, and compiles the contents of the coderef. This is a convenient way of compiling some code on the first pass and then calling it every iteration after that.

COLORS

setcolor

setcolor($r, $g, $b);
setcolor($r, $g, $b, $a);
setcolor(\@rgb);
setcolor(\@rgba);
setcolor('#RRGGBB');
setcolor('#RRGGBBAA');

Various ways to specify a color for glSetColor4f. If Alpha component is missing, it defaults to 1.0

color_parts

my ($r, $g, $b, $a)= color_parts('#RRGGBBAA');

Convenience method that always returns 4 components of a color, given the same variety of formats as setcolor.

color_mult

my ($r, $g, $b, $a)= color_mult( \@color1, \@color2 )

Multiply each component of color1 by that component of color2.

setup_sunlight

This function enables a generic overhead light source similar to sunlight. Light0 is set to a directional light source from above (+Y downward) with a slight yellow tinge and large ambient factor. This is mostly useful for quick one-liner scripts to inspect shapes.

MISC DRAWING

draw_axes_xy

draw_axes_xy( $range, $unit_size, $color );
draw_axes_xy( $range, $unit_size, $colorX, $colorY );

Renders the X and Y axis as lines from -$range to +$range, with a thinner lines making a grid of $unit_size squares on the X/Y plane.

$range defaults to 1. $unit_size defaults to 0.1. $color defaults to Red for the X axis and Green for the Y axis.

Automatically disables textures for this operation.

draw_axes_xyz

draw_axes_xyz( $range, $unit_size, $color );
draw_axes_xyz( $range, $unit_size, $colorX, $colorY, $colorZ );

Renders each of the X,Y,Z axes and the XY, XZ, YZ planes.

draw_boundbox

draw_boundbox( $x0, $y0, $x1, $y1, $color_edge, $color_to_origin );

Draw lines around a rectangle, and also a line from each corner to the origin, and the section of the X and Y axes that are within the bounds of the rectangle. This is useful for marking a 2D widget relative to the current coordinate system.

GETs

In general, "Get" is bad because if the data is coming from the graphics card it can be slow. However, they can be valuable for debugging. These are perl-ified versions of glGetxxx:

get_viewport_rect

my ($x, $y, $w, $h)= get_viewport_rect;

get_matrix

my @matrix4x4= get_matrix(GL_MODELVIEW_MATRIX);

AUTHOR

Michael Conrad <mike@nrdvana.net>

COPYRIGHT AND LICENSE

This software is copyright (c) 2019 by Michael Conrad.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.