PDA

View Full Version : OpenGL Texcoord to pixel



esc
11-07-2003, 02:00 AM
Hi!

I have to turn a texture coordinate to the corresponding pixel on screen (screen is a quad lowleft 0,0, upperright 1,1), but I get small differences...

Method 1:

int wndx = int(float(SCR_WIDTH) * texcoordU);
int wndy = int(float(SCR_HEIGHT) * texcoordV);
glOrtho(0, scrWidth, 0, scrHeight, -1, 1);
glVertex2i(wndx,wndy);


Method 2:

glOrtho(0, 1.0, 0, 1.0, -1, 1);
glVertex2f(u,v);


I get differences between Method 1 & 2, and method 2 seems to yield slightly better results, but I'd like to used Method 1 for other operations, i.e. calculating correct wndx,wndy in software. I've tried gluProject(), but that gives the same result as truncating to int as saw in my tests.

How exactly is OpenGL deciding which pixel a glVertex2f(u,v) becomes, if setting ortho mode like I did in Method 2?


I've read through specs, but can't seem to anything...

Bet this is easy for some of you, so please share your knowledge =)

Chris

rgpc
11-07-2003, 03:24 AM
At a glance the thing that stands out to me with method 1 is that you are setting your "Ortho" to WidthxHeight which would make your xpos from 0 to Width-1.

But your calculation of wndX will give you values from 0 to Width (so you're out by a pixel). Make your calcs the following and see if this helps...

int wndx = int(float(SCR_WIDTH - 1) * texcoordU);
int wndy = int(float(SCR_HEIGHT - 1) * texcoordV);

esc
11-07-2003, 04:02 AM
Originally posted by rgpc:

int wndx = int(float(SCR_WIDTH - 1) * texcoordU);
int wndy = int(float(SCR_HEIGHT - 1) * texcoordV);

I tried that, still differences, thanks anyway.

I'm reading the OGL spec about rasterization, and the different rules for different primitives...

Still, any thoughts or ideas appreciated.

Relic
11-07-2003, 06:51 AM
You have to be careful with which area is mapped to where.
Pixel != Integer coordinate.

Lets say you have a 16*16 pixel area,
coordinates go from lower left corner(!) 0,0 to upper right corner(!) of pixel 15,15.
That means a quad filling these 16*16 pixels has texture (u, v) == (0.0, 0.0) on the lower left corner and (1.0, 1.0) on the upper right corner.
Lets say x and y are floating point coordinates on this pixel grid from [0.0, 16.0).
Each pixel in this grid has the texture coordinates from (u0, v0) at the lower left corner to (u1, v1) at the upper right corner, with
u0 = floor(x) / 16.0f;
v0 = floor(y) / 16.0f;
u1 = u0 + 1.0 / 16.0f;
v1 = v0 + 1.0 / 16.0f;

Figure out how to set the projection matrix to get the correct placement for your quad.

What you don't want is to set points exactly on the edge of a pixel coordinate.
You didn't say what the glVertex2i is used for. For points, put the coordinate exactly in the center of a pixel!
You can also draw this as a real quad from lower left to upper right corner of the pixel area, which should be stitch-free in case you fill the whole screen.

Makes sense?