# LWJGL - Alpha-Probleme



## Quafel (6. Jun 2014)

Hallo,

ich möchte mit LWJGL ein Bild, das teilweiße transparent ist, auf dem Bildschirm rendern. Dazu wird jenes Bild von einer Klasse, die an ein Internettutorial angelehnt ist, geladen und dann in der Hauptfunktion gerendert. Leider werden aber die transparenten Anteile des Bildes mit der Farbe des anderen Bildteils gefüllt und ein einfarbiges Viereck entsteht.

Ich kann mir den Fehler einfach nicht erklären, vor allem, weil es mir ohne Probleme möglich ist, dass ganze Bild transparent zu machen...

Hier die Klassen:



Spoiler: TextureLoader





```
public class TextureLoader {
	
	private HashMap<String, Texture> table = new HashMap<String, Texture>();
	
	private ColorModel glAlphaColorModel;
	
	private ColorModel glColorModel;
	
	private IntBuffer textureIDBuffer = BufferUtils.createIntBuffer(1);
	
	public TextureLoader() {
		glAlphaColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 
				new int[] {8,8,8,8}, true, false, ComponentColorModel.TRANSLUCENT, DataBuffer.TYPE_BYTE);
		
		glColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 
				new int[] {8,8,8,0}, false, false, ComponentColorModel.OPAQUE, DataBuffer.TYPE_BYTE);
	}
	
	private int createTextureID() {
		GL11.glGenTextures(textureIDBuffer);
		return textureIDBuffer.get(0);
	}
	
	public Texture getTexture(String resName, BufferedImage bufferedImageGive) throws IOException {
		Texture texture = table.get(resName);
		
		if(texture != null) {
			return texture;
		}
		
		texture = getTexture(resName, GL11.GL_TEXTURE_2D, GL11.GL_RGBA, GL11.GL_LINEAR, GL11.GL_LINEAR, bufferedImageGive);
		
		table.put(resName, texture);
		
		return texture;
	}
	
	public Texture getTexture(String resName, int target, int dstPixelFormat, int minFilter, int magFilter, BufferedImage bufferedImageGive) throws IOException {
		int srcPixelFormat;
		int textureID = createTextureID();
		
		BufferedImage bufferedImage;
		
		Texture texture = new Texture(target, textureID);
		
		GL11.glBindTexture(target, textureID);
		
		if(bufferedImageGive == null) bufferedImage = this.loadImage(resName);
		else bufferedImage = bufferedImageGive;
		
		texture.setImageWidth(bufferedImage.getWidth());
		texture.setImageHeight(bufferedImage.getHeight());
		
		if(bufferedImage.getColorModel().hasAlpha()) {
			srcPixelFormat = GL11.GL_RGBA;
		} else {
			srcPixelFormat = GL11.GL_RGB;
		}
		
		ByteBuffer textureBuffer = this.convertImageData(bufferedImage, texture);
		
		if(target == GL11.GL_TEXTURE_2D) {
			GL11.glTexParameteri(target, GL11.GL_TEXTURE_MIN_FILTER, minFilter);
			GL11.glTexParameteri(target, GL11.GL_TEXTURE_MAG_FILTER, magFilter);
		}
		
		GL11.glTexImage2D(target, 0, dstPixelFormat, 
				this.getToFold(bufferedImage.getWidth()), this.getToFold(bufferedImage.getHeight()), 0, srcPixelFormat, GL11.GL_UNSIGNED_BYTE, textureBuffer);
		
		return texture;
	}

	private ByteBuffer convertImageData(BufferedImage bufferedImage, Texture texture) {
		ByteBuffer imageBuffer;
		WritableRaster raster;
		BufferedImage texImage;
		
		Dimension texSize = new Dimension(2, 2);
		
		while(texSize.getWidth() < bufferedImage.getWidth()) {
			texSize.setWidth(texSize.getWidth() * 2);
		}
		
		while(texSize.getHeight() < bufferedImage.getHeight()) {
			texSize.setHeight(texSize.getHeight() * 2);
		}
		
		texture.setImageWidth(texSize.getWidth());
		texture.setTextureHeight(texSize.getHeight());
		
		if(bufferedImage.getColorModel().hasAlpha()) {
			raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, texSize.getWidth(), texSize.getHeight(), 4, null);
			texImage = new BufferedImage(glAlphaColorModel, raster, false, new Hashtable<>());
		} else {
			raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, texSize.getWidth(), texSize.getHeight(), 3, null);
			texImage = new BufferedImage(glColorModel, raster, false, new Hashtable<>());
		}
		
		Graphics g = texImage.getGraphics();
		g.setColor(new Color(0f, 0f, 0f, 1f));
		g.fillRect(0, 0, texSize.getWidth(), texSize.getHeight());
		g.drawImage(bufferedImage, 0, 0, null);
		
		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;
	}

	private BufferedImage loadImage(String ref) throws IOException {
		URL url = TextureLoader.class.getClassLoader().getResource(ref);
		
		if(url == null) {
			throw new IOException("Cannot find: " + ref);
		}
		
		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;
	}
	
	private int getToFold(int fold) {
		int ret= 2;
		while (ret < fold) {
			ret *= 2;
		}
		return ret;
	}
}
```






Spoiler: Sprites





```
public class Sprite {

	private Texture texture;
	
	private Dimension size = new Dimension();
	
	public Sprite(TextureLoader loader, String path, BufferedImage bufferedImage) {
		try {
			texture = loader.getTexture("pics/" + path, bufferedImage);
			size.setSize(texture.getImageSize());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public Dimension getSize() {
		return size;
	}
	
	public void draw(int x, int y) {
		GL11.glPushMatrix();
		
		texture.bind();
		
		GL11.glTranslatef(x, y, 0);
		GL11.glBegin(GL11.GL_QUADS);
			GL11.glTexCoord2f(0, 0);
			GL11.glVertex2f(0, 0);
			
			GL11.glTexCoord2f(0, texture.getImageSize().getHeight());
			GL11.glVertex2f(0, size.getHeight());
			
			GL11.glTexCoord2f(texture.getImageSize().getWidth(), texture.getImageSize().getHeight());
			GL11.glVertex2f(size.getWidth(), size.getHeight());
			
			GL11.glTexCoord2f(texture.getImageSize().getWidth(), 0);
			GL11.glVertex2f(size.getWidth(), 0);
		GL11.glEnd();
		
		GL11.glPopMatrix();
	}
}
```






Spoiler: Initalisierung + Rendern





```
private void initDrawGround() {
		GL11.glEnable(GL11.GL_TEXTURE_2D);
		
		GL11.glDisable(GL11.GL_DEPTH_TEST);
		
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GL11.glOrtho(0, SIZE.getWidth(), 0, SIZE.getHeight(), 1, -1);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
		GL11.glLoadIdentity();
		
		GL11.glViewport(0, 0, SIZE.getWidth(), SIZE.getHeight());
		
		texLoader = new TextureLoader();
		
		map = new Map("Testmap.png", texLoader);
		
		money = new Sprite(texLoader, "geld.png", null);
	}

private Sprite createSprite(String name) {
		return new Sprite(texLoader, name, null);
	}

private void render() {
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
		
		map.renderMap();
		
		money.draw(700, 100);
	}
```


----------



## Lennart401 (12. Jun 2014)

Hallo Quafel,

ich vermute mal, dass das daran liegt, dass du kein blending aktivierst. 

Das geht wie folgt:

```
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
```
Den Code packst du am besten in die initDrawGround().

Ich hoffe, dass es dann funktioniert.

Viele Grüße, 
Lennart401


----------



## Quafel (13. Jun 2014)

Hallo Lennart401,

zuerst will ich dir für deine Antwort danken, ich habe deine Idee befolgt und den von dir beschrieben Codeschnipsel am Anfang der initDrawGroun() eingefügt, allerdings ohne eine erkennbare Veränderung. 

Gruß 
Quafel


----------

