Cocos2d-x   发布时间:2022-05-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了在Cocos2d-x v3.x 中实现带颜色滤镜的Sprite大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

CocoaChina论坛2014-11-10 16:38:251358 次阅读

一、目的

Cocos2d-x做项目时经常会碰到要对图片进行变色的需求,最常用的就是变灰了,就要让按钮变灰来表示当前的状态是不可点的。 但是Cocos2d-x的Sprite中是没有这个变灰支持的。那么,就要我们自己动手来扩展实现一个。我们让这个带变色功能的Sprite叫做FilterSprite。这个FilterSprite扩展了Sprite的功能:可以方便地变换颜色。


二、原理

对图片进行颜色变换,就是对图片上的每个像素进行变换。要实现这个,要新创建一个fragmentShader,这个fragmentShader 比sprite的那个fragmentShader多了一个颜色变换矩阵。shader会让图片上每个像素与颜色变换矩阵进行相乘,输出新的像素值。


这个shader是这样的

1
2
3
4
5
6
7
8
9
10
11
12
#ifdefGL_ES@H_197_66@
precisionmediump@H_197_66@ float@H_197_66@ ;@H_197_66@
#endif@H_197_66@
uniformsampler2Du_texture;@H_197_66@
varyingvec2v_texCoord;@H_197_66@
varyingvec4v_fragmentColor;@H_197_66@
uniformmat4fiterMat;@H_197_66@
void@H_197_66@ @H_796_69@main(@H_197_66@ )@H_197_66@
{@H_197_66@
@H_197_66@ vec4value=v_fragmentColor*texture2D(u_texture,v_texCoord);@H_197_66@
gl_FragColor=fiterMat*value;@H_197_66@
};@H_197_66@

从shader上我们看到,“filterMat” 就是所谓的颜色变换矩阵,仅仅在原来像素输出前用它处理了一下:与待输出像素相乘。 这个shader是opengl层级的,要应用到coco2dx引擎中,我们要着手实现cocos2dx的FilterSprite类了。


三、实现

实现这个FilterSprite注意几个要点:

引擎中一个shader对应一个GLProgram,所以这个带颜色滤镜的shader(称为filterShader)对应一个GLProgram(称为filterProgram)对象,在实际使用时,是用对GLProgram进行了封装的GLProgramState(称为filterProgramState)对象,FilterSprite对象的_glProgramState要设置成filterProgramState对象,在源码中FilterSprite的initWithTexture进行这个filterShader和filterProgram的关联。

在渲染时要将滤镜传递给shader程序,在源码中就是在onDraw回调时调用:

1
glProgramState->setUniformMat4(@H_197_66@ "fiterMat"@H_197_66@ ,m_uSpriteFilter)@H_197_66@

四、使用

使用起来非常简单,只需要设置一个颜色矩阵,例如,如果要变灰就设置一个灰度矩阵,如果要恢复原貌就设置一个单位矩阵。

11
Sprite*_sprite1;@H_197_66@
_sprite1=FilterSprite::create(@H_197_66@ "Images/BACkground3.png"@H_197_66@ );@H_197_66@
GLfloatfilterMat[16]={@H_197_66@
0.3f,0.3f,0.0f,@H_197_66@
0.59f,0.59f,@H_197_66@
0.11f,0.11f,@H_197_66@
0.0f,1.0f,@H_197_66@
};@H_197_66@
dynamic_cast@H_197_66@ <FilterSprite*>(_sprite1)->setFilterMat(filterMat);@H_197_66@

五、源码

FilterSprite.h:

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
FilterSpirte.h@H_197_66@
createdbyLiaoYanXuanon14-10-21.@H_197_66@
#ifndef__FilterSpirte_h@H_197_66@
#define__FilterSpirte_h@H_197_66@
#include@H_197_66@ "cocos2d.h"@H_197_66@
USING_NS_Cc;@H_197_66@
@H_197_66@ class@H_197_66@ FilterSprite:@H_197_66@ public@H_197_66@ Sprite{@H_197_66@
:@H_197_66@
FilterSprite();@H_197_66@
virtual@H_197_66@ ~FilterSprite();@H_197_66@
static@H_197_66@ FilterSprite*create();@H_197_66@
FilterSprite*create(@H_197_66@ const@H_197_66@ std::string&fileName);@H_197_66@
std::string&filename,@H_197_66@ Rect&rect);@H_197_66@
FilterSprite*createWithTexture(Texture2D*pTexturE);@H_197_66@
FilterSprite*createWithTexture(Texture2D*pTexture,monospace!important; font-size:1em!important; min-height:inherit!important; BACkground:none!important">Rect&rect,@H_197_66@ bool@H_197_66@ rotated=@H_197_66@ false@H_197_66@ );@H_197_66@
FilterSprite*createWithSpriteFrame(SpriteFrame*pSpriteFramE);@H_197_66@
FilterSprite*createWithSpriteFramename(@H_197_66@ std::string&spriteFrameName);@H_197_66@
@H_197_66@ initWithTexture(Texture2D*pTexture,monospace!important; font-size:1em!important; min-height:inherit!important; BACkground:none!important">Rect&tRect);@H_197_66@
virtual@H_197_66@ draw(Renderer*renderer,monospace!important; font-size:1em!important; min-height:inherit!important; BACkground:none!important">Mat4&transform,uint32_tflags)override;@H_197_66@
onDraw(@H_197_66@ :1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,uint32_tflags);@H_197_66@
setFilterMat(cocos2d::Mat4matrixArray);@H_197_66@
//to-do提供一个设置滤镜的方法@H_197_66@
protected@H_197_66@ :@H_197_66@
Customcatommand_customcatommand;@H_197_66@
private@H_197_66@ :@H_197_66@
cocos2d::Mat4m_uSpriteFilter;@H_197_66@
};@H_197_66@
#endif@H_197_66@


FilterSprite.cpp:

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
@H_543_607@ 88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
@H_667_673@ 121 @H_286_675@ 122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
@H_673_737@ 153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
@H_197_66@
"FilterSprite.h"@H_197_66@
FilterSprite::FilterSprite(@H_197_66@ )@H_197_66@
{@H_197_66@
@H_644_109@m_uSpriteFilter=Mat4::IDENTITY;@H_197_66@
}@H_197_66@
FilterSprite::~FilterSprite()@H_197_66@
{@H_197_66@
}@H_197_66@
FilterSprite*FilterSprite::create()@H_197_66@
{@H_197_66@
FilterSprite*sprite=@H_197_66@ new@H_197_66@ (std::@H_197_66@ nothrow@H_197_66@ )FilterSprite();@H_197_66@
if@H_197_66@ (sprite&&sprite->init())@H_197_66@
{@H_197_66@
sprite->autorelease();@H_197_66@
return@H_197_66@ sprite;@H_197_66@
}@H_197_66@
CC_SAFE_deletE(spritE);@H_197_66@
nullptr;@H_197_66@
}@H_197_66@
FilterSprite*FilterSprite::create(@H_197_66@ std::string&fileName)@H_197_66@
{@H_197_66@
)FilterSprite();@H_197_66@
(sprite&&sprite->initWithFile(fileName))@H_197_66@
{@H_197_66@
sprite->autorelease();@H_197_66@
sprite;@H_197_66@
}@H_197_66@
CC_SAFE_deletE(spritE);@H_197_66@
nullptr;@H_197_66@
}@H_197_66@
Rect&rect)@H_197_66@
{@H_197_66@
)FilterSprite();@H_197_66@
@H_772_959@ (sprite&&sprite->initWithFile(filename,rect))@H_197_66@
{@H_197_66@
sprite->autorelease();@H_197_66@
sprite;@H_197_66@
}@H_197_66@
CC_SAFE_deletE(spritE);@H_197_66@
nullptr;@H_197_66@
}@H_197_66@
FilterSprite*FilterSprite::createWithTexture(Texture2D*pTexturE)@H_197_66@
{@H_197_66@
)FilterSprite();@H_197_66@
Rectrect=Rect::ZERO;@H_197_66@
rect.size=pTexture->getContentSize();@H_197_66@
(sprite&&sprite->initWithTexture(pTexture,rect))@H_197_66@
{@H_197_66@
sprite->autorelease();@H_197_66@
sprite;@H_197_66@
}@H_197_66@
CC_SAFE_deletE(spritE);@H_197_66@
nullptr;@H_197_66@
}@H_197_66@
FilterSprite*FilterSprite::createWithTexture(Texture2D*texture,monospace!important; font-size:1em!important; min-height:inherit!important; BACkground:none!important">rotated)@H_197_66@
{@H_197_66@
)FilterSprite();@H_197_66@
(sprite&&sprite->initWithTexture(texture,rect))@H_197_66@
{@H_197_66@
sprite->autorelease();@H_197_66@
sprite;@H_197_66@
}@H_197_66@
CC_SAFE_deletE(spritE);@H_197_66@
nullptr;@H_197_66@
}@H_197_66@
FilterSprite*FilterSprite::createWithSpriteFrame(SpriteFrame*spriteFramE)@H_197_66@
{@H_197_66@
)FilterSprite();@H_197_66@
(sprite&&spriteFrame&&sprite->initWithSpriteFrame(spriteFramE))@H_197_66@
{@H_197_66@
sprite->autorelease();@H_197_66@
sprite;@H_197_66@
}@H_197_66@
CC_SAFE_deletE(spritE);@H_197_66@
nullptr;@H_197_66@
}@H_197_66@
FilterSprite*FilterSprite::createWithSpriteFramename(@H_197_66@ std::string&spriteFrameName)@H_197_66@
{@H_197_66@
SpriteFrame*frame=SpriteFrameCache::geTinstance()->getSpriteFrameByName(spriteFrameName);@H_197_66@
#@H_197_66@ COCOS2D_DEBUG>0@H_197_66@
char@H_197_66@ @H_796_69@msg[256]={0};@H_197_66@
@H_197_66@ sprintf@H_197_66@ (msg,@H_197_66@ "InvalidspriteFramename:%s"@H_197_66@ :1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,spriteFramename.c_str());@H_197_66@
CCassERT(frame!=nullptr,msg);@H_197_66@
#endif@H_197_66@
createWithSpriteFrame(framE);@H_197_66@
}@H_197_66@
FilterSprite::initWithTexture(Texture2D*pTexture,monospace!important; font-size:1em!important; min-height:inherit!important; BACkground:none!important">Rect&tRect){@H_197_66@
do@H_197_66@ {@H_197_66@
CC_BREAK_IF(!Sprite::initWithTexture(pTexture,tRect));@H_197_66@
GLchar*pszFragsource=@H_197_66@
"#ifdefGL_ES\n\@H_197_66@
;\n\@H_197_66@
#endif\n\@H_197_66@
uniformsampler2Du_texture;\n\@H_197_66@
varyingvec2v_texCoord;\n\@H_197_66@
varyingvec4v_fragmentColor;\n\@H_197_66@
uniformmat4fiterMat;\n\@H_197_66@
)\n\@H_197_66@
{\n\@H_197_66@
:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,v_texCoord);\n\@H_197_66@
gl_FragColor=fiterMat*value;\n\@H_197_66@
}";@H_197_66@
autoglprogram=GLProgram::createWithByteArrays(ccPositiontextureColor_vert,pszFragsourcE);@H_197_66@
autoglprogramstate=GLProgramState::getOrCreateWithGLProgram(glprogram);@H_197_66@
setGLProgramState(glprogramstatE);@H_197_66@
checK_GL_ERROR_DEBUG();@H_197_66@
return@H_197_66@ true@H_197_66@ ;@H_197_66@
}@H_197_66@ while@H_197_66@ (0);@H_197_66@
@H_673_1303@ ;@H_197_66@
}@H_197_66@
FilterSprite::setFilterMat(cocos2d::Mat4matrixArray)@H_197_66@
{@H_197_66@
@H_644_109@m_uSpriteFilter=matrixArray;@H_197_66@
}@H_197_66@
FilterSprite::draw(Renderer*renderer,uint32_tflags)@H_197_66@
{@H_197_66@
_customcatommand.init(_globalZOrder);@H_197_66@
_customcatommand.func=CC_CALLBACK_0(FilterSprite::onDraw,153)!important; BACkground:none!important">this@H_197_66@ :1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,transform,flags);@H_197_66@
renderer->addCommand(&_customcatommand);@H_197_66@
}@H_197_66@
FilterSprite::onDraw(@H_197_66@ :1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,uint32_tflags)@H_197_66@
{@H_197_66@
autoglProgramState=getGLProgramState();@H_197_66@
:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,m_uSpriteFilter);@H_197_66@
glProgramState->apply(transform);@H_197_66@
GL::blendFunc(_blendFunc.src,_blendFunc.dst);@H_197_66@
GL::bindTexture2D(_texture->getName());@H_197_66@
GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);@H_197_66@
#definekQuadSize@H_197_66@ sizeof@H_197_66@ (_quad.bl)@H_197_66@
size_t@H_197_66@ offset=(@H_197_66@ )&_quad;@H_197_66@
//vertex@H_197_66@
int@H_197_66@ diff=offsetof(V3F_C4B_T2F,vertices);@H_197_66@
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION,3,GL_FLOAT,GL_falSE,kQuadSize,(@H_197_66@ *)(offset+diff));@H_197_66@
//texCoods@H_197_66@
:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,texCoords);@H_197_66@
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD,2,monospace!important; font-size:1em!important; min-height:inherit!important; BACkground:none!important">*)(offset+diff));@H_197_66@
//color@H_197_66@
:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,colors);@H_197_66@
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR,4,GL_UNSIGNED_BYTE,GL_TRUE,monospace!important; font-size:1em!important; min-height:inherit!important; BACkground:none!important">*)(offset+diff));@H_197_66@
glDrawArrays(GL_TRIANGLE_StriP,4);@H_197_66@
checK_GL_ERROR_DEBUG();@H_197_66@
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,4);@H_197_66@
}@H_197_66@


来源网址:http://www.cocoachina.com/bbs/read.php?tid-238457.html

@H_339_1489@
分享到:
赞(0)
@H_874_1495@

文章评论 (3)

  • tjunxin 2014-12-11 15:07:22
    是不是直接继承自sprite的类想用shader都要重写draw啊?
  • q312998164 2014-11-12 10:23:01
Reference to 'Rect' is ambiguous ? 这是什么错误呀
@L_944_9@ 2014-11-11 17:16:33
Node下有个setColor函数 实现的就是这种效果。拿setcolor传入参数 乘于像素的颜色 得到最终的效果

大佬总结

以上是大佬教程为你收集整理的在Cocos2d-x v3.x 中实现带颜色滤镜的Sprite全部内容,希望文章能够帮你解决在Cocos2d-x v3.x 中实现带颜色滤镜的Sprite所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签:3cocoscocos2ddspritevv3.xx实现颜色
猜你在找的Cocos2d-x相关文章
其他相关热搜词更多
phpJavaPython程序员load如何string使用参数jquery开发安装listlinuxiosandroid工具javascriptcap