Documentation ¶
Overview ¶
Package ggl defines essential abstraction over opengl types, you should use this and dodge gl calls to make you code cleaner. If struct has methdod Drop it has to be called in order to prevent memory leak. All main datatypes that has Drop method contain pointer to underlining gl object so droping one struct makes all copies dengling and using them can produce undefined behavior. All constructors starts with N folwed by name of a struct. If struct ha a constructor it has to be used or you will not get expected behavior. Other methods that are repetitive are Start() and End<StructName>(), this is for binding and unbinding objects. Because calling gl functions introduces 120 nanoseconds overhead so package uses global state to skip redundant start and end calls, using of global state si justified by the fact that YOU HAVE TO USE ALL STRUCTS INTERFACING OPENGL OBJECTS FROM THREAD WHERE YOU CREATED A WINDOW anyway.
Package also utilizes gogen code generator (github.com/jakubDoka/gogen)
Index ¶
- Constants
- Variables
- func Clear(c mat.RGBA, mode ClearMode)
- func EndCanvas()
- func EndProgram()
- func EndTexture()
- func EndVao()
- func EndVbo()
- func FlipNRGBA(r *image.NRGBA)
- func LoadImage(p string) (*image.NRGBA, error)
- func PadMap(frame, padding mat.AABB) (v, h [4]float64)
- func SetBlend(val bool)
- func VerifyVertexData(v VertexData) error
- type Batch
- type Buffer
- type Canvas
- func (c *Canvas) Clear(color mat.RGBA)
- func (c *Canvas) ClearMode(color mat.RGBA, mode ClearMode)
- func (c *Canvas) Draw(t Renderer, mat mat.Mat, mask mat.RGBA)
- func (c *Canvas) Drop()
- func (c *Canvas) Frame() mat.AABB
- func (c *Canvas) Rect() mat.AABB
- func (c *Canvas) Render(data VertexData, indices Indices, texture *Texture, program *Program, ...)
- func (c *Canvas) RenderToScreen(mat mat.Mat, mask mat.RGBA, w, h int32)
- func (c *Canvas) Resize(frame mat.AABB)
- func (c *Canvas) SetCamera(mat mat.Mat)
- func (c *Canvas) Start()
- type ClearMode
- type Data
- type Drawer
- type Fetcher
- type Indices
- type Patch
- func (n *Patch) Draw(t Target, mat mat.Mat, mask mat.RGBA)
- func (n *Patch) Fetch(t Target)
- func (n *Patch) Resize(width, height float64)
- func (n *Patch) SetColor(value mat.RGBA)
- func (n *Patch) SetDist(dst mat.AABB)
- func (n *Patch) SetIntensity(value float64)
- func (n *Patch) Size() mat.Vec
- func (n *Patch) Update(mat mat.Mat, mask mat.RGBA)
- type Program
- func (p *Program) Drop()
- func (p *Program) SetCamera(mat mat.Mat)
- func (p *Program) SetInt(name string, i int32)
- func (p *Program) SetMat(name string, m *mat.Mat)
- func (p *Program) SetTextureSize(w, h int32)
- func (p *Program) SetUseTexture(b bool)
- func (p *Program) SetVec(name string, v mat.Vec)
- func (p *Program) SetViewportSize(w, h int32)
- func (p *Program) Start()
- type Ptr
- type Renderer
- type Setup
- type Setup2D
- func (s Setup2D) Batch(texture *Texture, fragmentShader string) (*Batch, error)
- func (s Setup2D) Buffer() Buffer
- func (s Setup2D) Canvas(w, h int, fragmentShader string) (*Canvas, error)
- func (s Setup2D) FragmentShader() string
- func (s Setup2D) Modify(win *Window)
- func (s Setup2D) VertexShader() string
- type Shader
- func LoadFragmentShader(p string) (*Shader, error)
- func LoadShader(p string, shaderType uint32) (*Shader, error)
- func LoadVertexShader(p string) (*Shader, error)
- func NFragmentShader(source string) (*Shader, error)
- func NShader(source string, shaderType uint32) (*Shader, error)
- func NVertexShader(source string) (*Shader, error)
- type Sprite
- func (s *Sprite) Clear()
- func (s *Sprite) Draw(b Target, mat mat.Mat, mask mat.RGBA)
- func (s *Sprite) Fetch(b Target)
- func (s *Sprite) Set(dst, src mat.AABB)
- func (s *Sprite) SetColor(value mat.RGBA)
- func (s *Sprite) SetDist(dst mat.AABB)
- func (s *Sprite) SetIntensity(value float64)
- func (s *Sprite) Size() mat.Vec
- func (s *Sprite) Update(mat mat.Mat, mask mat.RGBA)
- type Target
- type Texture
- type TextureParam
- type Updater
- type VAO
- type VBO
- type Vertex
- type VertexData
- type Vertexes
- type Window
- func (w *Window) JustPressed(button key.Key) bool
- func (w *Window) JustReleased(button key.Key) bool
- func (w *Window) MouseIsInside() bool
- func (w *Window) MousePos() mat.Vec
- func (w *Window) MousePrevPos() mat.Vec
- func (w *Window) MouseScroll() mat.Vec
- func (w *Window) Pressed(button key.Key) bool
- func (w *Window) Repeated(button key.Key) bool
- func (w *Window) Typed() string
- func (w *Window) Update()
- type WindowConfig
- type WindowHint
Constants ¶
const ( SpriteVertexSize = 4 SpriteIndicesSize = 6 NinePatchSide = 3 )
Sprite related constants
const Dynamic = gl.DYNAMIC_DRAW
Dynamic combines Static and stream
const Static = gl.STATIC_DRAW
Static is used when you want to draw once and reuse multiple times
const Stream = gl.STREAM_DRAW
Stream is used when you want to update a lot and use at most few times
Variables ¶
var DefaultTextureConfig = []TextureParam{ {gl.TEXTURE_MIN_FILTER, gl.NEAREST}, {gl.TEXTURE_MAG_FILTER, gl.NEAREST}, }
DefaultTextureConfig use this if you don't know what to use
var SpriteIndices = Indices{0, 1, 2, 0, 3, 2}
SpriteIndices is slice of constant indices used by Sprite
Functions ¶
func PadMap ¶
PadMap creates padding break points with help of witch we can determinate vertices of Patch, think of v as four vertical lines and h as 4 horizontal lines, if you draw them on paper you will get 9 rectangles
func VerifyVertexData ¶
func VerifyVertexData(v VertexData) error
VerifyVertexData should be used in UnitTest to verify that type you are using for VertexData is safe for use. Function uses heavy reflection and is not suited for ordinary usage.
Types ¶
type Batch ¶
Batch is main drawer, it performs direct draw to canvas and is used as target for Sprite. Batch acts like canvas i some ways but performance difference of drawing Batch to canvas and drawing canvas to canvas is significant. If you need image to ber redrawn ewer frame draw Batch to canvas and use canvas for drawing.
type Buffer ¶
Buffer combines VAO and VBO to finally draw to current frame buffer
func NBuffer ¶
NBuffer setups a buffer, sizes are passed to VBO constructor, indices determine whether you want to use EBO or not
type Canvas ¶
type Canvas struct { Ptr Texture Program Buffer Buffer ClearColor mat.RGBA // contains filtered or unexported fields }
Canvas allows of screen drawing, drawing to canvas produces draw calls. Its the abstraction over opengl framebuffer. It stores drawn image in given texture, if you want to capture it use Image method on texture. Program that canvas uses is applied on resulting image but also on triangles drawn by batch that does not have custom program. Same goes for Buffer.
func NCanvas ¶
NCanvas creates new framebuffer, all three arguments has to e valid instances of gl objects for canvas to work.
buff := ggl.NBuffer(2, 2, 4) // see buffer doc prog := ggl.LoadProgram("yourVertex.glsl", "yourFragment.glsl") texture := ggl.RawTexture(canvasInitialWidth, canvasInitialHeight, nil, DefaultTextureConfig) canvas := NCanvas(*texture, *program, buffer)
the texture you are creating is a drawing target, you can of corse use existing texture,draw to it and then capture the result via image:
img := canvas.Image() // returning savable image
func (*Canvas) Draw ¶
Draw draws canvas to another target as a sprite
c.Render(t, mat.IM, mat.Alpha(1)) //draws framebuffer to the center of a screen as it is to t c.Render(t, mat.IM.Scaled(mat.Vec{}, 2), mat.RGB(1, 0, 0)) //draws framebuffer scaled up with red mask to t
method makes draw call
func (*Canvas) Render ¶
func (c *Canvas) Render(data VertexData, indices Indices, texture *Texture, program *Program, buffer *Buffer)
Render implements Renderer interface
func (*Canvas) RenderToScreen ¶
RenderToScreen renders canvas to main framebuffer (window framebuffer) as a sprite:
c.Render(mat.IM, mat.Alpha(1)) //draws framebuffer to the center of a screen as it is c.Render(mat.IM.Scaled(mat.Vec{}, 2), mat.RGB(1, 0, 0)) //draws framebuffer scaled up with red mask
method makes draw call
func (*Canvas) Resize ¶
Resize resizes the canvas to given frame, canvas viewport is also set, that why you are passing frame,
type ClearMode ¶
type ClearMode uint32
ClearMode is enum type used for clearing a framebuffer
const ( Color ClearMode = gl.COLOR_BUFFER_BIT Depth ClearMode = gl.DEPTH_BUFFER_BIT Stencil ClearMode = gl.STENCIL_BUFFER_BIT )
Clearing modes
type Data ¶
Data is Vertex and indice collector, mainly utility that handles vertex offsets it also stores one aditionall slice as space for preporsessing
func (*Data) Accept ¶
Accept accepts vertex Data, this is only correct way of feeding batch with Vertexes along side indices, if you don't use indices append directly to Data
type Drawer ¶
Drawer is triangle drawer, it should always preporcess triangles with given matrix and color and then give them to target
type Fetcher ¶
type Fetcher interface {
Fetch(b Target)
}
Fetcher is something that only passes triangle data, and does no preprocessing use Fetch if you don't need to modify triangles, its faster for all structs that implement this interface
type Indices ¶
type Indices []uint32
Indices are drawing indices passed to opengl to lower data traffic. Theier use is optional you can always pass nil if you don't want to use them. Though mind that if Batch already contain indices produced by other drawer you have to use them otherwise your triangles will not get rendered.
type Patch ¶
Patch consists of grid layout of 3x3 sprites that together form a continuous rectangle. Even though it has same properties as sprite, every operation is 9x as expensive, now little showcase of how NPS works:
+-+-+-+ +-+------+-+ | | | | | | | | +-+-+-+ +-+------+-+ | | | | | | | | +-+-+-+ +-+------+-+ | | | | | | | | +-+-+-+ (7, 7) +-+------+-+ (12, 7)
Patch is not window thread dependant
func (*Patch) Resize ¶
Resize resizes NPS to given width and height, corners will stay as same scale while other 5 parts scale up accordingly to create continuos Rectangle. This is mainly usefull for ui panels and flexible frames.
func (*Patch) SetIntensity ¶
SetIntensity sets intensity of all inner sprites, so it has same effect as sprite intensity
type Program ¶
type Program struct { Ptr // contains filtered or unexported fields }
Program is handle to opengl shader program
func LoadProgram ¶
LoadProgram loads program from disk
func NProgramFromSource ¶
NProgramFromSource ...
func (*Program) SetTextureSize ¶
SetTextureSize sets "textureSize" in vertex shader, if the size is already equal to given values it does nothing
func (*Program) SetUseTexture ¶
SetUseTexture sets "useTexture" in fragment shader, its noop if value is already in given state
func (*Program) SetViewportSize ¶
SetViewportSize sets "viewportSize" in vertex shader, if the size is already equal to given values it does nothing
type Ptr ¶
type Ptr struct {
// contains filtered or unexported fields
}
Ptr is convenience struct, is sores pointer and only allows reading it
type Renderer ¶
type Renderer interface {
Render(data VertexData, indices Indices, texture *Texture, program *Program, buffer *Buffer)
}
Renderer is something that you can draw to, last tree parameters can be optional and not even be used by a target, though if you don't provide tham when you should Target can fall back to defaults or panic
type Setup ¶
type Setup interface { // VertexShader returns vertex shader source code of Setup FragmentShader() string // FragmentShader returns fragment shader source of Setup VertexShader() string // Buffer returns buffer that window will use Buffer() Buffer // Modify leaves space for some additional modification Modify(win *Window) }
Setup is something that sets up the window drawing state, as library will support and 3D different Setups can be used. its preferale to use lib setup with composition and override methods
type Setup2D ¶
type Setup2D struct{}
Setup2D is basic game rendering setup, if you would like to change some part of it just embed it in your setup struct and override methods. Thought setup isn't just that, it brings lot of utility to its scope to separate it from 3D setup (comming soon)
func (Setup2D) Batch ¶
Batch creates batch from texture with fragment shader, it does the setup of shader program for you
func (Setup2D) FragmentShader ¶
FragmentShader implements Setup interface
func (Setup2D) VertexShader ¶
VertexShader implements Setup interface
type Shader ¶
type Shader struct {
Ptr
}
Shader represents gl sager object
func LoadShader ¶
LoadShader loads shader from disk
type Sprite ¶
type Sprite struct {
// contains filtered or unexported fields
}
Sprite is most efficient way of drawing textures to Batch (if you find faster way i welcome your pr) sprite does not allocate any memory all data is on stack, its designed to be easily copied by value.
Sprite is not window thread dependant
func NSprite ¶
NSprite creates new sprite out of frame. Frame should be the region where the texture, you want to draw, is located on spritesheet
ggl.NSprite(yourTexture.Frame()) // draws whole texture
func (*Sprite) Clear ¶
func (s *Sprite) Clear()
Clear makes sprite invisible when its drawn, this is to impelemt paceholder data
func (*Sprite) Set ¶
Set sets sprites source texture region and destination rectangle, this is mainly used when drawing text
func (*Sprite) SetIntensity ¶
SetIntensity sets the intensity of sprite image, if you set it to 0 the rectangle in a color of sprite mask will be drawn, if you set it to 1 (which is default) it will draw texture as it is or black area if batch does not have texture.
type Target ¶
Target is something that accepts triangle data, but data is just copied, is is not used for anything, though shifting of indices is Targets roles
type Texture ¶
Texture is a handle to opengl texture object
func LoadTexture ¶
LoadTexture loads texture from disk and creates gl texture from it:
tex, err := LoadTexture("maPath.png")
Use NTexture instead if you have to modify it before turning it into gl object, Note that texture is fed with default params and converted ti *image.RGBA if format does not match
func NTextureWithParams ¶
func NTextureWithParams(img image.Image, flip bool, params ...TextureParam) *Texture
NTextureWithParams allows you to specify additional parameters when creating texture, paramethers are then in code set like:
for _, p := range params { gl.TexParameteri(gl.TEXTURE_, p.First, p.Second) }
Note that even though this function takes image.Image it will always convert it to image.NRGBA witch should already be present as png is parsed int this format. In order to not affect original image, image is copied either way. If you need multiple instances of texture but faster, flip or convert the image your self and use RawTexture instead.
func RawTexture ¶
func RawTexture(w, h int32, pixels []byte, params ...TextureParam) *Texture
RawTexture creates texture out of raw parts, if you do not provide bytes slice texture will be empty but opengl will allocate memory
func (*Texture) Image ¶
Image withdraws texture data from gpu, this is mainly usefull for capturing framebuffer state it basically makes recording possible
type TextureParam ¶
TextureParam specifies what is passed to gl.TextureParameteri
type VBO ¶
type VBO struct { Ptr // contains filtered or unexported fields }
VBO abstracts over opengl array buffer
func NVBO ¶
NVBO initializes buffer structure:
ggl.NVBO(2, 2, 4) // initializes buffer with 3 pointers with given sizes
Then in your vertex shader you access them like:
layout (location = 0) in vec2 vert; layout (location = 1) in vec2 tex; layout (location = 2) in vec4 mask;
bdw this is default buffer setup
func (*VBO) SetData ¶
func (v *VBO) SetData(data VertexData, mode uint32)
SetData loads data into VBO, for mode you can use gl version, or redefined package modes that also have some comments, Stream is mostly the best option.
panics if buffer vertexSize does not match with data vertex size
type VertexData ¶
type VertexData interface { // Len simply returns length of slice Len() int // VertexSize is amount of floats one element of VertexData contains VertexSize() int }
VertexData is what you use to hand data to opengl, its very important for you to pass a Slice containing doubles or structs composed only from doubles. If you are not sure whether your data is valid call VerifyVertexData with instance of your data, it will return helpfull error if behavior is not satisfied, though function is slow thats why its not used to infer parameters that you can provide with lot lower overhead.
type Vertexes ¶
type Vertexes []Vertex
Vertexes implements essential utility methods for any struct satisfying VertexData interface. Its a gogen TEMPLATE:
/*gen( Vertexes<Vertex, 9, Vertexes> )*/
this block generates VertexSlice with Vertex and 8 is the size of Vertex, Vertexes is name of generated struct divided by float64 byte size for more info search github.com/jakubDoka/gogen.
func (Vertexes) VertexSize ¶
VertexSize implements VertexData interface
type Window ¶
Window enables use of almost all other structs avaliable in this package, Window initializes opengl context.
func NWindow ¶
func NWindow(config *WindowConfig) (*Window, error)
NWindow creates new window from WindowConfig, if config is nil, default one will be used
func (*Window) JustPressed ¶
JustPressed returns whether the Button has just been pressed down.
func (*Window) JustReleased ¶
JustReleased returns whether the Button has just been released up.
func (*Window) MouseIsInside ¶
MouseIsInside returns true if the mouse position is within the Window's Bounds.
func (*Window) MousePrevPos ¶
MousePrevPos returns the previous mouse position in the Window's Bounds.
func (*Window) MouseScroll ¶
MouseScroll returns the mouse scroll amount (in both axes) since the last call to Window.Update.
func (*Window) Repeated ¶
Repeated returns whether a repeat event has been triggered on button.
Repeat event occurs repeatedly when a button is held down for some time.
type WindowConfig ¶
type WindowConfig struct { Setup Setup Width, Height int Title string Resizable bool Undecorated bool TransparentFramebuffer bool AlwaysOnTop bool NoIconify bool Maximized bool Invisible bool Hints []WindowHint Monitor *glfw.Monitor }
WindowConfig stores configuration for window, But that des not mean you cannot set these propertis later on, Its just nicer to have ewerithing on one place
type WindowHint ¶
WindowHint allows to specify vindow hints (revolution right here)