保存使用glReadPixels读取的图像,其中alpha值不是1

时间:2015-03-05 16:34:21

标签: qt opengl qml qtquick2

请看这张图片:

enter image description here

在左侧,使用glReadPixels保存图像。在右侧,相应的(正确的)渲染:颜色在其alpha值小于1时失真。

表面由QtQuick管理。使用glGetInteger我发现每个通道有8位,包括alpha。

我可以使用类似的东西获得更好的结果,但并不完美:

for x := 0; x < m.Bounds().Dx(); x++ {
    for y := 0; y < m.Bounds().Dy(); y++ {
        c := m.RGBAAt(x, y)
        w := float64(c.A) / 255
        c.R = uint8(float64(c.R)*w + 255*(1-w) + 0.5)
        c.G = uint8(float64(c.G)*w + 255*(1-w) + 0.5)
        c.B = uint8(float64(c.B)*w + 255*(1-w) + 0.5)
        c.A = 255
    m.SetRGBA(x, y, c)
    }
}

我尝试使用以下方法清除OpenGL中的alpha组件:

s.gl.ClearColor(0, 0, 0, 1)
s.gl.ColorMask(false, false, false, true)
s.gl.Clear(GL.COLOR_BUFFER_BIT)

现在结果类似于我的手动编写,而且显示并且捕获的图像相同但仍然不同于(并且比以前显示的更暗)。

我对OpenGL / Qt在显示颜色缓冲区时如何使用alpha通道感兴趣。也许QtQuick用背衬层组成它?

1 个答案:

答案 0 :(得分:1)

我通过在绘图期间永远不改变alpha来解决问题。因此,我现在使用gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)代替gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA),并修改其他参数以使其像以前一样。

Andon M. Coleman在他的评论中指出,这与使用预乘Alpha混合相同。这样,颜色缓冲区的alpha值始终保持为1,并且可以解决问题。

glBlendFuncSeparate分别指定RGB和alpha分量的像素算法,可以获得相同的结果。