kelechi96 0 Light Poster

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 ?

Here is the code I'm struggling with:

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);

    }
}

Dani AI

Generated

Most likely causes for blank white quads when sampling an NPOT sprite sheet are: the texture upload failed or was misinterpre (alignment/stride), texture coordinates fall outside the normalized [0,1] range or are inverted vertically, or driver/parameter issues with non‑power‑of‑two textures. Given 's description, start by treating these as a checklist rather than changing the math immediately.

First checks (quick diagnostics)

  • Confirm the GL texture object is valid and the upload reported no errors (check the returned texture ID and call glGetError after the upload). Render the whole sheet to a single quad to verify the on‑GPU image content before slicing it into tiles.
  • Ensure row alignment is correct: OpenGL defaults to a 4‑byte GL_UNPACK_ALIGNMENT, which corrupts uploads when row stride is not a multiple of 4. Use glPixelStorei(GL_UNPACK_ALIGNMENT, 1) if the image rows are tightly packed. See the glPixelStorei reference for details: glPixelStorei reference.

NPOT-specific pitfalls

  • Older GL drivers require explicit NPOT support for repeating and mipmaps. If NPOT support is absent, using repeat or mipmapped min filters can yield missing or white results. Set wrap modes to GL_CLAMP_TO_EDGE and use non‑mipmapped min filters, or confirm NPOT support on the target hardware. Background reading: .

Texcoord logic and practical tests

  • Verify your tile indexing convention (0‑based vs 1‑based) and compute column/row consistently. Normalize pixel extents to [0,1] for u/v, and remember many image loaders use top‑left origin while OpenGL expects bottom‑left — flip the V coordinate if needed.
  • Debug by hard‑coding normalized coords for one known tile, then print out computed u0,u1,v0,v1 values to compare with expectations. Reduce GL state noise: bind the texture once, avoid enabling/disabling per tile, and try a simple power‑of‑two test texture to isolate NPOT behavior.

If those checks are clean, inspect texture parameters (wrap/filter/min/mag) and use a frame capture tool (RenderDoc) to examine the uploaded texture and sampled coordinates.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.