Android OpenGL 学习笔记 --开始篇


2010-07-09 16:41:13


原创作品,允许转载,转载时请务必以超链接形式标明文章  原始出处 、作者信息和本声明。否则将追究法律责任。 http://terryblog.blog.51cto.com/1764499/346996



1、什么是 OpenGL?



OpenGL 是个专业的3D程序接口,是一个功能强大,调用方便的底层3D图形库。 OpenGL  的前身是 SGI 公司为其图形工作站开的 IRIS GL。IRIS GL 是一个工业标准的3D图形软件接口,功能虽然强大但是移植性不好,于是 SGI 公司便在 IRIS GL 的基础上开发  OpenGL  。具体详细的介绍请  点击这里 。



2、OpenGL 的发展历程



OpenGL 1.0 版本,并与微软共同推出 Windows NT 版本的  OpenGL



OpenGL 1.1



OpenGL 3.2,这是一年以来 OpenGL进行的第三次重要升级。



OpenGL 现状、发展历程、 OpenGL 规范、编程入门请  点击这里 。



3、OpenGL  ES 简介



引擎采用的是 OpenGL ES 。 OpenGL ES 是一套为手持和嵌入式系统设计的3D 引擎API ,由Khronos 公司维护。在PC 领域,一直有两种标准的3D API 进行竞争, OpenGL  和 DirectX 。一般主流的游戏和显卡都支持这两种渲染方式,DirectX 在Windows 平台上有很大的优势,但是  OpenGL  具有更好的跨平台性。



由于嵌入式系统和PC 相比,一般说来,CPU 、内存等都比PC 差很多,而且对能耗有着特殊的要求,许多嵌入式设备并没有浮点运算协处理器,针对嵌入式系统的以上特点,Khronos 对标准的  OpenGL  系统进行了维护和改动,以期望满足嵌入式设备对3D 绘图的要求。



4、<span times="" new="" roman'"="" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "> Android OpenGL ES 简介



系统使用  OpenGL  的标准接口来支持3D 图形功能,android 3D  图形系统也分为 java  框架和本地代码两部分。本地代码主要实现的  OpenGL  接口的库,在 Java  框架层,javax.microedition.khronos.opengles  是 java 标准的  OpenGL  包,android.opengl 包提供了  OpenGL  系统和 Android GUI  系统之间的联系。



5、Android 支持 OpenGL 列表



  • 1、GL
  • 2、GL 10
  • 3、GL 10 EXT
  • 4、GL 11
  • 5、GL 11 EXT
  • 6、GL 11 ExtensionPack

OpenGL



6、一步一步实现自己的 Renderer 类



OpenGL



  • 1、为 Renderer 类赶回命名空间
import 
         android.opengl.GLSurfaceView.Renderer;
  •  
  • 2、新建一个类来实现 Renderer 接口,代码如下:
public 
          
        class 
         ThreeDGl  
        implements 
         Renderer 
 {
 }
  •  
  • 3、如上代码所写,程序实现了 Renderer 类,则必须重写以下方法
public 
          
        void 
         onDrawFrame(GL10 gl) 
 {
 }
 
        public 
          
        void 
         onSurfaceChanged(GL10 gl,  
        int 
         width,  
        int 
         height)
 {}
 
        public 
          
        void 
         onSurfaceCreated(GL10 gl, EGLConfig config)
 {}
  •  
  • OpenGL 做一些初始化工作,例如:
• •        
• 
                 •          // 
          启用阴影平滑 
         
 •                  gl.glShadeModel(GL10.GL_SMOOTH);
         
          •          // 
          黑色背景 
         
 •                  gl.glClearColor( 
         0 
         ,  
         0 
         ,  
         0 
         ,  
         0 
         );
         
          •          // 
          设置深度缓存 
         
 •                  gl.glClearDepthf( 
         1.0f 
         );                            
          •          // 
          启用深度测试 
         
 •                  gl.glEnable(GL10.GL_DEPTH_TEST);                        
          •          // 
          所作深度测试的类型 
         
 •                  gl.glDepthFunc(GL10.GL_LEQUAL);                            
         
          •          // 
          告诉系统对透视进行修正 
         
 •                  gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);

 •       
•           
       glHint 用于告诉 OpenGL 我们希望进行最好的透视修正,这会轻微地影响性能,但会使得透视图更好看。
 glClearColor 设置清除屏幕时所用的颜色,色彩值的范围从 0.0f~1.0f 大小从暗到这的过程。
 glShadeModel 用于启用阴影平滑度。阴影平滑通过多边形精细地混合色彩,并对外部光进行平滑。
 glDepthFunc 为将深度缓存设想为屏幕后面的层,它不断地对物体进入屏幕内部的深度进行跟踪。
 glEnable 启用深度测试。• OpenGL 场景大小 ,代码如下:

// 
        设置OpenGL场景的大小 
        
 
        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();    

 •       
•           
       gl.glMatrixMode(GL10.GL_PROJECTION); 指明接下来的代码将影响 projection matrix (投影矩阵),投影矩阵负责为场景增加透视度。
  gl.glLoadIdentity(); 此方法相当于我们手机的重置功能,它将所选择的矩阵状态恢复成原始状态,调用  glLoadIdentity(); 之后为场景设置透视图。
 gl.glMatrixMode(GL10.GL_MODELVIEW);   指明任何新的变换将会影响 modelview matrix (模型观察矩阵)。
 gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
  • 6、场景画出来了,接下来我们就要实现场景里面的内容,比如:设置它的透视图,让它有种越远的东西看起来越小的感觉,代码如下:


  • 7、了解了上面两个重写方法的作用和功能之后,第三个方法 onDrawFrame 从字面上理解就知道此方法做绘制图操作的。嗯,没错。在绘图之前,需要将屏幕清除成前面所指定的颜色,清除尝试缓存并且重置场景,然后就可以绘图了, 代码如下:
// 
         清除屏幕和深度缓存 
        
 
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT  
        | 
         GL10.GL_DEPTH_BUFFER_BIT);
 
        // 
         重置当前的模型观察矩阵 
        
 
        gl.glLoadIdentity();
  •  
Renderer render          = 
         new 
          ThreeDGl( 
         this 
         );
               /** 
          Called when the activity is first created.  
         */ 
         
     @Override
               public 
           
         void 
          onCreate(Bundle savedInstanceState) {
                   super 
         .onCreate(savedInstanceState);
         GLSurfaceView gview          = 
         new 
          GLSurfaceView( 
         this 
         );
         gview.setRenderer(render);
         setContentView(gview);
     }
  • 8、Renderer 类在实现了上面的三个重写之后,在程序入口中只需要调用

下面分享一段使用Renderer类绘制的三角形和四边形的代码:


OpenGL 参考代码 
     
package         com.terry;

        import 
        java.nio.IntBuffer;

        import 
        javax.microedition.khronos.egl.EGLConfig;
        import 
        javax.microedition.khronos.opengles.GL10;

        import 
        android.opengl.GLSurfaceView.Renderer;

        public 
         
       class 
        GLRender  
       implements 
        Renderer{

             float 
        rotateTri,rotateQuad;
             int 
        one 
       = 
       0x10000 
       ;
     
             // 
       三角形的一个顶点 
       
             
       private 
        IntBuffer triggerBuffer 
       = 
       IntBuffer.wrap( 
       new 
         
       int 
       []{
                     0 
       ,one, 
       0 
       ,      
       // 
       上顶点 
       
                     
       - 
       one, 
       - 
       one, 
       0 
       ,     
       // 
       左顶点 
       
                    one, 
       - 
       one, 
       0 
            
       // 
       右下点 
       
            });
     
             // 
       正方形的四个顶点 
       
             
       private 
        IntBuffer quateBuffer 
       = 
       IntBuffer.wrap( 
       new 
         
       int 
       []{
             one,one,        0 
       ,
                     - 
       one, 
       - 
       one, 
       0 
       ,
             one,        - 
       one, 
       0 
       ,
                     - 
       one, 
       - 
       one, 
       0 
       
     });
     
     
             private 
        IntBuffer colorBuffer 
       = 
       IntBuffer.wrap( 
       new 
         
       int 
       []{
             one,        0 
       , 
       0 
       ,one,
                     0 
       ,one, 
       0 
       ,one,
                     0 
       , 
       0 
       ,one,one
     });
     
     
     
     @Override
             public 
         
       void 
        onDrawFrame(GL10 gl) {
                 // 
        TODO Auto-generated method stub
         
                 // 
        清除屏幕和深度缓存 
       
                gl.glClear(GL10.GL_COLOR_BUFFER_BIT  
       | 
        GL10.GL_DEPTH_BUFFER_BIT);
                 // 
        重置当前的模型观察矩阵 
       
                gl.glLoadIdentity();


                 // 
        左移 1.5 单位,并移入屏幕 6.0 
       
                gl.glTranslatef( 
       - 
       1.5f 
       ,  
       0.0f 
       ,  
       - 
       6.0f 
       );
                  // 
       设置旋转 
       
                gl.glRotatef(rotateTri,  
       0.0f 
       ,  
       1.0f 
       ,  
       0.0f 
       );
         
                 // 
       设置定点数组 
       
                gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
                 // 
       设置颜色数组 
       
                gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
         
         gl.glColorPointer(        4 
       , GL10.GL_FIXED,  
       0 
       , colorBuffer);
                 // 
        设置三角形顶点 
       
                gl.glVertexPointer( 
       3 
       , GL10.GL_FIXED,  
       0 
       , triggerBuffer);
                 // 
       绘制三角形 
       
                gl.glDrawArrays(GL10.GL_TRIANGLES,  
       0 
       ,  
       3 
       );
         
         gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
         
                 // 
       绘制三角形结束 
       
                gl.glFinish();
         
                 /** 
       ******************** 
       */ 
       
                 /* 
        渲染正方形  
       */ 
       
                 // 
        重置当前的模型观察矩阵 
       
                gl.glLoadIdentity();
         
                 // 
        左移 1.5 单位,并移入屏幕 6.0 
       
                gl.glTranslatef( 
       1.5f 
       ,  
       0.0f 
       ,  
       - 
       6.0f 
       );
         
                 // 
        设置当前色为蓝色 
       
                gl.glColor4f( 
       0.5f 
       ,  
       0.5f 
       ,  
       1.0f 
       ,  
       1.0f 
       );
                 // 
       设置旋转 
       
                gl.glRotatef(rotateQuad,  
       1.0f 
       ,  
       0.0f 
       ,  
       0.0f 
       );
         
                 // 
       设置和绘制正方形 
       
                gl.glVertexPointer( 
       3 
       , GL10.GL_FIXED,  
       0 
       , quateBuffer);
         gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,         0 
       ,  
       4 
       );
         
                 // 
       绘制正方形结束 
       
                gl.glFinish();

                 // 
       取消顶点数组 
       
                gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
         
                 // 
       改变旋转的角度 
       
                rotateTri  
       += 
         
       0.5f 
       ;
         rotateQuad         -= 
         
       0.5f 
       ;
     }

     @Override
             public 
         
       void 
        onSurfaceChanged(GL10 gl,  
       int 
        width,  
       int 
        height) {
                 // 
        TODO Auto-generated method stub 
       
                
                 float 
        ratio  
       = 
        ( 
       float 
       ) width  
       / 
        height;
                 // 
       设置OpenGL场景的大小 
       
                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 
       ,  
       0 
       ,  
       0 
       ,  
       0 
       );
         
                 // 
        设置深度缓存 
       
                gl.glClearDepthf( 
       1.0f 
       );                            
                 // 
        启用深度测试 
       
                gl.glEnable(GL10.GL_DEPTH_TEST);                        
                 // 
        所作深度测试的类型 
       
                gl.glDepthFunc(GL10.GL_LEQUAL);                            
         
                 // 
        告诉系统对透视进行修正 
       
                gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
     }

 }


到此基本对 OpenGL 有一些了解,当然OpenGL 还有更多的东西需要我们去探索,努力吧。


本文出自 “Terry_龙” 博客,请务必保留此出处http://terryblog.blog.51cto.com/1764499/346996