越来越感到知识相关性的重要性,光会一点编程,是远远不够的。数学,物理,和计算机是不可分割兄弟。
(1)Activity类
package sim.feel;
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Bundle;
public class FlagActivity extends Activity {
/** Called when the activity is first created. */
GLSurfaceView glSurfaceView;
Renderer renderer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LoadImage.load(getResources());
renderer = new MyRenderer();
glSurfaceView = new GLSurfaceView(this);
glSurfaceView.setRenderer(renderer);
setContentView(glSurfaceView);
}
}
//载入图片
class LoadImage {
public static Bitmap bitmap;
public static void load(Resources res) {
bitmap = BitmapFactory.decodeResource(res, R.drawable.img);
}
}
(2)Renderer类
package sim.feel;
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.GLSurfaceView.Renderer;
import android.opengl.GLUtils;
public class MyRenderer implements Renderer {
// Points 网格顶点数组(45,45,3)
float vertex[][][] = new float[45][45][3];
// 指定旗形波浪的运动速度
int wiggle_count = 0;
// 临时变量
float hold;
// x,y,z转角
float xrot, yrot, zrot;
// vertex
private float[] texVertex = new float[12];
// vetexBuffer
private FloatBuffer vertexBuffer;
// coord
private float[] coord = new float[8];
// coordBuffer
private FloatBuffer coordBuffer;
// textures
private int[] textures = new int[1];
// init()
public void init() {
ByteBuffer texByteBuffer = ByteBuffer
.allocateDirect(texVertex.length * 4);
texByteBuffer.order(ByteOrder.nativeOrder());
vertexBuffer = texByteBuffer.asFloatBuffer();
vertexBuffer.put(texVertex);
vertexBuffer.position(0);
ByteBuffer coordByteBuffer = ByteBuffer
.allocateDirect(coord.length * 4);
coordByteBuffer.order(ByteOrder.nativeOrder());
coordBuffer = coordByteBuffer.asFloatBuffer();
coordBuffer.put(coord);
coordBuffer.position(0);
}
@Override
public void onDrawFrame(GL10 gl) {
init();
int x, y; // 循环变量
float _x, _y, _xb, _yb; // 用来将旗形的波浪分割成很小的四边形
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_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, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, coordBuffer);
for (x = 0; x < 44; x++) {
for (y = 0; y < 44; y++) {
_x = (float) (x) / 44.0f; // 生成X浮点值
_y = (float) (y) / 44.0f; // 生成Y浮点值
_xb = (float) (x + 1) / 44.0f; // X浮点值+0.0227f
_yb = (float) (y + 1) / 44.0f; // Y浮点值+0.0227f
coordBuffer.clear();
// bottom left
coordBuffer.put(_x);
coordBuffer.put(_y);
// bottom right
coordBuffer.put(_x);
coordBuffer.put(_yb);
// top right
coordBuffer.put(_xb);
coordBuffer.put(_yb);
// top left
coordBuffer.put(_xb);
coordBuffer.put(_y);
vertexBuffer.clear();
// bottom left
vertexBuffer.put(vertex[x][y][0]);
vertexBuffer.put(vertex[x][y][1]);
vertexBuffer.put(vertex[x][y][2]);
// bottom right
vertexBuffer.put(vertex[x][y + 1][0]);
vertexBuffer.put(vertex[x][y + 1][1]);
vertexBuffer.put(vertex[x][y + 1][2]);
// top right
vertexBuffer.put(vertex[x + 1][y + 1][0]);
vertexBuffer.put(vertex[x + 1][y + 1][1]);
vertexBuffer.put(vertex[x + 1][y + 1][2]);
// top left
vertexBuffer.put(vertex[x + 1][y][0]);
vertexBuffer.put(vertex[x + 1][y][1]);
vertexBuffer.put(vertex[x + 1][y][2]);
gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 4);
}
}
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
if (wiggle_count == 2) { // 用来降低波浪速度(每隔2帧一次)
for (int j = 0; j < 45; j++) {
hold = vertex[0][j][2]; // 存储当前左侧波浪值
for (int i = 0; i < 44; i++) {
// 当前波浪值等于其右侧的波浪值
vertex[i][j][2] = vertex[i + 1][j][2];
}
vertex[44][j][2] = hold;
}
wiggle_count=0;
}
wiggle_count++;
xrot += 0.3f; // X 轴旋转
yrot += 0.2f; // Y 轴旋转
zrot += 0.4f; // Z 轴旋转
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
float ratio = (float) width / (float) height;
// 设置OpenGL场景的大小
gl.glViewport(0, 0, width, height);
// 设置投影矩阵
gl.glMatrixMode(GL10.GL_PROJECTION);
// 重置投影矩阵
gl.glLoadIdentity();
// 设置视口的大小
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 15);
// 选择模型观察矩阵
gl.glMatrixMode(GL10.GL_MODELVIEW);
// 重置模型观察矩阵
gl.glLoadIdentity();
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// 黑色背景
gl.glClearColor(0, 0, 0, 0);
// 启用阴影平滑
gl.glShadeModel(GL10.GL_SMOOTH);
// 启用深度测试
gl.glEnable(GL10.GL_DEPTH_TEST);
// 启用纹理映射
gl.glClearDepthf(1.0f);
// 深度测试的类型
gl.glDepthFunc(GL10.GL_LEQUAL);
// 精细的透视修正
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
// 允许2D贴图,纹理
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnable(GL10.GL_LEQUAL);
// 创建纹理
gl.glGenTextures(1, textures, 0);
// 设置要使用的纹理
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// 生成纹理
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, LoadImage.bitmap, 0);
// 线形滤波
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
GL10.GL_LINEAR);
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
GL10.GL_LINEAR);
//NEW
// 沿X平面循环
for (int x = 0; x < 45; x++) {
// 沿Y平面循环
for (int y = 0; y < 45; y++) {
// 向表面添加波浪效果
// -4.5f~4.5f
vertex[x][y][0] = ((float) x / 5.0f) - 4.5f;
vertex[x][y][1] = (((float) y / 5.0f) - 4.5f);
// 0-2*pai
vertex[x][y][2] = (float) (Math
.sin(((((float) x / 5.0f) * 40.0f) / 360.0f) * 3.141592654 * 2.0f));
}
}
}
}
效果如下: