2011-12-09 39 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