mark:qt opengl最终版(qt opengl+opengl原生混合编程)

This commit is contained in:
Barry 2018-11-04 12:46:43 +08:00
commit 9c02a1a403
2 changed files with 47 additions and 96 deletions

View file

@ -1,6 +1,5 @@
#include <QCoreApplication> #include <QCoreApplication>
#include <QOpenGLTexture> #include <QOpenGLTexture>
#include <QOpenGLPixelTransferOptions>
#include "qyuvopenglwidget.h" #include "qyuvopenglwidget.h"
@ -65,9 +64,7 @@ static QString s_fragShader = R"(
QYUVOpenGLWidget::QYUVOpenGLWidget(QWidget *parent) : QOpenGLWidget(parent) QYUVOpenGLWidget::QYUVOpenGLWidget(QWidget *parent) : QOpenGLWidget(parent)
{ {
m_textureY = new QOpenGLTexture(QOpenGLTexture::Target2D);
m_textureU = new QOpenGLTexture(QOpenGLTexture::Target2D);
m_textureV = new QOpenGLTexture(QOpenGLTexture::Target2D);
} }
QYUVOpenGLWidget::~QYUVOpenGLWidget() QYUVOpenGLWidget::~QYUVOpenGLWidget()
@ -75,19 +72,6 @@ QYUVOpenGLWidget::~QYUVOpenGLWidget()
makeCurrent(); makeCurrent();
m_vbo.destroy(); m_vbo.destroy();
deInitTextures(); deInitTextures();
if (m_textureY) {
delete m_textureY;
m_textureY = Q_NULLPTR;
}
if (m_textureU) {
delete m_textureU;
m_textureU = Q_NULLPTR;
}
if (m_textureV) {
delete m_textureV;
m_textureV = Q_NULLPTR;
}
doneCurrent(); doneCurrent();
} }
@ -106,28 +90,14 @@ void QYUVOpenGLWidget::setFrameSize(const QSize &frameSize)
if (m_frameSize != frameSize) { if (m_frameSize != frameSize) {
m_frameSize = frameSize; m_frameSize = frameSize;
m_needUpdate = true; m_needUpdate = true;
repaint();
} }
} }
void QYUVOpenGLWidget::updateTextures(quint8 *dataY, quint8 *dataU, quint8 *dataV, quint32 linesizeY, quint32 linesizeU, quint32 linesizeV) void QYUVOpenGLWidget::updateTextures(quint8 *dataY, quint8 *dataU, quint8 *dataV, quint32 linesizeY, quint32 linesizeU, quint32 linesizeV)
{ {
if (m_frameSize.isEmpty()) { updateTexture(m_texture[0], 0, dataY, linesizeY);
return; updateTexture(m_texture[1], 1, dataU, linesizeU);
} updateTexture(m_texture[2], 2, dataV, linesizeV);
QOpenGLPixelTransferOptions options;
if (m_textureY->isStorageAllocated()) {
options.setRowLength(linesizeY);
m_textureY->setData(QOpenGLTexture::Luminance, QOpenGLTexture::UInt8,dataY, &options);
}
if (m_textureU->isStorageAllocated()) {
options.setRowLength(linesizeU);
m_textureU->setData(QOpenGLTexture::Luminance, QOpenGLTexture::UInt8,dataU, &options);
}
if (m_textureV->isStorageAllocated()) {
options.setRowLength(linesizeV);
m_textureV->setData(QOpenGLTexture::Luminance, QOpenGLTexture::UInt8,dataV, &options);
}
update(); update();
} }
@ -149,23 +119,21 @@ void QYUVOpenGLWidget::initializeGL()
void QYUVOpenGLWidget::paintGL() void QYUVOpenGLWidget::paintGL()
{ {
if (m_frameSize.isEmpty()) {
return;
}
if (m_needUpdate) { if (m_needUpdate) {
//TODO 需要deInitTextures吗
deInitTextures();
initTextures(); initTextures();
m_needUpdate = false; m_needUpdate = false;
} }
if (m_textureY->isStorageAllocated()) { glActiveTexture(GL_TEXTURE0);
m_textureY->bind(0); glBindTexture(GL_TEXTURE_2D, m_texture[0]);
}
if (m_textureU->isStorageAllocated()) { glActiveTexture(GL_TEXTURE1);
m_textureU->bind(1); glBindTexture(GL_TEXTURE_2D, m_texture[1]);
}
if (m_textureV->isStorageAllocated()) { glActiveTexture(GL_TEXTURE2);
m_textureV->bind(2); glBindTexture(GL_TEXTURE_2D, m_texture[2]);
}
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
@ -211,54 +179,41 @@ void QYUVOpenGLWidget::initShader()
void QYUVOpenGLWidget::initTextures() void QYUVOpenGLWidget::initTextures()
{ {
deInitTextures(); // 创建纹理
if (m_textureY) { glGenTextures(1, &m_texture[0]);
m_textureY->create(); glBindTexture(GL_TEXTURE_2D, m_texture[0]);
m_textureY->setSize(m_frameSize.width(), m_frameSize.height()); // 设置纹理缩放时的策略
// 设置纹理缩放时的策略 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
m_textureY->setMinificationFilter(QOpenGLTexture::Linear); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
m_textureY->setMagnificationFilter(QOpenGLTexture::Linear); // 设置st方向上纹理超出坐标时的显示策略
// 设置所有方向上纹理超出坐标时的显示策略(也可单个方向单独设置) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
m_textureY->setWrapMode(QOpenGLTexture::ClampToEdge); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
m_textureY->setMipLevels(1); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, m_frameSize.width(), m_frameSize.height(), 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
m_textureY->setFormat(QOpenGLTexture::LuminanceFormat);
m_textureY->allocateStorage(QOpenGLTexture::Luminance, QOpenGLTexture::UInt8);
}
if (m_textureU) { glGenTextures(1, &m_texture[1]);
m_textureU->create(); glBindTexture(GL_TEXTURE_2D, m_texture[1]);
m_textureU->setSize(m_frameSize.width()/2, m_frameSize.height()/2); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
m_textureU->setMinificationFilter(QOpenGLTexture::Linear); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
m_textureU->setMagnificationFilter(QOpenGLTexture::Linear); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
m_textureU->setWrapMode(QOpenGLTexture::ClampToEdge); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
m_textureU->setMipLevels(1); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, m_frameSize.width()/2, m_frameSize.height()/2, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
m_textureU->setFormat(QOpenGLTexture::LuminanceFormat);
m_textureU->allocateStorage(QOpenGLTexture::Luminance, QOpenGLTexture::UInt8); glGenTextures(1, &m_texture[2]);
} glBindTexture(GL_TEXTURE_2D, m_texture[2]);
// 设置纹理缩放时的策略
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// 设置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);
if (m_textureV) {
m_textureV->create();
m_textureV->setSize(m_frameSize.width()/2, m_frameSize.height()/2);
m_textureV->setMinificationFilter(QOpenGLTexture::Linear);
m_textureV->setMagnificationFilter(QOpenGLTexture::Linear);
m_textureV->setWrapMode(QOpenGLTexture::ClampToEdge);
m_textureV->setMipLevels(1);
m_textureV->setFormat(QOpenGLTexture::LuminanceFormat);
m_textureV->allocateStorage(QOpenGLTexture::Luminance, QOpenGLTexture::UInt8);
}
} }
void QYUVOpenGLWidget::deInitTextures() void QYUVOpenGLWidget::deInitTextures()
{ {
if (m_textureY) { glDeleteTextures(3, m_texture);
m_textureY->destroy(); memset(m_texture, 0, 3);
}
if (m_textureU) {
m_textureU->destroy();
}
if (m_textureV) {
m_textureV->destroy();
}
} }
void QYUVOpenGLWidget::updateTexture(GLuint texture, quint32 textureType, quint8 *pixels, quint32 stride) void QYUVOpenGLWidget::updateTexture(GLuint texture, quint32 textureType, quint8 *pixels, quint32 stride)

View file

@ -1,12 +1,10 @@
#ifndef QYUVOPENGLWIDGET_H #ifndef QYUVOPENGLWIDGET_H
#define QYUVOPENGLWIDGET_H #define QYUVOPENGLWIDGET_H
#include <QOpenGLWidget> #include <QOpenGLWidget>
#include <QOpenGLFunctions> #include <QOpenGLFunctions>
#include <QOpenGLShaderProgram> #include <QOpenGLShaderProgram>
#include <QOpenGLBuffer> #include <QOpenGLBuffer>
QT_FORWARD_DECLARE_CLASS(QOpenGLTexture)
class QYUVOpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions class QYUVOpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{ {
Q_OBJECT Q_OBJECT
@ -43,9 +41,7 @@ private:
QOpenGLShaderProgram m_shaderProgram; QOpenGLShaderProgram m_shaderProgram;
// YUV纹理用于生成纹理贴图 // YUV纹理用于生成纹理贴图
QOpenGLTexture* m_textureY = Q_NULLPTR; GLuint m_texture[3] = {0};
QOpenGLTexture* m_textureU = Q_NULLPTR;
QOpenGLTexture* m_textureV = Q_NULLPTR;
}; };
#endif // QYUVOPENGLWIDGET_H #endif // QYUVOPENGLWIDGET_H