• cocos2d-x游戏开发(十四)用shader使图片背景透明


    好吧,终于抽时间写这篇文章了。

    手头上有很多人物行走图,技能特效图等,但这些图都有个纯黑色背景,怎么样将内容显示出来,让背景透明呢?前段时间搞了一下,感谢群里的童鞋们,提供了思路和方法。

     

    这里用shader处理了像素,使黑色背景透明,直接上代码

    ShaderSprite.h

    #ifndef __TestShader__ShaderSprite__
    #define __TestShader__ShaderSprite__
    
    #include "cocos2d.h"
    USING_NS_CC;
    
    class ShaderSprite : public CCSprite {
        
    public:
        static ShaderSprite* create(const char* pszFileName);
        virtual bool initWithTexture(CCTexture2D *pTexture, const CCRect& rect);
        virtual void draw(void);
    };
    
    #endif /* defined(__TestShader__ShaderSprite__) */


    ShaderSprite.cpp

    #include "ShaderSprite.h"
    
    static CC_DLL const GLchar *transparentshader =
    #include "tansparentshader.h"
    
    ShaderSprite* ShaderSprite::create(const char *pszFileName)
    {
        ShaderSprite *pRet = new ShaderSprite();
        if (pRet && pRet->initWithFile(pszFileName)) {
            pRet->autorelease();
            return pRet;
        }
        else
        {
            delete pRet;
            pRet = NULL;
            return NULL;
        }
    }
    
    bool ShaderSprite::initWithTexture(CCTexture2D *pTexture, const CCRect& rect)
    {
        do{
    //        CCLog("override initWithTexture!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
            CC_BREAK_IF(!CCSprite::initWithTexture(pTexture, rect));
            
            // 加载顶点着色器和片元着色器
            m_pShaderProgram = new  CCGLProgram();
            m_pShaderProgram ->initWithVertexShaderByteArray(ccPositionTextureA8Color_vert, transparentshader);
            
            CHECK_GL_ERROR_DEBUG();
            
            // 启用顶点着色器的attribute变量,坐标、纹理坐标、颜色
            m_pShaderProgram->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
            m_pShaderProgram->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);
            m_pShaderProgram->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);
            
            CHECK_GL_ERROR_DEBUG();
            
            // 自定义着色器链接
            m_pShaderProgram->link();
            
            CHECK_GL_ERROR_DEBUG();
            
            // 设置移动、缩放、旋转矩阵
            m_pShaderProgram->updateUniforms();
            
            CHECK_GL_ERROR_DEBUG();
            
            return true;
            
        }while(0);
        return false;
    }
    
    void ShaderSprite::draw(void)
    {
    //    CCLog("override draw!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
        CC_PROFILER_START_CATEGORY(kCCProfilerCategorySprite, "CCSprite - draw");
        
        CCAssert(!m_pobBatchNode, "If CCSprite is being rendered by CCSpriteBatchNode, CCSprite#draw SHOULD NOT be called");
        
        CC_NODE_DRAW_SETUP();
        
        //
    // 启用attributes变量输入,顶点坐标,纹理坐标,颜色
    //
    ccGLEnableVertexAttribs( kCCVertexAttribFlag_PosColorTex );
        ccGLBlendFunc(m_sBlendFunc.src, m_sBlendFunc.dst);
        
        m_pShaderProgram->use();
        m_pShaderProgram->setUniformsForBuiltins();
        
        // 绑定纹理到纹理槽0
        ccGLBindTexture2D(m_pobTexture->getName());
    
    
        
    #define kQuadSize sizeof(m_sQuad.bl)
    long offset = (long)&m_sQuad;
        
    // vertex
    int diff = offsetof( ccV3F_C4B_T2F, vertices);
    glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff));
        
    // texCoods
    diff = offsetof( ccV3F_C4B_T2F, texCoords);
    glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff));
        
    // color
    diff = offsetof( ccV3F_C4B_T2F, colors);
    glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff));
        
        
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
        
    CHECK_GL_ERROR_DEBUG();
    
        CC_INCREMENT_GL_DRAWS(1);
        CC_PROFILER_STOP_CATEGORY(kCCProfilerCategorySprite, "CCSprite - draw");
    }


    片段着色器代码

    tansparentshader.h 

    "                                                       
    
    #ifdef GL_ES                                            
    
    precision lowp float;                                   
    
    #endif                                                  
    
    varying vec4 v_fragmentColor;                           
    
    varying vec2 v_texCoord;                                
    
    uniform sampler2D u_texture;                            
    
    void main()                                             
    
    {                                                       
    
        float ratio=0.0;                                    
    
        vec4 texColor = texture2D(u_texture, v_texCoord);   
    
        ratio = texColor[0] > texColor[1]?(texColor[0] > texColor[2] ? texColor[0] : texColor[2]) :(texColor[1] > texColor[2]? texColor[1] : texColor[2]);                                      
    
    if (ratio != 0.0)                                          
    
    {                                                          
    
        texColor[0] = texColor[0] /  ratio;                    
    
        texColor[1] = texColor[1] /  ratio;                    
    
        texColor[2] = texColor[2] /  ratio;                    
    
        texColor[3] = ratio;                                   
    
    }                                                          
    
    else                                                       
    
    {                                                          
    
        texColor[3] = 0.0;                                     
    
    }                                                          
    
    gl_FragColor = v_fragmentColor*texColor;                   
    
    }";


    注意shader编程没有隐士数据类型转换,所以都显示为float了。

    然后ratio是指在rgb中找最大的,如果ratio为0直接将alpha设为0,否则alpha设为ratio,然后各rgb除以ratio,这里是为了做渐变,否则变化太生硬。

    上图:

    好了,上面两张图是一样的。只是屏幕背景一个是白色,一个是黑色。图片背景透明了。

  • 相关阅读:
    灰哥的二叉树
    BZOJ1029: [JSOI2007]建筑抢修[模拟 贪心 优先队列]
    POJ1155TELE[树形背包]
    HDU4003Find Metal Mineral[树形DP 分组背包]
    POJ1837 Balance[分组背包]
    HDU2639Bone Collector II[01背包第k优值]
    POJ3666Making the Grade[DP 离散化 LIS相关]
    HDU2955 Robberies[01背包]
    HDU2191悼念512汶川大地震遇难同胞——珍惜现在,感恩生活[多重背包]
    POJ1014Dividing[多重背包可行性]
  • 原文地址:https://www.cnblogs.com/cooka/p/3660514.html
Copyright © 2020-2023  润新知