00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "stdafx.h"
00023 #include "PixelShaderCompiler.h"
00024
00025 CPixelShaderCompiler::CPixelShaderCompiler(IDirect3DDevice9* pD3DDev, bool fStaySilent)
00026 : m_pD3DDev(pD3DDev)
00027 , m_hDll(NULL)
00028 , m_pD3DXCompileShader(NULL)
00029 , m_pD3DXDisassembleShader(NULL)
00030 {
00031 CString d3dx9_dll;
00032 d3dx9_dll.Format(_T("d3dx9_%d.dll"), D3DX_SDK_VERSION);
00033
00034 m_hDll = LoadLibrary(d3dx9_dll);
00035
00036 if(m_hDll)
00037 {
00038 m_pD3DXCompileShader = (D3DXCompileShaderPtr)GetProcAddress(m_hDll, "D3DXCompileShader");
00039 m_pD3DXDisassembleShader = (D3DXDisassembleShaderPtr)GetProcAddress(m_hDll, "D3DXDisassembleShader");
00040 }
00041 else if(!fStaySilent)
00042 {
00043 AfxMessageBox(_T("Cannot load ") + d3dx9_dll + _T(", pixel shaders will not work."), MB_OK);
00044 }
00045 }
00046
00047 CPixelShaderCompiler::~CPixelShaderCompiler()
00048 {
00049 if(m_hDll) FreeLibrary(m_hDll);
00050 }
00051
00052 HRESULT CPixelShaderCompiler::CompileShader(
00053 LPCSTR pSrcData,
00054 LPCSTR pFunctionName,
00055 LPCSTR pProfile,
00056 DWORD Flags,
00057 IDirect3DPixelShader9** ppPixelShader,
00058 CString* disasm,
00059 CString* errmsg)
00060 {
00061 if(!m_pD3DXCompileShader || !m_pD3DXDisassembleShader)
00062 return E_FAIL;
00063
00064 HRESULT hr;
00065
00066 CComPtr<ID3DXBuffer> pShader, pDisAsm, pErrorMsgs;
00067
00068 hr = m_pD3DXCompileShader(pSrcData, strlen(pSrcData), NULL, NULL, pFunctionName, pProfile, Flags, &pShader, &pErrorMsgs, NULL);
00069
00070 if(FAILED(hr))
00071 {
00072 if(errmsg)
00073 {
00074 CStringA msg = "Unexpected compiler error";
00075
00076 if(pErrorMsgs)
00077 {
00078 int len = pErrorMsgs->GetBufferSize();
00079 memcpy(msg.GetBufferSetLength(len), pErrorMsgs->GetBufferPointer(), len);
00080 }
00081
00082 *errmsg = msg;
00083 }
00084
00085 return hr;
00086 }
00087
00088 if(ppPixelShader)
00089 {
00090 if(!m_pD3DDev) return E_FAIL;
00091 hr = m_pD3DDev->CreatePixelShader((DWORD*)pShader->GetBufferPointer(), ppPixelShader);
00092 if(FAILED(hr)) return hr;
00093 }
00094
00095 if(disasm)
00096 {
00097 hr = m_pD3DXDisassembleShader((DWORD*)pShader->GetBufferPointer(), FALSE, NULL, &pDisAsm);
00098 if(SUCCEEDED(hr) && pDisAsm) *disasm = CStringA((const char*)pDisAsm->GetBufferPointer());
00099 }
00100
00101 return S_OK;
00102 }