NAME
OpenGL::Sandbox::ResMan - Resource manager for OpenGL prototyping
VERSION
version 0.120
SYNOPSIS
my $r= OpenGL::Sandbox::ResMan->default_instance;
$r->path( $path );
my $tex= $r->tex('foo');
my $font= $r->font('default');
DESCRIPTION
This object caches references to various OpenGL resources like textures and fonts. It is usually instantiated as a singleton from "default_instance" or from importing the $res
variable from OpenGL::Sandbox. It pulls resources from a directory of your choice. Where possible, files get memory-mapped directly into the library that uses them, which should keep the overhead of this library as low as possible.
Note that you need to install OpenGL::Sandbox::V1::FTGLFont in order to get font support, currently. Other font providers might be added later.
METHODS
new
Standard Moo constructor. All attributes may be initialized here.
default_instance
Return a global instance which uses the current directory as "path".
clear_cache
Call this method to remove all current references to any resource. If this was the last reference to those resources, it will also garbage collect any OpenGL resources that had been allocated. The next access to any font or texture will re-load the resource from disk. Any manually-created named resources (that didn't come from disk or config) must be re-created.
CONFIGURATION
Resouce Paths
The default file layout assumed by this module is a tree that looks like
./tex/ # textures
./tex/default # file or symlink for default texture. Required.
./font/ # fonts compatible with libfreetype
./font/default # file or symlink for default font. Required.
./shader/ # GLSL shaders with extension '.glsl', '.frag', or '.vert'
./data/ # raw data to be loaded into Buffer Objects
You can override these implied sub-paths with the following attributes:
- path
-
Root path for all other path fragments
- texture_path
- tex_path
-
(alias for texture_path)
- shader_path
- data_path
- font_path
A plain string is interpreted as relative to path
; an absolute path or path beginning with "."
is used as-is. An empty string means it is identical to path
.
path => '/opt/myapp/resources', # absolute path
tex_path => 'tex', # resolves as "/opt/myapp/resources/tex"
tex_path => '', # resolves as "/opt/myapp/resources"
tex_path => './tex', # resolves as getcwd()."/tex"
tex_path => '/tmp/foo', # absolute path
Per-Resource Config
For each type of resource managed by this object, there is a config_*
attribute which takes a hashref of configuration. Each named resource is configured by the matching entry in this hash at the time it is first used. Each config hash may also contain an element '*'
which applies default configuration to every resource of this type.
texture_config => {
'ResourceName' => ...,
'*' => ...
}
The values of the config are usually hashrefs of constructor arguments that get shallow-merged with arguments you pass to new_*
, but may also be plain scalars indicating that this resource is an alias for some other name.
'Resource1' => { ... }, # default constructor arguments for Resource1
'Resource2' => 'Resource1', # Resource2 is an alias for Resurce1
Several resource types also expect an entry for 'default'
, which gets returned on any request for a missing resource.
The namespace of each type of resource is independent. i.e. it is fine to have both a texture named "Foo" and a buffer named "Foo".
- texture_config
-
Configuration for "new_texture", constructing OpenGL::Sandbox::Texture.
Example texture_config:
{ '*' => { wrap_s => GL_CLAMP, wrap_t => GL_CLAMP }, # default settings default => { filename => 'foo.png' }, # texture named "default" tile1 => { wrap_s => GL_REPEAT, wrap_t => GL_REPEAT }, blocky => { mag_filter => GL_NEAREST }, alias1 => 'tile1', }
Existence of images in the texture directory implies default entries in this config. For example, if you have
tex/a.png tex/b.rgb tex/c.bgr
it has the implied effect of
{ a => { filename => 'a.png' }, b => { filename => 'b.rgb' }, c => { filename => 'c.bgr' }, }
in addition to whatever other settings you supplied for that name.
- tex_config
-
Alias for
texture_config
- tex_fmt_priority
-
If you have texture files with the same base name and different extensions (such as original image formats and derived ".png" or ".rgb") this resolves which image file you want to load automatically for
tex("basename")
. Default is to load ".bgr", else ".rgb", else ".png" - buffer_config
-
Configuration for "new_buffer", constructing OpenGL::Sandbox::Buffer.
{ '*' => { type => GL_VERTEX_ARRAY }, triangle_data => { data => pack('f*', 1,1, 2,1, 2,-1, ...) } }
Buffer filenames can also be implied by a file in the "data_path" directory, per the same rules described in "texture_config".
- vertex_array_config
-
Configuration for "new_vertex_array", constructing OpenGL::Sandbox::VertexArray.
{ my_triangles => { buffer => 'triangle_data', attributes => { pos => { size => 2, type => GL_FLOAT } } } }
Vertex Arrays must be configured; there is currently not a file format for them.
- vao_config
-
Alias for
vertex_array_config
- shader_config
-
Configuration for "new_shader", constructing OpenGL::Sandbox::Shader.
{ '*' => { type => GL_FRAGMENT_SHADER }, aurora => { filename => 'aurora.frag' }, vpassthrough => { filename => 'vtx-pass.vert', type => GL_VERTEX_SHADER }, }
Shaders are also implied by the presence of a file in the "shader_path" directory, per the same rules described in "texture_config".
- program_config
-
Configuration for "new_program", constructing OpenGL::Sandbox::Program.
{ '*' => { shaders => { vertex => 'vpassthrough', fragment => 'aurora' } }, 'demo' => { attr => { ... }, shaders => { vertex => 'special_vshader' } }, }
Programs are also implied by the presence shaders of the same name prefix. i.e. if you have shaders named
"a.frag"
and"a.vert"
, then it implies the existence of a program named"a"
composed of those shaders. - font_config
-
Configures OpenGL::Sandbox::V1::FTGLFont. (distributed separately)
{ '*' => { face_size => 48 }, # default settings get applied to all configs 3d => { face_size => 64, type => 'FTExtrudeFont' }, default => { face_size => 32, filename => 'myfont1' }, # font named 'default' myfont2 => 'myfont1', # alias }
Fonts are also implied by the presence of a file in the "font_path" directory, per the same rules described in "texture_config".
RESOURCE ACCESS
Textures
my $tex= $res->texture( $name );
my $tex= $res->tex( $name ); # handy alias
my $tex= $res->load_texture( $name, %options ); # load from file
my $tex= $res->new_texture( $name, %options ); # file not needed
Get a texture object. Textures can be configured, or implied by presence of image files in "tex_path", or both.
- texture
-
Return named texture, or load one with "load_texture".
The
texture
method has a feature that if you request a non-existent texture, it will return the texture named 'default' rather than throwing an exception. This operates on the assumption that you'd rather see a big visual cue about which texute is missing than to have your program crash from an exception. You still get the exception if you don't have a texture named 'default'. - tex
-
Alias for
texture
- load_texture
-
Load a texture, or throw an exception if there is no image file by that name.
It first checks for a file of no extension in "tex_path", which may be an image file, special "rgb" or "bgr" texture file, or symlink/hardlink to another file. Failing that, it checks for a file of that name with any file extension, and attempts to load them in whatever order they were returned.
- new_texture
-
Create a new texture object regardless of whether the filename exists. If the texture of this name was already created, it dies.
Buffer Objects
my $buffer= $res->buffer( $name );
my $buffer= $res->new_buffer( $name, %options );
Get a Buffer Object, either configured in buffer_config or loaded from data_path. Buffer objects require OpenGL version 2.0 or above.
- buffer
-
Return an existing buffer object, or create one from "buffer_config". If the
$name
is not configured, this dies. - new_buffer
-
This creates a new buffer object by combining
%options
with any (optional) configuration for this name in "buffer_config". This dies if$name
was already created.
Vertex Arrays
my $vertex_array= $res->vertex_array( $name );
my $vertex_array= $res->vao( $name ); # handy alias
my $vertex_array= $res->new_vao( $name, %options );
Return an existing or configured Vertex Array. The configurations may reference Buffer objects by name, and these will be translated to the actual perl object with calls to "buffer" before constructing the vertex array.
- vao
- vertex_array
-
Return an existing VAO, or create one from "vao_config". If the
$name
is not configured, this dies. - new_vao
- new_vertex_array
-
Create a new Vertex Array Object by combining
%options
with any (optional) configuration for this name in "vao_config". This dies if$name
was already created.
Shaders
my $shader= $res->shader( $name );
my $shader= $res->new_shader( $name, %options );
Returns a named shader. A $name
ending with .frag
or .vert
will imply the relevant GL shader type, unless you specifically passed it in %options
or configured it in "shader_config".
Shader and Program objects require OpenGL version 2.0 or above.
- shader
-
Return an existing or configured shader.
- new_shader
-
Create a new named shader from the options, including any configuration in "shader_config". The shader must not have previously been created.
Programs
my $prog= $res->program( $name );
my $prog= $res->new_program( $name, %options );
Return a named shader program. If the combined %options
and "program_config" do not specify shaders
, this will look through the shader/
directory for every shader that begins with this name. For example, if the directory contains:
shader/foo.vert
shader/foo.frag
Then this will augment the configuration with
shaders => { vert => 'foo.vert', frag => 'foo.frag' }
Shader and Program objects require OpenGL version 2.0 or above.
- program
-
Return a configured or existing or implied (by shader names) program object.
- new_program
-
Create and return a new named program, with the given constructor options, which get combined with any in "program_config".
Fonts
$font= $res->font( $name );
$font= $res->load_font( $name, %config );
Font support comes from a separate distribution, and these methods with attempt to load it on demand. Currently, the only font provider is OpenGL::Sandbox::V1::FTGLFont which is tied to OpenGL 1.x.
- font
-
Retrieve a named font, either confgured in font_config, previously created, or implied by the presence of a file in "font_path".
If the font cannot be loaded, this logs a warning and returns the 'default' font rather than throwing an exception or returning undef. If there is no font named 'default', it dies instead.
- new_font
-
Load a font by name. By default, a font file of the same name is loaded as a TextureFont and rendered at 24px. If multiple named fonts reference the same file (including hardlink checks), it will only be mapped into memory once.
Any configuration options specified here are combined with any defaults specified in "font_config".
If the font can't be loaded, this throws an exception. If the named font has already been loaded, this will return the existing font, even if the options have changed.
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.