zoukankan      html  css  js  c++  java
  • Android OpenGL(1)

    OpenGL开发基础

    OpenGL简介:

    Android通过OpenGL包含了对高性能2D和3D图形的支持.尤其支持OpenGL ES API。OpenGL是一个跨平台的图形API,提供了软件操作3D图形硬件的接口。OpenGL ES是一个专用于嵌入式设备的OpenGL规格。

    在Android框架中有两个基本的类使你可以通过OpenGL ES API创建和操作图形系统:

    GLSurfaceViewGLSurfaceView.Renderer。如果你的目标是在你的Android应用中使用OpenGL,了解如何在一个activity中实现这些类是首要目标.

    GLSurfaceView:这个类是一个View,你可以用OpenGLAPI调用来绘制对象并管理它们.它与SurfaceView很相似.你可以创建一个GLSurfaceView的实例然后把你的绘制操作添加给它.然而,如果你想捕获触屏事件,你应扩展GLSurfaceView类来实现触屏事件监听器。

    GLSurfaceView.Renderer:此接口定义了在一个OpenGL  GLSurfaceView上作画所需的方法.你必须提供另一个类来实现这个接口然后把它附加到你的GLSurfaceView实例上,使用GLSurfaceView.setRenderer().

    OpenGL包

    OpenGLES 1.0/1.1 API 包

    android.opengl- 这个包为OpenGLES 1.0/1.1 类提供了一个静态接口并且其性能好于javax.microedition.khronos包中的接口.

    GLES10、GLES10Ext、GLES11、GLES10Ext

    javax.microedition.khronos.opengles- 这个包提供了OpenGLES 1.0/1.1 的标准实现.

    GL10、GL10Ext、GL11、GL11Ext、GL11ExtensionPack

    OpenGLES 2.0 API 类

    android.opengl.GLES20- 这个包提供了OpenGLES 2.0 的接口并且从Android2.2 (API Level 8)开始才能用.

    如果你想正确创建支持OpenGL的应用,请看OpenGL ES 1.0或OpenGLES 2.0的指南.

    声明OpenGL的需求:如果你的应用使用的OpenGL特性不能被所有的设备支持,你必须在AndroidManifest.xml文件中包含你的OpenGL的需求。

    下面用绘制一个多边形、改变颜色、旋转多边形的例子来说明:

    /*MainActivity.java*/

    public class MainActivity extends Activity {
        Renderer render = new GLRender();
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            GLImage.load(this.getResources());
            GLSurfaceView glView = new GLSurfaceView(this);
            glView.setRenderer(render);//设置渲染
            setContentView(glView);
        }
    }

    GLSurfaceView包含了一个专门用于渲染3D的接口Renderer,我们只需要构建一个自己的GLRender类。GLRender中必须要实现下面的3个抽象方法:
    public void onDrawFrame(GL10 gl){}
    public void onSurfaceChanged(GL10 gl, int width, int height){}
    public void onSurfaceCreated(GL10 gl, EGLConfig config){}
    onSurfaceCreated(): 当创建GLSurfaceView时被调用,只调用一次.在这个方法中执行只发生一次的动作,比如设置OpenGL环境参数或初始化OpenGL图形对象.

        public void onSurfaceCreated(GL10 gl, EGLConfig config)
        {
           gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);// 告诉系统对透视进行修正 
            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);// 所作深度测试的类型 
        }

    onSurfaceChanged(): 当GLSurfaceView几何体改变时系统调用此方法,比如GLSurfaceView的大小改变或设备屏幕的方向改变.使用此方法来响应GLSurfaceView容器的变化.
        public void onSurfaceChanged(GL10 gl, int width, int height)
        {
            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();                            
        }

    onDrawFrame(): 系统在每次重绘GLSurfaceView时调用此方法.此方法是绘制图形对象的主要的执行点.

    下面是绘制三角形和四边形的代码,里面加上了颜色的渲染和旋转多边形的代码,以及3D空间的显示。下一次会写3D效果的渲染哈。

    /*GLRender.java*/

    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,});  //右下点
        
    //正方形的4个顶点
         private IntBuffer quaterBuffer = IntBuffer.wrap(new int[]{
                one,one,
    0,
              
    -one,one,0,
                one,
    -one,0,
              
    -one,-one,0});
       
    //三角形的顶点颜色值(r,g,b,a)
         private IntBuffer colorBuffer = IntBuffer.wrap(new int[]{
                 one,
    0,0,one,
               
    0,one,0,one,
               
    0,0,one,one,
         });

          private IntBuffer DcolorBufferForQuad = IntBuffer.wrap(new int[]{
                 0,one,0,one,
                 0,one,0,one,
                 0,one,0,one,
                 0,one,0,one,
                
                 one, one/2, 0, one,
                 one, one/2, 0, one,
                 one, one/2, 0, one,
                 one, one/2, 0, one,
                
                 one,0,0,one,
                 one,0,0,one,
                 one,0,0,one,
                 one,0,0,one,
                
                 one,one,0,one,
                 one,one,0,one,
                 one,one,0,one,
                 one,one,0,one,
                
                 0,0,one,one,
                 0,0,one,one,
                 0,0,one,one,
                 0,0,one,one,
                
                 one,0,one,one,
                 one,0,one,one,
                 one,0,one,one,
                 one,0,one,one,
        });
         private IntBuffer DcolorBuffer = IntBuffer.wrap(new int[]{
            //tri 4 face
             one,0,0,one,
             0,one,0,one,
             0,0,one,one,   
            
             one,0,0,one,
             0,one,0,one,
             0,0,one,one,
            
             one,0,0,one,
             0,one,0,one,
             0,0,one,one,
            
             one,0,0,one,
             0,one,0,one,
             0,0,one,one,
         });
        
        
         private IntBuffer DtriggerBuffer = IntBuffer.wrap(new int[]{
            0,one,0,
            -one,-one,0,
            one,-one,one,
           
            0,one,0,
            one,-one,one,
            one,-one,-one,
           
            0,one,0,
            one,-one,-one,
            -one,-one,-one,
           
            0,one,0,
            -one,-one,-one,
            -one,-one,one
        
         });
         private IntBuffer DquaterBuffer = IntBuffer.wrap(new int[]{
            one,one,-one,
            -one,one,-one,
            one,one,one,
            -one,one,one,
           
            one,-one,one,
            -one,-one,one,
            one,-one,-one,
            -one,-one,-one,
           
            one,one,one,
            -one,one,one,
            one,-one,one,
            -one,-one,one,
           
            one,-one,-one,
            -one,-one,-one,
            one,one,-one,
            -one,one,-one,
           
            -one,one,one,
            -one,one,-one,
            -one,-one,one,
            -one,-one,-one,
           
            one, one, -one,
            one, one, one,
            one, -one, -one,
            one, -one, one,
         });

       
        @Override
      
    public void onDrawFrame(GL10 gl)
        {
          
    // 清除屏幕和深度缓存
            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);
          
    //绘制三角锥
            for(int i=0; i<4; i++)
            {
                gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i
    *3, 3);
            }
          
    //绘制三角形结束
            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, quaterBuffer);
            gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
    0, 4);
          
    //绘制正方体
            for(int i=0; i<6; i++)
            {
                gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i
    *4, 4);
            }
          
    //绘制正方形结束
            gl.glFinish();
          
    // 取消顶点设置
            gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 
          
    //关闭颜色设置
              gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
          
    //改变旋转的角度
            rotateTri += 0.5f;
            rotateQuad
    -= 0.5f;
        }

        @Override
      
    public void onSurfaceChanged(GL10 gl, int width, int height)
        {
          
    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)
        {
          
    // 启用阴影平滑
            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也能够感兴趣,毕竟现在的3D游戏和一些3D的效果都是用OpenGL做的啦。

    接下来,还有更精彩的哦。敬请期待吧!

    代码下载链接:http://download.csdn.net/detail/klcf0220/5489181

    http://www.apkbus.com/android-121456-1-1.html

    喜欢开源,乐意分享的大神们,欢迎加入QQ群:176507146,你值的拥有哦!

    作者:快乐出发0220 ;Android群:151319601 ; Linux群:96394158 ;转载请注明出处 http://klcf0220.cnblogs.com/ !!!
  • 相关阅读:
    mongodump
    spring发邮件被识别为垃圾邮件:org.springframework.mail.MailSendException: Failed messages: com.sun.mail.smtp.SMTPSendFailedException: 554 DT:SPM 163
    springboot拦截器注入bean失败实例
    springboot拦截器配置、消息头校验、重复请求过滤
    web接口服务端鉴权
    spring data jpa指定联合索引
    spring data jpa自定义更新实现实例
    win10根据端口查进程以及杀进程
    linux修改jar包中的springboot配置文件
    linux修改配置文件解决mysql中文乱码和指定数据库存储引擎
  • 原文地址:https://www.cnblogs.com/klcf0220/p/3110591.html
Copyright © 2011-2022 走看看