This is very infamous bug/artifact, I kind of ran into it once, not sure if I fixed it or not or if it was appearing on certain machines only.
I tried that, and it works ok with a 2x2 tilesheet with 32x32 tiles(attached).
Changing bump in vert made line artifacts, but other two don't change a thing.
#include <SFML/Graphics.hpp>
sf::Vector2f vert(int x)
{
const sf::Vector2f bump(0.f,0.f);
switch(x)
{
case 1:return bump+sf::Vector2f();
case 2:return bump+sf::Vector2f(0.f,32.f);
case 3:return bump+sf::Vector2f(32.f,32.f);
case 4:return bump+sf::Vector2f(32.f,0.f);
}
}
sf::Vector2f texc(int x)
{
switch(x)
{
case 0:return sf::Vector2f();
case 1:return sf::Vector2f(32.f,0.f);
case 2:return sf::Vector2f(0.f,32.f);
case 3:return sf::Vector2f(32.f,32.f);
}
}
int main(int argc,char * argv[])
{
const sf::Vector2f bump(0.8f,0.3f);
const int mapx=5;
const int mapy=5;
const int map[mapx][mapy]=
{
{3,3,3,3,3},
{0,3,3,3,3},
{3,0,3,3,3},
{3,3,1,1,1},
{3,3,3,3,3},
};
sf::RenderWindow app(sf::VideoMode(640,480),"s");
app.setFramerateLimit(60);
sf::Texture tex;
tex.loadFromFile("img.png");
sf::VertexArray array;
array.setPrimitiveType(sf::Quads);
const float pos=64.f;
for(int x=0;x<mapx;++x) for(int y=0;y<mapy;++y)
{
const sf::Vector2f vec=texc(map[x][y]);
array.append(sf::Vertex(bump+sf::Vector2f(pos*x,pos*y),vert(1)+vec));
array.append(sf::Vertex(bump+sf::Vector2f(pos*x,pos*(y+1)),vert(2)+vec));
array.append(sf::Vertex(bump+sf::Vector2f(pos*(x+1),pos*(y+1)),vert(3)+vec));
array.append(sf::Vertex(bump+sf::Vector2f(pos*(x+1),pos*y),vert(4)+vec));
}
// tex.setSmooth(true);
while(true)
{
sf::Event eve;
while(app.pollEvent(eve));
const sf::Vector2f add(0.67325f,0.12354f);
sf::View v=app.getDefaultView();
v.setCenter(add+sf::Vector2f(sf::Mouse::getPosition(app)));
std::printf("%3.2f %3.2f\n",v.getCenter().x,v.getCenter().y);
app.setView(v);
app.clear();
app.draw(array,&tex);
app.display();
}
return 0;
}
sf::Vector2f vert(int x)
{
const sf::Vector2f bump(0.f,0.f);
this bump value must be 0 0 or line artifacts happen, the one that gets added to position:
const sf::Vector2f bump(0.8f,0.3f);
and view center:
const sf::Vector2f add(0.67325f,0.12354f);
can be set to weird values(as shown) and everything looks ok.
(Also, excellent job on the test case. Much better than mine would have been.)
Ok, but if that renders without any artifacts on your card then you must have done something wrong in your code or texture.
There are no jagged pixels appearing for me, everything is rendered 1:1 , unless by that you mean the pixels are not smoothed out and you want to use set smooth while having no artifacts.
Use this vert function and uncomment setSmooth true and see if these are the results you seek.
sf::Vector2f vert(int x)
{
const sf::Vector2f bump(0.f,0.f);
switch(x)
{
case 1:return bump+sf::Vector2f(0.5f,0.5f);
case 2:return bump+sf::Vector2f(0.5f,31.5f);
case 3:return bump+sf::Vector2f(31.5f,31.5f);
case 4:return bump+sf::Vector2f(31.5f,0.5f);
}
}
Since this is related to the same issue I thought I would post it here. I originally thought I had solved my problem because the diagonals were smoothed just fine. However, we recently added in a grass texture, and with smoothing on, I get a white border on the outside of the grass, as well as an obvious line between the tiles, which should fit perfectly.
(http://i.imgur.com/1NRx0w9.png)
If I remove the half-pixel addition to each size of a tile that was recommended earlier in this thread, the line between the tiles is now gone, but all of the grass now has a white border (and the tiny lines of pixels that jut out from the OP return).
(http://i.imgur.com/BH9rgJf.png)
To avoid the jutting pixels and the white grass tips, I turn smoothing off. Both of these issues are gone, but my original problem now remains. The diagonals are once again adding extra pixels, creating a jagged look. Another but also came up, which adds/removes single lines of pixels when i move around. I have highlighted both issues in the image. The vertical line of pixels is tough to see, but its a brown line that has been added to the bottom image. This can be avoided if I implement the solution from earlier, except instead of .5 extra pixels around each tile, I add an entire pixel. This of course adds the line between the grass and the floor again, and causes a bunch of other issues.
(http://i.imgur.com/un7F0O1.png)
In case it comes up, I am rounding my view coordinates to an integer, so that is not the issue. The resolution I am using on my view is 1920, 1080. When I zoom in far enough on the issues in the last image, they both go away. Note sure if that helps. My current code for drawing my tiles is:
for( int tx = leftTile; tx < rightTile; ++tx )
{
for( int ty = topTile; ty < bottomTile; ++ty )
{
if( staticTileSets[tx][ty] != NULL )
{
int tc = ((tx - leftTile) + (ty - topTile) * viewHalfWidthTiles * 2) * 4;
VertexArray &map = *(texVertexMap[staticTileSets[tx][ty]->texture]);
// define the position of the 4 points of the current tile
map[tc + 0].position = sf::Vector2f((tx + 0) * tileSize, (ty + 0) * tileSize);
map[tc + 1].position = sf::Vector2f((tx + 0) * tileSize, (ty + 1) * tileSize);
map[tc + 2].position = sf::Vector2f((tx + 1) * tileSize, (ty + 1) * tileSize);
map[tc + 3].position = sf::Vector2f((tx + 1) * tileSize, (ty + 0) * tileSize);
// define the texture coordinates of the 4 points of the current tile
float blend = .5f;
int ix = staticTileSets[tx][ty]->GetSubRect( staticLocalID[tx][ty] ).left / tileSize; // X index of the tile in the tileset
int iy = staticTileSets[tx][ty]->GetSubRect( staticLocalID[tx][ty] ).top / tileSize; // Y index of the tile in the tileset ;
map[tc+ 0].texCoords = sf::Vector2f((ix + 0) * tileSize + blend, (iy + 0) * tileSize + blend);
map[tc+ 1].texCoords = sf::Vector2f((ix + 0) * tileSize + blend, (iy + 1) * tileSize - blend);
map[tc+ 2].texCoords = sf::Vector2f((ix + 1) * tileSize - blend, (iy + 1) * tileSize - blend);
map[tc+ 3].texCoords = sf::Vector2f((ix + 1) * tileSize - blend, (iy + 0) * tileSize + blend);
}
else
{
}
}
}
for( std::map<sf::Texture*, sf::VertexArray*>::iterator mapIt = texVertexMap.begin();
mapIt != texVertexMap.end(); ++mapIt )
{
window->draw( *(*mapIt).second, (*mapIt).first );
}