扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
前些日子写了一个基于DrawDib视频函数库的Render,虽然显示图片速度非常快,但是还是难以满足一些交互式的实时显示.而且在放大缩小的时候,无法设置反锯齿功能(antialias). 本来不想用Directx的,看来现在还是逃不过. 我很讨厌用接口经常变动的东西,更讨厌需要安装支持动态链接库的东东, directx就是这样的东西,direct1到现在的directx9,每一次新接口都会变动,当然老的接口还是可以用的,但是出来相应的SDK文档却没有老接口的调用方法。没办法,down了个Directx9硬着头皮学学。
研究了一下午再加一晚上的SDK文档, 脑子里差不多有Render的框架了,大致如下:
class MMD3DRender
{
protected:
IDirect3D9* m_pD3D;
IDirect3DDevice9* m_pDev;
IDirect3DSurface9* m_pSuf;
……
//作一些Direct3D9的初始化工作
bool Init( HWND);
// 把Buffer里面的东西送到Surface上去(m_pSuf)
void Draw( BYTE* pBuffer,int iStep, LPRECT lpRc);
// WM_PAINT 消息处理
void Paint();
// 释放资源,退出的善后工作
void Destroy();
};
按道理调用这个Render很简单,只要在某个Window对象的WM_CREATE消息响应函数里面调用
Init( pWnd->GetSafeHwnd())
然后其WM_PAINT函数里加
ValidateRect(NULL);
render.Paint();
就OK了。
于是我就建立了一个MFC单视图结构(没有文档(CDocument)),往里面的CChildView插
加了OnCreate,OnPaint消息处理函数,并插入了上面的代码,可是运行并没有成功,是Init出了问题:
bool MMD3DRender::Init( HWND hWnd)
{
ASSERT(::IsWindow(hWnd));
m_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
if( !m_pD3D)
return false;
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.hDeviceWindow = hWnd;
HRESULT hr;
if( FAILED(hr = m_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING,&d3dpp,&m_pDev)))
{
SAFE_RELEASE(m_pD3D);
AfxMessageBox( DXGetErrorDescription9(hr));
return false;
}
return true;
}
上面的代码几乎和SDK文档中Tutorial里面的一模一样,可是我的程序每次到CreateDevice就Fail掉了,郁闷了半天也找不到原因,运行SDK中的例子程序却好好的,后来再SDK中看到这么一句话:
This method should not be run during the handling of WM_CREATE. An application should never pass a window handle to Direct3D while handling WM_CREATE. Any call to create, release, or reset the device must be done using the same thread as the window procedure of the focus window.
考!我一看晕倒,还有这么bt的限制啊,我就把Init代码移到了View的父窗口CMainFrame的OnCreate函数中,再创建View之后紧接着Init。
if( !m_wndView.Create(…))
…
g_render.Init(m_wnd.GetSafeHwnd());
这样总行了吧,考,运行之后还是错误!我又把上面改成
g_render.Init(this->GetSafeHwnd());
就是把CMainFrame的句柄传入,结果成功运行了,整个窗口被按照期望涂成了黑色,只是顺便把工具条什么的都一块涂掉了,呵呵。
想了半天,不知道什么原因,为什么CMainFrame可以,而且是在其WM_CREATE处理函数中出入句柄的,这个还是是SDK所禁止的。会不会和窗口的初始大小有关呢?我注意到m_wndView的创建函数是把其设成CRect(0,0,0,0)的,把它改成:
if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0, 0,100, 100), this, AFX_IDW_PANE_FIRST, NULL))
ft,一运行居然OK了~将 Init放回View的OnCreate处理函数中,也顺利运行了。
看来SDK里面写的东东也不能全信,应该改成:
Direct3D9 创建Device时依赖的窗口初始大小不能为0
濠电姷鏁告慨鐑姐€傛禒瀣劦妞ゆ巻鍋撻柛鐔锋健閸┾偓妞ゆ巻鍋撶紓宥咃躬楠炲啫螣鐠囪尙绐為梺褰掑亰閸撴盯鎮惧ú顏呪拺闂傚牊鍗曢崼銉ョ柧婵犲﹤瀚崣蹇旂節婵犲倻澧涢柛瀣ㄥ妽閵囧嫰寮介妸褋鈧帡鏌熼挊澶婃殻闁哄瞼鍠栭幃婊堝煛閸屾稓褰嬮柣搴ゎ潐濞叉ê鐣濈粙璺ㄦ殾闁割偅娲栭悡娑㈡煕鐏炲墽鐭嬫繛鍫熸倐濮婄粯鎷呯粵瀣異闂佹悶鍔嬮崡鍐茬暦閵忋倕鍐€妞ゆ劑鍎卞皬闂備焦瀵х粙鎴犫偓姘煎弮瀹曚即宕卞Ο闀愮盎闂侀潧鐗嗛幊搴㈡叏椤掆偓閳规垿鍩ラ崱妞剧凹濠电姰鍨洪敋閾荤偞淇婇妶鍛櫤闁稿鍊圭换娑㈠幢濡纰嶉柣搴㈣壘椤︾敻寮诲鍫闂佸憡鎸鹃崰搴敋閿濆鏁嗗〒姘功閻绻涢幘鏉戠劰闁稿鎹囬弻锝呪槈濞嗘劕纾抽梺鍝勬湰缁嬫垿鍩為幋锕€宸濇い鏇炴噺閳诲﹦绱撻崒娆戝妽妞ゃ劌鎳橀幆宀勫磼閻愰潧绁﹂柟鍏肩暘閸斿矂鎮為崹顐犱簻闁圭儤鍨甸鈺呮倵濮橆剦妲归柕鍥у瀵粙濡歌閸c儳绱撴担绛嬪殭婵☆偅绻堝濠氭偄绾拌鲸鏅i悷婊冪Ч閹﹢鎳犻鍌滐紲闁哄鐗勯崝搴g不閻愮儤鐓涢悘鐐跺Г閸犳﹢鏌℃担鐟板鐎规洜鍠栭、姗€鎮╅搹顐ら拻闂傚倷娴囧畷鍨叏閹惰姤鈷旂€广儱顦崹鍌炴煢濡尨绱氶柨婵嗩槸缁€瀣亜閺嶃劎鈽夋繛鍫熺矒濮婅櫣娑甸崨顔俱€愬銈庡亝濞茬喖宕洪埀顒併亜閹哄棗浜鹃梺鎸庢穿婵″洤危閹版澘绫嶉柛顐g箘椤撴椽姊虹紒妯哄鐎殿噮鍓欒灃闁告侗鍠氶崢鎼佹⒑閸撴彃浜介柛瀣閹﹢鏁冮崒娑氬幈闁诲函缍嗛崑鍡樻櫠椤掑倻纾奸柛灞剧☉缁椦囨煙閻熸澘顏柟鐓庢贡閹叉挳宕熼棃娑欐珡闂傚倸鍊风粈渚€骞栭銈傚亾濮樺崬鍘寸€规洖缍婇弻鍡楊吋閸涱垽绱遍柣搴$畭閸庨亶藝娴兼潙纾跨€广儱顦伴悡鏇㈡煛閸ャ儱濡煎褜鍨伴湁闁绘ǹ绉鍫熺畳闂備焦瀵х换鍌毼涘Δ鍛厺闁哄洢鍨洪悡鍐喐濠婂牆绀堟慨妯挎硾閽冪喖鏌曟繛褍瀚烽崑銊╂⒑缂佹ê濮囨い鏇ㄥ弮閸┿垽寮撮姀鈥斥偓鐢告煥濠靛棗鈧懓鈻嶉崶銊d簻闊洦绋愰幉楣冩煛鐏炵偓绀嬬€规洟浜堕、姗€鎮㈡總澶夌处
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者