SpriteCache

Description

sealed class Tinman.Engine.Rendering.Util.SpriteCache

Derived from

Disposable abstract
ICapacity

A sprite cache uses a set of 2D textures to cache rectangular sprite images for subsequent rendering in batches.

Sprites are (usually small) 2D images that are drawn onto the screen, either pixel-perfectly or with bilinear filtering when an affine transformation is used. Using a separate texture resource for each sprite may have negative impact on performance, especially for numerous sprites of small sizes. By packing sprite images into a sprite cache, near-optimal performance can be achieved when rendering many sprites. Using a SpriteCache involves the following steps:

  1. Choose the sprite cache parameters and create a new SpriteCache object.

  2. Use Allocate to add new sprites to the cache. Each sprite will get a unique sprite ID.

  3. Use Data to obtain a SpriteData object, which will be used to upload sprite image content.

  4. Call Prepare to prepare the sprite image content. This step includes transformations and texture encoding.

  5. Call Image to upload the prepared sprite image content to the GPU.

  6. Use Render to obtain render batch values for allocated sprites, in order to render their image content.

  7. Use Release to remove sprites from the cache.

The texels of each slice of each cache texture are arranged sequentially, using a 2D space-filling curve. An index range in the resulting texel sequence may then represent rectangular texel blocks of the following sizes: 1x1, 1x2, 1x3, 1x4, 2x3, 2x5, 3x4, 2x2, 2x4, 2x6, etc. Each sprite is represented by a single textured quadrilateral, where each quadrilateral has its own texel block.

Public / Constructors

Sprite​Cache


public constructor SpriteCache → (9)

capacity in : int32

[>0]
The sprite cache capacity (see remarks).

bufferFactory in : IBufferFactory

[not-null]
The buffer factory to use.

textureFactory in : ITextureFactory

[not-null]
The texture factory to use.

format opt : TextureFormat = null

The texture format. Will be validated with ITextureFactory.ValidateTextureFormat of IGraphicsContext.TextureFactory. If null, ITextureFactory.DefaultTextureFormat will be used.

srgb opt : bool = true

The sRGB behaviour flag.

size opt : int32 = 4096

[pow2]
The cache texture size. Will be clamped to [256..16384] and then validated with ITextureFactory.ValidateTextureSize of IGraphicsContext.TextureFactory.

count opt : int32 = 1

[>=1]
The number of cache texture slices to allocate. Will be clamped to ITextureFactory.MaximumCount.

mipmaps opt : int32 = 1

[>=1]
The number of mipmap levels to use.

clear opt : bool = false

Set to true to clear all texture data to zero initially. Please note that this is not required for correct sprite rendering. It can be helpful when reading back the cache textures, for example while debugging and testing.

Creates a new instance of SpriteCache.

The capacity in parameter depicts the maximum number of sprites that may be present in the cache, regardless of their size (this determines the vertex buffer size, see Vertices). The effective number of sprites that fit into the cache depends on the size opt and count opt parameters, as well on the actual sizes that are passed to Allocate.

RenderException

If a graphics subsystem error has occurred.

Public / Methods

Allocate


public method Allocate → (2)

width in : int32

[>0]
The sprite image width.

height in : int32

[>0]
The sprite image height.

returns → int32

The sprite ID or -1 if the sprite cache does not have enough free space.

Allocates a new sprite, without specifying its image content.

For aspect ratios (i.e. width in / height in) less than 0.25 or greater than 4.00, consider splitting the sprite image, in order to achieve better packing into the sprite texture atlas. This method does not update the GPU resources.

Data


[OwnerReturn] [Pure]
public method Data → ()

returns → SpriteData

The sprite data container.

Creates a reusable container for sprite data.

Image


public method Image → (6)

spriteId in : int32

The sprite ID.

content in : SpriteData

[not-null]
The sprite image content that has been prepared with Prepare.

opt : float32 = 0

X-coordinate of top-left corner of the top-left pixel of the sprite image pixel to use for the vertices of the textured quadrilateral.

opt : float32 = 0

Y-coordinate of top-left corner of the top-left pixel of the sprite image pixel to use for the vertices of the textured quadrilateral.

depth opt : float32 = 0

Depth coordinate in the range [0..1].

color opt : int64 = Colors.White

The vertex color to use.

returns → bool

true if the given sprite image content in has been applied,
false if spriteId in or content in is invalid.

Specifies the image content of the given sprite.

This method updates the GPU resources using GpuUpdateFlag.Discard.

Prepare


public method Prepare → (5)

spriteId in : int32

The sprite ID.

data in : SpriteData

[not-null]
The sprite data container to use.

image in : ColorBuffer

[not-null]
The buffer that contains the sprite image.

opt : int32 = 0

[0..image.Width]
X-coordinate of top-left pixel of the sprite image.

opt : int32 = 0

[0..image.Height]
Y-coordinate of top-left pixel of the sprite image.

returns → bool

true if the given sprite image in content has been prepared,
false if spriteId in is invalid.

Prepares the image content of the given sprite.

This method does not update the GPU resources.

Read​Pixels


public method ReadPixels → (4)

context in : IGraphicsContext

[not-null]
The graphics context to use.

mipmap opt : int32 = 0

The mipmap level to read from. Will be clamped to the valid range, see ITexture.Mipmaps of Texture.

background opt : int64 = Colors.DarkSlateGray

The background color to use.

sixteenBits opt : bool = false

Chooses the render target format:
true : RenderTargetFormat.RGBA_16
false : RenderTargetFormat.RGBA_8 + RenderTargetFormat.Srgb

returns → ColorBuffer

The pixel content of the sprite cache texture.

Reads the contents of the sprite cache texture from the GPU.

This method assumes that IBeginEnd.Begin has been called on context in and that no render effect is active.

RenderException

If a graphics subsystem error has occurred.

Release


public method Release → (1)

spriteId in : int32

The sprite ID.

returns → bool

true if the sprite has been released,
false if spriteId in is invalid.

Releases the given sprite.

The sprite identifier becomes invalid when a sprite is released and may be reused later, when another sprite is allocated. This method does not update the GPU resources.

Release​All


public method ReleaseAll → ()

Releases all sprites.

This method does not update the GPU resources.

Render


[Pure]
public method Render → (1)

spriteId in : int32

The sprite ID.

returns → int32

The vertex index X (see remarks) or -1 iff spriteId in is invalid.

Returns the vertex index of the textured quadrilateral to use for rendering the given sprite.

The textured quadrilateral may be used to submit GPU work until Release is called again (passing spriteId in). To render the sprite, the following triangles must be drawn:

triangle-0 = (X+0, X+1, X+2)
triangle-1 = (X+3, X+2, X+1)

The Z-coordinate of the vertex positions in Vertices depict the texture slice that contains the sprite image content.

Size


[Pure]
public method Size → (1)

spriteId in : int32

The sprite ID.

returns → Vec2I

The sprite size in pixels, as specified to Allocate. Will be Vec2I.Zero if spriteId in is invalid.

Returns the size of the given sprite.

Public / Attributes

Texture


[Constant]
public attribute Texture → (get)

value : ITexture2D

[not-null]
The cache texture.

Returns the texture that contains the cached sprite image content.

Vertices


[Constant]
public attribute Vertices → (get)

value : IVertexBuffer

[not-null]
The vertex buffer.

Returns the vertex buffer that holds the textured quadrilaterals to use for rendering the image content of the allocated sprites.

Each sprite has a textured quadrilateral with a contiguous range of four vertices in the buffer, which form a triangle strip primitive that represents the sprite image:

Sprite quadrilateral:         Position    TexCoord
0-----1   0 : top-left     = (x+0, y+0)   (u0, v0)
|     |   1 : top-right    = (x+w, y+0)   (u1, v0)
|     |   2 : bottom-left  = (x+0, y+h)   (u0, v1)
2-----3   3 : bottom-right = (x+w, y+h)   (u1, v1)

where w, h, x and y are the values that have been specified to Allocate. This is the vertex layout (see VertexElements):

@0  : Float x 3 (Position)
@12 : UInt8_Norm_Srgb x 4 (Color)
@16 : Float x 3 (TextureCoords)
@28 : - pad -
@32 : - end -

The VertexElementUsage.Position X- and Y-coordinates refer to sprite image pixels, where (x,y) is the top-left corner of the top-left pixel of the sprite image and (x+w,y+h) is the bottom-right corner of the bottom-right pixel. The Z-coordinate depicts the texture slice. The VertexElementUsage.TextureCoords coordinates are the normalized texture coordinates of the corresponding outer pixel corner.