Last active
August 29, 2015 14:04
-
-
Save t-takasaka/d221cb7d387456d2a975 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "HelloWorldScene.h" | |
USING_NS_CC; | |
Scene* HelloWorld::createScene(){ | |
auto scene = Scene::create(); | |
auto layer = HelloWorld::create(); | |
scene->addChild(layer); | |
return scene; | |
} | |
bool HelloWorld::init(){ | |
if(!Layer::init()){ return false; } | |
m_visibleSize = Director::getInstance()->getVisibleSize(); | |
//ブラーの幅等を計算 | |
calculateGaussianWeights(m_radius / m_step, m_weights); | |
//スプライトを作成 | |
m_sprite1 = Sprite::create("HelloWorld.png"); | |
m_textureSize = m_sprite1->getTexture()->getContentSizeInPixels(); | |
m_pixelSize = Size(float(m_step) / m_textureSize.width, float(m_step) / m_textureSize.height); | |
m_sprite1->setPosition(Point(m_textureSize.width / 2, m_textureSize.height / 2)); | |
m_sprite1->retain(); | |
// this->addChild(sprite1); | |
//シェーダをスプライトに紐付け(横方向にブラー) | |
GLProgram *shader1 = new GLProgram(); | |
m_sprite1->setShaderProgram(shader1); | |
shader1->initWithFilenames("shaders/blur.vsh", "shaders/blur.fsh"); | |
shader1->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION); | |
shader1->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS); | |
shader1->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR); | |
shader1->link(); | |
shader1->updateUniforms(); | |
shader1->setUniformLocationWith2f(shader1->getUniformLocationForName("pixelSize"), m_pixelSize.width, m_pixelSize.height); | |
shader1->setUniformLocationWith2f(shader1->getUniformLocationForName("direction"), 1.0f, 0.0f); | |
shader1->setUniformLocationWith1i(shader1->getUniformLocationForName("radius"), m_radius); | |
glUniform1fv(shader1->getUniformLocationForName("weights"), MAX_RADIUS, (GLfloat*)m_weights); | |
// this->addChild(sprite1); | |
//スプライトを作成 | |
m_sprite2 = Sprite::createWithTexture(m_sprite1->getTexture()); | |
m_sprite2->setPosition(Point(m_visibleSize.width / 2, m_visibleSize.height / 2)); | |
m_sprite2->setScale(2.0); | |
//シェーダをスプライトに紐付け(縦方向にブラー) | |
GLProgram *shader2 = new GLProgram(); | |
m_sprite2->setShaderProgram(shader2); | |
shader2->initWithFilenames("shaders/blur.vsh", "shaders/blur.fsh"); | |
shader2->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION); | |
shader2->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS); | |
shader2->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR); | |
shader2->link(); | |
shader2->updateUniforms(); | |
shader2->setUniformLocationWith2f(shader2->getUniformLocationForName("pixelSize"), m_pixelSize.width, m_pixelSize.height); | |
shader2->setUniformLocationWith2f(shader2->getUniformLocationForName("direction"), 0.0f, 1.0f); | |
shader2->setUniformLocationWith1i(shader2->getUniformLocationForName("radius"), m_radius); | |
glUniform1fv(shader2->getUniformLocationForName("weights"), MAX_RADIUS, (GLfloat*)m_weights); | |
this->addChild(m_sprite2); | |
m_texture1 = RenderTexture::create(m_textureSize.width, m_textureSize.height); | |
m_texture1->retain(); | |
this->scheduleUpdate(); | |
return true; | |
} | |
void HelloWorld::update(float delta){ | |
//ブラーの幅を再計算 | |
m_radius = ++m_radius % MAX_RADIUS; | |
calculateGaussianWeights(m_radius / m_step, m_weights); | |
//紐付け済みのシェーダを取得して、ブラーの幅を更新 | |
GLProgram *shader1 = m_sprite1->getShaderProgram(); | |
shader1->updateUniforms(); | |
shader1->setUniformLocationWith2f(shader1->getUniformLocationForName("pixelSize"), m_pixelSize.width, m_pixelSize.height); | |
shader1->setUniformLocationWith2f(shader1->getUniformLocationForName("direction"), 1.0f, 0.0f); | |
shader1->setUniformLocationWith1i(shader1->getUniformLocationForName("radius"), m_radius); | |
glUniform1fv(shader1->getUniformLocationForName("weights"), MAX_RADIUS, (GLfloat*)m_weights); | |
//スプライトをテクスチャに描画 | |
m_texture1->beginWithClear(0, 0, 0, 1); | |
m_sprite1->visit(); | |
m_texture1->end(); | |
//ブラーのかかったテクスチャを元にスプライトを作成 | |
m_sprite2->setTexture(m_texture1->getSprite()->getTexture()); | |
m_sprite2->setFlippedY(true); | |
//紐付け済みのシェーダを取得して、ブラーの幅を更新 | |
GLProgram *shader2 = m_sprite2->getShaderProgram(); | |
shader2->updateUniforms(); | |
shader2->setUniformLocationWith2f(shader2->getUniformLocationForName("pixelSize"), m_pixelSize.width, m_pixelSize.height); | |
shader2->setUniformLocationWith2f(shader2->getUniformLocationForName("direction"), 0.0f, 1.0f); | |
shader2->setUniformLocationWith1i(shader2->getUniformLocationForName("radius"), m_radius); | |
glUniform1fv(shader2->getUniformLocationForName("weights"), MAX_RADIUS, (GLfloat*)m_weights); | |
} | |
void HelloWorld::calculateGaussianWeights(const int points, float *weights){ | |
float dx = 1.0f / float(points - 1); | |
float sigma = 1.0f / 3.0f; | |
float norm = 1.0f / (sqrtf(2.0f * M_PI) * sigma * points); | |
float divsigma2 = 0.5f / (sigma * sigma); | |
weights[0] = 1.0f; | |
for(int i = 1; i < MAX_RADIUS; i++){ | |
if(i < points){ | |
float x = float(i) * dx; | |
weights[i] = norm * expf(-x * x * divsigma2); | |
weights[0] -= 2.0f * weights[i]; | |
}else{ | |
weights[i] = 0.0; | |
} | |
} | |
} | |
void HelloWorld::menuCloseCallback(Ref* pSender){ | |
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) | |
MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert"); | |
return; | |
#endif | |
Director::getInstance()->end(); | |
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) | |
exit(0); | |
#endif | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __HELLOWORLD_SCENE_H__ | |
#define __HELLOWORLD_SCENE_H__ | |
#include "cocos2d.h" | |
class HelloWorld : public cocos2d::Layer | |
{ | |
public: | |
enum{ MAX_RADIUS = 32 }; | |
HelloWorld():m_step(1), m_radius(0){} | |
~HelloWorld(){ | |
} | |
int m_step, m_radius; | |
float m_weights[MAX_RADIUS]; | |
cocos2d::Size m_visibleSize, m_textureSize, m_pixelSize; | |
cocos2d::Sprite *m_sprite1, *m_sprite2; | |
cocos2d::RenderTexture *m_texture1; | |
static cocos2d::Scene* createScene(); | |
virtual bool init(); | |
void update(float delta); | |
void calculateGaussianWeights(const int points, float *weights); | |
void menuCloseCallback(cocos2d::Ref* pSender); | |
CREATE_FUNC(HelloWorld); | |
}; | |
#endif // __HELLOWORLD_SCENE_H__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
attribute vec4 a_position; | |
attribute vec2 a_texCoord; | |
attribute vec4 a_color; | |
varying vec4 v_fragmentColor; | |
varying vec2 v_texCoord; | |
void main() { | |
gl_Position = CC_PMatrix * a_position; | |
v_fragmentColor = a_color; | |
v_texCoord = a_texCoord; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifdef GL_ES | |
precision mediump float; | |
#endif | |
varying vec2 v_texCoord; | |
uniform sampler2D u_texture; | |
uniform vec2 u_texSize; | |
uniform int u_mosaicLevel; | |
varying lowp vec4 v_fragmentColor; | |
uniform vec2 pixelSize; | |
uniform vec2 direction; | |
uniform int radius; | |
uniform float weights[32]; | |
void main() { | |
vec4 sum = texture2D(u_texture, vec2(v_texCoord.x, v_texCoord.y)) * weights[0]; | |
int MAX_RADIUS = 32; | |
for(int i = 1; i < MAX_RADIUS; i++){ | |
if(i < radius){ | |
vec2 offset = vec2(float(i) * pixelSize.x * direction.x, float(i) * pixelSize.y * direction.y); | |
sum += texture2D(u_texture, v_texCoord + offset) * weights[i]; | |
sum += texture2D(u_texture, v_texCoord - offset) * weights[i]; | |
} | |
} | |
gl_FragColor = sum * v_fragmentColor; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment