Qt:glClear不适用于OpenGL上的重绘

时间:2017-09-25 17:17:23

标签: c++ qt opengl qpainter

问题

QPainter之后创建glClear后,后者无效。

描述

我使用Qt 5.7.1。我在Linux上使用gcc和在Windows上使用vc ++获得相同的结果。

我在从QGLWidget派生的小部件中有以下内容:

void CanvasWidget::initializeGL()
{
    qglClearColor(m_backgroundColor);
}

V1:

void CanvasWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);
    QPainter painter(this);
    painter.drawLine(0, 0, 1000, 1000);
}

制作:

enter image description here

V2:

void CanvasWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);
}

制作:

enter image description here

我想要的是:

enter image description here

可以通过hack完成:

void CanvasWidget::paintGL()
{
    QPainter painter(this);
    qglClearColor(m_backgroundColor);
    glClear(GL_COLOR_BUFFER_BIT);
    painter.drawLine(0, 0, 1000, 1000);
}

问题

发生了什么事?为什么glCleanQPainter无法一起工作?为什么我不能用V1获得它?

最小可重复示例

  

的main.cpp

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

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MainWindow mainwindow;
    mainwindow.show();
    return app.exec();
}
  

MainWindow.h

#pragma once

#include "CanvasWidget.h"
#include <QMainWindow>
#include <memory>

class MainWindow : public QMainWindow
{
public:
    explicit MainWindow(QWidget *parent = 0);

    MainWindow(const MainWindow &) = delete;
    MainWindow & operator= (const MainWindow &) = delete;
    virtual ~MainWindow() = default;

private:
    std::unique_ptr<CanvasWidget> m_canvasWidget;
};
  

MainWindow.cpp

#include "MainWindow.h"
#include <QHBoxLayout>

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , m_canvasWidget(new CanvasWidget(parent))
{
    setCentralWidget(m_canvasWidget.get());
}
  

CanvasWidget.h

#pragma once

#include <QGLWidget>

class CanvasWidget : public QGLWidget
{
    Q_OBJECT
public:
    CanvasWidget(QWidget* parent = 0, const QGLWidget* shareWidget = 0, Qt::WindowFlags f = 0);
private:
    virtual void initializeGL() override;
    virtual void paintGL() override;
private:
    QColor m_backgroundColor;
};
  

CanvasWidget.cpp

#include "CanvasWidget.h"
#include <QMessageBox>
#include <QWheelEvent>

CanvasWidget::CanvasWidget(
    QWidget* parent /*= 0*/,
    const QGLWidget* shareWidget /*= 0*/,
    Qt::WindowFlags f /*= 0 */)
    : QGLWidget(parent, shareWidget, f)
    , m_backgroundColor(0, 93, 196)
{}

void CanvasWidget::initializeGL()
{
    qglClearColor(m_backgroundColor);
}

void CanvasWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);
    QPainter painter(this);
    painter.drawLine(0, 0, 1000, 1000);
}

2 个答案:

答案 0 :(得分:1)

setAutoFillBackground(false)构造函数中添加CanvasWidget可以解决问题。

所有功劳都归功于@ G.M。

答案 1 :(得分:0)

Qt tutorial关于用QPainter重写OpenGL的问题,请说明:

  

当将2D内容过度绘制到3D内容上时,我们需要使用a   QPainter并进行OpenGL调用以达到预期效果。以来   在QGLWidget子类上使用时,QPainter本身使用OpenGL调用,   我们需要在执行时保留各种OpenGL堆栈的状态   我们自己的电话

所以,看看V1中的代码,我认为QPainter设置了自己的清晰颜色状态,如果你没有明确设置glClearColor,你将得到QPainter对象设置的内容。 我还建议您使用RenderDocgDebugger等工具来跟踪应用的GL命令,以确切了解幕后发生的情况。