Tiling part of a texture.

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

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

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.

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

You must do this in the fragment shader. I remember that I saw an article called “practical texture atlas” in ShaderX3 or ShaderX4 book.

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.

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.

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.

Thanks a lot, those answers were great! Take care.

-r