透明 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;
}
}
I have a PNG with a transparent background, and I'm trying to display it using LWJGL. But instead of a transparent background, it appears with a black opaque background. I'm following the code from the "space invaders" example.
Here's my code. I apologise for its length, but I couldn't cut it down any further and still show the graphic. "ball.png" is a 256x256 image with a transparent background.
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;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用 OpenGL 时,您需要启用混合以允许图像上的透明位。
您需要在代码中添加类似以下内容:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
You need to enable blending to allow transparent bits on an image when using OpenGL.
You'll need to add something like the following to your code:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);