opengles特效之飘扬的旗帜
来源:互联网 发布:js随机动态显示 编辑:程序博客网 时间:2024/05/02 04:56
效果图
核心代码 主要看shader中的实现
x方向飘扬shader
uniform mat4 uMVPMatrix; //总变换矩阵uniform float uStartAngle;//本帧起始角度uniform float uWidthSpan;//横向长度总跨度attribute vec3 aPosition; //顶点位置attribute vec2 aTexCoor; //顶点纹理坐标varying vec2 vTextureCoord; //用于传递给片元着色器的变量void main(){ //计算X向波浪 float angleSpanH=4.0*3.14159265;//横向角度总跨度 float startX=-uWidthSpan/2.0;//起始X坐标 //根据横向角度总跨度、横向长度总跨度及当前点X坐标折算出当前点X坐标对应的角度 float currAngle=uStartAngle+((aPosition.x-startX)/uWidthSpan)*angleSpanH; float tz=sin(currAngle)*0.1; //根据总变换矩阵计算此次绘制此顶点位置 gl_Position = uMVPMatrix * vec4(aPosition.x,aPosition.y,tz,1); // gl_Position = uMVPMatrix * vec4(aPosition.x,tz,aPosition.y,1); vTextureCoord = aTexCoor;//将接收的纹理坐标传递给片元着色器}
斜向飘扬shader
uniform mat4 uMVPMatrix; //总变换矩阵uniform float uStartAngle;//本帧起始角度uniform float uWidthSpan;//横向长度总跨度attribute vec3 aPosition; //顶点位置attribute vec2 aTexCoor; //顶点纹理坐标varying vec2 vTextureCoord; //用于传递给片元着色器的变量void main(){ //计算X向角度 float angleSpanH=4.0*3.14159265;//横向角度总跨度 float startX=-uWidthSpan/2.0;//起始X坐标 //根据横向角度总跨度、横向长度总跨度及当前点X坐标折算出当前点X坐标对应的角度 float currAngleH=uStartAngle+((aPosition.x-startX)/uWidthSpan)*angleSpanH; //计算出随Y向发展起始角度的扰动值 float angleSpanZ=4.0*3.14159265;//纵向角度总跨度 float uHeightSpan=0.75*uWidthSpan;//纵向长度总跨度 float startY=-uHeightSpan/2.0;//起始Y坐标 //根据纵向角度总跨度、纵向长度总跨度及当前点Y坐标折算出当前点Y坐标对应的角度 float currAngleZ=((aPosition.y-startY)/uHeightSpan)*angleSpanZ; //计算斜向波浪 float tzH=sin(currAngleH-currAngleZ)*0.1; //根据总变换矩阵计算此次绘制此顶点位置 gl_Position = uMVPMatrix * vec4(aPosition.x,aPosition.y,tzH,1); vTextureCoord = aTexCoor;//将接收的纹理坐标传递给片元着色器}xy双向飘扬shader
uniform mat4 uMVPMatrix; //总变换矩阵uniform float uStartAngle;//本帧起始角度uniform float uWidthSpan;//横向长度总跨度attribute vec3 aPosition; //顶点位置attribute vec2 aTexCoor; //顶点纹理坐标varying vec2 vTextureCoord; //用于传递给片元着色器的变量void main(){ //计算X向波浪 float angleSpanH=4.0*3.14159265;//横向角度总跨度 float startX=-uWidthSpan/2.0;//起始X坐标 //根据横向角度总跨度、横向长度总跨度及当前点X坐标折算出当前点X坐标对应的角度 float currAngleH=uStartAngle+((aPosition.x-startX)/uWidthSpan)*angleSpanH; float tzH=sin(currAngleH)*0.1; //计算Y向波浪 float angleSpanZ=4.0*3.14159265;//纵向角度总跨度 float uHeightSpan=0.75*uWidthSpan;//纵向长度总跨度 float startY=-uHeightSpan/2.0;//起始Y坐标 //根据纵向角度总跨度、纵向长度总跨度及当前点Y坐标折算出当前点Y坐标对应的角度 float currAngleZ=uStartAngle+3.14159265/3.0+((aPosition.y-startY)/uHeightSpan)*angleSpanZ; float tzZ=sin(currAngleZ)*0.1; //根据总变换矩阵计算此次绘制此顶点位置 gl_Position = uMVPMatrix * vec4(aPosition.x,aPosition.y,tzH+tzZ,1); vTextureCoord = aTexCoor;//将接收的纹理坐标传递给片元着色器}
同时需要启动一个线程不断修改当前帧起始角度
package test.com.opengles_1_1;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import android.annotation.SuppressLint;import android.opengl.GLES20;/** * Created by hbin on 2016/11/1. * 有波浪效果的纹理矩形 */public class TextureRect { int[] mPrograms=new int[3];//自定义渲染管线着色器程序id int[] muMVPMatrixHandle=new int[3];//总变换矩阵引用 int[] maPositionHandle=new int[3]; //顶点位置属性引用 int[] maTexCoorHandle=new int[3]; //顶点纹理坐标属性引用 int[] maStartAngleHandle=new int[3]; //本帧起始角度属性引用 int[] muWidthSpanHandle=new int[3];//横向长度总跨度引用 int currIndex=0;//当前着色器索引 FloatBuffer mVertexBuffer;//顶点坐标数据缓冲 FloatBuffer mTexCoorBuffer;//顶点纹理坐标数据缓冲 int vCount=0; final float WIDTH_SPAN=3.3f;//2.8f;//横向长度总跨度 float currStartAngle=0;//当前帧的起始角度0~2PI public TextureRect(MySurfaceView mv) { //初始化顶点坐标与着色数据 initVertexData(); //初始化shader initShader(mv,0,"vertex_tex_x.sh"); initShader(mv,1,"vertex_tex_xie.sh"); initShader(mv,2,"vertex_tex_xy.sh"); //启动一个线程定时换帧 new Thread() { public void run() { while(Constant.threadFlag) { currStartAngle+=(float) (Math.PI/16); try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } private void initVertexData() { final int cols=12;//列数 final int rows=cols*3/4;//行数 final float UNIT_SIZE=WIDTH_SPAN/cols;//每格的单位长度 vCount=cols*rows*6;//每个格子两个三角形,每个三角形3个顶点 float vertices[]=new float[vCount*3];//每个顶点xyz三个坐标 int count=0; for (int j=0;j<rows;j++){ for (int i=0;i<cols;i++){ float zsx=-UNIT_SIZE*cols/2+i*UNIT_SIZE; float zsy=UNIT_SIZE*rows/2-j*UNIT_SIZE; float zsz=0; vertices[count++]=zsx; vertices[count++]=zsy; vertices[count++]=zsz; vertices[count++]=zsx; vertices[count++]=zsy-UNIT_SIZE; vertices[count++]=zsz; vertices[count++]=zsx+UNIT_SIZE; vertices[count++]=zsy; vertices[count++]=zsz; vertices[count++]=zsx+UNIT_SIZE; vertices[count++]=zsy; vertices[count++]=zsz; vertices[count++]=zsx; vertices[count++]=zsy-UNIT_SIZE; vertices[count++]=zsz; vertices[count++]=zsx+UNIT_SIZE; vertices[count++]=zsy-UNIT_SIZE; vertices[count++]=zsz; } } //创建顶点坐标数据缓冲 //vertices.length*4是因为一个整数四个字节 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4); vbb.order(ByteOrder.nativeOrder());//设置字节顺序 mVertexBuffer = vbb.asFloatBuffer();//转换为Float型缓冲 mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据 mVertexBuffer.position(0);//设置缓冲区起始位置 //顶点纹理坐标数据的初始化================begin============================ float texCoor[]=generateTexCoor(cols,rows); //创建顶点纹理坐标数据缓冲 ByteBuffer cbb = ByteBuffer.allocateDirect(texCoor.length*4); cbb.order(ByteOrder.nativeOrder());//设置字节顺序 mTexCoorBuffer = cbb.asFloatBuffer();//转换为Float型缓冲 mTexCoorBuffer.put(texCoor);//向缓冲区中放入顶点着色数据 mTexCoorBuffer.position(0);//设置缓冲区起始位置 } public void initShader(MySurfaceView mv,int index,String vertexName) { //加载顶点着色器的脚本内容 String mVertexShader=ShaderUtil.loadFromAssetsFile(vertexName, mv.getResources()); //加载片元着色器的脚本内容 String mFragmentShader=ShaderUtil.loadFromAssetsFile("frag_tex.sh", mv.getResources()); //基于顶点着色器与片元着色器创建程序 mPrograms[index] = ShaderUtil.createProgram(mVertexShader, mFragmentShader); //获取程序中顶点位置属性引用 maPositionHandle[index] = GLES20.glGetAttribLocation(mPrograms[index], "aPosition"); //获取程序中顶点纹理坐标属性引用 maTexCoorHandle[index]= GLES20.glGetAttribLocation(mPrograms[index], "aTexCoor"); //获取程序中总变换矩阵引用 muMVPMatrixHandle[index] = GLES20.glGetUniformLocation(mPrograms[index], "uMVPMatrix"); //获取本帧起始角度属性引用 maStartAngleHandle[index]=GLES20.glGetUniformLocation(mPrograms[index], "uStartAngle"); //获取横向长度总跨度引用 muWidthSpanHandle[index]=GLES20.glGetUniformLocation(mPrograms[index], "uWidthSpan"); } public void drawSelf(int texId) { //制定使用某套shader程序 GLES20.glUseProgram(mPrograms[currIndex]); //将最终变换矩阵传入shader程序 GLES20.glUniformMatrix4fv(muMVPMatrixHandle[currIndex], 1, false, MatrixState.getFinalMatrix(), 0); //将本帧起始角度传入shader程序 GLES20.glUniform1f(maStartAngleHandle[currIndex], currStartAngle); //将横向长度总跨度传入shader程序 GLES20.glUniform1f(muWidthSpanHandle[currIndex], WIDTH_SPAN); //将顶点位置数据传入渲染管线 GLES20.glVertexAttribPointer ( maPositionHandle[currIndex], 3, GLES20.GL_FLOAT, false, 3*4, mVertexBuffer ); //将顶点纹理坐标数据传入渲染管线 GLES20.glVertexAttribPointer ( maTexCoorHandle[currIndex], 2, GLES20.GL_FLOAT, false, 2*4, mTexCoorBuffer ); //启用顶点位置、纹理坐标数据 GLES20.glEnableVertexAttribArray(maPositionHandle[currIndex]); GLES20.glEnableVertexAttribArray(maTexCoorHandle[currIndex]); //绑定纹理 GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId); GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount); } //自动切分纹理产生纹理数组的方法 public float[] generateTexCoor(int bw,int bn) { float[] result=new float[bw*bn*6*2]; float sizew=1.0f/bw;//列数 float sizeh=0.75f/bn;//行数 int c=0; for(int i=0;i<bn;i++) { for(int j=0;j<bw;j++) { //每行列一个矩形,由两个三角形构成,共六个点,12个纹理坐标 float s=j*sizew; float t=i*sizeh; //第一个纹理三角形 result[c++]=s; result[c++]=t; result[c++]=s; result[c++]=t+sizeh; result[c++]=s+sizew; result[c++]=t; //第二个纹理三角形 result[c++]=s+sizew; result[c++]=t; result[c++]=s; result[c++]=t+sizeh; result[c++]=s+sizew; result[c++]=t+sizeh; } } return result; }}
完整代码下载地址
http://download.csdn.net/detail/hb707934728/9670345
0 0
- opengles特效之飘扬的旗帜
- opengles特效之飘扬的旗帜
- 愿自由开放的旗帜高高飘扬
- 普通的日子里哪儿有旗帜飘扬?
- 响铃:飘扬在德国的海尔旗帜是中国制造的世纪跨越
- android drawBitmapMesh()图片旗帜飘扬效果
- /LGC图形渲染/旗帜(waving texture)特效的实现
- 飘扬的五星红旗
- opengles膨胀吹气特效
- Android图像处理(五)镜像、倒影、drawBitmapMesh实现旗帜飘扬效果
- 父辈的旗帜
- iOS --- OpenGLES之简单的图形绘制
- opengles之展翅飞翔的雄鹰
- 线程同步之信号量("旗帜"就是方向,"旗帜"就是形象, "旗帜"就是指挥棒)
- oepngl飘动的旗帜(正弦)
- OpenGL -- 飘动的旗帜 (java)
- OpenGL -- 飘动的旗帜 (java)
- 随风飘扬的一颗种子
- Unity 异步加载场景
- Sublime Text 3安装指引
- MVN仓库调整优化jar包下载速度
- POI对Excel操作——java读取Excel数据
- 泡排冒序
- opengles特效之飘扬的旗帜
- 使用JS跳转时如何控制Target属性
- 百度云搭建服务器-----外网不能访问服务器
- 第九周OJ项目-大奖赛计分
- String 、StringBuilder、StringBuffer的区别 hr
- [leetcode]24. Swap Nodes in Pairs
- 【详解KMP算法 next数组详解】
- struts.xml文件中package元素的各大属性讲解
- Android加载大图片,实现简单的截屏功能与保存截屏显示在图库