Texture borders

Hi,

I’m loading a texture that is larger than my implementation allows. The redbook suggests cutting up the source image and loading it as a series of smaller textures then draw them next to each other. I’ve managed this with no problem. The problem comes when I use the GL_LINEAR glTexParameter option to smooth the textures as black lines appear at the boundaries between them. The redbook acknowledges that this happens and suggests using a texture border (p337). It seems that the texture buffer must be increased in size so it allows a one pixel wide edge to be added on each side (redbook p328)(width is therefore width+(one pixel wide edge times 2 edges) and height is (height +one pixel wide edge times 2 edges). Then the image to be loaded must be the equivalent size with the border included in the image source. Then I use glTexImage2D with the Border parameter set to 1 with the new width and height described.

To test the idea I loaded a red square that was 128 by 128 plus a one pixel border hence 130 by 130 in size hoping to see a complete red square once drawn. Instead I get a square that has black horizontal lines. When I put the Border parameter to 0 and put the texture size back to 128 by 128 I get a red square which implies that the border is causing the problem. This happens on both a UNIX platrom (mesa openGL) and an NT platform. (Using OpenGL 1.1).

Has anyone got any suggestions or even better, a source code example of using textures with borders.

Thanks for your time.

As I recall, your texture has to be a power of 2 INCLUDING the border. So, if you have a 1 pixel border around the texture, your texture needs to be 126 (+ 2 for the border = 128).

Thebluegnu2000,

Texture borders are a poorly supported OpenGL feature. You are correct though, the size of the texture is (size^2 + 2*border). I have written code which uses the OpenGL borders, but the NVidia and 3DFX drivers I’ve tested it on did not work. The 3DFX driver dropped to software mode, while the NVidia driver displayed a blank texture.

If you want to use borders, create a texture that is 2^n in size, then strech it over the tile by one-half pixel. You’ll have to do the math yourself with the texture coordinates, they cannot be auto-generated for this. IE: a 128x128 texture would be used over an area of 127 units, from 0.5 on the left to 127.5 on the right. (Note that texture cordinates are always in the range 0…1)

The edge between two tiles would thus share one pixel worth of data, and the blending from the card would look fine. Using one-half pixel overlap instead of a full pixel border saves two rows of texture memory (well, one row & one column).

I believe the topic of texture borders have been touched on several times here, try a search of these forums for some more info.

–Bryan
bryan.turner@pobox.com

All,

Thanks for the comments. I looked through the archives as suggested and yes indeedy this chestnut has cropped up before. Tried the texture border method (works now that I know I have to use glPixelStore to align to bytes) and tried the texture reduction version using:
LowerLeft: glTexCoord2f( 1.0/TEXTURE_WIDTH, 1.0/TEXTURE_HEIGHT );
UpperRight: glTexCoord2f( 1.0-(1.0/TEXTURE_WIDTH), 1.0-(1.0/TEXTURE_HEIGHT) );

For your info I found texture borders make the image complete but draws slower whereas the texture reduction method slightly crops the edges (as expected really) but doesn’t seem to impose any performance hit. It also is quicker on the texture load due to not having to work out and load the border.

>>As I recall, your texture has to be a power of 2 INCLUDING the border. So, if you have a 1 pixel border around the texture, your texture needs to be 126 (+ 2 for the border = 128).<<

No. Borders are extra pixel rows and columns around the texture.

> LowerLeft: glTexCoord2f( 1.0/TEXTURE_WIDTH, 1.0/TEXTURE_HEIGHT );
> UpperRight: glTexCoord2f( 1.0-(1.0/TEXTURE_WIDTH), 1.0-(1.0/TEXTURE_HEIGHT) );

This will lead to truncation, because your
texture coordinates are between the zeroth
and the first pixels. Instead of using
1.0/TEXTURE_DIMENSION, substitute
0.5/TEXTURE_DIMENSION in both lowerleft and
upperright above, and you will get less
truncation (especially if you can ovelap the
sub-images by a pixel when spreading across
your model).