Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl (Cocos2d-x)有任何动作可以模糊精灵吗?_Opengl_Textures_Cocos2d X - Fatal编程技术网

Opengl (Cocos2d-x)有任何动作可以模糊精灵吗?

Opengl (Cocos2d-x)有任何动作可以模糊精灵吗?,opengl,textures,cocos2d-x,Opengl,Textures,Cocos2d X,我添加了一个精灵作为背景。 现在我希望我的精灵能逐渐变得模糊 我想我可以修改Texture2D来完成这项工作,但似乎Texture2D无法修改 那么,我该怎么办呢?您有三个选择: 1) 在photoshop中制作模糊背景(快速简单,但尺寸较大) 2) 使用着色器(不是那么简单,模糊是一项繁重的操作) 3) 重新绘制(动态)背景,使其成为新纹理。 以下是我的帖子:如何绘制纹理: 了解这一点,我的项目中有一个函数,它将一个图像(数据数组)模糊到另一个图像: void Sample::blur(un

我添加了一个精灵作为背景。 现在我希望我的精灵能逐渐变得模糊

我想我可以修改Texture2D来完成这项工作,但似乎Texture2D无法修改


那么,我该怎么办呢?

您有三个选择:

1) 在photoshop中制作模糊背景(快速简单,但尺寸较大)

2) 使用着色器(不是那么简单,模糊是一项繁重的操作)

3) 重新绘制(动态)背景,使其成为新纹理。 以下是我的帖子:如何绘制纹理:

了解这一点,我的项目中有一个函数,它将一个图像(数据数组)模糊到另一个图像:

void Sample::blur(unsigned char* inputData, unsigned char* outputData, float r) {
    int R2 = pow(r + 2, 2);
    for(int i = 0; i < canvasHeight; i++){
        for(int j = 0; j < canvasWidth; j++) {
            int val1 = 0;
            int val2 = 0;
            int val3 = 0;
            int val4 = 0;

            int index2 = (j + (canvasHeight - i - 1) * canvasWidth) * 4;

            for(int iy = i - r; iy < i + r + 1; iy++){
                for(int ix = j - r; ix < j + r + 1; ix++) {

                    int x = CLAMP(ix, 0, canvasWidth - 1);
                    int y = CLAMP(iy, 0, canvasHeight - 1);

                    int index = (x + (canvasHeight - y - 1) * canvasWidth) * 4;

                    val1 += inputData[index];
                    val2 += inputData[index + 1];
                    val3 += inputData[index + 2];
                    val4 += inputData[index + 3];
                }
            }

            outputData[index2] = val1 / R2;
            outputData[index2 + 1] = val2 / R2;
            outputData[index2 + 2] = val3 / R2;
            outputData[index2 + 3] = val4 / R2;
        }
    }
}
void Sample::blur(无符号字符*inputData,无符号字符*outputData,浮点r){
int R2=功率(r+2,2);
for(int i=0;i

请记住,模糊是一个繁重而漫长的操作,所以如果你有一个大图像,它可能需要一段时间。

你可以使用着色器。您可以从cocos测试项目获得简单的模糊着色器,如下所示:

#ifdef GL_ES
precision mediump float;
#endif

varying vec4 v_fragmentColor;
varying vec2 v_texCoord;

uniform vec2 resolution;
uniform float blurRadius;
uniform float sampleNum;

vec4 blur(vec2);

void main(void)
{
vec4 col = blur(v_texCoord); //* v_fragmentColor.rgb;
gl_FragColor = vec4(col) * v_fragmentColor;
}

vec4 blur(vec2 p)
{
    if (blurRadius > 0.0 && sampleNum > 1.0)
    {
        vec4 col = vec4(0);
        vec2 unit = 1.0 / resolution.xy;

        float r = blurRadius;
        float sampleStep = r / sampleNum;

        float count = 0.0;

        for(float x = -r; x < r; x += sampleStep)
        {
            for(float y = -r; y < r; y += sampleStep)
            {
                float weight = (r - abs(x)) * (r - abs(y));
                col += texture2D(CC_Texture0, p + vec2(x * unit.x, y * unit.y)) * weight;
                count += weight;
            }
        }

        return col / count;
    }

    return texture2D(CC_Texture0, p);
}
然后实施它:

MySpriteBlur::~MySpriteBlur() {
}
MySpriteBlur* MySpriteBlur::create(const char *pszFileName) {
    MySpriteBlur* pRet = new (std::nothrow) MySpriteBlur();
    if (pRet && pRet->initWithFile(pszFileName)) {
        pRet->autorelease();
    } else {
        CC_SAFE_DELETE(pRet);
    }
    return pRet;
}
bool MySpriteBlur::initWithTexture(Texture2D* texture, const Rect& rect) {
    _blurRadius = 0;
    if (Sprite::initWithTexture(texture, rect)) {
#if CC_ENABLE_CACHE_TEXTURE_DATA
        auto listener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom* event) {
            initGLProgram();
        });
        _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
#endif
        initGLProgram();
        return true;
    }
    return false;
}
void MySpriteBlur::initGLProgram() {
    std::string fragSource = FileUtils::getInstance()->getStringFromFile(
        FileUtils::getInstance()->fullPathForFilename("shaders/example_blur.fsh"));
    auto program = GLProgram::createWithByteArrays(ccPositionTextureColor_noMVP_vert, fragSource.data());
    auto glProgramState = GLProgramState::getOrCreateWithGLProgram(program);
    setGLProgramState(glProgramState);
    auto size = getTexture()->getContentSizeInPixels();
    getGLProgramState()->setUniformVec2("resolution", size);
    getGLProgramState()->setUniformFloat("blurRadius", _blurRadius);
    getGLProgramState()->setUniformFloat("sampleNum", 7.0f);
}
void MySpriteBlur::setBlurRadius(float radius) {
    _blurRadius = radius;
    getGLProgramState()->setUniformFloat("blurRadius", _blurRadius);
}
void MySpriteBlur::setBlurSampleNum(float num) {
    _blurSampleNum = num;
    getGLProgramState()->setUniformFloat("sampleNum", _blurSampleNum);
}
希望这会有帮助

MySpriteBlur::~MySpriteBlur() {
}
MySpriteBlur* MySpriteBlur::create(const char *pszFileName) {
    MySpriteBlur* pRet = new (std::nothrow) MySpriteBlur();
    if (pRet && pRet->initWithFile(pszFileName)) {
        pRet->autorelease();
    } else {
        CC_SAFE_DELETE(pRet);
    }
    return pRet;
}
bool MySpriteBlur::initWithTexture(Texture2D* texture, const Rect& rect) {
    _blurRadius = 0;
    if (Sprite::initWithTexture(texture, rect)) {
#if CC_ENABLE_CACHE_TEXTURE_DATA
        auto listener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom* event) {
            initGLProgram();
        });
        _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
#endif
        initGLProgram();
        return true;
    }
    return false;
}
void MySpriteBlur::initGLProgram() {
    std::string fragSource = FileUtils::getInstance()->getStringFromFile(
        FileUtils::getInstance()->fullPathForFilename("shaders/example_blur.fsh"));
    auto program = GLProgram::createWithByteArrays(ccPositionTextureColor_noMVP_vert, fragSource.data());
    auto glProgramState = GLProgramState::getOrCreateWithGLProgram(program);
    setGLProgramState(glProgramState);
    auto size = getTexture()->getContentSizeInPixels();
    getGLProgramState()->setUniformVec2("resolution", size);
    getGLProgramState()->setUniformFloat("blurRadius", _blurRadius);
    getGLProgramState()->setUniformFloat("sampleNum", 7.0f);
}
void MySpriteBlur::setBlurRadius(float radius) {
    _blurRadius = radius;
    getGLProgramState()->setUniformFloat("blurRadius", _blurRadius);
}
void MySpriteBlur::setBlurSampleNum(float num) {
    _blurSampleNum = num;
    getGLProgramState()->setUniformFloat("sampleNum", _blurSampleNum);
}