注意事项,必须应用在一个 sprite 节点上:
function shaders.roundNode( head,edge )
local type = tolua.type(head)
if type ~= 'cc.Sprite' then
print('**WARNING**: [shaders.roundNode] node should be cc.Sprite, but', type)
return
end
local strVertSource = [[
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
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 strFragSource = [[
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
uniform float u_edge; // 0.1
void main()
{
float edge = u_edge;
float dis = 0.0;
vec2 texCoord = v_texCoord;
if ( texCoord.x < edge )
{
if ( texCoord.y < edge )
{
dis = distance( texCoord, vec2(edge, edge) );
}
if ( texCoord.y > (1.0 - edge) )
{
dis = distance( texCoord, vec2(edge, (1.0 - edge)) );
}
}
else if ( texCoord.x > (1.0 - edge) )
{
if ( texCoord.y < edge )
{
dis = distance( texCoord, vec2((1.0 - edge), edge ) );
}
if ( texCoord.y > (1.0 - edge) )
{
dis = distance( texCoord, vec2((1.0 - edge), (1.0 - edge) ) );
}
}
if(dis > 0.001)
{
float gap = edge * 0.1;
if(dis <= edge - gap)
{
gl_FragColor = texture2D( CC_Texture0,texCoord);
}
else if(dis <= edge)
{
//gl_FragColor = texture2D( CC_Texture0,texCoord) * (gap - (dis - edge + gap))/gap; // iOS 上四个角会闪烁
gl_FragColor = vec4(0,0,0,0);// 直接设置透明
}
}
else
{
gl_FragColor = texture2D( CC_Texture0,texCoord);
}
}
]]
local shaderKey = 'shaderRound'
local glCache = cc.GLProgramCache:getInstance()
local glProgram = glCache:getGLProgram(shaderKey)
if not glProgram then
glProgram = cc.GLProgram:createWithByteArrays(strVertSource, strFragSource)
glProgram:link()
glProgram:updateUniforms()
glCache:addGLProgram(glProgram, shaderKey)
end
if not glProgram then print('glProgram is nil') return end
local glProgramState = cc.GLProgramState:getOrCreateWithGLProgram(glProgram)
if not glProgramState then print('glProgramState is nil') return end
edge = edge or 0.1
glProgramState:setUniformFloat('u_edge', 0.1)
head:setGLProgramState(glProgramState)
end
实例:
icon 类型是 ImageView
shaders.roundNode(icon:getVirtualRenderer():getSprite())
已放到仓库中:
https://github.com/c0i/cocos2dx-lite/blob/dev/src/packages/shaders.lua
参考:
http://blog.csdn.net/zhaoxiaofeng44/article/details/72871043
http://forum.cocos.com/t/lua-opengl-shader-scale9sprite/14556
http://www.voidcn.com/article/p-amjyuvbh-ta.html
http://www.voidcn.com/article/p-tlstkqdp-cs.html
http://blog.csdn.net/Register_man/article/details/77980497
网友评论