由于quick2.25没有导出shader相应的接口,所以2.25无法直接使用shader。
本文简单介绍如何导出相应接口,同时教大家使用shader 实现精灵变灰
一、编写静态函数,以供导出使用(直接参考3.2版本的)
2.25的GLProgram是对应操作shader的类。
在GLProgram.h声明以下两个函数
static CCGLProgram* createWithByteArrays(const char* vShaderByteArray, const char* fShaderByteArray);
static CCGLProgram* createWithFilenames(const char* vShaderFilename, const char* fShaderFilename);
在GLProgram.cpp添加以下两个函数
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;
}
二、编写导出使用的.tolua脚本
在quick-2.2.5-pluslibluabindingcocos2dxdraw_nodes下新建CCGLProgram.tolua,复制GLProgram.h下的public方法到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);
。。。。。。。。。。。。。。。。。。。。。
const GLuint getProgram() { return m_uProgram; }
}
在quick-2.2.5-pluslibluabindingcocos2dxCocos2d.tolua 里面添加$pfile "cocos2dx/draw_nodes/CCGLProgram.tolua"
在命令行执行quick-2.2.5-pluslibluabindinguild.bat,检查quick-2.2.5-pluslibcocos2d-xscriptingluacocos2dx_supportLuaCocos2d.cpp是否生成CCGLProgram相关绑定函数
三、开始使用shader
精灵变灰实例:
//gray.vsh 顶点shader 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; } //gray.fsh 片段shader #ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
uniform sampler2D CC_Texture0;
uniform int grayFlag; //控制变灰和恢复
void main(void)
{
vec4 c = texture2D(CC_Texture0, v_texCoord);
if (grayFlag >0)
{
float gray = dot(c.rgb,vec3(0.299,0.587,0.114));
gl_FragColor.xyz = vec3(gray,gray,gray);
}
else
{
gl_FragColor.xyz = c.rgb;
}
gl_FragColor.w = c.w;
}
使用shader:
local pProgram self.sp = display.newSprite("img_248.png"):addTo(self) self.sp:setPosition(300, 300) self:darkNode(self.sp) self.sp:setTouchEnabled(true) self.sp:addNodeEventListener(cc.NODE_TOUCH_EVENT, function(event) if event.name == "began" then if not self.dark then self.dark = true local grayFlag = pProgram:getUniformLocationForName("grayFlag"); pProgram:use() pProgram:setUniformLocationWith1i(grayFlag,1.0) --变灰 else local grayFlag = pProgram:getUniformLocationForName("grayFlag"); pProgram:use() pProgram:setUniformLocationWith1i(grayFlag,0) --恢复 self.dark = false end end end) function MainScene:darkNode(node) local pProgram = CCGLProgram:createWithFilenames("res/shader/gray.vsh","res/shader/gray.fsh") pProgram:addAttribute("a_position", 0) --对应vs里面的顶点坐标 pProgram:addAttribute("a_color", 1) --对应vs里面的顶点颜色 pProgram:addAttribute("a_texCoord", 2)--对应vs里面的顶点纹理坐标 pProgram:link() -- 因为绑定了属性,所以需要link一下,否则vs无法识别属性 pProgram:updateUniforms() -- 绑定了纹理贴图 node:setShaderProgram(pProgram) end
效果: