-- if this is too wasteful, one could check nerby tiles to see whether faces could be visible
-- more robust solution would be to travel the level from observer point of view
function render_dungeon(dungeon)
    for y = 1, dungeon.size.y do
        for x = 1, dungeon.size.x do
            if dungeon.grid[y][x].wall_texture ~= nil then
                draw_quad {
                    texture = dungeon.grid[y][x].wall_texture,
                    v3 = { x = x,     y = 1, z = y },
                    v2 = { x = x,     y = 0, z = y },
                    v1 = { x = x + 1, y = 0, z = y },
                    v0 = { x = x + 1, y = 1, z = y },
                    texture_region = { w = 128, h = 128 },
                }
                draw_quad {
                    texture = dungeon.grid[y][x].wall_texture,
                    v3 = { x = x + 1, y = 1, z = y },
                    v2 = { x = x + 1, y = 0, z = y },
                    v1 = { x = x + 1, y = 0, z = y + 1 },
                    v0 = { x = x + 1, y = 1, z = y + 1 },
                    texture_region = { w = 128, h = 128 },
                }
                draw_quad {
                    texture = dungeon.grid[y][x].wall_texture,
                    v3 = { x = x + 1, y = 1, z = y + 1 },
                    v2 = { x = x + 1, y = 0, z = y + 1 },
                    v1 = { x = x,     y = 0, z = y + 1 },
                    v0 = { x = x,     y = 1, z = y + 1 },
                    texture_region = { w = 128, h = 128 },
                }
                draw_quad {
                    texture = dungeon.grid[y][x].wall_texture,
                    v3 = { x = x,     y = 1, z = y + 1 },
                    v2 = { x = x,     y = 0, z = y + 1 },
                    v1 = { x = x,     y = 0, z = y },
                    v0 = { x = x,     y = 1, z = y },
                    texture_region = { w = 128, h = 128 },
                }

            elseif dungeon.grid[y][x].tile_texture ~= nil then
                draw_quad {
                    texture = dungeon.grid[y][x].tile_texture,
                    v0 = { x = x + 1, y = 0, z = y },
                    v1 = { x = x,     y = 0, z = y },
                    v2 = { x = x,     y = 0, z = y + 1 },
                    v3 = { x = x + 1, y = 0, z = y + 1},
                    texture_region = { w = 128, h = 128 },
                }
                draw_quad {
                    texture = dungeon.grid[y][x].tile_texture,
                    v3 = { x = x + 1, y = 1, z = y },
                    v2 = { x = x,     y = 1, z = y },
                    v1 = { x = x,     y = 1, z = y + 1 },
                    v0 = { x = x + 1, y = 1, z = y + 1},
                    texture_region = { w = 128, h = 128 },
                }
            end

            if dungeon.grid[y][x].face_texture ~= nil then
                if dungeon.grid[y][x].face == "horizon" then
                    draw_quad {
                        texture = dungeon.grid[y][x].face_texture,
                        v3 = { x = x + 1, y = 1, z = y },
                        v2 = { x = x + 1, y = 0, z = y },
                        v1 = { x = x + 1, y = 0, z = y + 1 },
                        v0 = { x = x + 1, y = 1, z = y + 1 },
                        texture_region = { w = 64, h = 64 },
                    }
                    draw_quad {
                        texture = dungeon.grid[y][x].face_texture,
                        v3 = { x = x,     y = 1, z = y + 1 },
                        v2 = { x = x,     y = 0, z = y + 1 },
                        v1 = { x = x,     y = 0, z = y },
                        v0 = { x = x,     y = 1, z = y },
                        texture_region = { w = 64, h = 64 },
                    }

                elseif dungeon.grid[y][x].face == "observer" then
                    draw_billboard {
                        texture = dungeon.grid[y][x].face_texture,
                        position = { x = x + 0.5, y = 0.5, z = y + 0.5 },
                        size = { x = 0.5, y = 0.5 },
                    }
                end
            end
        end
    end
end