摘要 cocos2d-x 2.2.1 中没有直接用于模糊精灵的类,但是在TestCpp里面的ShaderTest实现了高斯模糊。于是直接搬过来用就行了。
你可以从下面的目录找到示例的源代码:
cocos2d-x-2.2.1\samples\Cpp\TestCpp\Classes\ShaderTest
SpriteBlur类用于实现高斯模糊,但并没有定义在ShaderTest.h中,打开ShaderTest.cpp,大概在488行有这个类的定义和实现:
<code>01</code>
<code>// ShaderBlur</code>
<code>02</code>
<code>03</code>
<code>class</code> <code>SpriteBlur : </code><code>public</code> <code>CCSprite</code>
<code>04</code>
<code>{</code>
<code>05</code>
<code>public</code><code>:</code>
<code>06</code>
<code> </code><code>~SpriteBlur();</code>
<code>07</code>
<code> </code><code>void</code> <code>setBlurSize(</code><code>float</code> <code>f);</code>
<code>08</code>
<code> </code><code>bool</code> <code>initWithTexture(CCTexture2D* texture, </code><code>const</code> <code>CCRect& rect);</code>
<code>09</code>
<code> </code><code>void</code> <code>draw();</code>
<code>10</code>
<code> </code><code>void</code> <code>initProgram();</code>
<code>11</code>
<code> </code><code>void</code> <code>listenBackToForeground(CCObject *obj);</code>
<code>12</code>
<code>13</code>
<code> </code><code>static</code> <code>SpriteBlur* create(</code><code>const</code> <code>char</code> <code>*pszFileName);</code>
<code>14</code>
<code>15</code>
<code> </code><code>CCPoint blur_;</code>
<code>16</code>
<code> </code><code>GLfloat sub_[4];</code>
<code>17</code>
<code>18</code>
<code> </code><code>GLuint blurLocation;</code>
<code>19</code>
<code> </code><code>GLuint subLocation;</code>
<code>20</code>
<code>};</code>
实现:
<code>001</code>
<code>SpriteBlur::~SpriteBlur()</code>
<code>002</code>
<code>003</code>
<code> </code><code>CCNotificationCenter::sharedNotificationCenter()->removeObserver(</code><code>this</code><code>, EVENT_COME_TO_FOREGROUND);</code>
<code>004</code>
<code>}</code>
<code>005</code>
<code>006</code>
<code>SpriteBlur* SpriteBlur::create(</code><code>const</code> <code>char</code> <code>*pszFileName)</code>
<code>007</code>
<code>008</code>
<code> </code><code>SpriteBlur* pRet = </code><code>new</code> <code>SpriteBlur();</code>
<code>009</code>
<code> </code><code>if</code> <code>(pRet && pRet->initWithFile(pszFileName))</code>
<code>010</code>
<code> </code><code>{</code>
<code>011</code>
<code> </code><code>pRet->autorelease();</code>
<code>012</code>
<code> </code><code>}</code>
<code>013</code>
<code> </code><code>else</code>
<code>014</code>
<code>015</code>
<code> </code><code>CC_SAFE_DELETE(pRet);</code>
<code>016</code>
<code>017</code>
<code> </code>
<code>018</code>
<code> </code><code>return</code> <code>pRet;</code>
<code>019</code>
<code>020</code>
<code>021</code>
<code>void</code> <code>SpriteBlur::listenBackToForeground(CCObject *obj)</code>
<code>022</code>
<code>023</code>
<code> </code><code>setShaderProgram(NULL);</code>
<code>024</code>
<code> </code><code>initProgram();</code>
<code>025</code>
<code>026</code>
<code>027</code>
<code>bool</code> <code>SpriteBlur::initWithTexture(CCTexture2D* texture, </code><code>const</code> <code>CCRect& rect)</code>
<code>028</code>
<code>029</code>
<code> </code><code>if</code><code>( CCSprite::initWithTexture(texture, rect) ) </code>
<code>030</code>
<code>031</code>
<code> </code><code>CCNotificationCenter::sharedNotificationCenter()->addObserver(</code><code>this</code><code>,</code>
<code>032</code>
<code> </code><code>callfuncO_selector(SpriteBlur::listenBackToForeground),</code>
<code>033</code>
<code> </code><code>EVENT_COME_TO_FOREGROUND,</code>
<code>034</code>
<code> </code><code>NULL);</code>
<code>035</code>
<code> </code>
<code>036</code>
<code> </code><code>CCSize s = getTexture()->getContentSizeInPixels();</code>
<code>037</code>
<code>038</code>
<code> </code><code>blur_ = ccp(1/s.width, 1/s.height);</code>
<code>039</code>
<code> </code><code>sub_[0] = sub_[1] = sub_[2] = sub_[3] = 0;</code>
<code>040</code>
<code>041</code>
<code> </code><code>this</code><code>->initProgram();</code>
<code>042</code>
<code>043</code>
<code> </code><code>return</code> <code>true</code><code>;</code>
<code>044</code>
<code>045</code>
<code>046</code>
<code> </code><code>return</code> <code>false</code><code>;</code>
<code>047</code>
<code>048</code>
<code>049</code>
<code>void</code> <code>SpriteBlur::initProgram()</code>
<code>050</code>
<code>051</code>
<code> </code><code>GLchar * fragSource = (GLchar*) CCString::createWithContentsOfFile(</code>
<code>052</code>
<code> </code><code>CCFileUtils::sharedFileUtils()->fullPathForFilename(</code><code>"Shaders/example_Blur.fsh"</code><code>).c_str())->getCString();</code>
<code>053</code>
<code> </code><code>CCGLProgram* pProgram = </code><code>new</code> <code>CCGLProgram();</code>
<code>054</code>
<code> </code><code>pProgram->initWithVertexShaderByteArray(ccPositionTextureColor_vert, fragSource);</code>
<code>055</code>
<code> </code><code>setShaderProgram(pProgram);</code>
<code>056</code>
<code> </code><code>pProgram->release();</code>
<code>057</code>
<code>058</code>
<code> </code><code>CHECK_GL_ERROR_DEBUG();</code>
<code>059</code>
<code>060</code>
<code> </code><code>getShaderProgram()->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);</code>
<code>061</code>
<code> </code><code>getShaderProgram()->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);</code>
<code>062</code>
<code> </code><code>getShaderProgram()->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);</code>
<code>063</code>
<code>064</code>
<code>065</code>
<code>066</code>
<code> </code><code>getShaderProgram()->link();</code>
<code>067</code>
<code>068</code>
<code>069</code>
<code>070</code>
<code> </code><code>getShaderProgram()->updateUniforms();</code>
<code>071</code>
<code>072</code>
<code>073</code>
<code>074</code>
<code> </code><code>subLocation = glGetUniformLocation( getShaderProgram()->getProgram(), </code><code>"substract"</code><code>);</code>
<code>075</code>
<code> </code><code>blurLocation = glGetUniformLocation( getShaderProgram()->getProgram(), </code><code>"blurSize"</code><code>);</code>
<code>076</code>
<code>077</code>
<code>078</code>
<code>079</code>
<code>080</code>
<code>void</code> <code>SpriteBlur::draw()</code>
<code>081</code>
<code>082</code>
<code> </code><code>ccGLEnableVertexAttribs(kCCVertexAttribFlag_PosColorTex );</code>
<code>083</code>
<code> </code><code>ccBlendFunc blend = getBlendFunc();</code>
<code>084</code>
<code> </code><code>ccGLBlendFunc(blend.src, blend.dst);</code>
<code>085</code>
<code>086</code>
<code> </code><code>getShaderProgram()->use();</code>
<code>087</code>
<code> </code><code>getShaderProgram()->setUniformsForBuiltins();</code>
<code>088</code>
<code> </code><code>getShaderProgram()->setUniformLocationWith2f(blurLocation, blur_.x, blur_.y);</code>
<code>089</code>
<code> </code><code>getShaderProgram()->setUniformLocationWith4fv(subLocation, sub_, 1);</code>
<code>090</code>
<code>091</code>
<code> </code><code>ccGLBindTexture2D( getTexture()->getName());</code>
<code>092</code>
<code>093</code>
<code> </code><code>//</code>
<code>094</code>
<code> </code><code>// Attributes</code>
<code>095</code>
<code>096</code>
<code>#define kQuadSize sizeof(m_sQuad.bl)</code>
<code>097</code>
<code> </code><code>long</code> <code>offset = (</code><code>long</code><code>)&m_sQuad;</code>
<code>098</code>
<code>099</code>
<code> </code><code>// vertex</code>
<code>100</code>
<code> </code><code>int</code> <code>diff = offsetof( ccV3F_C4B_T2F, vertices);</code>
<code>101</code>
<code> </code><code>glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (</code><code>void</code><code>*) (offset + diff));</code>
<code>102</code>
<code>103</code>
<code> </code><code>// texCoods</code>
<code>104</code>
<code> </code><code>diff = offsetof( ccV3F_C4B_T2F, texCoords);</code>
<code>105</code>
<code> </code><code>glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (</code><code>void</code><code>*)(offset + diff));</code>
<code>106</code>
<code>107</code>
<code> </code><code>// color</code>
<code>108</code>
<code> </code><code>diff = offsetof( ccV3F_C4B_T2F, colors);</code>
<code>109</code>
<code> </code><code>glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (</code><code>void</code><code>*)(offset + diff));</code>
<code>110</code>
<code>111</code>
<code>112</code>
<code> </code><code>glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);</code>
<code>113</code>
<code>114</code>
<code> </code><code>CC_INCREMENT_GL_DRAWS(1);</code>
<code>115</code>
<code>116</code>
<code>117</code>
<code>void</code> <code>SpriteBlur::setBlurSize(</code><code>float</code> <code>f)</code>
<code>118</code>
<code>119</code>
<code> </code><code>CCSize s = getTexture()->getContentSizeInPixels();</code>
<code>120</code>
<code>121</code>
<code> </code><code>blur_ = ccp(1/s.width, 1/s.height);</code>
<code>122</code>
<code> </code><code>blur_ = ccpMult(blur_,f);</code>
<code>123</code>
好了,直接copy到你的program里面,不过有一点需要注意,就是他这个只能用一个文件(图片)create,如果需要用一个Texture初始化(因为有时候需要模糊即时的sprite),可以稍微改装一下,加一个函数:
<code>1</code>
<code>static</code> <code>SpriteBlur* createWithTexture(CCTexture2D *pTexture);</code>
<code>SpriteBlur* SpriteBlur::createWithTexture(CCTexture2D *pTexture)</code>
<code> </code><code>CCAssert(pTexture != NULL, </code><code>"Invalid texture for sprite"</code><code>);</code>
<code> </code><code>CCRect rect = CCRectZero;</code>
<code> </code><code>rect.size = pTexture->getContentSize();</code>
<code> </code><code>if</code> <code>(pRet && pRet->initWithTexture(pTexture,rect))</code>
用法:
<code>SpriteBlur *bluredSpr = SpriteBlur::createWithTexture(tex);</code>
<code>2</code>
<code>bluredSpr->setPosition(ccp(sz.width/2,sz.height/2));</code>
<code>3</code>
<code>bluredSpr->setBlurSize(0.9f); </code><code>// 这里稍微设小一点</code>
<code>4</code>
<code>addChild(bluredSpr);</code>
效果:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5CM0kDM4UzXX90aN91M0IDNyIzLcJTMxAzLcRTMwIzLcV2YhB3cvw1ckF2bsBXdvwFdl5mLh5WaoN2cv5yYpRXY0N3Lc9CX6MHc0RHaiojIsJye.png)
注意:
他需要一个fsh文件(具体看它的实现),似乎是叠texture用的,找到example_Blur.fsh放到你的Resources\Shaders目录下
本文转蓬莱仙羽51CTO博客,原文链接:http://blog.51cto.com/dingxiaowei/1366154,如需转载请自行联系原作者