Question about occlusion culling

Started by
8 comments, last by programci_84 12 years ago
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!
My english is very poor!
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.

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
My english is very poor!
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.

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!
My english is very poor!
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).
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
My english is very poor!
Found error…drawSand() …causes this problem
My english is very poor!
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)
My english is very poor!
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
There's no "hard", and "the impossible" takes just a little time.

This topic is closed to new replies.

Advertisement