Skip to content

Instantly share code, notes, and snippets.

@t-takasaka
Last active August 29, 2015 14:05
Show Gist options
  • Save t-takasaka/600a0725e3fe2867eb48 to your computer and use it in GitHub Desktop.
Save t-takasaka/600a0725e3fe2867eb48 to your computer and use it in GitHub Desktop.
//↓参考元
//https://github.com/Quasimondo/QuasimondoJS
//Released under the MIT license
//http://opensource.org/licenses/mit-license.php
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
class HelloWorld : public cocos2d::Layer
{
public:
enum{ MAX_RADIUS = 32 };
HelloWorld(){}
~HelloWorld(){}
int m_rad, m_iterations;
int m_kernel[(MAX_RADIUS + MAX_RADIUS + 1) * 256];
struct STACK{
unsigned char r, g, b, a;
STACK *next;
} m_stacks[MAX_RADIUS + MAX_RADIUS + 1];
cocos2d::Size m_visibleSize, m_texSizeSrc;
cocos2d::Sprite *m_spriteSrc, *m_spriteDest;
cocos2d::RenderTexture *m_texture1, *m_texture2, *m_texture3;
static cocos2d::Scene* createScene();
virtual bool init();
void update(float delta);
bool initBlur(int rad, int sigma);
void Horizontal(cocos2d::Color4B *pixels, int width, int height);
void Vertical(cocos2d::Color4B *pixels, int width, int height);
void menuCloseCallback(cocos2d::Ref* pSender);
CREATE_FUNC(HelloWorld);
};
#endif // __HELLOWORLD_SCENE_H__
#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();
//スプライトを作成
m_spriteSrc = Sprite::create("HelloWorld512b.png");
m_texSizeSrc = m_spriteSrc->getTexture()->getContentSizeInPixels();
m_spriteSrc->setPosition(m_texSizeSrc / 2);
m_spriteSrc->retain();
// this->addChild(m_spriteSrc);
m_texture1 = RenderTexture::create(m_texSizeSrc.width, m_texSizeSrc.height);
m_texture1->setPosition(m_visibleSize / 2);
m_texture1->retain();
m_spriteDest = Sprite::create();
m_spriteDest->setVertexRect(Rect(0, 0, m_texSizeSrc.width, m_texSizeSrc.height));
m_spriteDest->setPosition(m_visibleSize / 2);
m_spriteDest->setScale(2.0);
m_spriteDest->retain();
this->addChild(m_spriteDest);
this->scheduleUpdate();
return true;
}
void HelloWorld::update(float delta){
timeval tv;
gettimeofday(&tv, nullptr);
long now = tv.tv_sec * 1000 + tv.tv_usec / 1000;
now = abs((abs(now) % 10000) - 5000);
m_texture1->beginWithClear(0, 0, 0, 1);
m_spriteSrc->visit();
m_texture1->end();
Size texSize = m_spriteSrc->getContentSize();
int wh = m_texSizeSrc.width * m_texSizeSrc.height;
Image *image = m_texture1->newImage(false);
Color4B *pixel = (Color4B*)image->getData();
initBlur(now * ((float)MAX_RADIUS / 5000), 200000);
Horizontal(pixel, m_texSizeSrc.width, m_texSizeSrc.height);
Vertical(pixel, m_texSizeSrc.width, m_texSizeSrc.height);
Texture2D *t2d = new Texture2D();
t2d->initWithData(pixel, sizeof(pixel) * texSize.width * texSize.height, Texture2D::PixelFormat::RGBA8888, texSize.width, texSize.height, texSize);
t2d->initWithImage(image);
m_spriteDest->setTexture(t2d);
m_spriteDest->setFlipY(true);
t2d->release();
image->release();
}
bool HelloWorld::initBlur(int rad, int sigma){
m_rad = rad;
if(m_rad > MAX_RADIUS){ m_rad = MAX_RADIUS; }
memset(m_kernel, 255, sizeof(m_kernel));
double _sigma = sigma * sigma;
double _exp[(MAX_RADIUS + MAX_RADIUS + 1) * 256] = { 0.0 };
double _max = 0.0, _min = 1.0;
int gaussWidth = m_rad + m_rad + 1;
for(int i = 0; i < 256 * gaussWidth; i++){
_exp[i] = exp(-((i * i) + (i * i)) / (2 * _sigma));
_max = std::max(_max, _exp[i]);
_min = std::min(_min, _exp[i]);
}
double nomalize = 255.0 / (_max - _min);
int max = 256 * gaussWidth - 1;
for(int i = 0; i <= max; i++){
m_kernel[max - i] = (int)((_exp[i] - _min) * nomalize);
}
STACK *pstack = &m_stacks[0];
for(int i = 1; i < gaussWidth; i++){
pstack->next = &m_stacks[i];
pstack = pstack->next;
}
pstack->next = &m_stacks[0];
return true;
}
void HelloWorld::Horizontal(Color4B *pixels, int width, int height){
int rad = m_rad;
int *kernel = m_kernel;
STACK *stacks = m_stacks;
int yw = 0, yi = 0;
for(int y = 0; y < height; y++){
Color4B pixel = pixels[yi];
int rsum = (rad + 1) * pixel.r;
int gsum = (rad + 1) * pixel.g;
int bsum = (rad + 1) * pixel.b;
int asum = (rad + 1) * pixel.a;
STACK *pstack = stacks;
for(int i = 0; i <= rad; i++){
pstack->r = pixel.r;
pstack->g = pixel.g;
pstack->b = pixel.b;
pstack->a = pixel.a;
pstack = pstack->next;
}
for(int i = 1; i <= rad; i++){
int p = yi + (width - 1 < i ? width - 1 : i);
Color4B pixel = pixels[p];
rsum += pstack->r = pixel.r;
gsum += pstack->g = pixel.g;
bsum += pstack->b = pixel.b;
asum += pstack->a = pixel.a;
pstack = pstack->next;
}
STACK *stackIn = stacks;
for(int x = 0; x < width; x++){
pixels[yi++] = Color4B(kernel[rsum], kernel[gsum], kernel[bsum], kernel[asum]);
int p = x + rad + 1;
p = yw + ((p < width - 1) ? p : width - 1);
Color4B pixel = pixels[p];
rsum -= stackIn->r - pixel.r;
gsum -= stackIn->g - pixel.g;
bsum -= stackIn->b - pixel.b;
asum -= stackIn->a - pixel.a;
stackIn->r = pixel.r;
stackIn->g = pixel.g;
stackIn->b = pixel.b;
stackIn->a = pixel.a;
stackIn = stackIn->next;
}
yw += width;
}
}
void HelloWorld::Vertical(Color4B *pixels, int width, int height){
int rad = m_rad;
int *kernel = m_kernel;
STACK *stacks = m_stacks;
int yw = 0, yi = 0;
for(int x = 0; x < width; x++){
yi = x;
Color4B pixel = pixels[yi];
int rsum = (rad + 1) * pixel.r;
int gsum = (rad + 1) * pixel.g;
int bsum = (rad + 1) * pixel.b;
int asum = (rad + 1) * pixel.a;
STACK *pstack = stacks;
for(int i = 0; i <= rad; i++){
pstack->r = pixel.r;
pstack->g = pixel.g;
pstack->b = pixel.b;
pstack->a = pixel.a;
pstack = pstack->next;
}
int yp = width;
for(int i = 1; i <= rad; i++){
yi = yp + x;
Color4B pixel = pixels[yi];
rsum += pstack->r = pixel.r;
gsum += pstack->g = pixel.g;
bsum += pstack->b = pixel.b;
asum += pstack->a = pixel.a;
pstack = pstack->next;
if(i < height - 1){ yp += width; }
}
yi = x;
STACK *stackIn = stacks;
for(int y = 0; y < height; y++){
int p = yi;
pixels[p] = Color4B(kernel[rsum], kernel[gsum], kernel[bsum], kernel[asum]);
p = y + rad + 1;
p = x + (((p < height - 1) ? p : height - 1) * width);
Color4B pixel = pixels[p];
rsum -= stackIn->r - pixel.r;
gsum -= stackIn->g - pixel.g;
bsum -= stackIn->b - pixel.b;
asum -= stackIn->a - pixel.a;
stackIn->r = pixel.r;
stackIn->g = pixel.g;
stackIn->b = pixel.b;
stackIn->a = pixel.a;
stackIn = stackIn->next;
yi += width;
}
}
}
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
}
//Director::getInstance()->getRenderer()->render();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment