From 404a87afd41dd1d628610a9331013f20e0252927 Mon Sep 17 00:00:00 2001 From: Ziemas Date: Sun, 17 Nov 2019 04:53:55 +0100 Subject: [PATCH] Fix issues with rendering order (#193) * Rework render passes * Fix drawing order logic Mostly at least, probably need the objects OrderFlags to do better. * Third pass required for Lut Gholein palace roof --- d2render/d2mapengine/engine.go | 117 ++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 53 deletions(-) diff --git a/d2render/d2mapengine/engine.go b/d2render/d2mapengine/engine.go index 61db0003..afa1cbbd 100644 --- a/d2render/d2mapengine/engine.go +++ b/d2render/d2mapengine/engine.go @@ -134,22 +134,70 @@ func (v *Engine) GenTiles(region *EngineRegion) { } func (v *Engine) RenderRegion(region EngineRegion, target *ebiten.Image) { - //tilesToRender := make([]RegionTile, len(region.Tiles)) - for tileIdx := range region.Tiles { sx, sy := d2helper.IsoToScreen(region.Tiles[tileIdx].tileX+region.Rect.Left, region.Tiles[tileIdx].tileY+region.Rect.Top, int(v.OffsetX), int(v.OffsetY)) if sx > -160 && sy > -160 && sx <= 880 && sy <= 1000 { - v.RenderTile(region.Region, region.Tiles[tileIdx].offX, region.Tiles[tileIdx].offY, region.Tiles[tileIdx].tileX, region.Tiles[tileIdx].tileY, target) + v.RenderPass1(region.Region, region.Tiles[tileIdx].offX, region.Tiles[tileIdx].offY, region.Tiles[tileIdx].tileX, region.Tiles[tileIdx].tileY, target) + } + } + for tileIdx := range region.Tiles { + sx, sy := d2helper.IsoToScreen(region.Tiles[tileIdx].tileX+region.Rect.Left, region.Tiles[tileIdx].tileY+region.Rect.Top, int(v.OffsetX), int(v.OffsetY)) + if sx > -160 && sy > -160 && sx <= 880 && sy <= 1000 { + v.RenderPass2(region.Region, region.Tiles[tileIdx].offX, region.Tiles[tileIdx].offY, region.Tiles[tileIdx].tileX, region.Tiles[tileIdx].tileY, target) + } + } + for tileIdx := range region.Tiles { + sx, sy := d2helper.IsoToScreen(region.Tiles[tileIdx].tileX+region.Rect.Left, region.Tiles[tileIdx].tileY+region.Rect.Top, int(v.OffsetX), int(v.OffsetY)) + if sx > -160 && sy > -160 && sx <= 880 && sy <= 1000 { + v.RenderPass3(region.Region, region.Tiles[tileIdx].offX, region.Tiles[tileIdx].offY, region.Tiles[tileIdx].tileX, region.Tiles[tileIdx].tileY, target) + if v.ShowTiles > 0 { + v.DrawTileLines(region.Region, region.Tiles[tileIdx].offX, region.Tiles[tileIdx].offY, region.Tiles[tileIdx].tileX, region.Tiles[tileIdx].tileY, target) + } } } - - //for _, tile := range tilesToRender { - // v.RenderTileObjects(region.Region, tile.offX, tile.offY, tile.tileX, tile.tileY, target) - //} } -func (v *Engine) RenderTileObjects(region *Region, offX, offY, x, y int, target *ebiten.Image) { +func (v *Engine) RenderPass1(region *Region, offX, offY, x, y int, target *ebiten.Image) { tile := region.DS1.Tiles[y][x] + for i := range tile.Floors { + if tile.Floors[i].Hidden || tile.Floors[i].Prop1 == 0 { + continue + } + region.RenderTile(offX+int(v.OffsetX), offY+int(v.OffsetY), x, y, d2enum.RegionLayerTypeFloors, i, target) + } + for i := range tile.Shadows { + if tile.Shadows[i].Hidden || tile.Shadows[i].Prop1 == 0 { + continue + } + region.RenderTile(offX+int(v.OffsetX), offY+int(v.OffsetY), x, y, d2enum.RegionLayerTypeShadows, i, target) + } + + // Draw lower walls + for i := range tile.Walls { + if tile.Walls[i].Orientation <= 15 { + continue + } + if tile.Walls[i].Hidden || tile.Walls[i].Orientation == 10 || tile.Walls[i].Orientation == 11 || tile.Walls[i].Orientation == 0 { + continue + } + region.RenderTile(offX+int(v.OffsetX), offY+int(v.OffsetY), x, y, d2enum.RegionLayerTypeWalls, i, target) + } +} + +func (v *Engine) RenderPass2(region *Region, offX, offY, x, y int, target *ebiten.Image) { + tile := region.DS1.Tiles[y][x] + + // Draw upper walls + for i := range tile.Walls { + if tile.Walls[i].Orientation >= 15 { + continue + } + if tile.Walls[i].Hidden || tile.Walls[i].Orientation == 10 || tile.Walls[i].Orientation == 11 || tile.Walls[i].Orientation == 0 { + continue + } + region.RenderTile(offX+int(v.OffsetX), offY+int(v.OffsetY), x, y, d2enum.RegionLayerTypeWalls, i, target) + } + for _, obj := range region.AnimationEntities { if int(math.Floor(obj.LocationX)) == x && int(math.Floor(obj.LocationY)) == y { obj.Render(target, offX+int(v.OffsetX), offY+int(v.OffsetY)) @@ -160,13 +208,20 @@ func (v *Engine) RenderTileObjects(region *Region, offX, offY, x, y int, target npc.Render(target, offX+int(v.OffsetX), offY+int(v.OffsetY)) } } +} + +func (v *Engine) RenderPass3(region *Region, offX, offY, x, y int, target *ebiten.Image) { + tile := region.DS1.Tiles[y][x] + // Draw ceilings for i := range tile.Walls { - if tile.Walls[i].Hidden || tile.Walls[i].Orientation != 15 { + if tile.Walls[i].Orientation != 15 { continue } region.RenderTile(offX+int(v.OffsetX), offY+int(v.OffsetY), x, y, d2enum.RegionLayerTypeWalls, i, target) } +} +func (v *Engine) DrawTileLines(region *Region, offX, offY, x, y int, target *ebiten.Image) { if v.ShowTiles > 0 { subtileColor := color.RGBA{255, 100, 100, 140} tileColor := color.RGBA{255, 255, 255, 255} @@ -189,47 +244,3 @@ func (v *Engine) RenderTileObjects(region *Region, offX, offY, x, y int, target } } } - -func (v *Engine) RenderTile(region *Region, offX, offY, x, y int, target *ebiten.Image) { - tile := region.DS1.Tiles[y][x] - for i := range tile.Floors { - if tile.Floors[i].Hidden || tile.Floors[i].Prop1 == 0 { - continue - } - region.RenderTile(offX+int(v.OffsetX), offY+int(v.OffsetY), x, y, d2enum.RegionLayerTypeFloors, i, target) - } - for i := range tile.Shadows { - if tile.Shadows[i].Hidden || tile.Shadows[i].Prop1 == 0 { - continue - } - region.RenderTile(offX+int(v.OffsetX), offY+int(v.OffsetY), x, y, d2enum.RegionLayerTypeShadows, i, target) - } - for i := range tile.Walls { - if tile.Walls[i].Orientation >= 15 { - // Upper walls only - continue - } - if tile.Walls[i].Hidden || tile.Walls[i].Orientation == 15 || tile.Walls[i].Orientation == 10 || tile.Walls[i].Orientation == 11 || tile.Walls[i].Orientation == 0 { - continue - } - region.RenderTile(offX+int(v.OffsetX), offY+int(v.OffsetY), x, y, d2enum.RegionLayerTypeWalls, i, target) - } - v.RenderTileObjects(region, offX, offY, x, y, target) - for i := range tile.Walls { - if tile.Walls[i].Orientation <= 15 { - // Lower walls only - continue - } - if tile.Walls[i].Hidden || tile.Walls[i].Orientation == 15 || tile.Walls[i].Orientation == 10 || tile.Walls[i].Orientation == 11 || tile.Walls[i].Orientation == 0 { - continue - } - region.RenderTile(offX+int(v.OffsetX), offY+int(v.OffsetY), x, y, d2enum.RegionLayerTypeWalls, i, target) - } - for i := range tile.Walls { - if tile.Walls[i].Orientation != 15 { - // Ceiling only - continue - } - region.RenderTile(offX+int(v.OffsetX), offY+int(v.OffsetY), x, y, d2enum.RegionLayerTypeWalls, i, target) - } -}