views:

86

answers:

1

Hey,

For some strange reason my depth buffer is not working, i.e. the triangles drawn later always overlap, regardless of their position.

I have these presenter parameters

D3DPRESENT_PARAMETERS d3dpp;

ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = mWindow;

d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = mScreenWidth;
d3dpp.BackBufferHeight = mScreenHeight;

d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

and these render states:

d3dDevice->SetRenderState(D3DRS_LIGHTING, TRUE);    // turn off the 3D lighting
d3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE);    // turn on the z-buffer
d3dDevice->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE);
d3dDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50));    // ambient light

edit: thanks for replying. this is the rendering code code:

d3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
d3dDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

d3dDevice->BeginScene();
// View transform
D3DXMATRIX matView;
D3DXMatrixLookAtLH(&matView,
                   &PlayerPos,    // the camera position
                   &(LookAtRelative + PlayerPos),    // the look-at position
                   &D3DXVECTOR3 (0.0f, 1.0f, 0.0f));    // the up direction
d3dDevice->SetTransform(D3DTS_VIEW, &matView);

// Projection transform
D3DXMATRIX matProjection;
D3DXMatrixPerspectiveFovLH(&matProjection,
                           D3DXToRadian(45),    // the horizontal field of view
                           (FLOAT)mScreenWidth / (FLOAT)mScreenHeight, // aspect ratio
                           0.0f,    // the near view-plane
                           1000.0f);    // the far view-plane
d3dDevice->SetTransform(D3DTS_PROJECTION, &matProjection);



for (unsigned int i=0; i < mModels.size(); i++) {
    mModels[i]->Draw();
}   

d3dDevice->EndScene();
d3dDevice->Present(NULL, NULL, NULL, NULL);

and the Model::Draw() code is this:

void Model :: Draw () {
// Setup the world transform matrix
D3DXMATRIX matScale;
D3DXMATRIX matRotate;
D3DXMATRIX matTranslate;
D3DXMATRIX matWorldTransform;

D3DXMatrixScaling(&matScale, mScale->x, mScale->y, mScale->z);
D3DXMatrixRotationY(&matRotate, 0);
D3DXMatrixTranslation(&matTranslate, mPosition->x, mPosition->y, mPosition->z);

matWorldTransform = matScale * matRotate * matTranslate;
d3dDevice->SetTransform(D3DTS_WORLD, &matWorldTransform);

d3dDevice->SetFVF(CUSTOMFVF);
d3dDevice->SetStreamSource(0, vertexBuffer, 0, sizeof(CUSTOMVERTEX));
d3dDevice->SetIndices(indexBuffer);

d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, vertexCount, 0, indexCount/3); 
}

where vertexBuffer and indexBuffer with with their counts are attributes of the class.

Here are some screenshots (FU, spam protection):

1) http://img822.imageshack.us/img822/1705/dx2010080913182262.jpg this is the situation

2) http://img691.imageshack.us/img691/7358/dx2010080913183790.jpg this is the (correct) view when the cube is in front (the cube is drawn later)

3) http://img340.imageshack.us/img340/4720/dx2010080913184509.jpg But when I have the truncated pyramid in front, the cube still overlaps

it's easier to see when you move the camera yourself...

+1  A: 

Now that's a gotcha. The problem was me setting the near view plane to 0.0f - when I changed it to something like 0.001f, the z-buffer suddenly started to work.

Jonas S.
It was probably (and this is a guess, I don't have formulas handy) related to a division-by-0 when the near plane was at 0. You can usually, depending on the scale of your scene (let's go with 1 unit = 1 inch) set it to 1 without any visible issues. You're better off setting it a little farther away, so you can get the most precision out of the depth buffer (the nearest 5% of the scene takes the lower 95% of the available buffer, so the further out your near plane is, the further out your depth testing will be accurate for).
peachykeen