Texture projection with stenciling

Hi,
I want to project a single copy of a texture image, i.e. with no repetition. So far, I haven’t been able to get the effect I want using GL_CLAMP unless I add a black border. I don’t want to use a border because that removes a 1-texel strip from around the texture image.

Since what I want to do, effectively, is project through a stencil, it seems that maybe I should be using the stencil buffer. My attempts to do this have failed so far though. Is the stencil buffer the right way to go, or is there a better method? Any useful code examples?

thanks
Gib

Hi,

I tried to search documentation before. It seems the stencil buffer is NOT available under windows.

Or anybody can tell me how to simulate the similar effect?

I don’t know where you get the idea that stencil isn’t available under Windows…
It does depend on you requesting an appropriate pixel format though.

-Mezz

Stencil buffer is supported on windows.

You cannot project through it though… it is a screen buffer, like the color buffer or the depth buffer. It can be used for information about individual pixels on the screen, at the time of writing to those pixels.

So it seems that the stencil buffer is not the way to do what I want. Is there a way?

Gib

Originally posted by gib:
[b]So it seems that the stencil buffer is not the way to do what I want. Is there a way?

Gib[/b]

Hi

setting the wrapping mode to GL_CLAMP_TO_EDGE should do it. Its part of at least GL 1.4 (or lower) core or an GL_ARB_texture_clamp _ extension (don’t know the exact name)

It assures that sampling does not use border colors.

Bye
ScottManDeath

Hi,

I think you should put zero alpha to texels on the edge of the texture, use GL_CLAMP and use alpha test to reject pixels outside the texture. Another option are clipping planes. Which one is faster depends on whether you are fill or geometry limited. On new cards, especially NVidia, alpha test is faster.

-Ilkka

Be careful with clipping planes for multi-pass algorithms. Clipped geometry is not generally invariant with unclipped geometry.

Originally posted by ScottManDeath:
[b] Hi

setting the wrapping mode to GL_CLAMP_TO_EDGE should do it. Its part of at least GL 1.4 (or lower) core or an GL_ARB_texture_clamp _ extension (don’t know the exact name)

It assures that sampling does not use border colors.

Bye
ScottManDeath

[/b]

ARB_texture_border_clamp. -Very- useful, as long as one’s video card supports it. It’s also incredibly simple to use.

You can use the stencil buffer if you really wanted to. If what you want to do is to project a texture, render the frustum planes as a “light volume” to tag pixels, thus limiting the texture projection to those pixels.
It’s a bit overkill but it works.

I prefer clamp_to_border or clamp_to_edge ( for textures where that makes sense, like pre-generated spotlight textures ).

Edit: That is, the frustum for the texture projection, not the view frustum.

[This message has been edited by PH (edited 01-21-2003).]

Originally posted by Ostsol:
ARB_texture_border_clamp. -Very- useful, as long as one’s video card supports it. It’s also incredibly simple to use.

It’s in core Ogl1.2. Most current card should have it now.

The current project I’m working on is on Windows, and GL_CLAMP_TO_EDGE is not recognized. I have a recent GeForce 4. Do I need to upgrade the nVidia driver or some other library?

Gib

Originally posted by gib:
[b]The current project I’m working on is on Windows, and GL_CLAMP_TO_EDGE is not recognized. I have a recent GeForce 4. Do I need to upgrade the nVidia driver or some other library?

Gib[/b]

It works fine for me so I think you need to get newer opengl headers. I think you can find them on opengl.org or maybe even at cvs1.nvidia.com. I’m not sure about the cvs site but you never know, I havn’t looked on there in quite a while.

Just for the record, GL_GLAMP_TO_EDGE is defined as 0x812F. So you can always just write that define in your code. But I would try to find newer headers first if I were you. If all else fails just define it like above.

-SirKnight

SirKnight is right. Windows headers are for GL1.1.

You can use many of the available library to load extensions or just create a new header yourself.

To use GL_CLAMP_TO_EDGE, you need to have the enumerant(which sirkngiht gave) and a driver supporting opengl 1.2 (reading the GL_VERSION string) or a driver that supports GL_EXT_texture_egde_clamp( from GL_EXTENSION string).

Actually, this leads me to a question :

If a driver supports Opengl1.2, does it have to also expose the ext or arb extensions that was promoted in the extension strings?

[This message has been edited by Gorg (edited 01-21-2003).]

I added a define for GL_CLAMP_TO_EDGE, but it seems to behave just like GL_CLAMP. The edge texels on the texture image are used outside the texture. I can suppress this by modifying the 1-texel strip around the texture to have color (0 0 0) or to have alpha=0 then using an alpha test. These two methods are equivalent for my purposes, and they both remove a 1-texel border from my texture image, which I don’t want to do.

How can I use GL_CLAMP_TO_EDGE and not lose the edge of my image?

Gib

Originally posted by gib:
[b]I added a define for GL_CLAMP_TO_EDGE, but it seems to behave just like GL_CLAMP. The edge texels on the texture image are used outside the texture. I can suppress this by modifying the 1-texel strip around the texture to have color (0 0 0) or to have alpha=0 then using an alpha test. These two methods are equivalent for my purposes, and they both remove a 1-texel border from my texture image, which I don’t want to do.

How can I use GL_CLAMP_TO_EDGE and not lose the edge of my image?

Gib[/b]

Hi

Im not sure if it helps but nVidia drivers have a driver setting to enable conformant textur clamping. It is somewhere in the OpenGL driver settings panel. Perhaps this helps.

Bye
ScottManDeath

What you need is GL_CLAMP_TO_BORDER, not GL_CLAMP_TO_EDGE. I believe this is only accelerated on GeForce3 and up, though.

– Tom

Is losing that 1-texel strip really that serious? You seem to be going through a lot of trouble to avoid it. Maybe if you have very low-res textures, otherwise it just can’t make that big a difference.

-Ilkka

In some cases 1 texel is significant, in others not (remember, my textures are really images for projecting). For generality I need to take care of it. And with GL_CLAMP_TO_BORDER (thanks Tom!!) it is actually very easy.

An minor observation: I now have two ways of “stenciling” the texture projection, one using clipping planes, the other using GL_CLAMP_TO_BORDER. Both work fine, but in the case of clipping the edges show staircasing, which is mostly absent in the other case.

I have a related question. Is it still the case that a texture must be 2^n x 2^m?

Gib

There are some extensions for texture rectangles, but they usually have restrictions like they can only be used for hud-like stuff.

A 1-texel strip usually won’t work if you use mipmapping… because you need a 2-pixel strip at mipmap level 0 to get a 1-pixel strip at mipmap level 1, a 4-pixel strip at 0 to get a 1 pixel strip at 2, and so on until you have to have a completely transparent image. So, you either have to disable mipmapping or live with the artifacts of whatever strip size you chose.