Hello Guest

# Blending / Transparency Problems

• 7 Replies
• 14372 Views

#### Molt

• 5
##### Blending / Transparency Problems
« on: October 13, 2011, 12:51:12 »
Hi everyone

I tried to draw a background and a cursor (both images). The background should be opaque and the cursor should have onla full transparent and full opaque pixels.
When I enable blending, it gets rendered 50% transparent on opaque pixels and transparent on transparent pixels.
When I disable blending, it gets rendered 100% opaque on opaque pixels and opaque and black on transparent pixels. -.-
I was experimenting with the glBlendFunc(), but I didn't get what I'm looking for.
I also Googled and searched in this forum, but I didn't get rid of my problem.
Has anyone an idea what I'm doing wrong?

Molt
« Last Edit: October 13, 2011, 12:53:56 by Molt »

#### Molt

• 5
##### Re: Blending / Transparency Problems
« Reply #1 on: October 13, 2011, 18:13:42 »
Still unsolved.
Here's some code I use (I use TextureHandler.java and a modified version of Texture.java from the Space Invaders Sample):
Code: [Select]
`// Added in Texture.java// Where the picture actually gets drawnpublic void drawQuad(int x, int y, double factorX, double factorY){ drawQuad(x, y, 0, factorX, factorY);}public void drawQuad(int x, int y, int z, double factorX, double factorY){ bind(); glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex3f(x, y, z); glTexCoord2f(0, getHeight()); glVertex3f(x, y + (int)Math.round(getImageHeight() * factorY), z); glTexCoord2f(getWidth(), getHeight()); glVertex3f(x + (int)Math.round(getImageWidth() * factorX), y + (int)Math.round(getImageHeight() * factorY), z); glTexCoord2f(getWidth(), 0); glVertex3f(x + (int)Math.round(getImageWidth() * factorX), y, z); glEnd();}`
Code: [Select]
`// initialize the whole thingpublic void initGL(){ glShadeModel(GL_SMOOTH); glEnable(GL_TEXTURE_2D); glEnable(GL_ALPHA); glEnable(GL_BLEND); glEnable(GL_DEPTH); glDepthFunc(GL_EQUAL); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);}`
Code: [Select]
`// This is executed before every "drawing phase"glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glLoadIdentity();`
Code: [Select]
`Texture cursor = renderer.getTex("gui/cursor.png");cursor.drawQuad(100, 100, -1, 1, 1);`
Hope this helps and anyone knows what to do...

Greetings
Molt

#### broumbroum

• 361
##### Re: Blending / Transparency Problems
« Reply #2 on: October 13, 2011, 20:04:10 »
...
When I enable blending, it gets rendered 50% transparent on opaque pixels and transparent on transparent pixels....
What do you set as current blending color ? should be white glColori(1,1,1,1) where you seem to have an alpha-blended glColorf(1f,1f,1f,.5f).

#### Molt

• 5
##### Re: Blending / Transparency Problems
« Reply #3 on: October 14, 2011, 11:27:54 »
I didn't set anything, I'm using the glClearColor.
When I add glColor4d(1,1,1,1), nothing happens, but when I change it to glColor4d(1,1,1,0.5), the pictures get more transparent.
There must be something that halves the alpha value...
Here's the whole TextureLoader:
Code: [Select]
`import java.awt.Color;import java.awt.Graphics;import java.awt.Image;import java.awt.color.ColorSpace;import java.awt.image.BufferedImage;import java.awt.image.ColorModel;import java.awt.image.ComponentColorModel;import java.awt.image.DataBuffer;import java.awt.image.DataBufferByte;import java.awt.image.Raster;import java.awt.image.WritableRaster;import java.io.IOException;import java.net.URL;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.IntBuffer;import java.util.HashMap;import java.util.Hashtable;import javax.swing.ImageIcon;import org.lwjgl.BufferUtils;import static org.lwjgl.opengl.GL11.*;public class TextureLoader{    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() { glGenTextures(textureIDBuffer); return textureIDBuffer.get(0);    } public Texture getTex(String path) { return getTexture("../../resources/graphic/" + path); }     public Texture getTexture(String path) {        Texture tex = table.get(path);        if(tex == null) {            tex = getTexture(path, GL_TEXTURE_2D, GL_RGBA, GL_LINEAR, GL_LINEAR); table.put(path,tex);        }        return tex;    }     public Texture getTexture(String path, int target, int dstPixelFormat, int minFilter, int magFilter) {        int srcPixelFormat;        int textureID = createTextureID();        Texture texture = new Texture(target,textureID);        glBindTexture(target, textureID);        BufferedImage bufferedImage = loadImage(path);        texture.setWidth(bufferedImage.getWidth());        texture.setHeight(bufferedImage.getHeight());        if(bufferedImage.getColorModel().hasAlpha()) {            srcPixelFormat = GL_RGBA;        } else {            srcPixelFormat = GL_RGB;        }        ByteBuffer textureBuffer = convertImageData(bufferedImage,texture);        if(target == GL_TEXTURE_2D) {            glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilter);            glTexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilter);        }        glTexImage2D(target, 0, dstPixelFormat, get2Fold(bufferedImage.getWidth()), get2Fold(bufferedImage.getHeight()), 0, srcPixelFormat, GL_UNSIGNED_BYTE, textureBuffer);        return texture;    }     private static int get2Fold(int fold) {        int ret = 2;        while (ret < fold) {            ret *= 2;        }        return ret;    }     private ByteBuffer convertImageData(BufferedImage bufferedImage,Texture texture) {        ByteBuffer imageBuffer;        WritableRaster raster;        BufferedImage texImage;        int texWidth = 2;        int texHeight = 2;        while(texWidth < bufferedImage.getWidth()) {            texWidth *= 2;        }        while(texHeight < bufferedImage.getHeight()) {            texHeight *= 2;        }        texture.setTextureHeight(texHeight);        texture.setTextureWidth(texWidth);        if(bufferedImage.getColorModel().hasAlpha()) {            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, texWidth, texHeight, 4, null);            texImage = new BufferedImage(glAlphaColorModel, raster, false, new Hashtable());        } else {            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, texWidth, texHeight, 3, null);            texImage = new BufferedImage(glColorModel, raster, false, new Hashtable());        }        Graphics g = texImage.getGraphics();        g.setColor(new Color(0f, 0f, 0f, 0f));        g.fillRect(0, 0, texWidth, texHeight);        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) { try { Image img = new ImageIcon(ref).getImage(); BufferedImage bufferedImage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB); Graphics g = bufferedImage.getGraphics(); g.drawImage(img, 0, 0, null); g.dispose(); return bufferedImage; } catch(Exception e) { return new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); }    } private HashMap<String, Texture> table = new HashMap<String, Texture>();    private ColorModel glAlphaColorModel;    private ColorModel glColorModel;    private IntBuffer textureIDBuffer = BufferUtils.createIntBuffer(1);}`The Texture:
Code: [Select]
`import static org.lwjgl.opengl.GL11.*;public class Texture{ public Texture(int target, int textureID) { this.target = target; this.textureID = textureID; } public void drawQuad(int x, int y) { drawQuad(x, y, 0); } public void drawQuad(int x, int y, int z) { bind(); glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex3f(x, y, z); glTexCoord2f(0, getHeight()); glVertex3f(x, y + getImageHeight(), z); glTexCoord2f(getWidth(), getHeight()); glVertex3f(x + getImageWidth(), y + getImageHeight(), z); glTexCoord2f(getWidth(), 0); glVertex3f(x + getImageWidth(), y, z); glEnd(); } public void drawQuadSize(int x, int y, int width, int height) { drawQuadSize(x, y, 0, width, height); } public void drawQuadSize(int x, int y, int z, int width, int height) { bind(); glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex3f(x, y, z); glTexCoord2f(0, getHeight()); glVertex3f(x, y + height, z); glTexCoord2f(getWidth(), getHeight()); glVertex3f(x + width, y + height, z); glTexCoord2f(getWidth(), 0); glVertex3f(x + width, y, z); glEnd(); } public void bind() { glBindTexture(target, textureID); } public void setHeight(int height) { this.height = height; setHeight(); } public void setWidth(int width) { this.width = width; setWidth(); } public int getImageHeight() { return height; } public int getImageWidth() { return width; } public float getHeight() { return heightRatio; } public float getWidth() { return widthRatio; } public void setTextureHeight(int texHeight) { this.texHeight = texHeight; setHeight(); } public void setTextureWidth(int texWidth) { this.texWidth = texWidth; setWidth(); } private void setHeight() { if (texHeight != 0) { heightRatio = ((float) height) / texHeight; } } private void setWidth() { if (texWidth != 0) { widthRatio = ((float) width) / texWidth; } } private int target; private int textureID; private int height; private int width; private int texWidth; private int texHeight; private float widthRatio; private float heightRatio;}`Where the cursor gets drawn:
Code: [Select]
`Texture cursor = cultrix.renderer.getTex("gui/cursor.png");cursor.drawQuad(mouseX, mouseY);`The cursor image can be loaded, gets displayed at the right coordinates, just transparent -.-
I attached the cursor image so u can be 100% sure the image is not transparent.

Greetings
Molt

#### Fool Running

• 828
##### Re: Blending / Transparency Problems
« Reply #4 on: October 14, 2011, 12:59:11 »
Quote
BufferedImage bufferedImage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);
It looks like you are loading your .png into a buffered image that has no alpha value. My guess is that your resulting image doesn't have alpha (i.e. you don't get to this line of code: srcPixelFormat = GL_RGBA;).

Then your blending mode (glBlendFunc(GL_SRC_ALPHA, GL_ONE)) is causing your fully opaque texture to have a weird alpha blending (which makes it look strange).
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option

#### Molt

• 5
##### Re: Blending / Transparency Problems
« Reply #5 on: October 14, 2011, 13:36:52 »
Your guess was right, it always returned false for hasAlpha() method.
I changed the ImageType to TYPE_INT_ARGB, and it returns true now, but the cursor is still half-transparent. -.-
And when I disable blending, the transparent part is black again.

Greetings
Molt

#### Molt

• 5
##### Re: Blending / Transparency Problems
« Reply #6 on: October 15, 2011, 10:42:20 »
I added this block:
Code: [Select]
` glBegin(GL_QUADS); glColor4f(1.0f, 0.0f, 0.0f, 1.0f); glVertex2f(0, 0); glVertex2f(0, 100); glVertex2f(100, 100); glVertex2f(100, 0); glColor4f(0.0f, 1.0f, 0.0f, 0.5f); glVertex2f(100, 0); glVertex2f(100, 100); glVertex2f(200, 100); glVertex2f(200, 0); glColor4f(0.0f, 0.0f, 1.0f, 0.0f); glVertex2f(200, 0); glVertex2f(200, 100); glVertex2f(300, 100); glVertex2f(300, 0); glEnd();`
The first and the second have both a transparency of 50%, the third is invisible (as it should be).
So it's not a problem with the TextureLoader or the Texture class, and the alpha value doesn't get multiplied, but there seems to be an alpha limit... any ideas?

Greetings
Molt

#### Fool Running

• 828
##### Re: Blending / Transparency Problems
« Reply #7 on: October 17, 2011, 12:53:54 »
Did you change your blending mode (usually glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) works as a good starting point)?
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option