給quick-cocos的drawnode支持alpha

可以透明是人類的終極夢(mèng)想

畫五維圖

很久很久很久以前,策劃要求我給他們做個(gè)功能,按照英雄當(dāng)前的屬性值,顯示一個(gè)五維圖,我拍了拍手里的磚頭,爽快的答應(yīng)了。
大概就長(zhǎng)下邊這樣


截圖

這很簡(jiǎn)單啊,display.newPolygon走一個(gè),半小時(shí)搞定(主要是為了要對(duì)上她畫的這幾個(gè)點(diǎn),媽耶累死我)。

縮放特效

然后策劃又來(lái)了,說(shuō)我要個(gè)縮放特效,讓這個(gè)東西從小放大,我又摸了摸手里的磚頭,點(diǎn)頭答應(yīng)了,也很簡(jiǎn)單啊,scaleTo一下就好了。

透明度變化

接著策劃又?叒來(lái)了,說(shuō),不僅要縮放,還要有透明度的變化。我心想好吧,砸嘛又不能砸死,只能做了。于是對(duì)創(chuàng)建的五維圖進(jìn)行了setOpacity,然鵝,并沒(méi)有變化。

凝重

怎么辦呢?

這個(gè)時(shí)候,要先冷靜下來(lái),總之要先找到Time Machine(鉆垃圾桶

查找問(wèn)題所在

既然設(shè)置不成功,肯定就是它不支持,那我來(lái)看看為啥不支持吧,首先打開CCDrawNode.cpp,看下draw方法是怎么寫的。
嗯,不出所料,是用OpenGL畫的,那我們看下它的shader是咋寫的,onDraw里只有個(gè)glProgram,所以還得繼續(xù)找找。

    auto glProgram = getGLProgram();
    glProgram->use();
    glProgram->setUniformsForBuiltins(transform);

既然是直接get,那肯定是init的時(shí)候設(shè)置了,看看init函數(shù)。

bool DrawNode::init()
{
    _blendFunc = BlendFunc::ALPHA_PREMULTIPLIED;

    setGLProgramState(GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_LENGTH_TEXTURE_COLOR));
    
    ensureCapacity(512);
    ...
}

那么這個(gè)SHADER_NAME_POSITION_LENGTH_TEXTURE_COLOR是對(duì)應(yīng)的哪個(gè)shader呢?繼續(xù)找,搜索一下SHADER_NAME_POSITION_LENGTH_TEXTURE_COLOR,發(fā)現(xiàn)它是在CCGLProgramCache.cpp里被設(shè)置的。

void GLProgramCache::loadDefaultGLPrograms()
{
    ...
    //
    // Position, Legth(TexCoords, Color (used by Draw Node basically )
    //
    p = new (std::nothrow) GLProgram();
    loadDefaultGLProgram(p, kShaderType_PositionLengthTexureColor);
    _programs.insert( std::make_pair(GLProgram::SHADER_NAME_POSITION_LENGTH_TEXTURE_COLOR, p) );
    ...
}

再看看loadDefaultGLProgram里的具體實(shí)現(xiàn):

void GLProgramCache::loadDefaultGLProgram(GLProgram *p, int type)
{
    switch (type) {
        ...
        case kShaderType_PositionLengthTexureColor:
            p->initWithByteArrays(ccPositionColorLengthTexture_vert, ccPositionColorLengthTexture_frag);
            break;
        ...
    }
}

破案了,用的是ccPositionColorLengthTexture_vert這個(gè)shader,再搜一下這個(gè),是ccShader_PositionColorLengthTexture.vert這個(gè)文件,目錄是cocos/renderer/ccShader_PositionColorLengthTexture.vert,系統(tǒng)性的shader好像都在cocos/renderer/下邊,加載是在CCShaders.cpp里加載的。

修改問(wèn)題

好,咱來(lái)看看這個(gè)shader怎么寫的:

const char* ccPositionColorLengthTexture_vert = STRINGIFY(

\n#ifdef GL_ES\n
attribute mediump vec4 a_position;
attribute mediump vec2 a_texcoord;
attribute mediump vec4 a_color;

varying mediump vec4 v_color;
varying mediump vec2 v_texcoord;

\n#else\n

attribute vec4 a_position;
attribute vec2 a_texcoord;
attribute vec4 a_color;

varying vec4 v_color;
varying vec2 v_texcoord;

\n#endif\n

void main()
{
    v_color = vec4(a_color.rgb * a_color.a, a_color.a);
    v_texcoord = a_texcoord;

    gl_Position = CC_MVPMatrix * a_position;
}
);

很明顯了,是v_color = vec4(a_color.rgb * a_color.a, a_color.a);這句的問(wèn)題,我們只要把a(bǔ)lpha加上即可,將以上shader改成:

const char* ccPositionColorLengthTexture_vert = STRINGIFY(

\n#ifdef GL_ES\n
attribute mediump vec4 a_position;
attribute mediump vec2 a_texcoord;
attribute mediump vec4 a_color;

varying mediump vec4 v_color;
varying mediump vec2 v_texcoord;

\n#else\n

attribute vec4 a_position;
attribute vec2 a_texcoord;
attribute vec4 a_color;

varying vec4 v_color;
varying vec2 v_texcoord;

uniform float u_alpha;

\n#endif\n

void main()
{
    v_color = vec4(a_color.rgb * a_color.a * u_alpha, a_color.a * u_alpha);
    v_texcoord = a_texcoord;

    gl_Position = CC_MVPMatrix * a_position;
}
);

既然增加了一個(gè)uniform u_alpha,那就要在程序里設(shè)置它。
打開CCDrawNode.cpp
onDraw,onDrawGLLine,onDrawGLPoint方法里都加上一句

glProgram->setUniformLocationWith1f(glProgram->getUniformLocation("u_alpha"), _displayedOpacity / 255.0);

重新編譯player,再來(lái)一次setOpacity,果然如我們所想的一樣,成功了。

最后

策劃看了一眼,說(shuō),加上透明度變化好丑哦,去掉吧。


敲里lailai
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容