3

I'm having some issues getting things to draw in DirectX9.

Here's my render function:

void Render(GameWorld& world)
{
    DWORD BackgroundColour = 0x00102010;    

    g_pd3dDevice -> Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, BackgroundColour, 1.0f, 0);

    // Begin rendering the scene.
    if (SUCCEEDED(g_pd3dDevice -> BeginScene()))
    {
        world.draw();

        g_pd3dDevice -> EndScene();
    }

    // Present the backbuffer to the display.
    g_pd3dDevice -> Present(NULL, NULL, NULL, NULL);
}

I'm setting up DirectX with this code:

// Create the D3D object, return failure if this can't be done.
if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION))) return E_FAIL;

// Set up the structure used to create the D3DDevice
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

// Create the D3DDevice
if (FAILED(g_pD3D -> CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                  D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                  &d3dpp, &g_pd3dDevice)))
{
    return E_FAIL;
}

// Turn on the Z buffer
g_pd3dDevice -> SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

g_pd3dDevice -> SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS);
g_pd3dDevice -> SetRenderState(D3DRS_ZWRITEENABLE, TRUE);

// Start with lighting off - we can add lights later.
g_pd3dDevice -> SetRenderState(D3DRS_LIGHTING, FALSE);

// Set transparencies
g_pd3dDevice -> SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_pd3dDevice -> SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pd3dDevice -> SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
g_pd3dDevice -> SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);




// Set culling
g_pd3dDevice -> SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW);

return S_OK;

As it is, this draws a BackgroundColour screen with nothing on it.

By turning the Z-buffer off [i.e. g_pd3dDevice -> SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);] everything is drawn in the order their "draw" functions are called. Objects drawn later obscure objects drawn earlier.

I have also tried making these changes:

g_pd3dDevice -> SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATER);

and

g_pd3dDevice -> Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, BackgroundColour, 0.0f, 0);

The effect is now that objects that are drawn first obscure objects that are drawn later, regardless of their spacial positions.

The effect I want is for near objects to obscure far objects.

Can anybody shed some light on this.

Thank you.

Arkady
  • 338
  • 1
  • 2
  • 8
  • The easiest way to solve this is by using PIX, you probably already have it installed as you get it with the SDK. With PIX debugging this is a cake walk ( going from memory ): You'll start your program in PIX, hit F12, and then close down your app to analyze the frame. Pick the very first draw call, click the mesh tab, at which point you'll be able to investigate the device. Look at attached Z target before & after the draw call. Investigating the device together with the Z buffer will narrow this down really fast and give you a good idea of what's going down. – Ylisar Dec 09 '11 at 20:41
  • When I run the program in PIX it goes back to drawing nothing, and fails to load any textures. – Arkady Dec 09 '11 at 22:28
  • It shouldn't, what happens if you launch the executable directly? Not from within VS. – Ylisar Dec 10 '11 at 00:45

1 Answers1

0

Try removing these lines:

g_pd3dDevice -> SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

g_pd3dDevice -> SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS);
g_pd3dDevice -> SetRenderState(D3DRS_ZWRITEENABLE, TRUE);

The z-buffer is enabled by default, so it should work.
Make sure you transform your objects by the correct WorldViewProjection matrix.
If your objects are not rendered, check if World.draw() is called. Maybe BeginScene() fails?

miloszmaki
  • 1,528
  • 13
  • 21
  • I never did get to the bottom of this, but I did discover a workaround: previously I had set DirectX up to use right handed projections. (x running left to right, y running forwards and backwards and z running up and down) so in general things with a higher z-value were nearer the camera. (Although I believe the z-buffer is independent of this, so...) Anyway - by switching to a left handed projection and inverting all the z values it now works. – Arkady Dec 15 '11 at 21:31