SFML community forums

Help => Graphics => Topic started by: DevilEdge on July 23, 2014, 05:26:28 pm

Title: Line artifacts when drawing tilemap
Post by: DevilEdge on July 23, 2014, 05:26:28 pm
Hi there,

I've (successfully) implemented the tilemap example from the resources into my game engine, but I'm getting these really odd line-like artifacts in between the tiles. I've recently switched computers, and on my other computer I already had this working with the same code and resources and did not have this issue. I've already validated that all of my tile resources have no artifacts on them, I've checked my code (it's exactly the same as in the examples), I've tried enabling vsync and texture smoothing with no avail, and I've looked around the forums for similar issues. On some posts I've seen people adding odd values to the texture coordinates like 0.375 and I also tried that, but it didn't work as well. I've attached a photo of my issue.

Thanks!
Title: AW: Line artifacts when drawing tilemap
Post by: eXpl0it3r on July 23, 2014, 05:46:13 pm
Did you make sure that your tiles are at integer position and the view isn't changed?
Title: Re: AW: Line artifacts when drawing tilemap
Post by: BaneTrapper on July 23, 2014, 06:06:55 pm
Did you make sure that your tiles are at integer position and the view isn't changed?
As eXpl0it3r said, its because your tiles are not at rounded position. when setting position do std::floor(position)
Title: Re: Line artifacts when drawing tilemap
Post by: DevilEdge on July 23, 2014, 08:30:36 pm
Ok, now I'm doing this to set position:

quad[0].position = sf::Vector2f(std::floor(topLeft.x), std::floor(topLeft.y));
quad[1].position = sf::Vector2f(std::floor(topRight.x), std::floor(topRight.y));                                        quad[2].position = sf::Vector2f(std::floor(downLeft.x), std::floor(downLeft.y));                                        quad[3].position = sf::Vector2f(std::floor(downRight.x), std::floor(downRight.y));

It hasn't done anything. I double checked to make sure each quad's position is an integer, which it is. The view isn't changing at all either.
Title: Re: Line artifacts when drawing tilemap
Post by: BaneTrapper on July 23, 2014, 10:49:51 pm
Post minimal example that reproduces the error.
Title: Re: Line artifacts when drawing tilemap
Post by: DevilEdge on July 24, 2014, 12:01:29 am
void load(const std::string& tileSet, sf::Vector2u tileSize, int* tiles,
                        unsigned int width, unsigned int height)
                {
                        m_tileset.loadFromFile(tileSet);

                        m_vertices.setPrimitiveType(sf::Quads);
                        m_vertices.resize(width * height * 4);

                        for (unsigned int i = 0; i < width; ++i)
                        {
                                for (unsigned int j = 0; j < height; ++j)
                                {
                                        int tileNumber = tiles[i + j * width];

                                        sf::Vector2f topLeft(i * tileSize.x, j * tileSize.y);
                                        sf::Vector2f topRight((i + 1) * tileSize.x, j * tileSize.y);
                                        sf::Vector2f downLeft((i + 1) * tileSize.x, (j + 1) * tileSize.y);
                                        sf::Vector2f downRight(i * tileSize.x, (j + 1) * tileSize.y);

                                        sf::FloatRect rect(topLeft.x, topLeft.y, topRight.x - topLeft.x, downLeft.y - topLeft.y);

                                        Tile tile(rect, tileNumber);

                                        m_tiles.push_back(tile);

                                        //Find the position in the tileset texture
                                        int tu = tileNumber % (m_tileset.getSize().x / tileSize.x);
                                        int tv = tileNumber / (m_tileset.getSize().x / tileSize.x);

                                        sf::Vertex* quad = &m_vertices[(i + j * width) * 4];

                                        //Define its 4 corners
                                        quad[0].position = sf::Vector2f(std::floor(topLeft.x), std::floor(topLeft.y));
                                        quad[1].position = sf::Vector2f(std::floor(topRight.x), std::floor(topRight.y));
                                        quad[2].position = sf::Vector2f(std::floor(downLeft.x), std::floor(downLeft.y));
                                        quad[3].position = sf::Vector2f(std::floor(downRight.x), std::floor(downRight.y));

                                        //Define its 4 texture coordinates
                                        quad[0].texCoords = sf::Vector2f(tu * tileSize.x, tv * tileSize.y);
                                        quad[1].texCoords = sf::Vector2f((tu + 1) * tileSize.x, tv * tileSize.y);
                                        quad[2].texCoords = sf::Vector2f((tu + 1) * tileSize.x, (tv + 1) * tileSize.y);
                                        quad[3].texCoords = sf::Vector2f(tu * tileSize.x, (tv + 1) * tileSize.y);
                                }
                        }
                }

That's the entirety of my drawing code.
Title: Re: Line artifacts when drawing tilemap
Post by: krzat on July 24, 2014, 12:17:52 am
I fixed similiar problem by using 1 pixel margin around tiles in spritesheet. For some reason GPU was pulling pixels from outside of the texcoords.
Title: Re: Line artifacts when drawing tilemap
Post by: Hapax on July 24, 2014, 01:27:12 am
That's the entirety of my drawing code.
We could use a complete and minimal example so others can compile it and test it for their selves.

Does your texture have smooth turned on?
Title: Line artifacts when drawing tilemap
Post by: The Terminator on July 24, 2014, 02:04:31 pm
That's the entirety of my drawing code.
We could use a complete and minimal example so others can compile it and test it for their selves.

The code is exactly the same as the tutorials. Exactly the same.

Quote
Does your texture have smooth turned on?

He's already said that texture smoothing didn't help.
Title: Re: Line artifacts when drawing tilemap
Post by: DevilEdge on July 24, 2014, 04:17:14 pm
I fixed similiar problem by using 1 pixel margin around tiles in spritesheet. For some reason GPU was pulling pixels from outside of the texcoords.

I tried this, but it made the problem even more apparent with even larger black lines.
Title: Re: Line artifacts when drawing tilemap
Post by: Hapax on July 24, 2014, 08:03:32 pm
my drawing code.
complete and minimal example
The code is exactly the same as the tutorials. Exactly the same.
That code might be but it's not complete. It's the rest of the code we need to see (especially since if that code is identical to the tutorials, we know it works).

Quote
Does your texture have smooth turned on?
I missed that, or forgot that it was mentioned by the time I'd read the entire thread. Sorry, my error.
Title: Re: Line artifacts when drawing tilemap
Post by: DevilEdge on July 25, 2014, 10:50:03 pm
I'm really stumped, and I can't figure out what the issue is. Does anyone else have any ideas?
Title: Re: Line artifacts when drawing tilemap
Post by: Jesper Juhl on July 25, 2014, 11:01:04 pm
This is a shot in the dark; but if your textures are not using "powers of two" dimentions, that might be it. Older graphics cards or old drivers may not deal properly with such textures. So, if your texture dimensions are not "power of two",  try making them so.
Title: Re: Line artifacts when drawing tilemap
Post by: DevilEdge on July 25, 2014, 11:49:20 pm
This is a shot in the dark; but if your textures are not using "powers of two" dimentions, that might be it. Older graphics cards or old drivers may not deal properly with such textures. So, if your texture dimensions are not "power of two",  try making them so.

The tiles are 16x16, and I thought it was a driver issue too. I'm running a Nvidia GTX 760, and I tested it on my brother's laptop which has an intel hd 3000. He had the exact same issue, so it's not a driver issue.
Title: Re: Line artifacts when drawing tilemap
Post by: DevilEdge on July 28, 2014, 05:37:37 pm
Ok, here's the entirety of all of my relevant code:

Player.hpp

class Player : public Entity
        {
        public:
                typedef std::shared_ptr<Player> Ptr;

                static Ptr create(const std::string& id = "player") { Ptr temp(new Player(id)); return temp; }

                void handleCollision();

                void move(const sf::Vector2f& offset);

                virtual void update(sf::Time dt);

                void draw(sf::RenderTarget& target, sf::RenderStates states) const;

        private:
                Player(const std::string& id = "player", bool active = true);

                sf::Texture m_texture;
                sf::Sprite m_sprite;

                sf::Vector2f m_viewArea;

                bool nextPosValid(const sf::Vector2f& offset);
                bool rectOverlapsTile(const sf::FloatRect& rect);
        };

Player.cpp

        Player::Player(const std::string& id, bool active) :
                m_viewArea(sf::Vector2f(100, 100))
        {
                m_texture.loadFromFile("Resources/player.png");
                m_sprite.setTexture(m_texture);
                m_sprite.setPosition(350, 300);

                registerAttribute("renderable", new bool(true));
                registerAttribute("health", new int(20));

                SceneManager::getView().setCenter(std::floor(350), std::floor(300));
                SceneManager::getView().setSize(m_viewArea);
        }

        bool Player::nextPosValid(const sf::Vector2f& offset)
        {
                sf::Vector2f offsettedPos(std::floor(m_sprite.getPosition().x + offset.x), std::floor(m_sprite.getPosition().y + offset.y));

                //The bounding rectangle of the future player
                sf::FloatRect rect(offsettedPos, sf::Vector2f(std::floor(m_sprite.getGlobalBounds().width), std::floor(m_sprite.getGlobalBounds().height)));

                if (SceneManager::getWorld().getCurrentCell()->getTileMap().collidesWithType(2, rect))
                        return false;

                return true;
        }

        void Player::move(const sf::Vector2f& offset)
        {
                m_sprite.move(offset);
                SceneManager::getView().move(offset);
        }

        void Player::update(sf::Time dt)
        {
                if (InputManager::isActive(User_Input::UPHOLD))
                {
                        if (nextPosValid(sf::Vector2f(0, -100 * dt.asSeconds())))
                                move(sf::Vector2f(0, -100 * dt.asSeconds()));
                }

                if (InputManager::isActive(User_Input::LEFTHOLD))
                {
                        if (nextPosValid(sf::Vector2f(-100 * dt.asSeconds(), 0)))
                                move(sf::Vector2f(-100 * dt.asSeconds(), 0));
                }

                if (InputManager::isActive(User_Input::DOWNHOLD))
                {
                        if (nextPosValid(sf::Vector2f(0, 100 * dt.asSeconds())))
                                move(sf::Vector2f(0, 100 * dt.asSeconds()));
                }

                if (InputManager::isActive(User_Input::RIGHTHOLD))
                {
                        if (nextPosValid(sf::Vector2f(100 * dt.asSeconds(), 0)))
                                move(sf::Vector2f(100 * dt.asSeconds(), 0));
                }

                if (InputManager::isActive(User_Input::PPRESS))
                {
                        getAttribute<int>("health") -= 5;

                        std::cout << "Player health is now: " << getAttribute<int>("health") << std::endl;
                }

                if (InputManager::isActive(User_Input::VHOLD))
                {
                        if (SceneManager::getView().getSize().x < 300 ||
                                SceneManager::getView().getSize().y < 300)
                                SceneManager::getView().setSize(sf::Vector2f(SceneManager::getView().getSize().x + 0.5, SceneManager::getView().getSize().y + 0.5));
                }

                else if (InputManager::isActive(User_Input::IHOLD))
                {
                        if (SceneManager::getView().getSize().x >= 100 ||
                                SceneManager::getView().getSize().y >= 100)
                                SceneManager::getView().setSize(sf::Vector2f(SceneManager::getView().getSize().x - 0.5, SceneManager::getView().getSize().y - 0.5));
                }

                if (getAttribute<int>("health") <= 0)
                        setAttribute("renderable", new bool(false));

                setPosition(m_sprite.getPosition());
                setBounds(m_sprite.getGlobalBounds());
        }

        void Player::draw(sf::RenderTarget& target, sf::RenderStates states) const
        {
                target.draw(m_sprite, states);
        }

Tilemap.hpp

        class TileMap : public sf::Drawable, public sf::Transformable
        {
        public:
                struct Tile
                {
                        Tile(const sf::FloatRect& bounds, int tileType) : bounds(bounds), tileType(tileType) {};

                        sf::FloatRect bounds;
                        int tileType;
                };

                void load(const std::string& tileSet, sf::Vector2u tileSize, int* tiles,
                        unsigned int width, unsigned int height)
                {
                        m_tileset.loadFromFile(tileSet);

                        m_vertices.setPrimitiveType(sf::Quads);
                        m_vertices.resize(width * height * 4);

                        for (unsigned int i = 0; i < width; ++i)
                        {
                                for (unsigned int j = 0; j < height; ++j)
                                {
                                        int tileNumber = tiles[i + j * width];

                                        sf::Vector2f topLeft(i * tileSize.x, j * tileSize.y);
                                        sf::Vector2f topRight((i + 1) * tileSize.x, j * tileSize.y);
                                        sf::Vector2f downLeft((i + 1) * tileSize.x, (j + 1) * tileSize.y);
                                        sf::Vector2f downRight(i * tileSize.x, (j + 1) * tileSize.y);

                                        sf::FloatRect rect(topLeft.x, topLeft.y, topRight.x - topLeft.x, downLeft.y - topLeft.y);

                                        Tile tile(rect, tileNumber);

                                        m_tiles.push_back(tile);

                                        //Find the position in the tileset texture
                                        int tu = tileNumber % (m_tileset.getSize().x / tileSize.x);
                                        int tv = tileNumber / (m_tileset.getSize().x / tileSize.x);

                                        sf::Vertex* quad = &m_vertices[(i + j * width) * 4];

                                        //Define its 4 corners
                                        quad[0].position = sf::Vector2f(std::floor(topLeft.x), std::floor(topLeft.y));
                                        quad[1].position = sf::Vector2f(std::floor(topRight.x), std::floor(topRight.y));
                                        quad[2].position = sf::Vector2f(std::floor(downLeft.x), std::floor(downLeft.y));
                                        quad[3].position = sf::Vector2f(std::floor(downRight.x), std::floor(downRight.y));

                                        //Define its 4 texture coordinates
                                        quad[0].texCoords = sf::Vector2f(tu * tileSize.x, tv * tileSize.y);
                                        quad[1].texCoords = sf::Vector2f((tu + 1) * tileSize.x, tv * tileSize.y);
                                        quad[2].texCoords = sf::Vector2f((tu + 1) * tileSize.x, (tv + 1) * tileSize.y);
                                        quad[3].texCoords = sf::Vector2f(tu * tileSize.x, (tv + 1) * tileSize.y);
                                }
                        }
                }

                bool collidesWithType(int tileType, const sf::FloatRect& bounds)
                {
                        for (auto& iter : m_tiles)
                        {
                                if (iter.tileType == tileType)
                                {
                                        if (bounds.intersects(iter.bounds))
                                                return true;
                                }
                        }

                        return false;
                }

        private:
                virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
                {
                        states.transform *= getTransform();
                        states.texture = &m_tileset;
                        target.draw(m_vertices, states);
                }

                sf::VertexArray m_vertices;
                sf::Texture m_tileset;

                std::vector<Tile> m_tiles;
        };

As you can see, I tried using std::floor on my views and my tiles, but unfortunately nothing has been working so far.
Title: Re: Line artifacts when drawing tilemap
Post by: DevilEdge on August 09, 2014, 07:31:44 pm
Sorry for the bump, but I'm still having the issue. I've tried so many things, does no one really have any ideas what might be causing this?

Thanks
Title: Re: Line artifacts when drawing tilemap
Post by: Jesper Juhl on August 09, 2014, 08:30:02 pm
Have you tried the latest master from github? It has many bug fixes compared to 2.1 (which I'm assuming you are using).
Title: Re: Line artifacts when drawing tilemap
Post by: krzat on August 10, 2014, 01:39:26 pm
I fixed similiar problem by using 1 pixel margin around tiles in spritesheet. For some reason GPU was pulling pixels from outside of the texcoords.

I tried this, but it made the problem even more apparent with even larger black lines.

I forgot to add that this margin should have same colors as the tile. So if you need 40x40 tiles, you need to draw 42x42 tiles and use rectangle 1 pixels from the edges. If that won't work, you should just post working example of the problem.
Title: Re: Line artifacts when drawing tilemap
Post by: BaneTrapper on August 10, 2014, 06:00:52 pm
Ok, here's the entirety of all of my relevant code:

Player.hpp

class Player : public Entity
        {
        public:
                typedef std::shared_ptr<Player> Ptr;

                static Ptr create(const std::string& id = "player") { Ptr temp(new Player(id)); return temp; }

                void handleCollision();

                void move(const sf::Vector2f& offset);

                virtual void update(sf::Time dt);

                void draw(sf::RenderTarget& target, sf::RenderStates states) const;

        private:
                Player(const std::string& id = "player", bool active = true);

                sf::Texture m_texture;
                sf::Sprite m_sprite;

                sf::Vector2f m_viewArea;

                bool nextPosValid(const sf::Vector2f& offset);
                bool rectOverlapsTile(const sf::FloatRect& rect);
        };

Player.cpp

        Player::Player(const std::string& id, bool active) :
                m_viewArea(sf::Vector2f(100, 100))
        {
                m_texture.loadFromFile("Resources/player.png");
                m_sprite.setTexture(m_texture);
                m_sprite.setPosition(350, 300);

                registerAttribute("renderable", new bool(true));
                registerAttribute("health", new int(20));

                SceneManager::getView().setCenter(std::floor(350), std::floor(300));
                SceneManager::getView().setSize(m_viewArea);
        }

        bool Player::nextPosValid(const sf::Vector2f& offset)
        {
                sf::Vector2f offsettedPos(std::floor(m_sprite.getPosition().x + offset.x), std::floor(m_sprite.getPosition().y + offset.y));

                //The bounding rectangle of the future player
                sf::FloatRect rect(offsettedPos, sf::Vector2f(std::floor(m_sprite.getGlobalBounds().width), std::floor(m_sprite.getGlobalBounds().height)));

                if (SceneManager::getWorld().getCurrentCell()->getTileMap().collidesWithType(2, rect))
                        return false;

                return true;
        }

        void Player::move(const sf::Vector2f& offset)
        {
                m_sprite.move(offset);
                SceneManager::getView().move(offset);
        }

        void Player::update(sf::Time dt)
        {
                if (InputManager::isActive(User_Input::UPHOLD))
                {
                        if (nextPosValid(sf::Vector2f(0, -100 * dt.asSeconds())))
                                move(sf::Vector2f(0, -100 * dt.asSeconds()));
                }

                if (InputManager::isActive(User_Input::LEFTHOLD))
                {
                        if (nextPosValid(sf::Vector2f(-100 * dt.asSeconds(), 0)))
                                move(sf::Vector2f(-100 * dt.asSeconds(), 0));
                }

                if (InputManager::isActive(User_Input::DOWNHOLD))
                {
                        if (nextPosValid(sf::Vector2f(0, 100 * dt.asSeconds())))
                                move(sf::Vector2f(0, 100 * dt.asSeconds()));
                }

                if (InputManager::isActive(User_Input::RIGHTHOLD))
                {
                        if (nextPosValid(sf::Vector2f(100 * dt.asSeconds(), 0)))
                                move(sf::Vector2f(100 * dt.asSeconds(), 0));
                }

                if (InputManager::isActive(User_Input::PPRESS))
                {
                        getAttribute<int>("health") -= 5;

                        std::cout << "Player health is now: " << getAttribute<int>("health") << std::endl;
                }

                if (InputManager::isActive(User_Input::VHOLD))
                {
                        if (SceneManager::getView().getSize().x < 300 ||
                                SceneManager::getView().getSize().y < 300)
                                SceneManager::getView().setSize(sf::Vector2f(SceneManager::getView().getSize().x + 0.5, SceneManager::getView().getSize().y + 0.5));
                }

                else if (InputManager::isActive(User_Input::IHOLD))
                {
                        if (SceneManager::getView().getSize().x >= 100 ||
                                SceneManager::getView().getSize().y >= 100)
                                SceneManager::getView().setSize(sf::Vector2f(SceneManager::getView().getSize().x - 0.5, SceneManager::getView().getSize().y - 0.5));
                }

                if (getAttribute<int>("health") <= 0)
                        setAttribute("renderable", new bool(false));

                setPosition(m_sprite.getPosition());
                setBounds(m_sprite.getGlobalBounds());
        }

        void Player::draw(sf::RenderTarget& target, sf::RenderStates states) const
        {
                target.draw(m_sprite, states);
        }

Tilemap.hpp

        class TileMap : public sf::Drawable, public sf::Transformable
        {
        public:
                struct Tile
                {
                        Tile(const sf::FloatRect& bounds, int tileType) : bounds(bounds), tileType(tileType) {};

                        sf::FloatRect bounds;
                        int tileType;
                };

                void load(const std::string& tileSet, sf::Vector2u tileSize, int* tiles,
                        unsigned int width, unsigned int height)
                {
                        m_tileset.loadFromFile(tileSet);

                        m_vertices.setPrimitiveType(sf::Quads);
                        m_vertices.resize(width * height * 4);

                        for (unsigned int i = 0; i < width; ++i)
                        {
                                for (unsigned int j = 0; j < height; ++j)
                                {
                                        int tileNumber = tiles[i + j * width];

                                        sf::Vector2f topLeft(i * tileSize.x, j * tileSize.y);
                                        sf::Vector2f topRight((i + 1) * tileSize.x, j * tileSize.y);
                                        sf::Vector2f downLeft((i + 1) * tileSize.x, (j + 1) * tileSize.y);
                                        sf::Vector2f downRight(i * tileSize.x, (j + 1) * tileSize.y);

                                        sf::FloatRect rect(topLeft.x, topLeft.y, topRight.x - topLeft.x, downLeft.y - topLeft.y);

                                        Tile tile(rect, tileNumber);

                                        m_tiles.push_back(tile);

                                        //Find the position in the tileset texture
                                        int tu = tileNumber % (m_tileset.getSize().x / tileSize.x);
                                        int tv = tileNumber / (m_tileset.getSize().x / tileSize.x);

                                        sf::Vertex* quad = &m_vertices[(i + j * width) * 4];

                                        //Define its 4 corners
                                        quad[0].position = sf::Vector2f(std::floor(topLeft.x), std::floor(topLeft.y));
                                        quad[1].position = sf::Vector2f(std::floor(topRight.x), std::floor(topRight.y));
                                        quad[2].position = sf::Vector2f(std::floor(downLeft.x), std::floor(downLeft.y));
                                        quad[3].position = sf::Vector2f(std::floor(downRight.x), std::floor(downRight.y));

                                        //Define its 4 texture coordinates
                                        quad[0].texCoords = sf::Vector2f(tu * tileSize.x, tv * tileSize.y);
                                        quad[1].texCoords = sf::Vector2f((tu + 1) * tileSize.x, tv * tileSize.y);
                                        quad[2].texCoords = sf::Vector2f((tu + 1) * tileSize.x, (tv + 1) * tileSize.y);
                                        quad[3].texCoords = sf::Vector2f(tu * tileSize.x, (tv + 1) * tileSize.y);
                                }
                        }
                }

                bool collidesWithType(int tileType, const sf::FloatRect& bounds)
                {
                        for (auto& iter : m_tiles)
                        {
                                if (iter.tileType == tileType)
                                {
                                        if (bounds.intersects(iter.bounds))
                                                return true;
                                }
                        }

                        return false;
                }

        private:
                virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
                {
                        states.transform *= getTransform();
                        states.texture = &m_tileset;
                        target.draw(m_vertices, states);
                }

                sf::VertexArray m_vertices;
                sf::Texture m_tileset;

                std::vector<Tile> m_tiles;
        };

As you can see, I tried using std::floor on my views and my tiles, but unfortunately nothing has been working so far.

You bumped... i repeat "Post minimal example that reproduces the error." i don't have time to waste going trough random code.
Meaning, you create a main function and you add intro it ONLY the things you need help with, make it compile and post the code, we will fix it for you.
By doing this you will most likely fix the mistake yourself.

EDIT:: also please, if you want to fix the error, post your specs, os, also did you update gpu drivers?
Title: Re: Line artifacts when drawing tilemap
Post by: DevilEdge on August 17, 2014, 04:44:53 pm
class TileMap : public sf::Drawable, public sf::Transformable
{
public:

    bool load(const std::string& tileset, sf::Vector2u tileSize, const int* tiles, unsigned int width, unsigned int height)
    {
        // load the tileset texture
        if (!m_tileset.loadFromFile(tileset))
            return false;

        // resize the vertex array to fit the level size
        m_vertices.setPrimitiveType(sf::Quads);
        m_vertices.resize(width * height * 4);

        // populate the vertex array, with one quad per tile
        for (unsigned int i = 0; i < width; ++i)
            for (unsigned int j = 0; j < height; ++j)
            {
                // get the current tile number
                int tileNumber = tiles[i + j * width];

                // find its position in the tileset texture
                int tu = tileNumber % (m_tileset.getSize().x / tileSize.x);
                int tv = tileNumber / (m_tileset.getSize().x / tileSize.x);

                // get a pointer to the current tile's quad
                sf::Vertex* quad = &m_vertices[(i + j * width) * 4];

                // define its 4 corners
                quad[0].position = sf::Vector2f(i * tileSize.x, j * tileSize.y);
                quad[1].position = sf::Vector2f((i + 1) * tileSize.x, j * tileSize.y);
                quad[2].position = sf::Vector2f((i + 1) * tileSize.x, (j + 1) * tileSize.y);
                quad[3].position = sf::Vector2f(i * tileSize.x, (j + 1) * tileSize.y);

                // define its 4 texture coordinates
                quad[0].texCoords = sf::Vector2f(tu * tileSize.x, tv * tileSize.y);
                quad[1].texCoords = sf::Vector2f((tu + 1) * tileSize.x, tv * tileSize.y);
                quad[2].texCoords = sf::Vector2f((tu + 1) * tileSize.x, (tv + 1) * tileSize.y);
                quad[3].texCoords = sf::Vector2f(tu * tileSize.x, (tv + 1) * tileSize.y);
            }

        return true;
    }

private:

    virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
    {
        // apply the transform
        states.transform *= getTransform();

        // apply the tileset texture
        states.texture = &m_tileset;

        // draw the vertex array
        target.draw(m_vertices, states);
    }

    sf::VertexArray m_vertices;
    sf::Texture m_tileset;
};

int main()
{
    // create the window
    sf::RenderWindow window(sf::VideoMode(512, 256), "tilemap");

    // define the level with an array of tile indices
    const int level[] =
    {
        0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0,
        1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
        0, 1, 0, 0, 2, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0,
        0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 2, 0, 0,
        0, 0, 1, 0, 1, 0, 2, 2, 0, 0, 1, 1, 1, 1, 2, 0,
        2, 0, 1, 0, 1, 0, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1,
        0, 0, 1, 0, 1, 2, 2, 2, 0, 0, 0, 0, 1, 1, 1, 1,
    };

    // create the tilemap from the level definition
    TileMap map;
    if (!map.load("spritesheet.png", sf::Vector2u(32, 32), level, 16, 8))
        return -1;

    // run the main loop
    while (window.isOpen())
    {
        // handle events
        sf::Event event;
        while (window.pollEvent(event))
        {
            if(event.type == sf::Event::Closed)
                window.close();
        }

        // draw the map
        window.clear();
        window.draw(map);
        window.display();
    }

    return 0;
}

I wanted to attach the spritesheet that I'm using, but unfortunately it doesn't let me attach it to the post. For some reason it says that the upload folder is "full" and I need to contact an administrator, even though the file is only 136 bytes.

Thanks!
Title: Re: Line artifacts when drawing tilemap
Post by: eXpl0it3r on August 17, 2014, 05:43:15 pm
I wanted to attach the spritesheet that I'm using, but unfortunately it doesn't let me attach it to the post. For some reason it says that the upload folder is "full" and I need to contact an administrator, even though the file is only 136 bytes.
And did you contact an administrator? ;)

Luckily I read the message and it seemed that there has been a limit which got copied over from the old system. The limit has now been changed and you should be able again to attache things.
Title: Re: Line artifacts when drawing tilemap
Post by: DevilEdge on August 17, 2014, 05:58:50 pm
The limit has now been changed and you should be able again to attache things.

Thank you!

And for the people that were kind enough to try to help me, I've attached the spritesheet that I'm using in my engine.
Title: Re: Line artifacts when drawing tilemap
Post by: Hapax on August 18, 2014, 12:02:24 am
Which problems are you having when you run the complete example that you posted (you forgot the includes :P)?
(http://i.imgur.com/LNSmQls.jpg)
Title: Re: Line artifacts when drawing tilemap
Post by: DevilEdge on August 18, 2014, 05:33:00 pm
I finally (somewhat) resolved the issue. VS 13 keeps giving me the bug even with the simple example, but CodeBlocks 13.12 doesn't, so I'm sticking with codeblocks. Thanks to anyone who tried to help!
Title: Re: Line artifacts when drawing tilemap
Post by: Hapax on August 24, 2014, 07:18:24 pm
Just so you know, the screenshot that I posted above from your code was generated using VS2013.