Texture Coordinates not working correctly in OpenGL ES 2.0

122 views Asked by At

I am trying to apply part of a big image to a rectangle in OpenGL ES 2.0

I have this big texture sheet or sprite sheet. Each image is 32x32. The Full Image is 192x32. enter image description here

Loading the Texture

glGenTextures(1, &texture->textureId);
bindTexture(texture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

stbi_set_flip_vertically_on_load(true);

unsigned char* textureData = stbi_load(texturePath, &texture->width, &texture->height, &texture->channels, 0);
if(textureData)
{
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->width, texture->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
}
else
{
    log_error("Couldn't load texture: %s", texturePath);
}

stbi_image_free(textureData);

So, To get the first sprite from this sprite sheet, I use ((1*32)/192) and get these texture coordinates enter image description here

static Vertex vertices[4] =
{
//  Position               Color                          Tex Coords
    {{{1.0f, 1.0f, 0.0f}}, {{1.0f, 1.0f, 0.0f, 1.0f}}, {{0.16f, 1.0f}}},
    {{{1.0f, -1.0f, 0.0f}}, {{1.0f, 1.0f, 0.0f, 1.0f}}, {{0.16, 0.0f}}},
    {{{-1.0f, -1.0f, 0.0f}}, {{1.0f, 1.0f, 0.0f, 1.0f}}, {{0.0f, 0.0f}}},
    {{{-1.0f, 1.0f, 0.0f}}, {{1.0f, 1.0f, 0.0f, 1.0f}}, {{0.0f, 1.0f}}},
};

Fragment Shader

#version 100

precision mediump float;

varying vec4 fColor;
varying vec2 fTexCoord;

uniform sampler2D textureSampler;

void main()
{
    gl_FragColor = texture2D(textureSampler, fTexCoord);
}

But I don't get the expected output. Instead it applies the full sprite sheet onto the rectangle enter image description here

Why is this happening? How do I fix this?

1

There are 1 answers

6
Joel On

The texture coordinates of your vertices seem to be off. Since each sprite is 32 pixels in height and the whole image is 32 pixels in height too, you would use 1.0 for the height. I guess your x component of the texture coordinates seem to be right tho.

I had a similar approach on a little game and the vertices look like this:

    float width = 1.0f / (float)m_spriteCount;
    float widthMin = m_spritePos * width;
    float widthMax = (m_spritePos + 1) * width;

    m_vertices = {
        //                x,                   y,          z,       w,    h
        size.x + position.x, size.y + position.y, position.z, widthMax, 1.0f,       // top right
        size.x + position.x,          position.y, position.z, widthMax, 0.0f,       // bottom right
                 position.x,          position.y, position.z, widthMin, 0.0f,       // bottom left
                 position.x, size.y + position.y, position.z, widthMin, 1.0f        // top left
    };

m_spriteCount is the count of images I have in my texture (in your case 6) and m_spritePos is the current texture position I am rendering (from 0 - 5).

I dont use any data for a color since the texture already contains the color (obviously) and I dont want to mix some colors but only render the textures colores.