I was playing around with shaders and the BlenderMaterial module for the game engine, and discovered a trick to quickly swap textures during the runtime. I like this better than swapping out meshes, and it grabs the textures from the texture slots instead of replacing it with a file using the Texture module.
#NEW TEXTURE SWAP LOGIC
vertex_shader = """
void main(void)
{
// simple projection of the vertex position to view space
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// coordinate of the texture channels (seems to be limit of 8)
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[1] = gl_MultiTexCoord1;
gl_TexCoord[2] = gl_MultiTexCoord2;
gl_TexCoord[3] = gl_MultiTexCoord3;
gl_TexCoord[4] = gl_MultiTexCoord4;
gl_TexCoord[5] = gl_MultiTexCoord5;
gl_TexCoord[6] = gl_MultiTexCoord6;
gl_TexCoord[7] = gl_MultiTexCoord7;
//gl_TexCoord[8] and above doesn't work
}
""";
fragment_shader="""
uniform sampler2D texture_a;
uniform sampler2D texture_b;
uniform float factor;
void main(void)
{
vec4 color_0 = texture2D(texture_a, gl_TexCoord[0].st);
vec4 color_1 = texture2D(texture_b, gl_TexCoord[1].st);
gl_FragColor = mix(color_0, color_1, factor);
}
""";
for mesh in body.meshes:
for material in mesh.materials:
shader = material.getShader()
shader.setSource(vertex_shader, fragment_shader, True)
shader.setUniform1f('factor', 1.0)# set blend factor to 1
shader.setSampler('texture_a', 0)#default slot
#test keys:
if XKEY==acv: #reset to neutral
shader.setSampler('texture_b', 0)#tex slot to replace with
if CKEY==acv:
shader.setSampler('texture_b', 1)#tex slot to replace with
if VKEY==acv:
shader.setSampler('texture_b', 2)#tex slot to replace with
if BKEY==acv:
shader.setSampler('texture_b', 3)#tex slot to replace with
#...
if NKEY==acv:
shader.setSampler('texture_b', 6)#tex slot to replace with
if MKEY==acv:
shader.setSampler('texture_b', 7)#tex slot to replace with
I am not well-versed in OpenGL, but I frankensteined this together and it works for me. This is particularly helpful for animated sprites or facial expressions/lip sync. HOWEVER, I discovered a catch. I am not sure, but it seems like if I try to add another slot, it will be considered invalid, even if there are 8+ frames (texture slots) assigned to the material in a stack in the blend file. I am guessing that since it is 8, this is the limit to the amount of textures that are “allowed” for OpenGL (?).