opengles特效之飘扬的旗帜

来源:互联网 发布:钻石4c哪个最重要 知乎 编辑:程序博客网 时间:2024/05/02 00:48

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


效果图





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

x方向飘扬shader

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  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.    //根据总变换矩阵计算此次绘制此顶点位置  
  17.    gl_Position = uMVPMatrix * vec4(aPosition.x,aPosition.y,tz,1);  
  18.     // gl_Position = uMVPMatrix * vec4(aPosition.x,tz,aPosition.y,1);  
  19.   
  20.    vTextureCoord = aTexCoor;//将接收的纹理坐标传递给片元着色器  
  21. }  

斜向飘扬shader

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  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.   
  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=((aPosition.y-startY)/uHeightSpan)*angleSpanZ;  
  21.   
  22.    //计算斜向波浪  
  23.    float tzH=sin(currAngleH-currAngleZ)*0.1;  
  24.    //根据总变换矩阵计算此次绘制此顶点位置  
  25.    gl_Position = uMVPMatrix * vec4(aPosition.x,aPosition.y,tzH,1);  
  26.    vTextureCoord = aTexCoor;//将接收的纹理坐标传递给片元着色器  
  27. }  
xy双向飘扬shader

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  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.   
  16.    //计算Y向波浪  
  17.    float angleSpanZ=4.0*3.14159265;//纵向角度总跨度  
  18.    float uHeightSpan=0.75*uWidthSpan;//纵向长度总跨度  
  19.    float startY=-uHeightSpan/2.0;//起始Y坐标  
  20.    //根据纵向角度总跨度、纵向长度总跨度及当前点Y坐标折算出当前点Y坐标对应的角度  
  21.    float currAngleZ=uStartAngle+3.14159265/3.0+((aPosition.y-startY)/uHeightSpan)*angleSpanZ;  
  22.    float tzZ=sin(currAngleZ)*0.1;  
  23.   
  24.    //根据总变换矩阵计算此次绘制此顶点位置  
  25.    gl_Position = uMVPMatrix * vec4(aPosition.x,aPosition.y,tzH+tzZ,1);  
  26.    vTextureCoord = aTexCoor;//将接收的纹理坐标传递给片元着色器  
  27. }  

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

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


完整代码下载地址

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


0 0
原创粉丝点击