Texture coords not working quite right

Started by
1 comment, last by Aardvajk 17 years, 8 months ago
I've got a system up and running that places images onto a texture, and attempts to store the correct FLOAT values at the time to later pass to the corners of a quad to render the image as a 2D sprite. Trouble is, it is sort of working but not quite. Some of the images seem to render pixel perfect, but others seem just off by a pixel. I don't think this can be float inaccuracy since the values are quite small. My current test program is using a 512x512 texture and placing a variety of different sized images onto this texture. As it places the images, it stores the texture co-ords like this: Rct.L=(FLOAT(X))/(FLOAT(W)); Rct.T=(FLOAT(Y))/(FLOAT(H)); Rct.R=(FLOAT(X+Wt))/(FLOAT(W)); Rct.B=(FLOAT(Y+Ht))/(FLOAT(H)); Where Rct is a struct containing four FLOATs, X and Y are the integer position on the texture where the image was just placed, W and H are the width and height of the overall texture and Wt and Ht are the dimensions of the image being placed. These values are then fed to the tu and tv values of the verticies of the quad that is supposed to render the image. It is a bit frustrating because some are being drawn perfectly but others are just off. If it is a float accuracy issue, can anyone suggest a solution? I don't think I can use double's in a FVF. I've tried jiggling the various values about but nothing seems to be working. Thanks. Paul [EDIT] I've just tried it with images whose dimensions are all exact multiples of 8 and they all display correctly, which leads me to think it is a float precision issue. I can just work round the problem like that if no-one has a solution but I'm quite suprised that FLOATs aren't accurate enough if that is the case. [Edited by - EasilyConfused on August 12, 2006 4:04:27 PM]
Advertisement
It could be that you're on a border case (which you are).

In D3D 1/w,1/h isn't the second pixel in the second row of pixels. It's mid-way between that pixel, and the pixels above, to the left, and above and to the left.

ie: 0,0 is the corner of the upper left texel, not it's center.

0.5/w, 0.5/h is the center of the corner texel.

Just add 0.5 to your X and Y before dividing and you should be fine.

A---+---+---+|   |   |   || C |   |   ||   |   |   |+---B---+---+|   |   |   ||   |   |   ||   |   |   |+---+---+---+
A = 0,0
B = 1/w, 1/h.
For both A and B, if you have linear filtering it will be the average of 4 texels. For point filtering, it could pick any of the 4 texels.
C = 0.5/w, 0.5/h.
This is the center of the texel and will look correct with linear or point filtering.

Note that in OpenGL and D3D10, C is 0,0.
That works! Namethatnobodyelsetook, you are an absolute star. Just in case anybody else is ever struggling with this, my corrected code is:

Rct.L=(FLOAT(X)+0.5f)/(FLOAT(W));
Rct.T=(FLOAT(Y)+0.5f)/(FLOAT(H));

Rct.R=(FLOAT(X+Wt)+0.5f)/(FLOAT(W));
Rct.B=(FLOAT(Y+Ht)+0.5f)/(FLOAT(H));

And now everything is working correctly.

Major thanks.

Paul

This topic is closed to new replies.

Advertisement