本文讲述使用GLSurfaceView创建一个3D旋转的图形
代码1:OpenGLESActivity.java
public class OpenGLESActivity extends AppCompatActivity {
private GLSurfaceView glSurfaceView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 如果本设备支持OpenGl ES 2.0
if (IsSupported()) {
// 先建GLSurfaceView实例
glSurfaceView = new GLSurfaceView(this);
// 创建渲染器实例
MyRenderer mRenderer = new MyRenderer();
// 设置渲染器
glSurfaceView.setRenderer(mRenderer);
// 显示SurfaceView
setContentView(glSurfaceView);
}else{
Toast.makeText(OpenGLESActivity.this,"此设备不支持OpenGL ES 2.0!",Toast.LENGTH_LONG).show();
}
}
/**
* 当前设备是否支持OpenGL ES 2.0
* */
private boolean IsSupported() {
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
boolean supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000
||(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1 && (Build.FINGERPRINT.startsWith("generic")
|| Build.FINGERPRINT.startsWith("unknown")
|| Build.MODEL.contains("google_sdk")
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86")));
return supportsEs2;
}
/**
* GLSurfaceView.Renderer实现类
* */
public class MyRenderer implements GLSurfaceView.Renderer {
/**
* 1.定义立方体的8个顶点
* */
float[] cubeVertices = {
//左面
-0.5f,0.5f,0.5f,
-0.5f,-0.5f,0.5f,
-0.5f,0.5f,-0.5f,
-0.5f,-0.5f,-0.5f,
//右面
0.5f, 0.5f,0.5f,
0.5f,-0.5f,0.5f,
0.5f,-0.5f,-0.5f,
0.5f,0.5f,-0.5f ,
//前面
-0.5f,0.5f,0.5f,
-0.5f,-0.5f,0.5f,
0.5f,-0.5f,0.5f,
0.5f, 0.5f,0.5f,
//后面
0.5f,-0.5f,-0.5f,
0.5f,0.5f,-0.5f,
-0.5f,0.5f,-0.5f,
-0.5f,-0.5f,-0.5f,
//上面
-0.5f,0.5f,0.5f,
0.5f, 0.5f,0.5f,
0.5f,0.5f,-0.5f,
-0.5f,0.5f,-0.5f,
//下面
-0.5f,-0.5f,0.5f,
0.5f,-0.5f,0.5f,
0.5f,-0.5f,-0.5f,
-0.5f,-0.5f,-0.5f
};
/**
* 2.各个位置对应的颜色数组
* */
float [] cubeColors = {
1f,0f,0f,1f ,
0f,1f,0f,1f,
0f,0f,1f,1f,
1f,0f,0f,1f,
1f,0f,0f,1f ,
0f,1f,0f,1f,
0f,0f,1f,1f,
1f,0f,0f,1f,
1f,0f,0f,1f ,
0f,1f,0f,1f,
0f,0f,1f,1f,
1f,0f,0f,1f,
1f,0f,0f,1f ,
0f,1f,0f,1f,
0f,0f,1f,1f,
1f,0f,0f,1f,
1f,0f,0f,1f ,
0f,1f,0f,1f,
0f,0f,1f,1f,
1f,0f,0f,1f,
1f,0f,0f,1f ,
0f,1f,0f,1f,
0f,0f,1f,1f,
1f,0f,0f,1f,
};
/**
* 索引数组
* */
private short[] indices={
0,1,2,
0,2,3,
4,5,6,
4,6,7,
8,9,10,
8,10,11,
12,13,14,
12,14,15,
16,17,18,
16,18,19,
20,21,22,
20,22,23,
};
private float rotate;// 控制旋转的角度
private FloatBuffer VerticesBuffer;//浮点形缓冲数据
private FloatBuffer Colorbuffer;//浮点型颜色数据
private ShortBuffer indexbuffer;//浮点型索引数据
public MyRenderer() {
//获取浮点形缓冲数据
VerticesBuffer = Utils.getFloatBuffer(cubeVertices);
//获取浮点型颜色数据
Colorbuffer= Utils.getFloatBuffer(cubeColors);
//获取浮点型索引数据
indexbuffer= Utils.getShortBuffer(indices);
}
/**
* onSurfaceCreated方法 Surface创建的时候调用
* */
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0, 0, 0, 0);
}
/**
* onSurfaceChanged方法 Surface改变的的时候调用
* */
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// 设置3D视窗的大小及位置
gl.glViewport(0, 0, width, height);
}
/**
* onDrawFrame方法 在Surface上绘制的时候调用
* */
@Override
public void onDrawFrame(GL10 gl) {
// 清除屏幕缓存和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// 启用顶点座标数据
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// 启用顶点颜色数据
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// 重置当前的模型视图矩阵
gl.glLoadIdentity();
// 沿着Y轴旋转
gl.glRotatef(rotate, 0f, 1f, 0f);
// 设置顶点的位置数据
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, VerticesBuffer);
// 设置顶点的颜色数据
gl.glColorPointer(4, GL10.GL_FLOAT, 0, Colorbuffer);
//绘制三角形
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indexbuffer);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
// 旋转角度增加1
rotate-=1;
}
}
/**
* onPause方法 glSurfaceView.onPause
* */
@Override
protected void onPause() {
super.onPause();
if (glSurfaceView != null) {
glSurfaceView.onPause();
}
}
/**
* onResume方法 glSurfaceView.onResume
* */
@Override
protected void onResume() {
super.onResume();
if (glSurfaceView != null) {
glSurfaceView.onResume();
}
}
}
代码2:Utils.java
public class Utils {
/**
* 获取浮点形缓冲数据 float 数组
*/
public static FloatBuffer getFloatBuffer(float[] vertexs) {
FloatBuffer buffer;
ByteBuffer qbb = ByteBuffer.allocateDirect(vertexs.length * 4);
qbb.order(ByteOrder.nativeOrder());
buffer = qbb.asFloatBuffer();
buffer.put(vertexs);
buffer.position(0);
return buffer;
}
/**
* 获取字节型缓冲数据 Byte 数组
*/
public static ShortBuffer getShortBuffer(short[] vertexs) {
ShortBuffer buffer;
ByteBuffer qbb = ByteBuffer.allocateDirect(vertexs.length * 2);
qbb.order(ByteOrder.nativeOrder());
buffer = qbb.asShortBuffer();
buffer.put(vertexs);
buffer.position(0);
return buffer;
}
}
运行结果: