由于想做一個應用軟體,把目前自己的算法應用出去,給給為研究者提供一丢丢便利,需要在MFC中顯示視訊流檔案。我嘗試了兩種方法:opencv+MFC;openGL+MFC;這兩種方法都可行。但是在使用opencv+MFC時,以為是設定雙緩沖處有點問題,導緻視訊流閃爍嚴重。(實際是讀取視訊的問題,修改後應該可行,後面改用opengl做了,也出現了這樣的問題,後來修改好了)。
1、首先需要加載一個Picture Control的控件;設定ID等
2、在CTrackingAppDlg.h(XXXDlg.h)中定義雙緩沖區:
HDC _hrenderDC; //DC
HGLRC _hrenderRC; //RC
添加兩個初始化函數:
bool CTrackingAppDlg::SetWindowPixelFormat(HDC hDC)
{
PIXELFORMATDESCRIPTOR pixelDesc;
pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pixelDesc.nVersion = ;
pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |PFD_DOUBLEBUFFER |PFD_TYPE_RGBA;
pixelDesc.iPixelType = PFD_TYPE_RGBA;
pixelDesc.cColorBits = ;
pixelDesc.cRedBits = ;
pixelDesc.cRedShift = ;
pixelDesc.cGreenBits = ;
pixelDesc.cGreenShift = ;
pixelDesc.cBlueBits = ;
pixelDesc.cBlueShift = ;
pixelDesc.cAlphaBits = ;
pixelDesc.cAlphaShift = ;
pixelDesc.cAccumBits = ;
pixelDesc.cAccumRedBits = ;
pixelDesc.cAccumGreenBits = ;
pixelDesc.cAccumBlueBits = ;
pixelDesc.cAccumAlphaBits = ;
pixelDesc.cDepthBits = ;
pixelDesc.cStencilBits = ;
pixelDesc.cAuxBuffers = ;
pixelDesc.iLayerType = PFD_MAIN_PLANE;
pixelDesc.bReserved = ;
pixelDesc.dwLayerMask = ;
pixelDesc.dwVisibleMask = ;
pixelDesc.dwDamageMask = ;
_pixelFormat = ChoosePixelFormat(hDC,&pixelDesc);
if( _pixelFormat== ) // Choose default
{
_pixelFormat = ;
if(DescribePixelFormat(hDC,_pixelFormat, sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==)
{
return false;
}
}
if(SetPixelFormat(hDC,_pixelFormat,&pixelDesc)==FALSE)
{
return false;
}
return true;
}
BOOL CTrackingAppDlg::CreateViewGLContext(HDC hDC)
{
_hrenderRC = wglCreateContext(hDC);
if(_hrenderRC==NULL)
return FALSE;
if(wglMakeCurrent(hDC,_hrenderRC)==FALSE)
return FALSE;
return TRUE;
}
3、在InitDialog函數中初始化;
//讀取Picture控件的大小;
CRect picRect;
CWnd *wnd = GetDlgItem(IDC_PIC_RAW);
wnd->GetWindowRect(&picRect);
//用于設定圖檔顯示的ViewPort視窗
_app->getRawPictureView(i)->setViewPort(picRect.Width(),picRect.Height());
初始化并設定Opengl顯示屬性等:
_hrenderDC = ::GetDC(wnd->m_hWnd);
///////////////////////////////////////////Tian///////////////////////////
if(SetWindowPixelFormat(_hrenderDC)==FALSE)
return ;
if(CreateViewGLContext(_hrenderDC)==FALSE)
return ;
glPolygonMode(GL_FRONT,GL_FILL);
glPolygonMode(GL_BACK,GL_FILL);
//////////////////////////////////////////////////////
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
//它負責把視景體截取的圖像按照怎樣的高和寬顯示到螢幕上。
//glViewport(0,0,259,231);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/* gluPerspective(45,1,0.1,100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); */
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(f, f, f, f); // Black Background
glClearDepth(f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);//緩存模式
SetTimer(,,);//每隔10ms執行Ontimer函數一次,将Reshape放在Ontimer中可以動态更換圖檔
5、OnTimer類:
void CTrackingAppDlg::OnTimer(UINT_PTR nIDEvent)
{
//showImage(picView->getRawImage(),IDC_PIC_RAW);
//showImage(picView->getBitImage(),IDC_PIC_BIT);
wglMakeCurrent(_hrenderDC , _hrenderRC);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(_app)
{
for(int i=;i<;i++)
_app->getRawPictureView(i)->reshape();
}
SwapBuffers(_hrenderDC);
CDialogEx::OnTimer(nIDEvent);
}
初始化部分就這麼多,其他的與opengl使用相同。不懂的自己多補一點opengl相關基礎。
reshape函數如下:
void RawPicView::reshape()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho( -, , -, , -, );
// glMatrixMode(GL_MODELVIEW);
if(_ChannelId == )
glViewport(,,_rectWight/-,_rectHight);
else
glViewport(_rectWight/+,,_rectWight/-,_rectHight);
glLoadIdentity();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
if(!_initialized)
initlize();
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _textureId );
if( !_valid )
replaceTexture();
glColor3f( , , );
glBegin(GL_QUADS); // Drawing Using Triangles
////////////////////////Tian//////////////////////////////////////////////
glTexCoord2f( , );
glVertex2f( -, f );
glTexCoord2f( , );
glVertex2f( -, -);
glTexCoord2f( , );
glVertex2f( , -);
glTexCoord2f( , );
glVertex2f( , );
//////////////////////////////////////////////////////////////////////////
glEnd();
}
當然還是給個結果比較好:
效果如下:
