【问题标题】:QPainter and OpenGL native code in QOpenGLWidget classQOpenGLWidget 类中的 QPainter 和 OpenGL 本机代码
【发布时间】:2015-04-14 08:48:48
【问题描述】:

我正在准备一个桌面应用程序来绘制一些 2D 绘图。我正在使用 C++:Qt 5 和 Visual Studio 2013。我创建了一个简单的 GUI 并将 myQOpenGLWidget 放入其中。我已经在使用我自己的 openGl 着色器绘制绘图、轴和刻度。一切正常,现在我想将描述添加到我的轴和刻度中,以使图表可以分析。由于 OpenGL 本身没有渲染文本的专用函数,我想出使用 QPainter 对象只是为了将所需的描述添加到已创建的绘图中。这里开始出现问题......

这是我的 QopenGLWidget 实现的功能:

void GLWidget::initializeGL() {
initializeOpenGLFunctions();
glEnable(GL_POINT_SPRITE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

vertexShad = new QOpenGLShader(QOpenGLShader::Vertex);
fragmentShad = new QOpenGLShader(QOpenGLShader::Fragment);

bool flag = vertexShad->compileSourceFile(QString("vs.glsl"));
if (flag) printf("compiled vertex Shader\n");
flag = fragmentShad->compileSourceFile(QString("fs.glsl"));
if (flag) printf("compiled fragment Shader\n");
flag = program.addShader(vertexShad);
if (flag) printf("linked vertex Shader\n");
flag = false;
flag =program.addShader(fragmentShad);
if (flag) printf("linked fragment Shader\n");

program.link();
program.bind();
}

油漆GL:

void GLWidget::paintGL() {
painter = new QPainter(this);

painter->beginNativePainting();
glViewport(0, 0, this->width(), this->height());
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
drawAxes();
glViewport(MARGIN, MARGIN, this->width() - MARGIN * 2, this->height() - MARGIN * 2);
glScissor(MARGIN, MARGIN, this->width() - MARGIN * 2, this->height() - MARGIN * 2);
glEnable(GL_SCISSOR_TEST);
  // here are the functions which use native openGL code
  // ...
  // disabling openGL settings
glDisable(GL_SCISSOR_TEST);
glDisable(GL_POINT_SPRITE);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
glDisable(GL_BLEND);
painter->endNativePainting();

drawTicksValues(); // function that uses QPainter
painter->end();
 }

drawTicksValues:

void GLWidget::drawTicksValues() {
char * maxText = new char[4];
sprintf(maxText, "%d", maxY);
char * minText = new char[4];
sprintf(minText, "%d", minY);
painter->drawText(0, MARGIN, QString(maxText));
painter->drawText(0, height() - MARGIN, QString(minText));
painter->drawText(MARGIN, height() - MARGIN + 20, QString("0"));
painter->drawText(width() - MARGIN, height() - MARGIN + 20, QString(100));
}

主要:

int main(int argc, char *argv[])
{
 QApplication a(argc, argv);
 QSurfaceFormat  format;
 format.setSamples(4);
 format.setDepthBufferSize(24);
 format.setStencilBufferSize(8);

 QSurfaceFormat::setDefaultFormat(format);
 SymmGaitModels w;
 w.show();
 return a.exec();
}

不幸的是,当我运行代码时,带有未注释的QPainter 部分,轴和绘图被清除,只显示我用 QPainter 绘制的数字。但如果我评论 QPainter 部分,绘图和轴将正常绘制。有什么建议可以让我使用 QPainter 将文本添加到我的绘图中而不是清除它?

【问题讨论】:

    标签: c++ qt opengl visual-studio-2013 qt5


    【解决方案1】:

    我终于成功了。

    首先,我必须更改和设置格式(您必须在显示小部件之前更改它),例如在 main function 中,在显示我的应用程序之前

    主要:

    int main(int argc, char *argv[])
    {
     QApplication a(argc, argv);
    
     SymmGaitModels w;
       // GLWidget is my implemantation of QOpenGLWidget
     GLWidget* gl = w.findChild<GLWidget*>("OpenGLWidget");
     QSurfaceFormat  format;
     //format.setSamples(4);
     //format.setDepthBufferSize(24);
     //format.setStencilBufferSize(8);
       format.setProfile(QSurfaceFormat::OpenGLContextProfile::CompatibilityProfile);
     QSurfaceFormat::setDefaultFormat(format);
    
     gl->setFormat(format);
     w.show();
     return a.exec();
    }
    

    此外,我必须在我的 openGL 函数之间移动所有(甚至启用和禁用诸如混合、point_sprite 等导致我的问题的东西)

    QPainter-> beginNativePainting()
     ...
    QPainter->endNativePainting();
    

    我必须实现paintEvent 函数。我只是把paintGL() 表达式放在那里。 现在我的函数看起来像这样:

    void GLWidget::initializeGL() {
     printf("autoFILL: %d\n",this->autoFillBackground());
     initializeOpenGLFunctions(); // this function has to stay in initializeGL
     // commented functions below has to be removed and put after beginNativePainting
         //glEnable(GL_POINT_SPRITE);
     //glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
     //glEnable(GL_BLEND);
     //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
       // shaders may be compiled and added here, but program has to be linked and built after beginNativePainting()
     vertexShad = new QOpenGLShader(QOpenGLShader::Vertex);
     fragmentShad = new QOpenGLShader(QOpenGLShader::Fragment);
    
     bool flag = vertexShad->compileSourceFile(QString("vs.glsl"));
     //bool flag = vertexShad->compileSourceCode(vertexShadSrc);
     if (flag) printf("compiled vertex Shader\n");
     flag = fragmentShad->compileSourceFile(QString("fs.glsl"));
     //flag = fragmentShad->compileSourceCode(fragmentShadSrc);
     if (flag) printf("compiled fragment Shader\n");
     flag = program.addShader(vertexShad);
     if (flag) printf("linked vertex Shader\n");
     flag = false;
     flag =program.addShader(fragmentShad);
     if (flag) printf("linked fragment Shader\n");
    }
    
    void GLWidget::paintEvent(QPaintEvent *e) {
     paintGL(); // still this, widget has to be now refreshed by widget->update()
     }
    
    void GLWidget::paintGL() {
     painter = new QPainter(this);
     painter->beginNativePainting();
     //
     glEnable(GL_POINT_SPRITE);
     glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
     glEnable(GL_BLEND);
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
     program.link();
     program.bind();
     //
     glViewport(0, 0, this->width(), this->height());
     glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
     glClear(GL_COLOR_BUFFER_BIT);
     drawAxes();
     glViewport(MARGIN, MARGIN, this->width() - MARGIN * 2, this->height() - MARGIN * 2);
     glScissor(MARGIN, MARGIN, this->width() - MARGIN * 2, this->height() - MARGIN * 2);
     glEnable(GL_SCISSOR_TEST);
     // methods using native openGL functions here
     glDisable(GL_SCISSOR_TEST);
     glDisable(GL_POINT_SPRITE);
     glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
     glDisable(GL_BLEND);
     program.disconnect();
     painter->endNativePainting();
     drawTicksValues();
     painter->end();
    }
    

    添加paintEvent 实现后,现在必须使用widget->update() 刷新openGL 小部件。

    希望它对同时使用 QPainter 和原生 openGL 函数的其他人有所帮助,因为 Qt doc 在这个主题上似乎有点肤浅。

    谢谢! 亚当

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多