ShaderEditorDlg.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:13k
- // ShaderEditorDlg.cpp : implementation file
- //
- #include "stdafx.h"
- #include "mplayerc.h"
- #include "PixelShaderCompiler.h"
- #include "ShaderEditorDlg.h"
- #undef SubclassWindow
- // CShaderLabelComboBox
- BEGIN_MESSAGE_MAP(CShaderLabelComboBox, CComboBox)
- ON_WM_CTLCOLOR()
- ON_WM_DESTROY()
- END_MESSAGE_MAP()
- HBRUSH CShaderLabelComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
- {
- if(nCtlColor == CTLCOLOR_EDIT)
- {
- if(m_edit.GetSafeHwnd() == NULL)
- m_edit.SubclassWindow(pWnd->GetSafeHwnd());
- }
- return __super::OnCtlColor(pDC, pWnd, nCtlColor);
- }
- void CShaderLabelComboBox::OnDestroy()
- {
- if(m_edit.GetSafeHwnd() != NULL)
- m_edit.UnsubclassWindow();
- __super::OnDestroy();
- }
- // CShaderEdit
- CShaderEdit::CShaderEdit()
- {
- m_acdlg.Create(CShaderAutoCompleteDlg::IDD, NULL);
- m_nEndChar = -1;
- m_nIDEvent = -1;
- }
- CShaderEdit::~CShaderEdit()
- {
- m_acdlg.DestroyWindow();
- }
- BOOL CShaderEdit::PreTranslateMessage(MSG* pMsg)
- {
- if(m_acdlg.IsWindowVisible()
- && pMsg->message == WM_KEYDOWN
- && (pMsg->wParam == VK_UP || pMsg->wParam == VK_DOWN
- || pMsg->wParam == VK_PRIOR || pMsg->wParam == VK_NEXT
- || pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE))
- {
- int i = m_acdlg.m_list.GetCurSel();
- if(pMsg->wParam == VK_RETURN && i >= 0)
- {
- CString str;
- m_acdlg.m_list.GetText(i, str);
- i = str.Find('(')+1;
- if(i > 0) str = str.Left(i);
-
- int nStartChar = 0, nEndChar = -1;
- GetSel(nStartChar, nEndChar);
- CString text;
- GetWindowText(text);
- while(nStartChar > 0 && _istalnum(text.GetAt(nStartChar-1)))
- nStartChar--;
- SetSel(nStartChar, nEndChar);
- ReplaceSel(str, TRUE);
- }
- else if(pMsg->wParam == VK_ESCAPE)
- {
- m_acdlg.ShowWindow(SW_HIDE);
- }
- else
- {
- m_acdlg.m_list.SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
- }
- return TRUE;
- }
- return __super::PreTranslateMessage(pMsg);
- }
- BEGIN_MESSAGE_MAP(CShaderEdit, CLineNumberEdit)
- ON_CONTROL_REFLECT(EN_UPDATE, OnUpdate)
- ON_WM_KILLFOCUS()
- ON_WM_TIMER()
- END_MESSAGE_MAP()
- void CShaderEdit::OnUpdate()
- {
- if(m_nIDEvent == -1)
- {
- m_nIDEvent = SetTimer(1, 100, NULL);
- }
- CString text;
- int nStartChar = 0, nEndChar = -1;
- GetSel(nStartChar, nEndChar);
- if(nStartChar == nEndChar)
- {
- GetWindowText(text);
- while(nStartChar > 0 && _istalnum(text.GetAt(nStartChar-1)))
- nStartChar--;
- }
- if(nStartChar < nEndChar)
- {
- text = text.Mid(nStartChar, nEndChar - nStartChar);
- text.TrimRight('(');
- text.MakeLower();
- m_acdlg.m_list.ResetContent();
- CString key, value;
- POSITION pos = m_acdlg.m_inst.GetStartPosition();
- while(pos)
- {
- POSITION cur = pos;
- m_acdlg.m_inst.GetNextAssoc(pos, key, value);
- if(key.Find(text) == 0)
- {
- CList<CString> sl;
- Explode(value, sl, '|', 2);
- if(sl.GetCount() != 2) continue;
- CString name = sl.RemoveHead();
- CString description = sl.RemoveHead();
- int i = m_acdlg.m_list.AddString(name);
- m_acdlg.m_list.SetItemDataPtr(i, cur);
- }
- }
- if(m_acdlg.m_list.GetCount() > 0)
- {
- int lineheight = GetLineHeight();
- CPoint p = PosFromChar(nStartChar);
- p.y += lineheight;
- ClientToScreen(&p);
- CRect r(p, CSize(100, 100));
- m_acdlg.MoveWindow(r);
- m_acdlg.SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
- m_acdlg.ShowWindow(SW_SHOWNOACTIVATE);
- m_nEndChar = nEndChar;
- return;
- }
- }
- m_acdlg.ShowWindow(SW_HIDE);
- }
- void CShaderEdit::OnKillFocus(CWnd* pNewWnd)
- {
- CString text;
- GetWindowText(text);
- __super::OnKillFocus(pNewWnd);
- GetWindowText(text);
- m_acdlg.ShowWindow(SW_HIDE);
- }
- void CShaderEdit::OnTimer(UINT nIDEvent)
- {
- if(m_nIDEvent == nIDEvent)
- {
- int nStartChar = 0, nEndChar = -1;
- GetSel(nStartChar, nEndChar);
- if(nStartChar != nEndChar || m_nEndChar != nEndChar)
- m_acdlg.ShowWindow(SW_HIDE);
- }
- __super::OnTimer(nIDEvent);
- }
- // CShaderEditorDlg dialog
- CShaderEditorDlg::CShaderEditorDlg(CString label, ISubPicAllocatorPresenter* pCAP, CWnd* pParent /*=NULL*/)
- : CResizableDialog(CShaderEditorDlg::IDD, pParent)
- , m_label(label)
- , m_pCAP(pCAP)
- , m_fSplitterGrabbed(false)
- {
- m_pPSC = new CPixelShaderCompiler(NULL);
- }
- CShaderEditorDlg::~CShaderEditorDlg()
- {
- delete m_pPSC;
- }
- void CShaderEditorDlg::DoDataExchange(CDataExchange* pDX)
- {
- __super::DoDataExchange(pDX);
- DDX_Control(pDX, IDC_COMBO1, m_labels);
- DDX_Control(pDX, IDC_COMBO2, m_targets);
- DDX_Control(pDX, IDC_EDIT1, m_srcdata);
- DDX_Control(pDX, IDC_EDIT2, m_output);
- }
- bool CShaderEditorDlg::HitTestSplitter(CPoint p)
- {
- CRect r, rs, ro;
- m_srcdata.GetWindowRect(&rs);
- m_output.GetWindowRect(&ro);
- ScreenToClient(&rs);
- ScreenToClient(&ro);
- GetClientRect(&r);
- r.left = ro.left;
- r.right = ro.right;
- r.top = rs.bottom;
- r.bottom = ro.top;
- return !!r.PtInRect(p);
- }
- BEGIN_MESSAGE_MAP(CShaderEditorDlg, CResizableDialog)
- ON_CBN_SELCHANGE(IDC_COMBO1, OnCbnSelchangeCombo1)
- ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
- ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)
- ON_WM_TIMER()
- ON_WM_CLOSE()
- ON_WM_LBUTTONDOWN()
- ON_WM_LBUTTONUP()
- ON_WM_MOUSEMOVE()
- ON_WM_SETCURSOR()
- END_MESSAGE_MAP()
- // CShaderEditorDlg message handlers
- BOOL CShaderEditorDlg::OnInitDialog()
- {
- __super::OnInitDialog();
- AddAnchor(IDC_COMBO1, TOP_LEFT, TOP_RIGHT);
- AddAnchor(IDC_COMBO2, TOP_RIGHT);
- AddAnchor(IDC_BUTTON1, TOP_RIGHT);
- AddAnchor(IDC_BUTTON2, TOP_RIGHT);
- AddAnchor(IDC_EDIT1, TOP_LEFT, BOTTOM_RIGHT);
- AddAnchor(IDC_EDIT2, BOTTOM_LEFT, BOTTOM_RIGHT);
- m_srcdata.SetTabStops(16);
- CRect r;
- GetWindowRect(r);
- CSize s = r.Size();
- s.cx = 400;
- s.cy = 150;
- SetMinTrackSize(s);
- CMap<CString, LPCTSTR, bool, bool> targetmap;
- targetmap[_T("ps_1_1")] = true;
- targetmap[_T("ps_1_2")] = true;
- targetmap[_T("ps_1_3")] = true;
- targetmap[_T("ps_1_4")] = true;
- targetmap[_T("ps_2_0")] = true;
- targetmap[_T("ps_2_a")] = true;
- targetmap[_T("ps_2_sw")] = true;
- targetmap[_T("ps_3_0")] = true;
- targetmap[_T("ps_3_sw")] = true;
- int nSelIndex = -1;
- for(int i = 0; ; i++)
- {
- CString str;
- str.Format(_T("%d"), i);
- str = AfxGetApp()->GetProfileString(_T("Shaders"), str);
- CList<CString> sl;
- Explode(str, sl, '|', 3);
- if(sl.GetCount() != 3) break;
- CString label = sl.RemoveHead();
- CString target = sl.RemoveHead();
- CString srcdata = sl.RemoveHead();
- srcdata.Replace(_T("\n"), _T("rn"));
- srcdata.Replace(_T("\t"), _T("t"));
- targetmap[target] = false;
- shader_t s = {target, srcdata};
- m_shaders[label] = s;
- int nIndex = m_labels.AddString(label);
- if(m_label == label)
- nSelIndex = nIndex;
- }
- m_labels.SetCurSel(nSelIndex);
- POSITION pos = targetmap.GetStartPosition();
- while(pos)
- {
- CString target;
- bool b;
- targetmap.GetNextAssoc(pos, target, b);
- m_targets.AddString(target);
- }
- OnCbnSelchangeCombo1();
- m_nIDEventShader = SetTimer(1, 1000, NULL);
- return TRUE; // return TRUE unless you set the focus to a control
- // EXCEPTION: OCX Property Pages should return FALSE
- }
- BOOL CShaderEditorDlg::PreTranslateMessage(MSG* pMsg)
- {
- if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN
- && pMsg->hwnd == m_labels.m_edit.GetSafeHwnd())
- {
- CString label;
- m_labels.GetWindowText(label);
- shader_t s;
- m_labels.SetCurSel(!m_shaders.Lookup(label, s)
- ? m_labels.AddString(label)
- : m_labels.FindStringExact(0, label));
- OnCbnSelchangeCombo1();
-
- return TRUE;
- }
- else if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB
- && pMsg->hwnd == m_srcdata.GetSafeHwnd())
- {
- int nStartChar, nEndChar;
- m_srcdata.GetSel(nStartChar, nEndChar);
- if(nStartChar == nEndChar)
- m_srcdata.ReplaceSel(_T("t"));
- return TRUE;
- }
- else if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
- {
- return TRUE;
- }
- return __super::PreTranslateMessage(pMsg);
- }
- void CShaderEditorDlg::OnCbnSelchangeCombo1()
- {
- int i = m_labels.GetCurSel();
- if(i < 0) return;
- CString label;
- m_labels.GetLBText(i, label);
- if(label.IsEmpty()) return;
- shader_t s;
- if(!m_shaders.Lookup(label, s))
- {
- s.target = _T("ps_2_0");
- s.srcdata =
- "sampler s0 : register(s0);rn"
- "float4 p0 : register(c0);rn"
- "rn"
- "#define width (p0[0])rn"
- "#define height (p0[1])rn"
- "#define counter (p0[2])rn"
- "#define clock (p0[3])rn"
- "rn"
- "float4 main(float2 tex : TEXCOORD0) : COLORrn"
- "{rn"
- "tfloat4 c0 = tex2D(s0, tex);rn"
- "t// TODOrn"
- "treturn c0;rn"
- "}rn";
- m_shaders[label] = s;
- }
- if(m_shaders.Lookup(label, s))
- {
- m_targets.SetWindowText(s.target);
- m_srcdata.SetWindowText(s.srcdata);
- }
- }
- void CShaderEditorDlg::OnBnClickedButton1()
- {
- CString label;
- m_labels.GetWindowText(label);
- int nIndex = m_labels.FindStringExact(0, label);
- if(nIndex >= 0) m_labels.DeleteString(nIndex);
- m_labels.SetWindowText(_T(""));
- m_targets.SetWindowText(_T(""));
- m_srcdata.SetWindowText(_T(""));
- m_shaders.RemoveKey(label);
- }
- void CShaderEditorDlg::OnBnClickedButton2()
- {
- CString label;
- m_labels.GetWindowText(label);
- m_targets.GetWindowText(m_shaders[label].target);
- m_srcdata.GetWindowText(m_shaders[label].srcdata);
- if(m_labels.FindStringExact(0, label) < 0)
- m_labels.SetCurSel(m_labels.AddString(label));
- }
- void CShaderEditorDlg::OnTimer(UINT nIDEvent)
- {
- if(nIDEvent == m_nIDEventShader)
- {
- static CString s_srcdata, s_target;
-
- CString srcdata;
- m_srcdata.GetWindowText(srcdata);
- srcdata.Trim();
- CString target;
- m_targets.GetWindowText(target);
- target.Trim();
- if(!srcdata.IsEmpty() && !target.IsEmpty() && (s_srcdata != srcdata || s_target != target))
- {
- CString disasm, errmsg(_T("Unknown Error"));
- HRESULT hr = m_pPSC->CompileShader(CStringA(srcdata), "main", CStringA(target), D3DXSHADER_DEBUG, NULL, &disasm, &errmsg);
- if(SUCCEEDED(hr))
- {
- errmsg = _T("D3DXCompileShader succeededn");
- if(m_pCAP && FAILED(m_pCAP->SetPixelShader(CStringA(srcdata), CStringA(target))))
- errmsg += _T("SetPixelShader failedn");
- errmsg += _T("n");
- errmsg += disasm;
- }
- errmsg.Replace(_T("n"), _T("rn"));
- m_output.SetWindowText(errmsg);
- }
- s_srcdata = srcdata;
- s_target = target;
- }
- __super::OnTimer(nIDEvent);
- }
- void CShaderEditorDlg::OnClose()
- {
- if(IDYES == AfxMessageBox(_T("Save changes?"), MB_YESNO))
- {
- OnBnClickedButton2();
- CWinApp* pApp = AfxGetApp();
- pApp->WriteProfileString(_T("Shaders"), NULL, NULL);
- pApp->WriteProfileInt(_T("Shaders"), _T("Initialized"), 1);
- for(int i = 0, id = 0; i < m_labels.GetCount(); i++)
- {
- CString label;
- m_labels.GetLBText(i, label);
- shader_t s;
- if(!label.IsEmpty() && m_shaders.Lookup(label, s))
- {
- CString str;
- str.Format(_T("%d"), id++);
- s.srcdata.Replace(_T("r"), _T(""));
- s.srcdata.Replace(_T("n"), _T("\n"));
- s.srcdata.Replace(_T("t"), _T("\t"));
- AfxGetApp()->WriteProfileString(_T("Shaders"), str, label + _T("|") + s.target + _T("|") + s.srcdata);
- }
- }
- }
- __super::OnClose();
- }
- void CShaderEditorDlg::OnLButtonDown(UINT nFlags, CPoint point)
- {
- if(HitTestSplitter(point))
- {
- m_fSplitterGrabbed = true;
- SetCapture();
- }
-
- __super::OnLButtonDown(nFlags, point);
- }
- void CShaderEditorDlg::OnLButtonUp(UINT nFlags, CPoint point)
- {
- if(m_fSplitterGrabbed)
- {
- ReleaseCapture();
- m_fSplitterGrabbed = false;
- }
- __super::OnLButtonUp(nFlags, point);
- }
- void CShaderEditorDlg::OnMouseMove(UINT nFlags, CPoint point)
- {
- if(m_fSplitterGrabbed)
- {
- CRect r, rs, ro;
- GetClientRect(&r);
- m_srcdata.GetWindowRect(&rs);
- m_output.GetWindowRect(&ro);
- ScreenToClient(&rs);
- ScreenToClient(&ro);
- int dist = ro.top - rs.bottom;
- int avgdist = dist / 2;
- rs.bottom = min(max(point.y, rs.top + 40), ro.bottom - 40) - avgdist;
- ro.top = rs.bottom + dist;
- m_srcdata.MoveWindow(&rs);
- m_output.MoveWindow(&ro);
- int div = 100 * ((rs.bottom + ro.top) / 2) / (ro.bottom - rs.top);
- RemoveAnchor(IDC_EDIT1);
- RemoveAnchor(IDC_EDIT2);
- AddAnchor(IDC_EDIT1, TOP_LEFT, CSize(100, div)/*BOTTOM_RIGHT*/);
- AddAnchor(IDC_EDIT2, CSize(0, div)/*BOTTOM_LEFT*/, BOTTOM_RIGHT);
- }
- __super::OnMouseMove(nFlags, point);
- }
- BOOL CShaderEditorDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
- {
- CPoint p;
- GetCursorPos(&p);
- ScreenToClient(&p);
- if(HitTestSplitter(p))
- {
- ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS));
- return TRUE;
- }
- return __super::OnSetCursor(pWnd, nHitTest, message);
- }