diff --git a/actor.go b/actor.go index da247ee..8314210 100644 --- a/actor.go +++ b/actor.go @@ -1,5 +1,9 @@ package goga +var ( + actorIdGen = ActorId(0) +) + // An actor ID is a unique integer, // which can be used to reference an actor. type ActorId uint64 @@ -10,10 +14,6 @@ type Actor struct { id ActorId } -var ( - actorIdGen = ActorId(0) -) - // Creates a new basic actor with unique ID. func NewActor() *Actor { actorIdGen++ diff --git a/game.go b/game.go index 45e3709..b650ab8 100644 --- a/game.go +++ b/game.go @@ -16,6 +16,20 @@ const ( default_exit_on_close = true ) +var ( + running = true + clearColor = Vec4{} + clearBuffer []uint32 + viewportWidth int + viewportHeight int + + // Default resources + DefaultCamera *Camera + Default2DShader *Shader + Default3DShader *Shader + DefaultTextShader *Shader +) + // If set in RunOptions, the function will be called on window resize. type ResizeCallback func(width, height int) @@ -43,20 +57,6 @@ type Game interface { Update(float64) } -var ( - running = true - clearColor = Vec4{} - clearBuffer []uint32 - viewportWidth int - viewportHeight int - - // Default resources - DefaultCamera *Camera - Default2DShader *Shader - Default3DShader *Shader - DefaultTextShader *Shader -) - func init() { // GL functions must be called from main thread, // so we disable multithreading by the runtime here. diff --git a/keyframe.go b/keyframe.go index cc3d0f4..bdcb65b 100644 --- a/keyframe.go +++ b/keyframe.go @@ -14,44 +14,6 @@ type Keyframe struct { Min, Max Vec2 } -// A set of keyframes making up an animation. -type KeyframeSet struct { - Keyframes []Keyframe -} - -// Keyframe animation component. -// It has a start and an end frame, a play speed and option to loop. -type KeyframeAnimation struct { - Start, End int - Loop bool - Speed float64 - Current int - Interpolation float64 -} - -// An animated sprite is a sprite with keyframe animation information. -// It will be updated and rendered by the KeyframeRenderer. -type AnimatedSprite struct { - *Actor - *Pos2D - *Tex - *KeyframeSet - *KeyframeAnimation -} - -// The keyframe renderer renders animated sprites. -// It has a 2D position component, to move all sprites at once. -type KeyframeRenderer struct { - Pos2D - - Shader *Shader - Camera *Camera - - sprites []AnimatedSprite - index, vertex *VBO - vao *VAO -} - // Creates a new single keyframe with texture VBO. func NewKeyframe(min, max Vec2) *Keyframe { keyframe := &Keyframe{Min: min, Max: max} @@ -74,6 +36,11 @@ func NewKeyframe(min, max Vec2) *Keyframe { return keyframe } +// A set of keyframes making up an animation. +type KeyframeSet struct { + Keyframes []Keyframe +} + // Creates a new empty keyframe set with given size. func NewKeyframeSet() *KeyframeSet { set := &KeyframeSet{} @@ -88,11 +55,31 @@ func (s *KeyframeSet) Add(frame *Keyframe) int { return len(s.Keyframes) } +// Keyframe animation component. +// It has a start and an end frame, a play speed and option to loop. +type KeyframeAnimation struct { + Start, End int + Loop bool + Speed float64 + Current int + Interpolation float64 +} + // Creates a new keyframe animation with given start, end and loop. func NewKeyframeAnimation(start, end int, loop bool, speed float64) *KeyframeAnimation { return &KeyframeAnimation{start, end, loop, speed, 0, 0} } +// An animated sprite is a sprite with keyframe animation information. +// It will be updated and rendered by the KeyframeRenderer. +type AnimatedSprite struct { + *Actor + *Pos2D + *Tex + *KeyframeSet + *KeyframeAnimation +} + // Creates a new animated sprite. func NewAnimatedSprite(tex *Tex, set *KeyframeSet, width, height int) *AnimatedSprite { sprite := &AnimatedSprite{} @@ -114,6 +101,19 @@ func NewAnimatedSprite(tex *Tex, set *KeyframeSet, width, height int) *AnimatedS return sprite } +// The keyframe renderer renders animated sprites. +// It has a 2D position component, to move all sprites at once. +type KeyframeRenderer struct { + Pos2D + + Shader *Shader + Camera *Camera + + sprites []AnimatedSprite + index, vertex *VBO + vao *VAO +} + // Creates a new keyframe renderer using given shader and camera. // If shader and/or camera are nil, the default one will be used. func NewKeyframeRenderer(shader *Shader, camera *Camera) *KeyframeRenderer { diff --git a/loader.go b/loader.go index 90b4148..a1287c9 100644 --- a/loader.go +++ b/loader.go @@ -21,27 +21,6 @@ type PngLoader struct { KeepData bool } -// Standford ply file resource. -type Ply struct { - name string - path string - ext string - - firstLine, data, hasVertex, hasTexCoord, hasNormal bool - elements, faces int - indices []uint32 - vertices, texCoords, normals []float32 - - IndexBuffer, VertexBuffer, TexCoordBuffer, NormalBuffer *VBO -} - -// Loads ply files and creates VBOs within the Ply resource. -// The indices must be present as triangles. -// Expected type is float32. If it fails to parse, it will panic. -type PlyLoader struct { - VboUsage uint32 -} - func (p *PngLoader) Load(file string) (Res, error) { // load texture imgFile, err := os.Open(file) @@ -82,6 +61,27 @@ func (p *PngLoader) Ext() string { return "png" } +// Standford ply file resource. +type Ply struct { + name string + path string + ext string + + firstLine, data, hasVertex, hasTexCoord, hasNormal bool + elements, faces int + indices []uint32 + vertices, texCoords, normals []float32 + + IndexBuffer, VertexBuffer, TexCoordBuffer, NormalBuffer *VBO +} + +// Loads ply files and creates VBOs within the Ply resource. +// The indices must be present as triangles. +// Expected type is float32. If it fails to parse, it will panic. +type PlyLoader struct { + VboUsage uint32 +} + // Drops contained GL buffers. func (p *Ply) Drop() { if p.IndexBuffer != nil { diff --git a/model.go b/model.go index f4033e5..0ca2c77 100644 --- a/model.go +++ b/model.go @@ -14,26 +14,6 @@ type Mesh struct { Vao *VAO } -// Model is an actor having a 3D position, a texture and a 3D mesh. -type Model struct { - *Actor - *Pos3D - *Tex - *Mesh -} - -// The model renderer is a system rendering models. -// It has a 3D position component, to move all models at once. -type ModelRenderer struct { - Pos3D - - Shader *Shader - Camera *Camera - ortho bool - - models []Model -} - // Creates a new mesh with given GL buffers. // The VAO must be prepared by ModelRenderer. func NewMesh(index, vertex, texcoord *VBO) *Mesh { @@ -56,6 +36,14 @@ func (m *Mesh) Drop() { m.Vao.Drop() } +// Model is an actor having a 3D position, a texture and a 3D mesh. +type Model struct { + *Actor + *Pos3D + *Tex + *Mesh +} + // Creates a new model with given mesh and texture. func NewModel(mesh *Mesh, tex *Tex) *Model { model := &Model{} @@ -72,6 +60,18 @@ func NewModel(mesh *Mesh, tex *Tex) *Model { return model } +// The model renderer is a system rendering models. +// It has a 3D position component, to move all models at once. +type ModelRenderer struct { + Pos3D + + Shader *Shader + Camera *Camera + ortho bool + + models []Model +} + // Creates a new model renderer using given shader and camera. // If shader and/or camera are nil, the default one will be used. // Orth can be set to true, to use orthogonal projection. diff --git a/pos.go b/pos.go index bfefd5a..9cbdbc7 100644 --- a/pos.go +++ b/pos.go @@ -8,13 +8,6 @@ type Pos2D struct { M Mat3 } -// Position component for 3D objects -type Pos3D struct { - Pos, Size, Scale, RotPoint, Rot Vec3 - Visible bool - M Mat4 -} - // Creates a default initialized Pos2D. func NewPos2D() *Pos2D { m := Mat3{} @@ -45,6 +38,13 @@ func (p *Pos2D) PointInRect(point Vec2) bool { return point.X > p.Pos.X && point.X < p.Pos.X+p.Size.X*p.Scale.X && point.Y > p.Pos.Y && point.Y < p.Pos.Y+p.Size.Y*p.Scale.Y } +// Position component for 3D objects +type Pos3D struct { + Pos, Size, Scale, RotPoint, Rot Vec3 + Visible bool + M Mat4 +} + // Creates a default initialized Pos3D. func NewPos3D() *Pos3D { m := Mat4{} diff --git a/scene.go b/scene.go index 594624d..051e992 100644 --- a/scene.go +++ b/scene.go @@ -4,6 +4,11 @@ import ( "log" ) +var ( + scenes []Scene + activeScene Scene +) + // A scene used to switch between game states. // The Cleanup() method is called when a scene is removed // or the program is stopped. It can be used to cleanup open resources @@ -19,11 +24,6 @@ type Scene interface { GetName() string } -var ( - scenes []Scene - activeScene Scene -) - // Adds a scene to game. // Returns false if the scene exists already. // The first scene added will be set active. diff --git a/sprite.go b/sprite.go index 06aea5c..be4c0bd 100644 --- a/sprite.go +++ b/sprite.go @@ -15,19 +15,6 @@ type Sprite struct { *Tex } -// The sprite renderer is a system rendering sprites. -// It has a 2D position component, to move all sprites at once. -type SpriteRenderer struct { - Pos2D - - Shader *Shader - Camera *Camera - - sprites []Sprite - index, vertex, texCoord *VBO - vao *VAO -} - // Creates a new sprite with given texture. func NewSprite(tex *Tex) *Sprite { sprite := &Sprite{} @@ -43,6 +30,19 @@ func NewSprite(tex *Tex) *Sprite { return sprite } +// The sprite renderer is a system rendering sprites. +// It has a 2D position component, to move all sprites at once. +type SpriteRenderer struct { + Pos2D + + Shader *Shader + Camera *Camera + + sprites []Sprite + index, vertex, texCoord *VBO + vao *VAO +} + // Creates a new sprite renderer using given shader and camera. // If shader and/or camera are nil, the default one will be used. func NewSpriteRenderer(shader *Shader, camera *Camera, flip bool) *SpriteRenderer { diff --git a/system.go b/system.go index f80c793..fcaefe5 100644 --- a/system.go +++ b/system.go @@ -2,6 +2,10 @@ package goga import () +var ( + systems []System +) + // A system provides logic for actors satisfying required components. // They are automatically updated on each frame. // When a system is removed from systems, the Cleanup() method will be called. @@ -17,10 +21,6 @@ type System interface { GetName() string } -var ( - systems []System -) - // Adds a system to the game. // Returns false if the system exists already. func AddSystem(system System) bool { diff --git a/text.go b/text.go index 5990374..3f46074 100644 --- a/text.go +++ b/text.go @@ -32,36 +32,6 @@ type Font struct { chars []character } -// Renderable text component. -// Use together with Text and create using NewText(). -type TextComponent struct { - Color Vec4 - - text string - bounds Vec2 - index, vertex, texCoord *VBO - vao *VAO -} - -// Text is an actor representing text rendered as texture mapped font. -// Each Text has a position and its own buffers. -type Text struct { - *Actor - *Pos2D - *TextComponent -} - -// The text renderer is a system rendering 2D texture mapped font. -// It has a 2D position component, to move all texts at once. -type TextRenderer struct { - Pos2D - - Shader *Shader - Camera *Camera - Font *Font - texts []Text -} - // Creates a new font for given texture. // The tile size specifies the size of one character tile on texture. // Characters must be added afterwards. @@ -78,47 +48,6 @@ func NewFont(tex *Tex, tileSize float64) *Font { return &font } -// Returns a new renderable text object. -func NewText(font *Font, textStr string) *Text { - text := Text{} - text.Actor = NewActor() - text.Pos2D = NewPos2D() - text.TextComponent = &TextComponent{} - text.index = NewVBO(gl.ELEMENT_ARRAY_BUFFER) - text.vertex = NewVBO(gl.ARRAY_BUFFER) - text.texCoord = NewVBO(gl.ARRAY_BUFFER) - text.vao = NewVAO() - text.SetText(font, textStr) - text.Color = Vec4{1, 1, 1, 1} - text.Size = Vec2{1, 1} - text.Scale = Vec2{1, 1} - text.Visible = true - - return &text -} - -// Creates a new text renderer using given shader, camera and font. -// If shader and/or camera are nil, the default one will be used. -func NewTextRenderer(shader *Shader, camera *Camera, font *Font) *TextRenderer { - if shader == nil { - shader = DefaultTextShader - } - - if camera == nil { - camera = DefaultCamera - } - - renderer := &TextRenderer{} - renderer.Shader = shader - renderer.Camera = camera - renderer.Font = font - renderer.texts = make([]Text, 0) - renderer.Size = Vec2{1, 1} - renderer.Scale = Vec2{1, 1} - - return renderer -} - // Loads characters from JSON file. // Format: // @@ -229,6 +158,17 @@ func (f *Font) getChar(char byte) *character { return nil } +// Renderable text component. +// Use together with Text and create using NewText(). +type TextComponent struct { + Color Vec4 + + text string + bounds Vec2 + index, vertex, texCoord *VBO + vao *VAO +} + // Deletes GL buffers bound to this text component. func (t *TextComponent) Drop() { t.index.Drop() @@ -237,6 +177,33 @@ func (t *TextComponent) Drop() { t.vao.Drop() } +// Text is an actor representing text rendered as texture mapped font. +// Each Text has a position and its own buffers. +type Text struct { + *Actor + *Pos2D + *TextComponent +} + +// Returns a new renderable text object. +func NewText(font *Font, textStr string) *Text { + text := Text{} + text.Actor = NewActor() + text.Pos2D = NewPos2D() + text.TextComponent = &TextComponent{} + text.index = NewVBO(gl.ELEMENT_ARRAY_BUFFER) + text.vertex = NewVBO(gl.ARRAY_BUFFER) + text.texCoord = NewVBO(gl.ARRAY_BUFFER) + text.vao = NewVAO() + text.SetText(font, textStr) + text.Color = Vec4{1, 1, 1, 1} + text.Size = Vec2{1, 1} + text.Scale = Vec2{1, 1} + text.Visible = true + + return &text +} + // Sets the given string as text and (re)creates buffers. func (t *Text) SetText(font *Font, text string) { t.text = text @@ -345,6 +312,39 @@ func (t *Text) GetBounds() Vec2 { return Vec2{t.bounds.X * t.Size.X * t.Scale.X, t.bounds.Y * t.Size.Y * t.Scale.Y} } +// The text renderer is a system rendering 2D texture mapped font. +// It has a 2D position component, to move all texts at once. +type TextRenderer struct { + Pos2D + + Shader *Shader + Camera *Camera + Font *Font + texts []Text +} + +// Creates a new text renderer using given shader, camera and font. +// If shader and/or camera are nil, the default one will be used. +func NewTextRenderer(shader *Shader, camera *Camera, font *Font) *TextRenderer { + if shader == nil { + shader = DefaultTextShader + } + + if camera == nil { + camera = DefaultCamera + } + + renderer := &TextRenderer{} + renderer.Shader = shader + renderer.Camera = camera + renderer.Font = font + renderer.texts = make([]Text, 0) + renderer.Size = Vec2{1, 1} + renderer.Scale = Vec2{1, 1} + + return renderer +} + // Prepares given text for rendering. func (r *TextRenderer) Prepare(text *Text) { text.vao = NewVAO()