纹理中GLUtils.texImage2D和Alpha的问题

Jas*_*ers 5 android opengl-es bitmap

我使用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是很昂贵的,像素2是一个字节缓冲区,我必须重新复制字节,同时将位图ARGB的值更改为纹理RGBA.

有人注意到了吗?如果是这样,你是如何解决这个问题的......

贾森


谢谢你的回答,我已经在使用了

gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
Run Code Online (Sandbox Code Playgroud)

而且我遇到了这个问题

我的问题是GLUtils生成的alpha不是纹理中的一个,它的颜色较深.

区别就像在阳光下和阴影中看颜色(如果有任何意义).

我已经尝试了gl.gltextimage2d但是创建缓冲区需要太长时间,除非有一个工具将位图转换为我不知道的字节缓冲区...

小智 5

GLUtils.texImage2D生成一个预乘的alpha纹理.在此生成的纹理中,所有像素都乘以alpha值,因此您无需再次将Alpha值相乘.我们试试吧

gl.glBlendFunc(GL10.GL_ONE,GL10.GL_ONE_MINUS_SRC_ALPHA);


Eik*_*ker 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));
    
    Run Code Online (Sandbox Code Playgroud)

很抱歉没有找到不同的解决方案...最初的问题是,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);
}
Run Code Online (Sandbox Code Playgroud)