我用相同的方式渲染了两个纹理。绿色纹理在正确的位置具有适当的透明度,但是当我在前面移动粉色纹理时,它将在应该透明的位置显示背景色。
这是用于渲染纹理的 paintGL 方法的代码段。
void OpenGLWidget::paintGL()
{
// ...
for (int i = 0; i < lights.size(); i++)
{
glUseProgram(lights[i].program);
setUniform3fv(program, "lightPosition", 1, &lights[i].position[0]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, lights[i].texture);
lights[i].svg.setColor(toColor(lights[i].diffuse));
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lights[i].svg.width(), lights[i].svg.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, lights[i].svg.toImage().constBits());
glGenerateMipmap(GL_TEXTURE_2D);
glBindVertexArray(lights[i].vertexArray);
glDrawElements(GL_TRIANGLES, lights[i].indices.size(), GL_UNSIGNED_BYTE, nullptr);
}
update();
}
svg 类的 toImage 方法会从svg文件生成一个新的QImage对象,因此新纹理值应随每一帧进行更新。
我在哪里做错了?谢谢!
答案 0 :(得分:2)
这可能是因为您启用了深度测试。即使部分纹理是(部分或全部)透明的,OpenGL仍会写入深度缓冲区,因此,粉红光的四边形似乎会遮挡绿光。反之亦然,因为首先绘制了粉红色的光,所以此时尚未将绿光写入深度缓冲区。
通常的解决方案是按从前到后的顺序渲染透明纹理。
如果您的片段着色器是透明的,也可以将它们写入discard
片段。但是,如果您具有半透明的片段,则会由于纹理过滤和mipmaps而产生伪像。