Here is an example of how to dynamically load the D3DCompiler_xx.dll under DX9 without requiring a newer DXSDK installation which includes the complete D3D10/11 headers/libraries.
This approach has the added benefit that it works with the mingw compiler / QtCreator as well.
First we declare some required COM interfaces, D3D structures and the D3DCompile() function prototype (ofcourse you can add more functions like D3DCompileFromFile, etc. if needed):
#ifndef __ID3D10Blob_FWD_DEFINED__
#define __ID3D10Blob_FWD_DEFINED__
typedef interface ID3D10Blob ID3D10Blob;
#endif
#define D3DCOMPILER_DLL_A "d3dcompiler_43.dll"
typedef struct {
LPCSTR Name;
LPCSTR Definition;
} D3D_SHADER_MACRO;
DEFINE_GUID(IID_ID3D10Blob, 0x8ba5fb08, 0x5195, 0x40e2, 0xac, 0x58,
0xd, 0x98, 0x9c, 0x3a, 0x1, 0x2);
typedef struct ID3D10BlobVtbl {
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE *QueryInterface )
(ID3D10Blob * This, REFIID riid, void **ppvObject);
ULONG ( STDMETHODCALLTYPE *AddRef )(ID3D10Blob * This);
ULONG ( STDMETHODCALLTYPE *Release )(ID3D10Blob * This);
LPVOID ( STDMETHODCALLTYPE *GetBufferPointer )(ID3D10Blob * This);
SIZE_T ( STDMETHODCALLTYPE *GetBufferSize )(ID3D10Blob * This);
END_INTERFACE
} ID3D10BlobVtbl;
#define ID3D10Blob_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define ID3D10Blob_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define ID3D10Blob_Release(This) \
( (This)->lpVtbl -> Release(This) )
#define ID3D10Blob_GetBufferPointer(This) \
( (This)->lpVtbl -> GetBufferPointer(This) )
#define ID3D10Blob_GetBufferSize(This) \
( (This)->lpVtbl -> GetBufferSize(This) )
interface ID3D10Blob
{
CONST_VTBL struct ID3D10BlobVtbl *lpVtbl;
};
typedef ID3D10Blob ID3DBlob;
typedef HRESULT (WINAPI *pD3DCompile)
(LPCVOID pSrcData,
SIZE_T SrcDataSize,
LPCSTR pFileName,
CONST D3D_SHADER_MACRO* pDefines,
void*/*ID3DInclude* */ pInclude,
LPCSTR pEntrypoint,
LPCSTR pTarget,
UINT Flags1,
UINT Flags2,
ID3DBlob** ppCode,
ID3DBlob** ppErrorMsgs);
Now we can load the D3DCompiler DLL, import the function via GetProcAddress and then compile our shader:
HINSTANCE hD3DCompiler = LoadLibraryA(D3DCOMPILER_DLL_A);
pD3DCompile D3DCompile = NULL;
if (hD3DCompiler) {
D3DCompile = (pD3DCompile) GetProcAddress(hD3DCompiler, "D3DCompile");
}
ID3DBlob* shaderBlob = NULL;
ID3DBlob* errorMsg = NULL;
D3DCompile(vsSource, strlen(vsSource), NULL, NULL, NULL, "main", "vs_2_0",
0, 0, &shaderBlob, &errorMsg);
if (errorMsg) {
char text[1024];
sprintf(text, "D3DCompile failed:\n%s",
(char*) ID3D10Blob_GetBufferPointer(errorMsg));
MessageBoxA(NULL, text, "Error", MB_OK|MB_ICONERROR|MB_TASKMODAL);
ID3D10Blob_Release(errorMsg);
exit(-1);
}
IDirect3DVertexShader9* shader = NULL;
if (shaderBlob) {
gD3DDevice->CreateVertexShader(
(DWORD *) ID3D10Blob_GetBufferPointer(shaderBlob),
&shader
);
ID3D10Blob_Release(shaderBlob);
}
No comments:
Post a Comment