我使用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);
但是处理创建像素2的代价很高,这是一个字节缓冲区,我必须重新复制字节,同时将位图ARGB中的值更改为纹理RGBA。
有人注意到了吗?如果是这样,你是如何解决这个问题的?
杰森感谢您的回答, 我已经在使用
了gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
我遇到了这个问题
我的问题是GLUtils生成的alpha不是纹理中的一个,它的颜色较深。
区别就像在阳光下和阴影中看颜色(如果有任何意义)。
我已经尝试了gl.gltextimage2d但是创建缓冲区需要太长时间,除非有一个工具将位图转换为我不知道的字节缓冲区...
答案 0 :(得分:5)
GLUtils.texImage2D生成一个预乘的alpha纹理。在此生成的纹理中,所有像素都乘以alpha值,因此您无需再次将Alpha值相乘。 我们试试
gl.glBlendFunc(GL10.GL_ONE,GL10.GL_ONE_MINUS_SRC_ALPHA);
答案 1 :(得分:3)
alpha通道是我所能说的大量程序员的不良受虐待的继子...但如果你这样做,上传工作效率相当高:
估算最大的纹理(如1024x1024)并创建一个大小为(1024 * 1024)的int数组,存储在某个静态变量中或可以访问它的某个位置,这样就不需要重新创建那个数组(这里的分配时间很宝贵)
然后这样做:
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, width, height,
0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, IntBuffer.wrap(pixels));
我很抱歉没有找到不同的解决方案......最初的问题是,GLUtils.texImage2D函数的实现者错误地处理了alpha通道,当图像显示得比它大时,会导致黑色边框(双线性滤波器计算四个像素之间的颜色,当具有透明alpha的像素的rgb值被破坏时(如设置为黑色),结果是,在透明边界上发生了某种“颜色渗色”,即非常难看。可能是为了提高压缩率,因为PSD中alpha透明区域的RGB值包含大量垃圾,当消除时会为压缩算法带来很大的改进空间)
编辑:遗憾的是,这种方法仅适用于灰度图像,因为在从位图获取像素时交换了红色和蓝色通道。至少在我的设备上。我不确定这对其他设备有多正确,但在我的情况下,这就是诀窍:
for (int i=0;i<pixels.length;i+=1) {
int argb = pixels[i];
pixels[i] = argb&0xff00ff00 | ((argb&0xff)<<16) | ((argb>>16)&0xff);
}
答案 2 :(得分:3)
找到解决方案here。如其他人所述,它与预乘alpha有关。
在surfaceView构造函数
中 setEGLConfigChooser(8, 8, 8, 8, 0, 0);
getHolder().setFormat(PixelFormat.RGBA_8888);
在View.Renderer onSurfaceCreated
中 gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
答案 3 :(得分:1)
Android Bitmap
存储从PNG加载的具有预乘颜色的图像。 GLUtils.texImage2D
也使用alpha预乘的颜色,因此您不能以这种方式获得原始颜色。
为了在没有 RGB 频道预加载的情况下加载PNG图像,我使用第三方PNGDecoder
并使用glTexImage2D
加载纹理。您可以从 PNGDecoder 库中解码PNG:http://twl.l33tlabs.org/#downloads
答案 4 :(得分:0)
GLUtils中存在预乘alpha的问题。我可以建议的唯一解决方法是使用:
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA)
如果您需要其他混合功能,则必须使用gl.glTexImage2D
。