【问题标题】:Qt OpenGL - Texture Transparency issueQt OpenGL - 纹理透明度问题
【发布时间】:2015-01-21 23:39:10
【问题描述】:

我目前正在尝试学习 OpenGL,但在纹理透明度方面遇到了问题。

我有 2 个带纹理的平面/矩形,第一个最靠近相机,第二个更靠后,在第一个后面。两者都使用具有 50% 不透明度背景的图像进行纹理处理。

我应该能够看到第一个平面后面的第二个平面的纹理,因为第一个平面在某种程度上是透明的 - 但我没有。我使用的图像实际上是单独出现的(如果我旋转相机可以看到它们),并且它们上面有文字(我希望它们会通过前面图像的半透明背景流血)。

有没有办法纠正这个问题? 这是我的初始化和paintGL 方法(它们可能经过了可怕的优化)

void oglWidget::initializeGL()
{
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glEnable(GL_CULL_FACE);

    qglClearColor(QColor(Qt::white));

    shaderProgram.addShaderFromSourceFile(QGLShader::Vertex, ":/vertexShader.vsh");
    shaderProgram.addShaderFromSourceFile(QGLShader::Fragment, ":/fragmentShader.fsh");
    shaderProgram.link();

    //    vertices[1] << QVector3D(-xAmt, -1,  0) << QVector3D( xAmt, -1,  0) << QVector3D( xAmt,  1,  0) // Front
    //            << QVector3D( xAmt, 1,  0) << QVector3D(-xAmt,  1,  0) << QVector3D(-xAmt, -1,  0);

    float xAmt = 16.00/9.00;
    vertices << QVector3D(-xAmt, -1,  0) << QVector3D( xAmt, -1,  0) << QVector3D( xAmt,  1,  0) // Midground
             /*<< QVector3D( xAmt, 1,  0) << QVector3D(-xAmt,  1,  0) << QVector3D(-xAmt, -1,  0)*/
             << QVector3D(-xAmt, -1,  -1) << QVector3D( xAmt, -1,  -1) << QVector3D( xAmt,  1,  -1) // Background
             << QVector3D( xAmt, 1,  -1) << QVector3D(-xAmt,  1,  -1) << QVector3D(-xAmt, -1,  -1);


    textureCoordinates << QVector2D(0, 0) << QVector2D(1, 0) << QVector2D(1, 1) // Front
                       << QVector2D(1, 1) << QVector2D(0, 1) << QVector2D(0, 0)
                       << QVector2D(0, 0) << QVector2D(1, 0) << QVector2D(1, 1) // Front
                       << QVector2D(1, 1) << QVector2D(0, 1) << QVector2D(0, 0);
}

void oglWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    QMatrix4x4 mMatrix;
    QMatrix4x4 vMatrix;

    QMatrix4x4 cameraTransformation;
    cameraTransformation.rotate(alpha, 0, 1, 0);
    cameraTransformation.rotate(beta, 1, 0, 0);

    QVector3D cameraPosition = cameraTransformation * QVector3D(0, 0, distance);
    QVector3D cameraUpDirection = cameraTransformation * QVector3D(0, 1, 0);

    vMatrix.lookAt(cameraPosition, QVector3D(0, 0, 0), cameraUpDirection);
    shaderProgram.bind();
    shaderProgram.setUniformValue("mvpMatrix", pMatrix * vMatrix * mMatrix);


    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    shaderProgram.setUniformValue("texture", 0);
    shaderProgram.setAttributeArray("vertex", vertices.constData());
    shaderProgram.enableAttributeArray("vertex");
    shaderProgram.setAttributeArray("textureCoordinate", textureCoordinates.constData());
    shaderProgram.enableAttributeArray("textureCoordinate");
    glGenTextures(0, &texture);    glBindTexture(GL_TEXTURE_2D, texture);

    QImage tempTexture = QGLWidget::convertToGLFormat(QImage(ImgManager::getImg("/Textures/Editor/m.png")));
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tempTexture.width(), tempTexture.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tempTexture.bits() );
    glDrawArrays(GL_TRIANGLES, 0, vertices.size());

    shaderProgram.release();
}

【问题讨论】:

  • 尝试禁用深度测试或设置深度掩码。
  • 是的,这就是问题所在。如果您愿意,请将其作为答案而不是评论进行回复,我会检查并接受它。

标签: c++ qt opengl transparency


【解决方案1】:

即使启用了混合,新几何图形也会执行深度测试以检查当前片段是否可见使用新值填充深度缓冲区。

解决此问题的一种简单方法是使用glDisable(GL_DEPTH_TEST); 完全禁用深度测试,但更好的方法如下:

  1. 设置glDepthMask(GL_TRUE);
  2. 绘制不透明的对象
  3. 设置glDepthMask(GL_FALSE);
  4. 绘制透明对象

glDepthMask(GL_FALSE); 将禁用对深度缓冲区的写入,而深度测试本身仍处于启用状态。因此,不透明对象只有在透明对象真正在它们面前时才会遮挡它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-03
    • 2015-03-20
    相关资源
    最近更新 更多