NAME
OpenGL::Sandbox - Rapid-prototyping utilities for OpenGL
VERSION
version 0.120
SYNOPSIS
use OpenGL::Sandbox qw( -V1 :all );
make_context;
setup_projection;
next_frame;
scale .01;
font('Arial.ttf')->render("Hello World");
next_frame;
(or, something more exciting and modern)
#! /usr/bin/env perl
use strict;
use warnings;
use Time::HiRes 'time';
use OpenGL::Sandbox qw( :all GL_FLOAT GL_TRIANGLES glDrawArrays );
use OpenGL::Sandbox -resources => {
path => './t/data',
program_config => {
demo => { shaders => { vert => 'xy_screen.vert' } },
},
vertex_array_config => {
unit_quad => {
buffer => { data => pack('f*', # two triangles covering entire screen
-1.0, -1.0, 1.0, -1.0, -1.0, 1.0,
1.0, -1.0, 1.0, 1.0, -1.0, 1.0
)},
attributes => { pos => { size => 2, type => GL_FLOAT } }
},
},
};
make_context;
new_program('demo', shaders => { frag => $ARGV[0] })->bind
->set_uniform("iResolution", 640, 480, 1.0);
vao('unit_quad')->bind;
my $started= time;
while (1) {
program('demo')->set_uniform("iGlobalTime", time - $started);
glDrawArrays( GL_TRIANGLES, 0, 6 );
next_frame;
}
DESCRIPTION
This module collection aims to provide quick and easy access to OpenGL, for use in one-liners or experiments or simple visualizations. There are many system dependencies involved, so to make the modules more accessible I divided it into multiple distributions:
- OpenGL::Sandbox
-
This package, containing the foundation for the rest, and anything in common among the different OpenGL APIs. It has methods to help set up the context, and load textures.
- OpenGL::Sandbox::V1
-
Everything related to OpenGL 1.x API
- OpenGL::Sandbox::V1::FTGLFont
-
A class providing fonts, but only for OpenGL 1.x
EXPORTS
Nothing is exported by default. You may request any of the following:
GL_$CONSTANT, gl$Function
This module can export OpenGL constants and functions, selecting them out of either OpenGL or OpenGL::Modern. When exported by name, constants will be exported as true perl constants. However, the full selection of GL constants and functions is *not* available directly from this module's namespace. i.e. OpenGL::Sandbox::GL_TRUE()
does not work.
-V1
Loads OpenGL::SandBox::V1 (which must be installed separately) and makes all its symbols available for importing. That module contains many "sugar" functions to make the GL 1.x API more friendly. These aren't much use in modern OpenGL, and actually missing in various OpenGL implementations (like ES) so they are supplied as a separate dist.
If OpenGL::SandBox::V1 is loaded, the :all
export will include everything from that module as well.
:all
This *only* exports the symbols defined by this module collection, *not* every OpenGL symbol, even though this module can export OpenGL symbols. However, this module exports lots of short (convenient) names which have a high chance of conflicting with your own symbols, so you should think twice before using :all
in any long-lived code that you want to maintain.
$res
Returns a default global instance of the resource manager with path
pointing to the current directory.
-resources => \%config
This isn't an actual export, but gives you a quick way to configure the default resource manager instance. Each key/value of %config
is applied as a method call.
Methods of $res
:
Shortcuts are exportable for the following methods of the default resource manager:
- tex
- new_texture
- buffer
- new_buffer
- vao
- new_vao
- shader
- new_shader
- program
- new_program
- font
(i.e. vao("Foo") is the same as OpenGL::Sandbox::ResMan->default_instance->vao("Foo")
)
Note that you need to install OpenGL::Sandbox::V1::FTGLFont in order to get font support, currently. Other font providers might be added later.
make_context
my $context= make_context( %opts );
Pick the lightest smallest module that can get a window set up for rendering. This tries: X11::GLX, OpenGL::GLFW, and SDLx::App in that order. You can override the detection with environment variable OPENGL_SANDBOX_CONTEXT_PROVIDER
. It assumes you don't have any desire to receive user input and just want to render some stuff. If you do actually have a preference, you should just invoke that package yourself.
Returns an object whose scope controls the lifecycle of the window, and that object always has a swap_buffers
method. If you call this method in void context, the object is stored internally and you can access it with "current_context".
This attempts to automatically pick up the window geometry, either from a "--geometry=" option or from the environment variable OPENGL_SANDBOX_GEOMETRY
. The Geometry value is in X11 notation of "${WIDTH}x${HEIGHT}+$X+$Y"
except that negative X
,Y
(from right edge) are not supported.
Not all options have been implemented for each source, but the list of possibilities is:
- x, y, width, height
-
Set the placement and dimensions of the created window.
- visible
-
Defaults to true, but if false, attempts to create an off-screen GL context.
- fullscreen
-
Attempts to create a full-screen context.
- noframe
-
Attempts to create a window without window border decorations.
- title
-
Window title
Note that if you're using Classic OpenGL (V1) you also need to set up the projection matrix to something more useful than the defaults before rendering anything. See "setup_projection" in OpenGL::Sandbox::V1.
current_context
Returns the most recently created result of "make_context", assuming it hasn't been garbage-collected. If you stored the return value of "make_context", then garbage collection happens according to that reference. If you called "make_context" in void context, then the GL context will live indefinitely.
If you have a simple program with only one context, this global simplifies life for you.
next_frame
This calls a sequence of:
current_context->swap_buffers;
warn_gl_errors;
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
If you have loaded "-V1" it also calls
glLoadIdentity();
Note that current_context->swap_buffers()
will only work after "make_context".
This is intended to help out with quick prototyping and one-liners:
perl -e 'use OpenGL::Sandbox qw( -V1 :all ); make_context; while(1) { next_frame; ...; }'
gl_error_name
my $name= gl_error_name( $code );
Returns the symbolic name of a GL error code.
get_gl_errors
my @names= get_gl_errors();
Returns the symbolic names of any pending OpenGL errors, as a list.
log_gl_errors
Write all GL errors to Log::Any as ->error
. Returns true if any errors were reported.
warn_gl_errors
Emit any GL errors using 'warn'. Returns true if any errors were reported.
Wrappers Around glGen*
OpenGL::Modern doesn't currently provide nice wrappers for glGen family of functions, so I wrote some of my own. They follow the pattern
my @ids= gen_textures($count);
delete_textures(@ids);
- gen_textures
- delete_textures
- gen_buffers
- delete_buffers
- gen_vertex_arrays
- delete_vertex_arrays
load_buffer_data
load_buffer_data( $buffer_target, $size, $data, $usage );
Wrapper around glBufferData. $size
may be undef, in which case it will use the length of $data
. $usage
may also be undef, in which case it will default to GL_STATIC_DRAW
.
load_buffer_sub_data
load_buffer_sub_data( $buffer_target, $offset, $size, $data, $data_offset );
Wrapper around glBufferSubData. $size
may be undef, in which case it uses the length of $data
. $data_offset
is an optional offset from the start of $data
to avoid the need for substring operations on the perl side.
get_glsl_type_name
my $typename= get_glsl_type_name(GL_FLOAT_MAT3);
# returns 'mat3'
Returns the GLSL type name that would be used to declare a type, per GL's type constants.
get_program_uniforms
my $uniform_set= get_program_uniforms($prog_id);
Returns a hashref of all uniforms defined for a program. The values are arrayrefs of
[ $name, $index, $type, $size ]
This cache can be passed to "set_uniform" to avoid further lookups.
set_uniform
set_uniform($program, $cache, $name, @values);
set_uniform($program, $cache, $name, \@values);
set_uniform($program, $cache, $name, \@val1, \@val2, ...);
set_uniform($program, $cache, $name, \OpenGL::Array);
Set a named uniform of a program. For OpenGL < 4.1 the program must be the active program. $cache
is the value returned by "get_program_uniforms". $value
can be a wide variety of things, but in general, must have a number of components that matches the size of the uniform being assigned; the values will be automatically packed into a buffer.
INSTALLING
Getting this module collection installed is abnormally difficult. This is a "selfish module" that I wrote primarily for me, but published in case it might be useful to someone else. My other more altruistic modules aim for high compatibility, but this one just unapologetically depends on lots of specific things.
For the core module, you need:
Perl 5.14 or higher
libGL, and headers
Image::PNG::Libpng, for the feature that automatically loads PNG.
File::Map, for efficiently memory-mapping resource files
XS support (C compiler)
For the "V1" module (OpenGL::Sandbox::V1) you will additionally need
libGLU and headers
For the "FTGLFont" module (OpenGL::Sandbox::V1::FTGLFont) you will additionally need
libftgl, and libfreetype2, and headers
You probably also want a module to open a GL context to see things in. This module is aware of OpenGL::GLFW, X11::GLX and SDL, but you can use anything you like since the GL context is global.
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.