QSurfaceFormat 不允许使用 OpenGL 进行绘制

Posted

技术标签:

【中文标题】QSurfaceFormat 不允许使用 OpenGL 进行绘制【英文标题】:QSurfaceFormat does not allow to draw with OpenGL 【发布时间】:2021-12-04 12:04:44 【问题描述】:

当我评论它时,它很好用(我看到一个正方形)没有 QSurfaceFormat:

int main(int argc, char *argv[])

    QApplication a(argc, argv);

//    QSurfaceFormat format;
//    format.setSamples(8);

    Widget w;
//    w.setFormat(format);
    w.show();
    return a.exec();

但是当我取消注释时,代码不会绘制正方形:

int main(int argc, char *argv[])

    QApplication a(argc, argv);

    QSurfaceFormat format;
//    format.setSamples(8);

    Widget w;
    w.setFormat(format);
    w.show();
    return a.exec();

main.cpp

// Add this line to .pro:
// win32: LIBS += -lopengl32

#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif

#include <QtWidgets/QApplication>
#include <QtWidgets/QOpenGLWidget>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QMatrix4x4>
#include <QtGui/QSurfaceFormat>

class Widget : public QOpenGLWidget

public:
    Widget()
    
        setWindowTitle("Square. Qt, OpenGL 3.3, C++");
        setFixedSize(QSize(400, 400));
    

private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
    QOpenGLBuffer m_texCoordBuffer;
    QMatrix4x4 m_mvpMatrix;
    QMatrix4x4 m_projMatrix;
    QMatrix4x4 m_viewMatrix;
    QMatrix4x4 m_modelMatrix;
    int m_uMvpMatrixLocation;

    void initializeGL() override
    
        glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
        const char *vertShaderSrc =
                "#version 330\n"
                "in vec3 aPosition;"
                "uniform mat4 uMvpMatrix;"
                "void main()"
                ""
                "    gl_Position = uMvpMatrix * vec4(aPosition, 1.0);"
                "";
        const char *fragShaderSrc =
                "#version 330\n"
                "out vec4 fragColor;"
                "void main()"
                ""
                "    fragColor = vec4(0.9, 0.9, 1.0, 1.0);"
                "";

        m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
        m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
        m_program.link();
        m_program.bind();

        float vertPositions[] = 
            -0.5f, -0.5f, 0.f,
            0.5f, -0.5f, 0.f,
            -0.5f, 0.5f, 0.f,
            0.5f, 0.5f, 0.f
        ;
        m_vertPosBuffer.create();
        m_vertPosBuffer.bind();
        m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
        m_program.bindAttributeLocation("aPosition", 0);
        m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(0);

        m_viewMatrix.lookAt(QVector3D(0.f, 0.f, 50.f),
                            QVector3D(0.f, 0.f, 0.f),
                            QVector3D(0.f, 1.f, 0.f));
        m_modelMatrix.scale(100.f, 100.f, 100.f);
    

    void paintGL() override
    
        glClear(GL_COLOR_BUFFER_BIT);
        m_mvpMatrix = m_projMatrix * m_viewMatrix * m_modelMatrix;
        m_program.bind();
        m_program.setUniformValue(m_uMvpMatrixLocation, m_mvpMatrix);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    

    void resizeGL(int w, int h) override
    
        glViewport(0, 0, w, h);
        m_projMatrix.setToIdentity();
        m_projMatrix.ortho(-100.f, 100.f, -100.f, 100.f, 100.f, -100.f);
    
;

int main(int argc, char *argv[])

    QApplication a(argc, argv);

    QSurfaceFormat format;
//    format.setSamples(8);

    Widget w;
    w.setFormat(format);
    w.show();
    return a.exec();

【问题讨论】:

无法重现(Linux,Qt5.15.2)。请检查QOpenGLShaderProgram::addShaderFromSourceCode / link / bind 等返回的值。 所有这些方法都返回 true。我也检查了qDebug() &lt;&lt; m_vertPosBuffer.create();qDebug() &lt;&lt; m_vertPosBuffer.bind();。我试图重新创建一个新项目,但它与此源代码相同。但是另一个项目没有这个问题。这是魔术。 @G.M.我之前只做了一件事——我禁用了代码分析器,重新运行 Qt Creator 并编写了这个示例。我试图打开另一个示例,但它们没有这个问题。我无法启用分析器,因为我在插件列表中看不到他。我的笔记本电脑很重。 有些事情看起来不太对劲。首先,您的着色器代码暗示您使用的是 3.3 核心配置文件,但您似乎没有按照该配置文件的要求创建顶点数组对象。其次,glDrawArrays等各种OpenGL函数入口点如何初始化?您是否在代码的其他地方使用了 gladglew 之类的东西? @G.M.我的项目中只有一个包含源代码的文件 - main.cpp。但是为什么当我评论QSurfaceFormat format;时它会起作用? 【参考方案1】:

我发现了我的愚蠢错误。我只是忘记获取 uMvpMatrix 的统一位置:m_uMvpMatrixLocation = m_program.uniformLocation("uMvpMatrix");

main.cpp

// Add this line to .pro:
// win32: LIBS += -lopengl32

#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif

#include <QtWidgets/QApplication>
#include <QtWidgets/QOpenGLWidget>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QMatrix4x4>
#include <QtGui/QSurfaceFormat>

class Widget : public QOpenGLWidget

    Q_OBJECT
public:
    Widget()
    
        setWindowTitle("Rectangle. Qt, OpenGL 3.3, C++");
        setFixedSize(QSize(400, 400));
        resize(400, 400);
    

private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
    QOpenGLBuffer m_texCoordBuffer;
    QMatrix4x4 m_mvpMatrix;
    QMatrix4x4 m_projMatrix;
    QMatrix4x4 m_viewMatrix;
    QMatrix4x4 m_modelMatrix;
    int m_uMvpMatrixLocation;

    void initializeGL() override
    
        glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
        glEnable(GL_DEPTH_TEST);
        const char *vertShaderSrc =
                "#version 330\n"
                "in vec3 aPosition;"
                "uniform mat4 uMvpMatrix;"
                "void main()"
                ""
                "    gl_Position = uMvpMatrix * vec4(aPosition, 1.0);"
                "";
        const char *fragShaderSrc =
                "#version 330\n"
                "out vec4 fragColor;"
                "void main()"
                ""
                "    fragColor = vec4(0.9, 0.9, 1.0, 1.0);"
                "";

        m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
        m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
        m_program.link();
        m_program.bind();

        m_uMvpMatrixLocation = m_program.uniformLocation("uMvpMatrix");

        float vertPositions[] = 
            -0.5f, -0.5f, 0.f,
            0.5f, -0.5f, 0.f,
            -0.5f, 0.5f, 0.f,
            0.5f, 0.5f, 0.f
        ;
        m_vertPosBuffer.create();
        m_vertPosBuffer.bind();
        m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
        m_program.bindAttributeLocation("aPosition", 0);
        m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3);
        m_program.enableAttributeArray(0);

        m_viewMatrix.lookAt(QVector3D(0.f, 0.f, 50.f),
                            QVector3D(0.f, 0.f, 0.f),
                            QVector3D(0.f, 1.f, 0.f));
        m_modelMatrix.translate(QVector3D(0.f, 0.f, 0.f));
        m_modelMatrix.rotate(20.f, QVector3D(0.f, 0.f, 1.f));
        m_modelMatrix.scale(50.f, 70.f, 1.f);
    

    void paintGL() override
    
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        m_mvpMatrix = m_projMatrix * m_viewMatrix * m_modelMatrix;
        m_program.bind();
        m_program.setUniformValue(m_uMvpMatrixLocation, m_mvpMatrix);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    

    void resizeGL(int w, int h) override
    
        glViewport(0, 0, w, h);
        m_projMatrix.setToIdentity();
        m_projMatrix.ortho(-100.f, 100.f, -100.f, 100.f, 100.f, -100.f);
    
;

#include "main.moc"

int main(int argc, char *argv[])

    QApplication a(argc, argv);

    QSurfaceFormat format;
    format.setSamples(8);

    Widget w;
    w.setFormat(format);
    QSurfaceFormat::setDefaultFormat(format);
    w.show();
    return a.exec();

【讨论】:

以上是关于QSurfaceFormat 不允许使用 OpenGL 进行绘制的主要内容,如果未能解决你的问题,请参考以下文章

对 ios7 的 shm_open 调用现在导致在 O_CREAT (EPERM) 期间不允许操作

IE浏览器在弹出窗口时提示:不支持此接口 window.open()方法是啥原因,以前用得挺好的

SQL SERVER2000不允许远程连接问题

使用with open语句(未完)

使用 read()、write()、open() 将文件的内容复制到另一个文件

[python] open()与with open()