Using Different Stencils on Different Layers of a Direct3D Scene

juicemonger
juicemonger used Ask the Experts™
on
I'm drawing some simple 2D graphics to a direct3D device using Direct3D.Font.DrawText() (etc.) and am trying to accomplish the following:

Essentially, I want to be able to draw "Hello" and "Goodbye" on top of each other, (so that they would overlap completely,) but only show the top half of "Hello" and the bottom half of "Goodbye". I thought that I could use Device.RenderState.StencilFunction and such to pass through only the part of the text/image that I wanted to see, though it seems that I can use a stencil only once per scene, and cannot use different stencils on different elements within the scene. Is there any easy way to do this besides rendering to a surface and copying each element? Is there a way to lock all but a small portion of the Device to which I'd like to draw?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Commented:
Your assumption about the use of the stencil buffer is maybe slightly wrong. You have only 1 buffer which you can use however you can change the stencil operation and the pass / fail / zfail functions as many times as you like - per rending pass. Which means you can only set up the stencil once per draw call, unless you want to make the draw call multiple times.

You are probably better off enabling user clip planes. The following link is a pretty good reference on that:
http://http.download.nvidia.com/developer/SDK/Individual_Samples/samples.html#NearClipPlane

Hope this helps :o)

Author

Commented:
I thought that clip planes were usually used in 3D space to hide detail that was a certain distance from the camera. I'm dealing only with 2D images, and can't believe there isn't a simpler way to do this than to wade through that sample.

If anything, I'm looking for a C# example that will do something similar to what I need.

I imagined that I could set the stencil to a different value in different regions in my frame: the rectangle around the top half of "Hello" might be 0x1, and around the bottom half of "Goodbye" might be 0x2. Can I not simply say:

ReferenceStencil = 1
DrawText("Hello")
ReferenceStencil = 2
DrawText("Goodbye")

I'm having a really hard time finding any documentation on stencils that doesn't apply to 3D shadow volumes and such.

Isn't there a simple way to do this?

Commented:
You can use clip planes for anything you like - they just clip it. Even your 2D images must be rendered with screen aligned quads.

Anyway there is a much easier solution - Clip your quads manually by say halving the height (and adjusting the texture appropriately).

Author

Commented:
"Screen aligned quad" sounds pretty vague. I fear that my ignorance is about to show pretty bad: What do you mean by a "quad"? A surface? A texture?

So, I do have to render to a texture or offscreen surface, clip it and blit it to the screen again?

I've searched all over the place for some sample code--anything that would give me some idea of how to do this, and haven't found anything. If you can find me something, I'll give you the points. Otherwise: yeah. I understand the vagaries, but I've had trouble implementing them. I just want to draw text and a bitmap onto something, clip part of that something, and display the remainder on the screen. Shouldn't this be a 5-minute project for someone who knows how to do it?
I have no idea about the clipping, but a quad is two triangles arranged to form a rectangle.

Or, in the case of drawing fonts, you just specify a RECT for the font (like for the DrawText function)

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial