Sign in to follow this  
TtDTtW

Detecting Changes

Recommended Posts

Say I want to draw a quad on the screen (say, like something covering a door to another room), is there a way to detect if any of that quad actually got drawn... (detect if it was fully occluded by other geometry...) Is there a way to count the number of pixels it actually effected? How about a way to detect the number of depth tests passed as opposed to those attempted (without counting the stencil buffer... aka, setting the stencil to 1 if depth failed, and 2 if depth passed, then go through the buffer and count the number of 2's vs the number of 1's and 2's... that make sense?) Just wondering if there's a built in DirectX api way of detecting these changes... since counting the stencil changes (ala reseting the stencil buffer everytime I need to draw a new portal/effect and then locking/copying the stencil buffer to read) seems a tad slow for my tastes... (I read something in an article once about improving a particle engine by detecting what was drawn last frame, and if something wasn't drawn, marking it as not visible as long as the camera didn't move... but it never said how to detect if nothing was drawn to the screen).

Share this post


Link to post
Share on other sites
I know you can do occlusion testing with directx queries (IDirect3DQuery9*) to see whether an object is drawn or not. I don't think there is a built in API stuff for the other things you mentioned. Unfortunatly I have never used queries so I can't throw a code snippet or more info at you. Sorry.

Share this post


Link to post
Share on other sites
Regarding queries, start here - it even has a snippet of code for basic occlusion querying:

IDirect3DQuery9* pOcclusionQuery;
DWORD numberOfPixelsDrawn;

m_pD3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, &pOcclusionQuery);

// Add an end marker to the command buffer queue.
pOcclusionQuery->Issue(D3DISSUE_BEGIN);

// API render loop
...
Draw(...)
...

// Add an end marker to the command buffer queue.
pOcclusionQuery->Issue(D3DISSUE_END);

// Force the driver to execute the commands from the command buffer.
// Empty the command buffer and wait until the GPU is idle.
while(S_FALSE == pOcclusionQuery->GetData( &numberOfPixelsDrawn,
sizeof(DWORD), D3DGETDATA_FLUSH ))
;


Bare in mind that the final while() loop can stall the application and actually hurt your overall performance. Because of the way the hardware/drivers implement the D3D pipeline the results may not be immediately available (I've read a few places saying it can take multiple frames)...

hth
Jack

Share this post


Link to post
Share on other sites
Hmm, seems interesting, thanks for the link... I'll have to test whether stencil testing or using the D3DQuery is faster for the effect I'm trying to pull off...

Again, thanks for the replies... Can't wait to get done with work and try it out...

Share this post


Link to post
Share on other sites
Quote:
Original post by jollyjeffers
Bare in mind that the final while() loop can stall the application and actually hurt your overall performance. Because of the way the hardware/drivers implement the D3D pipeline the results may not be immediately available (I've read a few places saying it can take multiple frames)...

It's not that it can stall your app - it's that it will. Generally, applications that use occlusion queries in an attempt to predicate rendering actually do the complete opposite - their performance actually becomes worse.

Note that with D3D10, you can use occlusion queries efficiently for things like this.

Share this post


Link to post
Share on other sites
I recently used occlusion queries for a lens flare effect, and found what circlesoft said to be very true. If i loop for the results using D3DGETDATA_FLUSH right after the request it takes about 1 millisecond, which is a lot of time for such a small effect. If i check for the result every frame without flushing it can take anywhere between 3-20 frames (about 15ms each) to get a result, but the CPU doesn't stall. I ended up waiting a frame before getting the results and then looping with D3DGETDATA_FLUSH. My performance counters show that using this method every fifth frame or so I get a query for free. I'm not really sure why though.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this