在cocos2d-x中有兩個類CCGLProgram和CCShaderCache.CCGLProgram類來處理著色器相干操作,對當前繪圖程序進行了封裝.CCShaderCache通過CCGLProgram來完成對shaders的緩存和管理.這兩個類的功能在項目中常常用到,比照實現(xiàn)圖像由正常色彩變成灰色(好處是減少資源圖),還有在刀塔傳奇中用令人物冰封,石化等效果都是用shader.
這里對這兩個類的功能不作深入討論,由于本人也是剛剛接觸,這里主要是介紹在Quick-cocos2dx-lua -v2.2.6版本中如何配置和使用這個功能。
由于Quick-cocos2dx-lua -v2.2.6版本中沒有在tolua中導出CCGLProgram,所以lua中不能使用。
接下來就是生成可使用CCGLProgram的framework和player
第1:找到CCGLProgram.h和CCGLProgram.cpp,:
在CCGLProgram.h中聲明以下兩個函數:
static CCGLProgram* createWithByteArrays(const char* vShaderByteArray, const char* fShaderByteArray);
static CCGLProgram* createWithFilenames(const char* vShaderFilename, const char* fShaderFilename);
在CCGLProgram.cpp實現(xiàn)這兩個方法(這兩個方法可以參考v3.5):
CCGLProgram* CCGLProgram::createWithByteArrays(const char* vShaderByteArray, const char* fShaderByteArray)
{
CCGLProgram* ret = new CCGLProgram();
if(ret && ret->initWithVertexShaderByteArray(vShaderByteArray, fShaderByteArray)) {
ret->autorelease();
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}
CCGLProgram* CCGLProgram::createWithFilenames(const char* vShaderFilename, const char* fShaderFilename)
{
auto ret = new CCGLProgram();
if(ret && ret->initWithVertexShaderFilename(vShaderFilename, fShaderFilename)) {
ret->autorelease();
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}
注掉:CCGLProgram構造方法中兩行:
// there is no need to delete the shaders. They should have been already deleted.
//CCAssert(m_uVertShader == 0, "Vertex Shaders should have been already deleted");
//CCAssert(m_uFragShader == 0, "Fragment Shaders should have been already deleted");
第2:修改framework
進入libluabindingcocos2dxdraw_nodes,新建文件CCGLProgram.tolua,內容以下:
class CCGLProgram : public CCObject
{
static CCGLProgram* createWithByteArrays(const char* vShaderByteArray, const char* fShaderByteArray);
static CCGLProgram* createWithFilenames(const char* vShaderFilename, const char* fShaderFilename);
void addAttribute(const char* attributeName, GLuint index);
bool link();
void use();
void updateUniforms();
}
注:這里是導出你所需要的公共方法,供在lua中調用。
修改:libluabindingcocos2dxCocos2d.tolua,
增加 $pfile "cocos2dx/draw_nodes/CCGLProgram.tolua"
接下履行tolua指令,由quick cocos framework提供:
履行:libluabindinguild.bat,和incompile_luabinding.bat
履行完命令后檢查tolua綁定:
libcocos2d-xscriptingluacocos2dx_supportLuaCocos2d.cpp是不是生成CCGLProgram相干綁定函數
生成:framework_precompiled.zip
履行bat:binmake_framework_package.bat會重生生成framework_precompiled.zip
第3:生新編譯生成player.exe
由于修改了cpp(LuaCocos2d.cpp,CCGLProgram.cpp),需要重新編譯player.
用vs2013直接打開playerproj.win32player.vcxproj編譯就能夠了。
第4:簡單利用shader:
local pProgram = CCGLProgram:createWithFilenames("res/shader/IceShader.vsh","res/shader/IceShader.fsh")
self.sp = display.newSprite("house.png"):addTo(self)
self.sp:setPosition(300, 100)
pProgram:addAttribute("a_position", 0) --對應vs里面的頂點坐標
pProgram:addAttribute("a_color", 1) --對應vs里面的頂點色彩
pProgram:addAttribute("a_texCoord", 2)--對應vs里面的頂點紋理坐標
pProgram:link() -- 由于綁定了屬性,所以需要link1下,否則vs沒法辨認屬性
pProgram:updateUniforms() -- 綁定了紋理貼圖
self.sp:setShaderProgram(pProgram)
注:
IceShader.fsh內容:
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
uniform sampler2D u_texture;
void main()
{
vec4 color1 = texture2D(u_texture, v_texCoord) * v_fragmentColor;
float brightness = (color1.r + color1.g + color1.b) * (1. / 3.);
float gray = (1.5)*brightness;
color1 = vec4(gray, gray, gray, color1.a)*vec4(0.8,1.2,1.5,1);
gl_FragColor =color1;
}
IceShader.vsh文件內容:
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
void main()
{
gl_Position = CC_MVPMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}
程序運行結果: