Page 1 of 1

[SOLVED] OpenGL Sprite sheet clipping problem

Posted: Fri Aug 09, 2013 8:54 am
by 0x0000000
Hi everyone, its been a while since I have posted here, mostly because of school.
But I have ran into another problem in my game engine development.

This is the problem:

When I load a *small* sprite sheet in OpenGL, for example 64x64 with 4 tiles each 32x32, the sprite clipping works fine,
but when I try to load a large sprite sheet, for example 512x512, it doesn't clip the sprite properly.

This is my code:

Code: Select all

void spritesheet::render() {
	const float tw = float(size.getX()) / float(getTexture().w());
	const float th = float(size.getY()) / float(getTexture().h());
	numPerRow = getTexture().w() / size.getX();
	const float tx = (m_frameIndex % numPerRow) * tw;
	const float ty = (m_frameIndex / numPerRow + 1) * th;

	texture.setCurrent();
	glBegin(GL_QUADS);
        glTexCoord2f(tx, ty + th);		glVertex3f((float)pos.getX(), (float)pos.getY(), 0);
        glTexCoord2f(tx + tw, ty + th);	glVertex3f((float)pos.getX() + (float)size.getX(), (float)pos.getY(), 0);
        glTexCoord2f(tx + tw, ty);		glVertex3f((float)pos.getX() + (float)size.getX(), (float)pos.getY() + (float)size.getY(), 0);
        glTexCoord2f(tx, ty);			glVertex3f((float)pos.getX(), (float)pos.getY() + (float)size.getY(), 0);
	glEnd();
}
If someone could at least tell me what is wrong I would be greatful, because I still can't figure it out. :oops:

[EDIT] Hi guys I've figured it out:

Code: Select all

void spritesheet::render() {

    tile t;
    t.numX = 4;
    t.numY = 0;
    t.w = 32.f / 512.f;
    t.h = 32.f / 512.f;

    GLfloat y = (16 - t.numY) * t.h;
    GLfloat x = (t.w * t.numX);

	texture.setCurrent();
	glBegin(GL_QUADS);
        glTexCoord2f(x, y);             glVertex3f((float)pos.getX(), (float)pos.getY(), 0);
        glTexCoord2f(x + t.w, y);       glVertex3f((float)pos.getX() + (float)size.getX(), (float)pos.getY(), 0);
        glTexCoord2f(x + t.w, y - t.h);	glVertex3f((float)pos.getX() + (float)size.getX(), (float)pos.getY() + (float)size.getY(), 0);
        glTexCoord2f(x, y - t.h);       glVertex3f((float)pos.getX(), (float)pos.getY() + (float)size.getY(), 0);
	glEnd();
}

Code: Select all

struct tile {
    GLfloat numX;
    GLfloat numY;
    GLfloat w;
    GLfloat h;
};
Thanks for trying to help me dandymcgee :)

Re: OpenGL Sprite sheet clipping problem

Posted: Fri Aug 09, 2013 5:44 pm
by dandymcgee
Are you sure it's exactly 512x512, or some other powers of 2?

Re: OpenGL Sprite sheet clipping problem

Posted: Fri Aug 09, 2013 6:25 pm
by 0x0000000
dandymcgee wrote:Are you sure it's exactly 512x512, or some other powers of 2?
Yes, I'm sure. I've checked everything but I still cant figure it out. I've just begun learning OpenGL the past few days so I probably
just screwed up something in my code. Anyways, thanks for the reply! :)

Re: OpenGL Sprite sheet clipping problem

Posted: Fri Aug 09, 2013 6:51 pm
by 0x0000000
I'm not sure if this is the problem but, if I set m_frameIndex to zero, which I always have been, then it would be 0 % numPerRow.
I am going to change the frame index to see if it helps.

Re: [SOLVED] OpenGL Sprite sheet clipping problem

Posted: Sun Aug 11, 2013 9:06 am
by dandymcgee
0x0000000 wrote:I'm not sure if this is the problem but, if I set m_frameIndex to zero, which I always have been, then it would be 0 % numPerRow.
I am going to change the frame index to see if it helps.
So was this the problem?

Re: [SOLVED] OpenGL Sprite sheet clipping problem

Posted: Sun Aug 11, 2013 10:06 am
by 0x0000000
dandymcgee wrote:
0x0000000 wrote:I'm not sure if this is the problem but, if I set m_frameIndex to zero, which I always have been, then it would be 0 % numPerRow.
I am going to change the frame index to see if it helps.
So was this the problem?
I can't be 100% sure that this was the problem, due to the fact that I didn't have the balls to make my own code for the function, the entire texture size/clipping thing was just something I found off StackExchange :oops: , the reason I posted it here was because I couldn't figure out why it was working on small sheets and not large ones.
Please don't ban me

Re: [SOLVED] OpenGL Sprite sheet clipping problem

Posted: Sun Aug 11, 2013 6:24 pm
by dandymcgee
Hey.. copy/pasta is how I learned. LazyFoo, 'nuff said. No hate. ;)

Re: [SOLVED] OpenGL Sprite sheet clipping problem

Posted: Mon Aug 12, 2013 3:02 am
by K-Bal
It could help to write unit tests. That way you can be sure that your numbers are right.

Re: [SOLVED-ish] OpenGL Sprite sheet clipping problem

Posted: Thu Aug 22, 2013 1:51 pm
by 0x0000000
Hello again guys, I'm sorry if I shouldn't revive this topic but I didn't
think it would be necessary to open another one for problems related to this.

In the solution I posted above, I made it so that if you wanted to select a tile,
you would have to give it a numX and numY, instead of just tileNum.

I've noticed that in the Elysian Shadows engine that the tiles are handled with just the
tile index, and I would like to understand how to do this.

Any help would be greatly appreciated :)

Re: [SOLVED] OpenGL Sprite sheet clipping problem

Posted: Thu Aug 22, 2013 5:26 pm
by dandymcgee
I usually do this:
Tile *tile = tileArray[(y * tilesPerRow) + x];

Re: [SOLVED] OpenGL Sprite sheet clipping problem

Posted: Fri Aug 23, 2013 12:49 am
by 0x0000000
dandymcgee wrote:I usually do this:
Tile *tile = tileArray[(y * tilesPerRow) + x];
I don't have a tile array but I figured it out;

Code: Select all

/*
	Draws a textured quad that
	is clipped like a spritesheet
 */
void khDrawClippedTexturedQuad(GLuint texture, float x, float y, float w, float h, float a, int cw, int ch, int tw, int th, int num) {
	GLfloat nx = (float)(num % (tw / cw));
	GLfloat ny = (float)(num / (th / ch));

	GLfloat tcw = (float)cw / (float)tw;
	GLfloat tch = (float)ch / (float)th;

	GLfloat tx = (tcw * nx);
	GLfloat ty = (th / ch - ny) * tch;
	
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glLoadIdentity();
	glPushMatrix();
	glTranslatef(x + w/2, y + h/2, 0);
	glRotatef(a, 0, 0, 1);
	if(!glIsTexture(texture)) {
		glBindTexture(GL_TEXTURE_2D, texture);
	}
	glBegin(GL_QUADS);
		glColor3f(1.0, 1.0, 1.0);
		glTexCoord2d(tx, ty);
		glVertex3f(-(w/2), -(h/2), 0);
		glTexCoord2d(tx + tcw, ty);
		glVertex3f(w/2, -(h/2), 0);
		glTexCoord2d(tx + tcw, ty - tch);
		glVertex3f(w/2, h/2, 0);
		glTexCoord2d(tx, ty - tch);
		glVertex3f(-(w/2), h/2, 0);
	glEnd();
	glPopMatrix();
}
Thanks for the help dandymcgee! :)

Re: [SOLVED] OpenGL Sprite sheet clipping problem

Posted: Fri Aug 23, 2013 7:51 am
by dandymcgee
0x0000000 wrote:
dandymcgee wrote:I usually do this:
Tile *tile = tileArray[(y * tilesPerRow) + x];
I don't have a tile array but I figured it out;

Code: Select all

/*
	Draws a textured quad that
	is clipped like a spritesheet
 */
void khDrawClippedTexturedQuad(GLuint texture, float x, float y, float w, float h, float a, int cw, int ch, int tw, int th, int num) {
	GLfloat nx = (float)(num % (tw / cw));
	GLfloat ny = (float)(num / (th / ch));

	GLfloat tcw = (float)cw / (float)tw;
	GLfloat tch = (float)ch / (float)th;

	GLfloat tx = (tcw * nx);
	GLfloat ty = (th / ch - ny) * tch;
	
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glLoadIdentity();
	glPushMatrix();
	glTranslatef(x + w/2, y + h/2, 0);
	glRotatef(a, 0, 0, 1);
	if(!glIsTexture(texture)) {
		glBindTexture(GL_TEXTURE_2D, texture);
	}
	glBegin(GL_QUADS);
		glColor3f(1.0, 1.0, 1.0);
		glTexCoord2d(tx, ty);
		glVertex3f(-(w/2), -(h/2), 0);
		glTexCoord2d(tx + tcw, ty);
		glVertex3f(w/2, -(h/2), 0);
		glTexCoord2d(tx + tcw, ty - tch);
		glVertex3f(w/2, h/2, 0);
		glTexCoord2d(tx, ty - tch);
		glVertex3f(-(w/2), h/2, 0);
	glEnd();
	glPopMatrix();
}
Ah, right. Same concept applies to clipping a sheet as you've already discovered. Thanks for posting the code instead of just saying, "Nevermind, I fixed it."
0x0000000 wrote:Thanks for the help dandymcgee! :)
You're welcome. It's what we're here for.

Re: [SOLVED] OpenGL Sprite sheet clipping problem

Posted: Sat Aug 24, 2013 7:14 am
by bbguimaraes
dandymcgee wrote:Thanks for posting the code instead of just saying, "Nevermind, I fixed it."
http://xkcd.com/979/