可以透明是人類的終極夢(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ō),加上透明度變化好丑哦,去掉吧。
