グレンジ Advent Calendar 2017 初日担当の mad_khaki です。
クライアントサイドを中心にサーバ / データ分析 等もやってます。
今回は cocos2d-x v3.2 でシェーダを追加する手順についてまとめました。
1. GLSLで頂点シェーダ書く
ccShader_GrayScale.vert
const char* ccGrayScale_vert = STRINGIFY(
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
\n#ifdef GL_ES\n
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
\n#else\n
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
\n#endif\n
void main()
{
gl_Position = CC_PMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}
);
STRINGIFYマクロで文字列化しておく
ccShader_PositionTextureColor_noMVP.vertをそのまま使ってもよい
2. GLSLでフラグメントシェーダ書く
ccShader_GrayScale.frag
const char* ccGrayScale_frag = STRINGIFY(
\n#ifdef GL_ES\n
precision lowp float;
\n#endif\n
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
void main()
{
vec4 color = texture2D(CC_Texture0, v_texCoord);
float alpha = color.a;
float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
gl_FragColor = vec4(gray, gray, gray, alpha);
}
);
STRINGIFYマクロで文字列化しておく
https://ja.wikipedia.org/wiki/%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%AB
係数はWikipediaから適当に引っ張ってきた
3. ccShadersに定義を追加する
ccShaders.h
extern CC_DLL const GLchar * ccGrayScale_vert;
extern CC_DLL const GLchar * ccGrayScale_frag;
ccShaders.cpp
#include "ccShader_GrayScale.vert"
#include "ccShader_GrayScale.frag"
4. GLProgramクラスのstaticメンバに追加する
CCGLProgram.h
static const char* SHADER_GRAYSCALE;
CCGLProgram.cpp
const char* GLProgram::SHADER_GRAYSCALE = "ShaderGrayScale";
5. シェーダキャッシュに追加する
enumに追加
CCGLProgramCache.cpp
kShaderType_GrayScale
loadDefaultGLPrograms()に追加
3項で追加した文字列とシェーダの実体(GLProgram)の対応関係をマップで管理
CCGLProgramCache.cpp
GLProgram* p = new GLProgram();
loadDefaultGLProgram(p, kShaderType_GrayScale);
_programs.insert(std::make_pair(GLProgram::SHADER_GRAYSCALE, p));
loadDefaultGLProgram(GLProgram *p, int type)に追加
ここで1項、2項で文字列化されたシェーダがコンパイルされる
CCGLProgramCache.cpp
case kShaderType_GrayScale:
p->initWithByteArrays(ccGrayScale_vert, ccGrayScale_frag);
break;
reloadDefaultGLPrograms()に追加
CCGLProgramCache.cpp
p = getGLProgram(GLProgram::SHADER_GRAYSCALE);
p->reset();
loadDefaultGLProgram(p, kShaderType_GrayScale);
6. 実際にシェーダを設定する
CCSprite.cpp
setGLProgramState(GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_GRAYSCALE));