【问题标题】:Translucent or Transparent Image created in Java does not display in Android OpenGL ES在 Java 中创建的半透明或透明图像在 Android OpenGL ES 中不显示
【发布时间】:2012-04-14 02:20:38
【问题描述】:

我使用带有以下代码的 Mac 计算机在 Java 6 中创建图像。然后我尝试使用 OpenGL ES 在 Android 设备中显示该图像。不显示图像,仅显示白色图像。但是,如果没有半透明像素,则图像会正常显示。

显示在 Photoshop 中创建的半透明图像没有问题。只有用 Java 创建的半透明图像才有问题。我还尝试了用 Java 创建半透明图像的不同方法,但我总是得到相同的结果,即在 OpenGL 中显示的白色图像。在这一点上,我相信这是 Java 的一个错误,(在 Mac 计算机中)。有没有人遇到过这样的事情?知道为什么会发生这种情况吗?

//创建图片的代码

int cmap[] = { 
0x00000000, /*transparent*/ 
0xFF000000, /*black*/ 
0xFFFF0000, /*red*/ 
0xFFFFFF00, /*yellow*/ 
0xFF00FF00, /*green*/ 
//...... 
}; 
IndexColorModel colorModel = new IndexColorModel(8, 
cmap.length, cmap, 0, true, -1, DataBuffer.TYPE_BYTE); 
BufferedImage image = new BufferedImage(256, 256, 
BufferedImage.TYPE_BYTE_INDEXED, colorModel); 
Graphics2D g = image.createGraphics(); 
g.setBackground(new Color(0,0,0,0)); /*transparent*/ 
g.clearRect(0 , 0, image.getWidth(), image.getHeight()); 
g.setColor(Color.red); 
g.draw(new Rectangle(10, 10, 40, 40));


ImageIO.write(image, "PNG", new File("rectangle.png")); 

下面是加载纹理的代码。请注意,这是特定于 Android 环境的。

public static void loadAndBindTexture(GL10 gl) throws Exception
{ 
    int numberTextures=1;
    int[] textures = new int[numberTextures];
    gl.glGenTextures(numberTextures, textures, 0);
    int textureID=textures[0];

    gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);//polyBreaker3DObject_.mTextureID);

    checkGLError(gl, 998);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR_MIPMAP_LINEAR);
    checkGLError(gl, 997);
    //NOTE: FOR GL_TEXTURE_MAG_FILTER only GL_NEAREST or GL_LINEAR are valid.
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
    checkGLError(gl, 996);

    /*Commented on Sept. 30, 2010 6:21AM
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
    */
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,GL10.GL_CLAMP_TO_EDGE);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,GL10.GL_CLAMP_TO_EDGE);
    checkGLError(gl, 1000);

    gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,GL10.GL_DECAL);
    checkGLError(gl, 1001);
    gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_GENERATE_MIPMAP, GL11.GL_TRUE);
    checkGLError(gl, 1002);


 if(mContext==null)//mContext is the Context of the current Android application (it is set before this method is called
    throw new Exception("Context has not been set.");
 InputStream is = mContext.getResources().openRawResource(R.drawable.metal128x128);//blueski);//robot);
Bitmap bitmap;
try {

    bitmap = BitmapFactory.decodeStream(is);

} finally {
    try {
        is.close();
    } catch(IOException e) {
        Log.printCaughtExceptionMsg(e);
    }
}

GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();

   checkGLError(gl, 1003);

}

【问题讨论】:

  • 你能展示你用来加载图像并从中创建纹理的代码吗?尤其是 glTexImage2D 调用

标签: java android image opengl-es


【解决方案1】:

您能否将实际呼叫发布到glDrawElements()glDrawArrays()?如果不查看实际的 OpenGL 绘图调用,很难判断您做错了什么。但您可能在绘制纹理之前没有启用混合。

这样的事情应该可以解决问题:

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

如果您想了解更多信息,请查看this question

编辑:

我的错误,我看错了你的问题。你应该看看你正在使用的 BufferedImage 格式。 TYPE_BYTE_INDEXED 似乎不支持基于 the documentation 的 alpha 值。您是否尝试过改用TYPE_INT_ARGB

【讨论】:

  • 感谢您的回答。我正在启用混合。正如我所提到的,半透明纹理的渲染适用于使用 Photoshop 创建的半透明图像。
  • 抱歉,我误读了这个问题。我已经更新了我的答案。
【解决方案2】:

我仍然无法弄清楚为什么用 Java 创建的透明图像在 Android OpenGL ES 中不起作用。但是,我确实找到了一个允许图像工作的 hack。

当你在java中创建新的透明图像时,你应该做的第一件事是使用方法调用在其上绘制一个半透明图像

        g.drawImage(Image img, x, y,  null);

//g 是从正在创建的新图像中获取的 Graphics 对象

//img 参数是在 Photoshop 中创建的半透明,而不是 100% 透明(否则它将不起作用)的图像。我使用 4x4 尺寸,这样就不会被注意到。

在此调用之后,您可以继续执行您的原始代码。新图像现在可以在 Android OpenGL ES 中使用。

我的猜测是,通过绘制一个半透明的图像,它改变了生成的 PNG 文件的格式,而这种格式的改变使它可以在 Android OpenGL ES 中工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-02
    • 2011-09-15
    • 1970-01-01
    • 1970-01-01
    • 2015-04-21
    相关资源
    最近更新 更多