mirror of
https://github.com/Kugelschieber/go-game.git
synced 2026-01-18 06:40:28 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e88c163725 | ||
|
|
bc624295be | ||
|
|
69886eff00 |
@@ -1,5 +1,10 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.2_beta
|
||||||
|
|
||||||
|
* code restructuring
|
||||||
|
* added system access functions (like GetSpriteRenderer())
|
||||||
|
|
||||||
## 0.1_beta
|
## 0.1_beta
|
||||||
|
|
||||||
* beta release
|
* beta release
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ Game engine written in Go using OpenGL and GLFW. Mostly for 2D rendering, but al
|
|||||||
go-game requires OpenGL and GLFW. The following three steps install everything you need:
|
go-game requires OpenGL and GLFW. The following three steps install everything you need:
|
||||||
|
|
||||||
```
|
```
|
||||||
go get github.com/go-gl/gl/v3.1-core/gl
|
go get github.com/go-gl/gl/v3.2-core/gl
|
||||||
go get github.com/go-gl/glfw/v3.1/glfw
|
go get github.com/go-gl/glfw/v3.2/glfw
|
||||||
go get github.com/DeKugelschieber/go-game
|
go get github.com/DeKugelschieber/go-game
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
8
actor.go
8
actor.go
@@ -1,5 +1,9 @@
|
|||||||
package goga
|
package goga
|
||||||
|
|
||||||
|
var (
|
||||||
|
actorIdGen = ActorId(0)
|
||||||
|
)
|
||||||
|
|
||||||
// An actor ID is a unique integer,
|
// An actor ID is a unique integer,
|
||||||
// which can be used to reference an actor.
|
// which can be used to reference an actor.
|
||||||
type ActorId uint64
|
type ActorId uint64
|
||||||
@@ -10,10 +14,6 @@ type Actor struct {
|
|||||||
id ActorId
|
id ActorId
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
actorIdGen = ActorId(0)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Creates a new basic actor with unique ID.
|
// Creates a new basic actor with unique ID.
|
||||||
func NewActor() *Actor {
|
func NewActor() *Actor {
|
||||||
actorIdGen++
|
actorIdGen++
|
||||||
|
|||||||
14
culling.go
14
culling.go
@@ -80,14 +80,14 @@ func (c *Culling2D) GetName() string {
|
|||||||
|
|
||||||
// Updates visibility of all contained sprites.
|
// Updates visibility of all contained sprites.
|
||||||
func (c *Culling2D) Update(delta float64) {
|
func (c *Culling2D) Update(delta float64) {
|
||||||
for i := range c.cullables {
|
for _, cullable := range c.cullables {
|
||||||
if c.cullables[i].Pos.X > c.viewport.Z ||
|
if cullable.Pos.X > c.viewport.Z ||
|
||||||
c.cullables[i].Pos.X+c.cullables[i].Size.X < c.viewport.X ||
|
cullable.Pos.X+cullable.Size.X < c.viewport.X ||
|
||||||
c.cullables[i].Pos.Y > c.viewport.W ||
|
cullable.Pos.Y > c.viewport.W ||
|
||||||
c.cullables[i].Pos.Y+c.cullables[i].Size.Y < c.viewport.Y {
|
cullable.Pos.Y+cullable.Size.Y < c.viewport.Y {
|
||||||
c.cullables[i].Visible = false
|
cullable.Visible = false
|
||||||
} else {
|
} else {
|
||||||
c.cullables[i].Visible = true
|
cullable.Visible = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,20 +33,10 @@ func (g *Game) Setup() {
|
|||||||
sprite.Size.X = sprite.Size.X / 4
|
sprite.Size.X = sprite.Size.X / 4
|
||||||
sprite.Size.Y = sprite.Size.Y / 4
|
sprite.Size.Y = sprite.Size.Y / 4
|
||||||
g.sprite = sprite
|
g.sprite = sprite
|
||||||
renderer, ok := goga.GetSystemByName("spriteRenderer").(*goga.SpriteRenderer)
|
renderer := goga.GetSpriteRenderer()
|
||||||
|
|
||||||
if !ok {
|
|
||||||
panic("Could not find renderer")
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer.Add(sprite.Actor, sprite.Pos2D, sprite.Tex)
|
renderer.Add(sprite.Actor, sprite.Pos2D, sprite.Tex)
|
||||||
|
|
||||||
culling, ok := goga.GetSystemByName("culling2d").(*goga.Culling2D)
|
culling := goga.GetCulling2DSystem()
|
||||||
|
|
||||||
if !ok {
|
|
||||||
panic("Could not find culling")
|
|
||||||
}
|
|
||||||
|
|
||||||
culling.Add(sprite.Actor, sprite.Pos2D)
|
culling.Add(sprite.Actor, sprite.Pos2D)
|
||||||
|
|
||||||
// register input listeners
|
// register input listeners
|
||||||
|
|||||||
@@ -39,12 +39,7 @@ func (g *Game) Setup() {
|
|||||||
sprite.KeyframeAnimation = goga.NewKeyframeAnimation(0, 7, true, 20)
|
sprite.KeyframeAnimation = goga.NewKeyframeAnimation(0, 7, true, 20)
|
||||||
|
|
||||||
// add to renderer
|
// add to renderer
|
||||||
renderer, ok := goga.GetSystemByName("keyframeRenderer").(*goga.KeyframeRenderer)
|
renderer := goga.GetKeyframeRenderer()
|
||||||
|
|
||||||
if !ok {
|
|
||||||
panic("Could not find renderer")
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer.Add(sprite.Actor, sprite.Pos2D, sprite.Tex, sprite.KeyframeSet, sprite.KeyframeAnimation)
|
renderer.Add(sprite.Actor, sprite.Pos2D, sprite.Tex, sprite.KeyframeSet, sprite.KeyframeAnimation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,12 +36,7 @@ func (g *Game) Setup() {
|
|||||||
mesh := goga.NewMesh(ply.IndexBuffer, ply.VertexBuffer, ply.TexCoordBuffer)
|
mesh := goga.NewMesh(ply.IndexBuffer, ply.VertexBuffer, ply.TexCoordBuffer)
|
||||||
|
|
||||||
model := goga.NewModel(mesh, tex)
|
model := goga.NewModel(mesh, tex)
|
||||||
renderer, ok := goga.GetSystemByName("modelRenderer").(*goga.ModelRenderer)
|
renderer := goga.GetModelRenderer()
|
||||||
|
|
||||||
if !ok {
|
|
||||||
panic("Could not find renderer")
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer.Prepare(model)
|
renderer.Prepare(model)
|
||||||
renderer.Add(model.Actor, model.Pos3D, model.Tex, model.Mesh)
|
renderer.Add(model.Actor, model.Pos3D, model.Tex, model.Mesh)
|
||||||
g.model = model
|
g.model = model
|
||||||
|
|||||||
@@ -26,20 +26,10 @@ func (g *Game) Setup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sprite := goga.NewSprite(tex)
|
sprite := goga.NewSprite(tex)
|
||||||
renderer, ok := goga.GetSystemByName("spriteRenderer").(*goga.SpriteRenderer)
|
renderer := goga.GetSpriteRenderer()
|
||||||
|
|
||||||
if !ok {
|
|
||||||
panic("Could not find renderer")
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer.Add(sprite.Actor, sprite.Pos2D, sprite.Tex)
|
renderer.Add(sprite.Actor, sprite.Pos2D, sprite.Tex)
|
||||||
|
|
||||||
culling, ok := goga.GetSystemByName("culling2d").(*goga.Culling2D)
|
culling := goga.GetCulling2DSystem()
|
||||||
|
|
||||||
if !ok {
|
|
||||||
panic("Could not find culling")
|
|
||||||
}
|
|
||||||
|
|
||||||
culling.Add(sprite.Actor, sprite.Pos2D)
|
culling.Add(sprite.Actor, sprite.Pos2D)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,12 +45,7 @@ func (g *Game) Setup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setup renderer
|
// setup renderer
|
||||||
renderer, ok := goga.GetSystemByName("textRenderer").(*goga.TextRenderer)
|
renderer := goga.GetTextRenderer()
|
||||||
|
|
||||||
if !ok {
|
|
||||||
panic("Could not find renderer")
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer.Font = font
|
renderer.Font = font
|
||||||
|
|
||||||
// create and add text
|
// create and add text
|
||||||
|
|||||||
28
game.go
28
game.go
@@ -16,6 +16,20 @@ const (
|
|||||||
default_exit_on_close = true
|
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.
|
// If set in RunOptions, the function will be called on window resize.
|
||||||
type ResizeCallback func(width, height int)
|
type ResizeCallback func(width, height int)
|
||||||
|
|
||||||
@@ -43,20 +57,6 @@ type Game interface {
|
|||||||
Update(float64)
|
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() {
|
func init() {
|
||||||
// GL functions must be called from main thread,
|
// GL functions must be called from main thread,
|
||||||
// so we disable multithreading by the runtime here.
|
// so we disable multithreading by the runtime here.
|
||||||
|
|||||||
106
keyframe.go
106
keyframe.go
@@ -14,44 +14,6 @@ type Keyframe struct {
|
|||||||
Min, Max Vec2
|
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.
|
// Creates a new single keyframe with texture VBO.
|
||||||
func NewKeyframe(min, max Vec2) *Keyframe {
|
func NewKeyframe(min, max Vec2) *Keyframe {
|
||||||
keyframe := &Keyframe{Min: min, Max: max}
|
keyframe := &Keyframe{Min: min, Max: max}
|
||||||
@@ -74,6 +36,11 @@ func NewKeyframe(min, max Vec2) *Keyframe {
|
|||||||
return 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.
|
// Creates a new empty keyframe set with given size.
|
||||||
func NewKeyframeSet() *KeyframeSet {
|
func NewKeyframeSet() *KeyframeSet {
|
||||||
set := &KeyframeSet{}
|
set := &KeyframeSet{}
|
||||||
@@ -88,11 +55,31 @@ func (s *KeyframeSet) Add(frame *Keyframe) int {
|
|||||||
return len(s.Keyframes)
|
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.
|
// Creates a new keyframe animation with given start, end and loop.
|
||||||
func NewKeyframeAnimation(start, end int, loop bool, speed float64) *KeyframeAnimation {
|
func NewKeyframeAnimation(start, end int, loop bool, speed float64) *KeyframeAnimation {
|
||||||
return &KeyframeAnimation{start, end, loop, speed, 0, 0}
|
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.
|
// Creates a new animated sprite.
|
||||||
func NewAnimatedSprite(tex *Tex, set *KeyframeSet, width, height int) *AnimatedSprite {
|
func NewAnimatedSprite(tex *Tex, set *KeyframeSet, width, height int) *AnimatedSprite {
|
||||||
sprite := &AnimatedSprite{}
|
sprite := &AnimatedSprite{}
|
||||||
@@ -114,6 +101,19 @@ func NewAnimatedSprite(tex *Tex, set *KeyframeSet, width, height int) *AnimatedS
|
|||||||
return sprite
|
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.
|
// Creates a new keyframe renderer using given shader and camera.
|
||||||
// If shader and/or camera are nil, the default one will be used.
|
// If shader and/or camera are nil, the default one will be used.
|
||||||
func NewKeyframeRenderer(shader *Shader, camera *Camera) *KeyframeRenderer {
|
func NewKeyframeRenderer(shader *Shader, camera *Camera) *KeyframeRenderer {
|
||||||
@@ -206,22 +206,22 @@ func (s *KeyframeRenderer) GetName() string {
|
|||||||
// Updates animation state and renders sprites.
|
// Updates animation state and renders sprites.
|
||||||
func (s *KeyframeRenderer) Update(delta float64) {
|
func (s *KeyframeRenderer) Update(delta float64) {
|
||||||
// update animation state
|
// update animation state
|
||||||
for i := range s.sprites {
|
for _, sprite := range s.sprites {
|
||||||
if s.sprites[i].KeyframeAnimation == nil {
|
if sprite.KeyframeAnimation == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
s.sprites[i].Interpolation += delta * s.sprites[i].KeyframeAnimation.Speed
|
sprite.Interpolation += delta * sprite.KeyframeAnimation.Speed
|
||||||
|
|
||||||
if s.sprites[i].Interpolation > 1 {
|
if sprite.Interpolation > 1 {
|
||||||
s.sprites[i].Interpolation = 0
|
sprite.Interpolation = 0
|
||||||
s.sprites[i].Current++
|
sprite.Current++
|
||||||
|
|
||||||
if s.sprites[i].Current > s.sprites[i].KeyframeAnimation.End {
|
if sprite.Current > sprite.KeyframeAnimation.End {
|
||||||
if s.sprites[i].KeyframeAnimation.Loop {
|
if sprite.KeyframeAnimation.Loop {
|
||||||
s.sprites[i].Current = s.sprites[i].KeyframeAnimation.Start
|
sprite.Current = sprite.KeyframeAnimation.Start
|
||||||
} else {
|
} else {
|
||||||
s.sprites[i].Current = s.sprites[i].KeyframeAnimation.End
|
sprite.Current = sprite.KeyframeAnimation.End
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -233,17 +233,17 @@ func (s *KeyframeRenderer) Update(delta float64) {
|
|||||||
s.Shader.SendUniform1i(Default_shader_2D_tex, 0)
|
s.Shader.SendUniform1i(Default_shader_2D_tex, 0)
|
||||||
s.vao.Bind()
|
s.vao.Bind()
|
||||||
|
|
||||||
for i := range s.sprites {
|
for _, sprite := range s.sprites {
|
||||||
if !s.sprites[i].Visible {
|
if !sprite.Visible {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
texCoord := s.sprites[i].KeyframeSet.Keyframes[s.sprites[i].Current].texCoord
|
texCoord := sprite.KeyframeSet.Keyframes[sprite.Current].texCoord
|
||||||
texCoord.Bind()
|
texCoord.Bind()
|
||||||
texCoord.AttribPointer(s.Shader.GetAttribLocation(Default_shader_2D_texcoord_attrib), 2, gl.FLOAT, false, 0)
|
texCoord.AttribPointer(s.Shader.GetAttribLocation(Default_shader_2D_texcoord_attrib), 2, gl.FLOAT, false, 0)
|
||||||
|
|
||||||
s.Shader.SendMat3(Default_shader_2D_model, *s.sprites[i].CalcModel())
|
s.Shader.SendMat3(Default_shader_2D_model, *sprite.CalcModel())
|
||||||
s.sprites[i].Tex.Bind()
|
sprite.Tex.Bind()
|
||||||
|
|
||||||
gl.DrawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, nil)
|
gl.DrawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, nil)
|
||||||
}
|
}
|
||||||
|
|||||||
42
loader.go
42
loader.go
@@ -21,27 +21,6 @@ type PngLoader struct {
|
|||||||
KeepData bool
|
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) {
|
func (p *PngLoader) Load(file string) (Res, error) {
|
||||||
// load texture
|
// load texture
|
||||||
imgFile, err := os.Open(file)
|
imgFile, err := os.Open(file)
|
||||||
@@ -82,6 +61,27 @@ func (p *PngLoader) Ext() string {
|
|||||||
return "png"
|
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.
|
// Drops contained GL buffers.
|
||||||
func (p *Ply) Drop() {
|
func (p *Ply) Drop() {
|
||||||
if p.IndexBuffer != nil {
|
if p.IndexBuffer != nil {
|
||||||
|
|||||||
56
model.go
56
model.go
@@ -14,26 +14,6 @@ type Mesh struct {
|
|||||||
Vao *VAO
|
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.
|
// Creates a new mesh with given GL buffers.
|
||||||
// The VAO must be prepared by ModelRenderer.
|
// The VAO must be prepared by ModelRenderer.
|
||||||
func NewMesh(index, vertex, texcoord *VBO) *Mesh {
|
func NewMesh(index, vertex, texcoord *VBO) *Mesh {
|
||||||
@@ -56,6 +36,14 @@ func (m *Mesh) Drop() {
|
|||||||
m.Vao.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.
|
// Creates a new model with given mesh and texture.
|
||||||
func NewModel(mesh *Mesh, tex *Tex) *Model {
|
func NewModel(mesh *Mesh, tex *Tex) *Model {
|
||||||
model := &Model{}
|
model := &Model{}
|
||||||
@@ -72,6 +60,18 @@ func NewModel(mesh *Mesh, tex *Tex) *Model {
|
|||||||
return 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.
|
// Creates a new model renderer using given shader and camera.
|
||||||
// If shader and/or camera are nil, the default one will be used.
|
// If shader and/or camera are nil, the default one will be used.
|
||||||
// Orth can be set to true, to use orthogonal projection.
|
// Orth can be set to true, to use orthogonal projection.
|
||||||
@@ -174,20 +174,20 @@ func (s *ModelRenderer) Update(delta float64) {
|
|||||||
|
|
||||||
var tid uint32
|
var tid uint32
|
||||||
|
|
||||||
for i := range s.models {
|
for _, model := range s.models {
|
||||||
if !s.models[i].Visible {
|
if !model.Visible {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Shader.SendMat4(Default_shader_3D_model, *s.models[i].CalcModel())
|
s.Shader.SendMat4(Default_shader_3D_model, *model.CalcModel())
|
||||||
s.models[i].Vao.Bind()
|
model.Vao.Bind()
|
||||||
|
|
||||||
// prevent texture switching when not neccessary
|
// prevent texture switching when not neccessary
|
||||||
if tid != s.models[i].Tex.GetId() {
|
if tid != model.Tex.GetId() {
|
||||||
tid = s.models[i].Tex.GetId()
|
tid = model.Tex.GetId()
|
||||||
s.models[i].Tex.Bind()
|
model.Tex.Bind()
|
||||||
}
|
}
|
||||||
|
|
||||||
gl.DrawElements(gl.TRIANGLES, s.models[i].Index.Size(), gl.UNSIGNED_INT, nil)
|
gl.DrawElements(gl.TRIANGLES, model.Index.Size(), gl.UNSIGNED_INT, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
pos.go
14
pos.go
@@ -8,13 +8,6 @@ type Pos2D struct {
|
|||||||
M Mat3
|
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.
|
// Creates a default initialized Pos2D.
|
||||||
func NewPos2D() *Pos2D {
|
func NewPos2D() *Pos2D {
|
||||||
m := Mat3{}
|
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
|
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.
|
// Creates a default initialized Pos3D.
|
||||||
func NewPos3D() *Pos3D {
|
func NewPos3D() *Pos3D {
|
||||||
m := Mat4{}
|
m := Mat4{}
|
||||||
|
|||||||
10
scene.go
10
scene.go
@@ -4,6 +4,11 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
scenes []Scene
|
||||||
|
activeScene Scene
|
||||||
|
)
|
||||||
|
|
||||||
// A scene used to switch between game states.
|
// A scene used to switch between game states.
|
||||||
// The Cleanup() method is called when a scene is removed
|
// The Cleanup() method is called when a scene is removed
|
||||||
// or the program is stopped. It can be used to cleanup open resources
|
// or the program is stopped. It can be used to cleanup open resources
|
||||||
@@ -19,11 +24,6 @@ type Scene interface {
|
|||||||
GetName() string
|
GetName() string
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
scenes []Scene
|
|
||||||
activeScene Scene
|
|
||||||
)
|
|
||||||
|
|
||||||
// Adds a scene to game.
|
// Adds a scene to game.
|
||||||
// Returns false if the scene exists already.
|
// Returns false if the scene exists already.
|
||||||
// The first scene added will be set active.
|
// The first scene added will be set active.
|
||||||
|
|||||||
38
sprite.go
38
sprite.go
@@ -15,19 +15,6 @@ type Sprite struct {
|
|||||||
*Tex
|
*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.
|
// Creates a new sprite with given texture.
|
||||||
func NewSprite(tex *Tex) *Sprite {
|
func NewSprite(tex *Tex) *Sprite {
|
||||||
sprite := &Sprite{}
|
sprite := &Sprite{}
|
||||||
@@ -43,6 +30,19 @@ func NewSprite(tex *Tex) *Sprite {
|
|||||||
return 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.
|
// Creates a new sprite renderer using given shader and camera.
|
||||||
// If shader and/or camera are nil, the default one will be used.
|
// If shader and/or camera are nil, the default one will be used.
|
||||||
func NewSpriteRenderer(shader *Shader, camera *Camera, flip bool) *SpriteRenderer {
|
func NewSpriteRenderer(shader *Shader, camera *Camera, flip bool) *SpriteRenderer {
|
||||||
@@ -140,17 +140,17 @@ func (s *SpriteRenderer) Update(delta float64) {
|
|||||||
s.vao.Bind()
|
s.vao.Bind()
|
||||||
var tid uint32
|
var tid uint32
|
||||||
|
|
||||||
for i := range s.sprites {
|
for _, sprite := range s.sprites {
|
||||||
if !s.sprites[i].Visible {
|
if !sprite.Visible {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Shader.SendMat3(Default_shader_2D_model, *s.sprites[i].CalcModel())
|
s.Shader.SendMat3(Default_shader_2D_model, *sprite.CalcModel())
|
||||||
|
|
||||||
// prevent texture switching when not neccessary
|
// prevent texture switching when not neccessary
|
||||||
if tid != s.sprites[i].Tex.GetId() {
|
if tid != sprite.Tex.GetId() {
|
||||||
tid = s.sprites[i].Tex.GetId()
|
tid = sprite.Tex.GetId()
|
||||||
s.sprites[i].Tex.Bind()
|
sprite.Tex.Bind()
|
||||||
}
|
}
|
||||||
|
|
||||||
gl.DrawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, nil)
|
gl.DrawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, nil)
|
||||||
|
|||||||
@@ -2,6 +2,10 @@ package goga
|
|||||||
|
|
||||||
import ()
|
import ()
|
||||||
|
|
||||||
|
var (
|
||||||
|
systems []System
|
||||||
|
)
|
||||||
|
|
||||||
// A system provides logic for actors satisfying required components.
|
// A system provides logic for actors satisfying required components.
|
||||||
// They are automatically updated on each frame.
|
// They are automatically updated on each frame.
|
||||||
// When a system is removed from systems, the Cleanup() method will be called.
|
// When a system is removed from systems, the Cleanup() method will be called.
|
||||||
@@ -17,10 +21,6 @@ type System interface {
|
|||||||
GetName() string
|
GetName() string
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
systems []System
|
|
||||||
)
|
|
||||||
|
|
||||||
// Adds a system to the game.
|
// Adds a system to the game.
|
||||||
// Returns false if the system exists already.
|
// Returns false if the system exists already.
|
||||||
func AddSystem(system System) bool {
|
func AddSystem(system System) bool {
|
||||||
|
|||||||
51
system_util.go
Normal file
51
system_util.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package goga
|
||||||
|
|
||||||
|
func GetSpriteRenderer() *SpriteRenderer {
|
||||||
|
renderer, ok := GetSystemByName(sprite_renderer_name).(*SpriteRenderer)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
panic("Could not obtain sprite renderer")
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderer
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetModelRenderer() *ModelRenderer {
|
||||||
|
renderer, ok := GetSystemByName(model_renderer_name).(*ModelRenderer)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
panic("Could not obtain model renderer")
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderer
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCulling2DSystem() *Culling2D {
|
||||||
|
system, ok := GetSystemByName(culling_2d_name).(*Culling2D)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
panic("Could not obtain culling system")
|
||||||
|
}
|
||||||
|
|
||||||
|
return system
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetKeyframeRenderer() *KeyframeRenderer {
|
||||||
|
renderer, ok := GetSystemByName(keyframe_sprite_renderer_name).(*KeyframeRenderer)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
panic("Could not obtain keyframe renderer")
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderer
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTextRenderer() *TextRenderer {
|
||||||
|
renderer, ok := GetSystemByName(text_renderer_name).(*TextRenderer)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
panic("Could not obtain text renderer")
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderer
|
||||||
|
}
|
||||||
154
text.go
154
text.go
@@ -32,36 +32,6 @@ type Font struct {
|
|||||||
chars []character
|
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.
|
// Creates a new font for given texture.
|
||||||
// The tile size specifies the size of one character tile on texture.
|
// The tile size specifies the size of one character tile on texture.
|
||||||
// Characters must be added afterwards.
|
// Characters must be added afterwards.
|
||||||
@@ -78,47 +48,6 @@ func NewFont(tex *Tex, tileSize float64) *Font {
|
|||||||
return &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.
|
// Loads characters from JSON file.
|
||||||
// Format:
|
// Format:
|
||||||
//
|
//
|
||||||
@@ -229,6 +158,17 @@ func (f *Font) getChar(char byte) *character {
|
|||||||
return nil
|
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.
|
// Deletes GL buffers bound to this text component.
|
||||||
func (t *TextComponent) Drop() {
|
func (t *TextComponent) Drop() {
|
||||||
t.index.Drop()
|
t.index.Drop()
|
||||||
@@ -237,6 +177,33 @@ func (t *TextComponent) Drop() {
|
|||||||
t.vao.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.
|
// Sets the given string as text and (re)creates buffers.
|
||||||
func (t *Text) SetText(font *Font, text string) {
|
func (t *Text) SetText(font *Font, text string) {
|
||||||
t.text = text
|
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}
|
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.
|
// Prepares given text for rendering.
|
||||||
func (r *TextRenderer) Prepare(text *Text) {
|
func (r *TextRenderer) Prepare(text *Text) {
|
||||||
text.vao = NewVAO()
|
text.vao = NewVAO()
|
||||||
@@ -423,15 +423,15 @@ func (r *TextRenderer) Update(delta float64) {
|
|||||||
r.Shader.SendUniform1i(Default_shader_text_tex, 0)
|
r.Shader.SendUniform1i(Default_shader_text_tex, 0)
|
||||||
r.Font.Tex.Bind()
|
r.Font.Tex.Bind()
|
||||||
|
|
||||||
for i := range r.texts {
|
for _, text := range r.texts {
|
||||||
if !r.texts[i].Visible {
|
if !text.Visible {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
r.texts[i].vao.Bind()
|
text.vao.Bind()
|
||||||
r.Shader.SendUniform4f(Default_shader_text_color, float32(r.texts[i].Color.X), float32(r.texts[i].Color.Y), float32(r.texts[i].Color.Z), float32(r.texts[i].Color.W))
|
r.Shader.SendUniform4f(Default_shader_text_color, float32(text.Color.X), float32(text.Color.Y), float32(text.Color.Z), float32(text.Color.W))
|
||||||
r.Shader.SendMat3(Default_shader_text_model, *r.texts[i].CalcModel())
|
r.Shader.SendMat3(Default_shader_text_model, *text.CalcModel())
|
||||||
|
|
||||||
gl.DrawElements(gl.TRIANGLES, r.texts[i].index.Size(), gl.UNSIGNED_INT, nil)
|
gl.DrawElements(gl.TRIANGLES, text.index.Size(), gl.UNSIGNED_INT, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user