cocos2dx 使用shader实现树木随风抖动效果

参考文章:https://www.byjth.com/jiqiao/92.html
本人shader也很水,里面有好多不懂的地方,先说一下,之前那个有几个问题

1、不能使用系统自带的那个shader,系统自带的那个 ccPositionTextureA8Color_vert,这个顶点会计算深度,如果这里的树木用的是GlobalZOrder的话,会有一个深度问题,移动的时候坐标不对。
2、原shader里面是只能在一张texture里面运行的,如果精灵用的是一张组图,运行的时候图片会串,而且组图的坐标不一样。

我这里不清楚怎么使用单独一个图的相对坐标,就只能按照整体的坐标进行计算了。如果有大神清楚 请指正。
Building.h

#ifndef __Building_H__
#define __Building_H__
#include "cocos2d.h"
USING_NS_CC;

class Building :public Node
{
public:

protected:
virtual bool init();
 Sprite * m_bg;
 //heartSetFunc
 void getHeart();
 //particle
 ParticleSystemQuad* m_par;
 //data
 BuildingData m_baseData;
 static int _tagnum;
 //shader
 int     m_nTimeUniformLocation;
 float   m_fTime;
};
#endif

Building.cpp
#include "Building.h"
#include "MyRandom.h"
VoidBuildingFunc Building::removeInMap = nullptr;
VoidSpriteFunc Building::setZorderInMapFunc = nullptr;
static const GLchar* szGrassShaderX =
"                                                                                                   \n\
#ifdef GL_ES                                                                                       \n\
precision mediump float;                                                                      \n\
#endif                                                                                              \n\
\n\
varying vec2 v_texCoord;                                                                          \n\
//uniform sampler2D u_texture;                                                                      \n\
uniform float u_time;                                                                             \n\
uniform float u_hight;                                                                             \n\
uniform float u_mid;                                                                             \n\
uniform float u_midx;                                                                             \n\
\n\
// 1                                                                                               \n\
const float speed = 2.0;                                                                            \n\
const float bendFactor = 0.2;                                                                       \n\
void main()                                                                                            \n\
{                                                                                                   \n\
// 获得高度,texCoord从下到上为0到1                                                                   \n\
float height = -(v_texCoord.y-u_hight)*2;                                                                 \n\
float weight = u_midx-abs(u_mid - v_texCoord.x);                                                                 \n\
// 获得偏移量,一个幂函数,值愈大,导数越大,偏移量愈大                                                  \n\
float offset = pow(height, 2.5)*weight;                                                                    \n\
// 偏移量随时间变化,并乘以幅度,设置频率                                                             \n\
offset *= (sin(u_time * speed) * bendFactor);                                                     \n\
// 使x坐标偏移,fract取区间值(0,1)                                                                   \n\
gl_FragColor = texture2D(CC_Texture0, fract(vec2(v_texCoord.x+ offset , v_texCoord.y)));                 \n\
//gl_FragColor = texture2D(CC_Texture0, v_texCoord);                 \n\
}";
static const GLchar* szGrassShader =
"                                                                                                   \n\
#ifdef GL_ES                                                                                       \n\
precision mediump float;                                                                      \n\
#endif                                                                                              \n\
\n\
varying vec2 v_texCoord;                                                                          \n\
//uniform sampler2D u_texture;                                                                      \n\
uniform float u_time;                                                                             \n\
uniform float u_hight;                                                                             \n\
uniform float u_mid;                                                                             \n\
uniform float u_midx;                                                                             \n\
\n\
// 1                                                                                               \n\
const float speed = 2.0;                                                                            \n\
const float bendFactor = 0.2;                                                                       \n\
void main()                                                                                            \n\
{                                                                                                   \n\
// 获得高度,texCoord从下到上为0到1                                                                   \n\
float height = (v_texCoord.x-u_hight)*2;                                                                 \n\
float weight = u_midx-abs(u_mid - v_texCoord.y);                                                                 \n\
// 获得偏移量,一个幂函数,值愈大,导数越大,偏移量愈大                                                  \n\
float offset = pow(height, 2.5)*weight;                                                                    \n\
// 偏移量随时间变化,并乘以幅度,设置频率                                                             \n\
offset *= (sin(u_time * speed) * bendFactor);                                                     \n\
// 使x坐标偏移,fract取区间值(0,1)                                                                   \n\
gl_FragColor = texture2D(CC_Texture0, fract(vec2(v_texCoord.x , v_texCoord.y+ offset)));                 \n\
//gl_FragColor = texture2D(CC_Texture0, v_texCoord);                 \n\
}";
static const GLchar* szGrassShadervsh =
"                                                                                                   \n\
attribute vec4 a_position;                                                                             \n\
attribute vec2 a_texCoord;                                                                    \n\
attribute vec4 a_color;                                                                                \n\
\n\
//varying vec4 v_fragmentColor;                                                                         \n\
varying vec2 v_texCoord;                                                                     \n\
\n\
void main()                                                                                            \n\
{                                                                                                   \n\
gl_Position = CC_PMatrix * a_position;                                                               \n\
//v_fragmentColor = a_color;                                                                \n\
v_texCoord = a_texCoord;                                                             \n\
}";

bool Building::ini(){
 
 m_bg = Sprite::createWithSpriteFrameName("XXX.png");
 addChild(m_bg);

 //init shader

 m_fTime = CCRANDOM_0_1();
 // 加载顶点着色器和片元着色器
 GLProgram* pShader = new  GLProgram();
 float m_baseH;
 float m_baseW;
 float m_baseWx;
 auto txSize = m_bg->getTexture()->getContentSize();
 auto bgrect = m_bg->getTextureRect();
 if (m_bg->isTextureRectRotated())
 {
  pShader->initWithByteArrays(szGrassShadervsh, szGrassShader);//顶点着色器,后一个参数则指定了像素着色器:
  m_baseH = bgrect.getMinX() / txSize.width;
  m_baseW = bgrect.getMidY() / txSize.height;
  m_baseWx = bgrect.size.height / (2 * txSize.height);
 }
 else {
  pShader->initWithByteArrays(szGrassShadervsh, szGrassShaderX);//顶点着色器,后一个参数则指定了像素着色器:
  m_baseH = bgrect.getMaxY() / txSize.height;
  m_baseW = bgrect.getMidX() / txSize.width;
  m_baseWx = bgrect.size.width / (2 * txSize.width);
 }

 m_bg->setGLProgram(pShader);
 pShader->release();
 CHECK_GL_ERROR_DEBUG();


 // 自定义着色器链接
 m_bg->getGLProgram()->link();//因为绑定了属性,所以需要link一下,否则vs无法识别属性
 CHECK_GL_ERROR_DEBUG();

 // 设置移动、缩放、旋转矩阵
 m_bg->getGLProgram()->updateUniforms();//绑定了纹理贴图
 CHECK_GL_ERROR_DEBUG();

 m_nTimeUniformLocation = glGetUniformLocation(m_bg->getGLProgram()->getProgram(), "u_time");

 auto m_hight = glGetUniformLocation(m_bg->getGLProgram()->getProgram(), "u_hight");
 auto m_mid = glGetUniformLocation(m_bg->getGLProgram()->getProgram(), "u_mid");
 auto m_midx = glGetUniformLocation(m_bg->getGLProgram()->getProgram(), "u_midx");


 glUniform1f(m_hight, m_baseH);
 glUniform1f(m_mid, m_baseW);
 glUniform1f(m_midx, m_baseWx);
 m_bg->getGLProgram()->use();//调用glUseProgram()方法

 // 开启帧更新
 this->scheduleUpdate();
 return true;
}
void Building::update(float delta)
{
 m_fTime += delta;
 m_bg->getGLProgram()->use();
 glUniform1f(m_nTimeUniformLocation, m_fTime);
}

最后说一句,不要用cocos2dx自带的那个 什么随风抖动的效果,那个东西在小游戏中使用没毛病,如果你场景里面树木很多,用哪个的话就很傻了,能卡出翔,而且不支持GlobalZOrder

你可能感兴趣的:(cocos2d-x,抖)