为什么我的PNG贴图没有透明度?

7

右下方的图片应该具有透明背景。

我通过以下函数加载Notch的PNG:

public void Image2D(Bitmap bmp, int mipmapReductionLevel = 0)
{
    var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
    var data = bmp.LockBits(rect, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

    GL.TexImage2D(TextureTarget.Texture2D, mipmapReductionLevel, PixelInternalFormat.Rgba, data.Width, data.Height, 0,
        OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);

    bmp.UnlockBits(data);
}

public void Image2D(string filename, int mipmapReductionLevel = 0)
{
    Image2D(new Bitmap(filename), mipmapReductionLevel);
}

我的片段着色器看起来像这样:

#version 330

in vec2 TexCoord0;

uniform sampler2D TexSampler;

void main()
{
    gl_FragColor = texture2D(TexSampler, TexCoord0.xy);
}

我用调试器检查了bmp,并使用bmp.GetPixel(255,0)(就在那棵树苗上方的黑色区域),结果是(0,0,0,0)文档说0表示完全透明,所以...我在OpenGL方面一定做错了什么。但是是什么呢?


渲染函数

protected override void OnRenderFrame(FrameEventArgs e)
{
    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

    _blockInstanceBuffer.Bind();
    _blockIndexBuffer.Bind();
    GL.DrawElementsInstancedBaseVertex(BeginMode.TriangleStrip, Data.FaceIndices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero, _blockCount, 0);

    SwapBuffers();
}

1
啊,我的上帝,Minecraft,我无法逃脱你的魔咒! - Zenexer
你在忙些什么呢?是一块一块地接管Minecraft吗?有点可疑!既然Minecraft本身就是用Java编写的,为什么不用Java呢?这样你可能已经完成更多了。(顺便说一句,我之前用C#制作过一个Minecraft客户端。是个有趣的项目。) - Zenexer
啊,祝你好运!体素引擎很有趣。 - Zenexer
嗯,我就是看不到它。我来自DirectX,所以可能是我错过了一些非常简单的东西。(添加了C#标签,以便引起更多关注。) - Zenexer
1
这正是我正在寻找的。在XNA中,它被称为BlendState.AlphaBlend。 - Zenexer
显示剩余6条评论
1个回答

11

只需要启用混合即可:

GL.Enable(EnableCap.Blend);
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);

如果你编写自己的着色器,我原本认为在OpenGL 3中这是不必要的,但我猜它仍然是必要的。


2
混合仍然不受着色器控制,即使在GL4核心中也是如此。 - Mārtiņš Možeiko
1
就像Mārtiņš Možeiko已经告诉你的那样,混合不是由着色器控制的。这个简单的原因是,混合只发生在片段被处理之后,即当所有着色器阶段完成执行时。然后混合发生在GPU的某个硬连线部分。也许,在未来几年中,我们将看到一些新的片段着色器输入变量“gl_DestColor”或类似变量,它允许我们在片段着色器中进行混合。但直到今天,这将引起的问题(这将对内存访问模式产生巨大影响)会阻碍这一进展。 - datenwolf
@datenwolf:对我来说不是问题;我只需要非常简单的混合。人们实际上会有很多需要自己进行混合的用例吗? - mpen
1
@Mark:确实有。只需看看Photoshop或The Gimp中可用的各种图层混合模式即可。其中大多数只能通过使用着色器或纹理组合器在OpenGL中实现。 - datenwolf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接