cocos构建了一个GLProgram的缓存,毕竟create GL program是一件消耗比较大的工作,且经常存在这种情况:两个绘制工作的shader逻辑一样,只是attribute、uniform的值不同,完全可以直接更新这些变量的值而避免再新建一个Program。
一、数据结构
class CC_DLL GLProgramCache : public Ref
{
// GLProgram的缓存。
// key: 自定义的string,用于唯一辨识。
// value: GLProgram object
std::unordered_map<std::string, GLProgram*> _programs;
};
class CC_DLL GLProgramCache : public Ref
{
public:
void loadDefaultGLPrograms(); // 加载所有内置的shader
void reloadDefaultGLPrograms(); // 重载所有内置的shader
void reloadDefaultGLProgramsRelativeToLights(); // 重载光照相关的内置的shader
// 自定义的GLProgram对象实例都需要手动缓存起来。
// 内置的shader都自动缓存了。
void addGLProgram(GLProgram* program, const std::string &key);
// 获得shader的GLProgram object,这里面已经一些内置的常用Shader了,
GLProgram * getGLProgram(const std::string &key);
}
二、内置Shader
在创建GLProgramCache的时候就加载内置shader的GLProgram Object。
auto glProgramCache = GLProgramCache::getInstance();
// Position Texture Color shader
//
// gl_Position = CC_MVPMatrix * a_position(顶点数据传入的顶点坐标)
// gl_FragColor = texutreColor * a_color(顶点数据传入的color)
//
// kShaderType_PositionTextureColor
// 顶点着色器代码:#include "renderer/ccShader_PositionTextureColor.frag"
// 片段着色器代码:#include "renderer/ccShader_PositionTextureColor.vert"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR );
// Position Texture Color without MVP shader
//
// gl_Position = CC_PMatrix * a_position
// gl_FragColor = texutreColor * a_color
//
// kShaderType_PositionTextureColor_noMVP
// #include "renderer/ccShader_PositionTextureColor_noMVP.frag"
// #include "renderer/ccShader_PositionTextureColor_noMVP.vert"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP );
// Position Texture Color alpha test
//
// gl_Position = CC_MVPMatrix * a_position
// gl_FragColor = texutreColor * a_color
//
// kShaderType_PositionTextureColorAlphaTest
// #include "renderer/ccShader_PositionTextureColor.frag"
// #include "renderer/ccShader_PositionTextureColor.vert"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_POSITION_TEXTURE_ALPHA_TEST );
// Position Texture Color alpha test
//
// gl_Position = CC_PMatrix * a_position
// gl_FragColor = texutreColor * a_color
//
// kShaderType_PositionTextureColorAlphaTestNoMV
// #include "renderer/ccShader_PositionTextureColor_noMVP.frag"
// #include "renderer/ccShader_PositionTextureColor_noMVP.vert"
// loadDefaultGLProgram(p, kShaderType_PositionTextureColorAlphaTestNoMV);
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_POSITION_TEXTURE_ALPHA_TEST_NO_MV );
// Position, Color shader
//
// gl_Position = CC_MVPMatrix * a_position;
// gl_FragColor = a_color;
//
// kShaderType_PositionColor
// #include "renderer/ccShader_PositionColor.frag"
// #include "renderer/ccShader_PositionColor.vert"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_POSITION_COLOR );
// Position, Color, PointSize shader
//
// gl_Position = CC_MVPMatrix * a_position;
// gl_PointSize = a_texCoord.x; // 一个顶点的像素大小
// v_fragmentColor = vec4(a_color.rgb * a_color.a * u_alpha, a_color.a * u_alpha);
//
// gl_FragColor = v_fragmentColor;
//
// kShaderType_PositionColorTextureAsPointsize
// #include "renderer/ccShader_PositionColorTextureAsPointsize.vert"
// #include "renderer/ccShader_PositionColor.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_POSITION_COLOR_TEXASPOINTSIZE );
//
// Position, Color shader no MVP
//
// gl_Position = CC_PMatrix * a_position;
// v_fragmentColor = a_color;
//
// gl_FragColor = v_fragmentColor;
//
// kShaderType_PositionColor_noMVP
// #include "renderer/ccShader_PositionTextureColor_noMVP.vert"
// #include "renderer/ccShader_PositionColor.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_POSITION_COLOR_NO_MVP );
//
// Position Texture shader
//
// gl_Position = CC_MVPMatrix * a_position;
//
// gl_FragColor = textureColor;
//
// kShaderType_PositionTexture
// #include "renderer/ccShader_PositionTexture.vert"
// #include "renderer/ccShader_PositionTexture.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_POSITION_TEXTURE );
//
// Position, Texture attribs, 1 Color as uniform shader
//
// uniform vec4 u_color;
//
// gl_Position = CC_MVPMatrix * a_position;
//
// gl_FragColor = textureColor * u_color;
//
// kShaderType_PositionTexture_uColor
// #include "renderer/ccShader_PositionTexture_uColor.vert"
// #include "renderer/ccShader_PositionTexture_uColor.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_POSITION_TEXTURE_U_COLOR );
//
// Position Texture A8 Color shader
//
// gl_Position = CC_MVPMatrix * a_position;
//
// gl_FragColor = vec4( a_color.rgb, a_color.a * textureColor.a );
//
// kShaderType_PositionTextureA8Color
// #include "renderer/ccShader_PositionTextureA8Color.vert"
// #include "renderer/ccShader_PositionTextureA8Color.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_POSITION_TEXTURE_A8_COLOR );
//
// Position and 1 color passed as a uniform (to simulate glColor4ub )
//
// uniform vec4 u_color;
// uniform float u_pointSize;
//
// gl_Position = CC_MVPMatrix * a_position;
// gl_PointSize = u_pointSize;
//
// gl_FragColor = u_color;
//
// kShaderType_Position_uColor
// #include "renderer/ccShader_Position_uColor.vert"
// #include "renderer/ccShader_Position_uColor.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_POSITION_U_COLOR );
//
// Position, Length(TexCoords, Color (used by Draw Node basically )
//
// uniform float u_alpha;
//
// gl_Position = CC_MVPMatrix * a_position;
//
// gl_FragColor = vec4(a_color.rgb * a_color.a * u_alpha, a_color.a * u_alpha)
// * step(0.0, 1.0 - length(a_texcoord));
//
// kShaderType_PositionLengthTextureColor
// #include "renderer/ccShader_PositionColorLengthTexture.vert"
// #include "renderer/ccShader_PositionColorLengthTexture.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_POSITION_LENGTH_TEXTURE_COLOR );
//
// uniform vec4 u_textColor;
//
// gl_Position = CC_MVPMatrix * a_position;
//
// float alpha = smoothstep(0.5 - 0.04, 0.5 + 0.04, textureColor.a) * u_textColor.a;
// gl_FragColor = a_color * vec4(u_textColor.rgb, alpha);
//
// kShaderType_LabelDistanceFieldNormal
// #include "renderer/ccShader_Label.vert"
// #include "renderer/ccShader_Label_df.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_NORMAL );
//
// uniform vec4 u_effectColor;
// uniform vec4 u_textColor;
//
// gl_Position = CC_MVPMatrix * a_position;
// float alpha = smoothstep(0.5 - 0.04, 0.5 + 0.04, textureColor.a);
//
// // glow
// float mu = smoothstep(0.5, 1.0, sqrt(textureColor.a));
// vec4 color = u_effectColor*(1.0 - alpha) + u_textColor * alpha;
// gl_FragColor = a_color * vec4(color.rgb, max(alpha, mu) * color.a);
//
// kShaderType_LabelDistanceFieldGlow
// #include "renderer/ccShader_Label.vert"
// #include "renderer/ccShader_Label_df_glow.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_GLOW );
//
// gl_Position = CC_MVPMatrix * a_position;
//
// vec4 c = a_color * textureColor;
// gl_FragColor.xyz = vec3(0.2126*c.r + 0.7152*c.g + 0.0722*c.b);
// gl_FragColor.w = c.w;
//
// kShaderType_UIGrayScale
// #include "renderer/ccShader_PositionTextureColor_noMVP.vert"
// #include "renderer/ccShader_UI_Gray.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_POSITION_GRAYSCALE );
//
// uniform vec4 u_textColor;
//
// gl_Position = CC_MVPMatrix * a_position;
// gl_FragColor = a_color * vec4(u_textColor.rgb, u_textColor.a * textureColor.a;
//
// kShaderType_LabelNormal
// #include "renderer/ccShader_Label.vert"
// #include "renderer/ccShader_Label_normal.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_LABEL_NORMAL );
// kShaderType_LabelOutline
// #include "renderer/ccShader_Label.vert"
// #include "renderer/ccShader_Label_outline.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_LABEL_OUTLINE );
// ETC1 ALPHA supports.
//
// gl_Position = CC_MVPMatrix * a_position;
//
// vec4 texColor = vec4(textureColor.rgb, textureColor1.r);
// texColor.rgb *= texColor.a;
// gl_FragColor = a_color * texColor;
//
// kShaderType_ETC1ASPositionTextureColor
// #include "renderer/ccShader_PositionTextureColor.vert"
// #include "renderer/ccShader_ETC1AS_PositionTextureColor.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_ETC1AS_POSITION_TEXTURE_COLOR );
//
// ETC1 ALPHA supports.
//
// gl_Position = CC_PMatrix * a_position;
//
// vec4 texColor = vec4(textureColor.rgb, textureColor1.r);
// texColor.rgb *= texColor.a;
// gl_FragColor = a_color * texColor;
//
// kShaderType_ETC1ASPositionTextureColor_noMVP
// #include "renderer/ccShader_PositionTextureColor_noMVP.vert"
// #include "renderer/ccShader_ETC1AS_PositionTextureColor.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_ETC1AS_POSITION_TEXTURE_COLOR_NO_MVP );
//
// ETC1 Gray supports.
//
// gl_Position = CC_MVPMatrix * a_position;
//
// vec4 texColor = vec4(textureColor.rgb, textureColor1.r);
// texColor.rgb *= texColor.a;
// texColor = a_color * texColor;
// gl_FragColor.rgb = vec3(0.2126 * texColor.r + 0.7152 * texColor.g + 0.0722 * texColor.b);
// gl_FragColor.a = texColor.a;
//
// kShaderType_ETC1ASPositionTextureGray
// #include "renderer/ccShader_PositionTextureColor.vert"
// #include "renderer/ccShader_ETC1AS_PositionTextureGray.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_ETC1AS_POSITION_TEXTURE_GRAY );
//
// ETC1 Gray supports.
//
// gl_Position = CC_PMatrix * a_position;
//
// vec4 texColor = vec4(textureColor.rgb, textureColor1.r);
// texColor.rgb *= texColor.a;
// texColor = a_color * texColor;
// gl_FragColor.rgb = vec3(0.2126 * texColor.r + 0.7152 * texColor.g + 0.0722 * texColor.b);
// gl_FragColor.a = texColor.a;
//
// kShaderType_ETC1ASPositionTextureGray_noMVP
// #include "renderer/ccShader_PositionTextureColor_noMVP.vert"
// #include "renderer/ccShader_ETC1AS_PositionTextureGray.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_NAME_ETC1AS_POSITION_TEXTURE_GRAY_NO_MVP );
//
// uniform vec4 u_startColor;
// uniform vec4 u_endColor;
// uniform vec2 u_center;
// uniform float u_radius;
// uniform float u_expand;
//
// gl_Position = CC_MVPMatrix * a_position;
// gl_FragColor = a_color;
//
// float d = distance(a_position.xy, u_center) / u_radius;
// if (d <= 1.0) {
// if (d <= u_expand) {
// gl_FragColor = u_startColor;
// }
// else {
// gl_FragColor = mix(u_startColor, u_endColor, (d - u_expand) / (1.0 - u_expand));
// }
// }
// else {
// gl_FragColor = vec4( 0.0, 0.0, 0.0, 0.0 );
// }
//
// kShaderType_LayerRadialGradient
// #include "renderer/ccShader_Position.vert"
// #include "renderer/ccShader_LayerRadialGradient.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_LAYER_RADIAL_GRADIENT );
//
// gl_Position = CC_MVPMatrix * a_position;
// gl_FragColor = a_color;
//
// kShaderType_3DPosition
// #include "renderer/ccShader_3D_PositionTex.vert"
// #include "renderer/ccShader_3D_Color.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_3D_POSITION );
//
// gl_Position = CC_MVPMatrix * a_position;
// gl_FragColor = a_color;
//
// kShaderType_3DPositionTex
// #include "renderer/ccShader_3D_PositionTex.vert"
// #include "renderer/ccShader_3D_ColorTex.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_3D_POSITION_TEXTURE );
//
// gl_Position = CC_MVPMatrix * a_position;
// gl_FragColor = a_color;
//
// kShaderType_3DSkinPositionTex
// #include "renderer/ccShader_3D_PositionTex.vert"
// #include "renderer/ccShader_3D_ColorTex.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_3D_SKINPOSITION_TEXTURE );
// loadDefaultGLProgram( p, kShaderType_3DPositionNormal );
glProgramCache->getGLProgram( GLProgram::SHADER_3D_POSITION_NORMAL );
// loadDefaultGLProgram( p, kShaderType_3DPositionNormalTex );
glProgramCache->getGLProgram( GLProgram::SHADER_3D_POSITION_NORMAL_TEXTURE );
// loadDefaultGLProgram( p, kShaderType_3DSkinPositionNormalTex );
glProgramCache->getGLProgram( GLProgram::SHADER_3D_SKINPOSITION_NORMAL_TEXTURE );
// loadDefaultGLProgram( p, kShaderType_3DPositionBumpedNormalTex );
glProgramCache->getGLProgram( GLProgram::SHADER_3D_SKINPOSITION_NORMAL_TEXTURE );
// loadDefaultGLProgram( p, kShaderType_3DSkinPositionBumpedNormalTex );
glProgramCache->getGLProgram( GLProgram::SHADER_3D_SKINPOSITION_BUMPEDNORMAL_TEXTURE );
// loadDefaultGLProgram( p, kShaderType_3DParticleColor );
glProgramCache->getGLProgram( GLProgram::SHADER_3D_PARTICLE_COLOR );
// kShaderType_3DParticleTex
// #include "renderer/ccShader_3D_Particle.vert"
// #include "renderer/ccShader_3D_Particle.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_3D_PARTICLE_TEXTURE );
// kShaderType_3DSkyBox
// #include "renderer/ccShader_3D_Skybox.vert"
// #include "renderer/ccShader_3D_Skybox.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_3D_SKYBOX );
// kShaderType_3DTerrain
// #include "renderer/ccShader_3D_Terrain.vert"
// #include "renderer/ccShader_3D_Terrain.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_3D_TERRAIN );
// kShaderType_CameraClear
// #include "renderer/ccShader_CameraClear.vert"
// #include "renderer/ccShader_CameraClear.frag"
glProgramCache->getGLProgram( GLProgram::SHADER_CAMERA_CLEAR );