# How to overwrite something after its already drawn

This topic is 4767 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hey all, I don’t think this is possible, but wanted to see what everyone else thought? I have a few areas where I want to do something similar, but I’ll give one example for now since it should work (or not) in all cases. This is all one frame: Let’s assume I draw a wall (a simple poly with two triangles) right in front of the player. Next I want to make an opening in the wall a hole, maybe by design, maybe it was broken, whatever Is there a tricky way to do this? I really don’t want to have to split the wall into a lot of triangles in order to get the hole. I was hoping there is a trick with the z buffer or stencil buffer or shaders, to somehow draw a wall ( w/ 2 tris) but exclude a particular shape (any shape) out of it so I see what’s through it? Any ideas, or do I need to do this in the triangles? If I’ve been too vague in my questioning just say so and I’ll try to elaborate more. Thanks. Quad

##### Share on other sites
How are you doing?

The Problem
"Making holes in walls"

The Solution
Here are a few options, generally you wouldn't make holes in walls but if you need it for a map or so it might be better to use a mesh. if not you can also modify the vertices in the vertex buffer and just check for vertices in a range and remove them and weld the other vertices to form a wall. I don't think you might be able to do it with stencilling, I will have to check for you... but right now I have to run to class...

Take care buddy, I hope some of this information was informative, I will check when I get back. Cheerio.

##### Share on other sites
Disable depth testing and draw over?

##### Share on other sites
There's at least 2 ways I can think of to do that:

1. with a texture with an alpha channel, just make the part you want have a 0 alpha value and use alpha blending.

2. This one has various sub-points :D
2.1. Enable stencil write and make it set the stencil values to 1
2.2. Draw the geometry you want as the hole (the square you were talking about)
2.3. Disable stencil writes
2.4. Enable stencil tests to pass only with stencil values of 0

If you don't know how to use the stencil buffer or don't know how it works, a quick [google] search on "stencil buffers" will give you some clues.

 Point enumeration corrected (just learned that after 2.4 is 2.5 and not 2.4 again [grin])
[edit2] Corrected urls

[Edited by - Kamikaze15 on August 31, 2005 4:42:36 PM]

##### Share on other sites
Thanks everyone.

Fruny, although the simplest idea, I don't think it's quite that simple. Unless all the triangles being drawn are presorted manually, I can't assume what will be drawn or when. Therefore, something I want behind the wall would possibly appear in front of the wall. I still need the depth buffer to ensure things that should be occluded are.

Kamikaze15, I think you’re describing what I want. I’ll have to play with the stencil buffer a bit to understand how to use it better.

In this day and age, is the stencil buffer still a good tool to use, or are there other ramifications that make it bad? Will I take much of a performance hit for this vs the other option of making my hole a full 3d model?

Thanks to all

##### Share on other sites
Nice, That's what I want exactly.

In a nutshell, this is what I've extracted from that DOC:

First step - Generate the outline of the hole=============================================glEnable(GL_STENCIL_TEST)       			= Enable Stencil Bufffer TestingglColorMask(0, 0, 0, 0)					= Disable rendering to the frame bufferglStencilFunc(GL_ALWAYS, 1, 1)				= Allow all pixels to pass the testglStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE)		= Replace the current value with the new oneglDepthMask(GL_FALSE)					= Disable depth buffer writingSecond step - Draw the objects, using the stencil buffer to mask out the shape of the hole==========================================================================================glColorMask(1, 1, 1, 1)					= Re-Enable writes to the frame bufferglDepthMask(GL_TRUE)					= Re-Enable depth buffer writesglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)			= Keep the current stencil buffer values (don't replace or overwrite)glStencilFunc(GL_ALWAYS, 1, 1)				= Allow all pixels to pass the testglStencilFunc(GL_NOTEQUAL, 1, 1)			= Only render where the value is not equal 1 (render around the mask)

Do we have a directx stencil buffer expert that can easily convert all the commands above into their directx equivalent? It would save me a lot of time and I’d really appreciate it.

Thanks

##### Share on other sites
Normally, a wall is three dimensional, and so the outline of the hole would be dependent on the viewing angle. In which case you'd need to design the geometry appropriately.

##### Share on other sites
By tweaking kamikaze's first method, it can work. Use alphatest, not really sure how to use it though, but thats what you can use. But heres what you need to do for the second method
///////////////////////////////////////////////////////////////// First step- generate the outline of the hole./////////////////////////////////////////////////////////////////enable stencil bufferDevice->SetRenderState(D3DRS_STENCILENABLE, true);//Disable write to back and z bufferDevice->SetRenderState(D3DRS_ZWRITEENABLE, false);Device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);//Allow all pixels to pass the testDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);//Set the reference value to 1, and not mask any valuesDevice->SetRenderState(D3DRS_STENCILREF, 0x1);Device->SetRenderState(D3DRS_STENCILMASK, 0xffffffff);Device->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff);//Replace the the passing pixels with the stencil ref (0x1) and keep if z-buffer failsDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);Device->SetRenderState(D3DRS_STENCILFAIL,  D3DSTENCILOP_KEEP);Device->SetRenderState(D3DRS_STENCILPASS,  D3DSTENCILOP_REPLACE);/////////////////////////////////////////////////////////////////Render the hole////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Second step - Draw the objects without the hole in the middle/////////////////////////////////////////////////////////////////Re-enable writes to z and back bufferDevice->SetRenderState(D3DRS_ZWRITEENABLE, true);Device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);//Keep the current stencil valuesDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);//Render where the stencil buffer doesn't equal the stencil ref(0x1)Device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_NOTEQUAL);/////////////////////////////////////////////////////////////////Render the wall////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Third step - Reset everything back to normal/////////////////////////////////////////////////////////////////Disable stencil testDevice->SetRenderState(D3DRS_STENCILENABLE, false);

But make sure that when you clear the device, make sure you clear the stencil buffer like this:
Device->Clear(0,0,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | /* and the most important:*/ D3DCLEAR_STENCIL,0xff000000/*clear to your color...*/,1.0f/*z-buffer*/,0/*and your favorite, stencil buffer*/);

##### Share on other sites
awesome, thanks. I'll be giving this a try very soon.

1. 1
2. 2
Rutin
22
3. 3
4. 4
frob
17
5. 5

• 33
• 13
• 12
• 10
• 12
• ### Forum Statistics

• Total Topics
632573
• Total Posts
3007140

×