Render multiple Z levels
Performance regression warning: this is now quite slow to render when showing all 7 Z levels. Bounds clipping may be enough to get it back to acceptable levels, or we may have to do something cleverer
This commit is contained in:
@@ -112,10 +112,10 @@ func (e *env) run() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *env) getSprite(palette []string, ref maps.ObjRef) (*conv.Sprite, *conv.Object) {
|
func (e *env) getSprite(palette []string, ref maps.ObjRef) *conv.Sprite {
|
||||||
if ref.Index() >= len(palette) {
|
if ref.Index() >= len(palette) {
|
||||||
log.Printf("Palette too small: %v requested", ref.Index())
|
log.Printf("Palette too small: %v requested", ref.Index())
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
name := palette[ref.Index()]
|
name := palette[ref.Index()]
|
||||||
@@ -123,15 +123,15 @@ func (e *env) getSprite(palette []string, ref maps.ObjRef) (*conv.Sprite, *conv.
|
|||||||
obj := e.objects[name]
|
obj := e.objects[name]
|
||||||
if obj == nil {
|
if obj == nil {
|
||||||
log.Printf("Failed to find surface sprite %#v -> %q", ref, name)
|
log.Printf("Failed to find surface sprite %#v -> %q", ref, name)
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if ref.Frame() >= len(obj.Sprites) {
|
if ref.Frame() >= len(obj.Sprites) {
|
||||||
log.Printf("Out-of-index sprite %v requested for %v", ref.Frame(), name)
|
log.Printf("Out-of-index sprite %v requested for %v", ref.Frame(), name)
|
||||||
return nil, obj
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &obj.Sprites[ref.Frame()], obj
|
return &obj.Sprites[ref.Frame()]
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -142,8 +142,6 @@ var (
|
|||||||
// TODO: build all the sprites in the set into a single spritesheet so we can
|
// TODO: build all the sprites in the set into a single spritesheet so we can
|
||||||
// use pixel.Batch
|
// use pixel.Batch
|
||||||
func (s *state) present(pWin *pixelgl.Window) {
|
func (s *state) present(pWin *pixelgl.Window) {
|
||||||
gameMap := s.env.gameMap
|
|
||||||
|
|
||||||
pWin.Clear(colornames.Black)
|
pWin.Clear(colornames.Black)
|
||||||
|
|
||||||
center := pWin.Bounds().Center()
|
center := pWin.Bounds().Center()
|
||||||
@@ -156,45 +154,56 @@ func (s *state) present(pWin *pixelgl.Window) {
|
|||||||
s.cam = cam
|
s.cam = cam
|
||||||
pWin.SetMatrix(cam)
|
pWin.SetMatrix(cam)
|
||||||
|
|
||||||
// TODO: bounds clipping
|
// TODO: we should be able to perform bounds clipping on these
|
||||||
z := int(s.zIdx)
|
minX := int(s.env.gameMap.MinWidth)
|
||||||
for y := int(gameMap.MinLength); y < int(gameMap.MaxLength); y++ {
|
maxX := int(s.env.gameMap.MaxWidth)
|
||||||
for x := int(gameMap.MinWidth); x < int(gameMap.MaxWidth); x++ {
|
minY := int(s.env.gameMap.MinLength)
|
||||||
|
maxY := int(s.env.gameMap.MaxLength)
|
||||||
|
minZ := 0
|
||||||
|
maxZ := int(s.zIdx) + 1
|
||||||
|
|
||||||
cell := gameMap.Cells.At(x, y, z)
|
for z := minZ; z < maxZ; z++ {
|
||||||
|
for y := minY; y < maxY; y++ {
|
||||||
|
for x := minX; x < maxX; x++ {
|
||||||
|
s.renderCell(x, y, z, pWin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
surfaceSprite, _ := s.env.getSprite(s.env.set.Palette, cell.Surface)
|
func (s *state) renderCell(x, y, z int, pWin *pixelgl.Window) {
|
||||||
centerSprite, _ := s.env.getSprite(s.env.set.Palette, cell.Center)
|
var sprites []*conv.Sprite
|
||||||
leftSprite, _ := s.env.getSprite(s.env.set.Palette, cell.Left)
|
|
||||||
rightSprite, _ := s.env.getSprite(s.env.set.Palette, cell.Right)
|
|
||||||
|
|
||||||
fX := float64(x)
|
cell := s.env.gameMap.Cells.At(x, y, z)
|
||||||
fY := float64(y)
|
|
||||||
|
// Try optimizing zero surfaces out, they tend to be? all-transparent
|
||||||
|
if cell.Surface.Index() != 0 {
|
||||||
|
sprites = append(sprites, s.env.getSprite(s.env.set.Palette, cell.Surface))
|
||||||
|
}
|
||||||
|
|
||||||
|
sprites = append(
|
||||||
|
sprites,
|
||||||
|
s.env.getSprite(s.env.set.Palette, cell.Center),
|
||||||
|
s.env.getSprite(s.env.set.Palette, cell.Left),
|
||||||
|
s.env.getSprite(s.env.set.Palette, cell.Right),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Taking the Z index away *seems* to draw the object in the correct place.
|
||||||
|
// FIXME: There are some artifacts, investigate more
|
||||||
|
fX := float64(x - z)
|
||||||
|
fY := float64(y - z)
|
||||||
|
|
||||||
xPos := fX * cellWidth
|
xPos := fX * cellWidth
|
||||||
yPos := fY * cellLength
|
yPos := fY * cellLength
|
||||||
|
|
||||||
// The rotation translates the rectangular coordinates to diamond
|
// The rotation translates the rectangular coordinates to diamond
|
||||||
// ones \o/
|
// ones \o/
|
||||||
// FIXME: these are off by a bit
|
|
||||||
orig := pixel.V(xPos, yPos)
|
orig := pixel.V(xPos, yPos)
|
||||||
iso := pixel.V(orig.X-orig.Y, (orig.X+orig.Y)/2.0)
|
iso := pixel.V(orig.X-orig.Y, (orig.X+orig.Y)/2.0)
|
||||||
|
|
||||||
if surfaceSprite != nil {
|
for _, sprite := range sprites {
|
||||||
surfaceSprite.Spr.Draw(pWin, pixel.IM.Moved(iso))
|
if sprite != nil {
|
||||||
}
|
sprite.Spr.Draw(pWin, pixel.IM.Moved(iso))
|
||||||
|
|
||||||
if centerSprite != nil {
|
|
||||||
centerSprite.Spr.Draw(pWin, pixel.IM.Moved(iso))
|
|
||||||
}
|
|
||||||
|
|
||||||
if leftSprite != nil {
|
|
||||||
leftSprite.Spr.Draw(pWin, pixel.IM.Moved(iso))
|
|
||||||
}
|
|
||||||
|
|
||||||
if rightSprite != nil {
|
|
||||||
rightSprite.Spr.Draw(pWin, pixel.IM.Moved(iso))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user