cocos2dx图片变灰
2015年02月12日 11:19
0 点赞
0 评论
更新于 2025-11-21 16:17
在cocos2dx中,实现图片变灰可以采用shader来完成,主要有以下两种方法:
- 像
CCSprite一样使用create方法创建变灰的图片。 - 传入
CCSprite对象,并传入一个用于标识图片是否变灰的标志位。具体实现可参考后续的代码及使用方法。
代码实现
GraySprite.h
//
// GraySprite.h
// goddess
//
// Created by rekoo on 13-7-23.
//
#ifndef __goddess__GraySprite__
#define __goddess__GraySprite__
#include "cocos2d.h"
#include "cocos-ext.h"
USING_NS_CC;
USING_NS_CC_EXT;
class GraySprite : public CCSprite {
public:
GraySprite();
~GraySprite();
bool initWithTexture(CCTexture2D* texture, const CCRect& rect);
void draw();
void initProgram();
void listenBackToForeground(CCObject *obj);
static GraySprite* create(const char* pszFileName);
};
#endif /* defined(__goddess__GraySprite__) */
GraySprite.cpp
//
// GraySprite.cpp
// goddess
//
// Created by rekoo on 13-7-23.
//
// 用shader创建灰度图, 用法跟sprite一样
// lua用法: local sprite = GraySprite:create("pic.png")
#include "GraySprite.h"
GraySprite::GraySprite() {}
GraySprite::~GraySprite() {}
GraySprite* GraySprite::create(const char* pszFileName) {
GraySprite* pRet = new GraySprite();
if (pRet && pRet->initWithFile(pszFileName)) {
pRet->autorelease();
} else {
CC_SAFE_DELETE(pRet);
}
return pRet;
}
void GraySprite::listenBackToForeground(CCObject *obj) {
setShaderProgram(NULL);
initProgram();
}
bool GraySprite::initWithTexture(CCTexture2D* texture, const CCRect& rect) {
if (CCSprite::initWithTexture(texture, rect)) {
CCSize s = getTexture()->getContentSizeInPixels();
this->initProgram();
return true;
}
return false;
}
void GraySprite::initProgram() {
const GLchar * pfrag = "#ifdef GL_ES \n"
" precision mediump float; \n"
" #endif \n"
" uniform sampler2D u_texture; \n"
" varying vec2 v_texCoord; \n"
" varying vec4 v_fragmentColor; \n"
" void main(void) \n"
" { \n"
" float alpha = texture2D(u_texture, v_texCoord).a; \n"
" float grey = dot(texture2D(u_texture, v_texCoord).rgb, vec3(0.299, 0.587, 0.114)); \n"
" gl_FragColor = vec4(grey, grey, grey, alpha); \n"
" } ";
CCGLProgram* pProgram = new CCGLProgram();
pProgram->initWithVertexShaderByteArray(ccPositionTextureColor_vert, pfrag);
setShaderProgram(pProgram);
pProgram->release();
CHECK_GL_ERROR_DEBUG();
getShaderProgram()->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
getShaderProgram()->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);
getShaderProgram()->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);
CHECK_GL_ERROR_DEBUG();
getShaderProgram()->link();
CHECK_GL_ERROR_DEBUG();
getShaderProgram()->updateUniforms();
}
void GraySprite::draw() {
ccGLEnableVertexAttribs(kCCVertexAttribFlag_PosColorTex);
ccBlendFunc blend = getBlendFunc();
ccGLBlendFunc(blend.src, blend.dst);
getShaderProgram()->use();
getShaderProgram()->setUniformsForBuiltins();
ccGLBindTexture2D(getTexture()->getName());
#define kQuadSize sizeof(m_sQuad.bl)
long offset = (long)&m_sQuad;
// vertex
int diff = offsetof(ccV3F_C4B_T2F, vertices);
glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff));
// texCoods
diff = offsetof(ccV3F_C4B_T2F, texCoords);
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff));
// color
diff = offsetof(ccV3F_C4B_T2F, colors);
glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff));
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
CC_INCREMENT_GL_DRAWS(1);
}
使用例子
方法一:使用create方法创建
GraySprite * gs = GraySprite::create("01.png");
// 后续操作与CCSprite相同,如设置位置、添加子节点等
gs->setPosition(ccp(100, 100));
addChild(gs);
方法二:传入CCSprite对象并设置变灰标志
CCSprite * cs = CCSprite::create("02.png");
// 变灰
GraySprite::setGray(cs, 1);
// 恢复原色
GraySprite::setGray(cs, 0);
Lua调用
将GraySprite暴露给Lua后,Lua代码中可以方便地调用,示例如下:
local sprite = GraySprite:create("pic.png")
通过以上方法,我们可以在cocos2dx中轻松实现图片变灰的效果。