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