Jump to content
  • Advertisement
Sign in to follow this  
kgstation

Question about occlusion culling

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I followed MSDN's guide.
And this is my code

IDirect3DQuery9* pOcclusionQuery = NULL;
gd3dDevice->CreateQuery( D3DQUERYTYPE_OCCLUSION, &pOcclusionQuery );
pOcclusionQuery->Issue( D3DISSUE_BEGIN );
for(float x = -50; x < 50; x++)
for(float z = -50; z < 50; z++)
{
drawSand(x , 0.0f, z);
}
pOcclusionQuery->Issue( D3DISSUE_END );
DWORD dwOccluded = 0;
if( S_FALSE == pOcclusionQuery->GetData( &dwOccluded, sizeof(DWORD), 0 ) )
{
// Query is not done yet or object not occluded; avoid flushing/wait by continuing with worst-case scenario
drawSand(rand()%100, 0.0f, rand()%100);
}
else if( dwOccluded != 0 )
{
// Query is not done yet or object not occluded; avoid flushing/wait by continuing with worst-case scenario
drawSand(rand()%100, 0.0f, rand()%100);
}


I use drawSand(float x, float y, float) method to render an object with position x,y,z;
The question is:
I don't know how #pOcclusionQuery->Issue( D3DISSUE_BEGIN );...pOcclusionQuery->Issue( D3DISSUE_END );# works!
How did it save data to pOcclusionQuery?
And how should I reder an object with it's position after culling?I don't know,I set it to random!
Thanks!

Share this post


Link to post
Share on other sites
Advertisement
I'd recommend reading This.

And how should I reder an object with it's position after culling?I don't know,I set it to random!
That depends - what are you doing the occlusion query for? All the occlusion query tells you is that if dwOccluded is > 0, then the object(s) is/are visible.

Share this post


Link to post
Share on other sites

I'd recommend reading This.
[quote name='kgs' timestamp='1332946150' post='4925992']
And how should I reder an object with it's position after culling?I don't know,I set it to random!
That depends - what are you doing the occlusion query for? All the occlusion query tells you is that if dwOccluded is > 0, then the object(s) is/are visible.
[/quote]
Thanks for your help!
And I changed my code
IDirect3DQuery9* pOcclusionQuery = NULL;
gd3dDevice->CreateQuery( D3DQUERYTYPE_OCCLUSION, &pOcclusionQuery );

for(float x = -50; x < 50; x++)
for(float z = -50; z < 50; z++)
{
bool render;
pOcclusionQuery->Issue( D3DISSUE_BEGIN );
drawSand(x , 0.0f, z);
pOcclusionQuery->Issue( D3DISSUE_END );
DWORD dwOccluded = 0;
while (S_FALSE == pOcclusionQuery->GetData( &dwOccluded, sizeof(DWORD), 0 ));
if(dwOccluded == 0)
render = false;
else
render = true;
IsRender.push_back(render);
}
int temp = 0;
for(float x = -50; x < 50; x++)
for(float z = -50; z < 50; z++)
{
if(IsRender[temp] == true)
drawSand(x, 0.0f, z);
temp++;
}

IsRender is used to store imformation about whether objects should be rendered!
But it didn't works!Display with white screen

Share this post


Link to post
Share on other sites
Define "doesn't work"?

And I assume this is just test code? Because issuing command flushes like that is pretty expensive, in a real world situation you should be buffering 2 or 3 frames of queries, and using the newest data you have available instead of blocking to wait for the data to come in.

Share this post


Link to post
Share on other sites

Define "doesn't work"?

And I assume this is just test code? Because issuing command flushes like that is pretty expensive, in a real world situation you should be buffering 2 or 3 frames of queries, and using the newest data you have available instead of blocking to wait for the data to come in.

I mean it didn't cull any object!

Share this post


Link to post
Share on other sites
Are you sure that some the objects you draw are actually occluded?

All an occlusion query does is tell you how many pixels passed the depth test. So if you have a box with a cone behind it, but you draw the cone and then the box, the occlusion query will tell you that both objects are visible - because at the time they were rendered, both passed the depth test. If you draw the objects in front-to-back order, so you draw the box and then the cone, then the occlusion query should report 0 pixels rendered for the cone (Assuming it's completely hidden by the box).

Share this post


Link to post
Share on other sites
Thanks for your help!
But I failed again...
gd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 200, 200, 200 ), 1.0f, 0);
for(float x = -5; x < 5; x++)
for(float z = -5; z < 5; z++)
{
drawSand(x, 0.0f, z);
}

for(float x = -5; x < 5; x++)
for(float z = -5; z < 5; z++)
{
bool render;
pOcclusionQuery->Issue( D3DISSUE_BEGIN );
drawSand(x , 0.0f, z);
pOcclusionQuery->Issue( D3DISSUE_END );
DWORD dwOccluded = 0;
while (pOcclusionQuery->GetData((void *) &dwOccluded, sizeof(DWORD), D3DGETDATA_FLUSH) == S_FALSE);
if( dwOccluded == 0 )
render = false; // No pixels visible, do not render
else
render = true; // Pixels visible, render
IsRender.push_back(render);
}
occlusionRender->EndScene( 0 );

RenderCode:
UINT numPasses = 0;
HR(mFX->Begin(&numPasses, 0));
HR(mFX->BeginPass(0));

int temp = 0;
for(float x = -5; x < 5; x++)
for(float z = -5; z < 5; z++)
{
if(IsRender[temp])
{
drawSand(x, 0.0f, z);
SandCount++;
}
}
HR(mFX->EndPass());
HR(mFX->End());

It seems "dwOccluded" always == 0 in my code...All the object were not drawn!
I can't find what's wrong with my code sad.png

Share this post


Link to post
Share on other sites
I have finished occlusion culling,thanks for your help!
But it takes too much time to query!
Is there other method to cull occluder?(Assume that all the object are cube)

Share this post


Link to post
Share on other sites
I think there's a good explanation about occlusion culling in GPU Gems 3. You can find it on nVidia's website; it's free to read.

Btw, I don't use occlusion culling. I don't know whether this will be helpful or not, but here's a list of what I'm doing:
1) Checking visibility: By using view frustum and bounding volumes. It's quite easy.
2) Filling Z-Buffer: First, setting ZWriteEnable to TRUE, ZEnable to TRUE and ZFunc to LESSEQUAL. Then I'm rendering the visible objects (returned from the prev. step) to only Z-Buffer (i.e. don't touch the front-buffer or any pixel) with a front-to-back order (Ordering is calculated in view space).
3) Rendering with Z-Culling: First, setting ZWriteEnable to FALSE, ZEnable to TRUE and ZFunct to EQUAL then rendering the objects.

This technique is called "Early Z Culling" and works well for forward renderers (like CryEngine 2 and Doom 3 Engines). With this technique, pixel shader won't be executed for invisible pixels (maybe invisible objects). I cannot say anything about performance comparison between occ. culling and this one; try and see.

hth.
-R

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!