3
votes

I'm coding a fighting game in which each character has a great number of sprites, and each character has several different palette swaps. I've been trying to use a grayscale texture for each sprite, and a 256x1 texture for each palette.

My shaders look like this:

Vertex:

varying vec2 coord;
void main(void)
{
    coord = gl_MultiTexCoord0.xy;
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

Fragment:

uniform sampler2D palette;
uniform sampler2D texture;
varying vec2 coord;
void main()
{
    gl_FragColor = texture2D(palette, vec2(texture2D(texture, coord).r, 0));
}

"palette" is set to 1 and "texture" is set to 0 with glGetUniformLocation and glUniform1i. They compile fine and link fine. I'm able to use the program object in my draw code.

The problem is, I have no idea how to use multitexturing to get the "palette" and "texture" textures cooperating with each other in the shader. This is my first time using multitexturing, and I can't seem to figure out how to get it to work for this kind of solution. Does anyone know how, with these shaders (if they are correct) to simulate a palette swap?

EDIT: Here's my drawing code right now:

glUseProgram(paletteProgram);
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, palette);
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);

glBegin(GL_QUADS);
glTexCoord2f(w1, h1);
glVertex3f(x1, y1, 0);
glTexCoord2f(w1, h2);
glVertex3f(x1, y2, 0);
glTexCoord2f(w2, h2);
glVertex3f(x2, y2, 0);
glTexCoord2f(w2, h1);
glVertex3f(x2, y1, 0);
glEnd();

glUseProgram(0);
2
Your code seems correct (except for glEnable(GL_TEXTURE_2D) which doesn't have any effect when you're using a shader, should remove it). Have you independently verified that these textures are loaded and can be sampled correctly, all multitexturing aside? - Tim
Yes, I've tested both textures, and they both work correctly independently without the shader. - Mathew Velasquez
Hmm I'm stumped. Anyway all I can suggest is to check glGetError if you haven't, and also to check the shader infologs (perhaps theres some kind of non-fatal warning there that could give a clue). - Tim
I'm pretty sure the problem is that it is unable to sample from the palette texture, or whatever is in GL_TEXTURE1. But I can't figure out exactly why... - Mathew Velasquez
All I can suggest is to put up all of your OGL code (shader init, uniform initialization, etc). I don't think there's anything wrong in what you've posted so far. Maybe a mistake is elsewhere. - Tim

2 Answers

1
votes

Your logic seems sound. What you need to do is to set the active texture using glActiveTexture and then bind your texture as usual (for texture units 0 and 1). Now also bind the values 0 to the uniform called texture and 1 to the uniform called palette.

Inside GLSL, you can then use texture2D to fetch texels from the appropriate sampler.

Hope this helps!

This is actually explained in detail over here in this NeHe tutorial (section: Using textures with GLSL).

This is what you need to do

    glUseProgramObject(my_program);
    int my_sampler_uniform_location = glGetUniformLocation(my_program, my_color_texture);

    glActiveTexture(GL_TEXTURE0 + i);
    glBindTexture(GL_TEXTURE_2D, my_texture_object);

    glUniform1i(my_sampler_uniform_location, i);
-2
votes

Okay, I figured it out!

Apparently the uniform variables are reset every time the script program is used... I just needed to set them every frame.

I feel so stupid now, but hey, that's what debugging is.