cocos构建了一个GLProgram的缓存,毕竟create GL program是一件消耗比较大的工作,且经常存在这种情况:两个绘制工作的shader逻辑一样,只是attribute、uniform的值不同,完全可以直接更新这些变量的值而避免再新建一个Program。
一、数据结构
class CC_DLL GLProgramCache : public Ref{// GLProgram的缓存。// key: 自定义的string,用于唯一辨识。// value: GLProgram objectstd::unordered_map<std::string, GLProgram*> _programs;};
class CC_DLL GLProgramCache : public Ref{public:void loadDefaultGLPrograms(); // 加载所有内置的shadervoid reloadDefaultGLPrograms(); // 重载所有内置的shadervoid 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 );
