Tex Coord for Middle of a Texture Rectangle

If I have a 256x256 GL_Texture_Rectangle_NV

Is the middle at 127.5, 127.5 or 128, 128

I think the coords run from 0 - 256.0 which would make the exact center 128,128

The center of the first pixel would be 0.5, 0.5 and the center of the last 255.5, 255.5

Is this correct ?

The first half of your texture coordinates is 0,1,2,…,127 and the second half of your texture coordinates is 128,129,130,…,255 (there is no pixel 256, 0-255 is 256 pixels)

So the exact middle of your texture would be 127.5 If I’m not mistaken, texture rectanges want integers for texture coordinates, so whether you round up or down is up to you, if you pass 127.5 in, I’m going to assume the driver will round down. My question is, is there something wrong with GL_TEXTURE_2D?


If there is an even number of pixels how can the middle of the texture be in the middle of a pixel?

Even if the 255th pixel is the 255th, it is still one pixel wide, making 256 pixels.

The middle is obviously exactly between the 128th and 129th pixels. If we restrict ourselves to integers then is no middle pixel.

If we are using floating point then it is just .5, which would map to the left edge of the 129th pixel or the right edge of the 128th pixel.

I am not up enough on the opengl spec to know off the top of my head what .5 maps to if you are using NEAREST filtering.

[This message has been edited by Nakoruru (edited 09-27-2002).]


I think you’re wrong.

If we assume wrapping for a moment (as a thought experiment) then 0.0 is the “same” position as 256.0; both locations lie between the first and the last pixel. Thus, 128.0 would like exactly between two halves of the texture, where each half contains 128 pixels.

This is easier to think about if you think of pixels as squares separated by a grid. The grid lines are numbered with whole integers, and the center of each square (pixel) is between two integers, and thus should correspond to a .5 coordinate.

Right. The exact center of a 1x1 texture rectangle is (0.5, 0.5). The exact center of a 2x2 texture rectangle is (1,1). The exact center of a 256x256 texture rectangle is (128,128).

In general it’s (w/2.0, h/2.0).

Thanks -

Ok, I think I know where my train of thought got derailed. I thought that the texture coordinate was for the actual pixel (I guess meaning the center of the pixel), but it’s actually the boundary edges of the pixels, right? not the inside of the pixel.


Texels values are at the center of the texel.

There is no middle to a 256x256 sized image, or any even numbered size image for that matter. You’re either on one side or the other.

So, does OpenGL round up or down? If you feed in 0.5f, does it map to 127 or 128 of a 256x256 size texture, assuming the range is 0 to 255?

[This message has been edited by WhatEver (edited 09-29-2002).]

Never mind, I just saw your post cass. It rounds up accoording to you.

x = u * width - 1
y = v * width - 1

So with a 256x256 image you get this:

x = 127 = 0.5f * 256 - 1
y = 127 = 0.5f * 256 - 1

That means it naturally rounds to 127, and not 128. Interesting. So 0.5f maps to the lesser side.

Don’t mind me, I’m just bored .


With filtering, 0.5 maps to the average of the 4 centermost pixels. Perhaps your question is: when you’re in nearest mode filtering, which pixel does 0.5,0.5 map to?

I know that if you draw a rectangle from 0,0 to 256,256 when the modelview is set to be == viewport coordinates, and map that to a 256x256 texture, then the texel ixel correlation will be 1:1. This leads to the surprising revelation that OpenGL, when rasterizing that triangle, actually will NOT rasterize a pixel at 0,0, but will rasterize a pixel at (0.5,0.5) in window coordinates.

At least, that’s the best I can come up with in how to explain how this works.

I see. Yes, I would be talking about nearest mode. I was having a flashback to the non-filtered mode days .

It should also be assumed that in my example the texture is clamped.

Here’s something I never understood. Why is your texture shifted over a bit when you choose to repeat the texture? If you have a texture that can be tiled, there’s no reason for it to be shifted…none that I can see anyway.

[This message has been edited by WhatEver (edited 09-29-2002).]

Changing the WRAP mode shouldn’t change the filtered texels - except where they wrap.

If we forget multisample, pixels are sampled at their center. That is where “coverage” is determined, and the location inside a polygon where values are interpolated.

That point where a polygon is sampled is used to produce a texture coordinate. That texture coordinate is used to look into a texture with cell-centered samples.

For me, it’s easiest to think of these things as independent.

Thanks -

If I draw two quads side by side with a texture covering the whole quad and with a clamped texture, you don’t see a seem…but if the texture is set to repeat, you see that the textures are shifted down and to the right by one pixel causeing a seem. The far right column of pixels will be on the left side of the quad…and the bottom row of pixels will be at the top of the quad.

It’s not really that big a deal, it just seams strange that the pixels would be shifted down and to the right by one.

Wait wait wait wait!

You mean if I wasn’t filtering I wouldn’t get that seem? So I can assume that the seem is caused by the filtering of surounding pixels…in the case of reapeating, the left column would be filtered along with the right column and visevesa.

Revelation baby!

I love understanding .

Originally posted by WhatEver:
Revelation baby!

I love understanding .[/b]

Cass is my Guru

I feel the need to explain OpenGL texture filtering and sampling every so often. The spec doesn’t explain it well – I rewrote this for 1.4, but it didn’t make it in.

One easy way to think about texture sampling is to assume that your texture map is a piece of graph paper. (0,0) is the lower left corner of the lower left texel. (1,1) is the upper right corner of the same texture. If your texture is m by n, (m,n) is the upper right corner of the last texel. The center of the texel is always (X.5, Y.5).

GL_NEAREST is basically “give me the color of the cell containing the sample point”. GL_LINEAR is basically “draw a 1-pixel square around the sample point and compute an average color”.

If you draw an aligned texture rectangle with window coordinates (0,0) through (m,n), your texture coordinates should cover the same range. Each pixel is sampled at the center with window coordinates (x.5, y.5). The corresponding texture coordinates are the same, so you hit the middle of the texel.

It shouldn’t matter if you use NEAREST or LINEAR (the 1-pixel square for LINEAR falls right on the texture map). In practice, you might get small rounding errors.

Clamp modes deal with what happens when your coordinates make you fall off.

First, we fix the sample point. For REPEAT and MIRRORED_REPEAT, the sample point bounces around in the obvious manner. For CLAMP, the sample point is clamped to the extent of the texture map. If it falls off, it goes straight to the edge. For now, CLAMP_TO_EDGE and CLAMP_TO_BORDER do nothing.

Next, we look at the sample filter, in particular what happens if we fall off the edge of the map. For 2D (or rectangle) textures, normal filters will sample 1-4 texels. For REPEAT, if the texel you sample is off one edge, you wrap around to the other edge. For CLAMP_TO_EDGE, your samples go back to the edge texture. MIRRORED_REPEAT works like CLAMP_TO_EDGE (seams between textures have the same texel repeated twice). For CLAMP and CLAMP_TO_BORDER, if you fall of the edge, you get either the border texel (if it’s in the image) or the constant border color.

CLAMP is the least intuitive mode. If you fall of the edge of a texture map, you start getting the border color blended in. But you will never more than 50% border (75% in corners) since your sample point is always clamped to the edge, producing a 50/50 filter.

This is pretty useless. If you see seams in a tiled texture, it’s probably because you used CLAMP and are seeing the border color. (To be sure, change the border color and your seams should change color.)

As I mentioned above, if you use a LINEAR filter with a 1:1 mapping of pixel to texels, you should get the same results as NEAREST. Except rounding errors may leave you off by a little bit, and you end up seeing a little bit of border. Annoying! Use CLAMP_TO_EDGE instead.

Anyone still awake? If so, hope this helps.

[This message has been edited by pbrown (edited 09-30-2002).]

I’m awake! Thanks for the description, Pat!

One comment: for GL_LINEAR, would you describe the “1-pixel square” as a square that connects texel centers of the 4 nearest samples? Just making sure what I think you mean by the 1-pixel square…

Thanks -

I think he means that there a square that’s exactly as large as a texel, and which is centered on the texture coordinate being fetched. The contributions of the four texels this square may intersect are weighted in relation to how much area of each texel the texel-sized square covers.

Once you’ve gotten used to thinking like this, you can think of MIP mapping as a texel-unit-sized cube in the texture stack (sort of :slight_smile: and anisotropic filtering as a texel-unit-sized cube that’s been stretched by the partial derivatives of the texture coordinates and thus is no longer cube-shaped.


Since you’re talking about a box that is centered on the texture coordinate being fetched… for this case - with linear filtering, I usually think of the reconstruction filter as a tent /\ that is two units wide. The area under the tent is 1.0.

How does what I’m describing jibe with the one unit wide box?

Thanks -