I am having a strange issue with my sprites, which is kind of difficult to describe, but hopefully the attached images will illustrate. I have drawn two 1 pixel lines on my sprite to help with this, one at the far edge, and one a few pixels in. When drawn at its native scale everything looks how you would expect it to.
However, if I try to scale up or zoom into my sprite, things start to get weird. Zooming in by 2 times, you can see the inner line is now 2 pixels wide, but the far one remains 1 pixel.
If I zoom in by 4 times, the inner is now 4 pixels, but the far is only 2.
So what is going on here, and how can I resolve it? This is giving my sprites a much different look than I want when I try to zoom in, resize the window, or broadly try to upscale them at all. My texture parameters are as follows:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
My camera matrix:
orthographicMatrix = glm::ortho(0.0f , float(screenWidth),
float(screenHeight) , 0.0f , -1.0f, 1.0f);
...
glm::vec3 translate(floor(-position.x) + halfWidth, floor(-position.y) + halfHeight, 0.0f);
glm::vec3 scale(cameraScale, cameraScale, 0.0f);
cameraMatrix = glm::translate(orthographicMatrix, translate);
cameraMatrix = glm::scale(glm::mat4(1.0f), scale) * cameraMatrix;
My fragment shader:
#version 330 core
in vec2 TextureCoordinates;
out vec4 color;
uniform sampler2D image;
uniform vec4 spriteColor;
void main()
{
color = vec4(spriteColor) * texture(image, TextureCoordinates);
}
I'm not exactly sure if the attached code is relevant to the issue, but they are the areas I've been looking.
Running some additional tests, the issue appears to be in how I am calculating my UV coordinates, so here is my code for that.
std::vector<glm::vec4> Texture2D::GetUVs(int w, int h)
{
std::vector<glm::vec4> uvs;
int rows = Width/ w;
int columns = Height / h;
for(int c = 0; c < columns; c ++)
{
for(int i = 0; i < rows; i ++)
{
float offset = 0.5;
uvs.emplace_back(glm::vec4(float(((i) * w + offset))/Width,
float(((1 + i) * w - offset))/Width,
float(((c) * h + offset))/Height,
float(((1 + c) * h - offset))/Height));
}
}
return uvs;
}
The offset value is to prevent pixel bleeding, though now I'm thinking it might be causing issues. Setting it to 0 resolves the issue, but then I obviously have pixel bleeding again. So I guess I'm doing that part wrong.