opengl 无法在macos Ventura 13上渲染[已关闭]

ahy6op9u  于 2023-01-08  发布在  Mac
关注(0)|答案(1)|浏览(321)

编辑问题以包含desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将有助于其他人回答问题。
昨天关门了。
Improve this question
我用qt 6.4创建了一个应用程序渲染yuv图像与QOpenGLWidget.代码工作正常,在windows 10,但没有渲染任何在我的macbook pro(英特尔芯片,Ventura 13.1),并没有报告任何错误.
下面是我的代码:
主要内容:cpp:

#include "mainwindow.h"

#include <QApplication>
#include <QSurfaceFormat>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);

    QSurfaceFormat glFormat;
    glFormat.setVersion(4, 1);
    glFormat.setProfile(QSurfaceFormat::CoreProfile);
    glFormat.setSwapBehavior (QSurfaceFormat::DoubleBuffer);
    glFormat.setRenderableType (QSurfaceFormat::OpenGL);
    QSurfaceFormat::setDefaultFormat(glFormat);

    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

从屏幕h:

#include "QtOpenGLWidgets/qopenglwidget.h"
#include <QOpenGLWidget>
#include <QOpenGLShaderProgram>
#include <QOpenGLFunctions>
#include <QOpenGLTexture>
#include <QTimer>
#include <QFile>

namespace Ui {
class FrmScreen;
}

#define GET_STR(x) #x
#define A_VER 3
#define T_VER 4

class FrmScreen : public QOpenGLWidget, protected QOpenGLFunctions
{
    Q_OBJECT

public:
    explicit FrmScreen(QWidget *parent = nullptr);
    ~FrmScreen();

    void displayImage(QString imgPath);
    void displayYuvImage(QString yuvPath);

protected:
    void initializeGL() Q_DECL_OVERRIDE;
    void resizeGL(int w, int h) Q_DECL_OVERRIDE;
    void paintGL() Q_DECL_OVERRIDE;

private:
    Ui::FrmScreen *ui;
    QString _img_path;

    QOpenGLShaderProgram program;    

    GLuint unis[3] = {0};           
    GLuint texs[3] = {0};           

    int width = 2688;
    int height = 1520;

    QFile m_file;
    QByteArray m_buf;  

};

#endif // FRMSCREEN_H

FrmScreen.cpp:

#include "FrmScreen.h"
#include "QtGui/qpainter.h"
#include "ui_FrmScreen.h"

FrmScreen::FrmScreen(QWidget *parent) :
    QOpenGLWidget(parent),
    ui(new Ui::FrmScreen)
{
    _img_path = "./frames/frame000.yuv";
    ui->setupUi(this);

}

const char* vString =
        "#version 410\n"
        "in vec4 vertexIn;\n"
        "in vec2 textureIn;\n"
        "out vec2 textureOut;\n"
        "void main(void)\n"
        "{\n"
        "    gl_Position = vertexIn;\n"
        "    textureOut = textureIn;\n"
        "}";

const char* tString = "#version 410\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"
                      "    vec3 yuv;\n"
                      "    vec3 rgb;\n"
                      "    yuv.x = texture(tex_y, textureOut).r;\n"
                      "    yuv.y = texture(tex_u, textureOut).r - 0.5;\n"
                      "    yuv.z = texture(tex_v, textureOut).r - 0.5;\n"
                      "    rgb = mat3( 1,       1,         1,\n"
                      "               0,       -0.21482,  2.12798,\n"
                      "               1.28033, -0.38059,  0) * yuv;\n"
                      "    fragColor = vec4(rgb, 1);\n"
                      "}";

FrmScreen::~FrmScreen()
{
    delete ui;
}

void FrmScreen::initializeGL()
{
    initializeOpenGLFunctions();

    qDebug() << "load fragment:" <<program.addShaderFromSourceCode(QOpenGLShader::Fragment, tString);  
    qDebug() << "load shader:" <<program.addShaderFromSourceCode(QOpenGLShader::Vertex, vString);    

    program.bindAttributeLocation("vertexIn", A_VER);
    program.bindAttributeLocation("textureIn", T_VER);
    qDebug() << "compile shader:" << program.link();
    qDebug() << "bind shader:" << program.bind();

    static const GLfloat ver[] = {
        -1.0f, -1.0f,
        1.0f, -1.0f,
        -1.0f, 1.0f,
        1.0f, 1.0f
    };
    static const GLfloat tex[] = {
        0.0f, 1.0f,
        1.0f, 1.0f,
        0.0f, 0.0f,
        1.0f, 0.0f
    };

    glVertexAttribPointer(A_VER, 2, GL_FLOAT, 0, 0, ver); 
    glEnableVertexAttribArray(A_VER); 
    glVertexAttribPointer(T_VER, 2, GL_FLOAT, 0, 0, tex);  
    glEnableVertexAttribArray(T_VER); 

    unis[0] = program.uniformLocation("tex_y");
    unis[1] = program.uniformLocation("tex_u");
    unis[2] = program.uniformLocation("tex_v");

    glGenTextures(3, texs);
    // Y
    glBindTexture(GL_TEXTURE_2D, texs[0]);   
    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, height, 0, GL_RED, GL_UNSIGNED_BYTE, 0);

    //  U
    glBindTexture(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);   

    glBindTexture(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);   

    glClearColor(0.3, 0.3, 0.3, 0.0); 

    m_file.setFileName(_img_path);
    if(!m_file.open(QIODevice::ReadOnly))
    {
        qDebug() << "open yuv file failed";
        return;
    }
}

void FrmScreen::paintGL()
{

    if(m_file.atEnd())
    {
        m_file.seek(0);
    }
    QByteArray buf = m_file.read(width * height);

    glActiveTexture(GL_TEXTURE0);   
    glBindTexture(GL_TEXTURE_2D, texs[0]);  
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RED, GL_UNSIGNED_BYTE, buf.data());
    glUniform1i(unis[0], 0);   

    buf = m_file.read(width * height / 4);
    glActiveTexture(GL_TEXTURE1);   
    glBindTexture(GL_TEXTURE_2D, texs[1]);  
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RED, GL_UNSIGNED_BYTE, buf.data());
    glUniform1i(unis[1], 1);   

    buf = m_file.read(width * height / 4);
    glActiveTexture(GL_TEXTURE2);  
    glBindTexture(GL_TEXTURE_2D, texs[2]);  
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RED, GL_UNSIGNED_BYTE, buf.data());
    glUniform1i(unis[2], 2);   

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 
    return;
}

void FrmScreen::resizeGL(int width, int height)
{
    if (height == 0) 
    {
        height = 1;  
    }

    glViewport(0, 0, width, height);
}

void FrmScreen::displayYuvImage(QString yuvPath)
{
    _img_path = yuvPath;
    update();
}

void FrmScreen::displayImage(QString imgPath)
{
    _img_path = imgPath;
    update();
}

为什么代码在macos上不能正常工作?

628mspwn

628mspwn1#

在Mac上,您必须使用OpenGL 4.1 Core配置文件context,并设置向前兼容标志。在Qt 6上,这可以通过关闭QSurfaceFormat::DeprecatedFunctions来实现:

QSurfaceFormat glFormat;
glFormat.setVersion(4, 1);
glFormat.setProfile(QSurfaceFormat::CoreProfile);
glFormat.setOption(QSurfaceFormat::DeprecatedFunctions, false);
glFormat.setRenderableType(QSurfaceFormat::OpenGL);

着色器版本应为#version 410 core

相关问题