cocos中用到了许多shader

例如最常用的Sprite所使用的

ccPositionTextureColor_noMVP_frag

其中主函数写到

void main()
{
  gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);
}

即最终片段的颜色值=图形颜色与纹理的混合

一般来说Sprite只对应一张纹理,也就是一张png贴图

那么纹理是如何与CC_Texture0建立关系的呢

下面梳理一下cocos的封装套路

个人认为并不能喷cocos封装的不好

毕竟底层的东西的确十分复杂

对于游戏开发人员,越简单的API越nice

但同样封装也不可避免的增加了学习底层技术的难度

 

1.CCGLProgram.cpp/GLProgram::compileShader

这里如下声明了CC_Texture0

const GLchar *sources[] = {

...

uniform sampler2D CC_Texture0;

...

}

我的理解是,sources内容被强加入每一个shader

作为通用部分

这里sampler2D类型在glsl中作为纹理单元/纹理句柄

大概就是一个类似指针的东西,指向具体的纹理数据(图片颜色数组)

 

2.CCGLProgram.cpp/GLProgram::updateUniforms()

这里为CC_Texture0做了赋值操作

首先找到location

_builtInUniforms[UNIFORM_SAMPLER0] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER0);
_builtInUniforms[UNIFORM_SAMPLER1] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER1);
_builtInUniforms[UNIFORM_SAMPLER2] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER2);
_builtInUniforms[UNIFORM_SAMPLER3] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER3);

然后做了这样的操作

// Since sample most probably won't change, set it to 0,1,2,3 now.
if(_builtInUniforms[UNIFORM_SAMPLER0] != -1)
  setUniformLocationWith1i(_builtInUniforms[UNIFORM_SAMPLER0], 0);

 

void GLProgram::setUniformLocationWith1i(GLint location, GLint i1)
{
  bool updated = updateUniformLocation(location, &i1, sizeof(i1)*1);

  if( updated )
  {
    glUniform1i( (GLint)location, i1);
  }
}

结果就是用glUniform1i把

CC_Texture0的值做成了0

我的理解是,CC_Texture0现在被赋值为对应0号纹理单元

 

3.GL::bindTexture2D(textureId);

将纹理绑定于纹理单元

因为多重纹理的关系,所以我们既可以选择纹理图,还可以选择纹理单元!

当然如果只有单个纹理,那么自然应该绑在默认纹理也就是CC_Texture0上面

GL::bindTexture2D(textureId)中调用如下函数

GL::bindTexture2DN(0, textureId);

 

GL::bindTexture2DN(GLuint textureUnit, GLuint textureId)

内部调用如下

activeTexture(GL_TEXTURE0 + textureUnit);//1.激活纹理单元,选择纹理单元
glBindTexture(GL_TEXTURE_2D, textureId);//2.为当前纹理单元绑定纹理图片

textureUnit == 0 表示我们激活CC_Texture0

textureId 是我们使用的纹理图片

 

因此这时在shader中就可以使用CC_Texture0来做纹理采样了!

 

写的不怎么好

帮助自己理解

高手看到错误劳烦指出!

 

参考文献

https://zhuanlan.zhihu.com/p/20289660

http://www.cnblogs.com/slysky/p/3981210.html