Cocos2dx底层图形绘制使用OpenGL ES可编程着色器(Shader)。OpenGL ES(OpenGl for Embedded System)是OpenGL三维图形API的子集,针对手机,PDA和游戏主机等嵌入式设备而设计。
2d_effect_frag.material 文件:
material Outline
{
technique
{
pass
{
shader
{
vertexShader = 2d_default.vert
fragmentShader = 2d_outline_frag.frag
u_outlineColor = 0,0,0
u_textureOffset = 0.03,0.0
}
}
}
}
2d_outline_frag.frag 文件:
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_texCoord;//从顶点文件传来的坐标
varying vec4 v_fragmentColor;
uniform vec3 u_outlineColor;//可以从外部传值的参数。
uniform float u_threshold;
uniform vec2 u_textureOffset;
void main()
{
vec4 accum = vec4(0.0);
vec4 normal = vec4(0.0);
normal = texture2D(CC_Texture0, vec2(v_texCoord.x, v_texCoord.y));//将CC_Texture0代表的图片的v_texCoord顶点位置的颜色取出到normal中。
//叠加4张图片,分布在上下左右,效果即为**对图片描边**
accum += texture2D(CC_Texture0, vec2(v_texCoord.x + u_textureOffset.x, v_texCoord.y + u_textureOffset.y));
accum += texture2D(CC_Texture0, vec2(v_texCoord.x - u_textureOffset.x, v_texCoord.y + u_textureOffset.y));
accum += texture2D(CC_Texture0, vec2(v_texCoord.x - u_textureOffset.x, v_texCoord.y - u_textureOffset.y));
accum += texture2D(CC_Texture0, vec2(v_texCoord.x + u_textureOffset.x, v_texCoord.y - u_textureOffset.y));
//设置叠加的4张图片的颜色,u_outlineColor可以从外部传入进来
accum.rgb = u_outlineColor * accum.a;
//将原始图片位置挖空
if (normal.a != 0.0)
{
accum.a = 0.0;
}
//只保留边框
normal = (accum * (1.0 - normal.a)); // + (normal * normal.a);
//输出边框
gl_FragColor = v_fragmentColor * normal;
}
2d_default.vert 文件:vertex shader,用于顶点计算,主要用于控制顶点的位置,可以传入当前顶点位置和纹理坐标。
attribute vec4 a_position;//attribute变量,可以从外部传入。
attribute vec2 a_texCoord;
attribute vec4 a_color;
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;//varying变量,用于vertex shader 和fragment shader 之间传递数据。
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
void main()
{
gl_Position = CC_PMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}
调用:调用时设置相对应的参数即可。
local color = cc.c3b(0,0,0)
local material = cc.Material:createWithFilename("shaders/Growth/2d_effect_frag.material")
local program_state = material:getTechniqueByIndex(0):getPassByIndex(0):getGLProgramState()
program_state:setUniformVec3("u_outlineColor", cc.vec3(color.r/255, color.g/255, color.b/255)) --设置u_outlineColor的值
program_state:setUniformVec2("u_textureOffset", {x = 0.02, y = 0.02})
sprite:setGLProgramState(program_state)