在cocos2dx中实现水波滤镜
因为工作原因,开始转向cocos2d-x开发方向了。 在此期间看了两本书 言归正传,在 《高级开发教程》 中有一篇是实现海底水纹效果的文章,里面代码不全,且代码和Shader并没有对应起来,于是我决定按照自己思路来将其补全,并贴上完整源码。 先上效果图:
首先创建一个 ShaderNode.h 类并继承CCNode
之后创建ShaderNode.cpp 并实现 ShaderNode.h 中的各方法
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
#include "ShaderNode.h"
ShaderNode :: ShaderNode ( ) } ShaderNode *ShaderNode shaderNodeWithVertex ( *frag ) ShaderNode *shader = newShaderNode ( ) if (shader &&shader - >initWithVertex (vert,frag ) ) { shader >autorelease ( ) returnshader } CC_SAFE_DELETE (shader ) return NULL voidShaderNode loadShaderVertex ( CCGLProgram newCCGLProgram ( ) shader >initWithVertexShaderFilename (vert,frag ) ; //载入着色器程序 //绑定attribute变量 >addAttribute ( "a_position",0 ) "a_color",160); margin:0px; padding:0px; line-height:1.4em">1 ) >link ( ) //获取attribute变量标识 m_attributeColor =glGetAttribLocation (shader >getProgram ( ),"a_color" ) m_attributePosition =glGetAttribLocation ( "a_position" ) >updateUniforms ( ) //获取uniform变量标识 m_uniformResolution =glGetUniformLocation (shader "resolution" ) m_uniformTime "time" ) m_uniformTex0 "tex0" ) //使用着色器程序 this >setShaderProgram (shader ) >release ( ) setColor (ccColor4F newColor ) color [ 0 ] =newColor. r 1 ] g 2 ] b 3 ] a boolShaderNode initWithVertex ( loadShaderVertex (vert,51); margin:0px; padding:0px; line-height:1.4em"> m_texture =CCTextureCache sharedTextureCache ( ) >addImage ( "HelloWorld.png" ) >getName ( ) setContentSize (CCSizeMake ( 1024,160); margin:0px; padding:0px; line-height:1.4em">768 ) ) setColor (ccc4f ( 0.5,1,160); margin:0px; padding:0px; line-height:1.4em">1 ) ) m_time = 0 scheduleUpdate ( ) true update ( floatdt ) m_time + =dt setContentSize ( &var ) CCNode setContentSize (var ) m_resolution =vertex2 (getContentSize ( ). width,getContentSize ( ). height ) m_center. x =m_resolution. x / 2 y y draw ( ) CC_NODE_DRAW_SETUP ( ) //传递uniform变量 =getShaderProgram ( ) >setUniformLocationWith2f (m_uniformResolution,m_resolution. x,51); margin:0px; padding:0px; line-height:1.4em"> m_resolution. y ) >setUniformLocationWith1i (m_uniformTex0,51); margin:0px; padding:0px; line-height:1.4em"> glUniform1f (m_uniformTime,m_time ) //获取attribute变量 CCSize size =this >getContentSize ( ) floatw =size. width floath height ccGLBindTexture2D (m_texture ) ; //绑定纹理到槽位 glCopyTexImage2D (GL_TEXTURE_2D,160); margin:0px; padding:0px; line-height:1.4em">0,GL_RGBA,w,h,64); margin:0px; padding:0px; font-style:italic; line-height:1.4em">//截取屏幕数据到纹理 glEnableVertexAttribArray (m_attributePosition ) glDisableVertexAttribArray (m_attributeColor ) //传递attribute变量 GLfloat vertices [ 12 ] = { //左下0 w,64); margin:0px; padding:0px; font-style:italic; line-height:1.4em">//右下1 //右上2 //左上3 } glVertexAttribPointer (m_attributePosition,160); margin:0px; padding:0px; line-height:1.4em">2,GL_FLOAT,GL_FALSE,vertices ) glVertexAttrib4fv (m_attributeColor,color ) //绘制 glDrawArrays (GL_TRIANGLES,160); margin:0px; padding:0px; line-height:1.4em">6 ) } |
之后在场景类中添加ShaderNode 即可
2
3
4
shader.vsh 和 shader.fsh 可以从网络中得到,就是glsl文件
shader.vsh 的内容为
2
3
4
5
6
7
8
9
v_color =a_color gl_Position =u_MVPMatrix *a_position shader.fsh 的内容为
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
uniform sampler2D tex0 precision highp float uniform float time uniform vec2 resolution floatPI = 3.1415926535897932 floatspeed 0.2 floatspeed_x 0.3 floatspeed_y floatintensity 3.0 intsteps 8 floatfrequency 4.0 intangle 7 floatdelta 20.0 floatintence 400.0 floatemboss floatcol (vec2 coord )
floatdelta_theta 2.0 *PI / float (angle ) floatcol 0.0 floattheta for ( inti ;i <steps ;i ++ )
vec2 adjc =coord theta =delta_theta * float (i ) adjc. cos (theta ) * time *speed + *speed_x adjc. sin (theta ) - *speed_y col =col cos ( (adjc. -adjc. sin (theta ) )
*frequency ) *intensity return cos (col ) voidmain ( void )
vec2 p = (gl_FragCoord. xy ) /resolution. xy,c1 =p,c2 =p floatcc1 =col (c1 ) c2. =resolution. /delta floatdx =emboss * (cc1 -col (c2 ) ) =p. x floatdy c1. =dx =dy floatalpha 1. +dot (dx,dy ) *intence gl_FragColor =texture2D (tex0,c1 ) * (alpha ) *v_color * (alpha ) github地址为:
https://github.com/AlexandreRangel/QuaseCinemaFeijoada/blob/master/QuaseCinemaFeijoada07d/data/water.glsl
在使用顶点程序的时候,里面有个模型世界投影矩阵 u_MVPMatrix
我们在cocos2d-x中使用它的时候,需要把 CC_MVPMatrix 赋值给 u_MVPMatrix
或者直接把 u_MVPMatrix 删除,替换成 CC_MVPMatrix
like this
2
3
4
5
6
7
8
9
10
11
12
13
14
(type ==GL_VERTEX_SHADER ? "precision highp float;n" : "precision mediump float;n" ),64); margin:0px; padding:0px; font-style:italic; line-height:1.4em">#endif
"uniform mat4 CC_PMatrix;n"
"uniform mat4 CC_MVMatrix;n"
"uniform mat4 CC_MVPMatrix;n"
"uniform vec4 CC_Time;n"
"uniform vec4 CC_SinTime;n"
"uniform vec4 CC_CosTime;n"
"uniform vec4 CC_Random01;n"
"//CC INCLUDES ENDnn",51); margin:0px; padding:0px; line-height:1.4em"> source,51); margin:0px; padding:0px; line-height:1.4em">;
that’s all. 本文对于原书教程补充的地方如下 修改 shader.vsh 替换 u_MVPMatrix 为 CC_MVPMatrix 删除 ShaderNode.cpp 中全部的 m_uniformCenter 的相关代码, m_uniformCenter 在Shader中并没有该字段,没有补完的意义 添加 ShaderNode.cpp 构造函数及SetColor方法 修改 ShaderNode.h 中 update 的参数
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!