Texture

class moderngl.Texture

A Texture is an OpenGL object that contains one or more images that all have the same image format. A texture can be used in two ways. It can be the source of a texture access from a Shader, or it can be used as a render target.

A Texture object cannot be instantiated directly, it requires a context. Use Context.texture() or Context.depth_texture() to create one.

Create

Context.texture(size, components, data=None, samples=0, alignment=1, dtype='f1', internal_format=None) → Texture

Create a Texture object.

Warning

Do not play with internal_format unless you know exactly you are doing. This is an override to support sRGB and compressed textures if needed.

Parameters:
  • size (tuple) – The width and height of the texture.
  • components (int) – The number of components 1, 2, 3 or 4.
  • data (bytes) – Content of the texture.
Keyword Arguments:
 
  • samples (int) – The number of samples. Value 0 means no multisample format.
  • alignment (int) – The byte alignment 1, 2, 4 or 8.
  • dtype (str) – Data type.
  • internal_format (int) – Override the internalformat of the texture (IF needed)
Returns:

Texture object

Context.depth_texture(size, data=None, samples=0, alignment=4) → Texture

Create a Texture object.

Parameters:
  • size (tuple) – The width and height of the texture.
  • data (bytes) – Content of the texture.
Keyword Arguments:
 
  • samples (int) – The number of samples. Value 0 means no multisample format.
  • alignment (int) – The byte alignment 1, 2, 4 or 8.
Returns:

Texture object

Methods

Texture.read(level=0, alignment=1) → bytes

Read the pixel data as bytes into system memory.

The texture can also be attached to a Framebuffer to gain access to Framebuffer.read() for additional features such ad reading a subsection or converting to another dtype.

Keyword Arguments:
 
  • level (int) – The mipmap level.
  • alignment (int) – The byte alignment of the pixels.
Returns:

bytes

Texture.read_into(buffer, level=0, alignment=1, write_offset=0)

Read the content of the texture into a bytearray or Buffer. The advantage of reading into a Buffer is that pixel data does not need to travel all the way to system memory:

# Reading pixel data into a bytearray
data = bytearray(4)
texture = ctx.texture((2, 2), 1)
texture.read_into(data)

# Reading pixel data into a buffer
data = ctx.buffer(reserve=4)
texture = ctx.texture((2, 2), 1)
texture.read_into(data)
Parameters:

buffer (Union[bytearray, Buffer]) – The buffer that will receive the pixels.

Keyword Arguments:
 
  • level (int) – The mipmap level.
  • alignment (int) – The byte alignment of the pixels.
  • write_offset (int) – The write offset.
Texture.write(data, viewport=None, level=0, alignment=1)

Update the content of the texture from byte data or a moderngl Buffer:

# Write data from a moderngl Buffer
data = ctx.buffer(reserve=4)
texture = ctx.texture((2, 2), 1)
texture.write(data)

# Write data from bytes
data = b'ÿÿÿÿ'
texture = ctx.texture((2, 2), 1)
texture.write(data)
Parameters:
  • data (Union[bytes, Buffer]) – The pixel data.
  • viewport (tuple) – The viewport.
Keyword Arguments:
 
  • level (int) – The mipmap level.
  • alignment (int) – The byte alignment of the pixels.
Texture.build_mipmaps(base=0, max_level=1000)

Generate mipmaps.

This also changes the texture filter to LINEAR_MIPMAP_LINEAR, LINEAR

Keyword Arguments:
 
  • base (int) – The base level
  • max_level (int) – The maximum levels to generate
Texture.bind_to_image(unit: int, read: bool = True, write: bool = True, level: int = 0, format: int = 0)

Bind a texture to an image unit (OpenGL 4.2 required)

This is used to bind textures to image units for shaders. The idea with image load/store is that the user can bind one of the images in a Texture to a number of image binding points (which are separate from texture image units). Shaders can read information from these images and write information to them, in ways that they cannot with textures.

It’s important to specify the right access type for the image. This can be set with the read and write arguments. Allowed combinations are:

  • Read-only: read=True and write=False
  • Write-only: read=False and write=True
  • Read-write: read=True and write=True

format specifies the format that is to be used when performing formatted stores into the image from shaders. format must be compatible with the texture’s internal format. By default the format of the texture is passed in. The format parameter is only needed when overriding this behavior.

More information:

Parameters:
  • unit (int) – Specifies the index of the image unit to which to bind the texture
  • texture (moderngl.Texture) – The texture to bind
Keyword Arguments:
 
  • read (bool) – Allows the shader to read the image (default: True)
  • write (bool) – Allows the shader to write to the image (default: True)
  • level (int) – Level of the texture to bind (default: 0).
  • format (int) – (optional) The OpenGL enum value representing the format (defaults to the texture’s format)
Texture.use(location=0)

Bind the texture to a texture unit.

The location is the texture unit we want to bind the texture. This should correspond with the value of the sampler2D uniform in the shader because samplers read from the texture unit we assign to them:

# Define what texture unit our two sampler2D uniforms should represent
program['texture_a'] = 0
program['texture_b'] = 1
# Bind textures to the texture units
first_texture.use(location=0)
second_texture.use(location=1)
Parameters:location (int) – The texture location/unit.
Texture.release()

Release the ModernGL object.

Attributes

Texture.repeat_x

The x repeat flag for the texture (Default True)

Example:

# Enable texture repeat (GL_REPEAT)
texture.repeat_x = True

# Disable texture repeat (GL_CLAMP_TO_EDGE)
texture.repeat_x = False
Type:bool
Texture.repeat_y

The y repeat flag for the texture (Default True)

Example:

# Enable texture repeat (GL_REPEAT)
texture.repeat_y = True

# Disable texture repeat (GL_CLAMP_TO_EDGE)
texture.repeat_y = False
Type:bool
Texture.filter

The minification and magnification filter for the texture. (Default (moderngl.LINEAR. moderngl.LINEAR))

Example:

texture.filter == (moderngl.NEAREST, moderngl.NEAREST)
texture.filter == (moderngl.LINEAR_MIPMAP_LINEAR, moderngl.LINEAR)
texture.filter == (moderngl.NEAREST_MIPMAP_LINEAR, moderngl.NEAREST)
texture.filter == (moderngl.LINEAR_MIPMAP_NEAREST, moderngl.NEAREST)
Type:tuple
Texture.swizzle

The swizzle mask of the texture (Default 'RGBA').

The swizzle mask change/reorder the vec4 value returned by the texture() function in a GLSL shaders. This is represented by a 4 character string were each character can be:

'R' GL_RED
'G' GL_GREEN
'B' GL_BLUE
'A' GL_ALPHA
'0' GL_ZERO
'1' GL_ONE

Example:

# Alpha channel will always return 1.0
texture.swizzle = 'RGB1'

# Only return the red component. The rest is masked to 0.0
texture.swizzle = 'R000'

# Reverse the components
texture.swizzle = 'ABGR'
Type:str
Texture.compare_func

The compare function of the depth texture (Default '<=')

By default depth textures have GL_TEXTURE_COMPARE_MODE set to GL_COMPARE_REF_TO_TEXTURE, meaning any texture lookup will return a depth comparison value.

If you need to read the actual depth value in shaders, setting compare_func to a blank string will set GL_TEXTURE_COMPARE_MODE to GL_NONE making you able to read the depth texture as a sampler2D:

uniform sampler2D depth;
out vec4 fragColor;
in vec2 uv;

void main() {
    float raw_depth_nonlinear = texture(depth, uv);
    fragColor = vec4(raw_depth_nonlinear);
}

Accepted compare functions:

texture.compare_func = ''    # Disale depth comparison completely
texture.compare_func = '<='  # GL_LEQUAL
texture.compare_func = '<'   # GL_LESS
texture.compare_func = '>='  # GL_GEQUAL
texture.compare_func = '>'   # GL_GREATER
texture.compare_func = '=='  # GL_EQUAL
texture.compare_func = '!='  # GL_NOTEQUAL
texture.compare_func = '0'   # GL_NEVER
texture.compare_func = '1'   # GL_ALWAYS
Type:tuple
Texture.anisotropy

Number of samples for anisotropic filtering (Default 1.0). The value will be clamped in range 1.0 and ctx.max_anisotropy.

Any value greater than 1.0 counts as a use of anisotropic filtering:

# Disable anisotropic filtering
texture.anisotropy = 1.0

# Enable anisotropic filtering suggesting 16 samples as a maximum
texture.anisotropy = 16.0
Type:float
Texture.width

The width of the texture.

Type:int
Texture.height

The height of the texture.

Type:int
Texture.size

The size of the texture.

Type:tuple
Texture.dtype

Data type.

Type:str
Texture.components

The number of components of the texture.

Type:int
Texture.samples

The number of samples set for the texture used in multisampling.

Type:int
Texture.depth

Is the texture a depth texture?

Type:bool
Texture.glo

The internal OpenGL object. This values is provided for debug purposes only.

Type:int
Texture.mglo

Internal representation for debug purposes only.

Texture.extra

Any - Attribute for storing user defined objects

Texture.ctx

The context this object belongs to