mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-20 07:27:19 -05:00
Started work on shadows (#630)
This commit is contained in:
parent
856043d8ac
commit
460e821a5e
@ -13,7 +13,7 @@ type Animation interface {
|
||||
SetSubLoop(startFrame, EndFrame int)
|
||||
Advance(elapsed float64) error
|
||||
Render(target Surface) error
|
||||
RenderFromOrigin(target Surface) error
|
||||
RenderFromOrigin(target Surface, shadow bool) error
|
||||
RenderSection(sfc Surface, bound image.Rectangle) error
|
||||
GetFrameSize(frameIndex int) (int, int, error)
|
||||
GetCurrentFrameSize() (int, int)
|
||||
|
@ -21,7 +21,10 @@ type Surface interface {
|
||||
PushEffect(effect d2enum.DrawEffect)
|
||||
PushFilter(filter d2enum.Filter)
|
||||
PushTranslation(x, y int)
|
||||
PushSkew(x, y float64)
|
||||
PushScale(x, y float64)
|
||||
PushBrightness(brightness float64)
|
||||
PushSaturation(saturation float64)
|
||||
Render(surface Surface) error
|
||||
// Renders a section of the surface enclosed by bounds
|
||||
RenderSection(surface Surface, bound image.Rectangle) error
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"image"
|
||||
"image/color"
|
||||
"math"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
|
||||
@ -112,6 +113,24 @@ func (a *animation) Advance(elapsed float64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *animation) renderShadow(target d2iface.Surface) error {
|
||||
//_, height := a.GetFrameBounds()
|
||||
direction := a.directions[a.directionIndex]
|
||||
frame := direction.frames[a.frameIndex]
|
||||
target.PushFilter(d2enum.FilterLinear)
|
||||
target.PushTranslation(
|
||||
frame.offsetX,
|
||||
int(float64(frame.offsetY)*0.5))
|
||||
target.PushScale(1.0, 0.5)
|
||||
target.PushSkew(0.5, 0.0)
|
||||
target.PushEffect(d2enum.DrawEffectPctTransparency25)
|
||||
target.PushBrightness(0.0)
|
||||
|
||||
defer target.PopN(6)
|
||||
|
||||
return target.Render(frame.image)
|
||||
}
|
||||
|
||||
// Render renders the animation to the given surface
|
||||
func (a *animation) Render(target d2iface.Surface) error {
|
||||
direction := a.directions[a.directionIndex]
|
||||
@ -130,7 +149,7 @@ func (a *animation) Render(target d2iface.Surface) error {
|
||||
}
|
||||
|
||||
// RenderFromOrigin renders the animation from the animation origin
|
||||
func (a *animation) RenderFromOrigin(target d2iface.Surface) error {
|
||||
func (a *animation) RenderFromOrigin(target d2iface.Surface, shadow bool) error {
|
||||
if a.originAtBottom {
|
||||
direction := a.directions[a.directionIndex]
|
||||
frame := direction.frames[a.frameIndex]
|
||||
@ -139,6 +158,14 @@ func (a *animation) RenderFromOrigin(target d2iface.Surface) error {
|
||||
defer target.Pop()
|
||||
}
|
||||
|
||||
if shadow {
|
||||
_, height := a.GetFrameBounds()
|
||||
height = int(math.Abs(float64(height)))
|
||||
target.PushTranslation((-height / 2), 0)
|
||||
defer target.Pop()
|
||||
return a.renderShadow(target)
|
||||
}
|
||||
|
||||
return a.Render(target)
|
||||
}
|
||||
|
||||
|
@ -59,10 +59,20 @@ func (c *Composite) Render(target d2interface.Surface) error {
|
||||
}
|
||||
|
||||
direction := d2cof.Dir64ToCof(c.direction, c.mode.cof.NumberOfDirections)
|
||||
|
||||
for _, layerIndex := range c.mode.cof.Priority[direction][c.mode.frameIndex] {
|
||||
layer := c.mode.layers[layerIndex]
|
||||
if layer != nil {
|
||||
if err := layer.RenderFromOrigin(target); err != nil {
|
||||
if err := layer.RenderFromOrigin(target, true); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, layerIndex := range c.mode.cof.Priority[direction][c.mode.frameIndex] {
|
||||
layer := c.mode.layers[layerIndex]
|
||||
if layer != nil {
|
||||
if err := layer.RenderFromOrigin(target, false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -85,8 +85,14 @@ func (r *Renderer) CreateSurface(surface d2interface.Surface) (d2interface.Surfa
|
||||
result := createEbitenSurface(
|
||||
surface.(*ebitenSurface).image,
|
||||
surfaceState{
|
||||
filter: ebiten.FilterNearest,
|
||||
effect: d2enum.DrawEffectNone,
|
||||
filter: ebiten.FilterNearest,
|
||||
effect: d2enum.DrawEffectNone,
|
||||
saturation: 1.0,
|
||||
brightness: 1.0,
|
||||
skewX: 0.0,
|
||||
skewY: 0.0,
|
||||
scaleX: 0.0,
|
||||
scaleY: 0.0,
|
||||
},
|
||||
)
|
||||
|
||||
|
@ -35,7 +35,15 @@ type ebitenSurface struct {
|
||||
}
|
||||
|
||||
func createEbitenSurface(img *ebiten.Image, currentState ...surfaceState) *ebitenSurface {
|
||||
state := surfaceState{effect: d2enum.DrawEffectNone}
|
||||
state := surfaceState{
|
||||
effect: d2enum.DrawEffectNone,
|
||||
saturation: 1.0,
|
||||
brightness: 1.0,
|
||||
skewX: 0.0,
|
||||
skewY: 0.0,
|
||||
scaleX: 1.0,
|
||||
scaleY: 1.0,
|
||||
}
|
||||
if len(currentState) > 0 {
|
||||
state = currentState[0]
|
||||
}
|
||||
@ -54,6 +62,20 @@ func (s *ebitenSurface) PushTranslation(x, y int) {
|
||||
s.stateCurrent.y += y
|
||||
}
|
||||
|
||||
// PushSkew pushes a skew to the state stack
|
||||
func (s *ebitenSurface) PushSkew(skewX, skewY float64) {
|
||||
s.stateStack = append(s.stateStack, s.stateCurrent)
|
||||
s.stateCurrent.skewX = skewX
|
||||
s.stateCurrent.skewY = skewY
|
||||
}
|
||||
|
||||
// PushScale pushes a scale to the state stack
|
||||
func (s *ebitenSurface) PushScale(scaleX, scaleY float64) {
|
||||
s.stateStack = append(s.stateStack, s.stateCurrent)
|
||||
s.stateCurrent.scaleX = scaleX
|
||||
s.stateCurrent.scaleY = scaleY
|
||||
}
|
||||
|
||||
// PushEffect pushes an effect to the state stack
|
||||
func (s *ebitenSurface) PushEffect(effect d2enum.DrawEffect) {
|
||||
s.stateStack = append(s.stateStack, s.stateCurrent)
|
||||
@ -78,6 +100,12 @@ func (s *ebitenSurface) PushBrightness(brightness float64) {
|
||||
s.stateCurrent.brightness = brightness
|
||||
}
|
||||
|
||||
// PushSaturation pushes a saturation value to the state stack
|
||||
func (s *ebitenSurface) PushSaturation(saturation float64) {
|
||||
s.stateStack = append(s.stateStack, s.stateCurrent)
|
||||
s.stateCurrent.saturation = saturation
|
||||
}
|
||||
|
||||
// Pop pops a state off of the state stack
|
||||
func (s *ebitenSurface) Pop() {
|
||||
count := len(s.stateStack)
|
||||
@ -99,15 +127,25 @@ func (s *ebitenSurface) PopN(n int) {
|
||||
// Render renders the given surface
|
||||
func (s *ebitenSurface) Render(sfc d2interface.Surface) error {
|
||||
opts := &ebiten.DrawImageOptions{}
|
||||
|
||||
if s.stateCurrent.skewX != 0 || s.stateCurrent.skewY != 0 {
|
||||
opts.GeoM.Skew(s.stateCurrent.skewX, s.stateCurrent.skewY)
|
||||
}
|
||||
|
||||
if s.stateCurrent.scaleX != 1.0 || s.stateCurrent.scaleY != 1.0 {
|
||||
opts.GeoM.Scale(s.stateCurrent.scaleX, s.stateCurrent.scaleY)
|
||||
}
|
||||
|
||||
opts.GeoM.Translate(float64(s.stateCurrent.x), float64(s.stateCurrent.y))
|
||||
|
||||
opts.Filter = s.stateCurrent.filter
|
||||
|
||||
if s.stateCurrent.color != nil {
|
||||
opts.ColorM = s.colorToColorM(s.stateCurrent.color)
|
||||
}
|
||||
|
||||
if s.stateCurrent.brightness != 0 {
|
||||
opts.ColorM.ChangeHSV(0, 1, s.stateCurrent.brightness)
|
||||
if s.stateCurrent.brightness != 1 || s.stateCurrent.saturation != 1 {
|
||||
opts.ColorM.ChangeHSV(0, s.stateCurrent.saturation, s.stateCurrent.brightness)
|
||||
}
|
||||
|
||||
// Are these correct? who even knows
|
||||
@ -137,7 +175,17 @@ func (s *ebitenSurface) Render(sfc d2interface.Surface) error {
|
||||
// Renders the section of the surface, given the bounds
|
||||
func (s *ebitenSurface) RenderSection(sfc d2interface.Surface, bound image.Rectangle) error {
|
||||
opts := &ebiten.DrawImageOptions{}
|
||||
|
||||
if s.stateCurrent.skewX != 0 || s.stateCurrent.skewY != 0 {
|
||||
opts.GeoM.Skew(s.stateCurrent.skewX, s.stateCurrent.skewY)
|
||||
}
|
||||
|
||||
if s.stateCurrent.scaleX != 1.0 || s.stateCurrent.scaleY != 1.0 {
|
||||
opts.GeoM.Scale(s.stateCurrent.scaleX, s.stateCurrent.scaleY)
|
||||
}
|
||||
|
||||
opts.GeoM.Translate(float64(s.stateCurrent.x), float64(s.stateCurrent.y))
|
||||
|
||||
opts.Filter = s.stateCurrent.filter
|
||||
|
||||
if s.stateCurrent.color != nil {
|
||||
@ -145,7 +193,7 @@ func (s *ebitenSurface) RenderSection(sfc d2interface.Surface, bound image.Recta
|
||||
}
|
||||
|
||||
if s.stateCurrent.brightness != 0 {
|
||||
opts.ColorM.ChangeHSV(0, 1, s.stateCurrent.brightness)
|
||||
opts.ColorM.ChangeHSV(0, s.stateCurrent.saturation, s.stateCurrent.brightness)
|
||||
}
|
||||
|
||||
// Are these correct? who even knows
|
||||
|
@ -9,10 +9,13 @@ import (
|
||||
)
|
||||
|
||||
type surfaceState struct {
|
||||
x int
|
||||
y int
|
||||
filter ebiten.Filter
|
||||
color color.Color
|
||||
brightness float64
|
||||
effect d2enum.DrawEffect
|
||||
x int
|
||||
y int
|
||||
filter ebiten.Filter
|
||||
color color.Color
|
||||
brightness float64
|
||||
saturation float64
|
||||
effect d2enum.DrawEffect
|
||||
skewX, skewY float64
|
||||
scaleX, scaleY float64
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user