zoukankan      html  css  js  c++  java
  • 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,这里是为了做渐变,否则变化太生硬。

    上图:

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

  • 相关阅读:
    _bzoj1061 [Noi2008]志愿者招募【最小费用最大流】
    _bzoj2243 [SDOI2011]染色【树链剖分】
    _bzoj1013 [JSOI2008]球形空间产生器sphere【高斯消元】
    _bzoj1002 [FJOI2007]轮状病毒【瞎搞】
    leetcode 273 Integer to English Words
    leetcode 12 Integer to Roman
    leetcode 1071 Greatest Common Divisor of Strings
    lc6 ZigZag Conversion
    lc13 Roman to Integer
    leetcode 171 Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/cooka/p/3660514.html
Copyright © 2011-2022 走看看