feat: fixed camera matrix bufferization.
This commit is contained in:
parent
f4bf94a0e6
commit
d378490396
6 changed files with 49 additions and 25 deletions
13
camera.go
13
camera.go
|
@ -7,7 +7,8 @@ type Camera struct {
|
||||||
// that the camera shows.
|
// that the camera shows.
|
||||||
ShaderOptions
|
ShaderOptions
|
||||||
Transform
|
Transform
|
||||||
buf *Matrix
|
buffered bool
|
||||||
|
buf Matrix
|
||||||
engine *Engine
|
engine *Engine
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,20 +25,20 @@ func (e *Engine) NewCamera() *Camera {
|
||||||
// transform to display on the screen.
|
// transform to display on the screen.
|
||||||
func (c *Camera)RealMatrix() Matrix {
|
func (c *Camera)RealMatrix() Matrix {
|
||||||
// Bufferization
|
// Bufferization
|
||||||
if c.buf != nil {
|
if c.buffered {
|
||||||
return *(c.buf)
|
return c.buf
|
||||||
}
|
}
|
||||||
g := &Matrix{}
|
g := Matrix{}
|
||||||
g.Translate(-c.Position.X, -c.Position.Y)
|
g.Translate(-c.Position.X, -c.Position.Y)
|
||||||
g.Rotate(c.Rotation)
|
g.Rotate(c.Rotation)
|
||||||
siz := c.engine.AbsWinSize()
|
siz := c.engine.AbsWinSize()
|
||||||
g.Translate(c.Around.X * siz.X, c.Around.Y * siz.Y)
|
g.Translate(c.Around.X * siz.X, c.Around.Y * siz.Y)
|
||||||
g.Scale(c.Scale.X, c.Scale.Y)
|
g.Scale(c.Scale.X, c.Scale.Y)
|
||||||
|
|
||||||
|
|
||||||
c.buf = g
|
c.buf = g
|
||||||
|
c.buffered = true
|
||||||
|
|
||||||
return *g
|
return g
|
||||||
}
|
}
|
||||||
|
|
||||||
// The matrix to convert things into the
|
// The matrix to convert things into the
|
||||||
|
|
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"vultras.su/core/gg"
|
"vultras.su/core/gg"
|
||||||
"github.com/hajimehoshi/ebiten/v2/examples/resources/images"
|
"github.com/hajimehoshi/ebiten/v2/examples/resources/images"
|
||||||
|
_ "github.com/silbinarywolf/preferdiscretegpu"
|
||||||
"bytes"
|
"bytes"
|
||||||
"log"
|
"log"
|
||||||
//"strings"
|
//"strings"
|
||||||
|
@ -34,6 +35,7 @@ func main() {
|
||||||
Width: 720,
|
Width: 720,
|
||||||
Height: 480,
|
Height: 480,
|
||||||
VSync: true,
|
VSync: true,
|
||||||
|
Fullscreen: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
|
@ -63,6 +63,15 @@ func (t *Tri) Update(c *Context) {
|
||||||
case gg.KeyV:
|
case gg.KeyV:
|
||||||
t.Rotation += d * gg.Pi * 0.3 * dt
|
t.Rotation += d * gg.Pi * 0.3 * dt
|
||||||
case gg.Key2 :
|
case gg.Key2 :
|
||||||
|
if t.Spawned {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
t.Triangles = append(t.Triangles, gg.Triangle{
|
||||||
|
gg.V(0, 10 + gg.Float(counter)),
|
||||||
|
gg.V(100 + gg.Float(counter), 0),
|
||||||
|
gg.V(0, -10 - gg.Float(counter)),
|
||||||
|
})
|
||||||
|
case gg.Key3 :
|
||||||
if t.Spawned {
|
if t.Spawned {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
45
engine.go
45
engine.go
|
@ -40,6 +40,10 @@ type WindowConfig struct {
|
||||||
VSync bool
|
VSync bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Objects struct {
|
||||||
|
store []Objecter
|
||||||
|
}
|
||||||
|
|
||||||
// The main structure that represents current state of [game] engine.
|
// The main structure that represents current state of [game] engine.
|
||||||
type Engine struct {
|
type Engine struct {
|
||||||
wcfg *WindowConfig
|
wcfg *WindowConfig
|
||||||
|
@ -47,7 +51,7 @@ type Engine struct {
|
||||||
// The main holder for objects.
|
// The main holder for objects.
|
||||||
// Uses the map structure to quickly
|
// Uses the map structure to quickly
|
||||||
// delete and create new objects.
|
// delete and create new objects.
|
||||||
Objects maps.Map[Objecter, struct{}]
|
Objects *Objects
|
||||||
|
|
||||||
// The main camera to display in window.
|
// The main camera to display in window.
|
||||||
// If is set to nil then the engine will panic.
|
// If is set to nil then the engine will panic.
|
||||||
|
@ -103,16 +107,22 @@ func NewEngine(
|
||||||
ret.Camera = ret.NewCamera()
|
ret.Camera = ret.NewCamera()
|
||||||
ret.outerEvents = make(EventChan)
|
ret.outerEvents = make(EventChan)
|
||||||
ret.handleEvents = make(EventChan)
|
ret.handleEvents = make(EventChan)
|
||||||
ret.Objects = maps.NewOrdered[Objecter, struct{}]()
|
ret.Objects = &Objects{}
|
||||||
ret.buttons = MouseButtonMap{}
|
ret.buttons = MouseButtonMap{}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the real window size in the current context.
|
// Get the real window size in the current context.
|
||||||
func (c *Engine) RealWinSize() Vector {
|
func (c *Engine) RealWinSize() Vector {
|
||||||
|
var w, h int
|
||||||
|
if c.wcfg.Fullscreen {
|
||||||
|
w, h = ebiten.ScreenSizeInFullscreen()
|
||||||
|
} else {
|
||||||
|
w, h = c.wcfg.Width, c.wcfg.Height
|
||||||
|
}
|
||||||
return V(
|
return V(
|
||||||
Float(c.wcfg.Width),
|
Float(w),
|
||||||
Float(c.wcfg.Height),
|
Float(h),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,35 +137,32 @@ func (e *Engine) EventInput() EventChan {
|
||||||
// Add new object considering what
|
// Add new object considering what
|
||||||
// interfaces it implements.
|
// interfaces it implements.
|
||||||
func (e *Engine) Spawn(b Objecter) error {
|
func (e *Engine) Spawn(b Objecter) error {
|
||||||
if e.Objects.Has(b) {
|
/*if e.Objects.Has(b) {
|
||||||
return ObjectExistErr
|
return ObjectExistErr
|
||||||
}
|
}*/
|
||||||
|
|
||||||
b.Start(&Context{Engine: e})
|
b.Start(&Context{Engine: e})
|
||||||
obj := b.GetObject()
|
obj := b.GetObject()
|
||||||
obj.input = make(chan *Context)
|
obj.input = make(chan *Context)
|
||||||
go func() {
|
go func() {
|
||||||
for c := range obj.input {
|
for c := range obj.input {
|
||||||
switch c.typ {
|
b.Update(c)
|
||||||
case updateContext:
|
|
||||||
b.Update(c)
|
|
||||||
}
|
|
||||||
e.wg.Done()
|
e.wg.Done()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
e.Objects.Set(b, struct{}{})
|
e.Objects.store = append(e.Objects.store, b)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete object from Engine.
|
// Delete object from Engine.
|
||||||
func (e *Engine) Del(b Objecter) error {
|
func (e *Engine) Del(b Objecter) error {
|
||||||
if !e.Objects.Has(b) {
|
/*if !e.Objects.Has(b) {
|
||||||
return ObjectNotExistErr
|
return ObjectNotExistErr
|
||||||
}
|
}
|
||||||
|
|
||||||
b.Delete(&Context{Engine: e})
|
b.Delete(&Context{Engine: e})
|
||||||
e.Objects.Del(b)
|
e.Objects.Del(b)*/
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -206,7 +213,6 @@ func (e *Engine) AbsCursorPosition() Vector {
|
||||||
func (e *engine) Update() error {
|
func (e *engine) Update() error {
|
||||||
eng := (*Engine)(e)
|
eng := (*Engine)(e)
|
||||||
|
|
||||||
e.dt = time.Since(e.lastTime).Seconds()
|
|
||||||
// Buffering the context for faster.
|
// Buffering the context for faster.
|
||||||
|
|
||||||
e.prevKeys = e.keys
|
e.prevKeys = e.keys
|
||||||
|
@ -274,20 +280,20 @@ func (e *engine) Update() error {
|
||||||
typ: updateContext,
|
typ: updateContext,
|
||||||
Events: events,
|
Events: events,
|
||||||
}
|
}
|
||||||
for object := range e.Objects.KeyChan() {
|
for _, object := range e.Objects.store {
|
||||||
e.wg.Add(1)
|
e.wg.Add(1)
|
||||||
object.Input() <- c
|
object.Input() <- c
|
||||||
}
|
}
|
||||||
e.wg.Wait()
|
e.wg.Wait()
|
||||||
|
|
||||||
e.lastTime = time.Now()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *engine) Draw(i *ebiten.Image) {
|
func (e *engine) Draw(i *ebiten.Image) {
|
||||||
|
e.dt = time.Since(e.lastTime).Seconds()
|
||||||
eng := (*Engine)(e)
|
eng := (*Engine)(e)
|
||||||
m := map[Layer][]Drawer{}
|
m := map[Layer][]Drawer{}
|
||||||
for object := range eng.Objects.KeyChan() {
|
for _, object := range eng.Objects.store {
|
||||||
// Skipping the ones we do not need to draw.
|
// Skipping the ones we do not need to draw.
|
||||||
if !object.IsVisible() {
|
if !object.IsVisible() {
|
||||||
continue
|
continue
|
||||||
|
@ -311,8 +317,10 @@ func (e *engine) Draw(i *ebiten.Image) {
|
||||||
drawer.Draw(c)
|
drawer.Draw(c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty the buff to generate it again.
|
// Empty the buff to generate it again.
|
||||||
eng.Camera.buf = nil
|
eng.Camera.buffered = false
|
||||||
|
e.lastTime = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *engine) Layout(ow, oh int) (int, int) {
|
func (e *engine) Layout(ow, oh int) (int, int) {
|
||||||
|
@ -341,6 +349,7 @@ func (e *Engine) Run() error {
|
||||||
ebiten.SetWindowSize(e.wcfg.Width, e.wcfg.Height)
|
ebiten.SetWindowSize(e.wcfg.Width, e.wcfg.Height)
|
||||||
ebiten.SetWindowSizeLimits(1, 1, e.wcfg.Width, e.wcfg.Height)
|
ebiten.SetWindowSizeLimits(1, 1, e.wcfg.Width, e.wcfg.Height)
|
||||||
|
|
||||||
|
ebiten.SetFullscreen(e.wcfg.Fullscreen)
|
||||||
ebiten.SetVsyncEnabled(e.wcfg.VSync)
|
ebiten.SetVsyncEnabled(e.wcfg.VSync)
|
||||||
|
|
||||||
e.lastTime = time.Now()
|
e.lastTime = time.Now()
|
||||||
|
|
3
go.mod
3
go.mod
|
@ -7,6 +7,8 @@ toolchain go1.21.3
|
||||||
require (
|
require (
|
||||||
github.com/di4f/gods v0.0.0-20231214190239-d523423d8d5e
|
github.com/di4f/gods v0.0.0-20231214190239-d523423d8d5e
|
||||||
github.com/hajimehoshi/ebiten/v2 v2.6.0-alpha.3.0.20230521122940-90562ee84b9b
|
github.com/hajimehoshi/ebiten/v2 v2.6.0-alpha.3.0.20230521122940-90562ee84b9b
|
||||||
|
github.com/silbinarywolf/preferdiscretegpu v1.0.0
|
||||||
|
golang.org/x/image v0.7.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
@ -14,7 +16,6 @@ require (
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b // indirect
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b // indirect
|
||||||
github.com/jezek/xgb v1.1.0 // indirect
|
github.com/jezek/xgb v1.1.0 // indirect
|
||||||
golang.org/x/exp/shiny v0.0.0-20230522175609-2e198f4a06a1 // indirect
|
golang.org/x/exp/shiny v0.0.0-20230522175609-2e198f4a06a1 // indirect
|
||||||
golang.org/x/image v0.7.0 // indirect
|
|
||||||
golang.org/x/mobile v0.0.0-20230427221453-e8d11dd0ba41 // indirect
|
golang.org/x/mobile v0.0.0-20230427221453-e8d11dd0ba41 // indirect
|
||||||
golang.org/x/sync v0.2.0 // indirect
|
golang.org/x/sync v0.2.0 // indirect
|
||||||
golang.org/x/sys v0.8.0 // indirect
|
golang.org/x/sys v0.8.0 // indirect
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -8,6 +8,8 @@ github.com/hajimehoshi/ebiten/v2 v2.6.0-alpha.3.0.20230521122940-90562ee84b9b h1
|
||||||
github.com/hajimehoshi/ebiten/v2 v2.6.0-alpha.3.0.20230521122940-90562ee84b9b/go.mod h1:+fFI6Ag5YvbX1ivNQD2TxNhpWFDPuxEoew421TTQAxI=
|
github.com/hajimehoshi/ebiten/v2 v2.6.0-alpha.3.0.20230521122940-90562ee84b9b/go.mod h1:+fFI6Ag5YvbX1ivNQD2TxNhpWFDPuxEoew421TTQAxI=
|
||||||
github.com/jezek/xgb v1.1.0 h1:wnpxJzP1+rkbGclEkmwpVFQWpuE2PUGNUzP8SbfFobk=
|
github.com/jezek/xgb v1.1.0 h1:wnpxJzP1+rkbGclEkmwpVFQWpuE2PUGNUzP8SbfFobk=
|
||||||
github.com/jezek/xgb v1.1.0/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
|
github.com/jezek/xgb v1.1.0/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
|
||||||
|
github.com/silbinarywolf/preferdiscretegpu v1.0.0 h1:tuvXLRCnoFMFyk74/8PFvO0B5rjDmXm0JgNTaOYAHT0=
|
||||||
|
github.com/silbinarywolf/preferdiscretegpu v1.0.0/go.mod h1:h3s2GkfAP2sWqoS7v/PxAlFOQ1azMRsZxUJNw47QhLc=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
|
Loading…
Reference in a new issue