@ -29,7 +29,6 @@ static const GLfloat coordinate[] = {
// 纹理坐标, 存储4个xy坐标
// 坐标范围为[0,1],左下角为 0,0
// TODO 为什么这个顺序指定四个顶点?顶点坐标和纹理坐标如何映射的?
0.0f ,
1.0f ,
1.0f ,
@ -62,15 +61,21 @@ static QString s_fragShader = R"(
{
vec3 yuv ;
vec3 rgb ;
// SDL2-2.0.10\src\render\opengl\SDL_shaders_gl.c BT709_SHADER_CONSTANTS
// SDL2 BT709_SHADER_CONSTANTS
// https://github.com/spurious/SDL-mirror/blob/4ddd4c445aa059bb127e101b74a8c5b59257fbe2/src/render/opengl/SDL_shaders_gl.c#L102
const vec3 Rcoeff = vec3 ( 1.1644 , 0.000 , 1.7927 ) ;
const vec3 Gcoeff = vec3 ( 1.1644 , - 0.2132 , - 0.5329 ) ;
const vec3 Bcoeff = vec3 ( 1.1644 , 2.1124 , 0.000 ) ;
// 根据指定的纹理textureY和坐标textureOut来采样
yuv . x = texture2D ( textureY , textureOut ) . r ;
yuv . y = texture2D ( textureU , textureOut ) . r - 0.5 ;
yuv . z = texture2D ( textureV , textureOut ) . r - 0.5 ;
// 采样完转为rgb
// 减少一些亮度
yuv . x = yuv . x - 0.0625 ;
rgb . r = dot ( yuv , Rcoeff ) ;
rgb . g = dot ( yuv , Gcoeff ) ;
rgb . b = dot ( yuv , Bcoeff ) ;
@ -220,7 +225,7 @@ void QYUVOpenGLWidget::initTextures()
// 设置st方向上纹理超出坐标时的显示策略
glTexParameterf ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE ) ;
glTexParameterf ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ;
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_ RED , m_frameSize . width ( ) , m_frameSize . height ( ) , 0 , GL_ RED, GL_UNSIGNED_BYTE , NULL ) ;
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_ LUMINANCE , m_frameSize . width ( ) , m_frameSize . height ( ) , 0 , GL_ LUMINANCE, GL_UNSIGNED_BYTE , nullptr ) ;
glGenTextures ( 1 , & m_texture [ 1 ] ) ;
glBindTexture ( GL_TEXTURE_2D , m_texture [ 1 ] ) ;
@ -228,7 +233,7 @@ void QYUVOpenGLWidget::initTextures()
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
glTexParameterf ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE ) ;
glTexParameterf ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ;
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_ RED , m_frameSize . width ( ) / 2 , m_frameSize . height ( ) / 2 , 0 , GL_ RED, GL_UNSIGNED_BYTE , NULL ) ;
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_ LUMINANCE , m_frameSize . width ( ) / 2 , m_frameSize . height ( ) / 2 , 0 , GL_ LUMINANCE, GL_UNSIGNED_BYTE , nullptr ) ;
glGenTextures ( 1 , & m_texture [ 2 ] ) ;
glBindTexture ( GL_TEXTURE_2D , m_texture [ 2 ] ) ;
@ -238,7 +243,7 @@ void QYUVOpenGLWidget::initTextures()
// 设置st方向上纹理超出坐标时的显示策略
glTexParameterf ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE ) ;
glTexParameterf ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ;
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_ RED , m_frameSize . width ( ) / 2 , m_frameSize . height ( ) / 2 , 0 , GL_ RED, GL_UNSIGNED_BYTE , NULL ) ;
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_ LUMINANCE , m_frameSize . width ( ) / 2 , m_frameSize . height ( ) / 2 , 0 , GL_ LUMINANCE, GL_UNSIGNED_BYTE , nullptr ) ;
m_textureInited = true ;
}
@ -249,7 +254,7 @@ void QYUVOpenGLWidget::deInitTextures()
glDeleteTextures ( 3 , m_texture ) ;
}
memset ( m_texture , 0 , 3 ) ;
memset ( m_texture , 0 , sizeof ( m_texture ) ) ;
m_textureInited = false ;
}
@ -262,7 +267,7 @@ void QYUVOpenGLWidget::updateTexture(GLuint texture, quint32 textureType, quint8
makeCurrent ( ) ;
glBindTexture ( GL_TEXTURE_2D , texture ) ;
glPixelStorei ( GL_UNPACK_ROW_LENGTH , stride ) ;
glTexSubImage2D ( GL_TEXTURE_2D , 0 , 0 , 0 , size . width ( ) , size . height ( ) , GL_ RED , GL_UNSIGNED_BYTE , pixels ) ;
glPixelStorei ( GL_UNPACK_ROW_LENGTH , static_cast < GLint > ( stride ) ) ;
glTexSubImage2D ( GL_TEXTURE_2D , 0 , 0 , 0 , size . width ( ) , size . height ( ) , GL_ LUMINANCE , GL_UNSIGNED_BYTE , pixels ) ;
doneCurrent ( ) ;
}