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