cocos2dx学习笔记(着色器水纹效果)

着色器

转载  http://www.25kx.com/art/2424495

参考:

//   ShaderNode.h
#include <iostream>
#include "cocos2d.h"
USING_NS_CC;
class ShaderNode : public CCNode
{
public:
    ShaderNode();
    bool initWithVertex(const char *vert, const char *frag);
    void loadShaderVertex(const char *vert, const char *frag);
    virtual void update(float delta);
    virtual void setContentSize(const CCSize& var);
    virtual void setColor(ccColor4F newColor);
    virtual void draw();
    static ShaderNode* shaderNodeWithVertex(const char *vert,
                                            const char *frag);
    
private:
//    标示符
    GLuint      m_uniformResolution, m_uniformTime, m_uniformTex0;
    GLuint      m_attributeColor, m_attributePosition;
//    取值
    float       m_time;
    ccVertex2F  m_resolution,m_center;
    GLuint      m_texture;
    GLfloat     color[4];
};

//   ShaderNode.cpp
#include "ShaderNode.h"
ShaderNode::ShaderNode()
{
    
}

ShaderNode* ShaderNode::shaderNodeWithVertex(const char *vert, const char *frag)
{
    ShaderNode* shader = new ShaderNode();
    if(shader && shader->initWithVertex(vert,frag))
    {
        shader->autorelease();
        return shader;
    }
    
    CC_SAFE_DELETE(shader);
    return NULL;
}

void ShaderNode::loadShaderVertex(const char *vert, const char *frag)
{
    CCGLProgram* shader = new CCGLProgram();
    shader->initWithVertexShaderFilename(vert, frag);   //载入着色器程序
//    链接着色器程序之前一定要先绑定attribute变量
    //绑定attribute变量
    shader->addAttribute("a_position", 0);
    shader->addAttribute("a_color", 1);
    shader->link();
    
    //获取attribute变量标识
    m_attributeColor = glGetAttribLocation(shader->getProgram(), "a_color");
    m_attributePosition = glGetAttribLocation(
                                              shader->getProgram(), "a_position");
    shader->updateUniforms();
    
    //获取uniform变量标识
    m_uniformResolution = glGetUniformLocation(shader->getProgram(), "resolution");
    m_uniformTime = glGetUniformLocation(shader->getProgram(), "time");
    m_uniformTex0 = glGetUniformLocation(shader->getProgram(), "tex0");
    
    //使用着色器程序
    this->setShaderProgram(shader);
    shader->release();
}

void ShaderNode::setColor(ccColor4F newColor)
{
    color[0] = newColor.r;
    color[1] = newColor.g;
    color[2] = newColor.b;
    color[3] = newColor.a;
}

bool ShaderNode::initWithVertex(const char *vert, const char *frag)
{
//    获取shader程序
    loadShaderVertex(vert,frag);
//aaaa.png为透明图片
    m_texture = CCTextureCache::sharedTextureCache()->addImage("aaaa.png")->getName();
    
    setContentSize(CCSizeMake(1024,768));
    setColor(ccc4f(0.5,0.5,1,1));
    m_time = 0;
    scheduleUpdate();
    return true;
}

void ShaderNode::update(float dt)
{
    m_time += dt;
}

void ShaderNode::setContentSize(const CCSize& var)
{
    CCNode::setContentSize(var);
    m_resolution = vertex2(getContentSize().width,getContentSize().height);
//    m_center.x = m_resolution.x/2;
//    m_center.y = m_resolution.y/2;
}

void ShaderNode::draw()
{
    CC_NODE_DRAW_SETUP();
    
    //传递uniform变量
    CCGLProgram* shader = getShaderProgram();
    shader->setUniformLocationWith2f(m_uniformResolution, m_resolution.x,
                                     m_resolution.y);
    shader->setUniformLocationWith1i(m_uniformTex0, 0);
    glUniform1f(m_uniformTime, m_time);
    
    //获取attribute变量
    CCSize size = this->getContentSize();
    float w = size.width;
    float h = size.height;
    
    ccGLBindTexture2D(m_texture);               //绑定纹理到槽位
    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, w, h, 0); //截取屏幕数据到纹理
    glEnableVertexAttribArray(m_attributePosition);
    glDisableVertexAttribArray(m_attributeColor);
    
    //传递attribute变量
    GLfloat vertices[12] = {
        0, 0, //左下0
        w, 0, //右下1
        w, h, //右上2
        0, 0, //左下0
        0, h, //左上3
        w, h, //右上2
    };
    glVertexAttribPointer(m_attributePosition, 2, GL_FLOAT, GL_FALSE, 0, vertices);
    glVertexAttrib4fv(m_attributeColor, color);  
    
    //绘制  
    glDrawArrays(GL_TRIANGLES, 0, 6);  
}

//shader.fsh
//段着色器
varying vec4 v_color;
//背景纹理
uniform sampler2D tex0;
precision highp float;
//时间
uniform float time;
//分辨率
uniform vec2 resolution;
const float PI = 3.1415926535897932;
//速度
const float speed = 0.2;
const float speed_x = 0.3;
const float speed_y = 0.3;
//几何参数
const float intensity = 3.0;
const int steps = 8;
const float frequency = 4.0;
const int angle = 7;
//反射与凸起参数
const float delta = 20.0;
const float intence = 400.0;
const float emboss = 0.3;
//水波效果
float col(vec2 coord)
{
    float delta_theta = 2.0 * PI / float(angle);
    float col = 0.0;
    float theta = 0.0;
    for (int i = 0; i < steps; i++)
    {
        vec2 adjc = coord;
        theta = delta_theta * float(i);
        adjc.x += cos(theta)*time*speed + time * speed_x;
        adjc.y -= sin(theta)*time*speed - time * speed_y;
        col = col + cos((adjc.x*cos(theta) - adjc.y*sin(theta))
                        *frequency)*intensity;
    }
    return cos(col);
}
//main函数
void main(void)
{
    vec2 p = (gl_FragCoord.xy) / resolution.xy, c1 = p, c2 = p;
    float cc1 = col(c1);
    
    c2.x += resolution.x/delta;
    float dx = emboss*(cc1-col(c2))/delta;
    
    c2.x = p.x;
    c2.y += resolution.y/delta;
    float dy = emboss*(cc1-col(c2))/delta;
    
    c1.x += dx;
    c1.y += dy;
    float alpha = 1.+dot(dx,dy)*intence;
    gl_FragColor = texture2D(tex0,c1)*(alpha) *v_color*(alpha);
}

//shader.vsh
//顶点着色器
//水纹颜色
attribute vec4 a_color;
//顶点坐标
attribute vec4 a_position;
varying vec4 v_color;
//坐标变换矩阵
//uniform mat4 u_MVPMatrix;
void main()
{
    v_color = a_color;
    gl_Position = CC_MVPMatrix * a_position;
}

测试代码:

ShaderNode* shader = ShaderNode::shaderNodeWithVertex("shader.vsh","shader.fsh");
    shader->setContentSize(getContentSize());
    shader->setColor(ccc4f(1,1,1.0,.5));
    this->addChild(shader,2);


除此之外,引擎封装了一个特殊段动作类CCActionGrid3D,里面模拟了一些简单的3d特效。

引擎Demo中的EffectsTest演示了这些3D动作类。

引擎中的水纹效果

在场景中加入

// CCWaves3D::create(时间,晃动网格大小,波动速度,振幅);
    CCGrid3DAction *grid = CCWaves3D::create(50, ccp(10, 10),40 , 10);
    this->runAction(grid);




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值