Android OpenGL(1)

。_饼干妹妹 提交于 2020-03-26 12:40:56

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,你值的拥有哦!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!