OpenGL::Sandbox::Texture - Wrapper object for OpenGL texture


version 0.120



Human-readable name of this texture (not GL's integer "name")


Path from which image data will be loaded. If not set, the texture will not have any default image data loaded.


A method name or coderef of your choice for lazy-loading the image data. If not set, the loader is determined from the "filename" and if that is not set, nothing gets loaded on creation of the texture id tx_id.

Gets executed as $tex->$loader($filename).


Boolean; whether any image data has been loaded yet. This is not automatically aware of data you load yourself via calls to glTexImage or glTexSubImage.


Original width of the image independent of whether it got stored in a power-of-two texture.


Original height of the image independent of whether it got stored in a power-of-two texture.


Lazy-built OpenGL texture ID (integer). Triggers "load" if image is not yet loaded.


Check this to find out whether tx_id has been initialized.


Width of texture, in texels.


Height of texture, in texels.


The enum (integer) of the internal storage format of the texture. See tables at


Boolean of whether the texture contains an alpha channel.


Boolean, whether texture has (or should have) mipmaps generated for it. When loading any "simple" image format, this setting controls whether mipmaps will be automatically generated.


Value for GL_TEXTURE_MIN_FILTER. Setting does not take effect until "loaded", but after that a change to this attribute takes effect immediately, causing the texture to be bound in the process. Change with care.


Value for GL_TEXTURE_MAG_FILTER. See notes on "min_filter".


Value for GL_TEXTURE_WRAP_S. See notes on "min_filter".


Value for GL_TEXTURE_WRAP_T. See notes on "min_filter".



  $tex->bind( $target );

Make this image the current texture for OpenGL's $target, with the default of GL_TEXTURE_2D. If "tx_id" does not exist yet, it gets created. If this texture has a "loader" or "filename" defined and has not yet been "loaded", this automatically calls "load".

Returns $self for convenient chaining.


  $tex->load; # from 'loader' or 'filename'
  $tex->load( $filename );
  $tex->load({ format => ..., type => ..., data => ... });

Load image data into the texture. When no arguments are given, the normal mechanism is to call $self->loader->($self, $self->filename). "loader" or "filename" can be configured in advance. This method is called automatically during the first call to "bind" if loader or filename are set.

A single non-hashref argument is assumed to be a filename to pass to the loader.

A hashref argument is treated as arguments to glTexImage2D or glTexSubImage2D. It uses the same parameter names documented at with defaults coming from the attributes of the object.


Defaults to GL_TEXTURE_2D. (and other targets are not supported yet)


Defaults to 0. (the main image)


Defaults to "internal_format", and if that isn't set, defaults to something matching format.


Defaults to "width".


Defaults to "height".


Defaults to 0. Setting this to a non-zero value calls glTexSubImage2D, which requires that the image has already had its storage initialized.


Defaults to 0. Setting this to a non-zero value calls glTexSubImage2D, which requires that the image has already had its storage initialized.


Defaults to 0. Ignored on any modern OpenGL.


Must be specified, unless data is undef.


Must be specified, unless data is undef.


A scalar-ref containing the bytes to be loaded. May be undef to request that OpenGL allocate space for the texture without loading any data into it. However, if there is a Pixel Buffer Object currently bound to GL_PIXEL_UNPACK_BUFFER then this may not be a ref, and must be either undef (0) or a numeric value, since it gets interpreted as an offset.


A number of bytes between one row of image data and the next. Note that OpenGL doesn't support arbitrary pitch values - it must be a multiple of the pixel size rounded up to one of the standard alignments. If you pass in a pitch value that doesn't work, this function dies. The values of GL_UNPACK_ALIGNMENT and GL_UNPACK_ROW_LENGTH will be returned to their original value afterward. They will not be changed at all if you don't specify a pitch.

Returns $self for convenient chaining.


Load image data from a file which is nothing more than raw RGB or RGBA pixels in a power-of-two dimension suitable for directly loading into OpenGL. The dimensions and presence of alpha channel are derived mathematically from the file size. The data is directly mmap'd so no copying is performed before handing the pointer to OpenGL.


Same as rgb, except the source data has the red and blue bytes swapped.


Load image data from a PNG file. The PNG must be internally encoded as RGB or RGBA, and the presence or absence of alpha channel will be carried over to the texture.

TODO: load_ktx

OpenGL has its own image file format designed to directly handle all the various things you might want to load into a texture. Integrating libktx is on my list.


  $tex->render( %opts );

Render the texture as a plain rectangle with optional coordinate/size modifications. Implies a call to /bind which might also trigger "load".

Assumes you have already enabled GL_TEXTURE_2D, and that you are not using shaders. (future versions might include a shader-compatible implementation)

x, y

Use specified origin point. Uses (0,0) if these are not provided.

w, h

Use specified width and/or height. If undefined, defaults to pixel dimensions of the source image, unless only one is specified then it calculates the other using the aspect ratio. If source dimensions are not set, it uses the actual texture dimensions. These may or might not make sense for your current OpenGL coordinate space.


Multiply width and height by this number.


Center the image on the origin, instead of using the origin as the lower-left corner.

s, t

Starting offset texture coordinates for the lower-left corner.

s_rep, t_rep

The number of repititions of the texture to use across the face of the described rectangle. These won't give the desired result if you set the wrap mode of the texture to GL_CLAMP.


Like "render" but skips the call to "bind", for when you know that it is already the current texture.



  convert_png("foo.png", "foo.rgb");

Read a .png file and write an .rgb (or .bgr) file. The pixel format of the PNG must be RGB or RGBA. This does not require an OpenGL context.


Michael Conrad <>


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.