Andriod OpenGL 教程 02 - 第一个多边形
来源:互联网 发布:香港有淘宝网吗 编辑:程序博客网 时间:2024/03/28 19:26
关键字: android OpenGL 移动开发 教程
在第一课的基础上,我们添加了一个三角形和一个四边形,在这里我们使用glDrawElements方法来绘制我们的第一个三角形和使用glDrawArrays来绘制我们的第一个四边形,来演示在OpenGL ES中怎样绘制最基本的图元。
在OpenGL ES中不支持glVertex方法,因此在绘制三角形和四边形的方法和NeHe教程中的方法有所不同。为了是程序条理清楚,我们分别实现MyTriangle和MySquare来绘制我们的一个三角形和四边形。
现在假设MyTriangl和 MySquare已经实现好,在后面详细叙述这两个类的实现。在MyGLRender的onDrawFrame中的代码如下:
public void onDrawFrame(GL10 gl){// 清除屏幕和深度缓存gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);// 重置当前的模型观察矩阵gl.glLoadIdentity();// 左移 1.5 单位,纵深向里移动 6.0gl.glTranslatef(-1.5f,0.0f,-6.0f);// 画三角形triangle.draw(gl);// 右移3单位gl.glTranslatef(3.0f,0.0f,0.0f);// 画四边形quad.draw(gl);}
当我们调用glLoadIdentity ()之后,实际上将当前点移到了屏幕中心,X坐标轴从左至右,Y坐标轴从下至上,Z坐标轴从里至外。OpenGL屏幕中心的坐标值是X和Y轴上的0.0f点。中心左面的坐标值是负值,右面是正值。移向屏幕顶端是正值,移向屏幕底端是负值。移入屏幕深处是负值,移出屏幕则是正值。
glTranslatef(x, y, z)沿着 X, Y和 Z轴移动。根据前面的次序,下面的代码沿着X轴左移1.5个单位,Y轴不动(0.0f),最后移入屏幕6.0f个单位。注意在glTranslatef(x, y, z)中移动的时候,它并不是相对屏幕中心移动,而是相对与当前所在的屏幕位置。
现在我们已经移到了屏幕的左半部分,并且将视图推入屏幕背后足够的距离以便我们可以看见全部的场景-创建三角形。triangle.draw(gl)来完成我们的第一个三角形绘制。
在屏幕的左半部分画完三角形后,我们要移到右半部分来画正方形。为此要再次使用glTranslate。这次右移,所以X坐标值为正值。因为前面左移了1.5个单位,这次要先向右移回屏幕中心(1.5个单位),再向右移动1.5个单位。总共要向右移3.0个单位。quad.draw(gl)来完成我们的第一四边形的绘制。
MyTriangle.java:
package wintop.gllesson02;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import javax.microedition.khronos.opengles.GL10;// 一个三角形包含三个顶点public class MyTriangle {private FloatBuffer vertexBuffer;// 顶点数组缓冲区private ByteBuffer indexBuffer;// 顶点索引缓冲区private float[] vertices = {// 三角形的顶点 0.0f, 1.0f, 0.0f,// 0. 顶-1.0f, -1.0f, 0.0f,// 1. 左下角 1.0f, -1.0f, 0.0f// 2. 右下角};private byte[] indices = {0, 1, 2};// 顶点索引(逆时针方向 CCW)// 构造函数 - 设置顶点数组public MyTriangle(){// 设置顶点数组,顶点数据为浮点数据类型。一个浮点类型的数据长度为四个字节ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);vbb.order(ByteOrder.nativeOrder());// 使用原生字节顺序vertexBuffer = vbb.asFloatBuffer();// 将字节类型缓冲区转换成浮点类型vertexBuffer.put(vertices);// 将数据复制进缓冲区vertexBuffer.position(0);// 定位到初始位置// 设置索引数组,索引数据位字节类型indexBuffer = ByteBuffer.allocateDirect(indices.length);indexBuffer.put(indices);indexBuffer.position(0);}// 渲染三角形public void draw(GL10 gl) {// 使能顶点数据并指定顶点数据缓冲区gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);// 通过索引数组绘制图元gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_BYTE, indexBuffer);gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);}}
然后我们分配一个顶点数组缓冲区,并将数据传送到缓冲区中。在这里我们使用nio类型的缓冲区,这是因为这种类型的缓冲区位于原生堆中,不会使用垃圾收集机制。
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder()); // 使用原生字节顺序
vertexBuffer = vbb.asFloatBuffer(); //将字节类型缓冲区转换成浮点类型
vertexBuffer.put(vertices); //将数据复制进缓冲区
vertexBuffer.position(0); //定位到初始位置
为了使用顶点数组渲染方式,我们必须使能client-state vertex-array:
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
我们可以直接使用glDrawArrays()方法来直接渲染顶点数组,或者使用glDrawElements()方法通过索引数组来渲染。
在这里我们使用了索引数组,顶点按逆时针方向(CCW)进行索引,法向为屏幕向外(正Z轴方向)。
//设置索引数组,索引数据位字节类型
indexBuffer = ByteBuffer.allocateDirect(indices.length);
indexBuffer.put(indices);
indexBuffer.position(0);
在draw()方法中实现我们第一个三角形的渲染。
首先,我们使能client-state vertex-array
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
然后,我们通过缓冲区指定位置:
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
// gl*Pointer(int size, int type, int stride, Buffer pointer)
// size: 每个顶点的坐标数目 (必须为 2, 3, or 4).
// type: 顶点坐标数据类型, GL_BYTE, GL_SHORT, GL_FIXED, or GL_FLOAT
// stride: 两个连续顶点间偏移的字节数.
最后我们使用glDrawElements()来绘制三角形。该方法使用索引数组来引用顶点和颜色值。
gl.glDrawElements(GL10.GL_TRIANGLES, numIndices, GL10.GL_UNSIGNED_BYTE, indexBuffer);
// glDrawElements(int mode, int count, int type, Buffer indices)
// mode: GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, or GL_TRIANGLES
// count: 要渲染的顶点数目.
// type: 索引数据类型(必须为 GL_UNSIGNED_BYTE或 GL_UNSIGNED_SHORT).
// indices: 索引数组指针.
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
MySquare.java
package wintop.gllesson02;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import javax.microedition.khronos.opengles.GL10;// 使用三角形带(TRIANGLE_STRIP)绘制一个正方形public class MySquare {private FloatBuffer vertexBuffer;// 顶点数组缓冲区private float[] vertices = {// 正方形的顶点数据-1.0f, -1.0f, 0.0f,// 0.左下角 1.0f, -1.0f, 0.0f,// 1.右下角-1.0f, 1.0f, 0.0f,// 2.左上角 1.0f, 1.0f, 0.0f,// 3.右上角};// 构造函数 - 设置顶点缓冲区public MySquare() {// 设置顶点数组,顶点数据为浮点数据类型。一个浮点类型的数据长度为四个字节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.glEnableClientState(GL10.GL_VERTEX_ARRAY);gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);// 通过顶点数组直接绘制图元序列gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length/3);gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);}}
在OpenGL ES中四边形不是图元,因为我们需要用两个三角形来实现绘制四边形。我们使用TRIANGLE_STRIP,按逆时针方向组合两个三角形V0V1V2和V2V1V3。如下图所示
最后运行结果如图所示:
源代码下载地址:http://download.csdn.net/detail/seniorwizard/4460814
- Andriod OpenGL 教程 02 - 第一个多边形
- 【Qt OpenGL教程】02:你的第一个多边形
- OpenGL 第一个多边形
- NeHe OpenGL教程第二课 你的第一个多边形
- Jeff Molofee(NeHe)的OpenGL教程 OpenGL教程之第一个多边形
- 第一个多边形
- OpenGL开发教程之--第一个OpenGL程序
- Andriod OpenGL 教程 04 - 旋转
- Andriod OpenGL 教程 08 - 混合
- OpenGL ES 2.0教程:你的第一个三角形(1)
- OpenGL ES2.0教程:你的第一个立方体(5)
- OpenGL ES 2.0教程:你的第一个三角形(1)
- OpenGL--第一个OpenGL程序
- [OpenGL]第一个OpenGL程序
- Andriod OpenGL 教程 03 - 添加颜色
- Andriod OpenGL 教程 05 - 3D空间
- Andriod OpenGL 教程 06 - 纹理映射
- Andriod OpenGL 教程 09 - 移动图像
- android 解析json数据格式
- 两个简单的Demo示例向读者展示Flash和ASP.NET交互原理以及过程
- 金山开源(bkwin) 定义界面时按钮没反应的问题
- Android获取文件目录路径
- 杭电1398,1028,1085//赤裸裸的母函数
- Andriod OpenGL 教程 02 - 第一个多边形
- CXF—六天系列—第五天—CXF+Spring配置客户端--HelloWorld!
- CXF—六天系列—第六天—找不到MessageFactoryImpl和BouncyCastleProvider类报错
- 【IAR】Error[Li005] no definition for "__program_start"
- hdu1595
- Android模拟器学framework和driver之battery & backlight-----5. backlight in linux
- 选择原料工厂
- 监视和截获指定进程网络数据传输WSockExpert0.6 工具介绍和使用实例
- hdoj1114