1. 程式人生 > >windows下用OPENGL播放視訊

windows下用OPENGL播放視訊

1.下載 

2.OPENGL 標準定義了基本的渲染API ,還定義了視窗系統的API ,WINDOWS 用wgl**,定義在 wingdi.h

3.本程式碼採用OPENGL 1.2 支援頂點著色

標頭檔案

#pragma once
#include "videodisplay.h"
#include <GL/glew.h>

class OpenGLDisplay2 : public VideoDisplay
{
public:
 OpenGLDisplay2(void);
 ~OpenGLDisplay2(void);
public:
 int init(HWND hwnd,int w,int h);
 void fini();
 int display(uint8_t* Y,uint8_t* U,uint8_t* V);
private:
 void InitShaders();
private:
 HDC                   hGLDC;
 HGLRC                 hGLRC;
 GLuint p;               
 GLuint id_y, id_u, id_v; // Texture id
 GLuint textureUniformY, textureUniformU,textureUniformV;
 GLint v, f;
 int m_nWidth2;
 int m_nHeight2;
 HWND videoHwnd;
 int gw;
 int gh;
};

 原始碼

#include "StdAfx.h"
#include "OpenGLDisplay2.h"
//#include "opengl.h"


#pragma comment(lib, "glew32.lib")

#define ATTRIB_VERTEX 3
#define ATTRIB_TEXTURE 4

OpenGLDisplay2::OpenGLDisplay2(void)
{
 hGLDC = NULL;
 hGLRC = NULL;

 p = v = f = 0;
 id_y = id_u = id_v = 0;
 textureUniformY = textureUniformU = textureUniformV = 0;
 videoHwnd = NULL;
 gw = gh = 0;
 m_nWidth2 = m_nHeight2 = 0;
}

OpenGLDisplay2::~OpenGLDisplay2(void)
{
 fini();
}

int OpenGLDisplay2::init(HWND hwnd,int w,int h)
{
 fini();

    hGLDC = GetDC(hwnd);
 videoHwnd = hwnd;

 m_nWidth2 = w;
 m_nHeight2 = h;

    /* Set the pixel format for the DC */
    PIXELFORMATDESCRIPTOR pfd;
    memset(&pfd, 0, sizeof(pfd));
    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;
    SetPixelFormat(hGLDC,
                   ChoosePixelFormat(hGLDC, &pfd), &pfd);

    /* Create and enable the render context */
    hGLRC = wglCreateContext(hGLDC);
    wglMakeCurrent(hGLDC, hGLRC);

 GLenum err = glewInit();
 if (GLEW_OK != err)
 {
  const char* str = (const char*)glewGetErrorString(err);
  int err = 1;
 }

    const char *version = (const char*)glGetString(GL_VERSION);
    const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
 if(version && (version[0]>'1' || (version[0]=='1' && version[2]>='2')))
 {
  InitShaders();
  RECT rc;
  ::GetWindowRect(videoHwnd,&rc);
  gw = rc.right - rc.left;
  gh = rc.bottom - rc.top;
  glViewport( 0, 0, gw, gh );
  return TRUE;
 }

 return FALSE;

}
void OpenGLDisplay2::fini()
{
 if (id_y>0)
  glDeleteTextures(1,&id_y);
 if (id_u>0)
  glDeleteTextures(1,&id_u);
 if (id_v>0)
  glDeleteTextures(1,&id_v);
 
 id_v = 0;
 id_u = 0;
 id_y = 0;

 if (p>0)
  glDeleteProgram(p);
 if (v>0)
  glDeleteShader(v);
 if (f>0)
  glDeleteProgram(f);

 p = v = f = 0;

 if (hGLDC && hGLRC)
        wglMakeCurrent(NULL, NULL);

    if (hGLRC)
        wglDeleteContext(hGLRC);

    if (hGLDC)
        ReleaseDC(videoHwnd, hGLDC);

 hGLRC = NULL;
 hGLDC = NULL;

}

int OpenGLDisplay2::display(uint8_t* Y,uint8_t* U,uint8_t* V)
{
 RECT rc;
 ::GetWindowRect(videoHwnd,&rc);
 int w = rc.right - rc.left;
 int h = rc.bottom - rc.top;
 glViewport( 0, 0, w, h );
 
 if ((w != gw || h != gh) )
 {
 // fini();
 // return FALSE;
 }
 //Clear
 glClearColor(0.0,0.0,0.0,0.0);
 glClear(GL_COLOR_BUFFER_BIT);
 //Y
 //
    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, id_y); 
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0, m_nWidth2, m_nHeight2, GL_LUMINANCE, GL_UNSIGNED_BYTE, Y);  
 glUniform1i(textureUniformY, 0);   
 //U
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, id_u);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,m_nWidth2/2, m_nHeight2/2, GL_LUMINANCE, GL_UNSIGNED_BYTE, U);      
    glUniform1i(textureUniformU, 1);
 //V
    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, id_v);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0, m_nWidth2/2, m_nHeight2/2, GL_LUMINANCE, GL_UNSIGNED_BYTE, V);   
    glUniform1i(textureUniformV, 2);  

    // Draw
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

  SwapBuffers(hGLDC);

 return TRUE;
}
char *const vertexShaderString = \
""\
 "attribute vec4 position;"\
 "attribute vec2 texcoord;"\
 "uniform mat4 modelViewProjectionMatrix;"\
 "varying vec2 v_texcoord;"\
 
 "void main()"\
 "{"\
"     gl_Position = modelViewProjectionMatrix * position;"\
     "v_texcoord = texcoord.xy;"\
 "}"\
 "";

char *const yuvFragmentShaderString = \
 "varying  vec2 v_texcoord;"\
 "uniform sampler2D s_texture_y;"\
 "uniform sampler2D s_texture_u;"\
 "uniform sampler2D s_texture_v;"
 "void main()"\
 "{"\
"      float y = texture2D(s_texture_y, v_texcoord).r;"\
     " float u = texture2D(s_texture_u, v_texcoord).r - 0.5;"\
     " float v = texture2D(s_texture_v, v_texcoord).r - 0.5;"\
    
     " float r = y +             1.402 * v;"\
     " float g = y - 0.344 * u - 0.714 * v;"\
     " float b = y + 1.772 * u;"\
    
     "gl_FragColor = vec4(r,g,b,1.0);     "\
 "}";


//Init Shader
const char * vs = \
"attribute vec4 vertexIn; "\
"attribute vec2 textureIn;"\
"varying vec2 textureOut;"

"void main(void)"\
"{"\
"    gl_Position = vertexIn; "\
    "textureOut = textureIn;"\
"}";

const char* fs = \
"varying vec2 textureOut;"\
"uniform sampler2D tex_y;"\
"uniform sampler2D tex_u;"\
"uniform sampler2D tex_v;"\
"void main(void)"\
"{"\
"    vec3 yuv;"\
" vec3 rgb;"\
"    yuv.x = texture2D(tex_y, textureOut).r;"\
"    yuv.y = texture2D(tex_u, textureOut).r - 0.5;"\
" yuv.z = texture2D(tex_v, textureOut).r - 0.5;"\
    "rgb = mat3( 1,       1,         1,"\
"                0,       -0.39465,  2.03211,"\
"                1.13983, -0.58060,  0) * yuv;    "\
"    gl_FragColor = vec4(rgb, 1);"\
"}";


void OpenGLDisplay2::InitShaders()
{
    GLint vertCompiled, fragCompiled, linked;   
   // const char *vs,*fs;
 //Shader: step1
    v = glCreateShader(GL_VERTEX_SHADER);
    f = glCreateShader(GL_FRAGMENT_SHADER);
 //Shader: step2
    glShaderSource(v, 1, &vs,NULL);
    glShaderSource(f, 1, &fs,NULL);
 //Shader: step3
    glCompileShader(v);
 //Debug
    glGetShaderiv(v, GL_COMPILE_STATUS, &vertCompiled);
    glCompileShader(f);
    glGetShaderiv(f, GL_COMPILE_STATUS, &fragCompiled);

 //Program: Step1
    p = glCreateProgram();
 //Program: Step2
    glAttachShader(p,v);
    glAttachShader(p,f);

    glBindAttribLocation(p, ATTRIB_VERTEX, "vertexIn");
    glBindAttribLocation(p, ATTRIB_TEXTURE, "textureIn");
 //Program: Step3
    glLinkProgram(p);
 //Debug
    glGetProgramiv(p, GL_LINK_STATUS, &linked); 
 //Program: Step4
    glUseProgram(p);
 //Get Uniform Variables Location
 textureUniformY = glGetUniformLocation(p, "tex_y");
 textureUniformU = glGetUniformLocation(p, "tex_u");
 textureUniformV = glGetUniformLocation(p, "tex_v");

 static const GLfloat vertexVertices[] = {
  -1.0f, -1.0f,
  1.0f, -1.0f,
  -1.0f,  1.0f,
  1.0f,  1.0f,
 };   

 static const GLfloat textureVertices[] = {
  0.0f,  1.0f,
  1.0f,  1.0f,
  0.0f,  0.0f,
  1.0f,  0.0f,
 };

 //Set Arrays
    glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, vertexVertices);
 //Enable it
    glEnableVertexAttribArray(ATTRIB_VERTEX);   
    glVertexAttribPointer(ATTRIB_TEXTURE, 2, GL_FLOAT, 0, 0, textureVertices);
    glEnableVertexAttribArray(ATTRIB_TEXTURE);
 //Init Texture
    glGenTextures(1, &id_y);
    glBindTexture(GL_TEXTURE_2D, id_y);   
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, m_nWidth2, m_nHeight2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,NULL);
   
    glGenTextures(1, &id_u);
    glBindTexture(GL_TEXTURE_2D, id_u);  
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, m_nWidth2/2, m_nHeight2/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,NULL);
   
    glGenTextures(1, &id_v);
    glBindTexture(GL_TEXTURE_2D, id_v);   
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, m_nWidth2/2, m_nHeight2/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,NULL);

}

//如果出現視窗複用播放視訊,視訊不顯示在在播放視訊的視窗

int VideoPlayerDlg::Init()
{
 hGLDC = ::GetDC(m_hImageWnd);
    /* Set the pixel format for the DC */
    PIXELFORMATDESCRIPTOR pfd;
    memset(&pfd, 0, sizeof(pfd));
    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;
    SetPixelFormat(hGLDC,ChoosePixelFormat(hGLDC, &pfd), &pfd);

 ::ReleaseDC(m_hImageWnd,hGLDC);

 return TRUE;
}