123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- #include "PlayerGLWidget.h"
- PlayerGLWidget::PlayerGLWidget(QWidget *parent) : QOpenGLWidget(parent)
- {
- }
- PlayerGLWidget::~PlayerGLWidget()
- {
- }
- /* 刷新一帧 */
- void PlayerGLWidget::updateFrame(Image_YUV420& image)
- {
- yData = image.yData;
- uData = image.uData;
- vData = image.vData;
- update();
- }
- void PlayerGLWidget::initShaders()
- {
- // 顶点着色器
- const char *vshader =
- "#version 330 core\n"
- "layout(location = 0) in vec4 vertexIn;\n"
- "layout(location = 1) in vec2 textureIn;\n"
- "out vec2 textureOut;\n"
- "void main(void)\n"
- "{\n"
- " gl_Position = vertexIn;\n"
- " textureOut = textureIn;\n"
- "}\n";
- // 片段着色器(YUV420P 转 RGB)
- const char *fshader =
- "#version 330 core\n"
- "in vec2 textureOut;\n"
- "out vec4 fragColor;\n"
- "uniform sampler2D tex_y;\n"
- "uniform sampler2D tex_u;\n"
- "uniform sampler2D tex_v;\n"
- "void main(void)\n"
- "{\n"
- " float y = texture(tex_y, textureOut).r;\n"
- " float u = texture(tex_u, textureOut).r - 0.5;\n"
- " float v = texture(tex_v, textureOut).r - 0.5;\n"
- " float r = y + 1.403 * v;\n"
- " float g = y - 0.344 * u - 0.714 * v;\n"
- " float b = y + 1.770 * u;\n"
- " fragColor = vec4(r, g, b, 1.0);\n"
- "}\n";
- // 创建着色器程序
- program.addShaderFromSourceCode(QOpenGLShader::Vertex, vshader);
- program.addShaderFromSourceCode(QOpenGLShader::Fragment, fshader);
- program.link();
- }
- void PlayerGLWidget::initTextures()
- {
- // 创建 YUV 纹理
- textureY = new QOpenGLTexture(QOpenGLTexture::Target2D);
- textureU = new QOpenGLTexture(QOpenGLTexture::Target2D);
- textureV = new QOpenGLTexture(QOpenGLTexture::Target2D);
- textureY->create();
- textureU->create();
- textureV->create();
- }
- void PlayerGLWidget::initVertex()
- {
- }
- void PlayerGLWidget::initFrameBuffer()
- {
- }
- void PlayerGLWidget::renderYUV420P()
- {
- if (yData.isEmpty() || uData.isEmpty() || vData.isEmpty())
- return;
- // 绑定纹理
- textureY->bind(0);
- textureU->bind(1);
- textureV->bind(2);
- // 上传 YUV 数据到纹理
- textureY->setData(QOpenGLTexture::Red, QOpenGLTexture::UInt8, yData.constData());
- textureU->setData(QOpenGLTexture::Red, QOpenGLTexture::UInt8, uData.constData());
- textureV->setData(QOpenGLTexture::Red, QOpenGLTexture::UInt8, vData.constData());
- // 绑定着色器程序
- program.bind();
- program.setUniformValue("tex_y", 0);
- program.setUniformValue("tex_u", 1);
- program.setUniformValue("tex_v", 2);
- // 绘制矩形
- static const GLfloat vertices[] = {
- -1.0f, -1.0f, 0.0f,
- 1.0f, -1.0f, 0.0f,
- -1.0f, 1.0f, 0.0f,
- 1.0f, 1.0f, 0.0f
- };
- static const GLfloat texCoords[] = {
- 0.0f, 1.0f,
- 1.0f, 1.0f,
- 0.0f, 0.0f,
- 1.0f, 0.0f
- };
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, texCoords);
- glEnableVertexAttribArray(0);
- glEnableVertexAttribArray(1);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- program.release();
- }
- void PlayerGLWidget::initializeGL()
- {
- initializeOpenGLFunctions();
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- // 初始化着色器
- initShaders();
- initTextures();
- }
- void PlayerGLWidget::resizeGL(int w, int h)
- {
- glViewport(0, 0, w, h);
- }
- void PlayerGLWidget::paintGL()
- {
- glClear(GL_COLOR_BUFFER_BIT);
- // 渲染 YUV 数据
- renderYUV420P();
- }
|