Using Cocos2d-x to realize UV animation--The realization of the article

Source: Internet
Author: User
Tags emscripten

using Cocos2d-x to realize UV animation--The realization of the articleUvsprite

UV animation refers to the dynamic effect of texture animation by dynamically changing texture coordinates while the program is running, using UV animation to achieve the effects of water flow, flame burning and so on.


This article by Liangneo Original, reproduced please retain the original address: http://blog.csdn.net/liangneo/article/details/42583533


1. Analysis

What we need is a UV animated Sprite, the simplest and most reasonable way is to let you uvsprite directly inherit from the Ccsprite, in addition we need two variables to control whether you or V need animation, the other two variables to control the U and V direction animation speed, So the declaration of the Uvsprite class is as follows:

Class Uvsprite:public cocos2d::ccsprite{//u direction requires animation bool _autoscrollu = true;    U aspect animation speed (0~~1) float _autoscrollspeedu = 0;    Whether the V-direction requires animation bool _AUTOSCROLLV = false;    V-direction animation speed (0~~1) float _autoscrollspeedv=0;    Saves the currently moved UV value float _autoscrollcountu=0; float _autoscrollcountv=0;};
In addition we need two interfaces to create Uvsprite and ccsprite consistency:

Creates a    static uvsprite* createwithspriteframename (const char *pszspriteframename) from a frame in plist;    Create a    static uvsprite* create (const char *pszfilename) directly from the map file;


In addition we need an update to update the UV offset values:

void Uvsprite::update (float dt) {    ccsprite::update (dt);        Update U    if (_autoscrollu)    {        _autoscrollcountu = dt * _autoscrollspeedu;    }        Update v    if (_autoscrollv) {        _AUTOSCROLLCOUNTV = dt * _AUTOSCROLLSPEEDV;    }        If the range is out of 0 if    (_autoscrollcountu > 1 | | _autoscrollcountu <-1) {        _autoscrollcountu = 0;    }        if (_autoscrollcountv > 1 | | _autoscrollcountv <-1) {        _autoscrollcountv = 0;    }}

As we mentioned in the previous article, the value of UV is within the (0~~1) range, so ensure that the offset is within the range of ( -1,1) when updating


2.shader

A. Updated UV updates Let's write shader, vertex shader we use the Ccpositiontexturecolor_vert provided by COCOS2D, the code is as follows

Attribute vec4 a_position;attribute vec2 a_texcoord;attribute vec4 a_color; #ifdef gl_esvarying lowp vec4 v_fragmentcolor ; varying mediump vec2 v_texcoord; #elsevarying vec4 v_fragmentcolor;varying vec2 V_texcoord; #endifvoid Main () {    Gl_ Position = Cc_mvpmatrix * A_position;v_fragmentcolor = A_color;v_texcoord = A_texcoord;}

B. Chip shader, in the element shader we need to update the UV coordinates, set a variable texoffset to represent the UV offset, the code is as follows:

#ifdef gl_esprecision lowp float; #endifvarying vec4 v_fragmentcolor;varying vec2 v_texcoord;uniform vec2 texoffset;                 Uniform sampler2d cc_texture0;void Main () {vec2 Texcoord = mod (texoffset+v_texcoord,1.0);   Gl_fragcolor = V_fragmentcolor * TEXTURE2D (CC_TEXTURE0, Texcoord);}

In the element shader, we add the default V_texcoord to the Texoffset, and we model the result with 1 to ensure that the texture coordinates go out of bounds and return to a reasonable position.


3.shader load, add a member function for Uvsprite, and a uniform reference to texoffset in shader, the code is as follows:

void Uvsprite::loadshadervertex (const char *vert, const char *frag) {    Ccglprogram *shader = new Ccglprogram ();    Shader->initwithvertexshaderbytearray (vert, frag);        Shader->addattribute (Kccattributenameposition, kccvertexattrib_position);    Shader->addattribute (Kccattributenamecolor, kccvertexattrib_color);    Shader->addattribute (Kccattributenametexcoord, kccvertexattrib_texcoords);        Shader->link ();        Shader->updateuniforms ();        _uniformoffset = Glgetuniformlocation (Shader->getprogram (), "Texoffset");        This->setshaderprogram (shader);        Shader->release ();}
In this function, first load Sahder, add COCOS2DX provide three default properties, namely point coordinates, point color, point UV coordinates, and then get Texoffset uniform reference in Shahder

4. Rendering, overriding Ccsprite's draw function, in addition to implementing the Ccsprite Draw rendering function, additional binding texoffset, code as follows:

void Uvsprite::d raw () {cc_profiler_start_category (Kccprofilercategorysprite, "Ccsprite-draw");        Ccassert (!m_pobbatchnode, "If ccsprite is being rendered by Ccspritebatchnode, Ccsprite#draw should not being called");    Getshaderprogram ()->use ();        Getshaderprogram ()->setuniformsforbuiltins ();    Ccglblendfunc (M_SBLENDFUNC.SRC, M_SBLENDFUNC.DST); Binding Texoffset Getshaderprogram ()->setuniformlocationwith2f (_uniformoffset, _autoscrollcountu, _    AUTOSCROLLCOUNTV);    Bind texture Map ccglbindtexture2d (m_pobtexture->getname ());    Ccglenablevertexattribs (Kccvertexattribflag_poscolortex);    #define Kquadsize sizeof (M_SQUAD.BL) #ifdef emscripten long offset = 0;            Setglbufferdata (&m_squad, 4 * kquadsize, 0); #else long offset = (long) &m_sQuad; #endif//Emscripten    Set render coordinates (x, y) int diff = Offsetof (ccv3f_c4b_t2f, vertices); Glvertexattribpointer (Kccvertexattrib_position, 3, Gl_float, Gl_false, Kquadsize, (void*) (offset + diff));        Set texture coordinates (U,V) diff = offsetof (ccv3f_c4b_t2f, texcoords);        Glvertexattribpointer (Kccvertexattrib_texcoords, 2, Gl_float, Gl_false, Kquadsize, (void*) (offset + diff));    set vertex color diff = offsetof (ccv3f_c4b_t2f, colors);        Glvertexattribpointer (Kccvertexattrib_color, 4, Gl_unsigned_byte, Gl_true, Kquadsize, (void*) (offset + diff));        Render Rectangle Gldrawarrays (Gl_triangle_strip, 0, 4);        Check_gl_error_debug (); #if Cc_sprite_debug_draw = = 1//DRAW bounding box ccpoint vertices[4]={CCP (m_squad.tl.vertices.x,m_squad.tl . Vertices.y), CCP (M_SQUAD.BL.VERTICES.X,M_SQUAD.BL.VERTICES.Y), CCP (M_squad.br.vertices.x,m_squad.br.vertice    S.Y), CCP (M_SQUAD.TR.VERTICES.X,M_SQUAD.TR.VERTICES.Y),}; Ccdrawpoly (vertices, 4, true); #elif Cc_sprite_debug_draw = = 2//DRAW texture box ccsize s = this->gettexturerect    (). Size;    Ccpoint Offsetpix = This->getoffsetposition (); Ccpoint Vertices[4] = {CCP (offsetpix.x,OFFSETPIX.Y), CCP (OFFSETPIX.X+S.WIDTH,OFFSETPIX.Y), CCP (Offsetpix.x+s.width,offsetpix.y+s.height), CCP (    Offsetpix.x,offsetpix.y+s.height)};        Ccdrawpoly (vertices, 4, true); #endif//Cc_sprite_debug_draw cc_increment_gl_draws (1); Cc_profiler_stop_category (Kccprofilercategorysprite, "Ccsprite-draw");}

The functionality of the code is basically consistent with the Ccsprite draw, with the only difference being the following:

    Binding Texoffset    Getshaderprogram ()->setuniformlocationwith2f (_uniformoffset, _autoscrollcountu, _ AUTOSCROLLCOUNTV);

This line of code associates the Texoffset in shader with the real-time updated Uvs in update.

This article source code: http://download.csdn.net/detail/liangneo/8348147

Instructions for use: Replace the original file in the samples/cpp/directory of the Cocos2d-x



Using Cocos2d-x to realize UV animation--The realization of the article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.