【问题标题】:Issues with GLUtils.texImage2D and Alpha in Textures纹理中 GLUtils.texImage2D 和 Alpha 的问题
【发布时间】:2010-10-13 07:48:27
【问题描述】:

我使用 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, pixel2);

但是创建像素2 的处理成本很高,它是一个字节缓冲区,我必须在将值从位图 ARGB 更改为纹理 RGBA 的同时重新复制字节。

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

杰森


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

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

我遇到了这个问题

我的问题是 GLUtils 生成的 alpha 不是纹理之一,它更暗。

区别就像在阳光下和阴影下看颜色(如果这有意义的话)。

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

【问题讨论】:

    标签: android opengl-es bitmap


    【解决方案1】:

    GLUtils.texImage2D 生成预乘 alpha 纹理。在这个生成的纹理中,所有像素都乘以 alpha 值,因此您不需要再次乘以 alpha 值。 来试试吧

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

    【讨论】:

      【解决方案2】:

      我只能说 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);
      }
      

      【讨论】:

        【解决方案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); 
        

        【讨论】:

          【解决方案4】:

          Android Bitmap 存储从 PNG 加载的带有预乘颜色的图像。 GLUtils.texImage2D 也使用了预乘 alpha 的颜色,因此无法通过这种方式获得原始颜色。

          为了在没有预乘 RGB 通道的情况下加载 PNG 图像,我使用第 3 方 PNGDecoder 并使用 glTexImage2D 加载纹理。您可以从这里获取 PNGDecoder 库来解码 PNG:http://twl.l33tlabs.org/#downloads

          【讨论】:

            【解决方案5】:

            在 GLUtils 中存在预乘 alpha 的问题。我可以建议的唯一解决方法是使用:

            gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA)
            

            如果您需要其他混合功能,则必须使用gl.glTexImage2D

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2010-11-20
              • 1970-01-01
              • 2015-12-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-03-12
              相关资源
              最近更新 更多