Qt & OpenGL, не удается отключить Vsync и порвать фрейм - PullRequest
0 голосов
/ 19 октября 2019

Используя QT и OpenGL под Windows 10, я пытаюсь отрисовать одиночный буфер и выключить VSync. Я просто переключаюсь между полноэкранным белым и полноэкранным черным, и я ожидаю увидеть некоторые разрывы, но я не вижу.

Вот мой код:

main.cpp:

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.showFullScreen();
    return a.exec();
}

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QOpenGLFunctions>
#include <QWindow>

class MainWindow : public QWindow, protected QOpenGLFunctions
{
    Q_OBJECT

public:
    MainWindow(QWindow *parent = nullptr);
    ~MainWindow();

public slots:

    void renderNow();

private:
    QOpenGLContext *m_context;
    QTimer *m_render_timer;
};
#endif // MAINWINDOW_H

mainwindow.cpp:

#include "mainwindow.h"

#include <QTimer>
#include <QDebug>

MainWindow::MainWindow(QWindow *parent)
    : QWindow(parent)
    , m_context(nullptr)
    , m_render_timer(nullptr)
{
    setSurfaceType(QWindow::OpenGLSurface);

    m_render_timer = new QTimer(this);
    connect(m_render_timer, SIGNAL(timeout()), this, SLOT(renderNow()));
    m_render_timer->start(3); //time specified in ms
}

MainWindow::~MainWindow()
{
    delete m_render_timer;
    delete m_context;
}

bool colorswap = false;
void MainWindow::renderNow() {
    if(!m_context){
        m_context = new QOpenGLContext(this);
        QSurfaceFormat fmt = QSurfaceFormat::defaultFormat();
        fmt.setDepthBufferSize(0);
        fmt.setVersion(3,1);
        fmt.setRenderableType(QSurfaceFormat::OpenGL); //can try openGLES too
        fmt.setSamples(0);
        fmt.setStencilBufferSize(0);
        fmt.setSwapBehavior(QSurfaceFormat::SingleBuffer);
        fmt.setSwapInterval(0); //turn off vsync;
        m_context->setFormat(fmt);
        qDebug() << "requested format:\n" << m_context->format();
        m_context->create();
        qDebug() << "\n\nactual format:\n" << m_context->format();
        m_context->makeCurrent(this);
        initializeOpenGLFunctions();
    }
    if(colorswap)
        glClearColor(255,255,255,255);
    else
        glClearColor(0,0,0,255);
    colorswap = !colorswap;
    glClear(GL_COLOR_BUFFER_BIT);

    glFlush();
}

Интересно, что даже после вызова m_context-> я запрашиваю swapInterval, равный 0. Создайте();вместо swapInterval указано значение 1. В соответствии с этим потоком Qt 5: отключить vsync сообщаемое значение 1 может не совпадать с тем, что было фактически установлено. Но, тем не менее, я не получаю никакого разрыва кадра.

Я также щелкнул правой кнопкой мыши по exe-файлу, зашел в свойства-> совместимость и выбрал «отключить полноэкранную оптимизацию» (поскольку я прочитал это без этой опции,приложения не получают «истинный» полноэкранный режим, а только полноэкранный режим без рамки), но все еще не разрывают фреймы.

Что еще мне нужно сделать, чтобы сделать рендеринг с одиночной буферизацией без vsync? (пожалуйста, не спрашивайте ПОЧЕМУ - я просто хочу это).

// edit: Я также только что узнал, что все еще вижу курсор мыши, так что это не может быть правдой OpenGL в полноэкранном режиме. Как мне получить настоящий полноэкранный OpenGL в Qt?

...