Only full-transparent/-opaque texture rendering

Hi everyone

I searched around on Google, this Forum and the LWJGL forum but I couldn’t find a solution for my problem.

So first, I’m creating a 2D game in Java, and I’m using the LWJGL libraries.
Now I want to render images/textures, starting with a main menu background and a cursor. The cursor is saved as a PNG image and has only full-opaque and full-transparent pixels. Now when I load the image and render it, (RGBA and ClearColor is 1,1,1,1) it gets rendered with at least 50% transparency.
I explained everything here quite precisely, but they couldn’t solve my problem.

Anyone an idea?

Greetings
Molt

PS: The attached image is the cursor.

Did you ensured you created an RGBA capable window ?

Common errors with java programmers are that they don’t create RGBA window or don’t enable stencil-window and so on.

So first, ensure it.

Second, from the code on the other forum, it is not easy to see your rendering function (mainly where you draw quads, where you set colors, where you set blending…).

I don’t know if I created an RGBA capable window, but I think so, because every alpha value from 0 to 0.5 works. But if it’s above 0.5, it gets set back to 0.5
(0 is Transparent, 1 is opaque in Java, don’t know if it’s like this in other languages)

The code structure is like this:

  • Init GL (Define Clear Color, Blending Func, …)
  • Instantiate a texture
  • Draw the Texture (the code for this is in Texture.java)

Maybe it helps if I restructure my code a little bit.

I guess this is somehow important: If I don’t change the blending function and draw one-colored quads, they also have a transparency of at least 50%.

<div class=“ubbcode-block”><div class=“ubbcode-header”>Click to reveal… (Code) <input type=“button” class=“form-button” value=“Show me!” onclick=“toggle_spoiler(this, ‘Yikes, my eyes!’, ‘Show me!’)” />]<div style=“display: none;”>Main Code:

initGL();
while(!Display.isCloseRequested())
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	Texture cursor = cultrix.renderer.getTex("gui/cursor.png");
	cursor.drawQuad(mouseX, mouseY);
}

Classes / Functions:

public 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);
}

TextureLoader.java

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);
}

Texture.java

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;
}

[/QUOTE]</div>

Greetings
Molt

it’s most likely this line glBlendFunc(GL_SRC_ALPHA, GL_ONE);
Because GL_ONE makes sure that you get additive blending which can in some cases can be mistaken for having an alpha of 0.5.
try instead glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Tested it and it works.

Thx :slight_smile: