简体   繁体   中英

Qt initializeOpenGLFunctions crashes application

So I've created test app to develop some OpenGL-Qt knowledge.

Here is my complete code so far.

Mi main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.0

Window {
    visible: true
    width: 1000
    height: 600
    title: qsTr("Qt-QML-VR Tester")

    Column{

        width: 100
        spacing: 10
        anchors.centerIn: parent

        Button {
            id: startTest
            width: parent.width
            height: 50
            text: "Start Test"
            onClicked: {
                control.startTest();
            }
        }

        Button {
            id: stopTest
            width: parent.width
            height: 50
            text: "Stop Test"
            onClicked: {
                control.stopTest();
            }
        }

    }

}

Mi main.cpp

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "control.h"

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

    QApplication app(argc, argv);

    Control control(nullptr);

    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);

    engine.rootContext()->setContextProperty("control",&control);

    engine.load(url);

    return app.exec();
}

My control.h

#ifndef CONTROL_H
#define CONTROL_H

#include <QObject>
#include <QDebug>
#include <QGuiApplication>
#include <QScreen>
#include <QTimer>
#include <QOpenGLFunctions>
#include <QMatrix4x4>
#include <QOpenGLShaderProgram>

#include "targettest.h"


class Control : public QObject, protected QOpenGLFunctions
{
    Q_OBJECT
public:
    explicit Control(QObject *parent = nullptr);
    ~Control();

    Q_INVOKABLE void startTest();
    Q_INVOKABLE void stopTest();

private:

    // Open GL Related variables.
    QOpenGLContext *openGLContext;
    //QOffscreenSurface *offscreenSurface;
    QOpenGLShaderProgram *shaderProgram;
    GLuint glid_PosAttr;
    GLuint glid_PerpectiveMatrix;
    bool initializeOpenGL();


    // Other variables and functions.
    bool systemInitialized;
    bool doIntialization();

};

My control.cpp

#include "control.h"

const char * Control::vertexShaderSource =
        "attribute highp vec4 posAttr;\n"
        "attribute highp vec4 colAttr;\n"
        "varying highp vec2 texCoord;\n"
        "uniform highp mat4 matrix;\n"
        "void main() {\n"
        "   texCoord = posAttr.xy;\n"
        "   gl_Position = matrix * posAttr;\n"
        "}\n";

const char * Control::fragmentShaderSource =
        "varying highp vec2 texCoord;\n"
        "uniform sampler2D ourTexture;\n"
        "void main() {\n"
        //        "   gl_FragColor = texture2D(ourTexture, texCoord);\n"
        //        "   gl_FragColor = vec4(1.0,1.0,1.0,1.0);\n"
        "   gl_FragColor = vec4(texCoord.x,texCoord.y,0.0,1.0);\n"
        "}\n";

Control::Control(QObject *parent) : QObject(parent)
{
    systemInitialized = false;
}


/////////////////////////////// INTIALIZATION FUNCTIONS
bool Control::initializeOpenGL(){

    QSurfaceFormat format;
    format.setMajorVersion( 4 );
    format.setMinorVersion( 1 );
    format.setProfile( QSurfaceFormat::CompatibilityProfile );

    openGLContext = new QOpenGLContext();
    openGLContext->setFormat( format );
    if( !openGLContext->create() ){
        qDebug() << "Open GL Context initialization failed";
        return false;
    }

    qDebug() << "Before";
    initializeOpenGLFunctions();
    qDebug() << "After";

    shaderProgram = new QOpenGLShaderProgram(this);
    if (!shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource)){
        qDebug() << "ERROR compiling vertex shader";
        qDebug() << shaderProgram->log();
        return false;
    }
    if (!shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource)){
        qDebug() << "ERROR compiling fragment shader";
        qDebug() << shaderProgram->log();
        return false;
    }
    shaderProgram->link();
    glid_PosAttr = static_cast<GLuint>(shaderProgram->attributeLocation("posAttr"));
    glid_PerpectiveMatrix = static_cast<GLuint>(shaderProgram->uniformLocation("matrix"));
    return true;
}


bool Control::doIntialization(){
    if (!initializeOpenGL()) return false;
    qDebug() << "Open GL Initialized";
    return true;
}


////////////////////////////////////////// CONTROL FUNCTIONS
void Control::startTest(){
    if (!systemInitialized){
        if (!doIntialization()){
            qDebug() << "INITIALIZATION FAILED";
            return;
        }
        systemInitialized = true;
    }
    timer.start(10);
    qDebug() << "Started rendering";
}


void Control::stopTest(){
    timer.stop();
    qDebug() << "Stopped rendering";
}


Control::~Control(){
}

However the program crashes when reaching intializeOpenGLFunctions. What am I doing wrong?

At the point at which QOpenGLFunctions::initializeOpenGLFunctions() is called a valid OpenGL context must be in place/current but the code shown only creates the context -- it doesn't call QOpenGLContext::makeCurrent .

Try adding the following immediately before the call to initializeOpenGLFunctions ...

auto *surface = new QOffscreenSurface;
surface->setFormat(format);
surface->create();
openGLContext->makeCurrent(surface);

(If it works then obviously you'll probably want to make surface a private member of Control .)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM