Qt一般是用來寫介面,而當系統對圖片繪製速度要求較高時,Qt內建的映像繪製引擎往往不能達到我們的要求,這個時候我們就需要更加底層的繪圖API,如DiretDraw(DirectDraw已經很舊了,目前使用的是Direct3D)。
在DirectDraw中,可以使用如下函數,將繪製操作映射到指定的視窗:
// create IDirectDraw interface 7.0 object and test for errorif (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL))) return(0); // set cooperation to full screenif (FAILED(lpdd->SetCooperativeLevel(m_pWnd->GetSafeHwnd(), DDSCL_NORMAL | DDSCL_NOWINDOWCHANGES))) return(0); |
關於DirectDraw API的使用,可以參考《windows遊戲編程大師技巧》第5-7章。
在MFC程式中,我們可以很容易的得到一個視窗的控制代碼
pWnd,那如何在Qt程式獲得Qt視窗(QWidget)的控制代碼呢?很簡單,直接調用winId()獲得HWnd,然後通過FromHandle將HWnd轉換成CWnd。假設我們要在videoWidget(QWidget對象)上顯示視頻,調用如下代碼即可。
m_ddraw = new MyDDraw(CWnd::FromHandle(videoWidget->winId()));
部分原始碼
qtDDraw.cpp
QtDDraw::QtDDraw(QWidget *parent /* = 0 */, Qt::WFlags flags /* = 0 */):QWidget(parent, flags){ setWindowTitle(tr("using DDraw in Qt")); videoWidget = new QWidget(this); videoWidget->setFixedSize(QSize(640,480)); m_ddraw = new MyDDraw(CWnd::FromHandle(videoWidget->winId())); m_timer = new QTimer(this); connect(m_timer, SIGNAL(timeout()), this, SLOT(refreshScreen())); m_timer->start(40); QVBoxLayout *layout = new QVBoxLayout; layout->setContentsMargins(0,0,0,0); layout->addWidget(videoWidget); setLayout(layout);} void QtDDraw::refreshScreen(){ m_ddraw->Update_Screen(); //m_timer->stop();} |
myDDraw.cpp
MyDDraw::MyDDraw(CWnd *cWnd) : m_pWnd(cWnd){ Init_DDraw();} int MyDDraw::Update_Screen(){ RECT rc; m_pWnd->GetClientRect(&rc); m_pWnd->ClientToScreen(&rc); // copy background to back buffer DDraw_Draw_Surface(lpddsbackground,rc.left,rc.top,SCREEN_WIDTH, SCREEN_HEIGHT, rc.right-rc.left, rc.bottom-rc.top, lpddsprimary,0); return(1); } // end Update_Screen |
項目工程檔案:(VS008+Qt4.8)http://download.csdn.net/detail/ajaxhe/4273871
若你是其他的Qt版本,編譯時間會出錯(valid Qt version for platfom)
只需要修改項目解決方案的屬性中的“Change Soluetion's Qt version”即可
運行結果: