============================================================
博文原创,转载请声明出处
============================================================
感谢开源社区的所有贡献者。
一维水波效果,地址:http://www.supersuraccoon-cocos2d.com/2011/09/17/sticky-demo-resource-list-keep-updating/
水波主要有Waves1DNode实现。详情见代码注释。截图如下:
Waves1DNode.h
#import "cocos2d.h" @interface Waves1DNode : CCNode { CGRect _bounds; float _diffusion; float _damping; int _count; // Heightfields that the simulation verlet integrates between. float *_h1, *_h2; } // 'bounds' are the rectangle to draw for the water. The top of the bounds is the rest height for the water, it wil wave above and below it. // 'count' is the number of slices to simulate. One per 10-20 pixels is usually sufficient. // 'damping' is how fast the water settles back to rest. 1.0 is never (bad), 0.0 is immediately (also bad). 0.99 is a decent damping amount. // 'diffusion' is how fast the waves spread to neighbors. Values outside of 0.6 - 0.9 can become unstable. -(id)initWithBounds:(CGRect)bounds count:(int)count damping:(float)damping diffusion:(float)diffusion; -(void)makeSplashAt:(float)x;
Waves1DNode.m
#import "Waves1DNode.h" @implementation Waves1DNode /** bounds 水深度 count 水平vertex数目,越大,越逼真 damping 阻尼 */ -(id)initWithBounds:(CGRect)bounds count:(int)count damping:(float)damping diffusion:(float)diffusion; { if((self = [super init])){ _bounds = bounds; _count = count; _damping = damping; _diffusion = diffusion; _h1 = calloc(_count, sizeof(float)); _h2 = calloc(_count, sizeof(float)); } return self; } - (void) dealloc { free(_h1); free(_h2); [super dealloc]; } /**屋里引擎算法,牵动运动,参考 http://en.wikipedia.org/wiki/Verlet_integration */ -(void)verlet { for(int i=0; i<_count; i++) { _h1[i] = 2.0*_h2[i] - _h1[i]; } float *temp = _h2; _h2 = _h1; _h1 = temp; } static inline float diffuse(float diff, float damp, float prev, float curr, float next){ return (curr*diff + ((prev + next)*0.5f)*(1.0f - diff))*damp; } //进行阻尼计算 -(void)diffuse { float prev = _h2[0]; float curr = _h2[0]; float next = _h2[1]; _h2[0] = diffuse(_diffusion, _damping, prev, curr, next); for(int i=1; i<(_count - 1); ++i){ prev = curr; curr = next; next = _h2[i + 1]; _h2[i] = diffuse(_diffusion, _damping, prev, curr, next); } prev = curr; curr = next; _h2[_count - 1] = diffuse(_diffusion, _damping, prev, curr, next); } //dx 相邻两点的距离(count个点) -(float)dx{return _bounds.size.width/(GLfloat)(_count - 1);} - (void)draw { // It would be better to run these on a fixed timestep. // As an GFX only effect it doesn't really matter though. //进行verlet和diffuse的simulate计算 [self verlet]; [self diffuse]; GLfloat dx = [self dx]; GLfloat top = _bounds.size.height; // Build a vertex array and render it. struct Vertex{GLfloat x,y;}; //opengl绘制三角形图元,数组绘制可以共用一个顶点,因此只绘制两个顶点,所以*2 struct Vertex verts[_count*2]; for(int i=0; i<_count; i++){ GLfloat x = i*dx; //底部顶点 verts[2*i + 0] = (struct Vertex){x, 0}; // top + _h2[i] 为水深+对应的波浪起伏 verts[2*i + 1] = (struct Vertex){x, top + _h2[i]}; } //By default, all client-side capabilities are disabled. //默认是disable,这里是在cocos2d中enable的 // printf("%s:%d %i,%i,%i,%i\n",__FUNCTION__,__LINE__,glIsEnabled(GL_COLOR_ARRAY),\ glIsEnabled(GL_TEXTURE_COORD_ARRAY),glIsEnabled(GL_TEXTURE_2D),glIsEnabled(GL_VERTEX_ARRAY)); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); // glDisableClientState(GL_VERTEX_ARRAY); GLfloat r = 105.0f/255.0f; GLfloat g = 193.0f/255.0f; GLfloat b = 212.0f/255.0f; GLfloat a = 0.3f; glColor4f(r*a, g*a, b*a, a); //制定vertex数组 glVertexPointer(2, GL_FLOAT, 0, verts); //因为后面要进行translate,所有需要push matrix glPushMatrix(); { //针对retina进行优化 glScalef(CC_CONTENT_SCALE_FACTOR(), CC_CONTENT_SCALE_FACTOR(), 1.0); //平移水面到bound位置,否则在(0,0)处 glTranslatef(_bounds.origin.x, _bounds.origin.y, 0.0); // glDrawArrays(GL_TRIANGLE_FAN, 0, _count*2); //绘制图元 glDrawArrays(GL_TRIANGLE_STRIP, 0, _count*2); } glPopMatrix(); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_TEXTURE_2D); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } -(void)makeSplashAt:(float)x; { // Changing the values of heightfield in h2 will make the waves move. // Here I only change one column, but you get the idea. // Change a bunch of the heights using a nice smoothing function for a better effect. int index = MAX(0, MIN((int)(x/[self dx]), _count - 1)); _h2[index] += CCRANDOM_MINUS1_1()*20.0; } @end
作者:shencaifeixia1 发表于2013-5-6 21:42:16 原文链接
阅读:28 评论:0 查看评论