Android实现飘动的旗帜效果实例

来源:互联网 发布:vb程序设计基础答案 编辑:程序博客网 时间:2024/05/02 00:40


做一个飘动的旗帜效果,思路大概为:将旗形的波浪分割成很小的四边形,然后多少时间进行刷新,Z方向上运用sin函数改变,看起来有飘动的感觉


实例代码如下:

1、准备图片资源 : initBitmap类

import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.BitmapFactory;public class initBitmap {    public static Bitmap bitmap;        public static void init(Resources res){        bitmap = BitmapFactory.decodeResource(res, R.drawable.flag) ; //图片    }}

2、Activity类


import android.app.Activity;import android.opengl.GLSurfaceView;import android.os.Bundle;public class FlagOpenGLActivity extends Activity {    GLSurfaceView glView;    FlagRender flagRender = new FlagRender();    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);                initBitmap.init(this.getResources());                glView = new GLSurfaceView(this);        glView.setRenderer(flagRender);                setContentView(glView);    }}

3、渲染类

import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.opengl.GLUtils;import android.opengl.GLSurfaceView.Renderer;public class FlagRender implements Renderer {/** * 制作飘动的旗帜效果 */private float[] texVertices = new float[12];FloatBuffer texBuffer;private float[] coord = new float[8];FloatBuffer coordBuffer;private int[] textures = new int[1];float vertex[][][] = new float[45][45][3];// 网格顶点数组int wiggle_count = 0; // 指定旗型波浪的运行速度float hold; // 临时变量float xrot, yrot, zrot; // 各轴旋转/** * 初始化缓冲数据 */public void init() {ByteBuffer bb = ByteBuffer.allocateDirect(texVertices.length * 4);bb.order(ByteOrder.nativeOrder());texBuffer = bb.asFloatBuffer();texBuffer.put(texVertices);texBuffer.position(0);//ByteBuffer coordbb = ByteBuffer.allocateDirect(coord.length * 4);coordbb.order(ByteOrder.nativeOrder());coordBuffer = coordbb.asFloatBuffer();coordBuffer.put(coord);coordBuffer.position(0);}@Overridepublic void onDrawFrame(GL10 gl) {init();// 初始化int x, y;float f_x, f_y, f_xb, f_yb; // 用来将旗形的波浪分割成很小的四边形//gl.glClear(GL10.GL_DEPTH_BUFFER_BIT | GL10.GL_COLOR_BUFFER_BIT);gl.glLoadIdentity();//gl.glTranslatef(0.0f, 0.0f, -12.0f);// 往里缩12单位gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);// 绕X轴旋转gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);// 绕Y轴旋转gl.glRotatef(zrot, 0.0f, 0.0f, 1.0f);// 绕Z轴旋转//gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);//gl.glVertexPointer(3, GL10.GL_FLOAT, 0, texBuffer);gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, coordBuffer);// gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);// 四边形绘制开始for (x = 0; x < 44; x++) {for (y = 0; y < 44; y++) {f_x = (float) x / 44.0f; // 生成X的浮点数f_y = (float) y / 44.0f;// 生成Y的浮点数f_xb = (float) (x + 1) / 44.0f; // X浮点值+0.0227ff_yb = (float) (y + 1) / 44.0f;// Y浮点值+0.0227f//coordBuffer.clear();// 左下角coordBuffer.put(f_x);coordBuffer.put(f_y);// 左上角coordBuffer.put(f_x);coordBuffer.put(f_yb);// 右上角coordBuffer.put(f_xb);coordBuffer.put(f_yb);// 右下角coordBuffer.put(f_xb);coordBuffer.put(f_y);//// 左下角texBuffer.clear();texBuffer.put(vertex[x][y][0]);texBuffer.put(vertex[x][y][1]);texBuffer.put(vertex[x][y][2]);// 左上角texBuffer.put(vertex[x][y + 1][0]);texBuffer.put(vertex[x][y + 1][1]);texBuffer.put(vertex[x][y + 1][2]);// 右上角texBuffer.put(vertex[x + 1][y + 1][0]);texBuffer.put(vertex[x + 1][y + 1][1]);texBuffer.put(vertex[x + 1][y + 1][2]);// 右下角texBuffer.put(vertex[x + 1][y][0]);texBuffer.put(vertex[x + 1][y][1]);texBuffer.put(vertex[x + 1][y][2]);//注意:如果设为GL10.GL_TRIANGLE_STRIP模式的话,会产生黑点点,不好看gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 4);}}gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);/** * 每绘制两次场景,循环一次sin值,以产生运动效果。 用来降低波浪速度(每隔2帧一次) */if (wiggle_count == 2) { // 沿着Y 平面循环for (y = 0; y < 45; y++) {hold = vertex[0][y][2];for (x = 0; x < 44; x++) {// 当前波浪值等于其右侧的波浪值vertex[x][y][2] = vertex[x + 1][y][2]; //}vertex[44][y][2] = hold; // 刚才的值成为最左侧的波浪值}wiggle_count = 0;// 清零}wiggle_count++;// 加一xrot += 0.3f;yrot += 0.2f;zrot += 0.4f;}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {gl.glViewport(0, 0, width, height);float ratio = (float) width / height;gl.glMatrixMode(GL10.GL_PROJECTION);gl.glLoadIdentity();gl.glFrustumf(-ratio, ratio, -1, 1, 1, 15);// 设置观察模型gl.glMatrixMode(GL10.GL_MODELVIEW);gl.glLoadIdentity();}@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);// 黑色背景色gl.glClearColorx(0, 0, 0, 0);// 启用阴影平滑gl.glShadeModel(GL10.GL_SMOOTH);// 启用深度测试gl.glEnable(GL10.GL_DEPTH_TEST);// 深度测试类型gl.glDepthFunc(GL10.GL_LEQUAL);// 设置深度缓存gl.glClearDepthf(1.0f);// 启用纹理gl.glEnable(GL10.GL_TEXTURE_2D);// 生成纹理 gl.glGenTextures(1, textures, 0);// 绑定纹理 gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, initBitmap.bitmap, 0);//线性滤波gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR);/** *  */// 沿X平面循环for (int x = 0; x < 45; x++) {// 沿Y平面循环for (int y = 0; y < 45; y++) {// 向表面添加波浪效果vertex[x][y][0] = (float) ((x / 5.0f) - 4.5f);vertex[x][y][1] = (float) ((y / 5.0f) - 4.5f);// 2 *pai* r 角度vertex[x][y][2] = (float) (Math.sin(((((float) x / 5.0f) * 40.0f) / 360.0f) * 3.141592654 * 2.0f));}}}}

4、运行效果:


原创粉丝点击