Implemented shaders on sprites.
This commit is contained in:
parent
f913f95d61
commit
b853924e19
5 changed files with 144 additions and 75 deletions
|
@ -7,6 +7,7 @@ import (
|
|||
"bytes"
|
||||
"log"
|
||||
"strings"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Player struct {
|
||||
|
@ -17,26 +18,65 @@ type Player struct {
|
|||
|
||||
type Debug struct{}
|
||||
|
||||
type Rect struct {
|
||||
*gx.DrawableRectangle
|
||||
}
|
||||
|
||||
func NewRect() *Rect {
|
||||
return &Rect{&gx.DrawableRectangle{
|
||||
Rectangle: gx.Rectangle{
|
||||
W: 200,
|
||||
H: 400,
|
||||
T: gx.T(),
|
||||
},
|
||||
Color: gx.Color{
|
||||
gx.MaxColorV,
|
||||
0,
|
||||
0,
|
||||
gx.MaxColorV,
|
||||
},
|
||||
Visible: true,
|
||||
/*Shader: gx.SolidWhiteColorShader,
|
||||
Options: gx.ShaderOptions{
|
||||
Images: [4]*gx.Image{
|
||||
playerImg,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
},*/
|
||||
}}
|
||||
}
|
||||
|
||||
func (r *Rect) Update(e *gx.Engine) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
playerImg *gx.Image
|
||||
)
|
||||
|
||||
func NewPlayer() *Player {
|
||||
return &Player{
|
||||
ret := &Player{
|
||||
Sprite: &gx.Sprite{
|
||||
T: gx.Transform {
|
||||
S: gx.Vector{5, 5},
|
||||
RA: gx.Vector{320, 240},
|
||||
},
|
||||
I: playerImg,
|
||||
Visible: true,
|
||||
Shader: gx.SolidWhiteColorShader,
|
||||
},
|
||||
MoveSpeed: 90.,
|
||||
ScaleSpeed: .2,
|
||||
}
|
||||
|
||||
ret.Images[0] = playerImg
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (p *Player) Start(e *gx.Engine) {
|
||||
func (p *Player) Start(e *gx.Engine, v ...any) {
|
||||
fmt.Println("starting")
|
||||
c := e.Camera()
|
||||
c.T.RA = gx.V(360, -240)
|
||||
}
|
||||
|
@ -130,28 +170,6 @@ func main() {
|
|||
|
||||
e.Add(0, NewPlayer())
|
||||
e.Add(1, &Debug{})
|
||||
e.Add(-1, gx.DrawableRectangle{
|
||||
Rectangle: gx.Rectangle{
|
||||
W: 4,
|
||||
H: 4,
|
||||
T: gx.T(),
|
||||
},
|
||||
Color: gx.Color{
|
||||
gx.MaxColorV,
|
||||
0,
|
||||
0,
|
||||
gx.MaxColorV,
|
||||
},
|
||||
Visible: true,
|
||||
Shader: gx.SolidWhiteColorShader,
|
||||
Options: gx.ShaderOptions{
|
||||
Images: [4]*gx.Image{
|
||||
playerImg,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
},
|
||||
})
|
||||
e.Add(-1, NewRect())
|
||||
e.Run()
|
||||
}
|
||||
|
|
|
@ -20,8 +20,12 @@ type Layer int
|
|||
// Window configuration type.
|
||||
type WindowConfig struct {
|
||||
Title string
|
||||
Width, Height int
|
||||
FixedSize bool
|
||||
|
||||
Width,
|
||||
Height int
|
||||
|
||||
FixedSize,
|
||||
Fullscreen,
|
||||
VSync bool
|
||||
}
|
||||
|
||||
|
@ -29,7 +33,7 @@ type WindowConfig struct {
|
|||
type Engine struct {
|
||||
wcfg *WindowConfig
|
||||
layers *sparsex.Sparse[Layer, *poolx.Pool[Drawer]]
|
||||
behavers *poolx.Pool[Behaver]
|
||||
updaters *poolx.Pool[Updater]
|
||||
lastTime time.Time
|
||||
dt Float
|
||||
camera *Camera
|
||||
|
@ -72,26 +76,36 @@ func New(
|
|||
S: Vector{1, 1},
|
||||
},
|
||||
},
|
||||
behavers: poolx.New[Behaver](),
|
||||
updaters: poolx.New[Updater](),
|
||||
}
|
||||
}
|
||||
|
||||
// Add new object considering what
|
||||
// interfaces it implements.
|
||||
func (e *Engine) Add(l Layer, b any) {
|
||||
beh, ok := b.(Behaver)
|
||||
starter, ok := b.(Starter)
|
||||
if ok {
|
||||
e.addBehaver(beh)
|
||||
starter.Start(e)
|
||||
}
|
||||
|
||||
updater, ok := b.(Updater)
|
||||
if ok {
|
||||
e.addUpdater(updater)
|
||||
}
|
||||
|
||||
drw, ok := b.(Drawer)
|
||||
drawer, ok := b.(Drawer)
|
||||
if ok {
|
||||
e.addDrawer(l, drw)
|
||||
e.addDrawer(l, drawer)
|
||||
}
|
||||
}
|
||||
|
||||
// Del object from Engine.
|
||||
func (e *Engine) Del(b any) {
|
||||
// Delete object from Engine.
|
||||
func (e *Engine) Del(b any, v ...any) {
|
||||
deleter, ok := b.(Deleter)
|
||||
if ok {
|
||||
deleter.Delete(e, v...)
|
||||
}
|
||||
|
||||
drawer, ok := b.(Drawer)
|
||||
if ok {
|
||||
for layer := range e.layers.Vals() {
|
||||
|
@ -99,9 +113,9 @@ func (e *Engine) Del(b any) {
|
|||
}
|
||||
}
|
||||
|
||||
behaver, ok := b.(Behaver)
|
||||
updater, ok := b.(Updater)
|
||||
if ok {
|
||||
e.behavers.Del(behaver)
|
||||
e.updaters.Del(updater)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -121,9 +135,8 @@ func (e *Engine) addDrawer(l Layer, d Drawer) {
|
|||
|
||||
}
|
||||
|
||||
func (e *Engine) addBehaver(b Behaver) {
|
||||
e.behavers.Append(b)
|
||||
b.Start(e)
|
||||
func (e *Engine) addUpdater(b Updater) {
|
||||
e.updaters.Append(b)
|
||||
}
|
||||
|
||||
func (e *engine) Update() error {
|
||||
|
@ -134,7 +147,7 @@ func (e *engine) Update() error {
|
|||
AppendPressedKeys(e.keys[:0])
|
||||
|
||||
e.dt = time.Since(e.lastTime).Seconds()
|
||||
for p := range eng.behavers.Range() {
|
||||
for p := range eng.updaters.Range() {
|
||||
err = p.V.Update(eng)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -4,8 +4,9 @@ package gx
|
|||
// will call the function OnStart
|
||||
// when first appear on scene BEFORE
|
||||
// the OnUpdate.
|
||||
// The v value will be get from Add function.
|
||||
type Starter interface {
|
||||
Start(*Engine)
|
||||
Start(*Engine, ...any)
|
||||
}
|
||||
|
||||
// Implementing the interface type
|
||||
|
@ -15,9 +16,10 @@ type Updater interface {
|
|||
Update(*Engine) error
|
||||
}
|
||||
|
||||
// The general interface for
|
||||
type Behaver interface {
|
||||
Starter
|
||||
Updater
|
||||
// Implementing the interface type
|
||||
// will call the function on deleting
|
||||
// the object.
|
||||
type Deleter interface {
|
||||
Delete(*Engine, ...any)
|
||||
}
|
||||
|
||||
|
|
|
@ -22,14 +22,19 @@ type Rectangle struct {
|
|||
type DrawableRectangle struct {
|
||||
Rectangle
|
||||
|
||||
Shader *Shader
|
||||
// Solid color of the rectangle.
|
||||
// Will be ignored if the Shader
|
||||
// field is not nil.
|
||||
Color Color
|
||||
|
||||
Options ShaderOptions
|
||||
// Shader to be applied
|
||||
Shader *Shader
|
||||
// Shader variables.
|
||||
Uniforms map[string] any
|
||||
// Shader images
|
||||
Images [4]*Image
|
||||
|
||||
// Should be draw or not.
|
||||
Visible bool
|
||||
}
|
||||
|
||||
|
@ -56,26 +61,29 @@ func NewImage(w, h int) (*Image) {
|
|||
return ebiten.NewImage(w, h)
|
||||
}
|
||||
|
||||
func (r DrawableRectangle) IsVisible() bool {
|
||||
func (r *DrawableRectangle) IsVisible() bool {
|
||||
return r.Visible
|
||||
}
|
||||
|
||||
func (r DrawableRectangle) Draw(
|
||||
func (r *DrawableRectangle) Draw(
|
||||
e *Engine,
|
||||
i *Image,
|
||||
) {
|
||||
t := r.T
|
||||
t.S.X *= r.W
|
||||
t.S.Y *= r.H
|
||||
|
||||
rm := e.Camera().RealMatrix(e, true)
|
||||
m := t.Matrix(e)
|
||||
m.Concat(rm)
|
||||
|
||||
// Draw solid color if no shader.
|
||||
if r.Shader == nil {
|
||||
img := NewImage(1, 1)
|
||||
img.Set(0, 0, r.Color)
|
||||
|
||||
t.S.X *= r.W
|
||||
t.S.Y *= r.H
|
||||
|
||||
m := t.Matrix(e)
|
||||
rm := e.Camera().RealMatrix(e, true)
|
||||
|
||||
m.Concat(rm)
|
||||
|
||||
opts := &ebiten.DrawImageOptions{
|
||||
GeoM: m,
|
||||
}
|
||||
|
@ -83,20 +91,35 @@ func (r DrawableRectangle) Draw(
|
|||
return
|
||||
}
|
||||
|
||||
|
||||
// Use the Color as base image if no is provided.
|
||||
if r.Options.Images[0] == nil {
|
||||
r.Options.Images[0] = NewImage(1, 1)
|
||||
r.Options.Images[0].Set(0, 0, r.Color)
|
||||
var did bool
|
||||
if r.Images[0] == nil {
|
||||
r.Images[0] = NewImage(1, 1)
|
||||
r.Images[0].Set(0, 0, r.Color)
|
||||
did = true
|
||||
}
|
||||
|
||||
w, h := r.Images[0].Size()
|
||||
if !did {
|
||||
t.S.X /= Float(w)
|
||||
t.S.Y /= Float(h)
|
||||
|
||||
t.S.X *= r.W
|
||||
t.S.Y *= r.H
|
||||
}
|
||||
|
||||
|
||||
rm := e.Camera().RealMatrix(e, true)
|
||||
m := t.Matrix(e)
|
||||
m.Concat(rm)
|
||||
|
||||
// Drawing with shader.
|
||||
opts := &ebiten.DrawRectShaderOptions{
|
||||
GeoM: m,
|
||||
Images: r.Options.Images,
|
||||
Uniforms: r.Options.Uniforms,
|
||||
Images: r.Images,
|
||||
Uniforms: r.Uniforms,
|
||||
}
|
||||
|
||||
w, h := r.Options.Images[0].Size()
|
||||
i.DrawRectShader(w, h, r.Shader, opts)
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,10 @@ import (
|
|||
)
|
||||
|
||||
type Sprite struct {
|
||||
I *Image
|
||||
T Transform
|
||||
S *Shader
|
||||
Shader *Shader
|
||||
Images [4]*Image
|
||||
Uniforms map[string] any
|
||||
Floating, Visible bool
|
||||
}
|
||||
|
||||
|
@ -15,25 +16,37 @@ func (s *Sprite) Draw(
|
|||
e *Engine,
|
||||
i *Image,
|
||||
) {
|
||||
op := &ebiten.DrawImageOptions{
|
||||
|
||||
// Nothing to draw.
|
||||
if s.Images[0] == nil {
|
||||
return
|
||||
}
|
||||
|
||||
m := &Matrix{}
|
||||
|
||||
m.Concat(s.T.Matrix(e))
|
||||
if e.camera != nil {
|
||||
m.Concat(e.camera.RealMatrix(
|
||||
if !s.Floating {
|
||||
m.Concat(e.Camera().RealMatrix(
|
||||
e,
|
||||
true,
|
||||
))
|
||||
}
|
||||
|
||||
op.GeoM = *m
|
||||
/*if s.S != nil {
|
||||
bufImg := ebiten.NewImageFromImage(s.I)
|
||||
} */
|
||||
// Drawing without shader.
|
||||
if s.Shader == nil {
|
||||
opts := &ebiten.DrawImageOptions{}
|
||||
opts.GeoM = *m
|
||||
i.DrawImage(s.Images[0], opts)
|
||||
return
|
||||
}
|
||||
|
||||
i.DrawImage(s.I, op)
|
||||
// Drawing with shader.
|
||||
w, h := s.Images[0].Size()
|
||||
opts := &ebiten.DrawRectShaderOptions{
|
||||
Images: s.Images,
|
||||
Uniforms: s.Uniforms,
|
||||
GeoM: *m,
|
||||
}
|
||||
i.DrawRectShader(w, h, s.Shader, opts)
|
||||
}
|
||||
|
||||
func (s *Sprite) IsVisible() bool {
|
||||
|
|
Loading…
Reference in a new issue