1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
|
Texture
=======
.. py:class:: Texture
Returned by :py:meth:`Context.texture` and :py:meth:`Context.depth_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 :py:meth:`Context.texture` or :py:meth:`Context.depth_texture`
to create one.
Methods
-------
.. py:method:: Texture.read(alignment: int = 1) -> bytes
Read the pixel data as bytes into system memory.
:param int alignment: The byte alignment of the pixels.
.. py:method:: Texture.read_into(buffer: Any, alignment: int = 1, write_offset: int = 0)
Read the content of the texture into a bytearray or :py:class:`~moderngl.Buffer`.
The advantage of reading into a :py:class:`~moderngl.Buffer` is that pixel data
does not need to travel all the way to system memory::
# Reading pixel data into a bytearray
data = bytearray(8)
texture = ctx.texture3d((2, 2, 2), 1)
texture.read_into(data)
# Reading pixel data into a buffer
data = ctx.buffer(reserve=8)
texture = ctx.texture3d((2, 2, 2), 1)
texture.read_into(data)
:param bytearray buffer: The buffer that will receive the pixels.
:param int alignment: The byte alignment of the pixels.
:param int write_offset: The write offset.
.. py:method:: Texture.write(data: Any, viewport: tuple, alignment: int = 1)
Update the content of the texture from byte data or a moderngl :py:class:`~moderngl.Buffer`.
Examples::
# Write data from a moderngl Buffer
data = ctx.buffer(reserve=8)
texture = ctx.texture3d((2, 2, 2), 1)
texture.write(data)
# Write data from bytes
data = b'\xff\xff\xff\xff\xff\xff\xff\xff'
texture = ctx.texture3d((2, 2), 1)
texture.write(data)
:param bytes data: The pixel data.
:param tuple viewport: The viewport.
:param int alignment: The byte alignment of the pixels.
.. py:method:: Texture.build_mipmaps(base: int = 0, max_level: int = 1000) -> None
Generate mipmaps.
This also changes the texture filter to ``LINEAR_MIPMAP_LINEAR, LINEAR``
(Will be removed in ``6.x``)
:param int base: The base level
:param int max_level: The maximum levels to generate
.. py:method:: Texture.bind_to_image(unit: int, read: bool = True, write: bool = True, level: int = 0, format: int = 0) -> None
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.**
Note that we bind the 3D textured layered making the entire texture
readable and writable. It is possible to bind a specific 2D section
in the future.
More information:
- https://www.khronos.org/opengl/wiki/Image_Load_Store
- https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBindImageTexture.xhtml
:param int unit: Specifies the index of the image unit to which to bind the texture
:param Texture texture: The texture to bind
:param bool read: Allows the shader to read the image (default: ``True``)
:param bool write: Allows the shader to write to the image (default: ``True``)
:param int level: Level of the texture to bind (default: ``0``).
:param int format: (optional) The OpenGL enum value representing the format (defaults to the texture's format)
.. py:method:: Texture.use(location: int = 0) -> None
Better to use :py:class:`Sampler` objects and avoid this call on the Texture object directly.
Bind the texture to a texture unit.
:param int location: The texture location/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 sampler3D 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)
.. py:method:: Texture.get_handle(resident: bool = True) -> int
Handle for Bindless Textures.
:param bool resident: Make the texture resident.
Once a handle is created its parameters cannot be changed.
Attempting to do so will have no effect. (filter, wrap etc).
There is no way to undo this immutability.
Handles cannot be used by shaders until they are resident.
This method can be called multiple times to move a texture
in and out of residency::
>> texture.get_handle(resident=False)
4294969856
>> texture.get_handle(resident=True)
4294969856
Ths same handle is returned if the handle already exists.
.. note:: Limitations from the OpenGL wiki
The amount of storage available for resident images/textures may be less
than the total storage for textures that is available. As such, you should
attempt to minimize the time a texture spends being resident. Do not attempt
to take steps like making textures resident/unresident every frame or something.
But if you are finished using a texture for some time, make it unresident.
.. py:method:: Texture.release
Attributes
----------
.. py:attribute:: Texture.width
:type: int
The width of the texture.
.. py:attribute:: Texture.height
:type: int
The height of the texture.
.. py:attribute:: Texture.size
:type: Tuple[int, int]
The size of the texture.
.. py:attribute:: Texture.components
:type: int
The number of components of the texture.
.. py:attribute:: Texture.samples
:type: int
The number of samples set for the texture used in multisampling.
.. py:attribute:: Texture.depth
:type: bool
Determines if the texture contains depth values.
.. py:attribute:: Texture.dtype
:type: str
Data type.
.. py:attribute:: Texture.swizzle
:type: str
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'
.. py:attribute:: Texture.repeat_x
See :py:class:`Sampler.repeat_x`
.. py:attribute:: Texture.repeat_y
See :py:class:`Sampler.repeat_y`
.. py:attribute:: Texture.filter
See :py:class:`Sampler.filter`
.. py:attribute:: Texture.compare_func
See :py:class:`Sampler.compare_func`
.. py:attribute:: Texture.anisotropy
See :py:class:`Sampler.anisotropy`
.. py:attribute:: Texture.ctx
:type: Context
The context this object belongs to
.. py:attribute:: Texture.glo
:type: int
The internal OpenGL object.
This values is provided for interoperability and debug purposes only.
.. py:attribute:: Texture.extra
:type: Any
User defined data.
|