qt - 使用 QPainter 时对象是透明的

标签 qt opengl qpainter qopenglwidget

所以我尝试在我的对象上贴上标签。我尝试了一个测试示例,只在那里放置一个简单的标签。然而,当我运行该程序时,所有对象都有些透明。

paintGL:

void mainWidget::paintGL(){
    QPainter painter(this);
    painter.beginNativePainting();
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    glViewport(0, 0, width(), height());

    projection = camera->getProjectionMatrix(60.0f, width(), height(), 0.1f, 100.0f);
    vec3 cameraPos(camera->getPosition());
    view = camera->getViewMatrix();

    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    if (isLine)
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    shaderProgram->bind();
    shaderProgram->setUniformValue("Light.ambient", 0.1f);
    shaderProgram->setUniformValue("Light.position", QVector3D(ld[0], ld[1], ld[2]));
    model = mat4(1.0f);
    model = glm::translate(model, modelOrigin + cubePosModel);
    setRotModel(cubeRotModel);
    setMatrices(shaderProgram, true);
    shaderProgram->setUniformValue("viewPosition", QVector3D(cameraPos[0], cameraPos[1], cameraPos[2]));

    if (showCube) 
        cubeMesh->render(shaderProgram);
    shaderProgram->release();
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    if (isLine)
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    view = camera->getViewMatrix();
    model = mat4(1.0f);
    model = glm::translate(model, modelOrigin + planePosModel);

    setRotModel(planeRotModel);
    shaderProgram->bind();
    setMatrices(shaderProgram, true);
    shaderProgram->setUniformValue("viewPosition", QVector3D(cameraPos[0], cameraPos[1], cameraPos[2]));
    if (showPlane)
        planeMesh->render(shaderProgram);
    shaderProgram->release();
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    if (isLine)
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    model = glm::mat4(1.0f);
    model = glm::translate(model, modelOrigin + teapotPosModel);
    setRotModel(teapotRotModel);

    shaderProgram->bind();
    setMatrices(shaderProgram, true);
    if (showTeapot)
        teapotMesh->render(shaderProgram);
    shaderProgram->release();
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

    model = glm::mat4(1.0f);
    model = glm::translate(model, modelOrigin + cubeLightPosModel);
    model = glm::scale(model, glm::vec3(0.3f));
    setRotModel(cubeLightRotModel);

    lightCubeProgram->bind();
    setMatrices(lightCubeProgram, false);
    if (showCubeLight)
        cubeMesh->render(lightCubeProgram);
    lightCubeProgram->release();
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

    axis_vao->bind();
    model = mat4(1.0f);
    model = glm::translate(model, modelOrigin);
    model = glm::scale(model, vec3(5.0f));
    model = glm::rotate(model, glm::radians(2.0f), vec3(1, 1, 0));
    drawAxisProgram->bind();
    glm::mat4 pvm = projection * view * model;
    drawAxisProgram->setUniformValue("mvpMatrix", QMatrix4x4(glm::value_ptr(pvm)).transposed());
    if (showGrid)
        glDrawArrays(GL_LINES, 0,  axisSize);
    axis_vao->release();
    drawAxisProgram->release();
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

    if (isLine)
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    model = mat4(1.0f);
    model = glm::translate(model, modelOrigin + vec3(0, 2, -1));
    shaderProgram->bind();
    setMatrices(shaderProgram, true);
    if (showSphere)
        sphereMesh->render(shaderProgram);
    shaderProgram->release();
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

    painter.endNativePainting();
    painter.setPen(Qt::yellow);
    painter.setFont(QFont("Helvetica", 8));
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    painter.drawText(200, 400, "Scene Maker"); // z = pointT4.z + distOverOp / 4
    painter.end();
}

我不知道为什么,但它是唯一透明的对象。另外,QPainter 的添加也弄乱了茶壶的盖子。也许这与发生的 glPolygonMode 困惑的事情有关?

万一是QPainter偷偷地禁用了GL_DEPTH_TEST,情况似乎如此,我后来重新启用了它,但仍然不起作用。

mainWidget 是一个QOpenGLWidget

那么,问题出在哪里呢? 图片:

enter image description here

(如您所见,网格线透过茶壶显示,但立方体却没有,使其不完全透明。)

编辑:我发现所有其他对象也是透明的。

最佳答案

您的深度测试已禁用或您的上下文没有深度缓冲区。首先确保在初始化期间设置带有深度缓冲区的像素格式。 QOpenGLWidget documentation有一个例子:

QOpenGLWidget *widget = new QOpenGLWidget(parent);
QSurfaceFormat format;
format.setDepthBufferSize(24); // <--- this is what you need
format.setStencilBufferSize(8);
format.setVersion(3, 2);
format.setProfile(QSurfaceFormat::CoreProfile);
widget->setFormat(format); // must be called before the widget or its parent window gets shown

接下来在绘图代码中启用深度测试:

glEnable(GL_DEPTH_TEST);

关于qt - 使用 QPainter 时对象是透明的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65453191/

相关文章:

c++ - 将数组中的对象放置在各个位置 OpenGL GLUT C++

c++ - 无法访问对象指针,即使它没有被删除

c++ - 如何使用 painter 类绘制 svg 图形

python - 尝试为日期单元格着色时出现问题

c++ - QT 5.4 QPrinterInfo::printerName 返回空白

c++ - Qt - 从回调中发出信号

c++ - Qt并发运行,按引用传值,但内存地址不一样?

qt - PyQt:QStandardItemModel:如何获取一行作为列表?

c++ - 在实现 openGL 拾取时遇到困难

c++ - DrawArc 未正确绘制 (qt/c++)