diff --git a/src/main.cpp b/src/main.cpp index 23767c6..815dc61 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,7 +17,7 @@ int main(int argc, char *argv[]) qputenv("QTSCRCPY_SERVER_PATH", "G:\\mygitcode\\QtScrcpy\\src\\scrcpy-server.jar"); Dialog w; - //w.move(50, 930); + w.move(50, 930); w.show(); return a.exec(); diff --git a/src/qyuvopenglwidget.cpp b/src/qyuvopenglwidget.cpp index 6ad983d..e176403 100644 --- a/src/qyuvopenglwidget.cpp +++ b/src/qyuvopenglwidget.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "qyuvopenglwidget.h" @@ -64,7 +65,9 @@ static QString s_fragShader = R"( 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() @@ -72,6 +75,19 @@ QYUVOpenGLWidget::~QYUVOpenGLWidget() makeCurrent(); m_vbo.destroy(); 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(); } @@ -95,9 +111,19 @@ void QYUVOpenGLWidget::setFrameSize(const QSize &frameSize) void QYUVOpenGLWidget::updateTextures(quint8 *dataY, quint8 *dataU, quint8 *dataV, quint32 linesizeY, quint32 linesizeU, quint32 linesizeV) { - updateTexture(m_texture[0], 0, dataY, linesizeY); - updateTexture(m_texture[1], 1, dataU, linesizeU); - updateTexture(m_texture[2], 2, dataV, linesizeV); + if (m_textureY->textureId()) { + QOpenGLPixelTransferOptions options; + options.setRowLength(linesizeY); + m_textureY->setData(QOpenGLTexture::Red, QOpenGLTexture::UInt8,dataY, &options); + options.setRowLength(linesizeU); + m_textureU->setData(QOpenGLTexture::Red, QOpenGLTexture::UInt8,dataU, &options); + options.setRowLength(linesizeV); + m_textureV->setData(QOpenGLTexture::Red, QOpenGLTexture::UInt8,dataV, &options); + } + + //updateTexture(m_texture[0], 0, dataY, linesizeY); + //updateTexture(m_texture[1], 1, dataU, linesizeU); + //updateTexture(m_texture[2], 2, dataV, linesizeV); update(); } @@ -121,10 +147,17 @@ void QYUVOpenGLWidget::paintGL() { if (m_needInit) { //TODO 需要deInitTextures吗 - initTextures(); + initTextures(); m_needInit = false; } + + if (m_textureY->textureId()) { + m_textureY->bind(0); + m_textureU->bind(1); + m_textureV->bind(2); + } + /* glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_texture[0]); @@ -133,6 +166,7 @@ void QYUVOpenGLWidget::paintGL() glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, m_texture[2]); + */ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -178,15 +212,43 @@ void QYUVOpenGLWidget::initShader() void QYUVOpenGLWidget::initTextures() { + deInitTextures(); + if (m_textureY) { + m_textureY->create(); + m_textureY->setSize(m_frameSize.width(), m_frameSize.height()); + // 设置纹理缩放时的策略 + m_textureY->setMinificationFilter(QOpenGLTexture::Linear); + m_textureY->setMagnificationFilter(QOpenGLTexture::Linear); + // 设置所有方向上纹理超出坐标时的显示策略(也可单个方向单独设置) + m_textureY->setWrapMode(QOpenGLTexture::ClampToEdge); + m_textureY->setMipLevels(1); + m_textureY->setFormat(QOpenGLTexture::R8_UNorm); + m_textureY->allocateStorage(); + } + + if (m_textureU) { + m_textureU->create(); + m_textureU->setSize(m_frameSize.width()/2, m_frameSize.height()/2); + m_textureU->setMinificationFilter(QOpenGLTexture::Linear); + m_textureU->setMagnificationFilter(QOpenGLTexture::Linear); + m_textureU->setWrapMode(QOpenGLTexture::ClampToEdge); + m_textureU->setMipLevels(1); + m_textureU->setFormat(QOpenGLTexture::R8_UNorm); + m_textureU->allocateStorage(); + } + + 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::R8_UNorm); + m_textureV->allocateStorage(); + } + /* - // 创建纹理 - m_textrueY = new QOpenGLTexture(QOpenGLTexture::Target2D); - // 设置纹理缩放时的策略 - m_textrueY->setMinificationFilter(QOpenGLTexture::Linear); - m_textrueY->setMagnificationFilter(QOpenGLTexture::Linear); - // 设置所有方向上纹理超出坐标时的显示策略(也可单个方向单独设置) - m_textrueY->setWrapMode(QOpenGLTexture::ClampToEdge); -*/ // 创建纹理 glGenTextures(1, &m_texture[0]); glBindTexture(GL_TEXTURE_2D, m_texture[0]); @@ -215,13 +277,21 @@ void QYUVOpenGLWidget::initTextures() 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); - + */ } void QYUVOpenGLWidget::deInitTextures() { - glDeleteTextures(3, m_texture); - memset(m_texture, 0, 3); + if (m_textureY) { + m_textureY->destroy(); + } + if (m_textureU) { + m_textureU->destroy(); + } + if (m_textureV) { + m_textureV->destroy(); + } + } void QYUVOpenGLWidget::updateTexture(GLuint texture, quint32 textureType, quint8 *pixels, quint32 stride) diff --git a/src/qyuvopenglwidget.h b/src/qyuvopenglwidget.h index bfc3fef..338aa0a 100644 --- a/src/qyuvopenglwidget.h +++ b/src/qyuvopenglwidget.h @@ -5,7 +5,7 @@ #include #include -//QT_FORWARD_DECLARE_CLASS(QOpenGLTexture) //TODO先不用QOpenGLTexture,Texture先使用opengl原生方式 +QT_FORWARD_DECLARE_CLASS(QOpenGLTexture) class QYUVOpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions { Q_OBJECT @@ -42,9 +42,9 @@ private: QOpenGLShaderProgram m_shaderProgram; // YUV纹理,用于生成纹理贴图 - //QOpenGLTexture* m_textrueY = Q_NULLPTR; - //QOpenGLTexture* m_textrueU = Q_NULLPTR; - //QOpenGLTexture* m_textrueV = Q_NULLPTR; + QOpenGLTexture* m_textureY = Q_NULLPTR; + QOpenGLTexture* m_textureU = Q_NULLPTR; + QOpenGLTexture* m_textureV = Q_NULLPTR; // YUV纹理,用于生成纹理贴图 GLuint m_texture[3] = {0};