[Help] Extracting Tiles from a NPOT Sprite Sheet

Basically I have created a sprite sheet/tileset with dimentions of 320 x 2048, the tiles are each 32 x 32. I’ve been able to load individual files with textures in them but I don’t seem to be able to load textures from a sprite sheet. Any help ?

Of course this is perfectly doable, and even in 2 very different ways.
Either load the whole as a NPOT texture, and when rendering each tile, use very specific texture coordinates to select onle the 32x32 desired part.
Or load the image in RAM, and inside your program create a different GL texture for each tile (maybe simpler to do, but less performance due to many switches of active texture).

Please be more specific about the help you need.

I thought had done the first option “use very specific texture coordinates”, but all my tiles are just plain white.

This is my tiling function


float VertexX[4], VertexY[4];
int TexcoordX, TexcoordY;
for (int y = 0; y < WorldSizey; ++y)
{
    for (int x = 0; x < WorldSizex; ++x)
    {
        CalculateTextureSheetCoords(TileData[0][y][x],
            TilesetX,32,TexcoordX,TexcoordY);

        CalculateTextureVertexCoords(TilesetX,TilesetY,TexcoordX,
            TexcoordY,32,VertexX[0],VertexY[0],VERTEX_LOWER_LEFT);
        CalculateTextureVertexCoords(TilesetX,TilesetY,TexcoordX,
            TexcoordY,32,VertexX[1],VertexY[1],VERTEX_UPPER_LEFT);
        CalculateTextureVertexCoords(TilesetX,TilesetY,TexcoordX,
            TexcoordY,32,VertexX[2],VertexY[2],VERTEX_UPPER_RIGHT);
        CalculateTextureVertexCoords(TilesetX,TilesetY,TexcoordX,
            TexcoordY,32,VertexX[3],VertexY[3],VERTEX_LOWER_RIGHT);

        glEnable(GL_TEXTURE_2D);
        glColor4fv(TextureColour);
        glBindTexture(GL_TEXTURE_2D,TILESET);
        glBegin(GL_QUADS);
        glTexCoord2f(VertexX[0],VertexY[0]);
        glVertex2f(x/8,(WorldSizey-(y+1))/8); //Lower left
        glTexCoord2f(VertexX[1],VertexY[1]);
        glVertex2f(x/8,(WorldSizey-y)/8); //Upper left
        glTexCoord2f(VertexX[2],VertexY[2]);
        glVertex2f((x+1)/8,(WorldSizey-y)/8); //Upper Right
        glTexCoord2f(VertexX[3],VertexY[3]);
        glVertex2f((x+1)/8,(WorldSizey-(y+1))/8); //Lower Right
        glEnd();
        glDisable(GL_TEXTURE_2D);
    }
}

And Here’s my functions which calculate the coordinates that should work to find the textures but all I’m getting is blank white squares.

enum VertexMode {VERTEX_LOWER_LEFT, VERTEX_UPPER_LEFT, VERTEX_UPPER_RIGHT, VERTEX_LOWER_RIGHT};
void CalculateTextureVertexCoords(float in_ImageSizeX, float in_ImageSizeY,
                                  float in_TextureCoordX, float in_TextureCoordY,
                                  float in_TextureSize,
                                  float &out_VertexCoordX, float &out_VertexCoordY,
                                  int in_VertexMode)
{
    switch (in_VertexMode)
    {
    case VERTEX_LOWER_LEFT:
        out_VertexCoordX = (in_TextureSize * in_TextureCoordX)/in_ImageSizeX;
        out_VertexCoordY = ( 1 - ((in_TextureSize * (in_TextureCoordY + 1))/in_ImageSizeY));
        break;
    case VERTEX_UPPER_LEFT:
        out_VertexCoordX = (in_TextureSize * in_TextureCoordX)/in_ImageSizeX;
        out_VertexCoordY = ( 1 - ((in_TextureSize * in_TextureCoordY)/in_ImageSizeY));
        break;
    case VERTEX_UPPER_RIGHT:
        out_VertexCoordX = ((in_TextureSize * (in_TextureCoordX + 1))/in_ImageSizeX);
        out_VertexCoordY = ( 1 - ((in_TextureSize * in_TextureCoordY)/in_ImageSizeY));
        break;
    case VERTEX_LOWER_RIGHT:
        out_VertexCoordX = (in_TextureSize * (in_TextureCoordX + 1))/in_ImageSizeX;
        out_VertexCoordY = ( 1 - ((in_TextureSize * (in_TextureCoordY + 1))/in_ImageSizeY));
        break;
    }
}

void CalculateTextureVertexCoordsABS(int in_ImageSizeX, int in_ImageSizeY,
                                     int in_TextureCoordX, int in_TextureCoordY,
                                     int in_TextureSize,
                                     int &out_VertexCoordX, int &out_VertexCoordY,
                                     int in_VertexMode)
{
    switch (in_VertexMode)
    {
    case VERTEX_LOWER_LEFT:
        out_VertexCoordX = (in_ImageSizeX - (in_ImageSizeX - in_TextureSize * in_TextureCoordX));
        out_VertexCoordY = (in_ImageSizeY - in_TextureSize * (in_TextureCoordY + 1));
        break;
    case VERTEX_UPPER_LEFT:
        out_VertexCoordX = (in_ImageSizeX - (in_ImageSizeX - in_TextureSize * in_TextureCoordX));
        out_VertexCoordY = (in_ImageSizeY - in_TextureSize * in_TextureCoordY);
        break;
    case VERTEX_UPPER_RIGHT:
        out_VertexCoordX = (in_ImageSizeX - (in_ImageSizeX - in_TextureSize * (in_TextureCoordX + 1)));
        out_VertexCoordY = (in_ImageSizeY - in_TextureSize * in_TextureCoordY);
        break;
    case VERTEX_LOWER_RIGHT:
        out_VertexCoordX = (in_ImageSizeX - (in_ImageSizeX - in_TextureSize * (in_TextureCoordX + 1)));
        out_VertexCoordY = (in_ImageSizeY - in_TextureSize * (in_TextureCoordY + 1));
        break;
    }
}

void CalculateTextureSheetCoords(int in_TextureNumber, int in_ImageSizeX,
                                 int in_TextureSize, int &out_TextureCoordX,
                                 int &out_TextureCoordY)
{
    if (in_TextureNumber != 0)
    {
        int TexturesPerRow = in_ImageSizeX/in_TextureSize;
        out_TextureCoordY = floor(((double)in_TextureNumber - 1) / (double)TexturesPerRow);
        out_TextureCoordX = (((in_TextureNumber - 1) - TexturesPerRow * out_TextureCoordY)  % TexturesPerRow);

    }
}

All white texture can mean that there is a texture error somewhere. Do you check for GL_ERRORs ?

What is your texture filtering set to ? Do you generate mipmaps ? Texture - OpenGL Wiki

Are your texcoords calculations correct ? Try a simpler case, 4 textures in one 128x128 texture, with texcoords like 0 to 0.5 and 0.5 to 1.