MFC+OpenGL显示视频流图片

原创 2016年04月06日 13:47:41

由于想做一个应用软件,把目前自己的算法应用出去,给给为研究者提供一丢丢便利,需要在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 = 1;  
    pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |PFD_DOUBLEBUFFER |PFD_TYPE_RGBA;

    pixelDesc.iPixelType = PFD_TYPE_RGBA;
    pixelDesc.cColorBits = 32;
    pixelDesc.cRedBits = 0;  
    pixelDesc.cRedShift = 0;
    pixelDesc.cGreenBits = 0;
    pixelDesc.cGreenShift = 0;
    pixelDesc.cBlueBits = 0;
    pixelDesc.cBlueShift = 0;  
    pixelDesc.cAlphaBits = 0;  
    pixelDesc.cAlphaShift = 0;  
    pixelDesc.cAccumBits = 0;  
    pixelDesc.cAccumRedBits = 0;  
    pixelDesc.cAccumGreenBits = 0;  
    pixelDesc.cAccumBlueBits = 0;  
    pixelDesc.cAccumAlphaBits = 0;  
    pixelDesc.cDepthBits = 0;  
    pixelDesc.cStencilBits = 1;  
    pixelDesc.cAuxBuffers = 0;  
    pixelDesc.iLayerType = PFD_MAIN_PLANE;  
    pixelDesc.bReserved = 0;  
    pixelDesc.dwLayerMask = 0;  
    pixelDesc.dwVisibleMask = 0;  
    pixelDesc.dwDamageMask = 0;  

    _pixelFormat = ChoosePixelFormat(hDC,&pixelDesc);  

    if( _pixelFormat==0 ) // Choose default  
    {  
        _pixelFormat = 1;  
        if(DescribePixelFormat(hDC,_pixelFormat,  sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)  
        {  
            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 0;  

        if(CreateViewGLContext(_hrenderDC)==FALSE)  
            return 0;  

        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(1.0f, 1.0f, 1.0f, 0.5f);    // Black Background  
        glClearDepth(1.0f);         // 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(1,10,0);//每隔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=0;i<2;i++)
            _app->getRawPictureView(i)->reshape();
    }
    SwapBuffers(_hrenderDC);
    CDialogEx::OnTimer(nIDEvent);
}

初始化部分就这么多,其他的与opengl使用相同。不懂的自己多补一点opengl相关基础。
reshape函数如下:

void RawPicView::reshape()
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glOrtho( -1.0, 1.0, -1.0, 1.0, -40.0, 40.0 );

//  glMatrixMode(GL_MODELVIEW);

    if(_ChannelId == 0)
        glViewport(0,0,_rectWight/2-5,_rectHight);
    else
        glViewport(_rectWight/2+5,0,_rectWight/2-5,_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( 1.0, 1.0, 1.0 );
    glBegin(GL_QUADS); // Drawing Using Triangles  
    ////////////////////////Tian//////////////////////////////////////////////
        glTexCoord2f( 0.0, 0.0 );
        glVertex2f( -1.0, 1.0f );

        glTexCoord2f( 0.0, 1.0 );
        glVertex2f( -1.0, -1.0);    

        glTexCoord2f( 1.0, 1.0 );
        glVertex2f( 1.0, -1.0);

        glTexCoord2f( 1.0, 0.0 );
        glVertex2f( 1.0, 1.0 ); 

    //////////////////////////////////////////////////////////////////////////
    glEnd();

}

当然还是给个结果比较好:
效果如下:这是准备做的一个应用软件截图,如果完成了将会上传,各位敬请期待

解析RTSP流后,使用opengl在MFC界面绘制1920*1080P的图像

glTexImage2D这个函数可以处理BMP的位图数据,由此可知解析rtsp流后,将H264转RGB24。再将RGB24数据转opencv的Iplimage,方便传输。 在低功耗的主板上使用了CVV...
  • sz76211822
  • sz76211822
  • 2017-02-24 13:10:56
  • 697

最简单的视音频播放示例5:OpenGL播放RGB/YUV

本文记录OpenGL播放视频的技术。OpenGL是一个和Direct3D同一层面的技术。相比于Direct3D,OpenGL具有跨平台的优势。尽管在游戏领域,DirectX的影响力已渐渐超越OpenG...
  • leixiaohua1020
  • leixiaohua1020
  • 2014-10-27 12:35:41
  • 23363

windows下用OPENGL播放视频 -采用纹理显示

 采用OPENGL纹理显示视频 OPENGL 显示视频2种 1.直接纹理显示 在1.0 就支持 2.基于可编程(着色器)纹理显示 1.5后支持 这个之前的文章介绍过 有一点要记住 在wi...
  • doitsjz
  • doitsjz
  • 2016-01-21 11:10:18
  • 1995

OpenGL播放视频的技术

本文记录OpenGL播放视频的技术。上一篇文章中,介绍了一种简单的使用OpenGL显示视频的方式。但是那还不是OpenGL显示视频技术的精髓。和Direct3D一样,OpenGL更好的显示视频的方式也...
  • gxflh
  • gxflh
  • 2017-04-20 15:09:15
  • 2213

opengl显示视频demo可以测试性能

  • 2016年12月14日 12:54
  • 1.73MB
  • 下载

windows下用OPENGL播放视频

1.下载  http://glew.sourceforge.net/  微软自带的OPENGL32.DLL gl.h 太老了,好久没更新了 2.OPENGL 标准定义了基本的渲染API ,还...
  • doitsjz
  • doitsjz
  • 2016-01-18 17:38:55
  • 669

如何基于OpenGL实现视频处理

  • 2015年07月03日 21:23
  • 944KB
  • 下载

yuv视频用opengl播放

// openGL_yuv.cpp : Defines the entry point for the console application. // #include "stdafx.h...
  • chence19871
  • chence19871
  • 2014-10-20 10:23:45
  • 3700

在VS2010里MFC对话框中使用OpenGL绘图,添加的控件不显示的一种解决方法

当我想在MFC对话框里一部分显示OpenGL图形,一部分显示滚动条和一些按钮等控件的时候,图形可以显示,但是控件不显示,网上很多人说是修改对话框的ClipChildren属性,我没搞明白,试了一下没有...
  • Main_3K10
  • Main_3K10
  • 2014-03-07 21:41:36
  • 1514

直接在MFC的对话框上利用OpenGL绘制图形

借鉴前人的经验,如链接http://www.cnblogs.com/phinecos/archive/2007/07/28/834916.html介绍了如何利用MFC的单文档来使用OpenGL(本文也...
  • hurricanecqj
  • hurricanecqj
  • 2015-05-01 15:20:46
  • 1925
收藏助手
不良信息举报
您举报文章:MFC+OpenGL显示视频流图片
举报原因:
原因补充:

(最多只允许输入30个字)