ShaderEditorDlg.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:13k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. // ShaderEditorDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "mplayerc.h"
  5. #include "PixelShaderCompiler.h"
  6. #include "ShaderEditorDlg.h"
  7. #undef SubclassWindow
  8. // CShaderLabelComboBox
  9. BEGIN_MESSAGE_MAP(CShaderLabelComboBox, CComboBox)
  10. ON_WM_CTLCOLOR()
  11. ON_WM_DESTROY()
  12. END_MESSAGE_MAP()
  13. HBRUSH CShaderLabelComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
  14. {
  15. if(nCtlColor == CTLCOLOR_EDIT)
  16. {
  17. if(m_edit.GetSafeHwnd() == NULL)
  18.             m_edit.SubclassWindow(pWnd->GetSafeHwnd());
  19. }
  20. return __super::OnCtlColor(pDC, pWnd, nCtlColor);
  21. }
  22. void CShaderLabelComboBox::OnDestroy()
  23. {
  24. if(m_edit.GetSafeHwnd() != NULL)
  25. m_edit.UnsubclassWindow();
  26. __super::OnDestroy();
  27. }
  28. // CShaderEdit
  29. CShaderEdit::CShaderEdit()
  30. {
  31. m_acdlg.Create(CShaderAutoCompleteDlg::IDD, NULL);
  32. m_nEndChar = -1;
  33. m_nIDEvent = -1;
  34. }
  35. CShaderEdit::~CShaderEdit()
  36. {
  37. m_acdlg.DestroyWindow();
  38. }
  39. BOOL CShaderEdit::PreTranslateMessage(MSG* pMsg)
  40. {
  41. if(m_acdlg.IsWindowVisible() 
  42. && pMsg->message == WM_KEYDOWN 
  43. && (pMsg->wParam == VK_UP || pMsg->wParam == VK_DOWN
  44. || pMsg->wParam == VK_PRIOR || pMsg->wParam == VK_NEXT
  45. || pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE))
  46. {
  47. int i = m_acdlg.m_list.GetCurSel();
  48. if(pMsg->wParam == VK_RETURN && i >= 0)
  49. {
  50. CString str;
  51. m_acdlg.m_list.GetText(i, str);
  52. i = str.Find('(')+1;
  53. if(i > 0) str = str.Left(i);
  54. int nStartChar = 0, nEndChar = -1;
  55. GetSel(nStartChar, nEndChar);
  56. CString text;
  57. GetWindowText(text);
  58. while(nStartChar > 0 && _istalnum(text.GetAt(nStartChar-1)))
  59. nStartChar--;
  60. SetSel(nStartChar, nEndChar);
  61. ReplaceSel(str, TRUE);
  62. }
  63. else if(pMsg->wParam == VK_ESCAPE)
  64. {
  65. m_acdlg.ShowWindow(SW_HIDE);
  66. }
  67. else
  68. {
  69. m_acdlg.m_list.SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
  70. }
  71. return TRUE;
  72. }
  73. return __super::PreTranslateMessage(pMsg);
  74. }
  75. BEGIN_MESSAGE_MAP(CShaderEdit, CLineNumberEdit)
  76. ON_CONTROL_REFLECT(EN_UPDATE, OnUpdate)
  77. ON_WM_KILLFOCUS()
  78. ON_WM_TIMER()
  79. END_MESSAGE_MAP()
  80. void CShaderEdit::OnUpdate()
  81. {
  82. if(m_nIDEvent == -1)
  83. {
  84. m_nIDEvent = SetTimer(1, 100, NULL); 
  85. }
  86. CString text;
  87. int nStartChar = 0, nEndChar = -1;
  88. GetSel(nStartChar, nEndChar);
  89. if(nStartChar == nEndChar)
  90. {
  91. GetWindowText(text);
  92. while(nStartChar > 0 && _istalnum(text.GetAt(nStartChar-1)))
  93. nStartChar--;
  94. }
  95. if(nStartChar < nEndChar)
  96. {
  97. text = text.Mid(nStartChar, nEndChar - nStartChar);
  98. text.TrimRight('(');
  99. text.MakeLower();
  100. m_acdlg.m_list.ResetContent();
  101. CString key, value;
  102. POSITION pos = m_acdlg.m_inst.GetStartPosition();
  103. while(pos)
  104. {
  105. POSITION cur = pos;
  106. m_acdlg.m_inst.GetNextAssoc(pos, key, value);
  107. if(key.Find(text) == 0)
  108. {
  109. CList<CString> sl;
  110. Explode(value, sl, '|', 2);
  111. if(sl.GetCount() != 2) continue;
  112. CString name = sl.RemoveHead();
  113. CString description = sl.RemoveHead();
  114. int i = m_acdlg.m_list.AddString(name);
  115. m_acdlg.m_list.SetItemDataPtr(i, cur);
  116. }
  117. }
  118. if(m_acdlg.m_list.GetCount() > 0)
  119. {
  120. int lineheight = GetLineHeight();
  121. CPoint p = PosFromChar(nStartChar);
  122. p.y += lineheight;
  123. ClientToScreen(&p);
  124. CRect r(p, CSize(100, 100));
  125. m_acdlg.MoveWindow(r);
  126. m_acdlg.SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
  127. m_acdlg.ShowWindow(SW_SHOWNOACTIVATE);
  128. m_nEndChar = nEndChar;
  129. return;
  130. }
  131. }
  132. m_acdlg.ShowWindow(SW_HIDE);
  133. }
  134. void CShaderEdit::OnKillFocus(CWnd* pNewWnd)
  135. {
  136. CString text;
  137. GetWindowText(text);
  138. __super::OnKillFocus(pNewWnd);
  139. GetWindowText(text);
  140. m_acdlg.ShowWindow(SW_HIDE);
  141. }
  142. void CShaderEdit::OnTimer(UINT nIDEvent)
  143. {
  144. if(m_nIDEvent == nIDEvent)
  145. {
  146. int nStartChar = 0, nEndChar = -1;
  147. GetSel(nStartChar, nEndChar);
  148. if(nStartChar != nEndChar || m_nEndChar != nEndChar)
  149. m_acdlg.ShowWindow(SW_HIDE);
  150. }
  151. __super::OnTimer(nIDEvent);
  152. }
  153. // CShaderEditorDlg dialog
  154. CShaderEditorDlg::CShaderEditorDlg(CString label, ISubPicAllocatorPresenter* pCAP, CWnd* pParent /*=NULL*/)
  155. : CResizableDialog(CShaderEditorDlg::IDD, pParent)
  156. , m_label(label)
  157. , m_pCAP(pCAP)
  158. , m_fSplitterGrabbed(false)
  159. {
  160. m_pPSC = new CPixelShaderCompiler(NULL);
  161. }
  162. CShaderEditorDlg::~CShaderEditorDlg()
  163. {
  164. delete m_pPSC;
  165. }
  166. void CShaderEditorDlg::DoDataExchange(CDataExchange* pDX)
  167. {
  168. __super::DoDataExchange(pDX);
  169. DDX_Control(pDX, IDC_COMBO1, m_labels);
  170. DDX_Control(pDX, IDC_COMBO2, m_targets);
  171. DDX_Control(pDX, IDC_EDIT1, m_srcdata);
  172. DDX_Control(pDX, IDC_EDIT2, m_output);
  173. }
  174. bool CShaderEditorDlg::HitTestSplitter(CPoint p)
  175. {
  176. CRect r, rs, ro;
  177. m_srcdata.GetWindowRect(&rs);
  178. m_output.GetWindowRect(&ro);
  179. ScreenToClient(&rs);
  180. ScreenToClient(&ro);
  181. GetClientRect(&r);
  182. r.left = ro.left;
  183. r.right = ro.right;
  184. r.top = rs.bottom;
  185. r.bottom = ro.top;
  186. return !!r.PtInRect(p);
  187. }
  188. BEGIN_MESSAGE_MAP(CShaderEditorDlg, CResizableDialog)
  189. ON_CBN_SELCHANGE(IDC_COMBO1, OnCbnSelchangeCombo1)
  190. ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
  191. ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)
  192. ON_WM_TIMER()
  193. ON_WM_CLOSE()
  194. ON_WM_LBUTTONDOWN()
  195. ON_WM_LBUTTONUP()
  196. ON_WM_MOUSEMOVE()
  197. ON_WM_SETCURSOR()
  198. END_MESSAGE_MAP()
  199. // CShaderEditorDlg message handlers
  200. BOOL CShaderEditorDlg::OnInitDialog()
  201. {
  202. __super::OnInitDialog();
  203. AddAnchor(IDC_COMBO1, TOP_LEFT, TOP_RIGHT);
  204. AddAnchor(IDC_COMBO2, TOP_RIGHT);
  205. AddAnchor(IDC_BUTTON1, TOP_RIGHT);
  206. AddAnchor(IDC_BUTTON2, TOP_RIGHT);
  207. AddAnchor(IDC_EDIT1, TOP_LEFT, BOTTOM_RIGHT);
  208. AddAnchor(IDC_EDIT2, BOTTOM_LEFT, BOTTOM_RIGHT);
  209. m_srcdata.SetTabStops(16);
  210. CRect r;
  211. GetWindowRect(r);
  212. CSize s = r.Size();
  213. s.cx = 400;
  214. s.cy = 150;
  215. SetMinTrackSize(s);
  216. CMap<CString, LPCTSTR, bool, bool> targetmap;
  217. targetmap[_T("ps_1_1")] = true;
  218. targetmap[_T("ps_1_2")] = true;
  219. targetmap[_T("ps_1_3")] = true;
  220. targetmap[_T("ps_1_4")] = true;
  221. targetmap[_T("ps_2_0")] = true;
  222. targetmap[_T("ps_2_a")] = true;
  223. targetmap[_T("ps_2_sw")] = true;
  224. targetmap[_T("ps_3_0")] = true;
  225. targetmap[_T("ps_3_sw")] = true;
  226. int nSelIndex = -1;
  227. for(int i = 0; ; i++)
  228. {
  229. CString str;
  230. str.Format(_T("%d"), i);
  231. str = AfxGetApp()->GetProfileString(_T("Shaders"), str);
  232. CList<CString> sl;
  233. Explode(str, sl, '|', 3);
  234. if(sl.GetCount() != 3) break;
  235. CString label = sl.RemoveHead();
  236. CString target = sl.RemoveHead();
  237. CString srcdata = sl.RemoveHead();
  238. srcdata.Replace(_T("\n"), _T("rn"));
  239. srcdata.Replace(_T("\t"), _T("t"));
  240. targetmap[target] = false;
  241. shader_t s = {target, srcdata};
  242. m_shaders[label] = s;
  243. int nIndex = m_labels.AddString(label);
  244. if(m_label == label) 
  245. nSelIndex = nIndex;
  246. }
  247. m_labels.SetCurSel(nSelIndex);
  248. POSITION pos = targetmap.GetStartPosition();
  249. while(pos) 
  250. {
  251. CString target;
  252. bool b;
  253. targetmap.GetNextAssoc(pos, target, b);
  254. m_targets.AddString(target);
  255. }
  256. OnCbnSelchangeCombo1();
  257. m_nIDEventShader = SetTimer(1, 1000, NULL);
  258. return TRUE;  // return TRUE unless you set the focus to a control
  259. // EXCEPTION: OCX Property Pages should return FALSE
  260. }
  261. BOOL CShaderEditorDlg::PreTranslateMessage(MSG* pMsg)
  262. {
  263. if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN
  264. && pMsg->hwnd == m_labels.m_edit.GetSafeHwnd())
  265. {
  266. CString label;
  267. m_labels.GetWindowText(label);
  268. shader_t s;
  269. m_labels.SetCurSel(!m_shaders.Lookup(label, s) 
  270. ? m_labels.AddString(label) 
  271. : m_labels.FindStringExact(0, label));
  272. OnCbnSelchangeCombo1();
  273.         
  274. return TRUE;
  275. }
  276. else if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB
  277. && pMsg->hwnd == m_srcdata.GetSafeHwnd())
  278. {
  279. int nStartChar, nEndChar;
  280. m_srcdata.GetSel(nStartChar, nEndChar);
  281. if(nStartChar == nEndChar)
  282.             m_srcdata.ReplaceSel(_T("t"));
  283. return TRUE;
  284. }
  285. else if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
  286. {
  287. return TRUE;
  288. }
  289. return __super::PreTranslateMessage(pMsg);
  290. }
  291. void CShaderEditorDlg::OnCbnSelchangeCombo1()
  292. {
  293. int i = m_labels.GetCurSel();
  294. if(i < 0) return;
  295. CString label;
  296. m_labels.GetLBText(i, label);
  297. if(label.IsEmpty()) return;
  298. shader_t s;
  299. if(!m_shaders.Lookup(label, s))
  300. {
  301. s.target = _T("ps_2_0");
  302. s.srcdata = 
  303.             "sampler s0 : register(s0);rn"
  304. "float4 p0 : register(c0);rn"
  305.             "rn"
  306. "#define width (p0[0])rn"
  307. "#define height (p0[1])rn"
  308. "#define counter (p0[2])rn"
  309.             "#define clock (p0[3])rn"
  310. "rn"
  311. "float4 main(float2 tex : TEXCOORD0) : COLORrn"
  312. "{rn"
  313. "tfloat4 c0 = tex2D(s0, tex);rn"
  314. "t// TODOrn"
  315. "treturn c0;rn"
  316. "}rn";
  317. m_shaders[label] = s;
  318. }
  319. if(m_shaders.Lookup(label, s))
  320. {
  321. m_targets.SetWindowText(s.target);
  322. m_srcdata.SetWindowText(s.srcdata);
  323. }
  324. }
  325. void CShaderEditorDlg::OnBnClickedButton1()
  326. {
  327. CString label;
  328. m_labels.GetWindowText(label);
  329. int nIndex = m_labels.FindStringExact(0, label);
  330. if(nIndex >= 0) m_labels.DeleteString(nIndex);
  331. m_labels.SetWindowText(_T(""));
  332. m_targets.SetWindowText(_T(""));
  333. m_srcdata.SetWindowText(_T(""));
  334. m_shaders.RemoveKey(label);
  335. }
  336. void CShaderEditorDlg::OnBnClickedButton2()
  337. {
  338. CString label;
  339. m_labels.GetWindowText(label);
  340. m_targets.GetWindowText(m_shaders[label].target);
  341. m_srcdata.GetWindowText(m_shaders[label].srcdata);
  342. if(m_labels.FindStringExact(0, label) < 0)
  343. m_labels.SetCurSel(m_labels.AddString(label));
  344. }
  345. void CShaderEditorDlg::OnTimer(UINT nIDEvent)
  346. {
  347. if(nIDEvent == m_nIDEventShader)
  348. {
  349. static CString s_srcdata, s_target;
  350. CString srcdata;
  351. m_srcdata.GetWindowText(srcdata);
  352. srcdata.Trim();
  353. CString target;
  354. m_targets.GetWindowText(target);
  355. target.Trim();
  356. if(!srcdata.IsEmpty() && !target.IsEmpty() && (s_srcdata != srcdata || s_target != target))
  357. {
  358. CString disasm, errmsg(_T("Unknown Error"));
  359. HRESULT hr = m_pPSC->CompileShader(CStringA(srcdata), "main", CStringA(target), D3DXSHADER_DEBUG, NULL, &disasm, &errmsg); 
  360. if(SUCCEEDED(hr))
  361. {
  362. errmsg = _T("D3DXCompileShader succeededn");
  363. if(m_pCAP && FAILED(m_pCAP->SetPixelShader(CStringA(srcdata), CStringA(target))))
  364. errmsg += _T("SetPixelShader failedn");
  365. errmsg += _T("n");
  366. errmsg += disasm;
  367. }
  368. errmsg.Replace(_T("n"), _T("rn"));
  369. m_output.SetWindowText(errmsg);
  370. }
  371. s_srcdata = srcdata;
  372. s_target = target;
  373. }
  374. __super::OnTimer(nIDEvent);
  375. }
  376. void CShaderEditorDlg::OnClose()
  377. {
  378. if(IDYES == AfxMessageBox(_T("Save changes?"), MB_YESNO))
  379. {
  380. OnBnClickedButton2();
  381. CWinApp* pApp = AfxGetApp();
  382. pApp->WriteProfileString(_T("Shaders"), NULL, NULL);
  383. pApp->WriteProfileInt(_T("Shaders"), _T("Initialized"), 1);
  384. for(int i = 0, id = 0; i < m_labels.GetCount(); i++)
  385. {
  386. CString label;
  387. m_labels.GetLBText(i, label);
  388. shader_t s;
  389. if(!label.IsEmpty() && m_shaders.Lookup(label, s))
  390. {
  391. CString str;
  392. str.Format(_T("%d"), id++);
  393. s.srcdata.Replace(_T("r"), _T(""));
  394. s.srcdata.Replace(_T("n"), _T("\n"));
  395. s.srcdata.Replace(_T("t"), _T("\t"));
  396. AfxGetApp()->WriteProfileString(_T("Shaders"), str, label + _T("|") + s.target + _T("|") + s.srcdata);
  397. }
  398. }
  399. }
  400. __super::OnClose();
  401. }
  402. void CShaderEditorDlg::OnLButtonDown(UINT nFlags, CPoint point)
  403. {
  404. if(HitTestSplitter(point))
  405. {
  406. m_fSplitterGrabbed = true;
  407. SetCapture();
  408. }
  409. __super::OnLButtonDown(nFlags, point);
  410. }
  411. void CShaderEditorDlg::OnLButtonUp(UINT nFlags, CPoint point)
  412. {
  413. if(m_fSplitterGrabbed)
  414. {
  415. ReleaseCapture();
  416. m_fSplitterGrabbed = false;
  417. }
  418. __super::OnLButtonUp(nFlags, point);
  419. }
  420. void CShaderEditorDlg::OnMouseMove(UINT nFlags, CPoint point)
  421. {
  422. if(m_fSplitterGrabbed)
  423. {
  424. CRect r, rs, ro;
  425. GetClientRect(&r);
  426. m_srcdata.GetWindowRect(&rs);
  427. m_output.GetWindowRect(&ro);
  428. ScreenToClient(&rs);
  429. ScreenToClient(&ro);
  430. int dist = ro.top - rs.bottom;
  431. int avgdist = dist / 2;
  432. rs.bottom = min(max(point.y, rs.top + 40), ro.bottom - 40) - avgdist;
  433. ro.top = rs.bottom + dist;
  434. m_srcdata.MoveWindow(&rs);
  435. m_output.MoveWindow(&ro);
  436. int div = 100 * ((rs.bottom + ro.top) / 2) / (ro.bottom - rs.top);
  437. RemoveAnchor(IDC_EDIT1);
  438. RemoveAnchor(IDC_EDIT2);
  439. AddAnchor(IDC_EDIT1, TOP_LEFT, CSize(100, div)/*BOTTOM_RIGHT*/);
  440. AddAnchor(IDC_EDIT2, CSize(0, div)/*BOTTOM_LEFT*/, BOTTOM_RIGHT);
  441. }
  442. __super::OnMouseMove(nFlags, point);
  443. }
  444. BOOL CShaderEditorDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  445. {
  446. CPoint p;
  447. GetCursorPos(&p);
  448. ScreenToClient(&p);
  449. if(HitTestSplitter(p))
  450. {
  451. ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS));
  452. return TRUE;
  453. }
  454. return __super::OnSetCursor(pWnd, nHitTest, message);
  455. }