diff --git a/ToDo.md b/ToDo.md index e5cb454..cffe077 100644 --- a/ToDo.md +++ b/ToDo.md @@ -5,3 +5,4 @@ * limit FPS * fullscreen * simple access to default resources like GetTex() +* text rendering + font loading diff --git a/default_shader.go b/default_shader.go new file mode 100644 index 0000000..a6b586e --- /dev/null +++ b/default_shader.go @@ -0,0 +1,83 @@ +package goga + +const ( + // constants for default 2D shader + Default_shader_2D_vertex_attrib = "vertex" + Default_shader_2D_texcoord_attrib = "texCoord" + Default_shader_2D_ortho = "o" + Default_shader_2D_model = "m" + Default_shader_2D_tex = "tex" + + // source for 2D shader + default_shader_2d_vertex_src = `#version 130 + uniform mat3 o, m; + in vec2 vertex; + in vec2 texCoord; + out vec2 tc; + void main(){ + tc = texCoord; + gl_Position = vec4(o*m*vec3(vertex, 1.0), 1.0); + }` + default_shader_2d_fragment_src = `#version 130 + precision highp float; + uniform sampler2D tex; + in vec2 tc; + out vec4 color; + void main(){ + color = texture(tex, tc); + }` + + // constants for default 3D shader + Default_shader_3D_vertex_attrib = "vertex" + Default_shader_3D_texcoord_attrib = "texCoord" + Default_shader_3D_pv = "pv" + Default_shader_3D_model = "m" + Default_shader_3D_tex = "tex" + + // source for 3D shader + default_shader_3d_vertex_src = `#version 130 + uniform mat4 pv, m; + in vec3 vertex; + in vec2 texCoord; + out vec2 tc; + void main(){ + tc = texCoord; + gl_Position = pv*m*vec4(vertex, 1.0); + }` + default_shader_3d_fragment_src = `#version 130 + precision highp float; + uniform sampler2D tex; + in vec2 tc; + out vec4 color; + void main(){ + color = texture(tex, tc); + }` + + // constants for default text shader + Default_shader_text_vertex_attrib = "vertex" + Default_shader_text_texcoord_attrib = "texCoord" + Default_shader_text_ortho = "o" + Default_shader_text_model = "m" + Default_shader_text_tex = "tex" + Default_shader_text_color = "color" + + // source for text shader + default_shader_text_vertex_src = `#version 130 + uniform mat3 o, m; + in vec2 vertex; + in vec2 texCoord; + out vec2 tc; + void main(){ + tc = texCoord; + gl_Position = vec4(o*m*vec3(vertex, 1.0), 1.0); + }` + default_shader_text_fragment_src = `#version 130 + precision highp float; + uniform sampler2D tex; + uniform vec4 color; + in vec2 tc; + out vec4 c; + void main(){ + c = texture(tex, tc)*color; + }` +) diff --git a/demo/text/text.go b/demo/text/text.go new file mode 100644 index 0000000..c5a46fa --- /dev/null +++ b/demo/text/text.go @@ -0,0 +1,55 @@ +package main + +import ( + "github.com/DeKugelschieber/go-game" +) + +const ( + font_path = "src/github.com/DeKugelschieber/go-game/demo/text/assets/font.png" +) + +type Game struct{} + +func (g *Game) Setup() { + // load texture + /*_, err := goga.LoadRes(gopher_path) + + if err != nil { + panic(err) + } + + // create sprite + tex, err := goga.GetTex("gopher.png") + + if err != nil { + panic(err) + } + + sprite := goga.NewSprite(tex) + renderer, ok := goga.GetSystemByName("spriteRenderer").(*goga.SpriteRenderer) + + if !ok { + panic("Could not find renderer") + } + + renderer.Add(sprite.Actor, sprite.Pos2D, sprite.Tex) + + culling, ok := goga.GetSystemByName("culling2d").(*goga.Culling2D) + + if !ok { + panic("Could not find culling") + } + + culling.Add(sprite.Actor, sprite.Pos2D)*/ +} + +func (g *Game) Update(delta float64) {} + +func main() { + game := Game{} + options := goga.RunOptions{ClearColor: goga.Vec4{0, 0, 0, 0}, + Resizable: true, + SetViewportOnResize: true, + ExitOnClose: true} + goga.Run(&game, &options) +} diff --git a/drop.go b/drop.go index 345b3cf..0dcea8c 100644 --- a/drop.go +++ b/drop.go @@ -7,7 +7,7 @@ type Dropable interface { } // Drops given GL objects. -// Objects must implement the Dropable inteface. +// Objects must implement the Dropable interface. func Drop(objects []Dropable) { for _, obj := range objects { obj.Drop() diff --git a/game.go b/game.go index 1490733..0448126 100644 --- a/game.go +++ b/game.go @@ -14,86 +14,6 @@ const ( default_height = uint32(400) default_title = "Game" default_exit_on_close = true - - // constants for default 2D shader - Default_shader_2D_vertex_attrib = "vertex" - Default_shader_2D_texcoord_attrib = "texCoord" - Default_shader_2D_ortho = "o" - Default_shader_2D_model = "m" - Default_shader_2D_tex = "tex" - - // source for 2D shader - default_shader_2d_vertex_src = `#version 130 - uniform mat3 o, m; - in vec2 vertex; - in vec2 texCoord; - out vec2 tc; - void main(){ - tc = texCoord; - gl_Position = vec4(o*m*vec3(vertex, 1.0), 1.0); - }` - default_shader_2d_fragment_src = `#version 130 - precision highp float; - uniform sampler2D tex; - in vec2 tc; - out vec4 color; - void main(){ - color = texture(tex, tc); - }` - - // constants for default 3D shader - Default_shader_3D_vertex_attrib = "vertex" - Default_shader_3D_texcoord_attrib = "texCoord" - Default_shader_3D_pv = "pv" - Default_shader_3D_model = "m" - Default_shader_3D_tex = "tex" - - // source for 3D shader - default_shader_3d_vertex_src = `#version 130 - uniform mat4 pv, m; - in vec3 vertex; - in vec2 texCoord; - out vec2 tc; - void main(){ - tc = texCoord; - gl_Position = pv*m*vec4(vertex, 1.0); - }` - default_shader_3d_fragment_src = `#version 130 - precision highp float; - uniform sampler2D tex; - in vec2 tc; - out vec4 color; - void main(){ - color = texture(tex, tc); - }` - - // constants for default text shader - Default_shader_text_vertex_attrib = "vertex" - Default_shader_text_texcoord_attrib = "texCoord" - Default_shader_text_ortho = "o" - Default_shader_text_model = "m" - Default_shader_text_tex = "tex" - Default_shader_text_color = "color" - - // source for text shader - default_shader_text_vertex_src = `#version 130 - uniform mat3 o, m; - in vec2 vertex; - in vec2 texCoord; - out vec2 tc; - void main(){ - tc = texCoord; - gl_Position = vec4(o*m*vec3(vertex, 1.0), 1.0); - }` - default_shader_text_fragment_src = `#version 130 - precision highp float; - uniform sampler2D tex; - uniform vec4 color; - in vec2 tc; - out vec4 c; - void main(){ - c = texture(tex, tc)*color; - }` ) // If set in RunOptions, the function will be called on window resize. diff --git a/keyframe.go b/keyframe.go index 81bf121..432eb7d 100644 --- a/keyframe.go +++ b/keyframe.go @@ -14,6 +14,44 @@ 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} @@ -36,11 +74,6 @@ 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{} @@ -55,31 +88,11 @@ 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{} @@ -101,19 +114,6 @@ 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 835acb8..e083629 100644 --- a/loader.go +++ b/loader.go @@ -21,6 +21,27 @@ 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) @@ -61,20 +82,6 @@ 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 -} - // Drops contained GL buffers. func (p *Ply) Drop() { if p.IndexBuffer != nil { @@ -124,13 +131,6 @@ func (p *Ply) SetExt(ext string) { p.ext = ext } -// 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 *PlyLoader) Load(file string) (Res, error) { handle, err := os.Open(file) defer handle.Close() diff --git a/model.go b/model.go index a66324d..428e7f2 100644 --- a/model.go +++ b/model.go @@ -14,6 +14,26 @@ 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 { @@ -36,14 +56,6 @@ 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{} @@ -60,18 +72,6 @@ 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 9cbdbc7..bfefd5a 100644 --- a/pos.go +++ b/pos.go @@ -8,6 +8,13 @@ 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{} @@ -38,13 +45,6 @@ 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/sprite.go b/sprite.go index 5dc8ba8..9da1067 100644 --- a/sprite.go +++ b/sprite.go @@ -15,6 +15,19 @@ 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{} @@ -30,19 +43,6 @@ 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/text.go b/text.go index b213882..df5e2eb 100644 --- a/text.go +++ b/text.go @@ -1,5 +1,47 @@ package goga +import () + +type character struct { + char byte + min, max, size Vec2 + offset float64 +} + +// Font represents a texture mapped font. +// It can be loaded from JSON together with a texture. +type Font struct { + Tex *Tex + tileSize float64 + CharPadding Vec2 + Space, Tab, Line float64 + chars []character +} + +// 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 + + text string + bounds Vec2 + index, vertex, texCoord *VBO + vao *VAO +} + +// 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 + Color Vec4 // TODO move this to Text? + texts []Text +} + /* import ( "core"