PDA

View Full Version : Tiling part of a texture.

rnodal
06-05-2008, 11:56 AM
Hello all:

I'm trying to improve the rendering speed of my game engine by taking advantage of opengl ability to repeat a texture if the texture coordinate goes beyond 1.0. The problem than I'm having is that the image that I want to tile is part of a bigger texture. I have manage to get close to archive what I want but I still don't get the effect right all the times. I will post my code as soon as I get home. The idea is to avoid rendering multiple quads to give the impression that the image is tiled. If I'm not clear just let me know and I will explain my self better. Thanks a lot.

-R

rnodal
06-05-2008, 12:55 PM
Here is how I'm calculating everything.

Initial texture coordinates.

x1 = (GLfloat)x / (GLfloat)this->textureIterator->width;
y1 = 1.0f - (GLfloat)y / (GLfloat)this->textureIterator->height;

x2 = ((GLfloat)(x + width) / (GLfloat)this->textureIterator->width);
y2 = 1.0f - ((GLfloat)y / (GLfloat)this->textureIterator->height);

x3 = (GLfloat)(x + width) / (GLfloat)this->textureIterator->width;
y3 = 1.0f - (GLfloat)(y + height) / (GLfloat)this->textureIterator->height;

x4 = (GLfloat)x / (GLfloat)this->textureIterator->width;
y4 = 1.0f - (GLfloat)(y + height) / (GLfloat)this->textureIterator->height;

Texture coordinates before rendering:

x1Texture = this->imageIterator->x1;
y1Texture = this->imageIterator->y1;

x2Texture = this->imageIterator->x2 + ((width * xtile) / width);
y2Texture = this->imageIterator->y1;

x3Texture = this->imageIterator->x3 + ((width * xtile) / width);
y3Texture = this->imageIterator->y3 + ((height * ytile) / height);

x4Texture = this->imageIterator->x4;
y4Texture = this->imageIterator->y4 + ((height * ytile) / height);

Where xtile, and ytile are integers. So if you wanted to tile the image 3 times in the x direction and 3 in the y direction then xtile=3 and ytile=3;

Code to render quad:

// Begin textured quad.
glBegin(GL_QUADS);

// Upper left corner of image.
glTexCoord2f(x1Texture, y1Texture);

x = -(this->imageIterator->xhotspot);
y = this->imageIterator->yhotspot;
glVertex2f(-x + this->imageIterator->shear, -y);

// Upper right corner of image.
glTexCoord2f(x2Texture, y2Texture);

x = (this->imageIterator->width * xtile - this->imageIterator->xhotspot);
y = this->imageIterator->yhotspot;
glVertex2f(x + this->imageIterator->shear, -y);

// Lower right corner of image.
glTexCoord2f(x3Texture, y3Texture);

x = (this->imageIterator->width * xtile - this->imageIterator->xhotspot);
y = (this->imageIterator->height * (ytile + 1) - this->imageIterator->yhotspot);
glVertex2f(x, y);

// Lower left corner of image.
glTexCoord2f(x4Texture, y4Texture);

x = -(this->imageIterator->xhotspot);
y = (this->imageIterator->height * (ytile + 1) - this->imageIterator->yhotspot);
glVertex2f(x, y);

// End of textured quad.
glEnd();

I can't see what I'm doing wrong. Any help will be of great value. Thanks.

-R

zeoverlord
06-05-2008, 02:01 PM
The quick answer is, you can't, at least not without either cutting out the part you need repeated and place it in it's own texture, or use some kind of custom texture sampling in the fragment shader.

rnodal
06-05-2008, 04:04 PM
It terms of performance what would be better? Place render multiple quads using a loop inside glBegin and glEnd, or do what you suggested, make a texture just for that tile image? Thanks for your help.

-r

elvis
06-05-2008, 07:21 PM
You must do this in the fragment shader. I remember that I saw an article called "practical texture atlas" in ShaderX3 or ShaderX4 book.

rnodal
06-05-2008, 07:32 PM
Quick question. How do I go about rendering a bunch of quads in arbitrary positions, scale, rotation etc, using only one call to glBegin/ glEnd or is this impossible? I'm trying to avoid calling glBegin/ glEnd for every image that I want to render. Thanks a lot.

-R

note: If you want me to start a new thread that's fine.

Zengar
06-06-2008, 12:37 AM
Let me put it this way: if you render only few images (rectangles), say a hundred or so, there is no problem with using the immediate mode. If you render much more, then you should use VBOs --- either with pre-transformed vertices, or do the transformation in the vertex shader.

zeoverlord
06-06-2008, 04:15 AM
Quick question. How do I go about rendering a bunch of quads in arbitrary positions, scale, rotation etc, using only one call to glBegin/ glEnd or is this impossible? I'm trying to avoid calling glBegin/ glEnd for every image that I want to render. Thanks a lot.

Just do it, you only have to drop out of immediate mode when you stop rendering or when you want to change the texture, but "a bunch of quads in arbitrary positions" are no problem.

rnodal
06-06-2008, 06:39 AM
Thanks a lot, those answers were great! Take care.

-r