JOGL- change hue of Texture

Hello guys,

can someone show me an example of drawing a textured quad where the hue(color) has been altered.

I know you can dim the lights, i.e. setting glColor4d(0.4,0.4,0.4,1); which would dim all the colors altogether.

What I need is a way to change the hue. If you know how to do it, you also know exactly what hue means. Shifting all the colors with the same index, ultimately replacing each colored pixel in a similar way across the entire texture.

I hope you guys can help me.

You can only do that using a pixel shader - there’s no nice easy simple fixed pipeline function to do it.

Cas :slight_smile:


package com.gameengine.gutils;

import javax.media.opengl.*;
import com.sun.opengl.util.texture.*;
import com.sun.opengl.util.*;
import java.io.*;
 
public class TextureLoader{
 
 
	/**
	* Texture loader utilizes JOGL's provided utilities to produce a texture.
	*
	* @param fileName relative filename from execution point
	* @return a texture binded to the OpenGL context
	*/
 
	public Texture load(String fileName){
		Texture text = null;
		try{
//                                            TextureIO.setTexRectEnabled(true);text = TextureIO.newTexture(getClass().getResource("/com/gameengine/res/sprites/"+fileName),false,TextureIO.PNG);
			///com/gameengine/res/sprites/
            ///client/res/img/
            text = TextureIO.newTexture(getClass().getResource("/com/gameengine/res/sprites/"+fileName),false,TextureIO.PNG);
			text.setTexParameteri(GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
			text.setTexParameteri(GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
		}catch(Exception e){
			System.out.println(e.getMessage());
			System.out.println("Error loading texture " + fileName);
		}
		return text;
	}
 
}
 


Ok, is there a way to have my loader do it? I really just need a quick and dirty method. hmm I haven’t had any great experience with pixel shaders, altough i’m very interested in shading.

If someone can point me to a tutorial or something.

One condition… it must run on low low spec computers. As in intels crap graphics cards.

You could load the picture in a buffered image and use java2d for manipulation. This http://www.curious-creature.org/2006/09/20/new-blendings-modes-for-java2d/ seems to have what you need. But maybe you could just use opengl blending and mix two textures to achieve what you want.

How would you use blending to achieve my goal? I don’t see how using appropriate blending can offer a hue effect?

If you wanted to do it at runtime you could split your original RGB image into three greyscale textures (one for each channel). Then at runtime tint them with vertex colours and blend them over the top of each other to get the correct combination of the individual channels. Three times the memory and fill rate but it’d work on all hardware.

Maybe if you told us what you’re trying to achieve? It might be easiest to use a fragment shader for proper hue manipulation and fall back to something cheap like vertex colours and/or tinting with GL_SECONDARY_COLOR on old/crap hardware.

Of course you are right, i need to specify what my purpose is:

I am making a small 2d game, and I don’t have any good graphical skills. Hence I need to use the same spritesheet multiple times, only changing the hue so it doesnt all look exactly the same. I just need to create a opengl texture with a changed hue once for each type of monster/player.

So it doesn’t have to be done runtime, and hence can be slow/ineffective. Is there a good example of using a fragment pixel shader? I never found a good tutorial for pixel-shaders in jogl even though I needed one before(for full screen blurring effect).

Since you mentioned wanting to run on old hardware then I’d go with cylab’s suggestion and load it via ImageIO and do the pixel manipulation yourself. Only the very new intel chipsets support fragment shaders (and even then it’s not great).

Hi Cylab,

I’m not sure if this is relevant to you, but there have been some great developments in java2d’s composites with the effects framework:

https://scenegraph-effects.dev.java.net/

java docs here: http://download.java.net/javadesktop/scenario/effects/releases/0.4.9/javadoc/

You can even get bloom effects done using the GPU and SIMD/SSE instructions (not that I know what this really means :P. Also it only works if the java2d pipeline is accelerated and you’re using java6 update 10 or better). See this blog entry by Chris Campbell: http://weblogs.java.net/blog/campbell/archive/2008/02/effectuation_th.html

Ok everyone thanks for your help. I used the java 2d stuff, namely the BufferedImage and Raster + WritableRaster. This is a really easy way to manipulate texture data.

Does anyone have a hue formula? I have access to each pixel in an int array of RGBA values ranging [0…255].

How would I compute the values with the changed hue? I found the wiki article, but it didn’t help me much. The Color class contains RGBtoHBS(or something like that), does anyone know a good way to compute hue with this info?

	public static int getR(int c) {
		return (c & R) >> 16;
	}

	public static int getG(int c) {
		return (c & G) >> 8;
	}

	public static int getB(int c) {
		return c & B;
	}

	private static float[] buf = new float[3];

	public static float[] getHSVvalues(int c) {
		Color.RGBtoHSB(getR(c), getG(c), getB(c), buf);
		return buf;
	}

	public static int hsv(float h, float s, float v) {
		if (s > 1)
			s = 1;
		if (v > 1)
			v = 1;
		return Color.getHSBColor(h, s, v).getRGB();
	}

	public static float getHue(int c) {
		Color.RGBtoHSB(getR(c), getG(c), getB(c), buf);
		return buf[0];
	}

	public static float getSaturation(int c) {
		Color.RGBtoHSB(getR(c), getG(c), getB(c), buf);
		return buf[1];
	}

	public static float getValue(int c) {
		Color.RGBtoHSB(getR(c), getG(c), getB(c), buf);
		return buf[2];
	}

to set the hue to red (for example) use:

int c; //some color 
float[] v=getHSVvalues(c);
c=hsv(0,f[1],f[2]);

edit: this is for ARGB, change it so it suits your RGBA

public static final int
R=0x00ff0000,
G=0x0000ff00,
B=0x000000ff;

Thats what I call a quick response :). I can’t test it now, but I will when I get home!

edit

You might be interested to know that I used some of your code and it worked. That is to say, I ended up only using the getR/G/B(int) functions because of the way the Color.HSVtoRGB/RGBtoHSV functions work.

That aside, it works flawlessly. I have 10 little monsters, each in their own color, following me in a nice little line. This is very satisfying, and will provide me with easy reusable content for my little monster breeder game :slight_smile:

I will be posting it whenever/ if ever I get a beta ready :smiley: Thanks for everyones help