2011-12-09 34 views
3

我有一些问题需要在DirectX9中绘制。Z缓冲区正在导致事物不能绘制

这是我的渲染功能:

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); 
} 

我设立的DirectX使用此代码:

// 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; 

正因为如此,这个绘制BackgroundColour屏幕没事就可以了。

通过关闭Z缓冲[即g_pd3dDevice - > SetRenderState(D3DRS_ZENABLE,D3DZB_FALSE);]所有东西都按照调用“draw”函数的顺序绘制。稍后绘制的对象会遮盖较早绘制的对象。

我自己也尝试做了这些改变:

g_pd3dDevice -> SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATER); 

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

现在的效果是被拉到中,以后抽中不起眼的对象,无论其空间位置的物体。

我想要的效果是让近处的物体遮住远处的物体。

任何人都可以对此有所了解。

谢谢。

+0

解决这个问题的最简单方法是使用PIX,您可能已经安装了它,因为您已经使用了它。使用PIX调试,这是一个蛋糕走路(从内存中走):您将在PIX中启动您的程序,点击F12,然后关闭您的应用程序以分析框架。选择第一个绘图调用,单击网格选项卡,此时您将能够调查设备。在平局之前和之后看附加的Z目标。与Z缓冲区一起调查这个设备将会非常快速地缩小这个设备,并且让你知道发生了什么。 – Ylisar

+0

当我在PIX中运行程序时,它回到没有绘制任何东西,并且无法加载任何纹理。 – Arkady

+0

它不应该,如果直接启动可执行文件会发生什么情况?不在VS内。 – Ylisar

回答

0

尝试删除这些行:

g_pd3dDevice -> SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); 

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

Z缓冲是默认启用的,所以它应该工作。
确保通过正确的WorldViewProjection矩阵来转换对象。
如果您的对象没有呈现,请检查是否调用了World.draw()。也许BeginScene()失败?

+0

我从来没有做到这一点,但我确实发现了一个解决方法:以前我已经将DirectX设置为使用右手投影。 (x从左到右,y向前和向后运动,z向上和向下运动),所以一般来说z值越高的东西越靠近相机。 (虽然我相信z-buffer与此无关,所以......)无论如何 - 通过切换到左手投影并反转现在的所有z值。 – Arkady