Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2622989
  • 博文数量: 315
  • 博客积分: 3901
  • 博客等级: 少校
  • 技术积分: 3640
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-08 15:32
个人简介

知乎:https://www.zhihu.com/people/monkey.d.luffy Android高级开发交流群2: 752871516

文章分类

全部博文(315)

文章存档

2019年(2)

2018年(1)

2016年(7)

2015年(32)

2014年(39)

2013年(109)

2012年(81)

2011年(44)

分类: Android平台

2013-04-12 23:52:49

ThreeDGl.java

点击(此处)折叠或打开

  1. package com.hl.androidopgles;

  2. import java.nio.ByteBuffer;
  3. import java.nio.ByteOrder;
  4. import java.nio.IntBuffer;

  5. import javax.microedition.khronos.egl.EGLConfig;
  6. import javax.microedition.khronos.opengles.GL10;
  7. import android.opengl.GLSurfaceView.Renderer;

  8. public class ThreeDGl implements Renderer
  9. {
  10.     public ThreeDGl()
  11.     {
  12.         // TODO Auto-generated method stub
  13.         int one = 0x10000;
  14.         int vertices[] = {
  15.                 -one, -one, -one,
  16.                 one, -one, -one,
  17.                 one, one, -one,
  18.                 -one, one, -one,
  19.                 -one, -one, one,
  20.                 one, -one, one,
  21.                 one, one, one,
  22.                 -one, one, one,
  23.         };

  24.         int colors[] = {
  25.                 0, 0, 0, one,
  26.                 one, 0, 0, one,
  27.                 one, one, 0, one,
  28.                 0, one, 0, one,
  29.                 0, 0, one, one,
  30.                 one, 0, one, one,
  31.                 one, one, one, one,
  32.                 0, one, one, one,
  33.         };

  34.         byte indices[] = {
  35.                 0, 4, 5, 0, 5, 1,
  36.                 1, 5, 6, 1, 6, 2,
  37.                 2, 6, 7, 2, 7, 3,
  38.                 3, 7, 4, 3, 4, 0,
  39.                 4, 7, 6, 4, 6, 5,
  40.                 3, 0, 1, 3, 1, 2
  41.         };

  42.         ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
  43.         vbb.order(ByteOrder.nativeOrder());
  44.         mVertexBuffer = vbb.asIntBuffer();
  45.         mVertexBuffer.put(vertices);
  46.         mVertexBuffer.position(0);

  47.         ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
  48.         cbb.order(ByteOrder.nativeOrder());
  49.         mColorBuffer = cbb.asIntBuffer();
  50.         mColorBuffer.put(colors);
  51.         mColorBuffer.position(0);

  52.         mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
  53.         mIndexBuffer.put(indices);
  54.         mIndexBuffer.position(0);

  55.         /**
  56.          * @brief Explain
  57.          * 0x10000是出于OPENGL前期内存节约的考虑,以INT型模拟FLOAT型来表示,0x 0001 0000 前面4位表示小数点前,后4位表示小数点后,所以0x10000表示浮点数的1。如果你用的是FloatBuffer,就可以知道此处应该写1.0。
  58.          * gl.glVertexPointer(3, GL10.GL_FIXED, 0, triggerBuffer);//GL_FIXED,则后面用的是intbuffer。如上面的例子
  59.          * gl.glVertexPointer(3, GL10.GL_FLOAT, 0, triggerBuffer);//则此处那个triggerBuffer用的则是floatBuffer类型。
  60.          */
  61.     }

  62.     @Override
  63.     public void onDrawFrame(GL10 gl) {
  64.         // TODO Auto-generated method stub
  65.         // 清除屏幕和深度缓存
  66.         gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
  67.         // 重置当前的模型观察矩阵
  68.         gl.glLoadIdentity();

  69.         // 允许设置顶点
  70.         gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
  71.         // 允许设置颜色
  72.         gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

  73.         // 左移1.5单位,并移入屏幕6.0
  74.         gl.glTranslatef(-1.5f, 0.0f, -6.0f);
  75.         //设置和绘制正方形
  76.         gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
  77.         gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer);
  78.         gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, mIndexBuffer);

  79.         // 取消颜色设置
  80.         gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
  81.         // 取消顶点设置
  82.         gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
  83.     }

  84.     @Override
  85.     public void onSurfaceChanged(GL10 gl, int width, int height) {
  86.         // TODO Auto-generated method stub
  87.         //设置OpenGL场景的大小
  88.         gl.glViewport(0, 0, width, height);
  89.         //设置投影矩阵
  90.         gl.glMatrixMode(GL10.GL_PROJECTION);
  91.         //重置投影矩阵
  92.         gl.glLoadIdentity();
  93.         // 设置视口的大小
  94.         gl.glFrustumf(-1.5f, 1.5f, -1.5f, 1.5f, 1.0f, 10.0f);
  95.         // 选择模型观察矩阵
  96.         gl.glMatrixMode(GL10.GL_MODELVIEW);
  97.         // 重置模型观察矩阵
  98.         gl.glLoadIdentity();

  99.         /**
  100.          * @brief Explain
  101.          *    小满(bill man)个人原创,欢迎转载,转载请注明地址,小满(bill man)的专栏地址http://blog.csdn.net/bill_man

  102.          *    在3d世界中投影也是很重要的一部分,openGL ES支持两种投影方式,正交投影和透视投影。

  103.          *    1.正交投影

  104.          *     正交投影中观察者的视线是平行的,不产生进大选小的效果,设置正交投影的语句为

  105.          *    gl.glOrthof(-ratio, ratio, -1, 1, 1, 10);

  106.          *    第一个和第二个参数为视口左右侧对应的x坐标,第三个和第四个参数为视口上下侧对应的y坐标,第五个和第六个坐标为最近端和最远端的z坐标

  107.          *    OpenGL不支持无限远的可视区域,视口就是屏幕上指定的矩形区域

  108.          *    设置的方法就是在GLSurfaceView.Renderer类中的onDrawFrame方法中设置这句即可

  109.          *    2.透视投影

  110.          *     透视投影和正交投影不同,如同现实中观测到的世界一样,会产生近大远小的效果,设置的方法和正交投影一样,也是在GLSurfaceView.Renderer类中的onDrawFrame方法中设置

  111.          *    设置正交的语句为

  112.          *    gl.glFrustumf(-ratio, ratio, -1, 1, 1f, 10);

  113.          *    第一个和第二个参数为视口左右侧对应的x坐标,第三个和第四个参数为视口上下侧对应的y坐标,第五个和第六个坐标为最近端和最远端的z坐标

  114.          *    在left,right,top,bottom值不变的情况下,near值越小,视角越大,在开发中对这六个参数的调整非常重要

  115.          *    3.设置视口

  116.          *     在GLSurfaceView.Renderer的onSurfaceChanged方法中调用如下的方法即可

  117.          *    gl.glViewport(0, 0, width, height);

  118.          *    前两个参数为视口矩形在屏幕左上侧点的坐标,后两个参数是宽度和高度

  119.          *    4.近大远小原理

  120.          *     正交投影的视景体就相当于长方体,没有近大远小的效果,所有物体都保留原有的大小和角度,而透视投影则是距离摄像机越远物体在图像中看上去就越小,离摄像机越近,则看上去越大。

  121.          *    参考自Android 3d 游戏开发技术详解与典型案例,如有错误之处,希望大家多多指正


  122.          *    转自CSDN:http://blog.csdn.net/bill_man/article/details/7262544

  123.          */
  124.     }

  125.     @Override
  126.     public void onSurfaceCreated(GL10 gl, EGLConfig config) {
  127.         // TODO Auto-generated method stub
  128.         // 启用阴影平滑
  129.         gl.glShadeModel(GL10.GL_SMOOTH);
  130.         //黑色背景
  131.         gl.glClearColor(1.0f, 1.0f, 1.0f, 0.7f);
  132.         //设置深度缓冲
  133.         gl.glClearDepthf(1.0f);
  134.         //启用深度缓冲
  135.         gl.glEnable(GL10.GL_DEPTH_TEST);
  136.         //设置深度测试类型
  137.         gl.glDepthFunc(GL10.GL_LEQUAL);
  138.         //对透视进行修正
  139.         gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);

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

  149.     private IntBuffer mVertexBuffer;
  150.     private IntBuffer mColorBuffer;
  151.     private ByteBuffer mIndexBuffer;
  152. }
MainActivity.java

点击(此处)折叠或打开

  1. package com.hl.androidopgles;

  2. import android.opengl.GLSurfaceView;
  3. import android.opengl.GLSurfaceView.Renderer;
  4. import android.os.Bundle;
  5. import android.app.Activity;
  6. import android.view.Menu;
  7. import android.view.MenuItem;

  8. public class MainActivity extends Activity {
  9.     Renderer render = new ThreeDGl();
  10.     @Override
  11.     public void onCreate(Bundle savedInstanceState) {
  12.         super.onCreate(savedInstanceState);
  13.         setContentView(R.layout.activity_main);
  14.         GLSurfaceView gview=new GLSurfaceView(this);
  15.         gview.setRenderer(render);
  16.         setContentView(gview);
  17.                        //---编译不过、注释掉-----
  18.         // getActionBar().setDisplayHomeAsUpEnabled(true);
  19.     }

  20.     @Override
  21.     public boolean onCreateOptionsMenu(Menu menu) {
  22.         getMenuInflater().inflate(R.menu.activity_main, menu);
  23.         return true;
  24.     }

  25.     
  26.     @Override
  27.     public boolean onOptionsItemSelected(MenuItem item) {
  28.              //---编译不过、注释掉-----
  29.         // switch (item.getItemId()) {
  30.         // case android.R.id.home:
  31.         // NavUtils.navigateUpFromSameTask(this);
  32.         // return true;
  33.         // }
  34.         return super.onOptionsItemSelected(item);
  35.     }

  36. }


阅读(3480) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~