[SOLVED] Problem with writing a Colorizer

Started by Bluecode, August 16, 2012, 14:29:41

Previous topic - Next topic

Bluecode

Hello,

I'm trying to code a "Colorizer" for my 2D platform game, so I wrote a FBO, and I applied some shaders to it.
The sprites are only made from 6 colors, so I made a Shader that gets a pixel from my FBO, replace it if the corresponding color is found, or leave it if not.
Unfortunately, this don't work as expected :(

In the game's level editor, I'm using some transparent sprites, which modifies the final pixel's color, which isn't detected by my Shader anymore. This leads to shitty results, see by yourself :




In these pictures, I'm trying to colorize my blue sprites in green, using this palette :


(Zoomed x10)

And here is the code of my shaders :
colorizer.vert
void main()
{
	gl_TexCoord[0] = gl_MultiTexCoord0;
	gl_Position = ftransform();
}


colorizer.frag
uniform sampler2D fboTex;

// Couleurs d'entrée
uniform vec3 iColor1;
uniform vec3 iColor2;
uniform vec3 iColor3;
uniform vec3 iColor4;
uniform vec3 iColor5;
uniform vec3 iColor6;

// Couleurs de sortie
uniform vec3 oColor1;
uniform vec3 oColor2;
uniform vec3 oColor3;
uniform vec3 oColor4;
uniform vec3 oColor5;
uniform vec3 oColor6;

void main()
{
	vec4 color = texture2D(fboTex, gl_TexCoord[0].xy);
	vec3 v3color = vec3(color);
	
	gl_FragColor = color;
	
	if(v3color == iColor1)
		gl_FragColor = vec4(oColor1, color.a);
	if(v3color == iColor2)
		gl_FragColor = vec4(oColor2, color.a);
	if(v3color == iColor3)
		gl_FragColor = vec4(oColor3, color.a);
	if(v3color == iColor4)
		gl_FragColor = vec4(oColor4, color.a);
	if(v3color == iColor5)
		gl_FragColor = vec4(oColor5, color.a);
	if(v3color == iColor6)
		gl_FragColor = vec4(oColor6, color.a);
}


So here is my question : is there any way to fix this ugly "glitch" ?
I thought of applying my shader for each sprite individually, while rendering it to the FBO, but I don't know if it's possible with GLSL 1.10 (I want to use OpenGL 2.0 methods and below only). Here comes my other question too : if I do that, will I be able to use something similar to glColor for applying transparency ?

Thanks in advance ! :)

CodeBunny

Using gradient transparency will screw you over because that changes the color field values.

The simplest thing you can do is render every individual object with your shader Your shader is a bit inefficient but that's what you get with non-optimized palletization (plus it doesn't look like your game is complicated enough for it to really matter).

Really though, this is an offshoot of you using a non-rigorous system - since you are using direct color swapping, as soon as the color is not exact everything gets screwed up.

Bluecode

Thanks for your reply !

I modified my code, and now every sprite render with my shader.
However, I was using glColor calls (for drawing some one-colored elements of the GUI, or for apply some transparency to my objects), and now everything is gone. Is there an alternative to glColor for that, or must I disable my shaders every time I draw something with glColor ? Here is two distinct examples on how I'm using this function :

glBegin(GL_QUADS);
	glColor4f(color.r / 255f, color.g / 255f, color.b / 255f, color.a / 255f);
	glVertex2f(x, y);
	glVertex2f(x + width, y);
	glVertex2f(x + width, y + height);
	glVertex2f(x, y + height);
glEnd();


For this one I can simply call GL20.glUseProgram(0); before glBegin and GL20.glUseProgram(Shader.program); after glEnd, but the following is a little more complicated :

GL11.glColor4f(1f, 1f, 1f, 0.5f);
cursor.render(mouseX, mouseY);
GL11.glColor4f(1f, 1f, 1f, 1f);


Here, the cursor's sprite needs to be colorized, so I can't disable my shaders.

Here is a pic showing the bottom info bar and the entity selection background being gone, too :


CodeBunny

Simply change your shaders to include the bound color.

Example

vert file:
void main()
{
	gl_FrontColor = gl_Color;
	gl_TexCoord[0] = gl_MultiTexCoord0;
	gl_Position = ftransform();
}



frag file:
uniform sampler2D fboTex;

// Couleurs d'entrée
uniform vec3 iColor1;
uniform vec3 iColor2;
uniform vec3 iColor3;
uniform vec3 iColor4;
uniform vec3 iColor5;
uniform vec3 iColor6;

// Couleurs de sortie
uniform vec3 oColor1;
uniform vec3 oColor2;
uniform vec3 oColor3;
uniform vec3 oColor4;
uniform vec3 oColor5;
uniform vec3 oColor6;

void main()
{
	vec4 color = texture2D(fboTex, gl_TexCoord[0].xy) * gl_Color;
	vec3 v3color = vec3(color);
	
	gl_FragColor = color;
	
	if(v3color == iColor1)
		gl_FragColor = vec4(oColor1, color.a);
	if(v3color == iColor2)
		gl_FragColor = vec4(oColor2, color.a);
	if(v3color == iColor3)
		gl_FragColor = vec4(oColor3, color.a);
	if(v3color == iColor4)
		gl_FragColor = vec4(oColor4, color.a);
	if(v3color == iColor5)
		gl_FragColor = vec4(oColor5, color.a);
	if(v3color == iColor6)
		gl_FragColor = vec4(oColor6, color.a);
}

Bluecode

Oh, ok, didn't know that we can include this color in GLSL !

Everything works fine now, thanks a lot !