3

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);
  • 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 May 30 '12 at 22:10
  • Yes, I've tested both textures, and they both work correctly independently without the shader. – Mathew Velasquez May 30 '12 at 22:22
  • 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 May 30 '12 at 22:34
  • 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 May 31 '12 at 00:04
  • How did you arrive at that conclusion? – Tim May 31 '12 at 00:09
  • If I make the palette GL_TEXTURE0, I can sample from it perfectly, but I can't sample from the actual sprite. If I make it GL_TEXTURE1, I can't sample from it, but I can sample from the sprite. – Mathew Velasquez Jun 01 '12 at 20:07
  • 1
    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 Jun 01 '12 at 20:14

2 Answers2

1

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);
Ani
  • 10,826
  • 3
  • 27
  • 46
  • May I have a code example? I thought I was doing this, but the result is always just a solid black texture. – Mathew Velasquez May 30 '12 at 20:37
  • Check the Nehe link. It is explained with code and sample in there. – Ani May 30 '12 at 21:13
  • @MathewVelasquez you should post your own code, so that we can see if there's something wrong with it, instead of asking for someone else to write it. – Tim May 30 '12 at 21:16
  • 1
    Whoa, whoa. Where's the glUniform (http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml) call where you set the sampler on the shader to the texture unit? – Ani May 31 '12 at 01:16
-2

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.

  • 5
    That shouldn't happen; the uniforms are supposed to persist indefinitely, you shouldn't have to overwrite them every frame. Maybe your initialization is failing for some reason, or you're accidentally overwriting it somewhere else? – Tim Jun 01 '12 at 20:23