Android OpenGL详解

来源:互联网 发布:c语言讲课比赛课件 编辑:程序博客网 时间:2024/05/23 23:00

OpenGL详解

 Android includes support for high performance 2D and 3D graphics with the Open Graphics Library (OpenGL), specifically, the OpenGL ES API. OpenGL is a cross-platform graphics API that specifies a standard software interface for 3D graphics processing hardware. OpenGL ES is a flavor of the OpenGL specification intended for embedded devices. The OpenGL ES 1.0 and 1.1 API specifications have been supported since Android 1.0. Beginning with Android 2.2 (API Level 8), the framework supports the OpenGL ES 2.0 API specification.

       以上是官方解释,相信大家应该能理解,在此简单的介绍: OpenGL 是个专业的3D程序接口,是一个功能强大调用方便底层3D图形库。OpenGL  的前身是SGI公司为其图形工作站开的 IRIS GL。IRISGL 是一个工业标准的3D图形软件接口,功能虽然强大但是移植性不好,于是 SGI 公司便在IRISGL 的基础上开发 OpenGL ,OpenGl(open graphics library)—跨平台  跨语言 (移植性好),
     
       Android 3D 引擎采用的是OpenGLES。OpenGLES是一套为手持和嵌入式系统设计的3D引擎API,由Khronos公司维护。在PC领域,一直有两种标准的3DAPI进行竞争,OpenGL和DirectX一般主流的游戏和显卡都支持这两种渲染方式,DirectX在Windows平台上有很大的优势,但是 OpenGL 具有更好的跨平台性。由于嵌入式系统和PC相比,一般说来,CPU、内存等都比PC差很多,而且对能耗有着特殊的要求,许多嵌入式设备并没有浮点运算协处理器,针对嵌入式系统的以上特点,Khronos对标准的 OpenGL 系统进行了维护和改动,以期望满足嵌入式设备对3D绘图的要求。

       好了,官方语言就不多说了,言归正传。在你的Android应用中用OpenGL ES绘制图形,首先需要有一个容器,最直接的方法是实现GLSurfaceView 和  GLSurfaceView.Renderer

 1、GLSurfaceView:是一个放置图形的View容器

 2、GLSurfaceView.Renderer:用来控制在这个View中如何进行绘制。

  GLSurfaceView只是一种选择,比较适合于全屏绘制图形或者近似全屏绘制,其他可以选择的还有 TextureViewSurfaceView

1.创建Activity

  在Activity的布局中,需要加入GLSurfaceView来放置绘制的图形。

  一个最简单的版本如下:



 

 

2.创建GLSurfaceView

  GLSurfaceView是一个特殊的组件,你可以在其中绘制OpenGL ES图形。

  你需要扩展这个类,在它的构造方法中设置渲染器:

复制代码
class MyGLSurfaceView extends GLSurfaceView {    public MyGLSurfaceView(Context context){        super(context);        // Set the Renderer for drawing on the GLSurfaceView        setRenderer(new MyRenderer());    }}

  如果使用OpenGL ES 2.0,还需要加一句声明:

// Create an OpenGL ES 2.0 contextsetEGLContextClientVersion(2);

 

  还有一个可选的设置是,把渲染模式改为 GLSurfaceView.RENDERMODE_WHEN_DIRTY ,这样仅在你的数据有变化时重新进行渲染。

// Render the view only when there is a change in the drawing datasetRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

 

  除非你调用requestRender(),这个设置会阻止帧被重画,有些情况下这样效率更高。

 

4.建立一个Renderer类

  Renderer类(渲染器类),即 GLSurfaceView.Renderer的实现类,它控制了与它相关联的 GLSurfaceView 上需要绘制的图形,其中有三个主要的回调方法:

  • onSurfaceCreated() - Called once to set up the view's OpenGL ES environment.
  • onDrawFrame() - Called for each redraw of the view.
  • onSurfaceChanged() - Called if the geometry of the view changes, for example when the device's screen orientation changes.

  

  一个简单的实现例子:

复制代码
public class MyGL20Renderer implements GLSurfaceView.Renderer {    public void onSurfaceCreated(GL10 unused, EGLConfig config) {        // Set the background frame color        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);    }    public void onDrawFrame(GL10 unused) {        // Redraw background color        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);    }    public void onSurfaceChanged(GL10 unused, int width, int height) {        GLES20.glViewport(0, 0, width, height);    }}

  一个简单的程序例子,只是设置了背景色,为了展示方便,GLSurfaceView类和渲染器类都作为Acitivity的内部类写出。

 

Manifest <manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.helloopengles"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="15" />    <!-- Tell the system this app requires OpenGL ES 2.0. -->    <uses-feature        android:glEsVersion="0x00020000"        android:required="true" />    <application        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name=".HelloOpenGLESActivity"            android:label="@string/title_activity_hello_open_gles" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>
<pre name="code" class="html">Activity package com.example.helloopengles;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.app.Activity;import android.content.Context;import android.opengl.GLES20;import android.opengl.GLSurfaceView;import android.os.Bundle;import android.util.Log;public class HelloOpenGLESActivity extends Activity{    private GLSurfaceView mGLView;    @Override    public void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        // Create a GLSurfaceView instance and set it        // as the ContentView for this Activity.        mGLView = new MyGLSurfaceView(this);        setContentView(mGLView);    }    class MyGLSurfaceView extends GLSurfaceView    {        public MyGLSurfaceView(Context context)        {            super(context);            try            {                // Create an OpenGL ES 2.0 context                setEGLContextClientVersion(2);                // Set the Renderer for drawing on the GLSurfaceView                setRenderer(new MyRenderer());                // Render the view only when there is a change in the drawing                // data                setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);                // 注意上面语句的顺序,反了可能会出错            }            catch (Exception e)            {                e.printStackTrace();            }        }    }    public class MyRenderer implements GLSurfaceView.Renderer    {        public void onSurfaceCreated(GL10 unused, EGLConfig config)        {            // Set the background frame color            GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);        }        public void onDrawFrame(GL10 unused)        {            // Redraw background color            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);        }        public void onSurfaceChanged(GL10 unused, int width, int height)        {            GLES20.glViewport(0, 0, width, height);        }    }}


4、在Manifest中添加声

 为了使用OpenGL ES 2.0 API,需要添加如下声明:

<uses-feature android:glEsVersion="0x00020000" android:required="true" />


   

0 0