glitch

package module
v0.0.0-...-ecc5831 Latest Latest
Warning

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

Go to latest
Published: Dec 2, 2024 License: MIT Imports: 26 Imported by: 8

README

Go Reference build

Warning: This library is very much a work in progress. But you're welcome to check it out and provide feedback/bugs if you want.

Overview

Glitch is a shader based rendering library built on top of OpenGL and WebGL. At a high level, I'd like glitch to be data driven. Shaders are just programs that run on the GPU, so my objective is to make Glitch a platform that makes it easier to do the things that are hard in rendering:

  1. Efficiently ordering, moving, and batching data to the GPU
  2. Efficiently executing programs on that copied data

Platform Support

Currently, we compile to:

  • Desktop (Windows, Linux)
  • Browser (via WebAssembly)

Platforms that I'd like to add, but haven't added or haven't tested:

  • Desktop (MacOS - OpenGL is deprecated, I also don't own a mac. So it's hard to test)
  • Mobile Apps
  • Mobile Browsers

Usage

You can look at the examples folder, sometimes they go out of date, but I try to keep them working. Because APIs are shifting I don't have definite APIs defined yet.

Documentation

Index

Constants

View Source
const (
	AxisLeftX        = GamepadAxis(glfw.AxisLeftX)
	AxisLeftY        = GamepadAxis(glfw.AxisLeftY)
	AxisRightX       = GamepadAxis(glfw.AxisRightX)
	AxisRightY       = GamepadAxis(glfw.AxisRightY)
	AxisLeftTrigger  = GamepadAxis(glfw.AxisLeftTrigger)
	AxisRightTrigger = GamepadAxis(glfw.AxisRightTrigger)
	AxisLast         = GamepadAxis(glfw.AxisLast)
)
View Source
const (
	ButtonA           = GamepadButton(glfw.ButtonA)
	ButtonB           = GamepadButton(glfw.ButtonB)
	ButtonX           = GamepadButton(glfw.ButtonX)
	ButtonY           = GamepadButton(glfw.ButtonY)
	ButtonLeftBumper  = GamepadButton(glfw.ButtonLeftBumper)
	ButtonRightBumper = GamepadButton(glfw.ButtonRightBumper)
	ButtonBack        = GamepadButton(glfw.ButtonBack)
	ButtonStart       = GamepadButton(glfw.ButtonStart)
	ButtonGuide       = GamepadButton(glfw.ButtonGuide)
	ButtonLeftThumb   = GamepadButton(glfw.ButtonLeftThumb)
	ButtonRightThumb  = GamepadButton(glfw.ButtonRightThumb)
	ButtonDpadUp      = GamepadButton(glfw.ButtonDpadUp)
	ButtonDpadRight   = GamepadButton(glfw.ButtonDpadRight)
	ButtonDpadDown    = GamepadButton(glfw.ButtonDpadDown)
	ButtonDpadLeft    = GamepadButton(glfw.ButtonDpadLeft)
	ButtonCross       = GamepadButton(glfw.ButtonCross)
	ButtonCircle      = GamepadButton(glfw.ButtonCircle)
	ButtonSquare      = GamepadButton(glfw.ButtonSquare)
	ButtonTriangle    = GamepadButton(glfw.ButtonTriangle)

	ButtonFirst = ButtonA
	ButtonLast  = GamepadButton(glfw.ButtonLast)
)
View Source
const (
	KeyUnknown      = Key(glfw.KeyUnknown)
	KeySpace        = Key(glfw.KeySpace)
	KeyApostrophe   = Key(glfw.KeyApostrophe)
	KeyComma        = Key(glfw.KeyComma)
	KeyMinus        = Key(glfw.KeyMinus)
	KeyPeriod       = Key(glfw.KeyPeriod)
	KeySlash        = Key(glfw.KeySlash)
	Key0            = Key(glfw.Key0)
	Key1            = Key(glfw.Key1)
	Key2            = Key(glfw.Key2)
	Key3            = Key(glfw.Key3)
	Key4            = Key(glfw.Key4)
	Key5            = Key(glfw.Key5)
	Key6            = Key(glfw.Key6)
	Key7            = Key(glfw.Key7)
	Key8            = Key(glfw.Key8)
	Key9            = Key(glfw.Key9)
	KeySemicolon    = Key(glfw.KeySemicolon)
	KeyEqual        = Key(glfw.KeyEqual)
	KeyA            = Key(glfw.KeyA)
	KeyB            = Key(glfw.KeyB)
	KeyC            = Key(glfw.KeyC)
	KeyD            = Key(glfw.KeyD)
	KeyE            = Key(glfw.KeyE)
	KeyF            = Key(glfw.KeyF)
	KeyG            = Key(glfw.KeyG)
	KeyH            = Key(glfw.KeyH)
	KeyI            = Key(glfw.KeyI)
	KeyJ            = Key(glfw.KeyJ)
	KeyK            = Key(glfw.KeyK)
	KeyL            = Key(glfw.KeyL)
	KeyM            = Key(glfw.KeyM)
	KeyN            = Key(glfw.KeyN)
	KeyO            = Key(glfw.KeyO)
	KeyP            = Key(glfw.KeyP)
	KeyQ            = Key(glfw.KeyQ)
	KeyR            = Key(glfw.KeyR)
	KeyS            = Key(glfw.KeyS)
	KeyT            = Key(glfw.KeyT)
	KeyU            = Key(glfw.KeyU)
	KeyV            = Key(glfw.KeyV)
	KeyW            = Key(glfw.KeyW)
	KeyX            = Key(glfw.KeyX)
	KeyY            = Key(glfw.KeyY)
	KeyZ            = Key(glfw.KeyZ)
	KeyLeftBracket  = Key(glfw.KeyLeftBracket)
	KeyBackslash    = Key(glfw.KeyBackslash)
	KeyRightBracket = Key(glfw.KeyRightBracket)
	KeyGraveAccent  = Key(glfw.KeyGraveAccent)
	KeyWorld1       = Key(glfw.KeyWorld1)
	KeyWorld2       = Key(glfw.KeyWorld2)
	KeyEscape       = Key(glfw.KeyEscape)
	KeyEnter        = Key(glfw.KeyEnter)
	KeyTab          = Key(glfw.KeyTab)
	KeyBackspace    = Key(glfw.KeyBackspace)
	KeyInsert       = Key(glfw.KeyInsert)
	KeyDelete       = Key(glfw.KeyDelete)
	KeyRight        = Key(glfw.KeyRight)
	KeyLeft         = Key(glfw.KeyLeft)
	KeyDown         = Key(glfw.KeyDown)
	KeyUp           = Key(glfw.KeyUp)
	KeyPageUp       = Key(glfw.KeyPageUp)
	KeyPageDown     = Key(glfw.KeyPageDown)
	KeyHome         = Key(glfw.KeyHome)
	KeyEnd          = Key(glfw.KeyEnd)
	KeyCapsLock     = Key(glfw.KeyCapsLock)
	KeyScrollLock   = Key(glfw.KeyScrollLock)
	KeyNumLock      = Key(glfw.KeyNumLock)
	KeyPrintScreen  = Key(glfw.KeyPrintScreen)
	KeyPause        = Key(glfw.KeyPause)
	KeyF1           = Key(glfw.KeyF1)
	KeyF2           = Key(glfw.KeyF2)
	KeyF3           = Key(glfw.KeyF3)
	KeyF4           = Key(glfw.KeyF4)
	KeyF5           = Key(glfw.KeyF5)
	KeyF6           = Key(glfw.KeyF6)
	KeyF7           = Key(glfw.KeyF7)
	KeyF8           = Key(glfw.KeyF8)
	KeyF9           = Key(glfw.KeyF9)
	KeyF10          = Key(glfw.KeyF10)
	KeyF11          = Key(glfw.KeyF11)
	KeyF12          = Key(glfw.KeyF12)
	KeyF13          = Key(glfw.KeyF13)
	KeyF14          = Key(glfw.KeyF14)
	KeyF15          = Key(glfw.KeyF15)
	KeyF16          = Key(glfw.KeyF16)
	KeyF17          = Key(glfw.KeyF17)
	KeyF18          = Key(glfw.KeyF18)
	KeyF19          = Key(glfw.KeyF19)
	KeyF20          = Key(glfw.KeyF20)
	KeyF21          = Key(glfw.KeyF21)
	KeyF22          = Key(glfw.KeyF22)
	KeyF23          = Key(glfw.KeyF23)
	KeyF24          = Key(glfw.KeyF24)
	KeyF25          = Key(glfw.KeyF25)
	KeyKP0          = Key(glfw.KeyKP0)
	KeyKP1          = Key(glfw.KeyKP1)
	KeyKP2          = Key(glfw.KeyKP2)
	KeyKP3          = Key(glfw.KeyKP3)
	KeyKP4          = Key(glfw.KeyKP4)
	KeyKP5          = Key(glfw.KeyKP5)
	KeyKP6          = Key(glfw.KeyKP6)
	KeyKP7          = Key(glfw.KeyKP7)
	KeyKP8          = Key(glfw.KeyKP8)
	KeyKP9          = Key(glfw.KeyKP9)
	KeyKPDecimal    = Key(glfw.KeyKPDecimal)
	KeyKPDivide     = Key(glfw.KeyKPDivide)
	KeyKPMultiply   = Key(glfw.KeyKPMultiply)
	KeyKPSubtract   = Key(glfw.KeyKPSubtract)
	KeyKPAdd        = Key(glfw.KeyKPAdd)
	KeyKPEnter      = Key(glfw.KeyKPEnter)
	KeyKPEqual      = Key(glfw.KeyKPEqual)
	KeyLeftShift    = Key(glfw.KeyLeftShift)
	KeyLeftControl  = Key(glfw.KeyLeftControl)
	KeyLeftAlt      = Key(glfw.KeyLeftAlt)
	KeyLeftSuper    = Key(glfw.KeyLeftSuper)
	KeyRightShift   = Key(glfw.KeyRightShift)
	KeyRightControl = Key(glfw.KeyRightControl)
	KeyRightAlt     = Key(glfw.KeyRightAlt)
	KeyRightSuper   = Key(glfw.KeyRightSuper)
	KeyMenu         = Key(glfw.KeyMenu)
	KeyLast         = Key(glfw.KeyLast)
)

Note: these are based on the key location for a qwerty keyboard

View Source
const (
	ModShift   = Key(glfw.ModShift)
	ModControl = Key(glfw.ModControl)
	ModAlt     = Key(glfw.ModAlt)
	ModSuper   = Key(glfw.ModSuper)
)
View Source
const (
	MouseButton1 = Key(glfw.MouseButton1)
	MouseButton2 = Key(glfw.MouseButton2)
	MouseButton3 = Key(glfw.MouseButton3)
	MouseButton4 = Key(glfw.MouseButton4)
	MouseButton5 = Key(glfw.MouseButton5)
	// Note: 6, 7, 8 dont exist in browsers
	// MouseButton6 = Key(glfw.MouseButton6)
	// MouseButton7 = Key(glfw.MouseButton7)
	// MouseButton8 = Key(glfw.MouseButton8)
	MouseButtonLeft   = Key(glfw.MouseButtonLeft)
	MouseButtonRight  = Key(glfw.MouseButtonRight)
	MouseButtonMiddle = Key(glfw.MouseButtonMiddle)
)

Mouse buttons

View Source
const (
	ScreenModeFull     = ScreenModeType(glfw.ScreenModeFull)
	ScreenModeWindowed = ScreenModeType(glfw.ScreenModeWindowed)
)
View Source
const GamepadNone = Gamepad(-1)

Variables

View Source
var (
	White = glm.White
	Black = glm.Black
)
View Source
var Mat4Ident = glm.Mat4Ident

Functions

func Clear

func Clear(target Target, color RGBA)

func GetKeyDescription

func GetKeyDescription(k Key) string

TODO: This won't work for wasm yet For text-keys, we return the upper case version of the key. For non-text we return a text string of the key. This may fall back to QWERTY keyboard layout in some cases Returns "Unknown" if we don't have a description for that key

func GetKeyName

func GetKeyName(k Key) string

func Run

func Run(function func())

func SetCamera

func SetCamera(camera *CameraOrtho)

func SetCameraMaterial

func SetCameraMaterial(camMaterial CameraMaterial)

func SetDefaultMsdfShader

func SetDefaultMsdfShader(shader *Shader)

func SetDefaultSpriteShader

func SetDefaultSpriteShader(shader *Shader)

func SortDrawCommands

func SortDrawCommands(buf []drawCommand, sortMode SoftwareSortMode)

Types

type Atlas

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

TODO - instead of creating a single atlas ahead of time. I should just load the font and then dynamically create the atlas as needed. This should probably change once you add automatic texture batching.

func AtlasFromSdf

func AtlasFromSdf(sdf SdfAtlas, sdfImg image.Image, kerning float64) (*Atlas, error)

func BasicFontAtlas

func BasicFontAtlas() (*Atlas, error)

func DefaultAtlas

func DefaultAtlas() (*Atlas, error)

TODO: Ideally this wouldn't return an error

func NewAtlas

func NewAtlas(face font.Face, runes []rune, config AtlasConfig) *Atlas

func (*Atlas) LineHeight

func (a *Atlas) LineHeight() float64

func (*Atlas) Material

func (a *Atlas) Material() *Material

func (*Atlas) Measure

func (a *Atlas) Measure(str string, scale float64) Rect

TODO: This could be improved by just calling specialized measurement functions

func (*Atlas) MeasureWrapped

func (a *Atlas) MeasureWrapped(str string, scale float64, wrapRect Rect) Rect

func (*Atlas) RuneVerts

func (a *Atlas) RuneVerts(mesh *Mesh, r rune, dot Vec2, scale float64, color RGBA) (Vec2, float64)

func (*Atlas) Text

func (a *Atlas) Text(str string, scale float64) *Text

func (*Atlas) UngappedLineHeight

func (a *Atlas) UngappedLineHeight() float64

type AtlasConfig

type AtlasConfig struct {
	Border      float64
	Smooth      bool
	Padding     int
	Kerning     float64
	TextureSize int // TODO: automagically calculate
}

type AtlasRect

type AtlasRect struct {
	Left, Bottom, Right, Top float64
}

type Batch

type Batch struct {
	Translucent bool
	// contains filtered or unexported fields
}

-------------------------------------------------------------------------------- For batching multiple meshes into one mesh

func NewBatch

func NewBatch() *Batch

func (*Batch) Add

func (b *Batch) Add(filler GeometryFiller, matrix glMat4, mask RGBA, material Material, translucent bool)

TODO - It may be faster to copy all the bufs to the destination and then operate on them there. that might save you a copy TODO: should I maintain a translucent and non-translucent batch mesh? TODO: Fix the interface here to only allow meshes to be drawn to batches

func (*Batch) Bounds

func (b *Batch) Bounds() Box

func (*Batch) Buffer

func (b *Batch) Buffer() *Batch

func (*Batch) Clear

func (b *Batch) Clear()

func (*Batch) Draw

func (b *Batch) Draw(target BatchTarget, matrix Mat4)

func (*Batch) DrawColorMask

func (b *Batch) DrawColorMask(target BatchTarget, matrix Mat4, color RGBA)

func (*Batch) RectDraw

func (b *Batch) RectDraw(target BatchTarget, bounds Rect)

func (*Batch) RectDrawColorMask

func (b *Batch) RectDrawColorMask(target BatchTarget, bounds Rect, mask RGBA)

TODO: Generalize this rectdraw logic. Copy paseted from Sprite

type BatchTarget

type BatchTarget interface {
	Add(GeometryFiller, glMat4, RGBA, Material, bool)
}

type BlendMode

type BlendMode uint8

Note: These are all packed into uint8s to reduce size of the Material object

const (
	BlendModeNormal BlendMode = iota
	BlendModeMultiply
)

type Box

type Box = glm.Box

type BufferPool

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

BufferPool TODO - Idea Improvements: You'd be able to calculate in the pass how many draws with the same material you'd be doing. Based on that you could have really well sized buffers. Also in here you could have different VertexBuffer sizes and order them as needed into a final draw slice

func NewBufferPool

func NewBufferPool(shader *Shader, triangleBatchSize int) *BufferPool

func (*BufferPool) Clear

func (b *BufferPool) Clear()

func (*BufferPool) Reserve

func (b *BufferPool) Reserve(indices []uint32, numVerts int, dests []interface{}) *VertexBuffer

Returns the vertexbuffer that we reserved to

type Camera

type Camera struct {
	Projection Mat4
	View       Mat4

	Position Vec3
	Target   Vec3
}

func NewCamera

func NewCamera() *Camera

func (*Camera) Material

func (c *Camera) Material() CameraMaterial

func (*Camera) SetPerspective

func (c *Camera) SetPerspective(win *Window)

func (*Camera) SetViewLookAt

func (c *Camera) SetViewLookAt(win *Window)

type CameraMaterial

type CameraMaterial struct {
	Projection, View glMat4
}

--------------------------------------------------------------------------------

type CameraOrtho

type CameraOrtho struct {
	Projection Mat4
	View       Mat4

	DepthRange Vec2 // Specifies the near and far plane of the camera, defaults to (-1, 1)

	// Tracks the view inverse and whether or not its been recalculated or not
	ViewInv Mat4
	// contains filtered or unexported fields
}

TODO - I feel like camera should be a higher-up abstraction and not held here

func NewCameraOrtho

func NewCameraOrtho() *CameraOrtho

func (*CameraOrtho) Bounds

func (c *CameraOrtho) Bounds() Rect

func (*CameraOrtho) Project

func (c *CameraOrtho) Project(point Vec3) Vec3

func (*CameraOrtho) SetOrtho2D

func (c *CameraOrtho) SetOrtho2D(bounds Rect)

func (*CameraOrtho) Unproject

func (c *CameraOrtho) Unproject(point Vec3) Vec3

type CullMode

type CullMode uint8
const (
	CullModeNone CullMode = iota
	CullModeNormal
)

type CursorMode

type CursorMode uint8
const (
	CursorNormal   CursorMode = iota // A normal cursor
	CursorHidden                     // A normal cursor, but not rendered
	CursorDisabled                   // Hides and locks the cursor
)

type DepthMode

type DepthMode uint8
const (
	DepthModeNone DepthMode = iota
	DepthModeLess
	DepthModeLequal
)

type DrawBatch

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

For batching multiple sprites into one

func NewDrawBatch

func NewDrawBatch() *DrawBatch

func (*DrawBatch) Add

func (b *DrawBatch) Add(filler GeometryFiller, matrix glMat4, mask RGBA, material Material, translucent bool)

func (*DrawBatch) Bounds

func (b *DrawBatch) Bounds() Box

func (*DrawBatch) Clear

func (b *DrawBatch) Clear()

func (*DrawBatch) Draw

func (b *DrawBatch) Draw(target BatchTarget, matrix Mat4)

func (*DrawBatch) DrawColorMask

func (b *DrawBatch) DrawColorMask(target BatchTarget, matrix Mat4, color RGBA)

func (*DrawBatch) RectDraw

func (b *DrawBatch) RectDraw(target BatchTarget, bounds Rect)

func (*DrawBatch) RectDrawColorMask

func (b *DrawBatch) RectDrawColorMask(target BatchTarget, bounds Rect, mask RGBA)

TODO: Generalize this rectdraw logic. Copy paseted from Sprite

type Frame

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

func NewFrame

func NewFrame(bounds Rect, smooth bool) *Frame

Type? Color, depth, stencil?

func (*Frame) Add

func (f *Frame) Add(filler GeometryFiller, mat glMat4, mask RGBA, material Material, translucent bool)

func (*Frame) Bind

func (f *Frame) Bind()

func (*Frame) Bounds

func (f *Frame) Bounds() Rect

func (*Frame) Draw

func (f *Frame) Draw(target BatchTarget, matrix Mat4)

func (*Frame) DrawColorMask

func (f *Frame) DrawColorMask(target BatchTarget, matrix Mat4, mask RGBA)

func (*Frame) Material

func (f *Frame) Material() *Material

func (*Frame) RectDraw

func (f *Frame) RectDraw(target BatchTarget, bounds Rect)

func (*Frame) RectDrawColorMask

func (f *Frame) RectDrawColorMask(target BatchTarget, bounds Rect, mask RGBA)

func (*Frame) Texture

func (f *Frame) Texture() *Texture

type Gamepad

type Gamepad int

type GamepadAxis

type GamepadAxis int

type GamepadButton

type GamepadButton int

type GeomDraw

type GeomDraw struct {
	Divisions int
	// contains filtered or unexported fields
}

func NewGeomDraw

func NewGeomDraw() *GeomDraw

func (*GeomDraw) Circle

func (g *GeomDraw) Circle(mesh *Mesh, center Vec3, radius float64, width float64)

func (*GeomDraw) Ellipse

func (g *GeomDraw) Ellipse(mesh *Mesh, center Vec3, size Vec2, rotation float64, width float64)

func (*GeomDraw) FillRect

func (g *GeomDraw) FillRect(rect Rect) *Mesh

func (*GeomDraw) FillRect2

func (g *GeomDraw) FillRect2(mesh *Mesh, rect Rect, mat glMat4)

func (*GeomDraw) Line

func (g *GeomDraw) Line(mesh *Mesh, a, b Vec3, lastAngle, nextAngle float64, width float64)

TODO different line endings

func (*GeomDraw) LineStrip

func (g *GeomDraw) LineStrip(mesh *Mesh, points []Vec3, width float64)

func (*GeomDraw) Polygon

func (g *GeomDraw) Polygon(mesh *Mesh, points []Vec3, width float64)

TODO - remake linestrip but don't have the looping indexes (ie modulo). This is technically for polygons

func (*GeomDraw) Polygon2D

func (g *GeomDraw) Polygon2D(mesh *Mesh, points []Vec2, width float64)

func (*GeomDraw) Rectangle

func (g *GeomDraw) Rectangle(rect Rect, width float64) *Mesh

if width == 0, then fill the rect

func (*GeomDraw) Rectangle2

func (g *GeomDraw) Rectangle2(mesh *Mesh, rect Rect, width float64)

if width == 0, then fill the rect

func (*GeomDraw) SetColor

func (g *GeomDraw) SetColor(color RGBA)

type GeometryFiller

type GeometryFiller interface {
	GetBuffer() *VertexBuffer // Returns a prebuild VertexBuffer

	// TODO: I think instead of BufferPool maybe just pass the shader (which has access to the buffer pool)
	// TODO: I think you can simplify all of the draw options into one struct and pass it by pointer
	Fill(*BufferPool, glMat4, RGBA) *VertexBuffer
	Bounds() glm.Box
}

TODO: I kindof want to implement one or the other

type Glyph

type Glyph struct {
	Advance  float64
	Bearing  Vec2
	BoundsUV Rect
}

type GlyphData

type GlyphData struct {
	Unicode     int
	Advance     float64
	PlaneBounds AtlasRect
	AtlasBounds AtlasRect
}

type ISubBuffer

type ISubBuffer interface {
	Clear()
	// VertexCount() uint32
	Buffer() []byte
	Offset() int
	Len() int
	Cap() int
	SetData(any)
}

TODO - rename

type Key

type Key int

type Mat4

type Mat4 = glm.Mat4

type Material

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

TODO: You could pack this down even more Shader: shader slot lut ID 256 maximum Texture: texture slot lut ID 256 maximum Uniform: uniform slot lut ID 256 maximum

func DefaultMaterial

func DefaultMaterial(texture *Texture) Material

func DefaultMsdfMaterial

func DefaultMsdfMaterial(texture *Texture) Material

func NewMaterial

func NewMaterial(shader *Shader) Material

func (Material) Bind

func (m Material) Bind()

func (*Material) SetBlendMode

func (m *Material) SetBlendMode(blendMode BlendMode) *Material

func (*Material) SetCullMode

func (m *Material) SetCullMode(cullMode CullMode) *Material

func (*Material) SetDepthMode

func (m *Material) SetDepthMode(depthMode DepthMode) *Material

func (*Material) SetShader

func (m *Material) SetShader(shader *Shader) *Material

func (*Material) SetTexture

func (m *Material) SetTexture(texture *Texture)

func (*Material) SetUniform

func (m *Material) SetUniform(name string, val any) *Material

type Mesh

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

func NewCubeMesh

func NewCubeMesh(size float64) *Mesh

func NewMesh

func NewMesh() *Mesh

func NewQuadMesh

func NewQuadMesh(bounds Rect, uvBounds Rect) *Mesh

func NewSpriteMesh

func NewSpriteMesh(w, h float64, uvBounds Rect) *Mesh

Basically a quad mesh, but with a centered position

func (*Mesh) Append

func (m *Mesh) Append(m2 *Mesh)

TODO - should this be more like draw?

func (*Mesh) AppendQuadMesh

func (m *Mesh) AppendQuadMesh(bounds Rect, uvBounds Rect, color RGBA)

func (*Mesh) Bounds

func (m *Mesh) Bounds() Box

func (*Mesh) Buffer

func (m *Mesh) Buffer(shader *Shader, translucent bool) *Mesh

func (*Mesh) Clear

func (m *Mesh) Clear()

TODO - clear function? Should append be more like draw?

func (*Mesh) Draw

func (m *Mesh) Draw(target BatchTarget, matrix Mat4)

func (*Mesh) DrawColorMask

func (m *Mesh) DrawColorMask(target BatchTarget, matrix Mat4, mask RGBA)

TODO - This should accept image/color and call RGBA(). Would that be slower?

func (*Mesh) Fill

func (m *Mesh) Fill(bufferPool *BufferPool, mat glMat4, mask RGBA) *VertexBuffer

func (*Mesh) GetBuffer

func (m *Mesh) GetBuffer() *VertexBuffer

func (*Mesh) Indices

func (m *Mesh) Indices() []uint32

func (*Mesh) NumVerts

func (m *Mesh) NumVerts() int

func (*Mesh) SetColor

func (m *Mesh) SetColor(col RGBA)

Sets the color of every vertex

func (*Mesh) WithSetOrigin

func (originalMesh *Mesh) WithSetOrigin(newOrigin Vec3) *Mesh

Changes the origin point of the mesh by translating all the geometry to the new origin. This shouldn't be called frequently Returns a newly allocated mesh and does not modify the original

type Metrics

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

func GetMetrics

func GetMetrics() Metrics

type Model

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

func NewModel

func NewModel(mesh *Mesh, material Material) *Model

func (*Model) Draw

func (m *Model) Draw(target BatchTarget, matrix Mat4)

func (*Model) DrawColorMask

func (m *Model) DrawColorMask(target BatchTarget, matrix Mat4, mask RGBA)

type NinePanelSprite

type NinePanelSprite struct {

	// Mask RGBA // This represents the default color mask to draw with (unless one is passed in via a draw function, Example: *Mask)
	Scale float64
	// contains filtered or unexported fields
}

func NewNinePanelSprite

func NewNinePanelSprite(texture *Texture, bounds Rect, border Rect) *NinePanelSprite

func SpriteToNinePanel

func SpriteToNinePanel(sprite *Sprite, border Rect) *NinePanelSprite

func (*NinePanelSprite) Border

func (s *NinePanelSprite) Border() Rect

The bounds of the borders rect

func (*NinePanelSprite) Bounds

func (s *NinePanelSprite) Bounds() Rect

func (*NinePanelSprite) RectDraw

func (s *NinePanelSprite) RectDraw(pass BatchTarget, bounds Rect)

func (*NinePanelSprite) RectDrawColorMask

func (s *NinePanelSprite) RectDrawColorMask(pass BatchTarget, rect Rect, mask RGBA)

func (*NinePanelSprite) SetTranslucent

func (s *NinePanelSprite) SetTranslucent(translucent bool)

type RGBA

type RGBA = glm.RGBA

type Rect

type Rect = glm.Rect

type RectFill

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

type ScreenModeType

type ScreenModeType glfw.ScreenModeType

type SdfAtlas

type SdfAtlas struct {
	Atlas   SdfAtlasPreamble
	Metrics SdfMetrics
	Glyphs  []GlyphData
}

type SdfAtlasPreamble

type SdfAtlasPreamble struct {
	Type                string
	DistanceRange       float64
	DistanceRangeMiddle int
	Size                int
	Width               int
	Height              int
	YOrigin             string
}

SDF ./msdf-atlas-gen/build/bin/msdf-atlas-gen -font ./Lato-Black.ttf -imageout atlas.png -json atlas.json -pots -size 32 -yorigin top -pxrange 10 PlaneBounds: https://github.com/Chlumsky/msdf-atlas-gen/issues/2

type SdfMetrics

type SdfMetrics struct {
	EmSize             int
	LineHeight         float64
	Ascender           float64
	Descender          float64
	UnderlineY         float64
	UnderlineThickness float64
}

type Shader

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

func GetDefaultMsdfShader

func GetDefaultMsdfShader() *Shader

func GetDefaultSpriteShader

func GetDefaultSpriteShader() *Shader

func NewShader

func NewShader(cfg shaders.ShaderConfig) (*Shader, error)

func NewShaderExt

func NewShaderExt(vertexSource, fragmentSource string, attrFmt shaders.VertexFormat, uniformFmt shaders.UniformFormat) (*Shader, error)

func (*Shader) BufferMesh

func (shader *Shader) BufferMesh(mesh *Mesh, translucent bool) *VertexBuffer

func (*Shader) SetUniform

func (s *Shader) SetUniform(name string, value any) bool

Binds the shader and sets the uniform

type SoftwareSortMode

type SoftwareSortMode uint8
const (
	SoftwareSortNone      SoftwareSortMode = iota
	SoftwareSortX                          // Sort based on the X position
	SoftwareSortY                          // Sort based on the Y position
	SoftwareSortZ                          // Sort based on the Z position
	SoftwareSortZNegative                  // Opposite order to SoftwareSortZ
	SoftwareSortCommand                    // Sort by the computed drawCommand.command
)

type Sorter

type Sorter struct {
	DepthTest    bool
	SoftwareSort SoftwareSortMode
	DepthBump    bool
	// contains filtered or unexported fields
}

you were here creating the sorter 1. every draw command needs ALL of the data to be sorted 2. you need to simplify the sorting to its all command based imo

func NewSorter

func NewSorter() *Sorter

func (*Sorter) Add

func (s *Sorter) Add(filler GeometryFiller, mat glMat4, mask RGBA, material Material, translucent bool)

func (*Sorter) Clear

func (s *Sorter) Clear()

func (*Sorter) Draw

func (s *Sorter) Draw(target BatchTarget)

func (*Sorter) Layer

func (s *Sorter) Layer() int8

func (*Sorter) SetLayer

func (s *Sorter) SetLayer(layer int8)

type Sprite

type Sprite struct {
	Translucent bool
	// contains filtered or unexported fields
}

func NewSprite

func NewSprite(texture *Texture, bounds Rect) *Sprite

func (*Sprite) Bounds

func (s *Sprite) Bounds() Rect

func (*Sprite) Draw

func (s *Sprite) Draw(target BatchTarget, matrix Mat4)

func (*Sprite) DrawColorMask

func (s *Sprite) DrawColorMask(target BatchTarget, matrix Mat4, mask RGBA)

func (*Sprite) Frame

func (s *Sprite) Frame() Rect

func (*Sprite) Material

func (s *Sprite) Material() *Material
func (s *Sprite) SetMaterial(material Material) {
	s.material = material
}

func (*Sprite) RectDraw

func (s *Sprite) RectDraw(target BatchTarget, bounds Rect)

func (*Sprite) RectDrawColorMask

func (s *Sprite) RectDrawColorMask(target BatchTarget, bounds Rect, mask RGBA)

func (*Sprite) SetTextureBounds

func (s *Sprite) SetTextureBounds(bounds Rect)

func (Sprite) WithSetOrigin

func (s Sprite) WithSetOrigin(origin Vec3) Sprite

Changes the origin point of the sprite by translating all the geometry to the new origin. This shouldn't be called frequently. The default origin is around the center of the sprite Returns a newly allocated mesh and does not modify the original

type SubBuffer

type SubBuffer[T SupportedSubBuffers] struct {
	// contains filtered or unexported fields
}

func (*SubBuffer[T]) Buffer

func (b *SubBuffer[T]) Buffer() []byte

func (*SubBuffer[T]) Cap

func (b *SubBuffer[T]) Cap() int

func (*SubBuffer[T]) Clear

func (b *SubBuffer[T]) Clear()

func (*SubBuffer[T]) Len

func (b *SubBuffer[T]) Len() int

func (*SubBuffer[T]) Offset

func (b *SubBuffer[T]) Offset() int

func (*SubBuffer[T]) Reserve

func (b *SubBuffer[T]) Reserve(count int) []T

func (*SubBuffer[T]) SetData

func (b *SubBuffer[T]) SetData(data any)

type SubSubBuffer

type SubSubBuffer[T SupportedSubBuffers] struct {
	Buffer []T
}

type SupportedSubBuffers

type SupportedSubBuffers interface {
	glVec4 | glVec3 | glVec2 | float32
}

type Target

type Target interface {
	// TODO - Should this be differentiated from being a source Vs a target binding. For example, I'm using this now to bind the target that we draw to. But If I want to have another function on frambuffers to use them as image texture inputs, what would that API be called?
	Bind()
}

type Text

type Text struct {
	Orig Vec2 // The baseline starting point from which to draw the text
	Dot  Vec2 // The location of the next rune to draw
	// contains filtered or unexported fields
}

func (*Text) AppendStringVerts

func (t *Text) AppendStringVerts(text string, measure bool) Rect

If measure is set true, dont add them to the text mesh, just measure the bounds of the string

func (*Text) Bounds

func (t *Text) Bounds() Rect

func (*Text) Clear

func (t *Text) Clear()

func (*Text) Draw

func (t *Text) Draw(target BatchTarget, matrix Mat4)

func (*Text) DrawColorMask

func (t *Text) DrawColorMask(target BatchTarget, matrix Mat4, color RGBA)

func (*Text) DrawRect

func (t *Text) DrawRect(target BatchTarget, rect Rect, color RGBA)

func (*Text) Material

func (t *Text) Material() *Material

func (*Text) MeshBounds

func (t *Text) MeshBounds() Rect

func (*Text) RectDraw

func (t *Text) RectDraw(target BatchTarget, rect Rect)

func (*Text) RectDrawColorMask

func (t *Text) RectDrawColorMask(target BatchTarget, bounds Rect, mask RGBA)

func (*Text) Set

func (t *Text) Set(str string)

This resets the text and sets it to the passed in string (if the passed in string is different!) TODO - I need to deprecate this in favor of a better interface

func (*Text) SetColor

func (t *Text) SetColor(col RGBA)

func (*Text) SetScale

func (t *Text) SetScale(scale float64)

func (*Text) SetShadow

func (t *Text) SetShadow(shadow Vec2)

func (*Text) SetWordWrap

func (t *Text) SetWordWrap(wrap bool, wrapRect Rect)

func (*Text) Write

func (t *Text) Write(p []byte) (n int, err error)

This appends the list of bytes onto the end of the string Note: implements io.Writer interface

func (*Text) WriteString

func (t *Text) WriteString(str string) (n int, err error)

type Texture

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

func NewEmptyTexture

func NewEmptyTexture(width, height int, smooth bool) *Texture

func NewRGBATexture

func NewRGBATexture(width, height int, col color.RGBA, smooth bool) *Texture

func NewTexture

func NewTexture(img image.Image, smooth bool) *Texture

func NewTransparentTexture64

func NewTransparentTexture64() *Texture

func WhiteTexture

func WhiteTexture() *Texture

func (*Texture) Bounds

func (t *Texture) Bounds() Rect

func (*Texture) GenerateMipmap

func (t *Texture) GenerateMipmap()

TODO: This needs to be combined into the NewTexture function, or this needs to bind the texture

func (*Texture) SetImage

func (t *Texture) SetImage(img image.Image)

Sets the texture to be this image. Texture size must match img size or this will panic! TODO - Should I just try and set it? or do nothing?

func (*Texture) SetPixels

func (t *Texture) SetPixels(x, y, w, h int, pixels []uint8)

Sets the pixels of a section of a texture

type Uniform

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

type Uniforms

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

func (*Uniforms) Bind

func (u *Uniforms) Bind(shader *Shader)

func (*Uniforms) Copy

func (u *Uniforms) Copy() *Uniforms

func (*Uniforms) SetUniform

func (u *Uniforms) SetUniform(name string, val any)

type Vec2

type Vec2 = glm.Vec2

type Vec3

type Vec3 = glm.Vec3

func EllipsePoints

func EllipsePoints(size Vec2, rotation float64, divisions int) []Vec3

Point generation functions:

type Vec4

type Vec4 = glm.Vec4

type VertexBuffer

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

func NewVertexBuffer

func NewVertexBuffer(shader *Shader, numVerts, numIndices int) *VertexBuffer

func (*VertexBuffer) Clear

func (v *VertexBuffer) Clear()

func (*VertexBuffer) Draw

func (v *VertexBuffer) Draw()

func (*VertexBuffer) Reserve

func (v *VertexBuffer) Reserve(indices []uint32, numVerts int, dests []interface{}) bool

type Window

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

func NewWindow

func NewWindow(width, height int, title string, config WindowConfig) (*Window, error)

func (*Window) Add

func (w *Window) Add(filler GeometryFiller, mat glMat4, mask RGBA, material Material, translucent bool)

func (*Window) AddCharCallback

func (w *Window) AddCharCallback(cb glfw.CharCallback)

func (*Window) AddKeyCallback

func (w *Window) AddKeyCallback(cb glfw.KeyCallback)

func (*Window) AddMouseButtonCallback

func (w *Window) AddMouseButtonCallback(cb glfw.MouseButtonCallback)

func (*Window) AddScrollCallback

func (w *Window) AddScrollCallback(cb glfw.ScrollCallback)

func (*Window) Bind

func (w *Window) Bind()

Binds the window as the OpenGL render targe

func (*Window) Bounds

func (w *Window) Bounds() Rect

func (*Window) BrowserHidden

func (w *Window) BrowserHidden() bool

Used to check if we are in browser and we are hidden. If not in a web browser this will always return false. Should be used to selectively disable code that shouldn't be run when the browser is hidden

func (*Window) Close

func (w *Window) Close()

func (*Window) Closed

func (w *Window) Closed() bool

func (*Window) ContentScale

func (w *Window) ContentScale() (float64, float64)

func (*Window) DisplaySize

func (w *Window) DisplaySize() [2]float32

func (*Window) EmbeddedIframe

func (w *Window) EmbeddedIframe() bool

Returns true if the window is embedded in an iframe, else returns false. Always returns false on desktop

func (*Window) FramebufferSize

func (w *Window) FramebufferSize() [2]float32

func (*Window) GetConnectedGamepads

func (w *Window) GetConnectedGamepads() []Gamepad

func (*Window) GetGamepadAxis

func (w *Window) GetGamepadAxis(g Gamepad, axis GamepadAxis) float64

Returns the gamepad axis value, ranging on -1 to +1

func (*Window) GetGamepadJustPressed

func (w *Window) GetGamepadJustPressed(g Gamepad, button GamepadButton) bool

Returns true if the gamepad button was just pressed this frame, else returns false

func (*Window) GetGamepadPressed

func (w *Window) GetGamepadPressed(g Gamepad, button GamepadButton) bool

Returns true if the gamepad button is pressed, else returns false

func (*Window) GetMouse

func (w *Window) GetMouse() (x, y float64)

--- Dear Imgui required ---

func (*Window) GetMouseButton

func (w *Window) GetMouseButton(b glfw.MouseButton) glfw.Action

func (*Window) GetPrimaryGamepad

func (w *Window) GetPrimaryGamepad() Gamepad

Returns the primary gamepad

func (*Window) JustPressed

func (w *Window) JustPressed(key Key) bool

// Returns true if the key was pressed in the last frame

func (*Window) JustReleased

func (w *Window) JustReleased(key Key) bool

func (*Window) MousePosition

func (w *Window) MousePosition() (float64, float64)

func (*Window) MouseScroll

func (w *Window) MouseScroll() (float64, float64)

func (*Window) Pressed

func (w *Window) Pressed(key Key) bool

func (*Window) Repeated

func (w *Window) Repeated(key Key) bool

func (*Window) ScreenMode

func (w *Window) ScreenMode() ScreenModeType

func (*Window) SetCursor

func (w *Window) SetCursor(mode CursorMode)

func (*Window) SetScreenMode

func (w *Window) SetScreenMode(smt ScreenModeType)

TODO - rename. also maybe do modes - window, borderless, full, etc.

func (*Window) SetVSync

func (w *Window) SetVSync(enable bool)

TODO - rename. Also potentially allow for multiple swaps?

func (*Window) Typed

func (w *Window) Typed() []rune

Don't cache the returned buffer because it gets overwritten

func (*Window) Update

func (w *Window) Update()

type WindowConfig

type WindowConfig struct {
	Fullscreen  bool
	Undecorated bool
	Maximized   bool
	Vsync       bool
	// Resizable bool
	Samples int
}

Directories

Path Synopsis
3d
sdf
ui
web
internal
gl
Package gl is a Go cross-platform binding for OpenGL, with an OpenGL ES 2-like API.
Package gl is a Go cross-platform binding for OpenGL, with an OpenGL ES 2-like API.
glfw
Package glfw experimentally provides a glfw-like API with desktop (via glfw) and browser (via HTML5 canvas) backends.
Package glfw experimentally provides a glfw-like API with desktop (via glfw) and browser (via HTML5 canvas) backends.

Jump to

Keyboard shortcuts

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