`
rocky225
  • 浏览: 11418 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

OpenGL ES的1.0

 
阅读更多

OpenGL ES的1.0

本教程演示了如何创建一个简单的Andr​​oid应用程序使用的OpenGL ES 1.0 API来执行一些基本图形操作。您将学习如何:

  • 使用GLSurfaceViewGLSurfaceView.Renderer创建活动
  • 创建和绘制图形对象
  • 定义一个投影屏幕几何纠正
  • 定义相机视图
  • 旋转的图形对象
  • 使图形触摸互动

Android框架的OpenGL ES 1.0/1.1和OpenGL ES 2.0 API的支持。您应该仔细考虑的OpenGL ES API(1.0/1.1或2.0)的版本是最适合您的需要 。欲了解更多信息,请参阅选择OpenGL API的版本。如果您希望使用的OpenGL ES 2.0,OpenGL ES 2.0的教程

在开始之前,您应该了解如何创建一个基本的Android应用程序 。如果你不知道如何创建一个应用程序,后续的Hello World教程将使你熟悉这个过程。

创建与GLSurfaceView活动

要开始使用OpenGL,你必须实现一个GLSurfaceViewGLSurfaceView.RendererGLSurfaceView是主视图类型的应用程序,使用OpenGL和GLSurfaceView.Renderer控制在该视图中绘制的是什么。(欲了解更多有关这些类的信息,请参阅与OpenGL的3D文件。)

使用GLSurfaceView创建活动:

  1. 启动一个新的Andr​​oid项目,该项目目标的Andr​​oid 1.6(API等级4)或更高。
  2. 将项目命名为HelloOpenGLES10和确保它包括一个称为HelloOpenGLES10活动。
  3. 修改HelloOpenGLES10类如下:
    package com.example.android.apis.graphics;
    
    import android.app.Activity;
    import android.content.Context;
    import android.opengl.GLSurfaceView;
    import android.os.Bundle;
    
    public class HelloOpenGLES10 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 HelloOpenGLES10SurfaceView(this);
            setContentView(mGLView);
        }
        
        @Override
        protected void onPause() {
            super.onPause();
            // The following call pauses the rendering thread.
            // If your OpenGL application is memory intensive,
            // you should consider de-allocating objects that
            // consume significant memory here.
            mGLView.onPause();
        }
        
        @Override
        protected void onResume() {
            super.onResume();
            // The following call resumes a paused rendering thread.
            // If you de-allocated graphic objects for onPause()
            // this is a good place to re-allocate them.
            mGLView.onResume();
        }
    }
      
    class HelloOpenGLES10SurfaceView extends GLSurfaceView {
    
        public HelloOpenGLES10SurfaceView(Context context){
            super(context);
            
            // Set the Renderer for drawing on the GLSurfaceView
            setRenderer(new HelloOpenGLES10Renderer());
        }
    }
    1. 注:你会得到一个HelloOpenGLES10Renderer引用编译错误。这是预期的结果;下一步将修复这个错误。

      如上图所示,此活动使用单一GLSurfaceView作为其视图。请注意,这个活动实现暂停和恢复的关键生命周期的回调 。

      HelloOpenGLES10SurfaceView的代码在上面的例子中仅仅是GLSurfaceView的一个实例,因此不是例子必须的。不过,如果你想您的应用程序能够监测和响应触摸屏事件(我们猜测你会这样做),你做你必须继承GLSurfaceView来添加触摸事件侦听器,您将会在Reponding to Touch Events学习如何做。

      为了在GLSurfaceView绘制图形,你必须定义一个继承GLSurfaceView.Renderer的类。在接下来的步骤,您将创建一个renderer类来完成这个OpenGL应用程序。

    2. 创建一个新的文件HelloOpenGLES10Renderer类,它实现GLSurfaceView.Renderer接口 :
      package com.example.android.apis.graphics;
      
      import javax.microedition.khronos.egl.EGLConfig;
      import javax.microedition.khronos.opengles.GL10;
      
      import android.opengl.GLSurfaceView;
      
      public class HelloOpenGLES10Renderer implements GLSurfaceView.Renderer {
      
          public void onSurfaceCreated(GL10 gl, EGLConfig config) {
              // Set the background frame color
              gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
          }
          
          public void onDrawFrame(GL10 gl) {
              // Redraw background color
              gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
          }
          
          public void onSurfaceChanged(GL10 gl, int width, int height) {
              gl.glViewport(0, 0, width, height);
          }
        
      }
      1. 这继承GLSurfaceView.Renderer接口使用OpenGL绘图方法而必须提供的最简代码结构 :

        如需有关这些方法的更多信息,请参阅与OpenGL的 3D文档。

      上面的代码示例创建了一个简单的Andr​​oid应用程序显示一个灰色的屏幕,使用OpenGL ES 1.0调用。虽然这个应用程序没有做任何事情非常有趣,通过创建这些类,你必须奠定开始绘制与OpenGL ES 1.0的图形元素所需的基础。

      如果你是熟悉的OpenGL ES API的,这些类应该给你足够的信息来使用的OpenGL ES 1.0 API和创建图形。但是,如果您需要更多的帮助开始使用OpenGL的头下一节一些更多的提示。

      画上GLSurfaceView的形状

      一旦你已经实现了GLSurfaceView.Renderer,下一步就是绘制它的东西 。本节说明如何定义和画一个三角形。

      定义一个三角形

      OpenGL允许您使用在三维空间的坐标来定义对象。所以,在你可以画一个三角形之前,你必须定义它的坐标。在OpenGL中,要做到这一点的典型方式是定义坐标的顶点数组。

      默认情况下,OpenGL ES的假设了一个坐标系,就是[0,0,0](X,Y,Z)指定为GLSurfaceView框架中心,[1,1,0]是框架的右上角和[ -1,-1,0]是框架的左下角。

      定义一个三角形的顶点数组:

      1. 在你的HelloOpenGLES10Renderer类中,添加新的成员变量,包含一个三角形状的 顶点:
        private FloatBuffer triangleVB;
      2. 创建一个方法,initShapes()用以填充该成员变量:
        private void initShapes(){
            
                float triangleCoords[] = {
                    // X, Y, Z
                    -0.5f, -0.25f, 0,
                     0.5f, -0.25f, 0,
                     0.0f,  0.559016994f, 0
                }; 
                
                // initialize vertex Buffer for triangle  
                ByteBuffer vbb = ByteBuffer.allocateDirect(
                        // (# of coordinate values * 4 bytes per float)
                        triangleCoords.length * 4); 
                vbb.order(ByteOrder.nativeOrder());// use the device hardware's native byte order
                triangleVB = vbb.asFloatBuffer();  // create a floating point buffer from the ByteBuffer
                triangleVB.put(triangleCoords);    // add the coordinates to the FloatBuffer
                triangleVB.position(0);            // set the buffer to read the first coordinate
            
            }
        这种方法定义了一个三相等的立体三角形。
      3. 修改onSurfaceCreated()方法来初始化您的三角形:
            public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            
                // Set the background frame color
                gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
                
                // initialize the triangle vertex array
                initShapes();
            }

          注意:形状和其他静态对象在onSurfaceCreated()初始化一次,以便获得最佳性能 。避免在onDrawFrame()初新的对象,因为这会导致系统重新创建每个重绘对象,从而减慢您的应用程序。

        现在已经定义了一个三角形的形状,但如果您运行的应用程序后,什么也没有出现。什么?您应该告诉OpenGL绘制三角形,你将会在下一节学会如何做。

        画出三角形

        你必须告诉OpenGL您使用的顶点数组,在你可以画出你的三角形之前。在这些步骤后,你可以调用绘图API来显示三角形。

        绘制三角形:

        1. glEnableClientState()方法必须添加到onSurfaceCreated()的底部,使得可以使用顶点数组。
                  // Enable use of vertex arrays
                  gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
          经过这一步,您已经准备在OpenGL视图中绘制三角形的对象。
        2. 下面的代码添加到您的onDrawFrame()方法末尾,以绘制的三角形。
          // Draw the triangle
                  gl.glColor4f(0.63671875f, 0.76953125f, 0.22265625f, 0.0f);
                  gl.glVertexPointer(3, GL10.GL_FLOAT, 0, triangleVB);
                  gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
        3. 运行的应用程序!你的程序应该是这个样子:

        图1。三角没有投影或相机视图绘制。

        有这个例子中的几个问题。首先,它没有给你友好的印象。其次,三角形是有点压扁,还有当您更改设备的屏幕方向时将改变其形状。它的形状歪斜的原因,是因为这个对象渲染在一个不是正方形的屏幕上。您将在下一节中使用投影和相机视图解决这一问题。

        最后,因为三角形是固定的,系统在完全相同的地方重绘对象多次,这方法不是最有效地利用OpenGL图形的方法。在Add Motion节,你会做出这种形状的旋转,从而证明这种使用方法的处理能力 。

        应用投影和相机视图

        显示图形的基本问题之一是显示,Android设备通常不是方形的,默认情况下,OpenGL的希望您画在一个正方形上,以便能够在不是方形的屏幕上使用统一的坐标系统。为了解决这个问题,你可以申请一个OpenGL投影模式和相机视图(眼点)来改变图形对象的坐标,使他们有正确的比例在任何显示器上 。关于OpenGL的坐标映射的详细信息,请查阅Mapping Coordinates for Drawn Objects.

        运用投影和相机视图转换到您的三角形:

        1. 修改您的onSurfaceChanged()的方法使支持GL10.GL_PROJECTION模式,计算屏幕比例和应用作为改造对象的坐标的比例。
            public void onSurfaceChanged(GL10 gl, int width, int height) {
                gl.glViewport(0, 0, width, height);
                
                // make adjustments for screen ratio
                float ratio = (float) width / height;
                gl.glMatrixMode(GL10.GL_PROJECTION);        // set matrix to projection mode
                gl.glLoadIdentity();                        // reset the matrix to its default state
                gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7);  // apply the projection matrix
            }  
        2. 接下来,修改您的onDrawFrame()方法来套用GL_MODELVIEW模式,并使用GLU.gluLookAt ()设置一个眼点
              public void onDrawFrame(GL10 gl) {
                  // Redraw background color
                  gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
                  
                  // Set GL_MODELVIEW transformation mode
                  gl.glMatrixMode(GL10.GL_MODELVIEW);
                  gl.glLoadIdentity();   // reset the matrix to its default state
                  
                  // When using GL_MODELVIEW, you must set the view point
                  GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);        
                  
                  // Draw the triangle
                  ...
              }
        3. 运行更新的应用程序,你应该看到像这样:

        图2。三角绘制与应用投影和相机视图。

        现在,您已经应用了这种转变,三角形的三个边都相等的,而不是早期版本中压扁的三角形 。

        添加运动

        虽然十分激动用OpenGL ES创建了一个静态图形对象,没准你想至少一些对象移动 。在本节中,您将添加运动到您的三角形旋转。

        要添加您的三角形旋转:

        1. 修改您onDrawFrame()方法,以旋转的三角形对象 :
              public void onDrawFrame(GL10 gl) {
                  ...    
                  // When using GL_MODELVIEW, you must set the view point
                  GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);        
              
                  // Create a rotation for the triangle
                  long time = SystemClock.uptimeMillis() % 4000L;
                  float angle = 0.090f * ((int) time);
                  gl.glRotatef(angle, 0.0f, 0.0f, 1.0f);        
                  
                  // Draw the triangle
                  ...
              }
        2. 运行应用程序和您的三角形应该围绕其中心旋转。

        响应触摸事件

        像旋转的三角形那样按照预设程序使物体移动是可以得到一些注意,但你是否想用户拥有与OpenGL图形的交互呢?在本节中,您将学习如何监听触摸事件,让用户能够和你的HelloOpenGLES10SurfaceView对象交互

        使您的OpenGL应用程序触摸互动的关键是继承GLSurfaceView覆盖onTouchEvent()方法来监听触摸事件。然而,在你开始之前,你要修改的渲染类显示三角形的旋转角度。之后,您将修改HelloOpenGLES10SurfaceView处理触摸事件并把这些数据传递到您的渲染类。

        使您的旋转三角形响应触摸事件:

        1. 修改您HelloOpenGLES10Renderer类,加入一个新的公共成员使您的HelloOpenGLES10SurfaceView类是能够传递新的旋转值到您的渲染:
          public float mAngle;
        2. 在您onDrawFrame()方法,注释掉代码产生的一个角度,更换新角度变量mAngle
                  // Create a rotation for the triangle (Boring! Comment this out:)
                  // long time = SystemClock.uptimeMillis() % 4000L;
                  // float angle = 0.090f * ((int) time);
          
                  // Use the mAngle member as the rotation value
                  gl.glRotatef(mAngle, 0.0f, 0.0f, 1.0f); 
        3. 在你的HelloOpenGLES10SurfaceView类中,添加下面的成员变量 。
            private final float TOUCH_SCALE_FACTOR = 180.0f / 320;
            private HelloOpenGLES10Renderer mRenderer;
            private float mPreviousX;
            private float mPreviousY;
        4. HelloOpenGLES10SurfaceView构造方法,设置mRenderer成员让您拥有一个处理旋转输入和设置渲染模式RENDERMODE_WHEN_DIRTY的类
              public HelloOpenGLES10SurfaceView(Context context){
                  super(context);
                  // set the mRenderer member
                  mRenderer = new HelloOpenGLES10Renderer();
                  setRenderer(mRenderer);
                  
                  // Render the view only when there is a change
                  setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
              }
        5. 在你的HelloOpenGLES10SurfaceView类中,重写onTouchEvent()方法来侦听触摸事件并将它们传递给你的渲染 。
              @Override 
              public boolean onTouchEvent(MotionEvent e) {
                  // MotionEvent reports input details from the touch screen
                  // and other input controls. In this case, you are only
                  // interested in events where the touch position changed.
          
                  float x = e.getX();
                  float y = e.getY();
                  
                  switch (e.getAction()) {
                      case MotionEvent.ACTION_MOVE:
              
                          float dx = x - mPreviousX;
                          float dy = y - mPreviousY;
              
                          // reverse direction of rotation above the mid-line
                          if (y > getHeight() / 2) {
                            dx = dx * -1 ;
                          }
              
                          // reverse direction of rotation to left of the mid-line
                          if (x < getWidth() / 2) {
                            dy = dy * -1 ;
                          }
                        
                          mRenderer.mAngle += (dx + dy) * TOUCH_SCALE_FACTOR;
                          requestRender();
                  }
          
                  mPreviousX = x;
                  mPreviousY = y;
                  return true;
              } 

          注:触摸事件返回该像素的坐标于OpenGL坐标是不一样的 。触摸坐标[0,0]是屏幕的左下角和[max_X,max_Y]是屏幕右上角的最高值。为了配合触摸事件OpenGL的图形对象,您必须转换触摸坐标为OpenGL的坐标。

        6. 运行应用程序和你的手指或光标在屏幕上拖动,旋转的三角形。

        对于OpenGL的触摸事件功能的另一个例子,请看TouchRotateActivity.

本人的英语水平不高,只能把Google翻译错误的地方改了一下,希望对大家有用,如果看不懂还是去官网看源文档吧....(*^__^*) 嘻嘻……



Portions of this page are reproduced from work created andshared by the Android Open Source Projectand used according to terms described in theCreative Commons 2.5 Attribution License.
分享到:
评论

相关推荐

    OpenGL ES 1.0 教程

    OpenGL ES 1.0 教程是一份专为学习移动设备和嵌入式系统图形编程设计的资源。OpenGL ES(Embedded Systems)是OpenGL标准的精简版本,特别针对低功耗设备,如智能手机、平板电脑和掌上电脑,如Windows CE平台。这个...

    OpenGL ES 1.0 开发库

    OpenGL ES 1.0 开发库是针对嵌入式设备,如智能手机和平板电脑等,设计的一个图形处理标准。它是OpenGL的精简版,专为资源有限的移动平台提供了高效且功能丰富的2D和3D图形渲染能力。OpenGL ES 1.0是该系列的第一个...

    OpenglES 1.0 纹理贴图

    OpenGL ES 1.0 是移动设备和嵌入式系统中广泛使用的图形库,它为2D和3D图形渲染提供了基础。纹理贴图是OpenGL ES中的一个重要概念,它允许我们为几何体表面添加复杂的视觉效果,如图像或颜色图案。在本篇中,我们将...

    android+ndk+opengles1.0点线抗锯齿

    在OpenGL ES 1.0版本中,抗锯齿技术是解决这一问题的有效手段。本文将深入探讨如何在Android环境下,利用NDK进行原生代码开发,结合OpenGL ES 1.0来实现点和线的抗锯齿效果。 首先,让我们理解什么是抗锯齿。抗锯齿...

    opengl es 1.0 api文档

    opengl es 1.0 api 文档

    opengl es 1.0 specification

    OpenGL® ES is a royalty-free, cross-platform API for full-function 2D and 3D graphics on embedded systems - including consoles, phones, appliances and vehicles. It consists of well-defined subsets of...

    OpenGL ES 1.0 的 pdf 手册和 chm 的 Api

    opengles_1_0_manual.pdf 可能是OpenGL ES 1.0的手册,通常会包含更深入的技术细节、最佳实践和概念性解释。手册可能涵盖了渲染管道的工作原理、混合和深度测试、视口变换、光照模型以及固定功能管线的使用等主题。...

    OpenGL ES 1.0 Demo

    很好用的特好用超好用OpenGL ES 1.0 Demo

    Android-OpenGL-1.0-Test-master.zip_OPENGL ES android_android

    Android-OpenGL-1.0-Test: Android app that uses OpenGL ES 1.0 used for researching OpenGL ES for Android

    OpenGLES.ppt

    ES2.x针对可编程管线硬件.OpenGL ES1.0是以OpenGL1.3规范为基础的,OpenGL ES1.1是以OpenGL1.5为基础 的,他们分别又支持common和common lite两种profile.OpenGL ES2.0是参照OpenGL2.0规范定义的”

    opengl-es-src-1.0.0.zip

    OpenGL ES(Embedded Systems)是OpenGL图形库的一个精简版本,专为嵌入式设备和移动设备设计,如智能手机、平板电脑以及游戏机等。OpenGL ES 1.0.0是这个标准的一个早期版本,它提供了基本的3D图形渲染功能,为移动...

    OpenGL ES Game Development.2004.pdf

    在短短的一年内,来自 3D 图形、OpenGL 和嵌入式系统的专家共同努力,于 2003 年 SIGGRAPH 大会上公开发布了 OpenGL ES 1.0 和 EGL 1.0 规范。六个月后,Khronos Group 发布了符合性测试,确保使用 OpenGL ES 商标的...

    Android OpenGL ES 简明开发教程

    OpenGL ES 1.0和1.1基于OpenGL 1.3和1.5标准,分别提供common和commonlite两种profile,后者仅支持定点数运算,前者则兼容定点和浮点运算。OpenGL ES 2.0于2005年发布,参照OpenGL 2.0规范,引入了对可编程管线的...

    OpenGL ES 详解

    除了基本功能外,《OpenGL ES 详解》还提到了OpenGLES1.0的一些扩展功能,这些扩展可以帮助开发者更好地利用硬件特性,例如纹理压缩、高级光照效果等。 #### OpenGLES1.1的新特性 OpenGLES1.1相对于1.0版本增加了...

    opengl es 1.1版本

    OpenGL ES 1.1是在OpenGL ES 1.0的基础上进行了一些功能增强和错误修复,是移动平台早期进行3D图形编程的重要标准。 在OpenGL ES 1.1中,主要包含了以下核心概念和知识点: 1. **固定功能管道**:这是OpenGL ES ...

    colorfullife:Android中带有OpenGLES 1.0的基于2D tune的游戏

    缤纷人生 Android中带有OpenGLES 1.0的基于2D tune的游戏

    OpenGL ES规范电子书.pdf

    OpenGL ES 1.0.02版本(Annotated),是由David Blythe编辑完成的。该版本是在2002年至2004年间由Khronos Group发布的。作为早期版本之一,它奠定了OpenGL ES的基础,并为后续版本的发展提供了重要参考。 #### 三、...

    android OpenGL ES 中文 API

    `GL10`接口是`javax.microedition.khronos.opengles`包中的一个核心接口,它继承自`GL`接口,并且是`GL11`接口的父接口。`GL10`接口封装了OpenGL ES的基本功能,包括核心渲染命令和其他一些重要的扩展特性。此接口...

    OpenGLFlag:在 Android OpenGL ES 1.0 中挥舞旗帜

    在 Android OpenGL ES 1.0 中挥舞旗帜 截图 在搭载 Android 4.4 的 Asus Nexus 7 上运行。 视频 您可以使用下面的链接下载视频,或尝试将其复制/粘贴到您最喜欢的媒体播放器中。 学分 标志纹理由维基百科(公共领域...

    OpenGL ES2.0中文版本

    书籍内容包括OpenGLES2.0的目录概览,其中提到了OpenGLES是什么,它包括定点着色器和片段预处理,并且讨论了OpenGL ES2.0与OpenGLES1.0之间的向后兼容性问题。书中还涉及了EGL(Embedded-OpenGL)的基础知识,EGL...

Global site tag (gtag.js) - Google Analytics