我有3个问题:
我知道何时使用spr1->setShaderProgram(glProgram)
为Sprite对象设置着色器。但是,我想为Armature对象设置着色器。我怎么能这样做?
在CCSprite中,我可以使用setBlendFunc,如何在Armature中使用。
我读了这篇文章http://blog.muditjaju.infiniteeurekas.in/?p=1,我看到了检测2个精灵之间碰撞的想法。但我想编写一个扩展函数,可以检测不同对象之间的冲突,如精灵与精灵,精灵与电枢,电枢与电枢。我怎么能这样做?
由于
答案 0 :(得分:0)
今天我遇到了和你一样的情况。幸运的是,我找到了其他人的解决方案。主要的是写一个Armature的子类,比如说ShaderArmature,并用着色器渲染每个骨骼的每个孩子----在我的例子中,着色器用于使骨架变灰。
您可以创建一个ShaderArmature对象并调用其 setgrayState ()以启用灰化和 setUsuaState ()以删除灰度效果。
1,添加ShaderArmature.h& ShaderArmature.cpp位于Armature.h的同一目录中。
ShaderArmature.h
//
// Created by Wangyq on 2017/8/13.
//
//
#ifndef __SHADERARMATURE_H__
#define __SHADERARMATURE_H__
//
//---------shaderArmature.h
///
#include "cocos2d.h"
//#include "extensions/cocos-ext.h"
#include "cocostudio/CocoStudio.h"
//USING_NS_CC_EXT;
USING_NS_CC;
namespace cocostudio{
class CC_STUDIO_DLL ShaderArmature : public Armature
{
public:
ShaderArmature();
virtual ~ShaderArmature();
bool init(const std::string& name) override;
static ShaderArmature *create(const std::string& name) ;
virtual void initShader(bool shaderState);
// void setBackgroundNotification();
// draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags)
virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t transformUpdated) override;
// void listenBackToForeground(Ref *obj);
void setIceState();
void setUsuaState();
void setblurState();
void setbanishState();
void setfrozenState();
void setgrayState();
void setinvisState();
void setmirrorState();
void setpoisonState();
void setstoneState();
protected:
std::string _fragSourceFile;
std::string _vertSourceFile;
//GLchar * fragSource;
//GLchar * vertSource;
GLchar fragSource[2048];
GLchar vertSource[2048];
bool bSetShader;
};
}
#endif /* __SHADERARMATURE_H__ */
ShaderArmature.cpp
//
// ShaderArmature.cpp
// cocos2d_libs
//
// Created by Wangyq on 2017/8/13.
//
//
#include "ShaderArmature.h"
using namespace cocos2d;
namespace cocostudio {
ShaderArmature::ShaderArmature(){
}
ShaderArmature::~ShaderArmature(){
}
bool ShaderArmature::init(const std::string& name)
{
return Armature::init(name);
}
ShaderArmature *ShaderArmature::create(const std::string& name)
{
ShaderArmature *armature = new ShaderArmature;
if (armature && armature->init(name))
{
armature->autorelease();
return armature;
}
else{
CC_SAFE_DELETE(armature);
return nullptr;
}
}
void ShaderArmature::initShader(bool shaderState){
//Traverse every bone to set shader
for (auto& object : _boneDic)
{
if (Bone *bone = dynamic_cast<Bone *>(object.second))
{
if (bone == nullptr)
continue;
//-----------------!! IMPORTANT !!-----------------
//Each bone may have more than one child, like several frames, also need to assign shader to them
//Without this step, only the first frame will have the shader effect.
const Vector<DecorativeDisplay*> list = bone->getDisplayManager()->getDecorativeDisplayList();
for (auto& display : list)
{
Node* node = display->getDisplay();
if (node == nullptr)
continue;
if (shaderState){
auto program = new GLProgram();
program->initWithByteArrays(vertSource, fragSource);
node->setGLProgram(program);
program->autorelease();
CHECK_GL_ERROR_DEBUG();
program->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
program->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
program->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
CHECK_GL_ERROR_DEBUG();
program->link();
CHECK_GL_ERROR_DEBUG();
program->updateUniforms();
CHECK_GL_ERROR_DEBUG();
}
else{//addNormal shader
node->setGLProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP));
}
}
}
}
}
void ShaderArmature::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
Armature::draw(renderer, transform, flags);
}
void ShaderArmature::setIceState(){
_fragSourceFile = "shader/IceShader.fsh";
_vertSourceFile = "shader/IceShader.vsh";
fragSource = (GLchar*)String::createWithContentsOfFile(
FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
vertSource = (GLchar*)String::createWithContentsOfFile(
FileUtils::getInstance()->fullPathForFilename(_vertSourceFile).c_str())->getCString();
initShader(true);
}
void ShaderArmature::setUsuaState(){
initShader(false);
}
void ShaderArmature::setblurState(){
_fragSourceFile = "shader/Blur.fsh";
_vertSourceFile = "shader/Blur.vsh";
fragSource = (GLchar*)String::createWithContentsOfFile(
FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
vertSource = (GLchar*)String::createWithContentsOfFile(
FileUtils::getInstance()->fullPathForFilename(_vertSourceFile).c_str())->getCString();
initShader(true);
}
void ShaderArmature::setbanishState(){
_fragSourceFile = "shader/BanishShader.fsh";
_vertSourceFile = "shader/BanishShader.vsh";
fragSource = (GLchar*)String::createWithContentsOfFile(
FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
vertSource = (GLchar*)String::createWithContentsOfFile(
FileUtils::getInstance()->fullPathForFilename(_vertSourceFile).c_str())->getCString();
initShader(true);
}
void ShaderArmature::setfrozenState(){
_fragSourceFile = "shader/FrozenShader.fsh";
_vertSourceFile = "shader/FrozenShader.vsh";
fragSource = (GLchar*)String::createWithContentsOfFile(
FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
vertSource = (GLchar*)String::createWithContentsOfFile(
FileUtils::getInstance()->fullPathForFilename(_vertSourceFile).c_str())->getCString();
initShader(true);
}
void ShaderArmature::setgrayState(){
_fragSourceFile = "shader/GrayScalingShader.fsh";
_vertSourceFile = "shader/GrayScalingShader.vsh";
fragSource = (GLchar*)String::createWithContentsOfFile(
FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
vertSource = (GLchar*)String::createWithContentsOfFile(
FileUtils::getInstance()->fullPathForFilename(_vertSourceFile).c_str())->getCString();
initShader(true);
}
void ShaderArmature::setinvisState(){
_fragSourceFile = "shader/InvisibleShader.fsh";
_vertSourceFile = "shader/InvisibleShader.vsh";
fragSource = (GLchar*)String::createWithContentsOfFile(
FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
vertSource = (GLchar*)String::createWithContentsOfFile(
FileUtils::getInstance()->fullPathForFilename(_vertSourceFile).c_str())->getCString();
initShader(true);
}
void ShaderArmature::setmirrorState(){
_fragSourceFile = "shader/MirrorShader.fsh";
_vertSourceFile = "shader/MirrorShader.vsh";
fragSource = (GLchar*)String::createWithContentsOfFile(
FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
vertSource = (GLchar*)String::createWithContentsOfFile(
FileUtils::getInstance()->fullPathForFilename(_vertSourceFile).c_str())->getCString();
initShader(true);
}
void ShaderArmature::setpoisonState(){
_fragSourceFile = "shader/PoisonShader.fsh";
_vertSourceFile = "shader/PoisonShader.vsh";
fragSource = (GLchar*)String::createWithContentsOfFile(
FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
vertSource = (GLchar*)String::createWithContentsOfFile(
FileUtils::getInstance()->fullPathForFilename(_vertSourceFile).c_str())->getCString();
initShader(true);
}
void ShaderArmature::setstoneState(){
_fragSourceFile = "shader/StoneShader.fsh";
_vertSourceFile = "shader/StoneShader.vsh";
fragSource = (GLchar*)String::createWithContentsOfFile(
FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
vertSource = (GLchar*)String::createWithContentsOfFile(
FileUtils::getInstance()->fullPathForFilename(_vertSourceFile).c_str())->getCString();
initShader(true);
}
}
2,对于着色器文件,我将它们放在“res / shader”文件夹中。每个着色器由2个文件组成 - .vsh文件&amp;一个.fsh文件。以灰色为例:
GrayScalingShader.fsh
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
uniform sampler2D u_texture;
void main()
{
vec4 normalColor = v_fragmentColor * texture2D(u_texture, v_texCoord);
//float gray = 0.299*0.5*normalColor.r + 0.587*0.5*normalColor.g + 0.114*0.5*normalColor.b;
//gl_FragColor = vec4(gray*0.8 + normalColor.r*0.2, gray*0.8 + normalColor.g*0.2, gray*0.8 + normalColor.b*0.2, normalColor.a*0.3);
float gray = dot(normalColor.rgb, vec3(0.299 * 0.5, 0.587 * 0.5, 0.114 * 0.5));
gl_FragColor = vec4(gray, gray, gray, normalColor.a * 1);
}
GrayScalingShader.vsh
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
void main()
{
//gl_Position = CC_MVPMatrix * a_position;
gl_Position = CC_PMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}
希望这会有所帮助。