原文地址: http://blog.csdn.net/hb707934728/article/details/52998569

效果图

核心代码 主要看shader中的实现

x方向飘扬shader

[cpp] view plaincopy
  1. uniform mat4 uMVPMatrix; //总变换矩阵
  2. uniform float uStartAngle;//本帧起始角度
  3. uniform float uWidthSpan;//横向长度总跨度
  4. attribute vec3 aPosition;  //顶点位置
  5. attribute vec2 aTexCoor;    //顶点纹理坐标
  6. varying vec2 vTextureCoord;  //用于传递给片元着色器的变量
  7. void main()
  8. {
  9. //计算X向波浪
  10. float angleSpanH=4.0*3.14159265;//横向角度总跨度
  11. float startX=-uWidthSpan/2.0;//起始X坐标
  12. //根据横向角度总跨度、横向长度总跨度及当前点X坐标折算出当前点X坐标对应的角度
  13. float currAngle=uStartAngle+((aPosition.x-startX)/uWidthSpan)*angleSpanH;
  14. float tz=sin(currAngle)*0.1;
  15. //根据总变换矩阵计算此次绘制此顶点位置
  16. gl_Position = uMVPMatrix * vec4(aPosition.x,aPosition.y,tz,1);
  17. // gl_Position = uMVPMatrix * vec4(aPosition.x,tz,aPosition.y,1);
  18. vTextureCoord = aTexCoor;//将接收的纹理坐标传递给片元着色器
  19. }

斜向飘扬shader

[cpp] view plaincopy
  1. uniform mat4 uMVPMatrix; //总变换矩阵
  2. uniform float uStartAngle;//本帧起始角度
  3. uniform float uWidthSpan;//横向长度总跨度
  4. attribute vec3 aPosition;  //顶点位置
  5. attribute vec2 aTexCoor;    //顶点纹理坐标
  6. varying vec2 vTextureCoord;  //用于传递给片元着色器的变量
  7. void main()
  8. {
  9. //计算X向角度
  10. float angleSpanH=4.0*3.14159265;//横向角度总跨度
  11. float startX=-uWidthSpan/2.0;//起始X坐标
  12. //根据横向角度总跨度、横向长度总跨度及当前点X坐标折算出当前点X坐标对应的角度
  13. float currAngleH=uStartAngle+((aPosition.x-startX)/uWidthSpan)*angleSpanH;
  14. //计算出随Y向发展起始角度的扰动值
  15. float angleSpanZ=4.0*3.14159265;//纵向角度总跨度
  16. float uHeightSpan=0.75*uWidthSpan;//纵向长度总跨度
  17. float startY=-uHeightSpan/2.0;//起始Y坐标
  18. //根据纵向角度总跨度、纵向长度总跨度及当前点Y坐标折算出当前点Y坐标对应的角度
  19. float currAngleZ=((aPosition.y-startY)/uHeightSpan)*angleSpanZ;
  20. //计算斜向波浪
  21. float tzH=sin(currAngleH-currAngleZ)*0.1;
  22. //根据总变换矩阵计算此次绘制此顶点位置
  23. gl_Position = uMVPMatrix * vec4(aPosition.x,aPosition.y,tzH,1);
  24. vTextureCoord = aTexCoor;//将接收的纹理坐标传递给片元着色器
  25. }

xy双向飘扬shader

[cpp] view plaincopy
  1. uniform mat4 uMVPMatrix; //总变换矩阵
  2. uniform float uStartAngle;//本帧起始角度
  3. uniform float uWidthSpan;//横向长度总跨度
  4. attribute vec3 aPosition;  //顶点位置
  5. attribute vec2 aTexCoor;    //顶点纹理坐标
  6. varying vec2 vTextureCoord;  //用于传递给片元着色器的变量
  7. void main()
  8. {
  9. //计算X向波浪
  10. float angleSpanH=4.0*3.14159265;//横向角度总跨度
  11. float startX=-uWidthSpan/2.0;//起始X坐标
  12. //根据横向角度总跨度、横向长度总跨度及当前点X坐标折算出当前点X坐标对应的角度
  13. float currAngleH=uStartAngle+((aPosition.x-startX)/uWidthSpan)*angleSpanH;
  14. float tzH=sin(currAngleH)*0.1;
  15. //计算Y向波浪
  16. float angleSpanZ=4.0*3.14159265;//纵向角度总跨度
  17. float uHeightSpan=0.75*uWidthSpan;//纵向长度总跨度
  18. float startY=-uHeightSpan/2.0;//起始Y坐标
  19. //根据纵向角度总跨度、纵向长度总跨度及当前点Y坐标折算出当前点Y坐标对应的角度
  20. float currAngleZ=uStartAngle+3.14159265/3.0+((aPosition.y-startY)/uHeightSpan)*angleSpanZ;
  21. float tzZ=sin(currAngleZ)*0.1;
  22. //根据总变换矩阵计算此次绘制此顶点位置
  23. gl_Position = uMVPMatrix * vec4(aPosition.x,aPosition.y,tzH+tzZ,1);
  24. vTextureCoord = aTexCoor;//将接收的纹理坐标传递给片元着色器
  25. }

同时需要启动一个线程不断修改当前帧起始角度

[java] view plaincopy
  1. package test.com.opengles_1_1;
  2. import java.nio.ByteBuffer;
  3. import java.nio.ByteOrder;
  4. import java.nio.FloatBuffer;
  5. import android.annotation.SuppressLint;
  6. import android.opengl.GLES20;
  7. /**
  8. * Created by hbin on 2016/11/1.
  9. * 有波浪效果的纹理矩形
  10. */
  11. public class TextureRect {
  12. int[] mPrograms=new int[3];//自定义渲染管线着色器程序id
  13. int[] muMVPMatrixHandle=new int[3];//总变换矩阵引用
  14. int[] maPositionHandle=new int[3]; //顶点位置属性引用
  15. int[] maTexCoorHandle=new int[3]; //顶点纹理坐标属性引用
  16. int[] maStartAngleHandle=new int[3]; //本帧起始角度属性引用
  17. int[] muWidthSpanHandle=new int[3];//横向长度总跨度引用
  18. int currIndex=0;//当前着色器索引
  19. FloatBuffer   mVertexBuffer;//顶点坐标数据缓冲
  20. FloatBuffer   mTexCoorBuffer;//顶点纹理坐标数据缓冲
  21. int vCount=0;
  22. final float WIDTH_SPAN=3.3f;//2.8f;//横向长度总跨度
  23. float currStartAngle=0;//当前帧的起始角度0~2PI
  24. public TextureRect(MySurfaceView mv)
  25. {
  26. //初始化顶点坐标与着色数据
  27. initVertexData();
  28. //初始化shader
  29. initShader(mv,0,"vertex_tex_x.sh");
  30. initShader(mv,1,"vertex_tex_xie.sh");
  31. initShader(mv,2,"vertex_tex_xy.sh");
  32. //启动一个线程定时换帧
  33. new Thread()
  34. {
  35. public void run()
  36. {
  37. while(Constant.threadFlag)
  38. {
  39. currStartAngle+=(float) (Math.PI/16);
  40. try
  41. {
  42. Thread.sleep(50);
  43. } catch (InterruptedException e)
  44. {
  45. e.printStackTrace();
  46. }
  47. }
  48. }
  49. }.start();
  50. }
  51. private void initVertexData()
  52. {
  53. final int cols=12;//列数
  54. final int rows=cols*3/4;//行数
  55. final float UNIT_SIZE=WIDTH_SPAN/cols;//每格的单位长度
  56. vCount=cols*rows*6;//每个格子两个三角形,每个三角形3个顶点
  57. float vertices[]=new float[vCount*3];//每个顶点xyz三个坐标
  58. int count=0;
  59. for (int j=0;j<rows;j++){
  60. for (int i=0;i<cols;i++){
  61. float zsx=-UNIT_SIZE*cols/2+i*UNIT_SIZE;
  62. float zsy=UNIT_SIZE*rows/2-j*UNIT_SIZE;
  63. float zsz=0;
  64. vertices[count++]=zsx;
  65. vertices[count++]=zsy;
  66. vertices[count++]=zsz;
  67. vertices[count++]=zsx;
  68. vertices[count++]=zsy-UNIT_SIZE;
  69. vertices[count++]=zsz;
  70. vertices[count++]=zsx+UNIT_SIZE;
  71. vertices[count++]=zsy;
  72. vertices[count++]=zsz;
  73. vertices[count++]=zsx+UNIT_SIZE;
  74. vertices[count++]=zsy;
  75. vertices[count++]=zsz;
  76. vertices[count++]=zsx;
  77. vertices[count++]=zsy-UNIT_SIZE;
  78. vertices[count++]=zsz;
  79. vertices[count++]=zsx+UNIT_SIZE;
  80. vertices[count++]=zsy-UNIT_SIZE;
  81. vertices[count++]=zsz;
  82. }
  83. }
  84. //创建顶点坐标数据缓冲
  85. //vertices.length*4是因为一个整数四个字节
  86. ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
  87. vbb.order(ByteOrder.nativeOrder());//设置字节顺序
  88. mVertexBuffer = vbb.asFloatBuffer();//转换为Float型缓冲
  89. mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
  90. mVertexBuffer.position(0);//设置缓冲区起始位置
  91. //顶点纹理坐标数据的初始化================begin============================
  92. float texCoor[]=generateTexCoor(cols,rows);
  93. //创建顶点纹理坐标数据缓冲
  94. ByteBuffer cbb = ByteBuffer.allocateDirect(texCoor.length*4);
  95. cbb.order(ByteOrder.nativeOrder());//设置字节顺序
  96. mTexCoorBuffer = cbb.asFloatBuffer();//转换为Float型缓冲
  97. mTexCoorBuffer.put(texCoor);//向缓冲区中放入顶点着色数据
  98. mTexCoorBuffer.position(0);//设置缓冲区起始位置
  99. }
  100. public void initShader(MySurfaceView mv,int index,String vertexName)
  101. {
  102. //加载顶点着色器的脚本内容
  103. String mVertexShader=ShaderUtil.loadFromAssetsFile(vertexName, mv.getResources());
  104. //加载片元着色器的脚本内容
  105. String mFragmentShader=ShaderUtil.loadFromAssetsFile("frag_tex.sh", mv.getResources());
  106. //基于顶点着色器与片元着色器创建程序
  107. mPrograms[index] = ShaderUtil.createProgram(mVertexShader, mFragmentShader);
  108. //获取程序中顶点位置属性引用
  109. maPositionHandle[index] = GLES20.glGetAttribLocation(mPrograms[index], "aPosition");
  110. //获取程序中顶点纹理坐标属性引用
  111. maTexCoorHandle[index]= GLES20.glGetAttribLocation(mPrograms[index], "aTexCoor");
  112. //获取程序中总变换矩阵引用
  113. muMVPMatrixHandle[index] = GLES20.glGetUniformLocation(mPrograms[index], "uMVPMatrix");
  114. //获取本帧起始角度属性引用
  115. maStartAngleHandle[index]=GLES20.glGetUniformLocation(mPrograms[index], "uStartAngle");
  116. //获取横向长度总跨度引用
  117. muWidthSpanHandle[index]=GLES20.glGetUniformLocation(mPrograms[index], "uWidthSpan");
  118. }
  119. public void drawSelf(int texId)
  120. {
  121. //制定使用某套shader程序
  122. GLES20.glUseProgram(mPrograms[currIndex]);
  123. //将最终变换矩阵传入shader程序
  124. GLES20.glUniformMatrix4fv(muMVPMatrixHandle[currIndex], 1, false, MatrixState.getFinalMatrix(), 0);
  125. //将本帧起始角度传入shader程序
  126. GLES20.glUniform1f(maStartAngleHandle[currIndex], currStartAngle);
  127. //将横向长度总跨度传入shader程序
  128. GLES20.glUniform1f(muWidthSpanHandle[currIndex], WIDTH_SPAN);
  129. //将顶点位置数据传入渲染管线
  130. GLES20.glVertexAttribPointer
  131. (
  132. maPositionHandle[currIndex],
  133. 3,
  134. GLES20.GL_FLOAT,
  135. false,
  136. 3*4,
  137. mVertexBuffer
  138. );
  139. //将顶点纹理坐标数据传入渲染管线
  140. GLES20.glVertexAttribPointer
  141. (
  142. maTexCoorHandle[currIndex],
  143. 2,
  144. GLES20.GL_FLOAT,
  145. false,
  146. 2*4,
  147. mTexCoorBuffer
  148. );
  149. //启用顶点位置、纹理坐标数据
  150. GLES20.glEnableVertexAttribArray(maPositionHandle[currIndex]);
  151. GLES20.glEnableVertexAttribArray(maTexCoorHandle[currIndex]);
  152. //绑定纹理
  153. GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
  154. GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
  155. GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
  156. }
  157. //自动切分纹理产生纹理数组的方法
  158. public float[] generateTexCoor(int bw,int bn)
  159. {
  160. float[] result=new float[bw*bn*6*2];
  161. float sizew=1.0f/bw;//列数
  162. float sizeh=0.75f/bn;//行数
  163. int c=0;
  164. for(int i=0;i<bn;i++)
  165. {
  166. for(int j=0;j<bw;j++)
  167. {
  168. //每行列一个矩形,由两个三角形构成,共六个点,12个纹理坐标
  169. float s=j*sizew;
  170. float t=i*sizeh;
  171. //第一个纹理三角形
  172. result[c++]=s;
  173. result[c++]=t;
  174. result[c++]=s;
  175. result[c++]=t+sizeh;
  176. result[c++]=s+sizew;
  177. result[c++]=t;
  178. //第二个纹理三角形
  179. result[c++]=s+sizew;
  180. result[c++]=t;
  181. result[c++]=s;
  182. result[c++]=t+sizeh;
  183. result[c++]=s+sizew;
  184. result[c++]=t+sizeh;
  185. }
  186. }
  187. return result;
  188. }
  189. }

完整代码下载地址

http://download.csdn.net/detail/hb707934728/9670345

opengles特效之飘扬的旗帜相关推荐

  1. C++ Opengl WaveFlag(飘扬的旗帜)源码

    C++ Opengl WaveFlag飘扬的旗帜源码 项目开发环境 项目功能 项目演示 项目源码传送门 项目开发环境 开发语言:C++和IDE:VS2017,操作系统Windows版本windows ...

  2. 3ds Max制作一面飘扬的旗帜效果图

    在大家平时建模过程中肯定会遇到很多力学作用的模型,它们有很多的不确定性,通过人工拖拽的手段很难达到理想的自然效果,这时我们就需要一些特殊的命令来完成我们模拟自然状态的效果.下面我们就一面飘扬的国旗来探 ...

  3. java适合舰旗_飘扬的旗帜!shader 编程实战!Cocos Creator!

    > 用 shader + mesh 立个 flag 吧! 文章底部获取完整代码! 效果预览 使用方法 创建一个空节点 添加用户脚本组件 mesh-texture-flag 添加图片 修改对应属性 ...

  4. Android 3D游戏开发技术详解与典型案例

    下载地址 <Android3D游戏开发技术详解与典型案例>主要以Android平台下3D游戏的开发为主题,并结合真实的案例向读者详细介绍了OpenGL ES的基础 知识及3D游戏程序开发的 ...

  5. 角色扮演游戏引擎的设计原理--转自MOVE2008

    角色扮演游戏引擎的设计原理--转自MOVE2008 角色扮演游戏引擎的设计原理 角色扮演游戏(RPG)是深受广大游戏迷们喜爱的一种游戏, 它以独特的互动性和故事性吸引了无数的玩家.它向人们提供了超出现 ...

  6. 角色扮演游戏引擎的设计原理

    角色扮演游戏引擎的设计原理 角色扮演游戏(RPG)是深受广大游戏迷们喜爱的一种游戏, 它以独特的互动性和故事性吸引了无数的玩家.它向人们提供了超出现实生活的广阔的虚拟世界,使人们能够尝试扮演不同的角色 ...

  7. 这么全的 Cocos Creator 3.x 学习资源,竟然是免费的!

    目前 Cocos Creator 3.0 越来越成熟,使用 Cocos Creator 做游戏的小伙伴越来越多.我们在这里整理了现阶段最全面.最优质的 Cocos Creator 3.x 的学习资料, ...

  8. Macromedia Flash MX 2004 V7.01 简体中文版下载地址及例视频教程(swf版)

    Macromedia Flash MX 2004 V7.01 简体中文版 软件大小:48.65 MB 软件语言:简体中文 软件类别:国外软件 / 动画制作 运行环境:XP, 2000, NT, Win ...

  9. RPG游戏引擎的设计原理

    角色扮演游戏(RPG)是深受广大游戏迷们喜爱的一种游戏, 它以独特的互动性和故事性吸引了无数的玩家.它向人们提供了超出现实生活的广阔的虚拟世界,使人们能够尝试扮演不同的角色,去经历和体验各种不同的人生 ...

  10. 角色扮演游戏(RPG)-------之谈

    角色扮演游戏(RPG)是深受广大游戏迷们喜爱的一种游戏, 它以独特的互动性和故事性吸引了无数的玩家.它向人们提供了超出现实生活的广阔的虚拟世界,使人们能够尝试扮演不同的角色,去经历和体验各种不同的人生 ...

最新文章

  1. WebGoat教程学习(三)--Ajax安全
  2. mysql autocommit 脚本_mysql autocommit的差异
  3. 高性能服务器架构思路「不仅是思路」
  4. ACM中Java输入输出
  5. 常用的函数式接口_Consumer接口练习_字符串拼接输出
  6. python3基础3--数据类型--数据运算--表达式if -else-while-for
  7. Java 抽象类和抽象方法
  8. 返回数据_多层数据返回匹配值
  9. Ubunut14.04安装wps最新方法
  10. oracle 数据的定义,oracle——数据定义
  11. pinia中文文档 指导文档中文翻译版 pinia指导中文翻译
  12. bzoj 1433: [ZJOI2009]假期的宿舍
  13. VS2017编译SNMP库
  14. adc0808温度换算公式_多路温度采集与控制(C51、ADC0808)
  15. 12帧跑步动画分解图_跑步动画原理讲解
  16. CSU oj 1681 Adjoin(dfs求树上最长路径)(搜索)
  17. UWB相关技术之测距定位方法
  18. JavaSE第04篇:Java基础语法之循环结构
  19. java-IOC(控制反转) 理论推导
  20. c++软件开发面试旋极面试题_北京旋极信息技术股份有限公司2015招聘

热门文章

  1. 将实时频谱分析仪与HIF输出配合使用
  2. HCIA-Big Data华为认证大数据工程师 习题册 含答案
  3. 企业上云,安全合规如何进阶 ——一文拆解亚马逊云科技云安全理念与实践
  4. iOS NSString,NSLog添加%百分号和引号等符号
  5. PYMOL-note
  6. GLFWError #65542 Happen, WGL: The driver does not appear to support OpenGL的问题处理经历
  7. MySQL慢查询,一口从天而降的锅!
  8. Linux远程终端工具之Xmanager-Xbrowser
  9. Prefix Sum —— 树状数组+懵逼的组合恒等式
  10. java ship_用Java对象来解答世界悖论难题“忒修斯之船”