如题,因为使用了3D场景,因此需要开启深度检测。另外由于子弹的图片如图
为了把黑色部分变为透明,参考了网上一位朋友的Blog使用了shader,具体做法就是将当前像素的alpha值设置为RGB的最大值。 shader代码如下:
#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 > texColor?(texColor > texColor ? texColor : texColor) :(texColor > texColor? texColor : texColor);
texColor = ratio;
gl_FragColor = v_fragmentColor*texColor;
}
然后启用了深度检测后,shader没有作用,如图:
关闭深度检测后就好了,但是人物的Z轴位置不对了(本应该被山丘遮住的部分到了前面),如图:
子弹使用shader的代码为:
bool CCGSpell::initAdditional(void)
{
.......
CCString* shaderCode = CCString::createWithContentsOfFile(std::string("Shaders/tansparent.fsh"));
// 加载顶点着色器和片元着色器
_pShaderProgram = new CCGLProgram();
_pShaderProgram->initWithVertexShaderByteArray(ccPositionTextureA8Color_vert, shaderCode->getCString());
// 启用顶点着色器的attribute变量,坐标、纹理坐标、颜色
_pShaderProgram->addAttribute(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
_pShaderProgram->addAttribute(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
_pShaderProgram->addAttribute(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORD);
// 自定义着色器链接
_pShaderProgram->link();
// 设置移动、缩放、旋转矩阵
_pShaderProgram->updateUniforms();
return true;
}
void CCGSpell::draw(Renderer *renderer, const Mat4& transform, uint32_t flags)
{
_insideBounds = (flags & FLAGS_TRANSFORM_DIRTY) ? renderer->checkVisibility(transform, _contentSize) : _insideBounds;
if (_insideBounds)
{
CCASSERT(!_batchNode, "If Sprite is being rendered by CCSpriteBatchNode, CCSprite::draw SHOULD NOT be called");
_customCommand.init(1);
_customCommand.func = CC_CALLBACK_0(CCGSpell::onDraw, this, transform, flags);
_customCommand.setTransparent(true); // 放入TransparentRenderQueue,相当于开启深度检测。
renderer->addCommand(&_customCommand);
}
}
void CCGSpell::onDraw(const Mat4 &transform, uint32_t flags)
{
// 启用attributes变量输入,顶点坐标,纹理坐标,颜色
ccGLEnableVertexAttribs(kCCVertexAttribFlag_PosColorTex);
_pShaderProgram->use();
_pShaderProgram->setUniformsForBuiltins(transform);
// 绑定纹理到纹理槽0
ccGLBindTexture2D(_texture->getName());
long offset = (long)&_quad;
// vertex
int diff = offsetof(V3F_C4B_T2F, vertices);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (void*)(offset + diff));
// texCoods
diff = offsetof(V3F_C4B_T2F, texCoords);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_T2F), (void*)(offset + diff));
// color
diff = offsetof(V3F_C4B_T2F, colors);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B_T2F), (void*)(offset + diff));
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
CC_INCREMENT_GL_DRAWS(1);
}
另外试过在渲染子弹的onDraw函数中先关闭深度检测(或者将深度缓存设为只读),画完再开启。但是子弹就看不见了(跑到背景后面去了,因为我所有的sprite都是开启了深度检测)。
难道捕鱼达人3没有开启深度检测吗?求高人解救_(:зゝ∠)_