在Direct3D11中使用effect

DX SDK August 2009已經包含了DXSDK的RTM,但似乎新的effect系統還不成熟,反正被降級到D3DX11了,而且源文件被放到utilities裏讓用戶自己編譯lib。
 
具體使用方法如下:
找到utilities文件夾裏的effect11,build出d3dx11effects.lib
將d3dx11effect.h和d3dx11effects.lib複製到你想放的位置上(自己的程序可以找到就行)
使用時,需要包含d3dx11effect.h和d3dx11effects.lib,還需要加上d3dcompiler.lib
fx文件需要先編譯才能創建effect(目前沒有D3D10中諸如D3DX10CreateEffectFromFile的功能)
使用D3DXCompileFromFile編譯,然後用D3DX11CreateEffectFromMemory創建effect.例如如下代碼:

D3DX11CompileFromFile(L"effect11.fx",NULL, NULL, NULL, "fx_5_0",D3D10_SHADER_SKIP_VALIDATION|D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY,NULL, NULL, &pCode, &pError, NULL);

V_RETURN( D3DX11CreateEffectFromMemory(pCode->GetBufferPointer(),pCode->GetBufferSize(), NULL, pDevice,&g_pEffect ) );

還有一個很重要的問題需要注意:

如果顯卡是D3D10級別,在創建Device的時候通常會選擇例如D3D_FEATURE_LEVEL_10_0,這時候會導致編譯shader失敗從而無法繪製場景。這個問題存在於effect11project的EffectNonRuntime.cpp裏,原代碼如下(第1270行左右): (XNAForum的牛人發現的)

if(pShader->pReflectionData->RasterizedStream== D3D11_SO_NO_RASTERIZED_STREAM )

pShader->IsValid =FALSE;

elseif( FAILED((m_pDevice->*(pShader->pVT->pCreateShader))((UINT *)pShader->pReflectionData->pBytecode,pShader->pReflectionData->BytecodeLength,m_pClassLinkage,&pShader->pD3DObject) ) )

{

pShader->IsValid =FALSE;

}

但如果Device不是11_0,則m_pClassLinkage必須爲NULL,所以這裏無法通過。

我們可以更改原代碼如下:

if(pShader->pReflectionData->RasterizedStream== D3D11_SO_NO_RASTERIZED_STREAM )

pShader->IsValid = FALSE;

elseif( FAILED((m_pDevice->*(pShader->pVT->pCreateShader))((UINT *)pShader->pReflectionData->pBytecode,pShader->pReflectionData->BytecodeLength,m_pClassLinkage,&pShader->pD3DObject) ) )

{

if( FAILED((m_pDevice->*(pShader->pVT->pCreateShader))((UINT *)pShader->pReflectionData->pBytecode,pShader->pReflectionData->BytecodeLength,0, &pShader->pD3DObject) ))

pShader->IsValid =FALSE;

}

很簡單,多加一層判斷即可。

然後build出新的d3dx11effects.lib應該就可以正常使用effect了。

發佈了4 篇原創文章 · 獲贊 4 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章