一、實現效果
二、pro文件
Qt += widgets opengl
三、主要代碼
#include "glwidget.h"GLWidget::GLWidget(QWidget *parent) : QOpenGLWidget(parent)
{connect(&m_timer, &QTimer::timeout, this,[&](){this->update();});m_timer.start(1000/33);
}void GLWidget::initializeGL()
{qDebug() << "初始化";initializeOpenGLFunctions(); // 初始化openglqDebug() << "加載片元腳本:" <<program.addShaderFromSourceFile(QGLShader::Vertex, ":/res/shader.vert"); // 片元qDebug() << "加載頂點腳本:" <<program.addShaderFromSourceFile(QGLShader::Fragment, ":/res/shader.frag"); // 頂點qDebug() << "編譯shader:" << program.link();qDebug() << "綁定shader:" << program.bind();int A_VER = -1;int T_VER = -1;// 設置頂點坐標的變量A_VER = program.attributeLocation("vertexIn");//, A_VER// 設置材質坐標T_VER = program.attributeLocation("textureIn");//, T_VERstatic const GLfloat ver[] = {-1.0f, -1.0f, 0.0f, 1.0f,//0.0f, 0.0f,1.0f, -1.0f, 1.0f, 1.0f,//1.0f, 0.0f,-1.0f, 1.0f, 0.0f, 0.0f,//0.0f, 1.0f,1.0f, 1.0f, 1.0f, 0.0f//1.0f, 1.0f};glGenVertexArrays(1, &m_vao);glBindVertexArray(m_vao);glGenBuffers(1, &m_vbo);glBindBuffer(GL_ARRAY_BUFFER, m_vbo);glBufferData(GL_ARRAY_BUFFER, sizeof(ver), ver, GL_STATIC_DRAW);glVertexAttribPointer(A_VER, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);glEnableVertexAttribArray(A_VER);glVertexAttribPointer(T_VER, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2* sizeof(float)));glEnableVertexAttribArray(T_VER);glBindVertexArray(0);glBindBuffer(GL_ARRAY_BUFFER, 0);// 從shader獲取材質unis[0] = program.uniformLocation("tex_y");unis[1] = program.uniformLocation("tex_u");unis[2] = program.uniformLocation("tex_v");// 創建材質glGenTextures(3, texs);// YglBindTexture(GL_TEXTURE_2D, texs[0]); // 綁定材質glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 設置紋理參數,放大過濾,線性插值 GL_NEAREST(效率高,效果差)glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, 0); // 創建材質顯卡空間// UglBindTexture(GL_TEXTURE_2D, texs[1]); // 綁定材質glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 設置紋理參數,放大過濾,線性插值glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width / 2, height/ 2, 0, GL_RED, GL_UNSIGNED_BYTE, 0); // 創建材質顯卡空間// 創建材質 VglBindTexture(GL_TEXTURE_2D, texs[2]); // 綁定材質glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 設置紋理參數,放大過濾,線性插值glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width / 2, height / 2, 0, GL_RED, GL_UNSIGNED_BYTE, 0); // 創建材質顯卡空間m_file.setFileName(":/res/1.yuv");if(!m_file.open(QIODevice::ReadOnly)){qDebug() << "打開失敗!";return;}}void GLWidget::paintGL()
{glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT); // 清除顏色緩沖區program.bind();//qDebug() << "繪制";if(m_file.atEnd()){m_file.seek(0);}QByteArray buf;buf = m_file.read(width * height);glBindVertexArray(m_vao);glActiveTexture(GL_TEXTURE0); // 激活第0層glBindTexture(GL_TEXTURE_2D, texs[0]); // 0層綁定到y材質中// 修改材質內容(復制內存內容)glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RED, GL_UNSIGNED_BYTE, buf.data());glUniform1i(unis[0], 0); // 與shader的uni變量關聯buf = m_file.read(width * height / 4);glActiveTexture(GL_TEXTURE0 + 1); // 激活第1層glBindTexture(GL_TEXTURE_2D, texs[1]); // 1層綁定到U材質中// 修改材質內容(復制內存內容)glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RED, GL_UNSIGNED_BYTE, buf.data());glUniform1i(unis[1], 1); // 與shader的uni變量關聯buf = m_file.read(width * height / 4);glActiveTexture(GL_TEXTURE0 + 2); // 激活第2層 VglBindTexture(GL_TEXTURE_2D, texs[2]); // 2層綁定到v材質中// 修改材質內容(復制內存內容)glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RED, GL_UNSIGNED_BYTE, buf.data());glUniform1i(unis[2], 2); // 與shader的uni變量關聯glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // 開始繪制glBindVertexArray(0);
}void GLWidget::resizeGL(int w, int h)
{//qDebug() << w <<" " << h;glViewport(0, 0, w, h);
}
完整demo下載:點擊跳轉
覺得有幫助的話,打賞一下唄。。
? ? ? ? ? ?
需要商務合作(定制程序)的歡迎私信!!?