【问题标题】:QOpenGLWidget and QPainter ,Can’t render 2D and 3D at the same timeQOpenGLWidget和QPainter,不能同时渲染2D和3D
【发布时间】:2017-03-03 17:56:24
【问题描述】:

我的Qt版本是5.4,我测试了新的类QOpenGWidget,我做Qt助手:把opengl代码放在QPainter::beginNativePainting();/QPainter::endNativePainting(); ,但 2D 不显示。我不知道我的代码有什么问题。这是我的代码:

.h

class Render : public QOpenGLWidget
{
public:
    Render();
    ~Render();
protected:
    void initializeGL();
    void paintGL();
    void resizeGL(int  w ,int h);
    QOpenGLFunctions_3_3_Core * f;
    QOpenGLBuffer * triangle;
    QOpenGLVertexArrayObject * vao;
    QOpenGLShaderProgram * program;
    QMatrix4x4 mv,p;
    QTimer * time;
    float rota;
    QPainter * painter;
    bool needInit;
    //void paintEvent(QPaintEvent *e);

};

.cpp

#include "render.h"
GLfloat tri[] =
{
    0.0f,1.0f,-1.0f,1.0f,
    1.0f,1.0f,-1.0f,1.0f,
    1.0f,0.0f,-1.0f,1.0f,

};
Render::Render()
{
    QSurfaceFormat format;
    format.setDepthBufferSize(24);
    format.setStencilBufferSize(8);
    // format.setVersion(3,3);
    //format.setProfile(QSurfaceFormat::CoreProfile);

    setFormat( format);
    rota = 1.5;
    needInit = true;
    //setAutoFillBackground(false);
    time =  new QTimer;
    connect(time,SIGNAL(timeout()),this,SLOT(update()));
    time->start(50);
}

Render::~Render()
{

}
void Render::initializeGL()
{
    f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();
    f->initializeOpenGLFunctions();

    //f = context()->functions();

}
void Render::resizeGL(int w ,int h)
{

    p.setToIdentity();
    p.perspective(35.0f,float(w)/float(h),1.0f,30.0f);

}

void Render::paintGL()
{
    QPainter pntr(this);
    // painter->setViewport(50,50,100,100);
    pntr.beginNativePainting();
    QOpenGLShaderProgram  programs ;
    programs.addShaderFromSourceCode(QOpenGLShader::Vertex,
                                     "#version 330 core \n\
                                    layout(location = 0) in vec4 vertex;\
           uniform mat4 mvp;\
   void main() \
   {\
       gl_Position = mvp * vertex;\
   }");

    programs.addShaderFromSourceCode(QOpenGLShader::Fragment,
                                     "#version 330 core \n\
                                    out vec4 fragColor;\
           void main() \
   { \
       fragColor = vec4(0.0f,1.0f,0.0f,1.0f);\
   }");
    programs.link();

    QOpenGLVertexArrayObject vaos;
    vaos.create();
    f->glBindVertexArray(vaos.objectId());
    QOpenGLBuffer triangles(QOpenGLBuffer::VertexBuffer);
    triangles.create();
    f->glBindBuffer(GL_ARRAY_BUFFER,triangles.bufferId());
    triangles.setUsagePattern(QOpenGLBuffer::DynamicDraw);
    triangles.allocate(tri,sizeof(tri));
    programs.enableAttributeArray(0);
    programs.setAttributeBuffer(0,GL_FLOAT,0,4,0);

    f->glEnable(GL_DEPTH_TEST);

    needInit = false;

    // this->makeCurrent();
    f->glViewport(0,0,width(),height());
    f->glClearColor(1.0f,0.5f,0.5f,1.0f);
    f->glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

    programs.bind();
    mv.setToIdentity();

    mv.lookAt(QVector3D(0.0f,0.0f,5.0f),QVector3D(0.0f,0.0f,0.0f),QVector3D(0.0f,1.0f,0.0f));
    mv.rotate(0.5+rota,0,1,0);
    programs.setUniformValue("mvp",p*mv);
    f->glBindVertexArray(vaos.objectId());
    f->glDrawArrays(GL_TRIANGLES,0,3);
    rota=rota+1.5;

    pntr.endNativePainting();

    pntr.drawText(50,100,"Look This!");

}

【问题讨论】:

  • 创建程序应该进入initializeGL(同时测试是否成功)
  • 谢谢!我试过了,还是不行。我认为这是 Qt 的一个 BUG。如果我只写 f-&gt;glClearColor(1.0f,0.5f,0.5f,1.0f); f-&gt;glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 文本可以渲染。如果我绘制 3D 的东西,它就不起作用了。

标签: c++ qt opengl


【解决方案1】:

仅当QOpenGLWidgetQSurfaceFormat format 未设置为“核心配置文件”时,QPainter 才能工作。

以下是如何从main 函数设置QSurfaceFormat format:(请注意,您必须从Render 构造函数中删除格式定义)

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

    QApplication a(argc, argv);

    QSurfaceFormat  format;

    format.setSamples(4);
    format.setDepthBufferSize(24);
    format.setStencilBufferSize(8);
    //format.setVersion(3,2);
    //format.setProfile(QSurfaceFormat::CoreProfile);
    QSurfaceFormat::setDefaultFormat(format);


    MainWindow w;
    w.show();

    return a.exec();
}

【讨论】:

    【解决方案2】:

    在开始绘制 2D 内容之前尝试禁用深度测试。

    ...
    glDisable(GL_DEPTH_TEST);
    pntr.endNativePainting();
    ...
    

    我遇到了类似的问题,每当我更新场景时,2D 内容都会消失。添加这一行就解决了。

    【讨论】:

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