关闭

android学习笔记之3D---多边形

351人阅读 评论(0) 收藏 举报

第一步:建立一个GLRender类并实现Renderer接口,同时实现Renderer接口的三个方法。

第二步:在onSurfaceChanged()方法体内做些初始化工作,代码如下:

            

  1. public void onSurfaceChanged(GL10 gl, int width, int height) {  
  2.         Log.d(this.getClass().getName(), "onSurfaceChanged.........");  
  3.         float ratio = (float) width / height;  
  4.         //设置OpenGL场景的大小  
  5.         gl.glViewport(00, width, height);  
  6.         //设置投影矩阵  
  7.         gl.glMatrixMode(GL10.GL_PROJECTION);  
  8.         //重置投影矩阵  
  9.         gl.glLoadIdentity();  
  10.         // 设置视图的大小  
  11.         gl.glFrustumf(-ratio, ratio, -11110);  
  12.         // 选择模型观察矩阵  
  13.         gl.glMatrixMode(GL10.GL_MODELVIEW);   
  14.         // 重置模型观察矩阵  
  15.         gl.glLoadIdentity();              
  16.     }  
 

第三步: 描述三角形和四边形。  

             三角形是由3个顶点组成的,同时OpenGL的坐标系也是三维的,因此每个顶点坐标都由x、y、z三个值组成。

             本例子将图形绘制在Z轴的原点处,因此所有坐标的第3个值(z轴)都为0.

                                三角形代码: 

                                                    

  1. //三角形三个顶点  
  2.  private IntBuffer triggerBuffer = IntBuffer.wrap(new int[]{  
  3.         0,one,0,        //上顶点  
  4.         -one,-one,0,    //左下点  
  5.         one,-one,0,});  //右下点  
 

                               四边形代码:

                                                    

  1. //正方形的4个顶点  
  2.      private IntBuffer quaterBuffer = IntBuffer.wrap(new int[]{  
  3.                 one,one,0,  
  4.                 -one,one,0,  
  5.                 one,-one,0,  
  6.                 -one,-one,0});  
 

第四步:本例子的结果是手机屏幕左侧为三角形,右侧为四边形。 这种方式是,绘制三角形时将坐标原点移动到左侧,绘制四边形时将坐标原点移动到右侧。

           而移动的方法是通过gl.glTranslatef(1.5f , 0.0f , -6.0f)完成 将坐标原点延X轴向右移动1.5个单位,Y轴不懂,Z轴移入屏幕6个单位。

            需要注意到是,每次移动的原点是 三维坐标系 的原点。 而三角形和四边形都有着各自的 坐标系原点。

 

第五步: 不管是绘制三角形,还是绘制四边形,都需要设置顶点。gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

第六步: 在绘制多边形之前,需要指定顶点以及顶点相关的信息。如下:

            

  1. // 设置三角形  
  2.         gl.glVertexPointer(3, GL10.GL_FIXED, 0, triggerBuffer);  
  3.         //绘制三角形  
  4.         gl.glDrawArrays(GL10.GL_TRIANGLES, 03);  
  5.           
  6.         //  正方形  
  7.         //设置和绘制正方形  
  8.         gl.glVertexPointer(3, GL10.GL_FIXED, 0, quaterBuffer);  
  9.         gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 04);  
 

           其中glVertexPointer方法的

         ----第1个参数表示坐标系的维度(该参数不是坐标数组的尺寸)。由于OpenGL是三维坐标系,因此该参数值是3。

         ----第2个参数表示顶点的类型

         ----第3个参数表示步长。

         ----第4个参数表示顶点缓存(也就是第三步定义的两个坐标数组)

红色文字为引用:http://www.cocoachina.com/gamedev/openal/2010/0430/1286.html (感谢Lotuslovenature给我的友情提示)

参数:
size:指定了每个顶点对应的坐标个数,只能是2,3,4中的一个,默认值是4
type:指定了数组中每个顶点坐标的数据类 型,可取常量:GL_BYTE, GL_SHORT,GL_FIXED,GL_FLOAT;
stride:指定了连续顶点间的字节排列方式,如果为0,数组中的顶点就会被认为是按照紧凑方式排列的,默认值为0
pointer:制订了数组中第一个顶点的首地址,默认值为0,对于我们的android,大家可以不 用去管什么地址的,一般给一个IntBuffer就可以了。


当开始render的时候,glVertexPointer 用一个数组指定了每个顶点的坐标,
第一个参数:size指定了每个顶点的坐标个数
第二个参数:type指定了每个坐标的数据类型,(和尚注:注意,这里不同的数据类型含义不同,如果选择GL_FIXED,那么0x10000表示单位长度,如果选择 GL_FLOAT那么1.0f表示单位度。)

第三个参数:stride指定了一个顶点和下一个顶点间数据的排列方式,是"单一数组"还是"分散数 组",单一数组的存储方式通常是更具效率的。当一个顶点数组被指定以后,size,type,stride,pointer被存储成client- side.
当glDrawArrays或者glDrawElements被调用的时候,如果顶点数组 处于可用状态, 就会被使用;可以使用glEnableClientState或者glDisableClientState来激活或者禁用一个顶点数组,顶点数组默认是 不可用并且是不可被glDrawArrays、glDrawElements两个函数使用的。

 


      最后用glDrawArrays方法绘制三角形和四边形。

 

 

通过步骤和方式完成所有的代码如下:

 

  1. package com.geolo.android.GL;  
  2. import java.nio.IntBuffer;  
  3. import javax.microedition.khronos.egl.EGLConfig;  
  4. import javax.microedition.khronos.opengles.GL10;  
  5. import android.opengl.GLSurfaceView.Renderer;  
  6. import android.util.Log;  
  7. public class GLRender implements Renderer{  
  8.      int one = 0x10000;  
  9.           
  10.      //三角形三个顶点  
  11.      private IntBuffer triggerBuffer = IntBuffer.wrap(new int[]{  
  12.             0,one,0,        //上顶点  
  13.             -one,-one,0,    //左下点  
  14.             one,-one,0,});  //右下点  
  15.      //正方形的4个顶点  
  16.      private IntBuffer quaterBuffer = IntBuffer.wrap(new int[]{  
  17.                 one,one,0,  
  18.                 -one,one,0,  
  19.                 one,-one,0,  
  20.                 -one,-one,0});  
  21.        
  22.     public void onDrawFrame(GL10 gl) {  
  23.         Log.d(this.getClass().getName(), "onDrawFrame.........");  
  24.         // 清除屏幕和深度缓存  
  25.         gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);  
  26.           
  27.         //  三角形  
  28.         // 重置当前的模型观察矩阵  
  29.         gl.glLoadIdentity();  
  30.         // 左移 1.5 单位,并移入屏幕 6.0  
  31.         gl.glTranslatef(-1.5f, 0.0f, -6.0f);      
  32.         // 允许设置顶点  
  33.         gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);  
  34.         // 设置三角形  
  35.         gl.glVertexPointer(3, GL10.GL_FIXED, 0, triggerBuffer);  
  36.         //绘制三角形  
  37.         gl.glDrawArrays(GL10.GL_TRIANGLES, 03);  
  38.           
  39.         //  正方形  
  40.         // 重置当前的模型观察矩阵  
  41.         gl.glLoadIdentity();  
  42.         // 左移 1.5 单位,并移入屏幕 6.0  
  43.         gl.glTranslatef(1.5f, 0.0f, -6.0f);  
  44.         //设置和绘制正方形  
  45.         gl.glVertexPointer(3, GL10.GL_FIXED, 0, quaterBuffer);  
  46.         gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 04);  
  47.           
  48.         // 取消顶点设置  
  49.         gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);  
  50.           
  51.     }  
  52.     public void onSurfaceChanged(GL10 gl, int width, int height) {  
  53.         Log.d(this.getClass().getName(), "onSurfaceChanged.........");  
  54.         float ratio = (float) width / height;  
  55.         //设置OpenGL场景的大小  
  56.         gl.glViewport(00, width, height);  
  57.         //设置投影矩阵  
  58.         gl.glMatrixMode(GL10.GL_PROJECTION);  
  59.         //重置投影矩阵  
  60.         gl.glLoadIdentity();  
  61.         // 设置视图的大小  
  62.         gl.glFrustumf(-ratio, ratio, -11110);  
  63.         // 选择模型观察矩阵  
  64.         gl.glMatrixMode(GL10.GL_MODELVIEW);   
  65.         // 重置模型观察矩阵  
  66.         gl.glLoadIdentity();              
  67.     }  
  68.     public void onSurfaceCreated(GL10 gl, EGLConfig config) {  
  69.         Log.d(this.getClass().getName(), "onSurfaceCreated.........");  
  70.         // 启用阴影平滑  
  71.         gl.glShadeModel(GL10.GL_SMOOTH);  
  72.         // 黑色背景  
  73.         gl.glClearColor(0000);  
  74.         // 设置深度缓存  
  75.         gl.glClearDepthf(1.0f);                           
  76.         // 启用深度测试  
  77.         gl.glEnable(GL10.GL_DEPTH_TEST);                          
  78.         // 所作深度测试的类型  
  79.         gl.glDepthFunc(GL10.GL_LEQUAL);                           
  80.         // 告诉系统对透视进行修正  
  81.         gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);  
  82.     }  
  83. }  

  1. package com.geolo.android;  
  2. import com.geolo.android.GL.GLRender;  
  3. import android.app.Activity;  
  4. import android.opengl.GLSurfaceView;  
  5. import android.opengl.GLSurfaceView.Renderer;  
  6. import android.os.Bundle;  
  7. public class AndroidOpendGL extends Activity {  
  8.     Renderer mRenderer = new GLRender();  
  9.     /** Called when the activity is first created. */  
  10.     @Override  
  11.     public void onCreate(Bundle savedInstanceState) {  
  12.         super.onCreate(savedInstanceState);  
  13.         GLSurfaceView mGlSurfaceView = new GLSurfaceView(this);  
  14.         mGlSurfaceView.setRenderer(mRenderer);  
  15.         setContentView(mGlSurfaceView);  
  16.     }  
  17. }  

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:260729次
    • 积分:4078
    • 等级:
    • 排名:第7885名
    • 原创:121篇
    • 转载:166篇
    • 译文:0篇
    • 评论:19条
    文章分类
    最新评论