Documentation
¶
Overview ¶
Package gfx draws a game's 2D and 3D graphics. A Graphics is the drawing context for one window. Every Draw* call queues work for the frame the engine has open, and the engine submits it. 2D and 3D share a frame. The 3D scene renders first into a high dynamic range image, the post pass tone-maps it, and sprites, text and paths draw over the top in layer order, preserving submission order within each layer.
GPU resources belong to the Graphics that created them. Different windows use independent devices, so upload resources separately for each output. Drawing and state methods panic before using foreign GPU resources; constructors and transfers with error results return errors. Text drawing reports invalid font ownership through frame submission. See Graphics.
2D ¶
Textures come from images (NewTexture), pixel writes (Texture.Write) or render targets (NewRenderTexture with DrawTo). Sprites are drawn with DrawTexture, DrawSprite and DrawRegion, in the units set by SetView with the origin at the top-left and +Y down. Consecutive sprites with one texture, blend mode and shader become one draw. A Camera2D pans, zooms and rotates them, and a Tilemap draws a grid of regions with culling and animated tiles. Paths (Path, FillPath, StrokePath) draw vector shapes, gradients and dashes anti-aliased. Fonts shape text with HarfBuzz (DrawText, TextOptions, RichText, Hyphenator) and rasterise glyphs, colour emoji included, into an atlas. An Atlas names packed frames from a TexturePacker or Aseprite JSON export (ParseAtlas) or from Aseprite's own file (ParseAseprite), and plays its tags with the timings they were authored at. SetShader, SetBlend, SetColorMatrix and SetLights2D change how later sprites are drawn; DrawLit lights a sprite through a normal map, and AddOccluder2D casts shadows from the lights that want them. PushTransform and PushClip nest.
3D ¶
A Mesh is indexed geometry from NewMesh, the shape functions (CubeMesh, SphereMesh, PlaneMesh, HeightfieldMesh and more) or a glTF Model loaded with LoadModel. Mesh.Update replaces geometry that changes. A Material is metallic-roughness PBR with textures, clearcoat, sheen, subsurface, transmission, outlines and x-ray, or a game's own mesh Shader. A Model's clips play through an AnimPlayer with crossfades, layers and masks, events, root motion, morph targets and node overrides for IK. DrawMesh, DrawModel and DrawSkinned queue draws that are instanced when they share a mesh and material, culled against the camera's Frustum (a skinned mesh by the boxes of its joints under the pose, and a mesh whose shape leaves its geometry by Mesh.SetBounds or Shader.VertexBounds), sorted for blending and lit by SetLight's directional light with cascaded shadows, AddPoint and AddSpot, whose lights cast shadows of their own and which a cluster grid sorts over the view, the procedural Sky or an Environment map, and Fog. Parts of a scene get their own light from a ReflectionProbe baked with BakeProbe and added with AddProbe, a LightProbeGrid baked with BakeLightProbes and set with SetLightProbes, and the screen-space reflections PostSettings.Reflections turns on. DrawLOD picks a mesh by distance. DrawBillboard and DrawText3D put camera-facing quads and labels in the scene, and DrawDecal projects a texture onto geometry. SetPost sets exposure, bloom, ambient occlusion, vignette and anti-aliasing. Project, ScreenRay and Mesh.Intersect convert between the view and the world. DrawLine3D and the DrawWire* helpers draw debug lines over everything.
Conventions ¶
Option and material fields follow "zero means the default". A zero Roughness is 0.6, a zero IOR is 1.5, a zero Color where a tint is expected is white, and a zero Camera field of view is 60 degrees. A field whose zero must mean something of its own is named for that zero (NoMipmaps, NoDepthTest, Sky.Vacuum), so an empty struct is always a valid starting point. 2D sizes and positions use float32 view units; 3D uses game-defined world units. Texture dimensions use pixels. Rectangles are lin.Rect, and angles are radians. Colours are linear, non-premultiplied floats (RGB and Hex convert from sRGB bytes). Graphics owns the GPU resources it creates and releases them at shutdown, including after setup or drawing fails. Call Destroy to release a resource earlier. Create, update and destroy resources on the game goroutine in Init, Update, Draw or Shutdown. Destruction during Draw is deferred until queued work finishes; outside a frame it waits for the GPU. Stats reports what the last frame cost.
Index ¶
- Constants
- Variables
- func ComputeNormals(verts []Vertex, indices []uint32)
- func FrustumCorners(viewProj lin.Mat4) [8]lin.Vec3
- func NeutralLUT(n int) *image.RGBA
- func TileFlipped(frame int, flipX, flipY, diagonal bool) int
- func TileFrame(cell int) (frame int, flipX, flipY, diagonal bool)
- type Align
- type AnimBlend
- type AnimEvent
- type AnimLayer
- type AnimMask
- type AnimPlayer
- func (p *AnimPlayer) AddEvent(clip string, time float32, name string) bool
- func (p *AnimPlayer) Advance(dt float64)
- func (p *AnimPlayer) Blend() []AnimBlend
- func (p *AnimPlayer) Clip() string
- func (p *AnimPlayer) CrossFade(name string, loop bool, seconds float64) bool
- func (p *AnimPlayer) Events() []AnimEvent
- func (p *AnimPlayer) Finished() bool
- func (p *AnimPlayer) Layer(clip string, weight float32, mask AnimMask) *AnimLayer
- func (p *AnimPlayer) Layers() []*AnimLayer
- func (p *AnimPlayer) Model() *Model
- func (p *AnimPlayer) MorphWeights(node int) []float32
- func (p *AnimPlayer) NodeLocal(node int) (t lin.Vec3, r lin.Quat, s lin.Vec3)
- func (p *AnimPlayer) NodeMatrix(node int) lin.Mat4
- func (p *AnimPlayer) NodePosition(node int) lin.Vec3
- func (p *AnimPlayer) NodeRotation(node int) lin.Quat
- func (p *AnimPlayer) Play(name string, loop bool) bool
- func (p *AnimPlayer) PlayIndex(i int, loop bool)
- func (p *AnimPlayer) RemoveLayer(l *AnimLayer)
- func (p *AnimPlayer) RootMotion() (delta lin.Vec3, yaw float32)
- func (p *AnimPlayer) RotateNode(node int, q lin.Quat)
- func (p *AnimPlayer) SetBlend(clips []AnimBlend)
- func (p *AnimPlayer) SetMorphWeights(node int, weights []float32)
- func (p *AnimPlayer) SetNodeLocal(node int, t lin.Vec3, r lin.Quat, s lin.Vec3)
- func (p *AnimPlayer) SetNodeRotation(node int, r lin.Quat)
- func (p *AnimPlayer) SetRootMotion(node string) bool
- func (p *AnimPlayer) SetSpeed(s float64)
- func (p *AnimPlayer) SetTime(t float64)
- func (p *AnimPlayer) Speed() float64
- func (p *AnimPlayer) Stop()
- func (p *AnimPlayer) Time() float64
- type AnimState
- type Animation
- type Aseprite
- type AsepriteFrame
- type AsepriteLayer
- type AsepriteOptions
- type AsepriteSlice
- type AsepriteSliceKey
- type AsepriteTag
- type Atlas
- type AtlasData
- type AtlasFrame
- type Atmosphere
- type BatchItem
- type Billboard
- type Blend
- type BlendEquation
- type BlendFactor
- type BlendOptions
- type Camera
- type Camera2D
- func (c *Camera2D) Advance(dt float64)
- func (c *Camera2D) Clamp(bounds lin.Rect, viewW, viewH float32)
- func (c *Camera2D) Follow(target lin.Vec2, rate float32, dt float64)
- func (c Camera2D) Matrix(viewW, viewH float32) lin.Mat4
- func (c *Camera2D) Shake(amplitude, seconds float32)
- func (c *Camera2D) Shaking() bool
- func (c Camera2D) ViewToWorld(p lin.Vec2, viewW, viewH float32) lin.Vec2
- func (c Camera2D) VisibleRect(viewW, viewH float32) lin.Rect
- func (c Camera2D) WorldToView(p lin.Vec2, viewW, viewH float32) lin.Vec2
- type CaretAffinity
- type Color
- type ColorFormat
- type ColorMatrix
- func Brightness(b float32) ColorMatrix
- func ColorIdentity() ColorMatrix
- func Contrast(c float32) ColorMatrix
- func Grayscale() ColorMatrix
- func HueRotate(angle float32) ColorMatrix
- func Invert() ColorMatrix
- func Saturation(s float32) ColorMatrix
- func Sepia() ColorMatrix
- func Tint(c Color) ColorMatrix
- type CompiledPath
- type Direction
- type Environment
- type EnvironmentOptions
- type FillOptions
- type FillRule
- type Filter
- type Fog
- type Font
- type FontOptions
- type FrameStats
- type Frustum
- type GPUSpan
- type Geometry2D
- type Glyph
- type Gradient
- type GradientStop
- type Graphics
- func (g *Graphics) AddOccluder2D(points ...lin.Vec2)
- func (g *Graphics) AddOccluder3D(m *Mesh, model lin.Mat4)
- func (g *Graphics) AddOccluder3DAt(m *Mesh, t Transform)
- func (g *Graphics) AddPoint(p PointLight)
- func (g *Graphics) AddPointLight(pos lin.Vec3, c Color, rng float32)
- func (g *Graphics) AddProbe(p *ReflectionProbe)
- func (g *Graphics) AddSpot(s SpotLight)
- func (g *Graphics) AddSpotLight(pos, dir lin.Vec3, c Color, rng, innerAngle, outerAngle float32)
- func (g *Graphics) BakeImpostor(m *Model, opts ImpostorOptions) (*Impostor, error)
- func (g *Graphics) BakeLightProbes(grid *LightProbeGrid, scene func()) error
- func (g *Graphics) BakeProbe(p *ReflectionProbe, scene func()) error
- func (g *Graphics) Blend() Blend
- func (g *Graphics) Blended(b Blend, draw func())
- func (g *Graphics) Camera2D() (Camera2D, bool)
- func (g *Graphics) ClearStencil(value uint8)
- func (g *Graphics) Clip(r lin.Rect, draw func())
- func (g *Graphics) ColorMatrixed(m ColorMatrix, draw func())
- func (g *Graphics) CompileMeshShader(ctx context.Context, source string) (*Shader, error)
- func (g *Graphics) CompilePath(path *Path, opts PathOptions) (*CompiledPath, error)
- func (g *Graphics) CompileShader(ctx context.Context, source string) (*Shader, error)
- func (g *Graphics) ConfigurePost(edit func(*PostSettings))
- func (g *Graphics) CustomBlended(options BlendOptions, draw func())
- func (g *Graphics) DebugFont() *Font
- func (g *Graphics) DebugText(x, y float32, text string)
- func (g *Graphics) DebugText3D(p lin.Vec3, text string)
- func (g *Graphics) Debugf(x, y float32, format string, args ...any)
- func (g *Graphics) Draw(tex *Texture, s Sprite)
- func (g *Graphics) DrawAxes(m lin.Mat4, size float32)
- func (g *Graphics) DrawBatch(b *StaticBatch)
- func (g *Graphics) DrawBillboard(b Billboard)
- func (g *Graphics) DrawDecal(tex *Texture, box lin.Mat4, tint Color)
- func (g *Graphics) DrawFrame(sheet *Sheet, frame int, s Sprite)
- func (g *Graphics) DrawGeometry(tex *Texture, geometry *Geometry2D)
- func (g *Graphics) DrawGlyphs(f *Font, glyphs []Glyph, x, y, scale float32, c Color)
- func (g *Graphics) DrawImpostor(im *Impostor, pos lin.Vec3, yaw float32, tint Color)
- func (g *Graphics) DrawIndexed(tex *Texture, verts []Vertex2D, indices []uint32)
- func (g *Graphics) DrawLOD(l *LOD, mat Material, model lin.Mat4)
- func (g *Graphics) DrawLODAt(l *LOD, mat Material, t Transform)
- func (g *Graphics) DrawLine3D(a, b lin.Vec3, c Color)
- func (g *Graphics) DrawLit(tex, normal *Texture, s Sprite)
- func (g *Graphics) DrawMesh(m *Mesh, mat Material, model lin.Mat4)
- func (g *Graphics) DrawMeshAt(m *Mesh, mat Material, t Transform)
- func (g *Graphics) DrawMeshMoved(m *Mesh, mat Material, model, prev lin.Mat4)
- func (g *Graphics) DrawModel(m *Model, world lin.Mat4)
- func (g *Graphics) DrawModelAnimated(m *Model, t Transform, p *AnimPlayer)
- func (g *Graphics) DrawModelAnimatedMoved(m *Model, t, prev Transform, p *AnimPlayer, override MaterialOverride)
- func (g *Graphics) DrawModelAnimatedWith(m *Model, t Transform, p *AnimPlayer, override MaterialOverride)
- func (g *Graphics) DrawModelAt(m *Model, t Transform)
- func (g *Graphics) DrawModelImpostor(m *Model, im *Impostor, t Transform)
- func (g *Graphics) DrawModelMoved(m *Model, world, prev lin.Mat4, override MaterialOverride)
- func (g *Graphics) DrawModelWith(m *Model, world lin.Mat4, override MaterialOverride)
- func (g *Graphics) DrawNineSlice(ns NineSlice, r lin.Rect, tint Color)
- func (g *Graphics) DrawParticles(tex *Texture, quads []ParticleQuad)
- func (g *Graphics) DrawParticles3D(tex *Texture, quads []ParticleQuad, opts Particles3D)
- func (g *Graphics) DrawPath(path *CompiledPath)
- func (g *Graphics) DrawRegion(r Region, s Sprite)
- func (g *Graphics) DrawRichText(fonts RichFonts, text RichText, x, y float32, opts TextOptions, tint Color) []RichLink
- func (g *Graphics) DrawSkinned(m *Mesh, mat Material, model lin.Mat4, joints []lin.Mat4)
- func (g *Graphics) DrawSkinnedMoved(m *Mesh, mat Material, model, prev lin.Mat4, joints []lin.Mat4)
- func (g *Graphics) DrawTerrain(t *Terrain)
- func (g *Graphics) DrawText(f *Font, text string, x, y float32, c Color)
- func (g *Graphics) DrawText3D(f *Font, text string, pos lin.Vec3, scale float32, c Color, onTop bool, ...)
- func (g *Graphics) DrawTextBlock(f *Font, text string, x, y float32, opts TextOptions, c Color)
- func (g *Graphics) DrawTextLayout(l *TextLayout, x, y float32, tint Color)
- func (g *Graphics) DrawTextOnPath(f *Font, text string, p *Path, offset float32, opts TextOptions, c Color)
- func (g *Graphics) DrawTexture(tex *Texture, x, y float32)
- func (g *Graphics) DrawTilemap(t *Tilemap, x, y float32, tint Color)
- func (g *Graphics) DrawTo(rt *RenderTexture, clear Color, draw func())
- func (g *Graphics) DrawTriangles(tex *Texture, verts []Vertex2D)
- func (g *Graphics) DrawWireBox(min, max lin.Vec3, c Color)
- func (g *Graphics) DrawWireCube(m lin.Mat4, c Color)
- func (g *Graphics) DrawWireFrustum(cam Camera, aspect float32, c Color)
- func (g *Graphics) DrawWireSphere(center lin.Vec3, radius float32, c Color)
- func (g *Graphics) FillCircle(cx, cy, r float32, c Color)
- func (g *Graphics) FillGradient(r lin.Rect, gr *Gradient)
- func (g *Graphics) FillPath(p *Path, c Color, opts FillOptions)
- func (g *Graphics) FillPolygon(points []lin.Vec2, c Color)
- func (g *Graphics) FillRect(x, y, w, h float32, c Color)
- func (g *Graphics) Frustum() Frustum
- func (g *Graphics) Layer() int
- func (g *Graphics) Layered(layer int, draw func())
- func (g *Graphics) LoadModel(doc *gltf.Document) (*Model, error)
- func (g *Graphics) Masked(mask, draw func())
- func (g *Graphics) MaxSamples() int
- func (g *Graphics) NewBlankTexture(width, height int, opts TextureOptions) (*Texture, error)
- func (g *Graphics) NewCompressedTexture(data []byte, opts TextureOptions) (*Texture, error)
- func (g *Graphics) NewEnvironment(panorama image.Image, opts EnvironmentOptions) (*Environment, error)
- func (g *Graphics) NewEnvironmentHDR(panorama *HDRImage, opts EnvironmentOptions) (*Environment, error)
- func (g *Graphics) NewFont(ttf []byte, size float32, opts FontOptions) (*Font, error)
- func (g *Graphics) NewGeometry2D(vertices []Vertex2D, indices []uint32) (*Geometry2D, error)
- func (g *Graphics) NewGradient(stops ...GradientStop) (*Gradient, error)
- func (g *Graphics) NewLUT(img image.Image) (*Texture, error)
- func (g *Graphics) NewMesh(verts []Vertex, indices []uint32) (*Mesh, error)
- func (g *Graphics) NewMeshShader(spirv []byte) (*Shader, error)
- func (g *Graphics) NewRenderTexture(width, height int) (*RenderTexture, error)
- func (g *Graphics) NewRenderTextureOptions(width, height int, opts RenderTextureOptions) (*RenderTexture, error)
- func (g *Graphics) NewSDFFont(ttf []byte, size float32, opts FontOptions) (*Font, error)
- func (g *Graphics) NewShader(spirv []byte) (*Shader, error)
- func (g *Graphics) NewSkinnedMesh(verts []SkinVertex, indices []uint32) (*Mesh, error)
- func (g *Graphics) NewStaticBatch(items []BatchItem) *StaticBatch
- func (g *Graphics) NewTerrain(opts TerrainOptions) (*Terrain, error)
- func (g *Graphics) NewTexture(src image.Image, opts TextureOptions) (*Texture, error)
- func (g *Graphics) PopClip()
- func (g *Graphics) PopTransform()
- func (g *Graphics) Post() PostSettings
- func (g *Graphics) Project(p lin.Vec3) (x, y float32, ok bool)
- func (g *Graphics) PushClip(r lin.Rect)
- func (g *Graphics) PushTransform(m lin.Affine)
- func (g *Graphics) Resources() []Resource
- func (g *Graphics) ScreenRay(x, y float32) Ray
- func (g *Graphics) ScreenSpace()
- func (g *Graphics) SetBlend(b Blend)
- func (g *Graphics) SetCamera(c Camera)
- func (g *Graphics) SetCamera2D(cam Camera2D)
- func (g *Graphics) SetColorMatrix(m *ColorMatrix)
- func (g *Graphics) SetLayer(layer int)
- func (g *Graphics) SetLight(l Light)
- func (g *Graphics) SetLightProbes(grid *LightProbeGrid)
- func (g *Graphics) SetLights2D(ambient Color, lights ...Light2D)
- func (g *Graphics) SetOcclusionSize(width, height int)
- func (g *Graphics) SetPost(p PostSettings)
- func (g *Graphics) SetShader(s *Shader)
- func (g *Graphics) SetSortKey(key float32)
- func (g *Graphics) SetView(width, height float32)
- func (g *Graphics) SetViewport(r lin.Rect) error
- func (g *Graphics) Shaded(s *Shader, draw func())
- func (g *Graphics) SortKey() float32
- func (g *Graphics) Stats() FrameStats
- func (g *Graphics) Stenciled(options StencilOptions, draw func())
- func (g *Graphics) StrokeCircle(cx, cy, r, width float32, c Color)
- func (g *Graphics) StrokeLine(x0, y0, x1, y1, width float32, c Color)
- func (g *Graphics) StrokePath(p *Path, c Color, opts StrokeOptions)
- func (g *Graphics) StrokeRect(x, y, w, h, width float32, c Color)
- func (g *Graphics) Transform() lin.Affine
- func (g *Graphics) Transformed(m lin.Affine, draw func())
- func (g *Graphics) View() (float32, float32)
- func (g *Graphics) Viewport() lin.Rect
- func (g *Graphics) WithCamera2D(cam Camera2D, draw func())
- func (g *Graphics) WithView(view View2D, draw func())
- type HDRImage
- type Hit
- type Hyphenator
- type Image
- func (i *Image) At(x, y int) color.Color
- func (i *Image) Bounds() image.Rectangle
- func (i *Image) ColorModel() color.Model
- func (i *Image) CopyFrom(src image.Image, dst image.Point) error
- func (i *Image) FlipHorizontal()
- func (i *Image) FlipVertical()
- func (i *Image) Mask(c color.Color)
- func (i *Image) SavePNG(path string) error
- func (i *Image) Set(x, y int, c color.Color)
- func (i *Image) WritePNG(w io.Writer) error
- type Impostor
- type ImpostorOptions
- type LOD
- type LODLevel
- type Light
- type Light2D
- type LightProbeGrid
- type LineCap
- type LineJoin
- type Material
- type MaterialOverride
- type Mesh
- func (m *Mesh) Bounds() (min, max lin.Vec3)
- func (m *Mesh) Destroy()
- func (m *Mesh) Indices() []uint32
- func (m *Mesh) Intersect(model lin.Mat4, r Ray) (Hit, bool)
- func (m *Mesh) SetBounds(min, max lin.Vec3)
- func (m *Mesh) Update(verts []Vertex, indices []uint32) error
- func (m *Mesh) UpdateSkinned(verts []SkinVertex, indices []uint32) error
- func (m *Mesh) Vertices() []Vertex
- type Model
- func (m *Model) ClipDuration(name string) float32
- func (m *Model) Clips() []string
- func (m *Model) Destroy()
- func (m *Model) Intersect(world lin.Mat4, r Ray) (Hit, bool)
- func (m *Model) MaskNodes(names ...string) AnimMask
- func (m *Model) MaskSubtree(names ...string) AnimMask
- func (m *Model) MorphTargets(node int) []string
- func (m *Model) MorphWeights(node int) []float32
- func (m *Model) NewAnimPlayer() *AnimPlayer
- func (m *Model) NodeCount() int
- func (m *Model) NodeIndex(name string) int
- func (m *Model) NodeMatrix(node int) lin.Mat4
- func (m *Model) NodeName(node int) string
- func (m *Model) NodeParent(node int) int
- func (m *Model) NodePosition(node int) lin.Vec3
- func (m *Model) SetMorphWeights(node int, weights []float32) error
- type ModelPart
- type NineSlice
- type ParticleQuad
- type Particles3D
- type Path
- func (p *Path) Arc(cx, cy, r, start, sweep float32) *Path
- func (p *Path) ArcTo(x1, y1, x2, y2, r float32) *Path
- func (p *Path) Bounds() lin.Rect
- func (p *Path) Circle(cx, cy, r float32) *Path
- func (p *Path) Close() *Path
- func (p *Path) CubicTo(c1x, c1y, c2x, c2y, x, y float32) *Path
- func (p *Path) Ellipse(cx, cy, rx, ry float32) *Path
- func (p *Path) Empty() bool
- func (p *Path) LineTo(x, y float32) *Path
- func (p *Path) MoveTo(x, y float32) *Path
- func (p *Path) Polygon(points ...lin.Vec2) *Path
- func (p *Path) QuadTo(cx, cy, x, y float32) *Path
- func (p *Path) Rect(x, y, w, h float32) *Path
- func (p *Path) Reset()
- func (p *Path) RoundRect(x, y, w, h, r float32) *Path
- type PathOptions
- type PointLight
- type PostSettings
- type Ray
- type ReflectionProbe
- type Region
- type RegionAnimation
- type RenderTexture
- type RenderTextureOptions
- type Resource
- type ResourceKind
- type RichFonts
- type RichLink
- type RichRun
- type RichText
- type Shader
- type Sheet
- type SkinVertex
- type Sky
- type SpotLight
- type Sprite
- type StaticBatch
- type StencilOp
- type StencilOptions
- type StencilTest
- type StrokeOptions
- type Terrain
- func (t *Terrain) Bounds() (min, max lin.Vec3)
- func (t *Terrain) ChunkCentre(i int) lin.Vec3
- func (t *Terrain) ChunkLevel(i int) int
- func (t *Terrain) Chunks() int
- func (t *Terrain) Destroy()
- func (t *Terrain) Height(x, z float32) float32
- func (t *Terrain) Heights() []float32
- func (t *Terrain) Levels() int
- func (t *Terrain) Normal(x, z float32) lin.Vec3
- func (t *Terrain) Raycast(r Ray, reach float32) (lin.Vec3, bool)
- func (t *Terrain) SetSplat(img image.Image) error
- func (t *Terrain) Shader() *Shader
- func (t *Terrain) Size() (cols, rows int, cell float32)
- func (t *Terrain) Update(minX, minZ, maxX, maxZ int) error
- type TerrainOptions
- type TextCaret
- type TextLayout
- func (l *TextLayout) Bounds() lin.Rect
- func (l *TextLayout) Caret(position TextCaret) lin.Rect
- func (l *TextLayout) HitTest(point lin.Vec2) TextCaret
- func (l *TextLayout) InkBounds() lin.Rect
- func (l *TextLayout) Lines() []TextLine
- func (l *TextLayout) Links() []RichLink
- func (l *TextLayout) Text() string
- type TextLine
- type TextOptions
- type Texture
- func (t *Texture) CopyFrom(src *Texture, srcRect image.Rectangle, dst image.Point) error
- func (t *Texture) Destroy()
- func (t *Texture) Read() (*image.RGBA, error)
- func (t *Texture) Replace(src image.Image) error
- func (t *Texture) ReplaceCompressed(data []byte) error
- func (t *Texture) SavePNG(path string) error
- func (t *Texture) Write(x, y int, src image.Image) error
- func (t *Texture) WritePNG(w io.Writer) error
- type TextureOptions
- type TileAnimation
- type Tilemap
- type Transform
- type Transform2
- type Vertex
- func AppendMesh(verts []Vertex, indices []uint32, moreVerts []Vertex, moreIndices []uint32) ([]Vertex, []uint32)
- func CapsuleMesh(rings, segments int, halfHeight float32) ([]Vertex, []uint32)
- func ConeMesh(segments int) ([]Vertex, []uint32)
- func CubeMesh() ([]Vertex, []uint32)
- func CylinderMesh(segments int) ([]Vertex, []uint32)
- func FlatShaded(verts []Vertex, indices []uint32) ([]Vertex, []uint32)
- func HeightfieldMesh(heights []float32, cols, rows int, cell float32) ([]Vertex, []uint32)
- func PlaneMesh(segments int) ([]Vertex, []uint32)
- func QuadMesh() ([]Vertex, []uint32)
- func SphereMesh(rings, segments int) ([]Vertex, []uint32)
- func TorusMesh(tube float32, rings, segments int) ([]Vertex, []uint32)
- func TransformVertices(verts []Vertex, m lin.Mat4) []Vertex
- type Vertex2D
- type View2D
Examples ¶
Constants ¶
const ( TileFlipX = 1 << 28 TileFlipY = 1 << 29 TileFlipDiag = 1 << 30 // swap the axes: with FlipX a quarter turn clockwise )
Tile flip bits, stored above the frame index in a Tilemap cell so a tile can be mirrored or turned without another sheet frame. They match the Tiled map editor's convention.
const MaxGPUMorphTargets = 8
MaxGPUMorphTargets is how many of a mesh's morph targets can carry a weight at once before the blend moves back to the processor. Eight is what the instance record holds, and more than a face usually needs at one time: a mesh with twenty targets is fine so long as no more than eight of them are open.
const MaxImpostorViews = 64
MaxImpostorViews is the most views one impostor may hold.
const MaxLights = maxPointLights
MaxLights is how many point and spot lights a frame keeps. The lights are sorted into a grid of clusters over the view, and a fragment is lit by its own cluster's lights alone, so a scene may add hundreds without every one costing every pixel. A cluster keeps 64 lights, and a light past that in a crowded part of the view does not light it.
const MaxOccluderTriangles = 4096
MaxOccluderTriangles is the most triangles an occluder mesh may have before AddOccluder3D ignores it. Occluders are rasterised on the CPU, so a blocking volume should be a box or a few quads, not the detailed geometry it stands for.
const MaxPointShadows = maxPointShadows
MaxPointShadows is how many point lights cast shadows in one frame. Each one costs six depth passes, one for each face of its cube.
const MaxProbes = maxProbes
MaxProbes is how many reflection probes a frame keeps.
const MaxSpotShadows = maxSpotShadows
MaxSpotShadows is how many spot lights cast shadows in one frame.
Variables ¶
var ( White = Color{1, 1, 1, 1} Black = Color{0, 0, 0, 1} Transparent = Color{} )
Functions ¶
func ComputeNormals ¶
ComputeNormals sets every vertex's normal to the average of its triangles' face normals, for geometry built without them: terrain, marching cubes, meshes edited in code.
func FrustumCorners ¶
Corners returns the frustum's eight corners for a view-projection matrix: the near plane's four then the far plane's, each as bottom-left, bottom-right, top-right, top-left.
func NeutralLUT ¶
NeutralLUT returns an identity colour lookup table of n slices (16 or 32 are usual): grade a screenshot with it pasted in the corner, crop it back out, and every frame gets the same grade through PostSettings.LUT.
func TileFlipped ¶
TileFlipped combines a frame index with flip bits for Tilemap.Set.
Types ¶
type AnimBlend ¶
type AnimBlend struct {
Clip string
Weight float32
Time float64 // sample time in seconds, supplied by the blend controller
}
AnimBlend is one clip's share of a blended pose, for SetBlend: the clip, its weight against the others and the time to sample it at.
type AnimEvent ¶
type AnimEvent struct {
Clip string
Time float32 // event's position in the clip, in seconds
Name string
}
AnimEvent is a moment in a clip that playback crossed: a footstep, a hit frame, a spawn point.
type AnimLayer ¶
type AnimLayer struct {
Weight float32 // how much of the layer shows, 0..1
// Additive adds the clip's difference from the rest pose to the pose
// underneath (a breathing motion over anything, a recoil); off, the
// layer replaces the pose of the nodes it covers (a wave over a walk).
Additive bool
// Loop starts the clip over at its end; off, the layer holds the last
// frame. Layer sets it.
Loop bool
// Mask is the set of nodes the layer affects; nil means every node.
Mask AnimMask
// contains filtered or unexported fields
}
AnimLayer plays a clip over part of the skeleton on top of the main clip. Get one from Layer.
type AnimMask ¶
type AnimMask []bool
AnimMask is the set of nodes an animation layer affects, one flag per node; nil means every node. Build one with MaskNodes or MaskSubtree.
type AnimPlayer ¶
type AnimPlayer struct {
// OnEvent, when set, is called from Advance for every event playback
// crosses; Events lists the same after Advance returns.
OnEvent func(AnimEvent)
// PostPose, when set, runs at the end of every Advance with the pose
// built, before joint matrices are made: the place for inverse
// kinematics, look-at and any other node override.
PostPose func(p *AnimPlayer)
// contains filtered or unexported fields
}
AnimPlayer plays a model's animation clips over its node hierarchy. One player per animated instance; it holds the current pose. Play and CrossFade choose the main clip, SetBlend mixes several clips in its place, Layer plays more clips over parts of the skeleton, AddEvent marks moments to be told about, SetRootMotion hands the root's movement to the game, and PostPose with the node setters adjusts the pose before it is drawn. Create one with Model.NewAnimPlayer; the zero value has no model or pose storage. Times and Advance deltas are seconds.
func (*AnimPlayer) AddEvent ¶
func (p *AnimPlayer) AddEvent(clip string, time float32, name string) bool
AddEvent marks a time in a clip; Advance reports crossing it through OnEvent and Events, on every loop and while the clip blends in, out or on a layer. Unknown clips return false.
func (*AnimPlayer) Advance ¶
func (p *AnimPlayer) Advance(dt float64)
Advance moves playback forward by dt seconds and rebuilds the pose: the main clip or blend, its crossfade, the layers, root motion, events and PostPose, in that order.
func (*AnimPlayer) Blend ¶
func (p *AnimPlayer) Blend() []AnimBlend
Blend lists the clips SetBlend is playing with their weights as given and their times, in a new slice; nil when no blend plays.
func (*AnimPlayer) Clip ¶
func (p *AnimPlayer) Clip() string
Clip is the name of the main clip, or "" when none plays.
func (*AnimPlayer) CrossFade ¶
func (p *AnimPlayer) CrossFade(name string, loop bool, seconds float64) bool
CrossFade starts a clip while the current one blends out over the given seconds, so a run does not snap out of a walk. With nothing playing, a blend playing, or a zero fade, it is Play.
func (*AnimPlayer) Events ¶
func (p *AnimPlayer) Events() []AnimEvent
Events lists the events the last Advance crossed, in clip order; the slice is reused by the next Advance.
func (*AnimPlayer) Finished ¶
func (p *AnimPlayer) Finished() bool
Finished reports whether a non-looping main clip has reached its end.
func (*AnimPlayer) Layer ¶
func (p *AnimPlayer) Layer(clip string, weight float32, mask AnimMask) *AnimLayer
Layer plays a clip on top of the main one over the nodes in the mask (nil for all of them), looping, at the given weight: a wave over the arms while the legs walk. Change the returned layer's fields at any time; RemoveLayer takes it off. Unknown clips return nil.
func (*AnimPlayer) Layers ¶
func (p *AnimPlayer) Layers() []*AnimLayer
Layers lists the playing layers in the order they blend, first to last.
func (*AnimPlayer) Model ¶
func (p *AnimPlayer) Model() *Model
Model is the model the player animates.
func (*AnimPlayer) MorphWeights ¶
func (p *AnimPlayer) MorphWeights(node int) []float32
MorphWeights returns a node's morph target weights in the current pose, one per target; nil when the node has none.
func (*AnimPlayer) NodeLocal ¶
NodeLocal returns a node's current local translation, rotation and scale, relative to its parent.
func (*AnimPlayer) NodeMatrix ¶
func (p *AnimPlayer) NodeMatrix(node int) lin.Mat4
NodeMatrix returns a node's current world matrix (in model space).
func (*AnimPlayer) NodePosition ¶
func (p *AnimPlayer) NodePosition(node int) lin.Vec3
NodePosition returns a node's position in model space.
func (*AnimPlayer) NodeRotation ¶
func (p *AnimPlayer) NodeRotation(node int) lin.Quat
NodeRotation returns a node's rotation in model space.
func (*AnimPlayer) Play ¶
func (p *AnimPlayer) Play(name string, loop bool) bool
Play starts a clip by name from its beginning, dropping any crossfade or blend; unknown names return false.
func (*AnimPlayer) PlayIndex ¶
func (p *AnimPlayer) PlayIndex(i int, loop bool)
PlayIndex starts a clip by index.
func (*AnimPlayer) RemoveLayer ¶
func (p *AnimPlayer) RemoveLayer(l *AnimLayer)
RemoveLayer stops a layer.
func (*AnimPlayer) RootMotion ¶
func (p *AnimPlayer) RootMotion() (delta lin.Vec3, yaw float32)
RootMotion returns how far the root node moved during the last Advance, in model space, and how much it turned about +Y in radians. Apply them to the entity's transform: position += rotation.Rotate(delta), then turn by yaw. Both are zero unless SetRootMotion is on.
func (*AnimPlayer) RotateNode ¶
func (p *AnimPlayer) RotateNode(node int, q lin.Quat)
RotateNode turns a node by a rotation given in model space, about its own position, so its children follow: what an inverse kinematics or look-at solver produces.
func (*AnimPlayer) SetBlend ¶
func (p *AnimPlayer) SetBlend(clips []AnimBlend)
SetBlend plays a weighted mix of clips in place of the main clip, each sampled at its own time: what a blend space produces. The weights are scaled to sum to 1; entries with no weight, or an unknown clip, are skipped, and an empty list stops the blend. The caller owns the times and sets them again before every Advance; a time that moved backwards counts as having looped. Events fire and root motion accrues for every clip in the blend by its weight. Play, CrossFade and Stop drop the blend; layers play over it as they do over a clip.
func (*AnimPlayer) SetMorphWeights ¶
func (p *AnimPlayer) SetMorphWeights(node int, weights []float32)
SetMorphWeights sets the weights a node's morph targets start from on every Advance, until a playing clip's weights channel replaces them: a smile held while the body animates. Weights beyond the target count are ignored.
func (*AnimPlayer) SetNodeLocal ¶
SetNodeLocal replaces a node's local transform in the current pose: an aimed turret, a procedural tail. The next Advance samples the clips again, so call it after Advance or from PostPose each frame.
func (*AnimPlayer) SetNodeRotation ¶
func (p *AnimPlayer) SetNodeRotation(node int, r lin.Quat)
SetNodeRotation replaces a node's local rotation in the current pose.
func (*AnimPlayer) SetRootMotion ¶
func (p *AnimPlayer) SetRootMotion(node string) bool
SetRootMotion names the node whose movement the game applies to the entity instead of the animation sliding it in place: usually the skeleton's root or hips. From then on the node's translation and its yaw (rotation about +Y) are held at the rest pose and their change per Advance is reported by RootMotion. "" turns root motion off; an unknown name returns false.
func (*AnimPlayer) SetSpeed ¶
func (p *AnimPlayer) SetSpeed(s float64)
SetSpeed scales playback; 1 is normal, negative runs clips backwards.
func (*AnimPlayer) SetTime ¶
func (p *AnimPlayer) SetTime(t float64)
SetTime moves the main clip to a time in seconds, as scrubbing does; events between the old and new times do not fire.
func (*AnimPlayer) Speed ¶
func (p *AnimPlayer) Speed() float64
Speed is the playback scale set by SetSpeed; 1 by default.
func (*AnimPlayer) Stop ¶
func (p *AnimPlayer) Stop()
Stop drops the main clip or blend, leaving the pose where it is; layers keep playing.
func (*AnimPlayer) Time ¶
func (p *AnimPlayer) Time() float64
Time is the main clip's current time in seconds.
type AnimState ¶
AnimState plays an Animation over time.
type Aseprite ¶
type Aseprite struct {
Width, Height int // one frame, in pixels
Frames []AsepriteFrame
Layers []AsepriteLayer
Tags []AsepriteTag
Slices []AsepriteSlice
Palette []color.RGBA // empty for a file with no palette chunk
Image *image.RGBA // every packed frame, premultiplied
Data *AtlasData // the frames and tag animations of Image
Atlas *Atlas // the bound atlas, once Upload has run
}
Aseprite is a parsed .aseprite or .ase file: every frame composited from its visible layers into one packed image, an AtlasData that names the packed frames and carries the file's tags as animations, and the pieces the editor keeps beside the pixels. ParseAseprite reads it and Upload puts it on the GPU.
Frames are named by their number, "0" upwards, in the order they play. With AsepriteOptions.Layers a layer's own frames are named "<layer>/<number>", where a layer inside a group carries the group's name first, so a hat drawn on its own is atlas.Region("gear/hat/3").
func ParseAseprite ¶
func ParseAseprite(data []byte, opts AsepriteOptions) (*Aseprite, error)
ParseAseprite reads an Aseprite file: its header, frames, layers, cels, palette, tags and slices. It composites each frame's visible layers into one image, packs the frames into a grid and describes them in an AtlasData, so Atlas.Animation plays a tag with the timings the editor gave it. RGBA, greyscale and indexed files all read; layers blend as normal with their opacity, whatever mode the editor set.
type AsepriteFrame ¶
type AsepriteFrame struct {
Duration float32 // seconds, as the editor timed it
}
AsepriteFrame is one frame of the file.
type AsepriteLayer ¶
type AsepriteLayer struct {
// Name is the layer's path: its own name, with the names of the
// groups it sits in before it, separated by slashes.
Name string
// Visible is the layer's own visibility in the editor. A layer inside
// a hidden group is left out of the composite even when this is set.
Visible bool
Opacity uint8 // 255 unless the file records layer opacity
Group bool // a group, which holds no pixels of its own
Level int // how deep in the group tree, zero at the top
// Blend names the layer's blend mode ("normal", "multiply", and the
// rest of the editor's list). Only normal is composited; a layer in
// any other mode is drawn as normal.
Blend string
UserData string // the note the editor keeps on the layer
UserColor color.RGBA // its colour, zero when it has none
}
AsepriteLayer is one layer, in the order the file stacks them from the bottom.
type AsepriteOptions ¶
type AsepriteOptions struct {
// Layers packs each layer's own frames beside the composited ones,
// for a game that draws a layer alone: a hat, a damage overlay, a
// mask. Hidden layers are packed too, because a layer hidden in the
// editor is often the one a game wants. It costs a packed frame per
// layer per frame.
Layers bool
}
AsepriteOptions selects what ParseAseprite packs.
type AsepriteSlice ¶
type AsepriteSlice struct {
Name string
Keys []AsepriteSliceKey
UserData string
UserColor color.RGBA
}
AsepriteSlice is a named rectangle drawn in the editor's slice tool, with one key per frame it changes on.
type AsepriteSliceKey ¶
type AsepriteSliceKey struct {
Frame int // the first frame the key applies to
Bounds lin.Rect // in the sprite's pixels
// Center is the nine-slice middle, relative to Bounds; it is zero
// when the slice is not a nine-patch.
Center lin.Rect
// Pivot is the slice's pivot, relative to Bounds; it is zero when the
// slice has none.
Pivot lin.Vec2
}
AsepriteSliceKey is a slice's rectangle from one frame onwards.
type AsepriteTag ¶
type AsepriteTag struct {
Name string
From, To int
// Direction is "forward", "reverse", "pingpong" or
// "pingpong_reverse", the same names the JSON export uses.
Direction string
Repeat int // how many times the editor plays it; zero means forever
UserData string
UserColor color.RGBA
}
AsepriteTag is one animation tag: a range of frames and how it plays.
type Atlas ¶
Atlas is a texture with named regions and animation tags.
func (*Atlas) Animation ¶
func (a *Atlas) Animation(tag string) RegionAnimation
Animation returns a tag's frames and durations as an animation that loops. An unknown tag gives an animation with no frames.
type AtlasData ¶
type AtlasData struct {
Frames map[string]AtlasFrame
Order []string // frame names in file order
Tags map[string][]string // frame names per animation tag, in play order
Image string // meta.image, the texture file the atlas expects
Size lin.Vec2 // meta.size, the texture size; zero if absent
}
AtlasData is a parsed atlas description before it is tied to a texture: TexturePacker JSON (hash or array) or Aseprite's JSON export.
func ParseAtlas ¶
ParseAtlas reads a TexturePacker or Aseprite JSON atlas.
type AtlasFrame ¶
type AtlasFrame struct {
Rect lin.Rect // pixels in the texture; for a rotated frame the packed size
Duration float32 // seconds, from Aseprite exports; zero otherwise
// Rotated frames are stored turned a quarter turn clockwise; Rect is
// the packed rectangle and SourceSize the upright one.
Rotated bool
Trimmed bool
// Offset is where the packed pixels sit within the untrimmed source.
Offset lin.Vec2
SourceSize lin.Vec2
}
AtlasFrame is one named rectangle of a packed texture.
type Atmosphere ¶
type Atmosphere struct {
// Height is how deep the air is in world units. Zero means no
// atmosphere: the sky keeps its Zenith and Horizon gradient. Density
// falls to 1/e at a seventh of it for air and a fiftieth for haze.
Height float32
// PlanetRadius is the ground's distance from the planet's centre in
// world units. It sets how far the horizon is and how long a grazing
// ray runs through the air; zero means a hundred times Height, which
// is Earth's proportion.
PlanetRadius float32
// Altitude is how far the camera is above the ground in world units.
// Set it from the camera each frame: the air below the camera stops
// scattering into the view as it climbs, so the sky darkens with
// height and the horizon drops away. Zero is the ground.
Altitude float32
// Rayleigh is how much the air scatters per world unit at the ground,
// by wavelength. Its zero is Earth's air scaled to Height, which is
// what makes the sky blue and the sunset red.
Rayleigh Color
// Mie is how much haze scatters per world unit at the ground, the same
// at every wavelength. It is the white glare around the sun and the
// milkiness of a humid day; zero means Earth's haze scaled to Height.
Mie float32
// Forward is how strongly haze scatters along the light rather than
// across it, 0 for even and towards 1 for a tight glare around the
// sun; zero means 0.76.
Forward float32
// Intensity is the radiance of the sunlight the scattering divides up.
// Raise it for a brighter sky without touching Light.Color; zero
// means 22.
Intensity float32
}
Atmosphere is the sky computed rather than described: single scattering of sunlight by air (Rayleigh) and by haze (Mie) through a shell around a planet. To use it, set Height to how deep the air is in world units and leave the rest at zero for Earth's air scaled to that depth. The sky then reddens along the horizon as the sun sets, keeps its blue overhead at noon, goes dark when the sun is below the horizon, and thins to black as Altitude climbs out of the shell, so a ship can fly from the ground to space with no seam. Distant geometry takes the same scattered light through Light.Fog's aerial perspective. Sky.Vacuum still scales the result, and Sky.Ground still lights the half below the horizon.
The model is integrated per pixel, eight samples along the view ray and four towards the sun at each, so a sky pixel costs about eighty exponentials. There is no precomputed table to load or keep in step.
type BatchItem ¶
BatchItem is one draw of a static batch: a mesh, its material and where it sits in the world, exactly what DrawMesh takes.
type Billboard ¶
type Billboard struct {
Texture *Texture // nil draws a flat colour
Region Region // a part of the texture, for atlases and sprite sheets; zero means all of it
Position lin.Vec3 // where the quad's centre sits, before Offset
Size lin.Vec2 // width and height in world units; zero means 1 by 1
// Offset moves the quad in its own plane in units of its size: (0,
// 0.5) puts Position at the bottom edge, for a sprite standing on
// the ground.
Offset lin.Vec2
Color Color // tint; zero means white
// Upright turns the quad about the world's up axis only, so it stays
// vertical when the camera looks down on it: trees, characters.
Upright bool
// Lit shades the quad with the scene's lights; otherwise it shows
// its texture as it is.
Lit bool
// Cutout draws hard edges: alpha under half is discarded, the rest
// writes depth and casts shadows. Otherwise the quad blends its
// alpha over the scene, after the opaque draws.
Cutout bool
// OnTop draws over everything, for labels that must not be hidden.
OnTop bool
}
Billboard is a textured quad in the 3D scene that turns to face the camera: a health bar over a unit, a name over a player, a tree or a bush in a scene that cannot afford a model, a glow around a star, a puff of smoke. It draws through the mesh path, so it is lit, fogged and shadowed like any mesh when asked to be, and many billboards with one texture become one instanced draw.
type Blend ¶
type Blend uint8
Blend is how a draw combines with what is already there. Colours are premultiplied throughout, so these are the premultiplied equations.
const ( BlendAlpha Blend = iota // source over: the default BlendAdd // add light: glows, fire, particles BlendMultiply // darken by the source: shadows, tinting BlendScreen // the inverse of multiply: brighten BlendLighten // keep the brighter of the two BlendDarken // keep the darker of the two BlendReplace // copy the source, ignoring what was there BlendErase // cut the source's shape out of what was there )
func ParseBlend ¶
ParseBlend reads a blend mode written the way String spells it, so a mode can be named in an asset file or on a console line. It reports false for anything else, leaving the caller to keep its default.
func (Blend) Options ¶
func (b Blend) Options() BlendOptions
Options returns the equations of a built-in blend mode. The result is independent and can be edited before passing it to CustomBlended.
type BlendEquation ¶
type BlendEquation uint8
BlendEquation combines the scaled source and destination components. Min and Max ignore their factors, as required by the graphics API.
const ( EquationAdd BlendEquation = iota // source plus destination EquationSubtract // source minus destination EquationReverseSubtract // destination minus source EquationMin // smaller source/destination component EquationMax // larger source/destination component )
type BlendFactor ¶
type BlendFactor uint8
BlendFactor scales a source or destination component before blending.
const ( FactorZero BlendFactor = iota // discard the input FactorOne // use the input unchanged FactorSrcColor // multiply by the source colour FactorOneMinusSrcColor // multiply by one minus source colour FactorDstColor // multiply by the destination colour FactorOneMinusDstColor // multiply by one minus destination colour FactorSrcAlpha // multiply by source alpha FactorOneMinusSrcAlpha // multiply by one minus source alpha FactorDstAlpha // multiply by destination alpha FactorOneMinusDstAlpha // multiply by one minus destination alpha FactorSrcAlphaSaturate // min(source alpha, 1-destination alpha); one for alpha )
type BlendOptions ¶
type BlendOptions struct {
SrcColor, DstColor BlendFactor
ColorOp BlendEquation
SrcAlpha, DstAlpha BlendFactor
AlphaOp BlendEquation
}
BlendOptions controls colour and alpha independently. Values are literal: zero factors discard both inputs. Start with BlendAlpha.Options() for source-over defaults, then change the fields your effect needs. Colours supplied to the blend stage are premultiplied.
type Camera ¶
type Camera struct {
Position lin.Vec3
Target lin.Vec3
Up lin.Vec3 // zero means +Y
FovY float32 // radians; zero means 60 degrees
Near float32 // zero means 0.1
Far float32 // zero means 1000
// Ortho is half the view's height in world units for an orthographic
// camera; zero means perspective.
Ortho float32
}
Camera looks from Position at Target: perspective with FovY, or orthographic when Ortho is set, for isometric and strategy views where distance does not shrink things.
func OrbitCamera ¶
OrbitCamera makes a camera looking at target from yaw and pitch radians at a distance, the usual control scheme for strategy and viewer cameras.
func (Camera) Frustum ¶
Frustum returns the camera's frustum for a view of the given aspect ratio (width over height).
func (Camera) Project ¶
Project maps a world point to a view of the given size: where a label or a health bar for it belongs. ok is false when the point is behind the camera; a point outside the view still projects, off the edges. The view size is what Graphics.View reports, so this answers from Update as well as from Draw.
func (Camera) Projection ¶
Projection returns the projection matrix alone.
type Camera2D ¶
type Camera2D struct {
Position lin.Vec2
Zoom float32 // zero means 1
Rotation float32
// contains filtered or unexported fields
}
Camera2D frames a region of a 2D world: Position is the world point at the centre of the view, Zoom scales world units to view units (2 shows half as much), Rotation is radians anticlockwise. Follow, Clamp and Shake move it over time; a camera used by value is still valid, it just has no motion of its own.
func (*Camera2D) Advance ¶
Advance steps the camera's shake by dt seconds; call it once per update. Without a shake in progress it does nothing.
func (*Camera2D) Clamp ¶
Clamp keeps the view inside a world rectangle, so the camera stops at the edge of a level rather than showing what lies beyond it. Where the rectangle is narrower or shorter than the view, the view is centred on it along that axis. Rotation is ignored.
func (*Camera2D) Follow ¶
Follow moves the camera towards a target, closing the gap at rate per second: 5 trails the player softly, 20 keeps close, and zero snaps. The motion is the same at any frame rate. Call it from Update with the step, or from Draw with the frame's time.
func (*Camera2D) Shake ¶
Shake throws the view about by up to amplitude world units, fading out over seconds: an explosion, a heavy landing. A shake started while one is running takes the larger amplitude and the longer time left. Advance runs it.
func (Camera2D) ViewToWorld ¶
ViewToWorld maps a view point (for example the mouse) back to the world.
func (Camera2D) VisibleRect ¶
VisibleRect is the world-space box the camera can see, conservatively enlarged when rotated.
type CaretAffinity ¶
type CaretAffinity uint8
CaretAffinity chooses the side of a source boundary at a wrap or bidi transition. Leading follows the next cluster; Trailing follows the previous.
const ( CaretLeading CaretAffinity = iota CaretTrailing )
type Color ¶
type Color struct{ R, G, B, A float32 }
Color is a straight (non-premultiplied) RGBA colour in linear light, with alpha in 0..1. RGB values above 1 represent HDR radiance in lights, emissive materials and other HDR inputs; sprite colours are clamped.
func FromHSV ¶
FromHSV makes an opaque colour in linear light from a hue in degrees, saturation and value in 0..1: the easy way to pick distinct team or debug colours.
func (Color) HSV ¶
HSV returns the hue in degrees (0..360), saturation and value (0..1) of the colour in linear light.
func (Color) Premultiplied ¶
Premultiplied returns the colour with RGB scaled by alpha, the form the blend modes and DrawTriangles vertices use.
func (Color) Scale ¶
Scale brightens or darkens the colour, leaving alpha alone; values above 1 make emissive colours for bloom.
type ColorFormat ¶
type ColorFormat int
ColorFormat is the pixel format of a render texture's colour image.
const ( // ColorScreen is the window's own format, eight bits a channel with // sRGB encoding. It is the default and what a texture drawn back onto // the screen wants. ColorScreen ColorFormat = iota // ColorHDR is sixteen-bit floating point RGBA: values above 1 survive, // so a render texture can hold light rather than a tone-mapped // picture. Feed one to a material or grade it later. ColorHDR // ColorMask is one eight-bit channel, for a mask, a height field or a // coverage buffer. Only the red channel is stored; sampling it gives // that value in red and one in alpha. ColorMask )
type ColorMatrix ¶
ColorMatrix recolours sprites: the straight colour goes through M and gains Offset before the alpha is put back. Build one with the constructors, compose with Mul, and set it with SetColorMatrix or ColorMatrixed; the standard sprite shader applies it. It is laid out as the shader's uniform block.
func Brightness ¶
func Brightness(b float32) ColorMatrix
Brightness scales colours: below 1 darkens, above 1 brightens.
func Contrast ¶
func Contrast(c float32) ColorMatrix
Contrast stretches colours about mid grey: 0 is flat grey, 1 unchanged.
func HueRotate ¶
func HueRotate(angle float32) ColorMatrix
HueRotate turns every hue by angle radians around the grey axis.
func Saturation ¶
func Saturation(s float32) ColorMatrix
Saturation scales colourfulness: 0 is greyscale, 1 unchanged, above 1 more vivid.
func Tint ¶
func Tint(c Color) ColorMatrix
Tint scales each channel by a colour, like a sprite tint but after the matrix stack.
func (ColorMatrix) Apply ¶
func (m ColorMatrix) Apply(c Color) Color
Apply runs a colour through the matrix on the CPU, for previews.
func (ColorMatrix) Mul ¶
func (m ColorMatrix) Mul(n ColorMatrix) ColorMatrix
Mul composes matrices so that m.Mul(n) applies n first, then m.
type CompiledPath ¶
type CompiledPath struct {
// contains filtered or unexported fields
}
CompiledPath is a path's tessellated fill and stroke stored on the GPU. It captures the path, paint coordinates and colours at compilation time, and borrows any paint textures. Keep those textures alive while drawing it. Later changes to the source Path or paint options do not change the result. Graphics owns the compiled geometry; Destroy releases it early.
func (*CompiledPath) Bounds ¶
func (c *CompiledPath) Bounds() lin.Rect
Bounds returns the local bounds of the compiled triangles, including stroke and antialias fringes. It excludes the drawing transform and camera.
func (*CompiledPath) Destroy ¶
func (c *CompiledPath) Destroy()
Destroy releases the compiled geometry after queued GPU work finishes. Paint textures remain owned by their creators. Repeated calls do nothing.
type Direction ¶
type Direction uint8
Direction is the direction text runs in.
const ( // DirectionAuto reads the text: right to left when it starts with a // right-to-left script (Arabic, Hebrew), left to right otherwise. DirectionAuto Direction = iota DirectionLTR DirectionRTL // DirectionTTB lays glyphs top to bottom in columns that step from // right to left, for vertical Japanese and Chinese. DirectionTTB )
type Environment ¶
type Environment struct {
// contains filtered or unexported fields
}
Environment is distant light from every direction, for image-based lighting: metals reflect it, rough surfaces are tinted by it, and it can be drawn as the sky behind the scene. Build one from an equirectangular panorama with NewEnvironment or NewEnvironmentHDR and set it on the Light; without one the light's procedural Sky does the same job from parameters alone.
func (*Environment) Destroy ¶
func (env *Environment) Destroy()
Destroy frees the environment. Called inside a frame it costs no wait: the cube map and its descriptor set go on the frame slot's retire list and are freed once that frame has finished.
type EnvironmentOptions ¶
type EnvironmentOptions struct {
// Intensity multiplies the environment's light; zero means 1. A photo
// of an overcast day is around 1; a bright sky panorama may need more.
Intensity float32
// Size is the cube map's side in texels; zero means 128. Larger is
// sharper in mirror-like reflections and slower to prepare.
Size int
}
EnvironmentOptions tunes an environment.
type FillOptions ¶
type FillOptions struct {
Rule FillRule
// Texture maps an image over the path: view point p gets texture
// coordinate (p - TextureOrigin) / TextureSize. Zero size means the
// path's bounds.
Texture *Texture
TextureOrigin lin.Vec2
TextureSize lin.Vec2
// Gradient colours the fill by position instead of a texture; the
// colour argument then tints it.
Gradient *Gradient
NoAntiAlias bool
}
FillOptions controls FillPath.
type FillRule ¶
type FillRule uint8
FillRule decides which regions of a self-overlapping path are inside.
type Fog ¶
type Fog struct {
Color Color
Start, End float32
Density float32
Height float32
HeightFalloff float32
}
Fog fades geometry into a colour with distance from the camera: the cheapest way to give a scene depth and to hide the far plane. Linear fog ramps from Start to full at End; exponential fog thickens with Density (1 - exp(-(distance * Density)^2)); when both are set the denser wins. Height and HeightFalloff make ground fog: full at and below Height, thinning above it by exp(-(y - Height) * HeightFalloff), along the world's y axis. A zero End and Density means no fog. The sky is not fogged, so pick a colour near the horizon's for outdoor scenes.
type Font ¶
type Font struct {
Size float32 // em size in view units
LineHeight float32 // baseline to baseline
Ascent float32 // baseline to the top of the tallest glyph
Descent float32 // baseline to the bottom of the deepest glyph, positive
// contains filtered or unexported fields
}
Font is an OpenType face (with optional fallbacks) rasterised into a glyph atlas at one size. Text is shaped with HarfBuzz, so kerning, ligatures, mark placement, Arabic joining and right-to-left order all come out right; glyphs are rendered from the font's outlines at the framebuffer's pixel density and drawn in view units, so text is crisp on high-DPI displays. Create fonts with NewFont or NewSDFFont; Graphics releases their atlases at shutdown, or Destroy releases one earlier. The base atlas has fixed capacity: Layout and Shape report glyphs that cannot fit. Choose FontOptions.AtlasSize for the character set and raster size the game needs. Lazy outline atlases are also owned by the font.
func (*Font) Layout ¶
func (f *Font) Layout(text string, opts TextOptions) (*TextLayout, error)
Layout shapes and wraps text once for drawing, measurement and caret queries. Indices always address the original UTF-8 string, including paragraphs and wrapping with generated hyphens. Invalid options, exhausted atlas capacity and GPU allocation/upload failures are returned to the caller. A layout of the same text and options made recently is returned from the font's cache without laying the text out again or allocating.
func (*Font) Measure ¶
func (f *Font) Measure(text string, opts TextOptions) (w, h float32)
Measure returns the size text takes when drawn with the options: one line with the zero options, or wrapped, spaced and sized as they say. The width is the widest line's advance and the height is the line height times the line spacing for every line; vertical text swaps the two. Measure shares the layout Layout and DrawTextBlock use, so text measured and then drawn with the same options is shaped once, and measuring the same static label every frame costs a map lookup. Text that cannot be laid out (a destroyed font, a full atlas) is measured by shaping alone.
func (*Font) Shape ¶
func (f *Font) Shape(text string, opts TextOptions) ([]Glyph, error)
Shape lays out one line of text and returns its glyphs in visual order, for drawing them yourself with Draw and the font's Texture, or for hit-testing. This low-level operation ignores block alignment, wrapping and decorations; Layout handles those. Rasterization and upload errors are returned explicitly. The source must be one valid UTF-8 line.
type FontOptions ¶
type FontOptions struct {
// OutlinePages limits lazy outline-atlas pages; zero allows 16. Pages
// reuse power-of-two distance spreads, so animating width reuses them.
OutlinePages int
AtlasSize int // texture side in pixels; default 1024
Preload []rune // glyphs rendered up front; ASCII is always included
Ranges [][2]rune // inclusive ranges rendered up front
// Fallbacks are further TTF/OTF fonts consulted, in order, for runs of
// text the main font has no glyphs for: a CJK or Arabic font behind a
// Latin one, for example.
Fallbacks [][]byte
// Features turns OpenType features on ("smcp", "frac", "ss01") or off
// ("-liga", "-kern") for all text drawn with the font.
Features []string
// Variations sets variable font axes, such as "wght": 650 or "wdth": 90.
Variations map[string]float32
}
FontOptions tunes a font.
type FrameStats ¶
type FrameStats struct {
Draws2D int // 2D draw calls after batching
Vertices2D int // 2D vertices drawn
Draws3D int // mesh draw calls after instancing, all passes
Instances int // mesh instances drawn in the main pass
Culled int // mesh draws outside the camera's view, skipped in the main pass
// Occluded counts the mesh draws inside the camera's view that the
// software occlusion buffer found behind an occluder, which is a
// subset of Culled. It is zero in a frame with no AddOccluder3D.
Occluded int
// CullTests counts the bounding volume tests culling ran: one per
// queued draw, plus one per hierarchy node a static batch visited.
// A batch shows up as far fewer tests than it holds items.
CullTests int
// ShadowDraws counts the mesh instances recorded into the shadow maps,
// summed over the cascades, the shadowed spot lights and the cube
// faces of the shadowed point lights. A caster is only recorded into
// the maps its bounds reach, so this falls as lights and casters
// spread out.
ShadowDraws int
// Culled2D counts sprites and glyphs outside the view, or outside the
// 2D camera's view under a camera, that were dropped before reaching
// the vertex stream.
Culled2D int
// Lights2DDropped counts the lights passed to SetLights2D past the
// eighth, which lit sprites are not lit by; a nonzero count means the
// game should pass its nearest lights first.
Lights2DDropped int
// LightsDropped counts point and spot lights added past MaxLights,
// which a frame keeps none of; a nonzero count means the scene should
// add its nearest lights first.
LightsDropped int
// Waits counts the times the frame stopped and waited for the GPU to
// go idle. Uploads and destroys inside a frame go through the staging
// arena and the retire ring, and every per-frame buffer grows through
// the retire ring too, so a running game reports zero; a nonzero
// count means something stalled the whole pipeline, such as a
// Texture.Read or a resource destroyed outside a frame.
Waits int
// Lights counts the point and spot lights the frame kept, out of
// MaxLights, whatever part of the view each one reaches. The
// directional light is not counted: every frame has one.
Lights int
// Particles counts the instances drawn by DrawParticles and
// DrawParticles3D. Each batch is one draw call however many
// instances it holds, counted in Draws2D or Draws3D.
Particles int
// ProbesDropped counts reflection probes added past MaxProbes, which
// a frame keeps none of.
ProbesDropped int
// GPU is how long the GPU spent in each pass, in the order the passes
// were recorded: the shadow atlas, the opaque and blended scene, the
// reflections, the decals, bloom, ambient occlusion, the composite,
// the anti-alias resolve and the 2D stream. A pass that runs for a
// render texture as well as the screen is summed into one entry. It is
// empty on a device without timestamp queries or before results arrive.
// Available queries can still report zero durations when the device's
// timestamp resolution cannot distinguish the pass endpoints. MoltenVK
// without Metal counter sampling can report zero for every pass. The
// figures come from queries read back without waiting, so they describe
// a frame two frames back, and the slice is reused every frame; copy it
// to keep it.
GPU []GPUSpan
// GPUFrameMS is the GPU time from the frame's first pass to the end
// of its last, so it covers the gaps between passes as well. It is zero
// when no results are available or the timestamps cannot resolve a
// duration, including on some devices that emulate timestamp queries.
GPUFrameMS float64
}
FrameStats counts what a frame cost the GPU, for the debug overlay and a draw-call budget.
type Frustum ¶
type Frustum struct {
// contains filtered or unexported fields
}
Frustum is the volume a camera sees, as six planes facing inward. The engine culls every mesh draw against the camera's frustum on its own; a game uses one to skip whole chunks, regions or units before it asks to draw them, which saves the work of building their draws at all.
func (Frustum) ContainsBox ¶
ContainsBox reports whether any of an axis-aligned box lies inside the frustum. It errs on the side of visible: a box near a corner may pass while being just outside, which only costs a draw.
func (Frustum) ContainsPoint ¶
ContainsPoint reports whether a point lies inside the frustum.
type GPUSpan ¶
GPUSpan is one pass of a frame and the milliseconds the GPU spent in it, as FrameStats.GPU reports it.
type Geometry2D ¶
type Geometry2D struct {
// contains filtered or unexported fields
}
Geometry2D is reusable triangle geometry in GPU memory. DrawGeometry places it in the ordinary 2D queue with the current transform, camera, layer, sort key, clip, blend and shader. Graphics owns its lifetime; Destroy releases it early. Its zero value cannot be drawn or updated.
func (*Geometry2D) Bounds ¶
func (m *Geometry2D) Bounds() lin.Rect
Bounds returns the local axis-aligned bounds of all uploaded vertices, including unused vertices. It excludes the graphics transform and camera.
func (*Geometry2D) Destroy ¶
func (m *Geometry2D) Destroy()
Destroy releases this geometry after queued and in-flight draws finish. Repeated calls do nothing. Later DrawGeometry calls with it draw nothing.
type Glyph ¶
type Glyph struct {
Pos lin.Vec2 // top-left of the glyph image
Size lin.Vec2
UV0, UV1 lin.Vec2 // region of the font's Texture
Index int // index of the first byte of its text in the string
// Advance is how far the pen moves after the glyph, in view units at
// the font's own size, for caret positions and hit-testing. It is the
// line height for vertical text.
Advance float32
Empty bool // no image (a space)
Color bool // a colour glyph such as an emoji, drawn untinted
}
Glyph is one positioned glyph from Shape: where to draw a piece of the atlas relative to the text's origin (the pen at the start of the baseline), in view units at the font's size.
type Gradient ¶
type Gradient struct {
// contains filtered or unexported fields
}
Gradient colours a fill or stroke by position: linear from one point to another, or radial out from a centre. Graphics releases its small texture at shutdown, or Destroy releases it earlier.
type GradientStop ¶
GradientStop is a colour at a position along a gradient, 0 to 1.
type Graphics ¶
type Graphics struct {
// contains filtered or unexported fields
}
Graphics is the drawing context for one window. The engine opens a frame, the Draw* calls queue work, and the engine submits it. Obtain Graphics from engine.Context; its zero value is not usable. Use it and its GPU resources only on the game goroutine. Graphics owns every GPU resource it creates and releases it when the engine closes, including when game setup or drawing fails. Call a resource's Destroy method to release it earlier, for example when unloading a level.
GPU resources belong to the Graphics that created them. Passing resources from another output to drawing or state methods panics before recording their handles. Constructors and transfer methods with error results return errors instead; text drawing reports invalid font ownership at submission.
func (*Graphics) AddOccluder2D ¶
AddOccluder2D adds a shadow caster for this frame: a closed polygon in the same units as sprite positions, which is world units under a 2D camera. Lights given Shadows in SetLights2D are blocked by it, and every DrawLit sprite in the frame sees the same set. Two points make a single wall segment; fewer than two are ignored. Occluders are cleared at the start of each frame, like the lights, so a game adds them every frame. The cost is the occluder's edges times the shadowed lights, computed on the CPU, so a few hundred edges are free and tens of thousands are not.
func (*Graphics) AddOccluder3D ¶
AddOccluder3D marks a mesh as blocking the camera's view for this frame: a wall, a hill, a building's shell. The engine rasterises the frame's occluders into a small depth buffer on the CPU and skips the draws that lie entirely behind them, which the frustum test cannot do; FrameStats.Occluded counts them and they still cast shadows. Adding an occluder does not draw it, so draw the mesh as well, or add a coarse stand-in for geometry that is drawn in detail. Occluders are cleared at the end of the frame, like lights. Keep them few and low-poly: every triangle is rasterised on the CPU, and a mesh with more than MaxOccluderTriangles triangles is ignored.
func (*Graphics) AddOccluder3DAt ¶
AddOccluder3DAt is AddOccluder3D with a Transform.
func (*Graphics) AddPoint ¶
func (g *Graphics) AddPoint(p PointLight)
AddPoint adds a point light for this frame.
func (*Graphics) AddPointLight ¶
AddPointLight adds a light shining from a point in every direction for this frame, fading to nothing rng units away: torches, muzzle flashes, glowing ore. A frame keeps its first 1024 point and spot lights (MaxLights); add the nearest ones first when a scene has more.
func (*Graphics) AddProbe ¶
func (g *Graphics) AddProbe(p *ReflectionProbe)
AddProbe adds a reflection probe for this frame. Draws inside its volume reflect it; a frame keeps its first MaxProbes probes and counts the rest in FrameStats.ProbesDropped. A probe that has not been baked is ignored.
func (*Graphics) AddSpotLight ¶
AddSpotLight adds a light shining from a point along dir in a cone, fading to nothing rng units away: flashlights, headlights, stage lights. The cone is full inside innerAngle and fades to nothing at outerAngle (both full angles in radians; a zero inner angle means a hard-edged cone, a zero outer angle means 45 degrees). Spot lights count against the same limit as point lights.
func (*Graphics) BakeImpostor ¶
func (g *Graphics) BakeImpostor(m *Model, opts ImpostorOptions) (*Impostor, error)
BakeImpostor renders a model from a ring of directions around it into one atlas texture, which DrawImpostor then draws as a billboard. Call it from Init or Update, never from Draw: it runs a frame of its own to render the views and reads them back, so it costs one stall and must not be nested inside the game's frame.
The colour of each view comes from the model with its own materials, and its shape from a second pass that draws the model unlit and white, so the atlas is a hard cutout with no background bleeding into it. A model or material resource from another Graphics returns an error.
func (*Graphics) BakeLightProbes ¶
func (g *Graphics) BakeLightProbes(grid *LightProbeGrid, scene func()) error
BakeLightProbes renders the scene from every cell of the grid and projects what it sees onto spherical harmonics. Call it from Init or Update, not from Draw: it submits its own command buffers and waits for them, once for every four cells. The scene function queues the draws and lights the bake sees, exactly as Draw would; it is called once for each face rendered together, up to 24 times, so it must queue the same scene every time. Baking again replaces the harmonics.
func (*Graphics) BakeProbe ¶
func (g *Graphics) BakeProbe(p *ReflectionProbe, scene func()) error
BakeProbe renders the scene from the probe's position into a cube map and prefilters it for every roughness. Call it from Init or Update, not from Draw: it submits its own command buffer and waits for it, once for all six faces. The scene function queues the draws and lights the bake sees, exactly as Draw would, and the engine sets the camera for each of the six faces. It is called once for each face, so it must queue the same scene every time. A second call rebakes the probe and frees what the first one made.
func (*Graphics) Blend ¶
Blend returns the current built-in 2D blend mode. CustomBlended temporarily overrides its equations without changing this value.
func (*Graphics) Blended ¶
Blended runs draw with the blend mode set, then restores the original queue's mode, including when draw panics.
func (*Graphics) ClearStencil ¶
ClearStencil queues a stencil-only clear in the current view and clips. Drawing before and after it cannot reorder across the clear, even when their layers or sort keys differ. Colour and depth remain unchanged. It panics if the target has no stencil attachment.
func (*Graphics) Clip ¶
Clip runs draw clipped to r intersected with the enclosing clip, then restores the original queue's clip stack, including when draw panics.
func (*Graphics) ColorMatrixed ¶
func (g *Graphics) ColorMatrixed(m ColorMatrix, draw func())
ColorMatrixed runs draw with the matrix set, then restores the original queue's matrix, including when draw panics.
func (*Graphics) CompileMeshShader ¶
CompileMeshShader compiles Bunyip mesh WGSL source and creates an owned GPU shader. The source defines fn surface(s: Surface) -> Surface and may define finish and vertex hooks. All required lit, transparency and vertex variants are compiled together. Compiler requirements and threading are the same as CompileShader. See the shader guide for hook signatures and engine bindings.
func (*Graphics) CompilePath ¶
func (g *Graphics) CompilePath(path *Path, opts PathOptions) (*CompiledPath, error)
CompilePath tessellates a path once using opts, independently of current graphics state. DrawPath applies the current transform, camera, clipping, layer, blend and shader. Empty paths compile successfully and draw nothing. Paint textures and gradients must belong to this Graphics; foreign paints return an error before any geometry is uploaded.
func (*Graphics) CompileShader ¶
CompileShader compiles Bunyip sprite WGSL source and creates an owned GPU shader. The source defines fn fragment(uv: vec2f, color: vec4f) -> vec4f; the engine supplies bindings and the entry point. Compilation uses Go only. This synchronous method belongs on the game goroutine, like NewShader. Cancellation is checked between compilation phases, not during a phase or GPU creation. To compile on a worker, use shaders.Compiler.Compile, then call NewShader on the game goroutine.
func (*Graphics) ConfigurePost ¶
func (g *Graphics) ConfigurePost(edit func(*PostSettings))
ConfigurePost edits a copy of the current global post-processing settings and commits it when edit returns normally. A panic leaves the settings unchanged unless edit changed them directly. Numeric zero is kept as supplied; fields not edited retain their current values. Like SetPost, the result applies to the screen and all render textures when the frame submits. Do not retain the pointer passed to edit.
func (*Graphics) CustomBlended ¶
func (g *Graphics) CustomBlended(options BlendOptions, draw func())
CustomBlended runs 2D drawing with explicit blend equations, restoring the original queue's blend state even on panic. It includes geometry and flat particles. Invalid factors or equations panic before drawing.
func (*Graphics) DebugFont ¶
DebugFont is the engine's built-in font, 14 view units tall, for overlays and tools; nil when it could not be made.
func (*Graphics) DebugText ¶
DebugText draws a line of text in the engine's own font with a dark shadow, so a value can go on screen without loading a font first.
func (*Graphics) DebugText3D ¶
DebugText3D draws debug text at a world position, projected to the view: an entity's id over its head, a value beside a probe. Points behind the camera draw nothing.
func (*Graphics) Draw ¶
Draw queues a sprite. A nil texture draws with a 1x1 white texture, so a coloured rectangle is a tinted sprite. A sprite wholly outside the view, or outside the 2D camera's view under a camera, is dropped and counted in FrameStats.Culled2D.
Example ¶
package main
import (
"image"
"github.com/matjam/bunyip/gfx"
"github.com/matjam/bunyip/lin"
)
// The Graphics value comes from engine.Context.Gfx inside a game's Init
// and Draw; these examples show the calls a game makes with it.
var (
g *gfx.Graphics
img image.Image
)
func main() {
tex, err := g.NewTexture(img, gfx.TextureOptions{Linear: true})
if err != nil {
return
}
defer tex.Destroy()
// A sprite is a rectangle with a texture window and a tint.
g.Draw(tex, gfx.Sprite{Pos: lin.V2(100, 80), Size: lin.V2(64, 64), UV1: lin.V2(1, 1), Color: gfx.White})
g.DrawTexture(tex, 200, 80) // at the texture's own size
g.FillRect(0, 0, 320, 4, gfx.RGB(255, 200, 40))
}
Output:
func (*Graphics) DrawAxes ¶
DrawAxes draws a transform's x, y and z axes in red, green and blue, each size units long.
func (*Graphics) DrawBatch ¶
func (g *Graphics) DrawBatch(b *StaticBatch)
DrawBatch queues the items of a static batch the camera can see. The hierarchy is walked when the frame's draws are prepared, so occluders added after this call still cull it, and the items that survive are ordinary draws: instanced together, sorted, shadowed and lit like any others. Items the camera cannot see but a shadow map can are queued for the shadow pass alone, so they cast shadows as culled DrawMesh draws do.
func (*Graphics) DrawBillboard ¶
DrawBillboard draws a camera-facing quad in the scene.
func (*Graphics) DrawDecal ¶
DrawDecal projects a texture onto whatever geometry lies inside a box: bullet holes, blood, footprints, road markings. box maps the unit cube to the world; the texture is projected along the box's y axis, its x and z spanning the image, and fades on surfaces facing away from it.
func (*Graphics) DrawFrame ¶
DrawFrame draws one frame of a sheet with the sprite's placement; the sprite's UV fields are filled in and a zero Size means the frame size.
func (*Graphics) DrawGeometry ¶
func (g *Graphics) DrawGeometry(tex *Texture, geometry *Geometry2D)
DrawGeometry queues a GPU-resident geometry version without copying its vertices. A nil texture means white. Nil, empty or destroyed geometry draws nothing. Geometry and textures must belong to this Graphics context.
func (*Graphics) DrawGlyphs ¶
DrawGlyphs draws glyphs from Shape with the text's origin at (x, y), scaled by scale (1, or zero, for the font's own size).
func (*Graphics) DrawImpostor ¶
DrawImpostor draws the baked view nearest the camera as a quad at pos, with the model turned by yaw radians about the world's up axis. A zero tint means white. The quad is a cutout, so it writes depth and casts shadows like the model it stands for.
func (*Graphics) DrawIndexed ¶
DrawIndexed queues textured triangles from vertices and indices, three indices per triangle, for meshes whose vertices are shared.
func (*Graphics) DrawLOD ¶
DrawLOD draws the level of detail for the model's distance from the frame's camera, with a material and model matrix like DrawMesh.
func (*Graphics) DrawLine3D ¶
DrawLine3D draws a one-pixel line between two world points, on top of everything: for seeing colliders, paths, rays and bones while a game is being written. Lines ignore depth so nothing hides them.
func (*Graphics) DrawLit ¶
DrawLit draws a sprite lit by the SetLights2D lights through a tangent-space normal map (a texture made with TextureOptions.Data), so a flat sprite catches light from the side a torch is on. Lights that cast shadows are blocked by the occluders AddOccluder2D added this frame.
func (*Graphics) DrawMesh ¶
DrawMesh queues a mesh with a material and a model matrix. Draws that share a mesh and material become one instanced draw call; blended materials draw after everything opaque, farthest first.
Example ¶
package main
import (
"image"
"github.com/matjam/bunyip/gfx"
"github.com/matjam/bunyip/lin"
)
// The Graphics value comes from engine.Context.Gfx inside a game's Init
// and Draw; these examples show the calls a game makes with it.
var g *gfx.Graphics
func main() {
verts, indices := gfx.CubeMesh()
cube, err := g.NewMesh(verts, indices)
if err != nil {
return
}
defer cube.Destroy()
g.SetCamera(gfx.OrbitCamera(lin.V3(0, 0, 0), 0.6, 0.4, 6))
g.SetLight(gfx.Light{Direction: lin.V3(-0.4, -1, -0.5), Color: gfx.Color{R: 2, G: 2, B: 1.8, A: 1}, Shadows: true})
g.DrawMeshAt(cube, gfx.Material{BaseColor: gfx.RGB(200, 80, 60), Roughness: 0.5}, gfx.At(0, 0, 0).Rotated(lin.V3(0, 1, 0), 0.7))
}
Output:
func (*Graphics) DrawMeshAt ¶
DrawMeshAt draws a mesh at a transform.
func (*Graphics) DrawMeshMoved ¶
DrawMeshMoved is DrawMesh for a mesh that moved: prev is the model matrix it was drawn with last frame. The velocity buffer carries the difference, so temporal anti-aliasing reprojects the mesh instead of smearing it and motion blur smears it along its own path. Drawing through DrawMesh says the mesh did not move, which is what a static scene wants; the camera's own motion is reconstructed from depth either way.
func (*Graphics) DrawModel ¶
DrawModel queues every part of the model under a world transform, each with the material its file gave it and its current morph pose.
func (*Graphics) DrawModelAnimated ¶
func (g *Graphics) DrawModelAnimated(m *Model, t Transform, p *AnimPlayer)
DrawModelAnimated draws a model under a transform with the player's pose: node-animated parts move rigidly, skinned parts deform and morph targets blend to the player's weights. Each draw captures its morph pose, so players sharing a model can draw different expressions.
func (*Graphics) DrawModelAnimatedMoved ¶
func (g *Graphics) DrawModelAnimatedMoved(m *Model, t, prev Transform, p *AnimPlayer, override MaterialOverride)
DrawModelAnimatedMoved is DrawModelAnimatedWith for a model that moved: prev is the transform it was drawn with last frame, which the velocity buffer carries for temporal anti-aliasing and motion blur. The pose's own motion is not carried; see DrawSkinnedMoved.
func (*Graphics) DrawModelAnimatedWith ¶
func (g *Graphics) DrawModelAnimatedWith(m *Model, t Transform, p *AnimPlayer, override MaterialOverride)
DrawModelAnimatedWith is DrawModelAnimated with a material override, so a posed character can be drawn in a team colour or with one part swapped. A nil override draws the file's materials.
func (*Graphics) DrawModelAt ¶
DrawModelAt draws a model at a transform.
func (*Graphics) DrawModelImpostor ¶
DrawModelImpostor draws the model while the camera is inside the impostor's Distance and the impostor beyond it, which is a level of detail whose far level costs one quad. A nil impostor draws the model at any distance, and a nil model draws the impostor at any distance, so a game can bake lazily and still call this every frame.
func (*Graphics) DrawModelMoved ¶
func (g *Graphics) DrawModelMoved(m *Model, world, prev lin.Mat4, override MaterialOverride)
DrawModelMoved is DrawModelWith for a model that moved: prev is the world transform it was drawn with last frame, which the velocity buffer carries for temporal anti-aliasing and motion blur.
func (*Graphics) DrawModelWith ¶
func (g *Graphics) DrawModelWith(m *Model, world lin.Mat4, override MaterialOverride)
DrawModelWith queues every part of the model under a world transform, passing each part through override to decide the material it is drawn with: one material for the whole model, a different one for a named part, or the file's own material with a field changed. A nil override is DrawModel.
gr.DrawModelWith(ship, world, func(i int, p gfx.ModelPart) gfx.Material {
if p.Name == "hull" {
m := p.Material
m.BaseColor = team
return m
}
return p.Material
})
func (*Graphics) DrawNineSlice ¶
DrawNineSlice draws a nine-slice stretched over r while keeping its corners at their pixel size; a zero tint means white.
func (*Graphics) DrawParticles ¶
func (g *Graphics) DrawParticles(tex *Texture, quads []ParticleQuad)
DrawParticles queues a batch of 2D particles as one instanced draw, for the very large counts a sprite-by-sprite path cannot afford. A nil texture draws plain quads. The batch takes the queue's current layer and blend mode, and draws in the same place a sprite drawn at that point would: by layer first, then by the order the calls were made. A sort key set with SetSortKey orders sprites within a layer but not particle batches, which keep their call order.
The slice is copied into this frame's instance buffer, so it may be reused as soon as the call returns. Particles are drawn in the order given, without depth sorting, which is what additive effects want; for alpha-blended particles that overlap, order the slice yourself.
func (*Graphics) DrawParticles3D ¶
func (g *Graphics) DrawParticles3D(tex *Texture, quads []ParticleQuad, opts Particles3D)
DrawParticles3D queues a batch of camera-facing particles in the 3D scene as one instanced draw: smoke, embers, snow, magic. A nil texture draws plain quads. Positions and sizes are in world units.
The particles are drawn over the finished scene, after decals, and are hidden by geometry in front of them; opts.Soft fades them out as they approach it. They are neither depth sorted against each other nor lit, so additive and unlit effects suit them best. The slice is copied, so it may be reused as soon as the call returns.
func (*Graphics) DrawPath ¶
func (g *Graphics) DrawPath(path *CompiledPath)
DrawPath queues a compiled path's fill followed by its stroke. Nil or destroyed compiled paths draw nothing. It performs no tessellation or vertex upload, and uses the same drawing state as DrawGeometry.
func (*Graphics) DrawRegion ¶
DrawRegion draws a region with the sprite's placement; the sprite's UVs are taken from the region, and a zero Size means the region's own.
func (*Graphics) DrawRichText ¶
func (g *Graphics) DrawRichText(fonts RichFonts, text RichText, x, y float32, opts TextOptions, tint Color) []RichLink
DrawRichText draws a styled block through the common text layout and returns its link rectangles translated to the drawing origin. A zero tint is white; explicit run colours multiply tint. Layout and upload failures are reported by frame submission, as with DrawTextBlock.
func (*Graphics) DrawSkinned ¶
DrawSkinned draws a skinned mesh with explicit joint matrices (one per joint, already multiplied by the inverse bind matrices).
func (*Graphics) DrawSkinnedMoved ¶
DrawSkinnedMoved is DrawSkinned for a mesh that moved: prev is the model matrix it was drawn with last frame. The motion vectors it produces carry the model matrix's motion only, not the pose's, so a character walking across the screen reprojects correctly while an arm swinging in place does not.
func (*Graphics) DrawTerrain ¶
DrawTerrain queues every chunk of a terrain at the resolution its distance from the frame's camera deserves. Chunks are ordinary mesh draws, so the frustum and the frame's occluders cull them and ChunkLevel reports what each was drawn at.
func (*Graphics) DrawText3D ¶
func (g *Graphics) DrawText3D(f *Font, text string, pos lin.Vec3, scale float32, c Color, onTop bool, opts TextOptions)
DrawText3D draws a line of text in the scene facing the camera, its origin at pos, scale world units per view unit of the font (a 32 unit font at 0.02 stands about 0.64 units tall). The text is centred on pos and drawn on top of the scene when onTop is set; opts gives alignment and size as for DrawText. Each glyph is a billboard, so a label is one instanced draw.
func (*Graphics) DrawTextBlock ¶
DrawTextBlock draws wrapped, aligned text with its top-left at (x, y), or its first baseline there with Baseline set. With a Width, alignment is within that width; without, lines align to x. Size scales the text and Angle rotates it about (x, y). Vertical text runs down from (x, y) in columns stepping left, so x is the right edge.
func (*Graphics) DrawTextLayout ¶
func (g *Graphics) DrawTextLayout(l *TextLayout, x, y float32, tint Color)
DrawTextLayout draws a reusable layout at its origin. Zero tint is white. Tint multiplies explicit rich colours; runs without a colour use tint. Colour glyphs retain RGB and use the effective alpha. A nil layout is a no-op. Invalid fonts or upload failures are reported by frame submission.
func (*Graphics) DrawTextOnPath ¶
func (g *Graphics) DrawTextOnPath(f *Font, text string, p *Path, offset float32, opts TextOptions, c Color)
DrawTextOnPath lays one line of text along a path, each glyph turned to follow it, starting offset units from the path's start: labels on arcs, text around a badge, a river's name along its course. Glyphs past the end of the path are not drawn; only the path's first sub-path is used.
func (*Graphics) DrawTexture ¶
DrawTexture queues a texture at its own size.
func (*Graphics) DrawTilemap ¶
DrawTilemap draws the map with its top-left at (x, y), skipping tiles outside the view, or outside the active 2D camera's view under a camera. The view is taken back through the transform stack into the map's own units, so a scrolled, scaled or rotated map only visits the tiles that can be seen.
func (*Graphics) DrawTo ¶
func (g *Graphics) DrawTo(rt *RenderTexture, clear Color, draw func())
DrawTo runs draw with the render texture as the output; every Draw*, SetCamera and SetLight call inside it lands on the texture. The texture is rendered before the main frame, so it can be drawn in the same frame. A second DrawTo on the same texture in one frame adds to what the first queued, with the first call's clear colour. Camera and lighting state belong to the target; post-processing is global and uses the final SetPost settings when the frame submits. The previous output is restored even when draw panics; drawing already queued is not rolled back. This call does not submit GPU work itself. A render texture from another Graphics panics before switching output or invoking draw.
Example ¶
package main
import (
"image"
"github.com/matjam/bunyip/gfx"
)
// The Graphics value comes from engine.Context.Gfx inside a game's Init
// and Draw; these examples show the calls a game makes with it.
var g *gfx.Graphics
func main() {
rt, err := g.NewRenderTexture(256, 256)
if err != nil {
return
}
defer rt.Destroy()
rt.SetView(256, 256)
g.DrawTo(rt, gfx.Black, func() {
g.FillRect(64, 64, 128, 128, gfx.RGB(90, 200, 255))
})
g.DrawTexture(rt.Texture(), 16, 16) // the render texture is an ordinary texture now
}
Output:
func (*Graphics) DrawTriangles ¶
DrawTriangles queues textured triangles: three vertices each, with positions in view units, texture coordinates in 0..1 and a tint. It is the primitive under sprites and paths, for games that build their own geometry.
func (*Graphics) DrawWireBox ¶
DrawWireBox outlines the axis-aligned box between two corners.
func (*Graphics) DrawWireCube ¶
DrawWireCube outlines the unit cube (corners at ±0.5) under a matrix: an oriented box, the shape of a Box3 collider.
func (*Graphics) DrawWireFrustum ¶
DrawWireFrustum outlines what a camera sees, for the given aspect ratio: another camera's view, a light's shadow box, a culling volume being debugged.
func (*Graphics) DrawWireSphere ¶
DrawWireSphere outlines a sphere as three great circles.
func (*Graphics) FillCircle ¶
FillCircle fills a circle.
func (*Graphics) FillGradient ¶
FillGradient fills a rectangle with a gradient.
func (*Graphics) FillPath ¶
func (g *Graphics) FillPath(p *Path, c Color, opts FillOptions)
FillPath fills the path's interior with a colour.
func (*Graphics) FillPolygon ¶
FillPolygon fills a polygon through the points.
func (*Graphics) Frustum ¶
Frustum returns the frustum of the camera set for this frame, for the current view's aspect ratio.
func (*Graphics) Layered ¶
Layered runs draw on layer, then restores the original queue's layer, including when draw panics. Drawing already queued is not undone.
func (*Graphics) Masked ¶
func (g *Graphics) Masked(mask, draw func())
Masked draws only where mask rasterizes fragments, composing up to eight nested masks. Mask drawing writes no colour. Transparent fragments still mark coverage unless their shader discards them; use an opaque shape or a shader that discards outside the desired mask.
Setup, mask, body and cleanup are separate ordering groups. Layers and sort keys order within each group, so callbacks may change either safely. Masked restores the original stencil, layer and sort key even on panic; queued draws remain queued. It temporarily uses one low stencil bit per nesting level, clears that bit afterward, and preserves all other bits. Advanced Stenciled state is suspended during the mask and then restored. A helper using Masked may also be called from mask: its clipped drawing contributes to the enclosing mask's coverage without writing colour. A depthless target or more than eight nested masks panic before mutation.
func (*Graphics) MaxSamples ¶
MaxSamples is the highest sample count PostSettings.Samples and RenderTextureOptions.Samples accept on this GPU: 1 when it cannot multisample at all, and usually 8.
func (*Graphics) NewBlankTexture ¶
func (g *Graphics) NewBlankTexture(width, height int, opts TextureOptions) (*Texture, error)
NewBlankTexture makes a transparent texture of a size, to be filled by Write: a canvas to paint on, a video frame, a procedural map.
func (*Graphics) NewCompressedTexture ¶
func (g *Graphics) NewCompressedTexture(data []byte, opts TextureOptions) (*Texture, error)
NewCompressedTexture uploads a KTX2 file written by bunyip-tex. Its blocks and its mip levels go to the GPU as they stand, so a game pays nothing at load time for compression or for mip generation, and the texture takes a quarter to an eighth of the memory an uncompressed one would.
The file's format decides whether sampling decodes from sRGB, so TextureOptions.Data is ignored; Linear and Repeat choose the sampler as usual, and NoMipmaps uploads level 0 alone. Where the device cannot sample the format, which some MoltenVK configurations cannot for the BC formats, level zero is decoded on the processor into a plain RGBA texture and any requested mipmaps are generated at load. This fallback supports the formats and BC7 modes the ktx2 CPU decoder implements; unsupported formats such as ASTC return an error on such a device.
func (*Graphics) NewEnvironment ¶
func (g *Graphics) NewEnvironment(panorama image.Image, opts EnvironmentOptions) (*Environment, error)
NewEnvironment builds an environment from an equirectangular panorama: longitude across, latitude down, sRGB colour, any size. It prefilters the image for every roughness on every core, which takes a fraction of a second for a large panorama.
func (*Graphics) NewEnvironmentHDR ¶
func (g *Graphics) NewEnvironmentHDR(panorama *HDRImage, opts EnvironmentOptions) (*Environment, error)
NewEnvironmentHDR builds an environment from a floating-point panorama, keeping its full range so a bright sun in it lights the scene as strongly as it should.
func (*Graphics) NewGeometry2D ¶
func (g *Graphics) NewGeometry2D(vertices []Vertex2D, indices []uint32) (*Geometry2D, error)
NewGeometry2D uploads vertices and triangle indices once. Nil or empty indices use consecutive groups of three vertices. Incomplete triangles, out-of-range indices and non-finite positions return errors. Empty geometry is valid and draws nothing. The input slices may be reused after return.
func (*Graphics) NewGradient ¶
func (g *Graphics) NewGradient(stops ...GradientStop) (*Gradient, error)
NewGradient bakes stops into a gradient; stops need not be sorted and a single stop is a flat colour. Give it a direction with Linear or Radial before drawing with it.
func (*Graphics) NewLUT ¶
NewLUT uploads a colour lookup table for PostSettings.LUT: linear filtering, no colour-space conversion.
func (*Graphics) NewMeshShader ¶
NewMeshShader creates a mesh (surface) shader from SPIR-V produced by bunyip-shader -kind mesh from a source that defines fn surface(s: Surface) -> Surface.
func (*Graphics) NewRenderTexture ¶
func (g *Graphics) NewRenderTexture(width, height int) (*RenderTexture, error)
NewRenderTexture creates an offscreen surface in pixels. It has the full 3D pipeline (shadows, bloom, post) but no FXAA pass, matches the window's colour format and samples with linear filtering; NewRenderTextureOptions chooses all of that, multisampling included.
func (*Graphics) NewRenderTextureOptions ¶
func (g *Graphics) NewRenderTextureOptions(width, height int, opts RenderTextureOptions) (*RenderTexture, error)
NewRenderTextureOptions is NewRenderTexture with a choice of sampling, colour format, depth and multisampling.
func (*Graphics) NewSDFFont ¶
NewSDFFont prepares a scalable font. Size is a nominal em size in view units used by DrawText; TextOptions.Size draws at any other size and stays sharp, where a bitmap font would blur. The printable ASCII glyphs every font preloads are rasterised on all cores.
func (*Graphics) NewShader ¶
NewShader creates a sprite (2D) shader from SPIR-V produced by bunyip-shader from a source that defines fn fragment(uv: vec2f, color: vec4f) -> vec4f.
func (*Graphics) NewSkinnedMesh ¶
func (g *Graphics) NewSkinnedMesh(verts []SkinVertex, indices []uint32) (*Mesh, error)
NewSkinnedMesh uploads skinned geometry; draw it with DrawSkinned or through an animated model.
func (*Graphics) NewStaticBatch ¶
func (g *Graphics) NewStaticBatch(items []BatchItem) *StaticBatch
NewStaticBatch builds the hierarchy over a set of draws that never move. Items with no mesh are skipped, and an empty set gives a batch that draws nothing. Building costs one pass over the items per level of the tree, so do it at load rather than every frame.
func (*Graphics) NewTerrain ¶
func (g *Graphics) NewTerrain(opts TerrainOptions) (*Terrain, error)
NewTerrain builds the chunk meshes, the splat texture and the terrain shader from a heightfield. It uploads every chunk at every level at once, so a large terrain costs its whole geometry in device memory: with the default chunk size and four levels that is about a third more than the finest level alone. Layer textures must belong to this Graphics; foreign layers return an error.
func (*Graphics) NewTexture ¶
NewTexture uploads an image without modifying it. Colour pixels are premultiplied in linear light and stored as sRGB, so shaders sample premultiplied linear colour. Data textures skip this colour conversion. Nil sources, empty bounds and unsupported dimensions return an error. During Draw, the upload is recorded before rendering; outside a frame it waits for the GPU.
func (*Graphics) PopClip ¶
func (g *Graphics) PopClip()
PopClip restores the clip rectangle in force before the matching PushClip.
func (*Graphics) PopTransform ¶
func (g *Graphics) PopTransform()
PopTransform restores the transform in force before the matching PushTransform.
func (*Graphics) Project ¶
Project maps a world point to the current 2D view through the queue's camera; see Camera.Project. It only answers while drawing.
func (*Graphics) PushClip ¶
PushClip limits later sprite drawing to a view-space rectangle, intersected with any enclosing clip. Pair with PopClip.
func (*Graphics) PushTransform ¶
PushTransform composes a transform onto the 2D transform stack: later sprites, text and paths are mapped through it (after their own placement, before the camera). Pair with PopTransform.
func (*Graphics) Resources ¶
Resources lists the GPU resources this context has created and not destroyed, oldest first: what a debug view shows to find a leak or a texture nobody meant to load. A font's atlas, a render texture's image and a model's meshes are counted once each, under their own kind. The byte figures are estimates of the images and buffers alone, with no allowance for alignment or driver overhead.
func (*Graphics) ScreenRay ¶
ScreenRay returns the world-space ray under a point in the current 2D view through the queue's camera; see Camera.ScreenRay. It only answers while drawing.
Example ¶
package main
import (
"image"
"github.com/matjam/bunyip/gfx"
"github.com/matjam/bunyip/lin"
)
// The Graphics value comes from engine.Context.Gfx inside a game's Init
// and Draw; these examples show the calls a game makes with it.
var g *gfx.Graphics
func main() {
verts, indices := gfx.SphereMesh(16, 32)
sphere, err := g.NewMesh(verts, indices)
if err != nil {
return
}
defer sphere.Destroy()
world := lin.Translate(lin.V3(0, 1, -5))
ray := g.ScreenRay(400, 300) // the pixel under the mouse
if hit, ok := sphere.Intersect(world, ray); ok {
_ = hit.Point // where the ray met the surface
}
}
Output:
func (*Graphics) ScreenSpace ¶
func (g *Graphics) ScreenSpace()
ScreenSpace returns sprite drawing to view coordinates.
func (*Graphics) SetBlend ¶
SetBlend sets the blend mode for later 2D drawing in the current queue. It is reset to BlendAlpha at the start of each frame.
func (*Graphics) SetCamera2D ¶
SetCamera2D makes later sprite draws world-space under cam. Call ScreenSpace to return to view coordinates for interface drawing. Sprites wholly outside the camera's view are dropped before they reach the vertex stream.
Example ¶
package main
import (
"image"
"github.com/matjam/bunyip/gfx"
"github.com/matjam/bunyip/lin"
)
// The Graphics value comes from engine.Context.Gfx inside a game's Init
// and Draw; these examples show the calls a game makes with it.
var (
g *gfx.Graphics
font *gfx.Font
)
func main() {
// World-space sprites follow the camera; screen-space ones (HUD) do not.
cam := gfx.Camera2D{Position: lin.V2(1000, 500), Zoom: 2}
g.SetCamera2D(cam)
g.FillRect(990, 490, 20, 20, gfx.White) // drawn at the view centre
g.ScreenSpace()
g.DrawText(font, "score 10", 8, 8, gfx.White)
}
Output:
func (*Graphics) SetColorMatrix ¶
func (g *Graphics) SetColorMatrix(m *ColorMatrix)
SetColorMatrix recolours later sprite, text and shape drawing in the current queue through the matrix; nil restores plain colours. It is reset at the start of each frame, and a game's own SetShader takes precedence over it.
func (*Graphics) SetLayer ¶
SetLayer sets the sort layer for later sprite draws. Sprites draw in ascending layer order and, within a layer, by sort key (SetSortKey) and then in submission order. Text and interface drawing typically use a high layer.
func (*Graphics) SetLightProbes ¶
func (g *Graphics) SetLightProbes(grid *LightProbeGrid)
SetLightProbes uses a baked grid for this frame's ambient light, or nil for none. An unbaked grid is ignored.
func (*Graphics) SetLights2D ¶
SetLights2D sets the ambient light and up to eight point lights that DrawLit sprites in the current queue are lit by, for this frame. Lights with Shadows are blocked by the frame's AddOccluder2D occluders. Eight is the limit the lit shader holds: lights past the eighth are dropped and counted in FrameStats.Lights2DDropped, so pass the lights nearest what is drawn first.
func (*Graphics) SetOcclusionSize ¶
SetOcclusionSize sizes the software occlusion buffer in pixels. A larger buffer culls more, because a gap narrower than a pixel counts as covered, and costs more to rasterise into and to test against. Zero restores the default of 256 by 144, and sizes are clamped to 2048.
func (*Graphics) SetPost ¶
func (g *Graphics) SetPost(p PostSettings)
SetPost replaces the global post-processing settings for the screen and every render texture. Queued DrawTo calls use the final settings when the frame submits, so they cannot choose different post effects. A change to Samples takes effect on the next frame, which rebuilds the scene targets.
func (*Graphics) SetShader ¶
SetShader makes later 2D drawing in the current queue use a sprite shader; nil restores the default. It is reset at the start of each frame. A shader from another Graphics panics without changing the current shader.
func (*Graphics) SetSortKey ¶
SetSortKey orders later sprite draws within their layer: draws with a lower key are drawn first, and equal keys keep submission order. A game that sorts by depth sets the key to each sprite's feet, so a character standing lower on the screen draws over one behind it, without ordering its own draw calls. Zero, the default, keeps submission order alone.
func (*Graphics) SetView ¶
SetView sets the 2D coordinate space: (0,0) top-left to (width,height) bottom-right, whatever the framebuffer's pixel size. It panics inside WithView.
func (*Graphics) SetViewport ¶
SetViewport limits the main output to a pixel rectangle: the 2D view maps onto it, the 3D scene renders at its size, and the window outside it stays black. The engine sets it from Config's view size and scaling policy; a zero rect means the whole window. It panics inside WithView.
func (*Graphics) Shaded ¶
Shaded runs draw with the shader set, then restores the original queue's shader, including when draw panics.
func (*Graphics) Stats ¶
func (g *Graphics) Stats() FrameStats
Stats returns the last finished frame's counts.
func (*Graphics) Stenciled ¶
func (g *Graphics) Stenciled(options StencilOptions, draw func())
Stenciled applies advanced stencil controls to 2D drawing, including geometry and flat particles, and restores the previous options on panic. Options are captured per draw, but ordinary layer and sort-key ordering still applies. Use Masked for automatic mask setup and ordering boundaries. Stencil contents persist for the rest of this target's frame. Invalid options or a target without stencil panic before draw is called.
func (*Graphics) StrokeCircle ¶
StrokeCircle outlines a circle with a line width.
func (*Graphics) StrokeLine ¶
StrokeLine draws a line segment with a width and butt caps.
func (*Graphics) StrokePath ¶
func (g *Graphics) StrokePath(p *Path, c Color, opts StrokeOptions)
StrokePath outlines the path with a colour.
func (*Graphics) StrokeRect ¶
StrokeRect outlines a rectangle with a line width.
func (*Graphics) Transformed ¶
Transformed runs draw with the transform pushed, then restores the original queue's transform stack, including when draw panics.
func (*Graphics) WithCamera2D ¶
WithCamera2D runs draw under cam, then restores the original queue's camera or screen-space state, including when draw panics.
func (*Graphics) WithView ¶
WithView draws in a local 2D view, clipped to its viewport and enclosing clips. It inherits the current camera, recalculated for the virtual size; WithCamera2D can select another camera inside. The viewport itself is in enclosing view coordinates and is not moved by a camera or transform.
View geometry is validated before any state changes. The previous view, camera and clips are restored even on panic; queued draws remain queued. This affects sprites, paths, text, geometry and 2D particles, not 3D passes. Use render textures for separately rendered 3D cameras. SetView and SetViewport panic inside the closure; configure the main output outside view scopes. DrawTo may select another target normally.
type HDRImage ¶
HDRImage is a floating-point RGB image: linear radiance, no gamma, values above 1 for bright light sources. DecodeHDR reads one from a Radiance .hdr file and NewEnvironmentHDR lights a scene with it.
func DecodeEXR ¶
DecodeEXR reads an OpenEXR image, as HDR panoramas are often distributed. Half and float channels are read from single-part scanline files that are uncompressed or compressed with RLE, ZIPS or ZIP. The R, G and B channels become the result's radiance; a file with a single Y channel becomes grey. Tiled, deep and multi-part files, and the PIZ, PXR24, B44, B44A, DWAA and DWAB schemes, are refused with an error saying so. Pass the result to NewEnvironmentHDR. The chunks are decoded on up to GOMAXPROCS goroutines.
func DecodeHDR ¶
DecodeHDR reads a Radiance RGBE (.hdr) file, flat or run-length encoded, as most panoramas are distributed.
func DecodePanorama ¶
DecodePanorama reads an equirectangular panorama from encoded bytes, whichever format it is in: an OpenEXR file, a Radiance .hdr file, or any image the program has registered a decoder for, whose sRGB colours are converted to linear radiance. Pass the result to NewEnvironmentHDR. A program that loads PNG or JPEG panoramas must import image/png or image/jpeg for their decoders, as it would for image.Decode.
type Hit ¶
type Hit struct {
Distance float32
Point lin.Vec3
Normal lin.Vec3
Part int // index of the model part, for models
}
Hit describes where a ray met geometry.
type Hyphenator ¶
type Hyphenator struct {
// MinLeft and MinRight are the fewest letters left before and after a
// break; TeX's defaults for English are 2 and 3.
MinLeft, MinRight int
// contains filtered or unexported fields
}
Hyphenator finds the points where a word may break at a line end, by Liang's pattern method as TeX does. Set one on TextOptions.Hyphenate and wrapped text breaks long words with a hyphen instead of leaving ragged gaps.
func EnglishHyphenator ¶
func EnglishHyphenator() *Hyphenator
EnglishHyphenator returns the shared American English hyphenator, built from the standard TeX patterns on first use.
func HyphenatorFor ¶
func HyphenatorFor(lang string) (*Hyphenator, error)
HyphenatorFor returns the shared hyphenator for a BCP 47 language tag, built from the TeX patterns the engine ships on first use. A tag with no patterns of its own falls back to its primary language, so "de-AT" gives the German hyphenator and "en-AU" the American English one; "en-GB" has patterns of its own. Languages the engine ships no patterns for return an error, and the shipped set is listed in gfx/hyph/README.md. The hyphenator is shared, so treat MinLeft and MinRight as read-only.
func NewHyphenator ¶
func NewHyphenator(patterns, exceptions []string) *Hyphenator
NewHyphenator builds a hyphenator from Liang patterns ("hy3ph", ".ab1o") and exception words with their breaks marked ("ta-ble").
func ParseTeXPatterns ¶
func ParseTeXPatterns(src string) *Hyphenator
ParseTeXPatterns reads a TeX hyphenation file: every \patterns{...} block and every \hyphenation{...} block of exceptions. A hyphenmins comment in the file's header, which the hyph-utf8 pattern files carry, sets MinLeft and MinRight from its typesetting values; without one they are TeX's 2 and 3.
func (*Hyphenator) Hyphenate ¶
func (h *Hyphenator) Hyphenate(word string) []int
Hyphenate returns the rune offsets in word where it may break, in order, respecting MinLeft and MinRight.
func (*Hyphenator) SoftHyphens ¶
func (h *Hyphenator) SoftHyphens(text string) string
SoftHyphens returns text with a soft hyphen (U+00AD) at every break point of every word of letters, which is how wrapping is told where a word may split; the marks are invisible unless a line ends on one.
type Image ¶
Image owns editable CPU pixels in straight-alpha NRGBA form. NewImage copies its source, so later edits do not affect that source. The embedded NRGBA and its Pix slice are exposed for standard image/draw operations; subimages share those pixels. The zero value is empty. Methods are not synchronized.
func NewImage ¶
NewImage copies src to owned, zero-based bounds. Nil or empty sources and dimensions whose RGBA storage would overflow return an error.
func (*Image) ColorModel ¶
ColorModel returns color.NRGBAModel, including for the zero value.
func (*Image) CopyFrom ¶
CopyFrom copies the full source at dst using draw.Src, clipped to this image. Source bounds may start anywhere. Overlapping self-copies read original pixels before writing, including when src is a subimage sharing this image's storage.
func (*Image) FlipHorizontal ¶
func (i *Image) FlipHorizontal()
FlipHorizontal reverses each row in place. An empty image is unchanged.
func (*Image) FlipVertical ¶
func (i *Image) FlipVertical()
FlipVertical reverses the row order in place. An empty image is unchanged.
func (*Image) Mask ¶
Mask sets alpha to zero for pixels whose straight RGB exactly matches c. The supplied alpha is ignored; existing RGB values are preserved. Nil colours and empty images have no effect. There is no tolerance or colour-space conversion.
type Impostor ¶
type Impostor struct {
// Size is the quad's width and height in world units. BakeImpostor
// sets it to the model's bounds, and a game may change it.
Size lin.Vec2
// Offset moves the quad in its own plane in units of its size, as
// Billboard.Offset does. BakeImpostor sets it to stand the quad where
// the model stood on the ground.
Offset lin.Vec2
// Distance is the camera distance past which DrawModelImpostor draws
// the impostor rather than the model. Zero means always the impostor.
Distance float32
// Upright turns the quad about the world's up axis only, so it stays
// vertical when the camera looks down on it. BakeImpostor sets it.
Upright bool
// contains filtered or unexported fields
}
Impostor is a model baked into an atlas of views around it, drawn as one camera-facing quad. A tree, a rock or a building far enough away covers a few pixels, and an impostor spends one quad and no vertex work on it where the model would spend thousands of triangles. Bake one with BakeImpostor, draw it with DrawImpostor, or hand both the model and the impostor to DrawModelImpostor and let the distance choose. Every impostor of one model shares its atlas, so a forest of them is one instanced draw.
The bake fixes the lighting into the atlas, and it is lit the same way relative to each view, so an impostor does not turn its shading as the sun moves. Keep them far enough away that this does not read, which is where they belong anyway.
type ImpostorOptions ¶
type ImpostorOptions struct {
// Views is how many directions around the model are baked, evenly
// spaced; zero means 8. More views turn more smoothly and cost atlas
// space. The most is MaxImpostorViews.
Views int
// Resolution is the pixels across one view; zero means 128. The atlas
// is the smallest grid of views that holds them all.
Resolution int
// Pitch is how far above the model each view looks down, in radians;
// zero means 15 degrees. Match it to the camera's usual elevation.
Pitch float32
// Light lights the bake. Pass the light the scene draws under, so the
// impostor matches the model it replaces; its Background, Environment,
// Shadows and Fog are ignored, since the sky must stay out of the
// atlas's transparent parts and the fog is applied again when the
// impostor is drawn. The zero value is a sun over the viewer's left
// shoulder against a pale sky.
Light Light
// Upright is what the drawn quad's Upright becomes; it is on by
// default, which is what a ring of views around a model wants. Set
// FaceCamera to turn it off.
FaceCamera bool
}
ImpostorOptions says how BakeImpostor renders a model.
type LOD ¶
type LOD struct {
Levels []LODLevel
}
LOD is a mesh at several levels of detail: a full model up close, a simpler one at a distance, a few triangles far away and nothing at all beyond. Levels are listed nearest first, each with the distance at which the next takes over; DrawLOD picks by the camera's distance to the model's origin.
type LODLevel ¶
type LODLevel struct {
Mesh *Mesh // nil draws nothing at this level, for things that vanish far away
Distance float32 // used while the camera is closer than this; zero means always
}
LODLevel is one mesh of a LOD and the camera distance up to which it is drawn.
type Light ¶
type Light struct {
Direction lin.Vec3 // direction the light travels
Color Color
Ambient Color // light from every direction when the Sky leaves a colour unset
// Sky is the procedural environment: sky and ground colours around an
// up axis, thinning to space, with a drawn sun and stars.
Sky Sky
Shadows bool // render cascaded shadow maps for the directional light
ShadowDistance float32 // how far from the camera shadows reach; default 60
ShadowStrength float32 // 0..1 how dark shadows are; zero means 1
// Environment lights the scene from every direction with an image:
// reflections in metals, tinted ambient on everything. It replaces
// Ambient and Sky when set.
Environment *Environment
// Background draws the environment, or the Sky, behind the scene.
Background bool
// Fog fades distant geometry into a colour; the zero value is none.
Fog Fog
}
Light is the directional light plus ambient, with optional shadows.
type Light2D ¶
type Light2D struct {
Pos lin.Vec2
Height float32 // zero means 40
Radius float32 // zero means 300
Color Color // zero means white
// Shadows makes the occluders added with AddOccluder2D block this
// light, so a wall between it and a sprite darkens the sprite. It
// costs one polar shadow map a frame, built on the CPU.
Shadows bool
// Softness is the width of the shadow's soft edge in view units at
// the shadowed point; zero means 8. It has no effect without
// Shadows.
Softness float32
}
Light2D is a point light for lit sprites: a position in the same units as sprites, a height above their plane and a radius where it fades out.
type LightProbeGrid ¶
type LightProbeGrid struct {
// Origin is the world position of cell (0, 0, 0).
Origin lin.Vec3
// Spacing is the distance between neighbouring cells on each axis;
// a zero component means 1.
Spacing lin.Vec3
// Counts is how many cells the grid has along x, y and z. Each is at
// least 1, and their product is at most 4096.
Counts [3]int
// Resolution is the cube face size each cell is rendered at before it
// is projected onto harmonics; zero means 16. The harmonics keep only
// the low frequencies, so small is enough.
Resolution int
// Intensity multiplies the grid's light; zero means 1.
Intensity float32
// contains filtered or unexported fields
}
LightProbeGrid is the diffuse light of a scene sampled on a lattice of points: the red bounce along a red wall, the dark under a bridge, the warm glow near a fire. Each cell holds the irradiance around it as nine spherical harmonics, baked from the scene by BakeLightProbes and uploaded once a frame by SetLightProbes. Where the grid covers a fragment it replaces the single environment ambient, blended between the eight cells around the point; outside the grid the environment or sky ambient stands.
A grid lights the diffuse term. Reflections come from the light's Environment, the Sky or a ReflectionProbe.
func (*LightProbeGrid) Baked ¶
func (grid *LightProbeGrid) Baked() bool
Baked reports whether the grid holds harmonics yet.
type Material ¶
type Material struct {
Texture *Texture // albedo, sRGB
BaseColor Color // multiplies the albedo; zero means white
Metallic float32 // 0 dielectric .. 1 metal; with a texture, a factor (0 means 1)
Roughness float32 // 0.04 .. 1; zero means 0.6
MetalRoughTexture *Texture // glTF layout: G roughness, B metallic; data, not colour
NormalTexture *Texture // tangent-space normal map; data, not colour
EmissiveTexture *Texture // sRGB, scaled by Emissive
Emissive float32 // glow strength; without a texture the mesh glows in its base colour
// OcclusionTexture darkens ambient light by its red channel, for baked
// crevice shadows; OcclusionStrength scales it (zero means 1).
OcclusionTexture *Texture
OcclusionStrength float32
// AlphaCutoff discards fragments whose alpha is below it, in both the
// lit and shadow passes: leaves, fences, decals with hard edges. Zero
// means no cutout.
AlphaCutoff float32
// Blend draws after opaque geometry, back to front or through the
// order-independent transparency pass. BaseColor alpha, multiplied by
// texture and vertex alpha, fades the entire shaded surface, including
// lighting, emissive and fog. Pass straight colors; the engine
// premultiplies the result before blending. Without Blend or
// Transmission, alpha only controls AlphaCutoff.
Blend bool
DoubleSided bool // no back-face culling; back faces are lit with a flipped normal
Unlit bool // the base colour and emissive as they are, ignoring lights
NoDepthTest bool // draw over everything already drawn: overlays, highlights through walls
NoDepthWrite bool // leave the depth buffer alone: ghosts, additive effects
// UVTransform maps texture coordinates before sampling the material's
// textures: scrolling, tiling, rotation. Zero means identity.
UVTransform lin.Affine
// OcclusionUV2 samples the occlusion map with the vertices' second
// texture coordinates, the lightmap convention.
OcclusionUV2 bool
// Clearcoat adds a glossy varnish layer of that strength (0..1) with
// its own roughness: car paint, lacquer, wet surfaces.
Clearcoat float32
ClearcoatRoughness float32
// Sheen adds soft back-scattered light at grazing angles in that colour,
// the look of velvet and cloth; zero means none.
Sheen Color
SheenRoughness float32 // zero means 0.5
// Subsurface (0..1) lets light through thin parts, tinted by the base
// colour: leaves, wax, skin. ThicknessTexture (red channel, 1 = thick)
// shapes it; nil is uniformly thin.
Subsurface float32
ThicknessTexture *Texture
// Transmission (0..1) is how much light passes through the surface:
// glass, water, ice. The scene behind shows through, refracted by IOR
// (zero means 1.5) across Thickness world units of material, blurred
// by the roughness and tinted by the base colour. AttenuationColor is
// what white light becomes after AttenuationDistance units inside the
// volume; a zero distance means no absorption. ThicknessTexture scales
// Thickness; with a Thickness and no map the mesh is uniformly thick.
// Transmissive meshes draw after the opaque ones, like Blend.
Transmission float32
IOR float32
Thickness float32
AttenuationColor Color
AttenuationDistance float32
// TransmissionTexture scales Transmission by its red channel, so a
// window frame can be opaque and its panes glass in one material;
// nil is the factor everywhere. Data, not colour.
TransmissionTexture *Texture
// Specular scales a dielectric's reflection and SpecularColor tints
// it, the KHR_materials_specular extension: zero means 1 and white,
// the plain material. A small Specular such as 0.01 all but removes
// the reflection, for chalk and unglazed clay. SpecularTexture
// carries the tint in its RGB and the strength in its alpha. Metals
// keep their own reflection, which is their base colour.
Specular float32
SpecularColor Color
SpecularTexture *Texture
// Iridescence (0..1) puts a thin film over the surface, whose
// interference shifts the reflection's hue with the viewing angle:
// soap bubbles, oil on water, beetle shells, tempered steel.
// IridescenceIOR is the film's index of refraction (zero means 1.3)
// and IridescenceThickness how thick it is in nanometres (zero means
// 400, and 100 to 800 is the range that shows colour).
// IridescenceTexture scales the strength by its red channel and mixes
// the thickness from IridescenceThicknessMin to IridescenceThickness
// by its green channel, the two maps glTF packs into one image.
Iridescence float32
IridescenceIOR float32
IridescenceThickness float32
IridescenceThicknessMin float32
IridescenceTexture *Texture
// Anisotropy (-1..1) stretches the specular highlight along the
// surface rather than leaving it round: brushed metal, hair, satin,
// vinyl records. AnisotropyRotation turns the direction it stretches
// in, in radians, and AnisotropyTexture holds a direction of its own
// in red and green (around a half, as glTF stores it) and a strength
// in blue. The direction comes from the mesh's texture coordinates,
// so an anisotropic mesh needs UVs but no tangents of its own.
Anisotropy float32
AnisotropyRotation float32
AnisotropyTexture *Texture
// Shells draws the mesh that many more times, each a little further
// out along its normals, for fur, grass, moss and hair; zero means
// none and eight to twenty-four look like fur. ShellLength is how far
// the outermost shell stands off in world units (zero means 0.05).
// FurTexture is the strand mask: a shell keeps a fragment where the
// map's red channel is above that shell's height, so a tiled noise
// image gives strands, and the material's UVTransform tiles it.
// Without a map the shells are solid and only fade outwards. Shells
// draw after the opaque scene, leave the depth buffer alone and cast
// no shadow, and each one costs an instance of the mesh.
Shells int
ShellLength float32
FurTexture *Texture
// Stencil masks the material against the stencil buffer: it draws only
// where the value already there compares to StencilRef the way the
// test says. StencilAlways, the zero value, draws everywhere.
// StencilWrite is what a drawn fragment stores, StencilKeep leaving
// the buffer alone. One material marks a shape with StencilReplace
// and another draws only inside it with StencilEqual: portals,
// cutaways, magic windows. The buffer starts each frame at zero, and
// materials that write it draw before those that do not, whatever
// order they were queued in. A material with an Outline uses the
// stencil buffer for the outline itself and ignores these three.
Stencil StencilTest
StencilRef uint8
StencilWrite StencilOp
// Outline draws a line of that many pixels around the mesh's
// silhouette in OutlineColor (zero means black): selection rings,
// cartoon edges. It needs a depth format with stencil, which every
// desktop GPU has.
Outline float32
OutlineColor Color
// XRay tints the parts of the mesh hidden behind other geometry, so a
// unit shows through walls; zero means none.
XRay Color
// Shader is a mesh shader from NewMeshShader that adjusts the surface
// before lighting; nil is the standard material.
Shader *Shader
}
Material is how a mesh is shaded, in the metallic-roughness model. Every texture is optional: nil albedo is white, nil metal-rough is the factors alone, nil normal map is the geometric normal, nil emissive is black.
type MaterialOverride ¶
MaterialOverride returns the material to draw one part of a model with. i is the part's index in Model.Parts and part is the part itself, so a game can decide by index or by part.Name, the name glTF gave the material. Returning part.Material draws what the file asked for.
type Mesh ¶
type Mesh struct {
IndexCount uint32
Min, Max lin.Vec3 // axis-aligned bounds in mesh space
// contains filtered or unexported fields
}
Mesh is indexed triangle geometry in device memory. Build one from vertices with NewMesh, from the shapes in this package (CubeMesh, SphereMesh, PlaneMesh, HeightfieldMesh and the rest), or by loading a glTF Model. Meshes that change, such as voxel chunks and procedural terrain, take new geometry through Update.
func (*Mesh) Bounds ¶
Bounds returns the mesh's axis-aligned bounds in mesh space, the box culling and picking test. They come from the vertices unless SetBounds replaced them.
func (*Mesh) Destroy ¶
func (m *Mesh) Destroy()
Destroy frees the mesh. Called inside a frame it costs no wait: the buffers go on the frame slot's retire list and are freed once that frame has finished, so draws already queued this frame still draw.
func (*Mesh) Indices ¶
Indices returns the mesh's triangle indices, three per triangle; the slice is the mesh's own and must not be modified. Copy it to retain a snapshot across Update.
func (*Mesh) Intersect ¶
Intersect tests the ray against a mesh under a model matrix, first by bounding box and then triangle by triangle, returning the nearest hit.
func (*Mesh) SetBounds ¶
SetBounds replaces the bounds culling tests the mesh against, for a mesh whose drawn shape leaves its vertices: a material shader that displaces vertices, or an animation that swings a limb outside the geometry as uploaded. Give the box the drawn shape stays inside, in mesh space. The bounds hold until the next SetBounds; Update and UpdateSkinned leave them alone. A mesh that has never been given bounds uses the box its vertices fill, and a skinned one the boxes of its joints under the pose.
func (*Mesh) Update ¶
Update replaces the mesh's geometry: a voxel chunk after a block is broken, terrain after an edit, a procedural mesh that grows. Draws already queued this frame keep the old geometry, which is freed once the frame is done, so Update is safe at any point of a frame. Skinned meshes cannot be updated.
func (*Mesh) UpdateSkinned ¶
func (m *Mesh) UpdateSkinned(verts []SkinVertex, indices []uint32) error
UpdateSkinned replaces a skinned mesh's geometry, as Update does for a plain mesh: draws already queued this frame keep the old geometry. It is what morph targets on a skinned model go through.
type Model ¶
Model is a glTF document uploaded to the GPU: one Mesh per primitive, one Texture per image, and the placements to draw.
func (*Model) ClipDuration ¶
ClipDuration returns a clip's length in seconds; unknown names give 0.
func (*Model) Destroy ¶
func (m *Model) Destroy()
Destroy frees the model's meshes, textures and morph targets after queued and submitted draws have finished using them.
func (*Model) MaskNodes ¶
MaskNodes makes a mask of exactly the named nodes; unknown names are ignored.
func (*Model) MaskSubtree ¶
MaskSubtree makes a mask of the named nodes and everything under them: "Spine1" for the upper body, "Head" for the head and its children.
func (*Model) MorphTargets ¶
MorphTargets names the morph targets of the node's mesh, blank where the file names none; nil when the node has no morph targets.
func (*Model) MorphWeights ¶
MorphWeights returns the morph target weights the node's mesh is drawn with, whether they blend in the vertex shader or on the processor; nil when the node has no morph targets. The slice is the model's own.
func (*Model) NewAnimPlayer ¶
func (m *Model) NewAnimPlayer() *AnimPlayer
NewAnimPlayer makes a player for the model in its rest pose.
func (*Model) NodeMatrix ¶
NodeMatrix returns a node's rest-pose world matrix in model space, for a socket on a model that is not animated: a lamp's bulb, a turret's muzzle. An animated model's current pose comes from AnimPlayer.NodeMatrix. An unknown index gives the identity.
func (*Model) NodeParent ¶
NodeParent returns a node's parent index, or -1 for a root.
func (*Model) NodePosition ¶
NodePosition returns a node's rest-pose position in model space.
func (*Model) SetMorphWeights ¶
SetMorphWeights blends the node's morph targets by the weights (one per target, 0 for none and 1 for the full shape) and uploads the result: a facial expression, a wind-bent plant. A player's weights channels do the same through DrawModelAnimated. Up to MaxGPUMorphTargets open at once blend in the vertex shader and cost nothing to change; past that the blend runs here, one pass over the mesh's vertices per open target plus an upload, each time the weights change. DrawModel captures the current weights and geometry, so later changes do not affect instances already queued.
type ModelPart ¶
type ModelPart struct {
Mesh *Mesh
// Name is the name glTF gave the primitive's material, empty when the
// file names none. Match on it to override one part's material.
Name string
Material Material
World lin.Mat4
// contains filtered or unexported fields
}
ModelPart is one primitive placed by one node.
type NineSlice ¶
type NineSlice struct {
Tex *Texture
Left, Top, Right, Bottom float32
// Tile repeats the edge and centre pieces at their own size instead
// of stretching them, for patterned borders and textured fills.
Tile bool
}
NineSlice is a texture drawn stretched to any size while its corners keep their size and its edges stretch along one axis: panels, buttons and speech bubbles from one small image. The borders are in texture pixels.
type ParticleQuad ¶
type ParticleQuad struct {
// Pos is the quad's centre: view units for DrawParticles, world
// units for DrawParticles3D, whose Z is ignored in 2D.
Pos lin.Vec3
// Rotation turns the quad about its centre, in radians. In 3D it
// turns about the axis facing the camera.
Rotation float32
// Size is the width and height. Zero draws nothing.
Size lin.Vec2
// UV0 and UV1 are the texture's top-left and bottom-right corners,
// so one atlas serves a whole effect. Both zero shows the top-left
// texel alone; use Region.UV0 and Region.UV1, or (0,0) and (1,1).
UV0, UV1 lin.Vec2
// Color tints the texture. Zero is transparent, not white, because
// this is a raw GPU record rather than an options struct.
Color Color
}
ParticleQuad is one particle handed to the instanced draw path: where it is, how big it is, which part of the texture it shows and what colour it is tinted. DrawParticles and DrawParticles3D take a whole slice of them and draw it as one instanced call, so hundreds of thousands cost one draw rather than one draw each.
The struct is the GPU's instance layout, so a slice of them uploads without being converted or copied field by field. Keep it that way: the particle package fills a slice of these directly. Color is straight alpha, not premultiplied, and the shader premultiplies it.
type Particles3D ¶
type Particles3D struct {
// Blend combines the particles with the scene. Zero is alpha
// blending; BlendAdd suits fire, sparks and magic.
Blend Blend
// Soft fades a particle out over this many world units as it
// approaches the geometry behind it, which hides the hard line a
// quad otherwise cuts where it meets the ground. Zero is a hard
// edge. One or two units suits smoke.
Soft float32
}
Particles3D is how a batch of 3D particles is drawn.
type Path ¶
type Path struct {
// contains filtered or unexported fields
}
Path is a sequence of lines and curves in view units, built by chaining calls: MoveTo starts a sub-path, the others extend it, Close joins it back to its start. A path can be filled, stroked, or both, as many times as you like; it holds no GPU state.
func (*Path) Arc ¶
Arc adds an arc of a circle centred at (cx, cy) with radius r, from angle start sweeping by sweep radians (positive turns the way angles increase: clockwise on a y-down screen). It joins the current point to the arc's start with a line when the sub-path is open.
func (*Path) ArcTo ¶
ArcTo adds an arc of radius r tangent to the lines from the current point to (x1, y1) and from there to (x2, y2), as a rounded corner.
func (*Path) Bounds ¶
Bounds returns the tight axis-aligned bounds of the path's lines and Bézier curves, including isolated MoveTo points. It excludes stroke width, antialiasing and graphics transforms. An empty path returns a zero Rect. Arcs and ellipses are bounded as the cubic curves stored by Path.
type PathOptions ¶
type PathOptions struct {
Fill *FillOptions
Stroke *StrokeOptions
FillColor, StrokeColor Color
// PixelsPerUnit chooses curve precision and antialias fringe width.
// Zero means 1. Choose the expected framebuffer pixels per local path
// unit, including camera zoom and scale. Recompile when a substantially
// different density is needed; drawing never tessellates the path again.
PixelsPerUnit float32
}
PathOptions selects the paints baked into a CompiledPath. The zero value fills white. When either Fill or Stroke is non-nil, only the non-nil paints are used; Fill precedes Stroke. Zero colours mean white. To make a paint transparent, use a nonzero colour with A=0, or omit that paint.
type PointLight ¶
type PointLight struct {
Position lin.Vec3
Color Color
Range float32 // fades to nothing this far away
Shadows bool // render a cube shadow map for this light
}
PointLight is a light shining from a point in every direction for AddPoint, with the option of a shadow map: a lamp in a room, a fire under a bridge. The first four shadowed point lights a frame get cube maps (MaxPointShadows), the rest shine without; add the nearest first.
type PostSettings ¶
type PostSettings struct {
Exposure float32 // scene multiplier before tone mapping; default 1
Bloom float32 // bloom strength; default 0.25, 0 disables the passes
BloomThreshold float32 // luminance where bloom starts; default 1
Vignette float32 // 0..1 edge darkening; default 0
Saturation float32 // default 1
Contrast float32 // default 1
NoAntiAlias bool // skip the FXAA pass on the main frame
// Samples multisamples the 3D scene pass: 1 (the default), 2, 4 or 8,
// clamped to what the GPU supports. Every triangle edge is then
// resolved from that many coverage samples, which is the one form of
// anti-aliasing that does not blur the picture, at the cost of that
// many times the scene's colour and depth memory and bandwidth. Set
// NoAntiAlias with it: FXAA over an already resolved image only
// softens it. TemporalAA already resolves the edges and turns FXAA off
// by itself, so leave this at 1 when that is on. Changing it rebuilds
// the scene targets and the pipelines that draw into them, on the next
// frame.
Samples int
// AmbientOcclusion is the strength of screen-space ambient occlusion,
// 0 (off) to 1; default 0.6. It darkens creases and contact points.
AmbientOcclusion float32
// OcclusionRadius is the occlusion kernel size in world units; default 1.
OcclusionRadius float32
// ShowOcclusion displays the occlusion buffer instead of the scene, for tuning.
ShowOcclusion bool
// OrderIndependent composites blended materials without sorting them.
// Each pixel's translucent fragments accumulate with a weight that
// favours the nearest, and one pass resolves them, so meshes that
// intersect or overlap themselves no longer pick a single order for
// the whole draw (weighted blended order-independent transparency,
// McGuire and Bavoil). It costs two more images the size of the frame
// and one pass. Zero keeps the sorted path, and transmissive
// materials stay on it either way, because they read the scene behind
// them and so must draw in order.
OrderIndependent bool
// Reflections is the strength of screen-space reflections, 0 (off, the
// default) to 1. A smooth surface mirrors what the screen already
// shows: a polished floor under a bright object, a wet road under a
// sign. Where a ray leaves the screen or hits nothing the surface
// keeps its environment or probe reflection.
Reflections float32
// ReflectionRoughness is the roughness a surface stops reflecting the
// screen at, fading out over the half of the range below it; zero
// means 0.35.
ReflectionRoughness float32
// ReflectionDistance is how far a reflection ray travels in world
// units; zero means 30.
ReflectionDistance float32
// ReflectionSteps is the most samples a reflection ray takes along the
// way; zero means 32. A ray that crosses fewer half-resolution pixels
// on screen takes one a pixel. More is sharper and slower.
ReflectionSteps int
// LUT grades the final colours through a lookup table: a strip of n
// slices of n by n, n by n squared pixels wide, as NeutralLUT lays it
// out and image editors export it after grading a screenshot. Load it
// with NewLUT; nil grades nothing. LUTStrength blends towards the
// graded colour; zero means 1.
LUT *Texture
LUTStrength float32
// TemporalAA averages each frame with the ones before it, jittering
// the projection by a fraction of a pixel so the average fills in the
// steps along an edge. It replaces FXAA on the main frame while it is
// on; default off. Moving meshes need DrawMeshMoved and its
// companions, or they smear until the neighbourhood clamp catches up.
// Motion vectors are written by the opaque meshes the camera sees, so
// a moving blended or transmissive mesh reprojects as if it were
// still whatever it was drawn with.
TemporalAA bool
// TemporalBlend is how much of the new frame goes into the average,
// 0.02 to 1; zero means 0.1. Lower is steadier and softer.
TemporalBlend float32
// FocusDistance is how far in front of the camera the image is sharp,
// in world units; zero turns depth of field off. FocusRange is how
// far either side of it stays sharp before the blur grows, and how
// far past that the blur reaches its full width; zero means a quarter
// of FocusDistance. BokehRadius is that full width in pixels (zero
// means 12) and BokehSamples how many taps the disc takes (zero means
// 16).
FocusDistance float32
FocusRange float32
BokehRadius float32
BokehSamples int
// MotionBlur smears each pixel back along the way it moved since the
// last frame, 0 (off) to 1; default 0. MotionSamples is how many taps
// it takes along that path; zero means 8. The camera's motion is read
// from depth, an object's from the velocity buffer, so a moving mesh
// needs DrawMeshMoved to blur along its own path.
MotionBlur float32
MotionSamples int
// Aberration splits the red and blue channels apart towards the edge
// of the frame, as a cheap lens does; zero means off, 1 is about three
// pixels at the edge of a 1080-wide frame and 0.5 is a subtle fringe.
Aberration float32
// Distortion bends the image about the centre: positive is barrel,
// negative pincushion; zero means off.
Distortion float32
// Ghosts draws the bright pass mirrored through the centre a few
// times over, the reflections a lens makes of a bright light; zero
// means off. It reads the bloom image, so it needs Bloom above zero.
Ghosts float32
// Grain adds per-pixel noise that moves each frame, as film does;
// zero means off, 0.05 is subtle.
Grain float32
// GodRays is the strength of the shafts of light the directional
// light throws past an occluder; zero means off. GodRayDecay is how
// fast a shaft fades along its length (zero means 0.96),
// GodRayDensity how far towards the sun each pixel walks (zero means
// 0.6) and GodRaySamples how many steps it takes (zero means 32).
// The pass is skipped when the sun is behind the camera.
GodRays float32
GodRayDecay float32
GodRayDensity float32
GodRaySamples int
// Post2D runs the composite on a frame that has no 3D draws at all,
// so bloom, the grade, the LUT, the lens effects and FXAA reach a 2D
// game. Zero keeps the direct path, which draws the 2D stream
// straight to the screen and costs nothing. Exposure and tone mapping
// are skipped in this mode, so a 2D game with no other setting on
// gets back the colours it drew; the effects that need depth
// (ambient occlusion, depth of field, motion blur, temporal
// anti-aliasing, god rays) stay off. It applies to the screen and not
// to a render texture, whose alpha the composite would flatten.
Post2D bool
}
PostSettings controls the post-processing applied to 3D scenes.
type ReflectionProbe ¶
type ReflectionProbe struct {
// Position is where the cube map is captured, in world units. It is
// also the centre a box projection reflects around, so put it where a
// viewer looks from rather than in a wall.
Position lin.Vec3
// Extent is the half-size of the box the probe covers. A zero Extent
// with a positive Radius makes a sphere probe instead. A probe with
// neither covers nothing and is ignored.
Extent lin.Vec3
// Radius is the sphere probe's radius in world units; zero means the
// probe is a box.
Radius float32
// Margin is how far inside the volume's edge the probe fades towards
// the frame's own environment, in world units; zero means it does not
// fade and the reflection changes at the boundary.
Margin float32
// Resolution is the cube face size in texels the bake renders and
// prefilters; zero means 64. Larger is sharper in a mirror and slower
// to bake.
Resolution int
// Intensity multiplies the probe's light; zero means 1.
Intensity float32
// BoxProjection reflects the box's walls at the place the ray meets
// them rather than at infinity, so a floor mirrors the wall it faces.
// It applies to box probes and is ignored by a sphere probe, which
// always projects onto its sphere.
BoxProjection bool
// contains filtered or unexported fields
}
ReflectionProbe is the environment of one part of a scene, captured from a point and reflected by the surfaces inside its volume: a red room that reddens the chrome in it, a cave that stays dark under a bright sky. Fill in the position and the volume, bake it once with BakeProbe, and add it to each frame with AddProbe. Draws whose centre falls inside the volume reflect the probe instead of the light's Environment or Sky; everything outside every probe keeps those.
A probe changes reflections, not the diffuse ambient light, which comes from the light's environment or a LightProbeGrid.
func (*ReflectionProbe) Destroy ¶
func (p *ReflectionProbe) Destroy()
Destroy frees the probe's cube map. Baking again destroys the previous one on its own, so this is for a probe a game is finished with.
func (*ReflectionProbe) Environment ¶
func (p *ReflectionProbe) Environment() *Environment
Environment returns the probe's baked environment, or nil before the first BakeProbe. It is the same form NewEnvironment builds, so it can be set as Light.Environment to light a whole scene from a probe.
type Region ¶
Region is a rectangle of a texture, the piece an atlas or a sheet frame refers to. DrawRegion draws it; Sheet.Region and NewRegion make them.
type RegionAnimation ¶
type RegionAnimation struct {
Frames []Region
Durations []float32 // seconds per frame; a zero duration means 0.1
Loop bool
}
RegionAnimation is a tag's frames with the timing the atlas gave each one, for playing an Aseprite animation as authored. Build one with Atlas.Animation and read the frame to draw with At.
func (RegionAnimation) At ¶
func (r RegionAnimation) At(t float64) (Region, bool)
At returns the frame showing at a time from the start, and whether the animation has ended (never, for one that loops). An animation with no frames returns an empty region and done.
func (RegionAnimation) Length ¶
func (r RegionAnimation) Length() float64
Length is the animation's total time in seconds.
type RenderTexture ¶
type RenderTexture struct {
Width, Height int
// contains filtered or unexported fields
}
RenderTexture is an offscreen surface that draws like the screen and is then used like a texture: minimaps, portraits, mirrors, picture-in-picture.
func (*RenderTexture) Destroy ¶
func (rt *RenderTexture) Destroy()
Destroy frees the surface. Called inside a frame it costs no wait: everything it owns goes on the frame slot's retire list and is freed once that frame has finished.
func (*RenderTexture) Read ¶
func (rt *RenderTexture) Read() (*image.RGBA, error)
Read copies the last rendered image back from the GPU, after waiting for it to finish: thumbnails, saved portraits, tests. Whatever the surface's colour format, the result is an ordinary image: a ColorHDR surface is encoded the way the screen is, so values above 1 clip, and a ColorMask surface reads as grey, its one channel copied into red, green and blue alike. Colours follow Go's sRGB-premultiplied alpha convention. Calls during an active frame return an error; its queued draws have not been submitted yet.
func (*RenderTexture) ReadDepth ¶
func (rt *RenderTexture) ReadDepth() ([]float32, error)
ReadDepth copies the depth the last 3D scene drawn into this texture left behind, one float per pixel, row-major from the top-left corner: 0 at the near plane and 1 at the far plane, in the non-linear distribution a perspective projection produces. It is the depth the engine's own ambient occlusion and decals read, resolved to one sample per pixel when the scene is multisampled.
It waits for the GPU and copies the whole image back to the host, so it is for tools, tests and one-off queries rather than for every frame. Read only after a completed 3D render; no previous depth content is guaranteed before that. Active frames and missing or destroyed scene targets return an error.
func (*RenderTexture) SetView ¶
func (rt *RenderTexture) SetView(width, height float32)
SetView sets the render texture's 2D coordinate space; default is pixels.
func (*RenderTexture) Texture ¶
func (rt *RenderTexture) Texture() *Texture
Texture returns the surface for drawing as a sprite or material. RenderTexture owns it; destroy the RenderTexture rather than this view.
type RenderTextureOptions ¶
type RenderTextureOptions struct {
// Nearest keeps a low-resolution scene's pixels sharp when it is
// scaled up (a pixel-art game rendering at 320 by 180).
Nearest bool
// Repeat tiles the texture instead of clamping at its edges.
Repeat bool
// Format is the colour format; the default matches the window.
Format ColorFormat
// NoDepth leaves out the depth buffer of the surface's own pass, which
// nothing tests against: the 3D scene has its own depth buffer and
// composites through it, and 2D drawing never uses one. Set it to save
// the memory on a target that is only ever drawn to.
NoDepth bool
// Samples multisamples the surface itself: 1 (the default), 2, 4 or 8,
// clamped to what the GPU supports and reported by Graphics.MaxSamples.
// Every edge drawn into it, including 2D paths and triangles, is
// resolved from that many coverage samples. It is separate from
// PostSettings.Samples, which multisamples the 3D scene behind the
// composite, here as on screen.
Samples int
}
RenderTextureOptions says how a render texture is made and how it samples when it is drawn.
type Resource ¶
type Resource struct {
Kind ResourceKind
// Width and Height are texels, for textures, render textures, font
// atlases and an environment's cube face.
Width, Height int
// Vertices and Indices are a mesh's counts.
Vertices, Indices int
// Parts is a model's primitive count.
Parts int
// Bytes is an estimate of the GPU memory the resource holds. It
// counts the images and buffers the resource owns, so a model reads
// as zero: its meshes and textures are listed on their own.
Bytes int
}
Resource describes one live GPU resource: what it is, how big it is and roughly how much GPU memory it holds. Only the fields that suit the kind are filled in.
type ResourceKind ¶
type ResourceKind uint8
ResourceKind names one kind of GPU resource in a Resources snapshot.
const ( ResourceTexture ResourceKind = iota ResourceMesh ResourceModel ResourceFont ResourceRenderTexture ResourceEnvironment ResourceGeometry2D )
func (ResourceKind) String ¶
func (k ResourceKind) String() string
String names the kind in lower case, for a debug listing.
type RichFonts ¶
type RichFonts struct {
Regular, Bold, Italic, BoldItalic *Font
}
RichFonts are the faces rich text draws with; a nil variant falls back to Regular, so plain text needs only that.
func (RichFonts) Layout ¶
func (rf RichFonts) Layout(text RichText, opts TextOptions) (*TextLayout, error)
Layout constructs the same reusable result as Font.Layout, preserving styles and links. Text indices address RichText.Plain, never markup tags. Regular is required; missing style faces fall back to it. Fonts must be live and belong to the same Graphics. The result borrows their atlases. A layout of the same runs and options made recently is returned from the regular font's cache; finding it hashes the runs, so keep the returned layout and draw it with DrawTextLayout to skip even that.
func (RichFonts) MeasureRich ¶
func (rf RichFonts) MeasureRich(rt RichText, opts TextOptions) (w, h float32)
MeasureRich returns logical text dimensions using the same Unicode shaping and wrapping as Layout, without rasterizing or uploading glyphs. It returns zero for missing fonts or invalid options; Layout reports those errors.
type RichLink ¶
RichLink is where a link was drawn, for hit-testing clicks; a link that wraps reports one rectangle per line.
type RichRun ¶
type RichRun struct {
Text string
Color Color // zero means the block's colour
Bold bool
Italic bool
Underline bool
Strikethrough bool
OutlineWidth float32 // zero inherits TextOptions.OutlineWidth
OutlineColor Color // zero inherits the block's outline colour
Link string // a name reported back with its rectangle
}
RichRun is a stretch of text in one style: a colour, a bold or italic face, decorations, an outline, or a link a click can hit. A shaping cluster crossing a style boundary takes all styles from its first source byte; combining sequences and ligatures are never split by a colour or link change.
type RichText ¶
type RichText struct {
Runs []RichRun
}
RichText is styled text made of runs, from ParseRich or by hand.
type Shader ¶
type Shader struct {
// VertexBounds is how far a mesh shader's vertex program moves a
// vertex, as a multiple of the mesh's bounding radius: 0.25 for a flag
// that ripples a quarter of its own size. Culling grows a draw's
// radius by 1 + VertexBounds. Zero means the program may put a vertex
// anywhere, so draws made with the shader are never culled; set it as
// soon as the displacement has a limit. This applies only to shaders
// with a vertex hook. It is read when the frame prepares its queued
// draws, so the final value applies to every draw using this shader.
VertexBounds float32
// contains filtered or unexported fields
}
Shader is a fragment program the game wrote, compiled to SPIR-V with bunyip-shader or Compiler. A sprite shader colours 2D drawing; a mesh shader adjusts a surface before the engine lights it. Uniforms and up to four extra images ride along with every draw made while it is set.
func (*Shader) Destroy ¶
func (s *Shader) Destroy()
Destroy frees the shader's pipelines. Called inside a frame it costs no wait: they go on the frame slot's retire list and are freed once that frame has finished.
func (*Shader) Reload ¶
Reload replaces the shader's program with newly compiled SPIR-V from bunyip-shader, rebuilding its pipelines, so a game watching its shader files (asset.Watcher) can swap them while it runs. Images and uniforms are kept. The old pipelines are freed once the frame that may still be drawing with them has finished.
func (*Shader) ReloadSource ¶
ReloadSource compiles WGSL for this shader's existing kind, then replaces its GPU programs. Compilation or pipeline creation errors preserve the old shader. Uniforms and images are retained. Call on the game goroutine; this method compiles in Go and blocks until compilation finishes. For background compilation, compile through shaders.Compiler and call Reload with the resulting bytes on the game goroutine. Cancellation is checked between compilation phases, not during a phase or GPU pipeline creation.
func (*Shader) SetImage ¶
SetImage binds a texture as image0..image3 for draws from now on; nil unbinds it (the shader then samples white). A texture from another Graphics panics without changing the binding.
func (*Shader) SetUniforms ¶
SetUniforms packs a struct or non-nil pointer to one into a std140 block for subsequent draws. Fields follow declaration order and must be exported. Supported values are float32, int32, uint32, bool (including named scalar types), lin.Vec2/Vec3/Vec4, Color, lin.Mat3/Mat4, fixed arrays and nested structs. Matrices are column-major. A plain [N]float32 is a scalar array, with 16-byte strides; use lin vector/matrix types for WGSL vectors/matrices. Booleans map to WGSL u32 fields (0 or 1). WGSL scalar arrays need padded element wrappers to match the 16-byte std140 stride. Padding is automatic and zeroed. No Go memory is retained. Unsupported fields or blocks exceeding 1024 packed bytes return errors and preserve the previous block. The caller must match the shader's declarations; this does not inspect SPIR-V or perform numeric precision conversions.
type Sheet ¶
type Sheet struct {
Texture *Texture
FrameW int
FrameH int
Columns, Rows int
Margin int // pixels around the whole grid
Spacing int // pixels between frames
}
Sheet cuts a texture into a grid of equal frames, numbered row-major from the top-left, for tilesets and sprite sheets.
type SkinVertex ¶
type SkinVertex struct {
Pos lin.Vec3
Normal lin.Vec3
UV lin.Vec2
UV2 lin.Vec2
Color Color // zero means white
Joints [4]uint8
Weights [4]float32
}
SkinVertex is a Vertex with up to four joint influences.
type Sky ¶
type Sky struct {
// Space is a distant image environment behind the procedural sky. Its
// radiance is attenuated by the atmosphere and adds to diffuse lighting
// and reflections. Light.Environment, when set, takes precedence.
Space *Environment
Up lin.Vec3 // away from the ground, or from the planet below a ship; zero means +Y
Zenith Color // the sky straight up, in full atmosphere; zero means Horizon
Horizon Color // the sky at the horizon; zero means Zenith, or the light's Ambient
Ground Color // light from below: terrain, sea, the face of a planet; zero means Ambient
// Vacuum thins the air: 0 is a full sky, 1 is space, where the sky is
// black and the stars come out while the ground half stays.
Vacuum float32
Sun Color // radiance of the drawn sun disc; zero means thirty times the light's colour
SunSize float32 // the disc's angular radius in radians; zero means 0.0047, the Sun seen from Earth
Stars float32 // brightness of a starfield showing through thin air; zero means none
// Atmosphere replaces Zenith and Horizon with scattered sunlight when
// its Height is set: blue overhead, red along the horizon at sunrise
// and sunset, dark when the sun is down, and thinning as the camera
// climbs. Ground still colours the half below the horizon.
Atmosphere Atmosphere
// contains filtered or unexported fields
}
Sky is a procedural environment described by what a game already knows: which way is up, how much atmosphere there is, and where the sun is. It needs no image and costs nothing to change, so it can follow a ship from orbit down to the ground, or point its ground half at the planet a ship is passing. Set it as Light.Sky. Rough surfaces take its tint from every direction, metals reflect its gradient, and with Light.Background the sun's disc and the stars are drawn behind the scene. An image Environment on the light replaces it.
type SpotLight ¶
type SpotLight struct {
Position lin.Vec3
Direction lin.Vec3
Color Color
Range float32 // fades to nothing this far away
// InnerAngle and OuterAngle are the cone's full angles in radians: full
// inside the inner, fading to nothing at the outer; zero outer means
// 45 degrees.
InnerAngle, OuterAngle float32
Shadows bool // render a shadow map for this light
}
SpotLight is a cone of light for AddSpot, with the option of a shadow map: a flashlight that throws the bars' shadows, a lamp over a table. The first four shadowed spot lights a frame get maps (MaxSpotShadows), the rest shine without; add the nearest first.
type Sprite ¶
type Sprite struct {
Pos lin.Vec2 // pivot position in view units before the transform stack
Size lin.Vec2 // dimensions in view units; DrawRegion/DrawFrame fill a zero size
UV0, UV1 lin.Vec2 // normalized texture bounds; zero UV1 selects the full texture
Color Color // straight linear tint; zero means white
Rotation float32 // radians clockwise on a Y-down screen
Origin lin.Vec2 // pivot fraction: zero is top-left, (0.5, 0.5) is center
// FlipX and FlipY mirror the image, for a character facing the other
// way.
FlipX, FlipY bool
// Filter overrides the texture's own filtering for this draw.
Filter Filter
}
Sprite is one textured quad. Size is in view units; UV0 and UV1 select the texture region in 0..1; Origin is the rotation pivot as a fraction of Size.
func (Sprite) Bounds ¶
Bounds returns the axis-aligned rectangle enclosing Corners. It includes placement, origin and rotation, but not the graphics transform or camera.
func (Sprite) Corners ¶
Corners returns the four corners in texture order: top-left, top-right, bottom-right, bottom-left, after placement, origin and rotation. Negative sizes reverse the corresponding axis. The graphics transform and camera are not included, and texture flips do not move the corners.
type StaticBatch ¶
type StaticBatch struct {
// contains filtered or unexported fields
}
StaticBatch is a set of mesh draws that never move, held behind a bounding volume hierarchy built once. Drawing the batch tests the hierarchy against the camera's frustum and the frame's occluders and queues only the items that survive, so a level's ten thousand rocks, crates and lamp posts cost a few dozen box tests instead of ten thousand. Items keep their own meshes and materials, so draws that share both are still merged into one instanced call. Items the camera cannot see still cast shadows: a subtree the camera rejects is walked again against the frame's shadow maps.
A batch does not own its meshes or textures; destroy those as usual. Its meshes, materials and shader belong to the Graphics that built it; constructing or drawing with resources from another Graphics panics. Build one with NewStaticBatch and draw it with DrawBatch. Anything that moves belongs in DrawMesh instead: the hierarchy is built from the models given and is not rebuilt. Mesh geometry and bounds must also remain fixed; rebuild the batch after changing either. Include any shader displacement in mesh bounds before building the hierarchy.
func (*StaticBatch) Bounds ¶
func (b *StaticBatch) Bounds() (min, max lin.Vec3)
Bounds is the world box every item of the batch fits inside. An empty batch reports a zero box.
type StencilOp ¶
type StencilOp uint8
StencilOp is what a fragment that passes both the stencil and the depth test does to the stencil buffer. The zero value leaves it alone.
const ( StencilKeep StencilOp = iota // leave the value alone: the default StencilReplace // store StencilRef StencilIncrement // add one, stopping at 255 StencilDecrement // subtract one, stopping at 0 StencilZero // store zero StencilInvert // invert all bits StencilIncrementWrap // add one, wrapping 255 to zero StencilDecrementWrap // subtract one, wrapping zero to 255 )
type StencilOptions ¶
type StencilOptions struct {
Test StencilTest
Reference uint8
Pass, Fail, DepthFail StencilOp
ReadMask, WriteMask uint8
DisableWrite bool
NoColor bool
}
StencilOptions controls stencil testing and updates for 2D fragments. Zero options draw normally and leave stencil unchanged. Zero ReadMask and WriteMask mean all eight bits; DisableWrite prevents all stencil updates. NoColor suppresses colour writes while retaining fragment stencil updates. The test compares the masked stored value to the masked Reference.
type StencilTest ¶
type StencilTest uint8
StencilTest is when a material's fragments pass the stencil test: how the value already in the stencil buffer must compare to the material's StencilRef. The zero value draws everywhere.
const ( StencilAlways StencilTest = iota // no test at all: the default StencilEqual // only where the buffer holds StencilRef StencilNotEqual // only where it holds anything else StencilLess // only where it holds less than StencilRef StencilGreater // only where it holds more than StencilRef StencilNever // reject every fragment; only its Fail operation can update stencil StencilLessEqual // only where it holds at most StencilRef StencilGreaterEqual // only where it holds at least StencilRef )
type StrokeOptions ¶
type StrokeOptions struct {
Width float32 // zero means 1
Cap LineCap
Join LineJoin
MiterLimit float32 // miter length over width beyond which corners bevel; zero means 4
// Dash is a pattern of on and off lengths in view units, repeated
// along the path, starting DashOffset in; empty strokes solid.
Dash []float32
DashOffset float32
// Gradient colours the stroke by position; the colour then tints it.
Gradient *Gradient
NoAntiAlias bool
}
StrokeOptions controls StrokePath.
type Terrain ¶
type Terrain struct {
// contains filtered or unexported fields
}
Terrain is a heightfield split into square chunks, each with a mesh at several resolutions, drawn at the resolution its distance from the camera deserves. Chunks are ordinary draws, so the frustum and the frame's occluders cull them, and each carries a skirt around its edge deep enough to hide the crack where it meets a coarser neighbour.
The ground is shaded by the built-in terrain shader: a splat map whose four channels weight four tiling layer textures. Height and Normal answer where the ground is, for placing trees, dropping items and walking on it, and Heights with Update let a game dig into it.
Build one with NewTerrain, draw it with DrawTerrain and free it with Destroy. One Terrain owns one shader and its pipelines, so a game with several of them pays for each; a game usually has one.
func (*Terrain) ChunkCentre ¶
ChunkCentre is the middle of a chunk's world box, which is what the level is chosen by.
func (*Terrain) ChunkLevel ¶
ChunkLevel is the resolution the last DrawTerrain chose for a chunk: 0 is the finest, each level after it halves the samples along each side. It is what to print when the terrain is refining in the wrong places.
func (*Terrain) Destroy ¶
func (t *Terrain) Destroy()
Destroy frees the chunk meshes, the shader and the splat texture the terrain made. Layer textures belong to the game and are left alone.
func (*Terrain) Height ¶
Height is the ground's world y at a world x and z, interpolated across the cell the point falls in. Outside the terrain it is the height of the nearest edge sample.
func (*Terrain) Heights ¶
Heights is the terrain's own height samples, row by row, so Heights()[z*cols+x] is the height at column x of row z. Write into it to dig or raise the ground, then call Update over the samples that changed so the meshes and their normals follow.
func (*Terrain) Normal ¶
Normal is the ground's unit normal at a world x and z, from the heights either side of the nearest sample. Use it to lie a rock flat on a slope or to refuse to build on one.
func (*Terrain) Raycast ¶
Raycast walks a ray over the heightfield and returns the first point where it passes under the ground, for a click that digs, a shot that throws up dust or a unit ordered to a spot. It steps a cell at a time and then narrows the step it crossed on, so it finds the nearest hit on ground that is no steeper than a cell is wide; reach is how far along the ray to look, and zero means the terrain's whole diagonal. A ray that starts under the ground reports its own origin.
func (*Terrain) SetSplat ¶
SetSplat replaces the layer weights, for a splat map painted after the terrain was built or repainted as the ground changes: the game asks the terrain's own Height and Normal where sand, grass, rock and snow belong, then hands the answer back. The image is stretched over the whole heightfield, its channels weighting layers one to four, and the terrain owns and frees the texture it makes from it. A nil image restores the default of the first layer everywhere.
func (*Terrain) Shader ¶
Shader is the terrain's own mesh shader, for a game that wants to rebind a layer with SetImage or change the layer scales with SetUniforms after it is built.
func (*Terrain) Size ¶
Size is the terrain's samples across and deep and the world units between them.
type TerrainOptions ¶
type TerrainOptions struct {
// Heights is one world height per sample, row by row, so
// Heights[z*Cols+x] is the height at column x of row z. NewTerrain
// copies it.
Heights []float32
// Cols and Rows are the samples across (x) and deep (z). Both minus
// one must be whole multiples of ChunkSize.
Cols, Rows int
// Cell is the world units between samples; zero means 1.
Cell float32
// Centre is where the middle of the heightfield sits in the world,
// and its y is added to every height. Zero puts it at the origin.
Centre lin.Vec3
// ChunkSize is the samples across one chunk, a power of two; zero
// means 32. Small chunks cull and refine finely and cost more draws.
ChunkSize int
// Levels is how many resolutions each chunk keeps, each halving the
// samples of the one before; zero means 4, and it is clamped to what
// ChunkSize can be halved to.
Levels int
// LODDistance is how far the finest level reaches; each level after
// it covers twice the distance of the one before. Zero means eight
// chunks' width.
LODDistance float32
// Splat weights the four layers by its channels, stretched over the
// whole heightfield. Nil weights the first layer everywhere.
Splat image.Image
// Layers are the tiling albedo textures the splat's red, green, blue
// and alpha channels choose between. Give them TextureOptions.Repeat,
// since they tile. A nil layer samples white.
Layers [4]*Texture
// LayerScale is the world units per repeat of each layer; a zero
// entry means 8.
LayerScale [4]float32
// LayerRoughness is each layer's roughness; a zero entry means 0.9,
// which is the ground.
LayerRoughness [4]float32
}
TerrainOptions describes a heightfield to NewTerrain.
type TextCaret ¶
type TextCaret struct {
Index int
Affinity CaretAffinity
}
TextCaret identifies an insertion boundary in the original UTF-8 source. Ligatures and combining clusters are atomic. Invalid or interior indices snap to the nearest valid cluster boundary, preferring the lower on a tie.
type TextLayout ¶
type TextLayout struct {
// contains filtered or unexported fields
}
TextLayout is an immutable, reusable shaped text block. It owns ordinary Go data and borrows its fonts and their atlases; it needs no Destroy. Queries remain valid after font destruction, but drawing requires live fonts. Construct one with Font.Layout or RichFonts.Layout, then DrawTextLayout.
func (*TextLayout) Bounds ¶
func (l *TextLayout) Bounds() lin.Rect
Bounds returns logical advance and line-box bounds, including alignment, spacing and rotation. Wrapped trailing whitespace has zero advance but retains source caret boundaries; unwrapped whitespace keeps its advance. Glyphs can extend beyond this rectangle.
func (*TextLayout) Caret ¶
func (l *TextLayout) Caret(position TextCaret) lin.Rect
Caret returns the caret's axis-aligned rectangle in layout coordinates. The rectangle is one view unit thick before rotation. Out-of-range indices clamp to the source ends; points inside a cluster snap to its closest edge.
func (*TextLayout) HitTest ¶
func (l *TextLayout) HitTest(point lin.Vec2) TextCaret
HitTest returns the closest cluster boundary to a point in layout coordinates. It inverse-rotates the point and clamps outside the text to its closest line and caret, preserving wrap and bidi affinity.
func (*TextLayout) InkBounds ¶
func (l *TextLayout) InkBounds() lin.Rect
InkBounds returns glyph ink and decoration bounds, including outlines and rotation. Atlas padding and the sampling filter's antialias fringe are excluded.
func (*TextLayout) Lines ¶
func (l *TextLayout) Lines() []TextLine
Lines returns an independent copy of the line descriptions.
func (*TextLayout) Links ¶
func (l *TextLayout) Links() []RichLink
Links returns an independent copy of link rectangles in layout coordinates.
func (*TextLayout) Text ¶
func (l *TextLayout) Text() string
Text returns the original text (RichText.Plain for a styled layout).
type TextLine ¶
TextLine describes one visual line or vertical column. Start and End are byte offsets into TextLayout.Text, excluding an explicit terminating newline. Bounds includes advances and the line height, not glyph overhangs. Baseline is its baseline origin; all coordinates include TextOptions.Angle.
type TextOptions ¶
type TextOptions struct {
Underline bool
Strikethrough bool
OutlineWidth float32 // view units; zero disables the outline
OutlineColor Color // zero follows the effective text colour
Width float32 // wrap width in view units (column height for vertical text); zero means no wrapping
Align Align
LineSpacing float32 // multiplier; zero means 1
// Size is the em size to draw at; zero means the font's own. SDF fonts
// stay crisp at any size; bitmap fonts resample their atlas.
Size float32
// Angle rotates the text about its origin, in radians, clockwise on
// screen.
Angle float32
// Baseline puts the first line's baseline at the origin's y instead of
// the block's top, so text of different sizes lines up.
Baseline bool
// LetterSpacing adds view units between glyphs, for tracked-out
// headings; negative tightens.
LetterSpacing float32
// Hyphenate breaks long words at the hyphenator's points when a line
// wraps, drawing a hyphen at the break.
Hyphenate *Hyphenator
// AutoHyphenate breaks long words with the hyphenator for Language, or
// American English when Language is empty. A language the engine ships
// no patterns for is not hyphenated. Hyphenate wins when both are set.
AutoHyphenate bool
Direction Direction
// Language is a BCP 47 tag ("tr", "zh-Hant") that picks language-specific
// glyph forms; empty means the font's default.
Language string
}
TextOptions lays out text.
type Texture ¶
type Texture struct {
Width, Height int
// contains filtered or unexported fields
}
Texture is an image on the GPU, sampled by sprites, materials and shaders. Create it through Graphics; its zero value is not drawable. Width and Height are pixel dimensions maintained by the engine and must not be assigned by callers. Destroy releases owned GPU storage.
func (*Texture) CopyFrom ¶
CopyFrom copies srcRect from src to dst on this texture's GPU image, preserving the stored bytes and regenerating this texture's mip chain. A zero rectangle selects the whole source. Both regions must fit; there is no clipping, scaling, blending or colour conversion. Source and destination need identical formats and Graphics ownership. Compressed textures, destroyed textures, overlapping self-copies and render-texture destinations are rejected.
Within a frame this records before all queued drawing, like Write. A source render texture already queued through DrawTo is rejected because its new pixels will not exist until the frame renders. Otherwise it copies the last completed source image, plus any preceding texture uploads in the frame. Outside a frame it waits for the GPU. Non-overlapping self-copies are supported.
func (*Texture) Destroy ¶
func (t *Texture) Destroy()
Destroy frees the texture. Called inside a frame it costs no wait: the image and its descriptor sets go on the frame slot's retire list and are freed once that frame has finished, so sprites and meshes already queued this frame still draw with it.
func (*Texture) Read ¶
Read copies pixels back from the GPU as an ordinary Go image, with colours premultiplied in sRGB space. Data texture channels retain their stored values. It waits for the GPU and is only valid outside an active frame; queued uploads and rendering have not been submitted during Update or Draw. A compressed texture holds blocks rather than texels, so reading one is an error; decode its KTX2 file with gfx/ktx2 instead.
func (*Texture) Replace ¶
Replace swaps the texture's pixels for another image, keeping the *Texture the game holds valid: every sprite, material and shader slot that names it draws the new image without being told. Use it to reload a texture whose file changed on disk; asset.Reloader calls it for you. The image may be a different size, and the filtering, edge handling, colour handling and mip choice the texture was made with are kept. Inside a frame it costs no wait, and the old image is freed once the frames that may still draw from it have finished. A render texture's image belongs to the render texture, so replacing one is an error.
func (*Texture) ReplaceCompressed ¶
ReplaceCompressed swaps a compressed texture's blocks for those of another KTX2 file, keeping the *Texture the game holds, the way Replace does for an image. asset.Reloader calls it when a .ktx2 file changes on disk.
func (*Texture) SavePNG ¶
SavePNG reads the completed texture, then creates or truncates path and closes the output file. It has the same format and frame-timing restrictions as Read.
func (*Texture) Write ¶
Write replaces the pixels under src placed at (x, y), clipped to the texture, and rebuilds the mip chain. Inside a frame (between the engine's Begin and End, which is where Update and Draw run) the copy is recorded into the frame and costs no wait, so video and painting can write every frame; outside one it joins the batch of uploads the next frame submits first, and also costs no wait. Nil sources and coordinate overflow return errors. Render-texture views reject Write; use Graphics.DrawTo to change their pixels.
type TextureOptions ¶
type TextureOptions struct {
Linear bool // bilinear filtering; the default is nearest, for pixel art
// Data marks pixels that are not sRGB colour (masks, glyph coverage,
// lookup tables); they are sampled without gamma decoding.
Data bool
// NoMipmaps keeps a single level; linear textures get a full mip chain
// by default so distant surfaces do not shimmer.
NoMipmaps bool
// Repeat tiles the texture instead of clamping at the edges.
Repeat bool
}
TextureOptions selects sampling and colour handling.
type TileAnimation ¶
TileAnimation cycles a frame through others: water, torches, grass in the wind. Durations are seconds per frame; one value applies to all.
type Tilemap ¶
type Tilemap struct {
Sheet *Sheet
Width, Height int // in tiles
Tiles []int // row-major, len Width*Height; frames with optional flip bits
TileW, TileH float32 // drawn size of one tile; zero means the frame size
// contains filtered or unexported fields
}
Tilemap is a grid of frame indices into a sheet; -1 is empty.
func NewTilemap ¶
NewTilemap makes an empty map of the given size.
func (*Tilemap) Animate ¶
func (t *Tilemap) Animate(frame int, a TileAnimation)
Animate makes every cell showing frame play the animation instead.
type Transform ¶
type Transform struct {
Position lin.Vec3
Rotation lin.Quat // zero means no rotation
Scale lin.Vec3 // zero means 1
}
Transform is a position, rotation and scale in 3D; its zero value is identity. Use it instead of building matrices by hand.
type Transform2 ¶
Transform2 places a 2D entity: its centre in view or world units, a rotation in radians and a scale (zero means 1). Physics and animation systems write it; Apply turns a sprite template into the sprite to draw there.
func (Transform2) Apply ¶
func (t Transform2) Apply(s Sprite) Sprite
Apply centres the sprite on the transform's position, rotating about its centre and scaling its size.
type Vertex ¶
Vertex is a mesh vertex: position, normal, a texture coordinate, an optional second set (UV2, for lightmaps and occlusion) and an optional colour that multiplies the material's base colour (zero means white).
func AppendMesh ¶
func AppendMesh(verts []Vertex, indices []uint32, moreVerts []Vertex, moreIndices []uint32) ([]Vertex, []uint32)
AppendMesh adds a second mesh's geometry to the first, offsetting its indices, so a chunk, a building or a compound shape becomes one mesh and one draw.
func CapsuleMesh ¶
CapsuleMesh returns a capsule of radius 1 whose straight middle runs from y = -halfHeight to y = halfHeight, with rings across each cap and segments around: the shape of a Capsule collider and of most characters' bodies.
func ConeMesh ¶
ConeMesh returns a cone of radius 1 at y = -1 rising to a point at y = 1, in segments around: spikes, trees, arrow heads, spot light gizmos.
func CubeMesh ¶
CubeMesh returns a unit cube centred on the origin with flat normals and a full UV square on each face.
func CylinderMesh ¶
CylinderMesh returns a cylinder of radius 1 from y = -1 to y = 1 with flat caps, in segments around: pillars, barrels, wheels, the shape of a capsule collider's middle.
func FlatShaded ¶
FlatShaded returns a copy of a mesh with no shared vertices, each triangle's vertices carrying its face normal: the faceted look of low-poly art and voxel worlds.
func HeightfieldMesh ¶
HeightfieldMesh returns terrain from a grid of heights, cols across (x) by rows deep (z), cell world units apart and centred on the origin, with smooth normals and UVs running 0..1 across the grid. Heights are read row by row, so heights[z*cols+x] is the height at column x of row z. Pair it with a MeshShape collider of the same vertices.
func PlaneMesh ¶
PlaneMesh returns a unit square in the xz plane centred on the origin, facing +y, divided into segments by segments quads so a vertex shader can ripple it: ground, water, a tabletop. UVs run 0..1 across it.
func QuadMesh ¶
QuadMesh returns a unit square in the xy plane centred on the origin, facing +z, its UVs running from the top-left: the shape of a billboard or a flat sprite in a 3D scene.
func SphereMesh ¶
SphereMesh returns a UV sphere of radius 1 with the given resolution.
type View2D ¶
View2D maps a local 2D coordinate space into a rectangle of its enclosing view. Viewport is in enclosing view units, independent of camera and transform state. Size is the local virtual size; a zero component uses the matching viewport dimension. Coordinates outside the viewport clip.
Viewport dimensions must be positive, Size components nonnegative, and all values finite. Mapping methods and WithView panic on invalid values.
func (View2D) LocalToParent ¶
LocalToParent maps a local view point into the enclosing view. It does not apply a camera or clamp points to the viewport.
func (View2D) ParentToLocal ¶
ParentToLocal maps an enclosing view point, such as pointer input, into local view coordinates. Points outside the viewport are not clamped.
func (View2D) ParentToWorld ¶
ParentToWorld maps an enclosing view point through the inverse camera into world coordinates. Test Viewport.Contains first when input outside the view should be ignored. Nested views map through each parent in turn.
Source Files
¶
- anim.go
- animation.go
- aseprite.go
- atlas.go
- batch.go
- batch2d.go
- billboard.go
- blend.go
- bounds.go
- camera2d.go
- cluster.go
- color.go
- colorglyph.go
- colormatrix.go
- colr.go
- compiled_path.go
- compressed.go
- cull.go
- debug.go
- environment.go
- exr.go
- font.go
- font_ink.go
- fontface.go
- geometry2d.go
- gradient.go
- graphics.go
- hdr.go
- hook.go
- hyphen.go
- image.go
- impostor.go
- instances.go
- lightprobe.go
- lod.go
- matintern.go
- mesh.go
- mesh_draw.go
- model.go
- morph.go
- occlude.go
- ownership.go
- particles.go
- path.go
- path_bounds.go
- pick.go
- pipes.go
- post.go
- posteffects.go
- pow.go
- primitives.go
- probe.go
- queue.go
- rendertexture.go
- resource_owner.go
- resources.go
- rgba.go
- rich.go
- scopes.go
- sdf.go
- shader.go
- shader_source.go
- shadow2d.go
- shadowcasters.go
- shapes.go
- skin.go
- sky.go
- sky_space.go
- sortkey.go
- sprite.go
- ssr.go
- stencil.go
- svgglyph.go
- svgpath.go
- terrain.go
- text.go
- textcache.go
- textlayout.go
- textoutline.go
- texture.go
- texture_transfer.go
- tilemap.go
- transform.go
- trig.go
- uniforms.go
- velocity.go
- view2d.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package ktx2 reads and writes KTX2 texture files and encodes and decodes the block-compressed formats they carry.
|
Package ktx2 reads and writes KTX2 texture files and encodes and decodes the block-compressed formats they carry. |
|
Package shaders holds the gfx package's WGSL sources and committed SPIR-V, and the preludes that game shaders are compiled against.
|
Package shaders holds the gfx package's WGSL sources and committed SPIR-V, and the preludes that game shaders are compiled against. |