Removed Add() method from System interface, added 2D culling.

This commit is contained in:
Marvin Blum
2016-05-07 11:28:42 +02:00
parent 11cf7a9251
commit 80e5cb20f8
4 changed files with 123 additions and 41 deletions

99
culling.go Normal file
View File

@@ -0,0 +1,99 @@
package goga
import (
"log"
)
const (
culling_2d_name = "culling2d"
)
type Cullable struct {
*Actor
*Pos2D
}
type Culling2D struct {
cullables []Cullable
viewport Vec4
}
// Creates a new sprite culling system.
// To update the viewport, call SetViewport().
func NewCulling2D(x, y, width, height int) *Culling2D {
culling := &Culling2D{}
culling.cullables = make([]Cullable, 0)
culling.viewport = Vec4{float64(x), float64(y), float64(width), float64(height)}
return culling
}
// Sets the culling outer bounds.
// Actors outside of this box won't be rendered.
func (c *Culling2D) SetViewport(x, y, width, height int) {
c.viewport = Vec4{float64(x), float64(y), float64(width), float64(height)}
}
func (c *Culling2D) Cleanup() {}
// Adds actor with Pos2D to the system.
func (c *Culling2D) Add(actor *Actor, pos *Pos2D) bool {
id := actor.GetId()
for _, cull := range c.cullables {
if id == cull.Actor.GetId() {
return false
}
}
c.cullables = append(c.cullables, Cullable{actor, pos})
return true
}
// Removes actor with Pos2D from system.
func (c *Culling2D) Remove(actor *Actor) bool {
return c.RemoveById(actor.GetId())
}
// Removes actor with Pos2D from system by ID.
func (c *Culling2D) RemoveById(id ActorId) bool {
for i, cull := range c.cullables {
if cull.GetId() == id {
c.cullables = append(c.cullables[:i], c.cullables[i+1:]...)
return true
}
}
return false
}
// Removes all cullable objects.
func (c *Culling2D) RemoveAll() {
c.cullables = make([]Cullable, 0)
}
// Returns number of cullable objects.
func (c *Culling2D) Len() int {
return len(c.cullables)
}
func (c *Culling2D) GetName() string {
return culling_2d_name
}
// Updates visibility of all contained sprites.
func (c *Culling2D) Update(delta float64) {
for i := range c.cullables {
if c.cullables[i].Pos.X > c.viewport.Z ||
c.cullables[i].Pos.X+c.cullables[i].Size.X < c.viewport.X ||
c.cullables[i].Pos.Y > c.viewport.W ||
c.cullables[i].Pos.Y+c.cullables[i].Size.Y < c.viewport.Y {
c.cullables[i].Visible = false
log.Print("h")
} else {
c.cullables[i].Visible = true
log.Print("s")
}
}
}

13
game.go
View File

@@ -227,6 +227,7 @@ func initGoga(width, height int) {
EnableAlphaBlending(true)
AddLoader(&PngLoader{gl.LINEAR, false})
AddSystem(NewSpriteRenderer(nil, nil, false))
AddSystem(NewCulling2D(0, 0, width, height))
}
func cleanup() {
@@ -296,13 +297,23 @@ func EnableAlphaBlending(enable bool) {
}
}
// Sets GL viewport.
// Sets GL viewport and updates default resources and systems.
func SetViewport(x, y, width, height int32) {
viewportWidth = int(width)
viewportHeight = int(height)
DefaultCamera.SetViewport(int(x), int(y), viewportWidth, viewportHeight)
DefaultCamera.CalcRatio()
DefaultCamera.CalcOrtho()
if culling2d := GetSystemByName(culling_2d_name); culling2d != nil {
system, ok := culling2d.(*Culling2D)
if ok {
system.SetViewport(int(x), int(y), viewportWidth, viewportHeight)
}
}
gl.Viewport(x, y, width, height)
}

View File

@@ -87,27 +87,23 @@ func (s *SpriteRenderer) Cleanup() {
}
// Adds sprite to the renderer.
func (s *SpriteRenderer) Add(actor interface{}) bool {
sprite, ok := actor.(*Sprite)
func (s *SpriteRenderer) Add(actor *Actor, pos *Pos2D, tex *Tex) bool {
id := actor.GetId()
if !ok {
return false
for _, sprite := range s.sprites {
if id == sprite.Actor.GetId() {
return false
}
}
s.sprites = append(s.sprites, *sprite)
s.sprites = append(s.sprites, Sprite{actor, pos, tex})
return true
}
// Removes sprite from renderer.
func (s *SpriteRenderer) Remove(actor interface{}) bool {
sprite, ok := actor.(*Sprite)
if !ok {
return false
}
return s.RemoveById(sprite.Actor.GetId())
func (s *SpriteRenderer) Remove(actor *Actor) bool {
return s.RemoveById(actor.GetId())
}
// Removes sprite from renderer by ID.

View File

@@ -10,8 +10,7 @@ import ()
type System interface {
Update(float64)
Cleanup()
Add(interface{}) bool
Remove(interface{}) bool
Remove(*Actor) bool
RemoveById(ActorId) bool
RemoveAll()
Len() int
@@ -76,34 +75,11 @@ func updateSystems(delta float64) {
}
}
// Takes an actor and tries to add it to all systems that accept it.
// This maybe not as performant as directly adding it to the right system.
// Returns true if it could be added to at least one system, else false.
func AddActor(actor interface{}) bool {
accepted := false
for _, system := range systems {
if system.Add(actor) {
accepted = true
}
}
return accepted
}
// Removes an actor from all systems.
// This maybe not as performant as directly removing it from the right system.
// Returns true if it could be removed from at least one system, else false.
func RemoveActor(actor interface{}) bool {
removed := false
for _, system := range systems {
if system.Remove(actor) {
removed = true
}
}
return removed
func RemoveActor(actor *Actor) bool {
return RemoveActorById(actor.GetId())
}
// Removes an actor from all systems by ID.