Andriod OpenGL 教程 05 - 3D空间
来源:互联网 发布:c语言1到n求和 编辑:程序博客网 时间:2024/04/27 03:37
关键字: android OpenGL 移动开发 教程
在上节课的基础上,我们现在开始生成真正的3D对象,而不是象前两节课中那样3D世界中的2D对象。我们给三角形增加一个左侧面,一个右侧面,一个后侧面来生成一个金字塔(四棱锥)。给正方形增加左、右、上、下及背面生成一个立方体。我们混合金字塔上的颜色,创建一个平滑着色的对象。给立方体的每一面则来个不同的颜色。这样在我们的工程中MyTriangle类变成了MyPyramid , MySquare变成了MyCube。
MyPyramid.java
package wintop.gllesson05;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import javax.microedition.khronos.opengles.GL10; public class MyPyramid { private FloatBuffer vertexBuffer; // 顶点数组缓冲区 private FloatBuffer colorBuffer; // 顶点颜色缓冲区 private ByteBuffer indexBuffer; // 索引数组缓冲区 private float[] vertices = { // 在(x,y,z)坐标系中金字塔的五个顶点坐标 -1.0f, -1.0f, -1.0f, // 0. 左-底-后 1.0f, -1.0f, -1.0f, // 1. 右-底-后 1.0f, -1.0f, 1.0f, // 2. 右-底-前 -1.0f, -1.0f, 1.0f, // 3. 左-底-前 0.0f, 1.0f, 0.0f // 4. 顶 }; private float[] colors = { // 五个顶点的颜色(RGBA模式) 0.0f, 0.0f, 1.0f, 1.0f, // 0. 蓝 0.0f, 1.0f, 0.0f, 1.0f, // 1. 绿 0.0f, 0.0f, 1.0f, 1.0f, // 2. 蓝 0.0f, 1.0f, 0.0f, 1.0f, // 3. 绿 1.0f, 0.0f, 0.0f, 1.0f // 4. 红 }; private byte[] indices = { // 四个三角形的顶点索引 2, 4, 3, // 前面 (CCW) 1, 4, 2, // 右面 0, 4, 1, // 后面 4, 0, 3 // 左面 }; // 构造函数 - 设置缓冲区 public MyPyramid() { // 设置顶点数组,顶点数据为浮点数据类型。一个浮点类型的数据长度为四个字节 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); vbb.order(ByteOrder.nativeOrder()); // 使用原生字节顺序 vertexBuffer = vbb.asFloatBuffer(); // 将字节类型缓冲区转换成浮点类型 vertexBuffer.put(vertices); // 将数据复制进缓冲区 vertexBuffer.position(0); // 定位到初始位置 // 设置颜色缓冲区. 颜色数据为浮点数据类型。一个浮点类型的数据长度为四个字节 ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4); cbb.order(ByteOrder.nativeOrder()); colorBuffer = cbb.asFloatBuffer(); colorBuffer.put(colors); colorBuffer.position(0); // 设置索引缓冲区. 索引数据为字节数据类型. indexBuffer = ByteBuffer.allocateDirect(indices.length); indexBuffer.put(indices); indexBuffer.position(0); } // 绘图 public void draw(GL10 gl) { gl.glFrontFace(GL10.GL_CCW); // 设置正前面为逆时针方面 // 数组使能并定义它们各自的缓冲区 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); gl.glEnableClientState(GL10.GL_COLOR_ARRAY); gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer); gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_BYTE,indexBuffer); gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisableClientState(GL10.GL_COLOR_ARRAY); }}
MyCube.java
package wintop.gllesson05;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import javax.microedition.khronos.opengles.GL10; public class MyCube { private FloatBuffer vertexBuffer; // 顶点数组缓冲区 private int numFaces = 6; private float[][] colors = { // 六个面的颜色 {1.0f, 0.5f, 0.0f, 1.0f}, // 0. 橙色 {1.0f, 0.0f, 1.0f, 1.0f}, // 1. 紫色 {0.0f, 1.0f, 0.0f, 1.0f}, // 2. 绿色 {0.0f, 0.0f, 1.0f, 1.0f}, // 3. 蓝色 {1.0f, 0.0f, 0.0f, 1.0f}, // 4. 红色 {1.0f, 1.0f, 0.0f, 1.0f} // 5. 黄色 }; private float[] vertices = { // 六个面的顶点坐标 // 前 -1.0f, -1.0f, 1.0f, // 0. 左-底-前 1.0f, -1.0f, 1.0f, // 1. 右-底-前 -1.0f, 1.0f, 1.0f, // 2. 左-顶-前 1.0f, 1.0f, 1.0f, // 3. 右-顶-前 // 后 1.0f, -1.0f, -1.0f, // 6. 右-底-后 -1.0f, -1.0f, -1.0f, // 4. 左-底-后 1.0f, 1.0f, -1.0f, // 7. 右-顶-后 -1.0f, 1.0f, -1.0f, // 5. 左-顶-后 // 左 -1.0f, -1.0f, -1.0f, // 4. 左-底-后 -1.0f, -1.0f, 1.0f, // 0. 左-底-前 -1.0f, 1.0f, -1.0f, // 5. 左-顶-后 -1.0f, 1.0f, 1.0f, // 2. 左-顶-前 // 右 1.0f, -1.0f, 1.0f, // 1. 右-底-前 1.0f, -1.0f, -1.0f, // 6. 右-底-后 1.0f, 1.0f, 1.0f, // 3. 右-顶-前 1.0f, 1.0f, -1.0f, // 7. 有-顶-后 // 上 -1.0f, 1.0f, 1.0f, // 2. 左-顶-前 1.0f, 1.0f, 1.0f, // 3. 右-顶-前 -1.0f, 1.0f, -1.0f, // 5. 左-顶-后 1.0f, 1.0f, -1.0f, // 7. 右-顶-后 // 下 -1.0f, -1.0f, -1.0f, // 4. 左-底-后 1.0f, -1.0f, -1.0f, // 6. 右-底-后 -1.0f, -1.0f, 1.0f, // 0. 左-底-前 1.0f, -1.0f, 1.0f // 1. 右-底-后 }; // 构造函数 - 设置缓冲区 public MyCube() { // 设置顶点数组,顶点数据为浮点数据类型。一个浮点类型的数据长度为四个字节 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); vbb.order(ByteOrder.nativeOrder()); // 使用原生字节顺序 vertexBuffer = vbb.asFloatBuffer(); // 将字节类型缓冲区转换成浮点类型 vertexBuffer.put(vertices); // 将数据复制进缓冲区 vertexBuffer.position(0); // 定位到初始位置 } // 绘图 public void draw(GL10 gl) { gl.glFrontFace(GL10.GL_CCW); // 正前面为逆时针方向 gl.glEnable(GL10.GL_CULL_FACE); // 使能剔除面 gl.glCullFace(GL10.GL_BACK); // 剔除背面(不显示) gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); // 渲染所有的面 for (int face = 0; face < numFaces; face++) { // 设置每个面的颜色 gl.glColor4f(colors[face][0], colors[face][1], colors[face][2], colors[face][3]); // 根据顶点数据直接绘制图元 gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, face*4, 4); } gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisable(GL10.GL_CULL_FACE); }}
立方体所有面相对应法向法向都是按逆时针方向排列。这样使我们可以进行背面剔除操作,背面剔除操作的代码如下:
gl.glFrontFace(GL10.GL_CCW); //正前面为逆时针方向
gl.glEnable(GL10.GL_CULL_FACE);//使能剔除面
gl.glCullFace(GL10.GL_BACK); //剔除背面(不显示)
立方体的面顶点排列方式
最终运行结果如下图所示:
源代码下载地址:http://download.csdn.net/detail/seniorwizard/4460814
- Andriod OpenGL 教程 05 - 3D空间
- Andriod OpenGL 教程 10 - 3D世界
- iOS OpenGL ES 2.0教程 Lesson04--3D空间
- 【Qt OpenGL教程】05:3D模型
- Andriod OpenGL 教程 04 - 旋转
- Andriod OpenGL 教程 08 - 混合
- NeHe OpenGL教程 第九课 在3D空间中移动位图
- 【Qt OpenGL教程】09:在3D空间中移动位图
- NeHe OpenGL第五课:3D空间
- OpenGL教程之向3D进军
- OpenGL教程之漫游3D世界
- Andriod OpenGL 教程 02 - 第一个多边形
- Andriod OpenGL 教程 03 - 添加颜色
- Andriod OpenGL 教程 06 - 纹理映射
- Andriod OpenGL 教程 09 - 移动图像
- Direct3D 10教程4:3D空间
- Andriod OpenGL 教程 01 - 创建一个OpenGL 窗口
- Android OpenGL实战三——3D空间效果
- 如何远程复制另一台Linux服务器及相关问题
- Oracle 11g系列—4—Oracle的体系结构
- MacDonalds 翻译成“麦当劳”为什么好?英语翻译技巧E
- 通用基于TCP协议的C/S模型的代码
- ModelSim PE Student Edition 10.1b 的安装和使用
- Andriod OpenGL 教程 05 - 3D空间
- TextField输入完成后关闭键盘
- XCode编译器技巧
- Oracle表中重复记录只显示一条
- Struts2的OGNL表达式对编辑器输入的内容不进行转义
- JNI学习笔记(二)JNI中的java语言与本地C/C++语言之间的映射(附例子)
- 正则表达式学习(三)正则表达式各种操作符的运算优先级
- 仿android系统主界面 下方的小按钮滑动
- 读书笔记整理二:11g存储增强