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
[source lang="cpp"]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); }}[/source]
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.
[source lang="cpp"]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); }}[/source]
How do I Extract Tiles from a NPOT Sprite Sheet
Started by kelechi96, Aug 07 2012 08:21 AM
3 replies to this topic
Sponsor:
#2 Members - Reputation: 142
Posted 07 August 2012 - 02:06 PM
Your code looks extremely complicated for something so simple. Are you making a 2D game? Why are you using world coordinates instead of orthographic projection?
In addition to ortho, texture states, etc. you should also read up a little on classes and object oriented programming. For example, you might:
Here's a very simple example, similar to what I use:
In addition to ortho, texture states, etc. you should also read up a little on classes and object oriented programming. For example, you might:
- Define a "Texture" class which wraps OpenGL textures (bind, wrap modes, filtering, etc) and pads for NPOT
- Define a "TextureRegion" class utility which determines normalized texture coordinates from un-normalized pixel coordinates
- Define a "TextureAtlas" (or "SpriteSheet") class which splits a TextureRegion into an array of many TextureRegion objects
Here's a very simple example, similar to what I use:
public class TextureRegion {
protected float normalizedWidth, normalizedHeight;
protected float width, height;
protected float centerX, centerY;
protected float textureOffsetX, textureOffsetY;
protected Texture texture;
public TextureRegion(Texture texture) {
this.texture = texture;
//e.g. a 240x240 PNG image would be loaded as a 256x256 texture
this.normalizedWidth = texture.getImageWidth() / (float) texture.getTextureWidth();
this.normalizedHeight = texture.getImageHeight() / (float) texture.getTextureHeight();
this.width = texture.getImageWidth();
this.height = texture.getImageHeight();
this.centerX = width / 2f;
this.centerY = height / 2f;
}
public TextureRegion copy() {
TextureRegion img = new TextureRegion(texture);
return img;
}
public TextureRegion getSubImage(float x, float y, float width, float height) {
float tx = ( x / this.width * normalizedWidth ) + textureOffsetX;
float ty = ( y / this.height * normalizedHeight ) + textureOffsetY;
float tw = width / this.width * normalizedWidth;
float th = height / this.height * normalizedHeight;
TextureRegion img = copy();
img.textureOffsetX = tx;
img.textureOffsetY = ty;
img.width = width;
img.height = height;
img.normalizedWidth = tw;
img.normalizedHeight = th;
img.centerX = width / 2f;
img.centerY = height / 2f;
return img;
}
// ideally you should use a modern solution like VBOs and place rendering elsewhere...
public void begin() {
GL11.glEnable(GL11.GL_TEXTURE_2D);
texture.bind();
GL11.glBegin(GL11.GL_QUADS);
}
public void end() {
GL11.glEnd();
GL11.glDisable(GL11.GL_TEXTURE_2D);
}
public void draw(float x, float y) {
GL11.glTexCoord2f(textureOffsetX, textureOffsetY; //TOP LEFT
GL11.glVertex2f(x, y);
GL11.glTexCoord2f(textureOffsetX, textureOffsetY+normalizedHeight); //BOTTOM LEFT
GL11.glVertex2f(x, y+height);
GL11.glTexCoord2f(textureOffsetX+normalizedWidth, textureOffsetY+normalizedHeight); //BOTTOM RIGHT
GL11.glVertex2f(x+width, y+height);
GL11.glTexCoord2f(textureOffsetX+normalizedWidth, textureOffsetY); //TOP RIGHT
GL11.glVertex2f(x+width, y);
}
}
Edited by mattdesl, 07 August 2012 - 02:07 PM.
#3 Members - Reputation: 106
Posted 07 August 2012 - 03:51 PM
Yeah I'm making a 2D game, I don't know how to use orthographic projection.
I generally don't use classes because other than private variables they really don't carry many advantages over just using functions.
Could you explain what your code does from the perspective of "draw" ?
I generally don't use classes because other than private variables they really don't carry many advantages over just using functions.
Could you explain what your code does from the perspective of "draw" ?
#4 Members - Reputation: 1030
Posted 09 August 2012 - 04:58 AM
Yeah I'm making a 2D game, I don't know how to use orthographic projection.
I generally don't use classes because other than private variables they really don't carry many advantages over just using functions.
Could you explain what your code does from the perspective of "draw" ?
Orthographic projection basically makes it so objects don't get smaller as they move further down the z axis, which is what they would do in a perspective projection. It's a useful projection when you want to render 2D.
When rendering a sprite sheet, you need to map the texture coordinates on a 0 - 1 scale.
Say you have a sprite sheet that's 128x128 and you have a sprite at the top left that's 64x64. To render it on a quad, you map it from 0 to 0.5 on the x and y axis (64 is 0.5 of 128).
And you will soon learn the value of OOP. Having code in loosely packed modules is vital when you have thousands upon thousands of lines of code to manage.
Learn to make games with my SDL Tutorials.
Transition from OpenGL 2 to modern OpenGL using my OpenGL Tutorial.
Transition from OpenGL 2 to modern OpenGL using my OpenGL Tutorial.






