
OpenGL(Open Graphics Library)是用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口(API),它由数百个不同的函数调用组成,用来呈现复杂的三维景象。下面这个实例演示了使用OpenGL在Android手机场景中绘制五角星。
实例功能
此实例主要通过使用GLSurfaceView控件加载自定义OpenGL渲染器Renderer,并在该Renderer中设置glDrawArrays()方法的参数值为GL10.GL_LINE_LOOP,实现在场景中绘制五角星。OpenGL(Open Graphics Library)是用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口(API),它由数百个不同的函数调用组成,用来呈现复杂的三维景象。
当该实例运行之后,单击“绘制五角星”按钮,在场景中绘制的五角星效果分别如图1(a)和图1(b)所示。在Android中,通常使用android.opengl.GLSurfaceView控件承载OpenGL的内容。

■ 图1
实现代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.bin.luo.mysample.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="onClickButton1"
android:text="绘制五角星"
android:textAllCaps="false"
android:textSize="16dp" />
</LinearLayout>
<android.opengl.GLSurfaceView
android:id="@+id/myGLSurfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
代码说明
上面这段代码在MyCode\MySampleO61\app\src\main\res\layout\activity_main.xml文件中。在Android中,GLSurfaceView控件继承自SurfaceView,该控件实现了SurfaceHolder.Callback2接口,拥有SurfaceView的全部特性,也有View所有的功能和属性,特别是处理事件的功能,它主要是在SurfaceView的基础上加入了EGL的管理,并自带了一个GLThread绘制线程(EGLContext创建GL环境所在线程即为GLThread),绘制的工作直接通过OpenGL在绘制线程中进行,不会阻塞主线程,绘制的结果输出到SurfaceView所提供的Surface上,这使得GLSurfaceView也拥有了OpenGL ES所提供的图形处理功能,通过它定义的Render接口,使更改具体的Render的行为非常灵活,只需要将实现了渲染功能的Renderer的实现类设置给GLSurfaceView即可,如下面的代码所示:
public class MainActivity extends Activity {
MyRenderer myRenderer;
GLSurfaceView myGLSurfaceView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myGLSurfaceView = (GLSurfaceView) findViewById(R.id.myGLSurfaceView);
myRenderer = new MyRenderer();
myGLSurfaceView.setRenderer(myRenderer);
}
public void onClickButton1(View v) {//响应单击按钮“绘制五角星”
float[] myVerticesCoord = new float[]{
0.5f, 0f, 0.0f,
0.63f, 0.38f, 0.0f,
1, 0.38f, 0.0f,
0.69f, 0.59f, 0.0f,
0.82f, 1f, 0.0f,
0.5f, 0.75f, 0.0f,
0.18f, 1f, 0.0f,
0.31f, 0.59f, 0.0f,
0, 0.38f, 0.0f,
0.37f, 0.38f, 0.0f};
myRenderer.resetVerticesCoord(myVerticesCoord);
}
}
上面这段代码在MyCode\MySampleO61\app\src\main\java\com\bin\luo\mysample\ MainActivity.java文件中。在上面这段代码中,MyRenderer类即是一个自定义的OpenGL渲染器,所有的绘制工作均在此类中实现。MyRenderer类的主要代码如下:
public class MyRenderer implements GLSurfaceView.Renderer{
float myVerticesCoord[]={};
FloatBuffer myVerticesBuffer;
public MyRenderer(){resetVerticesCoord(myVerticesCoord);}
//重新设置顶点坐标,并初始化对应的缓冲区
public void resetVerticesCoord(float[] verticesCoord){
myVerticesCoord=verticesCoord;
myVerticesBuffer=ByteBuffer.allocateDirect(myVerticesCoord.length*4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
myVerticesBuffer.put(myVerticesCoord);
myVerticesBuffer.position(0);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config){}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height){
gl.glViewport(0,0,width,height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl,45.0f,(float)width/(float)height,0.1f,100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
}
@Override
public void onDrawFrame(GL10 gl){
//设置场景背景为白色
gl.glClearColor(1.0f,1.0f,1.0f,1.0f);
//清除颜色和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef(-0.5f,-0.5f,-2); //平移图形到指定位置
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3,GL10.GL_FLOAT,0,myVerticesBuffer);
gl.glLineWidth(8f); //设置线条宽度
gl.glColor4f(1.0f,0.0f,0.0f,1.0f); //设置线条颜色
//根据顶点坐标绘制封闭图形
gl.glDrawArrays(GL10.GL_LINE_LOOP,0,myVerticesCoord.length/3);
}
}
上面这段代码在MyCode\MySampleO61\app\src\main\java\com\bin\luo\mysample\ MyRenderer.java文件中。在这段代码中gl.glDrawArrays(GL10.GL_LINE_LOOP,0, myVerticesCoord.length/3)用于绘制封闭图形(五角星),glDrawArrays()方法的语法声明如下:
void glDrawArrays(int mode,int first,int count)
其中,参数int mode 表示绘制模式,OpenGL 2.0及其后续版本提供以下参数值: GL_LINE_LOOP、GL_LINE_STRIP、GL_TRIANGLES、GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN、GL_POINTS、GL_LINES;参数int first设置从数组缓存中的哪个位置开始绘制,一般为0;参数int count表示在数组中顶点的数量。
此实例的完整代码在MyCode\MySampleO61文件夹中。
补充说明
在测试代码时,必须保持网络畅通。
源代码下载
关注微信公众号,后台回复关键词 “Android App开发超实用代码136” 即可获得完整源代码。
参考书籍


扫码优惠购书
《Android App开发超实用代码集锦——jQuery Mobile+OpenCV+O》
ISBN:9787302589358
作者:罗帅、罗斌
定价:99元
问题描述+解决方案+真实源码+效果截图
介绍jQuery Mobile、OpenCV、OpenGL等在Android平台运行的应用
300个实例,提供完整源代码,边看边做边学











