对openGL早有耳闻,但是刚接触android下的opengl,做个demo学习下,
先把opengl的框架搭建起来:只要有如下几个文件,
openActivity.java ----作为启动入口,android通过GLSurfaceView显示openGL试图,而GLSurfaceView提供了专门渲染3D的Renderer接口
GLRender.java ----渲染图形
GLImage.java ----获取资源文件
GLRender.java 实现Renderer接口:只要实现如下方法:
public void onDrawFrame(GL10 gl); //进行图形的绘制
public void onSurfaceChanged(GL10 gl, int width, int height);
public void onSurfaceCreated(GL10 gl, EGLConfig config);
GLRender.java 代码如下:
package com.aurora.android.render;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.Random;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import com.aurora.android.model.GLImage;
import com.aurora.android.model.Star;
import android.opengl.GLUtils;
import android.opengl.GLSurfaceView.Renderer;
import android.view.KeyEvent;
public class GLRender implements Renderer {
public static final int num = 50;
public Star[] star = new Star[num];
Random random = new Random();
boolean key;
boolean twinkle = true;
float spin;
float zoom = -10.0f;
float tilt = 90.0f;
int texture;
int one = 0x10000;
//纹理数据
IntBuffer coords = IntBuffer.wrap(new int[] {
0, 0,
one, 0,
one, one,
0,one });
IntBuffer vertexs = IntBuffer.wrap(new int[] {
-one, -one, 0,
one, -one, 0,
one, one, 0,
-one, one, 0 });
ByteBuffer indices = ByteBuffer.wrap(new byte[] {
1, 0, 2, 3
});
@Override
public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);//绑定纹理
for (int i = 0; i < num; i++) {
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 0.0f, zoom);
gl.glRotatef(tilt, 1.0f, 0.0f, 0.0f);
gl.glRotatef(star[i].angle, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(star[i].dist, 0.0f, 0.0f);
gl.glRotatef(-star[i].angle, 0.0f, 1.0f, 0.0f);
gl.glRotatef(-tilt, 1.0f, 0.0f, 0.0f);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//启用顶点
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);//启用着色
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);//启用纹理
if (twinkle) {//启用星星闪烁效果
//使用byte型数值指定一颜色
gl.glColor4f((float) star[(num - i) - 1].r / 255.0f,
(float) star[(num - i) - 1].g / 255.0f,
(float) star[(num - i) - 1].b / 255.0f, 1.0f);
gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertexs);
gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, coords);
{
coords.position(0);
vertexs.position(0);
indices.position(0);
//绘图
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4,
GL10.GL_UNSIGNED_BYTE, indices);
}
//闪烁星星绘制完成
gl.glFinish();
}
//绕z轴旋转
gl.glRotatef(spin, 0.0f, 0.0f, 1.0f);
gl.glColor4f((float) star[(num - i) - 1].r / 255.0f,
(float) star[(num - i) - 1].g / 255.0f,
(float) star[(num - i) - 1].b / 255.0f, 1.0f);
gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertexs);
gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, coords);
{
coords.position(0);
vertexs.position(0);
indices.position(0);
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4,
GL10.GL_UNSIGNED_BYTE, indices);
}
gl.glFinish();
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
spin += 0.01f;
star[i].angle += (float) (i) / (float) num;
star[i].dist -= 0.01f;
if (star[i].dist < 0.0f) {
star[i].dist += 5.0f;
star[i].r = random.nextInt(256);
star[i].g = random.nextInt(256);
star[i].b = random.nextInt(256);
}
}
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
float ratio = (float) width / height;
gl.glViewport(0, 0, width, height);// 设置场景大小
gl.glMatrixMode(GL10.GL_PROJECTION);// 设置投影矩阵
gl.glLoadIdentity();
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);// 设置视口大小
gl.glMatrixMode(GL10.GL_MODELVIEW);// 设置观察模式
gl.glLoadIdentity();
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
gl.glShadeModel(GL10.GL_SMOOTH);// 启用平滑
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);// 设置黑背景
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);// 精细的透视修正
IntBuffer intBuffer = IntBuffer.allocate(1);
gl.glGenTextures(1, intBuffer);
texture = intBuffer.get();
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
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);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap, 0);
gl.glEnable(GL10.GL_TEXTURE_2D);// 设置纹理
gl.glShadeModel(GL10.GL_SMOOTH);// 启用平滑
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);// 设置黑背景
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);// 精细的透视修正
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);// 设置混合函数取半透明
gl.glEnable(GL10.GL_BLEND);// 设置混色
for (int i = 0; i < num; i++) {
Star starTemp = new Star();
starTemp.angle = 0.0f;
starTemp.dist = ((float) (i) / (float) num) * 5.0f;
starTemp.r = random.nextInt(256);
starTemp.g = random.nextInt(256);
starTemp.b = random.nextInt(256);
star[i] = starTemp;
}
}
public boolean onKeyUp(int keyCode, KeyEvent event) {
twinkle = !twinkle;
return false;
}
}
openActivity.java代码如下:
package com.aurora.android.advanced;
import com.aurora.android.model.GLImage;
import com.aurora.android.render.GLRender;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.KeyEvent;
public class OpenActivity extends Activity {
GLRender render = new GLRender();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GLImage.load(this.getResources());
GLSurfaceView glView = new GLSurfaceView(this);
glView.setRenderer(render);
setContentView(glView);
}
public boolean onKeyUp(int keyCode, KeyEvent event){
render.onKeyUp(keyCode, event);
return false;
}
}
GLImage.java:
package com.aurora.android.model;
import com.aurora.android.advanced.R;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class GLImage {
public static Bitmap mBitmap;
public static void load(Resources resource){
//获取图片资源
mBitmap = BitmapFactory.decodeResource(resource, R.drawable.star);
}
}
Star.java:星星
package com.aurora.android.model;
public class Star {
public int r,g,b; //星星RGB颜色
public float dist;//星星距离中心的距离
public float angle = 0.0f; //当前星星处的角度
}