2011-04-22 229 views
3

我有一個透明背景的PNG,我試圖用LWJGL來顯示它。但不是透明的背景,它顯示爲黑色不透明背景。我遵循「太空侵略者」示例中的代碼。透明PNG在LWJGL中不透明

這是我的代碼。我對它的長度表示歉意,但我無法進一步削減它,仍然顯示圖形。 「ball.png」是具有透明背景的256x256圖像。

package com.ziroby.kata.bouncingBalls; 

import static org.lwjgl.opengl.GL11.*; 
import org.lwjgl.opengl.Display; 

import java.awt.*; 
import java.awt.color.ColorSpace; 
import java.awt.image.*; 
import java.io.IOException; 
import java.net.URL; 
import java.nio.ByteBuffer; 
import java.nio.ByteOrder; 
import java.util.Hashtable; 
import javax.swing.ImageIcon; 

public class Game { 

public void start() throws Exception { 
    Display.setInitialBackground(0.5f, 0.5f, 0.5f); 
    Display.create(); 

    // enable textures since we're going to use these for our sprites 
    glEnable(GL_TEXTURE_2D); 

    glMatrixMode(GL_PROJECTION); 

    glOrtho(0, 800, 600, 0, -1, 1); 
    glMatrixMode(GL_MODELVIEW); 

    getTexture("ball.png"); 

    // clear screen 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    // translate to the right location and prepare to draw 
    glTranslatef(300, 200, 0); 

    // draw a quad textured to match the sprite 
    glBegin(GL_QUADS); 
    { 
     glTexCoord2f(0, 0); 
     glVertex2f(0, 0); 

     glTexCoord2f(0, 1); 
     glVertex2f(0, 100); 

     glTexCoord2f(1, 1); 
     glVertex2f(100, 100); 

     glTexCoord2f(1, 0); 
     glVertex2f(100, 0); 
    } 
    glEnd(); 

    // update window contents 
    Display.update(); 
    Thread.sleep(1000); 

    Display.destroy(); 
} 

public void getTexture(String resourceName) throws IOException { 
    glBindTexture(GL_TEXTURE_2D, 1); 

    BufferedImage bufferedImage = loadImage(resourceName); 
    ByteBuffer textureBuffer = convertImageData(bufferedImage); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

    // produce a texture from the byte buffer 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferedImage.getWidth(), 
      bufferedImage.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 
      textureBuffer); 
} 

/** 
* Convert the buffered image to a texture 
*/ 
private ByteBuffer convertImageData(BufferedImage bufferedImage) { 
    ByteBuffer imageBuffer; 
    WritableRaster raster; 
    BufferedImage texImage; 

    ColorModel glAlphaColorModel = new ComponentColorModel(ColorSpace 
      .getInstance(ColorSpace.CS_sRGB), new int[] { 8, 8, 8, 8 }, 
      true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE); 

    raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, 
      bufferedImage.getWidth(), bufferedImage.getHeight(), 4, null); 
    texImage = new BufferedImage(glAlphaColorModel, raster, true, 
      new Hashtable()); 

    // copy the source image into the produced image 
    Graphics g = texImage.getGraphics(); 
    g.setColor(new Color(0f, 0f, 0f, 0f)); 
    g.fillRect(0, 0, 256, 256); 
    g.drawImage(bufferedImage, 0, 0, null); 

    // build a byte buffer from the temporary image 
    // that be used by OpenGL to produce a texture. 
    byte[] data = ((DataBufferByte) texImage.getRaster().getDataBuffer()) 
      .getData(); 

    imageBuffer = ByteBuffer.allocateDirect(data.length); 
    imageBuffer.order(ByteOrder.nativeOrder()); 
    imageBuffer.put(data, 0, data.length); 
    imageBuffer.flip(); 

    return imageBuffer; 
} 

/** 
* Load a given resource as a buffered image 
*/ 
private BufferedImage loadImage(String ref) throws IOException { 
    URL url = getClass().getClassLoader().getResource(ref); 

    // due to an issue with ImageIO and mixed signed code 
    // we are now using good oldfashioned ImageIcon to load 
    // images and the paint it on top of a new BufferedImage 
    Image img = new ImageIcon(url).getImage(); 
    BufferedImage bufferedImage = new BufferedImage(img.getWidth(null), img 
      .getHeight(null), BufferedImage.TYPE_INT_ARGB); 
    Graphics g = bufferedImage.getGraphics(); 
    g.drawImage(img, 0, 0, null); 
    g.dispose(); 

    return bufferedImage; 
} 
} 

回答

10

在使用OpenGL時,您需要啓用混合以允許圖像上的透明位。

你需要添加類似下面給您的代碼:

glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

+0

謝謝。那樣做了。 – 2011-04-22 21:47:22