A unified mechanism for hardware (GPU) texture creation and management is exposed in the API. The textures are cached for reuse regardless of whether they are internally or externally loaded, and all memory management is handled internally.
Textures can be created either from an image on disk or via a block of pixels in CPU memory. The types of textures and the number of formats supported are much greater than any of the legacy interfaces. The interfaces are also draw API agnostic as opposed to legacy interfaces that only support OpenGL.
A texture is represented by the class MTexture and the management is handled by the class MTextureManager.
There are three basic interfaces for acquiring a texture:
Uniqueness of a texture is provided by the name given to the texture. In the case of images on disk, the file path provides the unique name. Otherwise, the plug-in code is responsible for determining what is unique.
As it is not the purpose of MTexture and the manager to handle CPU side pixel maps, additional image codecs cannot be added directly via this interface. Instead, existing interfaces such as MImage can be used in conjunction with these interfaces. In fact, any interface which creates a block of pixels in CPU memory can use the interface which accepts CPU data to acquire GPU textures.
The relationships for texture acquisition are shown in the following diagram:
The most direct scenario is to load images from disk directly into GPU memory. In this scenario, CPU side memory is not persistently held. Other scenarios require a two-step process of allocating a block of pixels in CPU memory and then transferring the data to the GPU. Here, three options are shown: reading from a plug-in on a shader node, reading via the MImage class, and via some custom code.
The GPU handle to textures is accessible and is meant to be read only. As long as the data itself is not deleted or resized it is possible to perform updates directly on textures via this GPU handle. For DirectX11, this is actually a texture handle, for OpenGL this is a texture id (integer).
The general use case for textures is to bind to shaders. As an example, an MTexture instance can be bound to a texture parameter on an MShaderInstance. If a texture is bound to a shader instance, this information is used during render item categorization phase. For example, setting the texture to indicate that it has semi-transparent pixels (between 0 and 1) can be used to categorize a render item as being transparent. There are also other query and set methods for checking different alpha channel properties of a texture.