cocos2d-lua shader 高效率做圆角图标

注意事项,必须应用在一个 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

你可能感兴趣的:(cocos2d-lua shader 高效率做圆角图标)