atlas

package module
v0.0.0-...-6ae5079 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 5, 2024 License: MIT Imports: 4 Imported by: 0

README

Atlas

A small package providing an Atlas type as well as atlas.Image which can be used for more control over batching draw calls.

It works by alleviating some generic work done by ebitengine when treating DrawImage commands. Here, since the images are just regions of an atlas image, the commands can be converted to a slice of triangles that can be submitted in a single ebitengine command, relieving ebitengine from doing additional unnecessary work.

Originally made to address this: https://github.com/hajimehoshi/ebiten/issues/2976

Usage

go get github.com/Zyko0/Ebiary/atlas

  • Empty atlas
// Create an atlas
atlas := atlas.New(1024, 1024, nil)
// Allocate an image on the atlas at a random location
img := app.atlas.NewImage(48, 48)
// Access the *ebiten.Image as a sub-image and set its content
img.Image().Fill(color.White)
  • Atlas from spritesheet
// Create an atlas
atlas := atlas.New(1024, 1024, nil)
// Set the atlas image's content with the spritesheet image content
atlas.Image().DrawImage(spriteSheet, nil)
// Locate the sprite sub images on the atlas manually
img := app.atlas.SubImage(image.Rect(0,0,48,48))
  • DrawList
// It's best to re-use the DrawList as Flush() clears the triangles
// but keeps the capacities for next Add commands
dl := &atlas.DrawList{}
dc := &atlas.DrawCommand{}
for _, s := range sprites {
	dc.Image = s.Image
	dc.GeoM = s.GeoM
	dl.Add(dc)
}
// Flush all draws to the screen
dl.Flush(screen, nil)

An example can be found in examples/usage/main.go

Notes
  • The Text* related stuff is not implemented properly and will probably never work, since I realized we lack context from text/v2 to cache all the variations of a glyphs. This results in a drawn text but some characters will have an incorrect X offset.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Atlas

type Atlas struct {
	// contains filtered or unexported fields
}

Atlas is a minimal write-only container for sub-images, that can be used with a DrawList to batch draw commands as triangles.

func New

func New(width, height int, opts *NewAtlasOptions) *Atlas

func (*Atlas) Bounds

func (a *Atlas) Bounds() image.Rectangle

Bounds returns the bounds of the atlas.

func (*Atlas) Free

func (a *Atlas) Free(img *Image)

Free frees a region on the atlas, making it available for next allocations.

func (*Atlas) Image

func (a *Atlas) Image() *ebiten.Image

Image returns the full atlas image.

func (*Atlas) NewImage

func (a *Atlas) NewImage(width, height int) *Image

NewImage allocates a rectangle area on the atlas and returns the corresponding image. It returns a nil if there was no space to allocate the region specified by width, height.

func (*Atlas) SubImage

func (a *Atlas) SubImage(bounds image.Rectangle) *Image

SubImage returns an image matching a specific region of the atlas. It is useful if you want to create the atlas from a spritesheet and that you know the regions of you sub images.

type DrawCommand

type DrawCommand struct {
	Image *Image

	ColorScale ebiten.ColorScale
	GeoM       ebiten.GeoM
}

DrawCommand is the equivalent of the regular DrawImageOptions but only including options that will not break batching. Filter, Address, Blend and AntiAlias are determined at Flush()

type DrawList

type DrawList struct {
	// contains filtered or unexported fields
}

DrawList stores triangle versions of DrawImage calls when all images are sub-images of an atlas. Temporary vertices and indices can be re-used after calling Flush, so it is more efficient to keep a reference to a DrawList instead of creating a new one every frame.

func (*DrawList) Add

func (dl *DrawList) Add(commands ...*DrawCommand)

Add adds DrawImage commands to the DrawList, images from multiple atlases can be added but they will break the previous batch bound to a different atlas, requiring an additional draw call internally. So, it is better to have the maximum of consecutive DrawCommand images sharing the same atlas.

func (*DrawList) Flush

func (dl *DrawList) Flush(dst *ebiten.Image, opts *DrawOptions)

Flush executes all the draw commands as the smallest possible amount of draw calls, and then clears the list for next uses.

type DrawOptions

type DrawOptions struct {
	ColorScaleMode ebiten.ColorScaleMode
	Blend          ebiten.Blend
	Filter         ebiten.Filter
	Address        ebiten.Address
	AntiAlias      bool
}

DrawOptions are additional options that will be applied to all draw commands from the draw list when calling Flush().

type Image

type Image struct {
	// contains filtered or unexported fields
}

func (*Image) Atlas

func (i *Image) Atlas() *Atlas

func (*Image) Bounds

func (i *Image) Bounds() image.Rectangle

func (*Image) DrawImage

func (i *Image) DrawImage(src *ebiten.Image, opts *ebiten.DrawImageOptions)

func (*Image) Image

func (i *Image) Image() *ebiten.Image

func (*Image) SubImage

func (i *Image) SubImage(bounds image.Rectangle) *Image

type NewAtlasOptions

type NewAtlasOptions struct {
	// MinSize is the minimum size of images on the atlas.
	// It is an optional hint to improve the allocation time
	// of new images on the atlas.
	MinSize image.Point
	// Unmanaged is the same ebitengine's image option.
	Unmanaged bool
}

Directories

Path Synopsis
examples
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL