首页 > 解决方案 > 在 QOpenGLWidget 中使用 glBlendFunc

问题描述

我正在尝试glBlendFuncQOpenGLWidget(在paintGL中)使用,但对象不混合(阿尔法有效)。

我的代码:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);

glBlendFunc(blenFunc, GL_ONE);

m_world.setToIdentity();
m_world.rotate((m_xRot / 16.0f), 1, 0, 0);
m_world.rotate(m_yRot / 16.0f, 0, 1, 0);
m_world.rotate(m_zRot / 16.0f, 0, 0, 1);

QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
m_program->bind();
m_tex->bind();
fillYoffsetLightning();

const GLfloat scaleFactor = 0.05f;
m_world.scale(scaleFactor, scaleFactor, 0.0f);
m_world.translate(0.f, 0.0f, 0.0f);

const GLfloat fact = 1 / scaleFactor;
const uint8_t X = 0, Y = 1;

for(int i = 0; i < maxElem; ++i) {
    const GLfloat offX = m_ELECT[i][X] * fact;
    const GLfloat offY = m_ELECT[i][Y] * fact;
    m_world.translate(offX, offY);

    m_program->setUniformValue(m_projMatrixLoc, m_proj);
    m_program->setUniformValue(m_mvMatrixLoc, m_camera * m_world);
    QMatrix3x3 normalMatrix = m_world.normalMatrix();
    m_program->setUniformValue(m_normalMatrixLoc, normalMatrix);

glDrawArrays(GL_TRIANGLE_FAN, 0, m_logo.vertexCount());

    update();
    m_world.translate(-offX, -offY);
}

m_program->release();

着色器很简单:

// vertex
"attribute highp vec4 color;\n"
"varying highp vec4 colorVertex;\n"
//......... main:
"colorVertex = color;\n"

// fragment
"varying highp vec4 colorVertex;\n"
//......... main:
"gl_FragColor = colorVertex;\n"

颜色为:绘制一个从中心到蓝色到边缘渐变的五边形(中心颜色为1,1,1,边缘为0,0,0.5)

截图

为什么会这样?

标签: qtopenglqt5

解决方案


如果要实现混合效果,则必须禁用深度测试:

glDisable(GL_DEPTH_TEST);

注意,默认的深度测试函数是GL_LESS. 如果一个片段是在前一个片段的位置上绘制的,那么它会被深度测试丢弃,因为这个条件没有被完全填充。
如果深度测试被禁用,则片段将由混合函数 ( glBlendFunc) 和方程 ( glBlendEquation) “混合”。

我建议使用以下混合功能:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

推荐阅读