我使用 GLUtils.texImage2D 成功生成了纹理,
但是当我使用生成的纹理时,我的 Alpha 出现了问题:它们比想要的更暗。
在检查了几件事之后,我终于得到了问题来自 GLUtils.texImage2D(GL10.GL_TEXTURE_2D, level, bmp, 0); 的结论。
我创建了第二个函数,它使用 gl.glTexImage2D(GL10.GL_TEXTURE_2D, level, GL10.GL_RGBA, width, height, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, Pixels2);
但创建 Pixel2 是一个字节缓冲区,在将值从位图 ARGB 更改为纹理 RGBA 时,我必须在其中重新复制字节,处理成本很高。
有人注意到了吗?如果是这样,你是如何解决这个问题的...
杰森
谢谢你的回答,
我已经在使用
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
并且遇到了这个问题,
我的问题是 GLUtils 生成的 alpha 不是纹理之一,它更暗。
区别就像在阳光下和阴影下观察颜色一样(如果这有意义的话)。
我已经尝试过 gl.gltextimage2d 但创建缓冲区需要太长时间,除非有一个工具将位图转换为我不知道的字节缓冲区...
I'm successfully generating my textures using GLUtils.texImage2D,
but when I use the textures generated I get problems with my alpha: they are darker than wanted.
after having checked several things I finally got the the conclusions that the problem comes from GLUtils.texImage2D(GL10.GL_TEXTURE_2D, level, bmp, 0);
I created a second function that uses gl.glTexImage2D(GL10.GL_TEXTURE_2D, level, GL10.GL_RGBA, width, height, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixels2);
but it is costly in processing to create pixels2 which is a bytebuffer in which I have to recopy the bytes while changing the values from the bitmap ARGB to texture RGBA.
Has anybody noticed that ? and if so how did you solve this...
jason
Thank you for your answer,
I'm already using
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
and I'm getting this problem
my problem is that the alpha generated by GLUtils isn't the one of the texture, its darker.
the difference is like looking at a color in the sun and in the shade (if that makes any sence).
I already tried gl.gltextimage2d but the creating the buffer takes too long, unless there is a tool to convert a bitmap to a byte buffer that I don't know of...
发布评论
评论(6)
GLUtils.texImage2D 生成预乘 alpha 纹理。在这个生成的纹理中,所有像素都乘以 alpha 值,因此您不需要再次乘以 alpha 值。
让我们尝试一下
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
GLUtils.texImage2D generates a premultiplied-alpha texture. In this generated texture, all pixels are multiplied by alpha value, so you don't need to multiply alpha value once again.
Let's try
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
我只能说,alpha 通道是大量程序员中可怜的、被虐待的继子......但是如果你这样做的话,上传的效率相当高:
估计你最大的纹理(如 1024x1024)并创建一个 int 数组您存储在某个静态变量或可以访问它的地方的大小(1024*1024),这样您就不需要重新创建该数组(分配时间在这里很宝贵)
然后这样做:
我很抱歉没有找到不同的解决方案...最初的问题是,GLUtils.texImage2D 函数的实现者以某种方式错误地处理了 alpha 通道,导致当图像显示得比实际更大(双线性过滤器计算四个像素之间的颜色,并且当具有透明 Alpha 的像素的 RGB 值被破坏(例如设置为黑色)时,结果是,存在某种“颜色”在那里形成的透明边框上发生了“出血”现象。非常丑陋。也许这样做是为了提高压缩比,因为 PSD 中 alpha 透明区域中的 RGB 值包含大量垃圾,消除这些垃圾后会产生很大的改进空间压缩算法)
编辑:遗憾的是,这种方法仅适用于灰色图像,因为从位图中获取像素时会交换红色和蓝色通道。至少在我的设备上是这样。我不确定这对于其他设备来说有多正确,但就我而言,这在这里做到了:
The alpha channel is the poor mistreated stepchild of a huge number of programmers is all I can say... but the upload works fairly efficient if you do that:
Estimate your largest texture (like 1024x1024) and create an int array of that size (1024*1024) that you store in some static variable or somewhere where you can access it so that you don't need to recreate that array (allocation time is precious here)
then do this:
I am sorry not having found a different solution... the original problem is, that the implementor of the GLUtils.texImage2D function has mistreated the alpha channel somehow resulting in black borders when the image is displayed larger than it is (the bilinear filter calculates the color between four pixels and when the rgb values of the pixels with transparent alphas have been mangled (like set to black), the result is, that there's some kind of a "color bleeding" happening over the transparent border that is forming there. Very ugly. Maybe it was done to improve the compression ratio as the RGB values in alpha transparent areas in PSDs contain a lot of junk that when eliminated yield a lot of room of improvement for compression algorithms)
Edit: Sadly, this approach was only working for grey images correctly as the red and blue channel is swapped when fetching the pixels from the bitmap. At least on MY device. I am not sure how correctly this is for other devices, but in my case, this here did the trick:
解决方案可在此处找到。正如其他人所述,它与预乘 alpha 相关。
在 surfaceView 构造函数中
在 View.Renderer 中 onSurfaceCreated
Solution is found here. It is related as is stated by others with premultiplied alpha.
In the surfaceView Constructor
In the View.Renderer onSurfaceCreated
Android
Bitmap
存储从 PNG 加载的具有预乘颜色的图像。GLUtils.texImage2D
也使用预乘 alpha 的颜色,因此您无法通过这种方式获得原始颜色。为了在不预乘 RGB 通道的情况下加载 PNG 图像,我使用第 3 方
PNGDecoder
并使用glTexImage2D
加载纹理。您可以从此处获取用于解码 PNG 的 PNGDecoder 库:http://twl.l33tlabs。 org/#downloadsAndroid
Bitmap
stores images loaded from PNG with premultiplied colors.GLUtils.texImage2D
also uses colors premultiplied by alpha, so you can't get original colours this way.In order to load PNG images without RGB channels being premultiplied I use 3rd party
PNGDecoder
and load texture withglTexImage2D
. You can get PNGDecoder library to decode PNG from here: http://twl.l33tlabs.org/#downloadsAndroid 的
BitmapFactory.decode()
在加载时默认预乘 alpha。,如果您不想加载预乘位图,请在加载纹理位图时使用
Bitmap.Options
并将inPremultiplied
设置为true
:因此 将此位图传递给
GLUtils.texImage2D
PS
了解预乘 Alpha 的精彩视频:
https://www.youtube.com/watch?v=wVkLeaWQOlQ
Android's
BitmapFactory.decode()
premultiplies alpha by default on loading.So if you don't want to load premultiplied bitmaps, use
Bitmap.Options
withinPremultiplied
set totrue
when loading the bitmap for texture:Then pass this bitmap to
GLUtils.texImage2D
P.S.
Nice video for understanding premultiplied alpha:
https://www.youtube.com/watch?v=wVkLeaWQOlQ
GLUtils 中的预乘 alpha 存在问题。我可以建议的唯一解决方法是使用:
如果您需要其他混合函数,则必须使用
gl.glTexImage2D
。There is an issues in GLUtils with premultiplied alpha. The only workaround that I can propose is to use:
In case you need other blend functions you will have to use
gl.glTexImage2D
.