2012-04-12 65 views
3

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

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

} 
+0

你可以显示你用来加载图像并从中创建纹理的代码吗?特别是glTexImage2D调用 – haffax 2012-04-12 14:18:49

回答

0

我还没有真正弄清楚为什么用Java创建的透明图像在Android OpenGL ES中不起作用。但是,我确实发现了一个允许图像工作的黑客技术。

当你在Java中创建新的透明图像,你应该做的第一件事就是使用方法调用Graphics对象获得

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

// g还就画一个半透明图像从正在创建的新图像

// img参数是在Photoshop中创建的半透明,不是100%透明(或者它不起作用)的图像。我使用4x4的尺寸,以免引人注目。

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

我的猜测是,通过绘制半透明图像,它会更改生成的PNG文件的格式,并且此格式更改使其可在Android 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

+0

感谢您的答案。我正在启用混合。正如我所提到的,对于使用Photoshop创建的半透明图像,半透明纹理的渲染效果很好。 – Felipe 2012-04-13 17:59:35

+0

对不起,我误解了这个问题。我已经更新了我的答案。 – theisenp 2012-04-13 18:08:54