在做游戏的时候,特别是2D游戏,人物的动画常常是通过许多张图片不断切断组成的,如果这些图片还想通过不同颜色制造不同风格,就会导致图片数量成倍的增加。
这会导致资源消耗太多的问题。
于是通过使用索引图配合不同的色表就可以达到一组图片,多种效果的功能
但是如果组合索引图和色表的时候,是预先为索引图片填色,同样会消耗很多内存,而使用像SDL这些自带填色功能的引擎实时生成图片,填色,删除效率又不太理想。
使用GLSL的片段着色器就能较快的根据图片生成的纹理去填色
具体操作如下
(事先声明,方法不唯一,只是我现在用GLSL填色的时候,效率挺好,故拿上来和大家分享)
1.需要一个顶点着色器:
void main(void) { gl_Position = ftransform(); //裁剪坐标 gl_TexCoord[0]=gl_MultiTexCoord0; //纹理坐标 }
2.片段着色器
uniform vec3 color_value[256];//用于记录颜色表数据 uniform sampler2D sampler0;//用于记录纹理采样 void main(void) { int index; //索引 vec3 color; //最终颜色 vec4 clrIndex =texture2D(sampler0,vec2(gl_TexCoord[0])); //索引图 index=clrIndex[0]*255; //获取索引值 color.rgb=color_value[index]/255.0; //从色表对应的索引位置获取颜色值 gl_FragColor=color; }
3.在程序中调用示例
GLint uniformLoc = 0; //填色 GLfloat* palPtr = LoadPalette(szPaletteFile); //读取色表函数就不在这里提供了 if (palPtr) { glUseProgram(myProgram); //假设myProgram是已经配置好的program if ((uniformLoc = glGetUniformLocation(myProgram,"sampler0")) != -1) glUniform1i(uniformLoc, 0); if ((uniformLoc = glGetUniformLocation(myProgram,"color_value")) != -1) glUniform3fv(uniformLoc,256,palPtr); } glBegin(GL_QUADS); glColor4ub(red,green,blue,alpha); glTexCoord2f(texL,texB);glVertex3f(l, b, sprPrior); glTexCoord2f(texR,texB);glVertex3f(r, b, sprPrior); glTexCoord2f(texR,texT);glVertex3f(r, t, sprPrior); glTexCoord2f(texL,texT);glVertex3f(l, t, sprPrior); glEnd();
//只展示部分代码,用来作为示例
//另外,我发现这种填色在对纹理缩放之后,会出现颜色错误的问题,原因未知,这也是我发这篇文章的主要原因,希望能得到帮助