Skip to content

Textures

Textures are objects which present images with one, two, or three dimensions, and one or multiple layers. Additionally, they can have multiple mipmap levels, which contain lower resolution variants of the image.

Info

The various objects described on this page are declared in the packages Orka.Rendering.Textures and Orka.Rendering.Samplers.

Creating a texture

A texture can be created by calling function Create_Texture:

Texture_1 : Texture (Textures.LE.Texture_2D) := Create_Texture
  ((Kind     => Textures.LE.Texture_2D_Multisample,
    Format   => GL.Pixels.R11F_G11F_B10F,
    Size     => (1280, 720, 1),
    Levels   => 1,
    Samplers => 2));

After the texture has been created, it can be attached to a framebuffer. See Attaching textures for more information on how to attach a texture.

The depth (third parameter of Size) must be a multiple of 6 if the texture is a cube map array.

Creating a view of a layered texture

Some textures are considered layered, meaning they have an additional dimension representing the layers of the texture. For example, a Texture_2D_Array is a layered texture containing an array of 2D textures.

The function Create_View can be used to create a texture whose data points to a single layer of another texture:

Texture_2 : Texture := Texture_Cube.Create_View (Layer => 5);

In this example Texture_2 is a 2D texture representing the face -Z of the cube map texture Texture_Cube.

Textures with the following kinds are layered textures and can be used by the function Create_View:

  • Texture_1D_Array
  • Texture_2D_Array
  • Texture_2D_Multisample_Array
  • Texture_3D
  • Texture_Cube_Map
  • Texture_Cube_Map_Array

Getting the description

The description used to create a texture can be retrieved by calling the function Description.

Downloading data

TODO

Uploading data

TODO

Clearing pixels

TODO

Copying pixels to another texture

TODO

Binding textures

A texture can be binded to a binding point so that it can be read and/or written in a shader.

As a readonly texture

A texture can be binded as a readonly texture by calling the procedure Bind:

Texture_2.Bind (0);

It can then be read in a shader by declaring a uniform sampler using the same binding point for the layout parameter binding:

layout(binding = 0) uniform sampler2D inputTexture;

and then by reading the texture with the function texture():

const vec4 pixel = texture(inputTexture, textureCoordinate);

where textureCoordinate is a normalized coordinate unless the texture is a sampler2DRect. If it is then it must contain the pixel column and row instead.

As a writable image

A texture can be binded as a writable image by calling the procedure Bind_As_Image:

Texture_3.Bind_As_Image (1);

In a shader it must then be declared as a uniform image. For example, an image that is only written by a shader can be declared as follows:

layout(binding = 1) volatile restrict writeonly uniform image2D outputImage;

If a texture is binded as an image, the functions imageLoad() and imageStore() must be used instead. For example, a color can be written to a pixel as follows:

imageStore(outputImage, ivec2(column, row), color);

where the variable color has the type vec4.

Saving to a KTX file

To save a Texture object to a file, the procedure Write_Texture in the package Orka.Resources.Textures.KTX can be used to write the texture to a .ktx file in a writable location:

Orka.Resources.Textures.KTX.Write_Texture
  (Texture_1, Location_Screenshots, "screenshot.ktx");

The location given to the procedure must implement the interface Writable_Location. See Directories on how to create such an object.

View the saved .ktx file with the orka_ktx tool

The executable orka_ktx of the Alire crate orka_tools can display textures in .ktx files.

Samplers

A sampler specifies how a texture should be sampled. Create a sampler by declaring it:

use all type Orka.Rendering.Samplers.Minifying_Function;
use all type Orka.Rendering.Samplers.Magnifying_Function;
use all type Orka.Rendering.Samplers.Wrapping_Mode;

Sampler_1 : Sampler := Create_Sampler
  ((Wrapping          => (others => Clamp_To_Edge),
    Minifying_Filter  => Linear_Mipmap_Linear,
    Magnifying_Filter => Linear,
    others            => <>));

Using a sampler in a shader

To use a sampler in a shader, bind it to the index of a binding point:

Sampler_1.Bind (0);

The binding point must be specified in the shader as well:

layout(binding = 0) uniform sampler2D diffuseTexture;

Verify compatibility

To verify that the kind and format of the sampler and texture are compatible, call procedure Verify_Compatibility:

declare
   Uniform_1 : Uniform_Sampler := Program_1.Uniform_Sampler ("matrixBuffer");
begin
   Uniform_1.Verify_Compatibility (Buffer_Texture_1);
end;

Since Verify_Compatibility is a null procedure, make sure to compile with assertions enabled by building with `ADAFLAGS="-gnata".