cocos2D-X源码分析之从cocos2D-X学习OpenGL(6)---cocos内置着色器

       上一篇我们介绍了cocos2d-x绘制基本图形的基本流程,我们还留下了一个着色器的部分没有讲,本篇内容将从openGL的渲染流程讲起,介绍cocos2d-x中的着色器,openGL的渲染流程如图所示:

       

       openGL的绘制通常就是将顶点数据传输到openGL服务端。我们可以将一个顶点视为一个需要统一处理的数据包,这个包中的数据可以是我们需要的任何数据,通常其中几乎始终会包含位置数据。其他数据可能用来决定一个像素的最终颜色。

       顶点着色器:一个复杂的应用程序可能包含许多个顶点着色器,但是在同一时刻只能有一个顶点着色器起作用,它用来进行顶点的变换,可能会非常简单,简单到传递着色器,也可能包含大量的计算。

       几何着色器:对几何图元做处理,可以创建新的图元,这个阶段是可选的

       细分着色器:顶点着色器存在一些限制,一个就是它们在执行的过程中无法创建额外的几何图形,它们仅仅更新与它们当前所处理的顶点相关数据,无法访问当前图元中其他顶点数据,它包含细分控制着色器和细分计算着色器。

       像素着色器(片元着色器):通过编程控制在屏幕上显示颜色的阶段,在这个阶段中,我们使用着色器来计算片元的最终颜色和它的深度值。片元着色器非常强大,在这里我们会使用纹理映射的方式,对顶点处理阶段进行补充。可能还会丢弃不需要处理的片元

       简而言之,顶点着色器决定一个图元应该位于屏幕什么位置,而片元着色器使用这些信息来决定摸个片元的颜色是什么。这两个着色器是必选的。另外因为顶点着色器阶段处理的顶点比较少,而在像素着色阶段处理的像素会很多,所以有时会在顶点阶段处理颜色和光照,其余的像素进行插值处理,为了节约效率,当然效果要差些了。

       下面来看cocos2d-x的着色器流程,回到上一篇讲的DrawNode的init函数中

    //设置着色器
    setGLProgramState(GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_LENGTH_TEXTURE_COLOR));
       这句话调用setGLProgramState设置着色器状态,setGLProgramState函数代码如下:

void Node::setGLProgramState(cocos2d::GLProgramState* glProgramState)
{
    if (glProgramState != _glProgramState)
    {
        CC_SAFE_RELEASE(_glProgramState);
        _glProgramState = glProgramState;
        CC_SAFE_RETAIN(_glProgramState);

        if (_glProgramState)
            _glProgramState->setNodeBinding(this);
    }
}
      这段代码判断设置的着色器是否与之前设置的相同,不同就重新设置,在onDraw函数中,会使用设置的着色器

auto glProgram = getGLProgram();
glProgram->use();
glProgram->setUniformsForBuiltins(transform);
       其中getGLProgram函数就是获得着色器,代码如下:

GLProgram * Node::getGLProgram() const
{
    return _glProgramState ? _glProgramState->getGLProgram() : nullptr;
}
      或者干脆直接在使用时传递使用哪个着色器

auto glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_LENGTH_TEXTURE_COLOR);
glProgram->use();
glProgram->setUniformsForBuiltins(transform);
       无论哪种方式,我们这里都使用的是cocos2d-x的内置的着色器代码,它们在“cocos目录/cocos/renderer”目录中    
       具体的详细加载可以看GLProgramCache类的loadDefaultGLProgram函数,这是一个单例类,在初始化的时候就会加载所有的内置着色器,然后这些着色器的代码文本以键值对的方式存储程序中,当使用的时候就通过getGLProgram调用,我们看一下这里使用的 GLProgram :: SHADER_NAME_POSITION_LENGTH_TEXTURE_COLOR:

        顶点着色器:ccShader_PositionColorLengthTexture.vert

        像素着色器:ccShader_PositionColorLengthTexture.frag


const char* ccPositionColorLengthTexture_vert = STRINGIFY(

\n#ifdef GL_ES\n
attribute mediump vec4 a_position;
attribute mediump vec2 a_texcoord;
attribute mediump vec4 a_color;

varying mediump vec4 v_color;
varying mediump vec2 v_texcoord;

\n#else\n

attribute vec4 a_position;
attribute vec2 a_texcoord;
attribute vec4 a_color;

varying vec4 v_color;
varying vec2 v_texcoord;

\n#endif\n

void main()
{
    v_color = vec4(a_color.rgb * a_color.a, a_color.a);
    v_texcoord = a_texcoord;

    gl_Position = CC_MVPMatrix * a_position;
}
);

       cocos2d-x的内置着色器采用字符串的方式存储,可读性上会差一些,忽略掉“\n”之类的应该还好,着色器使用GLSL,在下一篇中会详细介绍,它类似于C语言,main函数是入口,这里处理了输入进来的颜色,贴图和位置信息,并做相应处理,位置进行了MVP的转换。

       下一篇会介绍GLSL

       

       能力不足,水平有限,如有错误,欢迎指出。







  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值