首页 Android 3D 游戏开发教程

Android 3D 游戏开发教程

举报
开通vip

Android 3D 游戏开发教程 Android 3D 游戏开发教程 这几篇 Android 3D 游戏开发的文章原文出自一位德国人 Martin 写的文章,有 lixinso 翻译为中文。 第一部分首先介绍OpenGL相关的术语,并引导你开始 3D开发的第一步。 这个关于 3D游戏的系列的叫做 Vortex . 这个教程主要focus在 3D编程上,其他的东西比如菜单和程序生命周期虽然是 代码的一部分,但是在这里不会被提到。www.linuxidc.com 首先开始介绍 OpenGL 的术语。 顶点 Verte...

Android 3D 游戏开发教程
Android 3D 游戏开发教程 这几篇 Android 3D 游戏开发的文章原文出自一位德国人 Martin 写的文章,有 lixinso 翻译为中文。 第一部分首先介绍OpenGL相关的术语,并引导你开始 3D开发的第一步。 这个关于 3D游戏的系列的叫做 Vortex . 这个教程主要focus在 3D编程上,其他的东西比如菜单和程序生命周期虽然是 代码的一部分,但是在这里不会被提到。www.linuxidc.com 首先开始介绍 OpenGL 的术语。 顶点 Vertex 顶点是 3D 空间中的一个点,也是许多对象的基础元素。在 OpenGL 中你可以 生命少至二维坐标(X,Y),多至四维(X,Y,Z,W). w 轴是可选的,默认的值是 1.0. Z 轴也是可选的,默认为 0. 在这个系列中,我们将要用到 3 个主要的坐标 X,Y, Z,因为 W 一般都是被用来作为占位符。vertex 的复数是 vertices(这对非英 语母语的人来说比较重要,因为这容易产生歧义)。所有的对象都是用 vertices 作为它们的点,因为点就是 vertex。 三角形 Triangle 三角形需要三个点才能创建。因此在 OpenGL 中,我们使用 3 个顶点来创建一 个三角形。 多边形 Polygon 多边形是至少有 3 个连接着的点组成的一个对象。三角形也是一个多边形。 图元 Primitives 一个 Primitive 是一个三维的对象,使用三角形或者多边形创建。形象的说,一 个有 50000 个顶点的非常精细的模型是一个 Primitive,同样一个只有 500 个顶 点的低模也叫做一个 Primitive。 现在我们可以开始变成了。 创建一个 工程 路基工程安全技术交底工程项目施工成本控制工程量增项单年度零星工程技术标正投影法基本原理 交 Vortex,activity 也是这个名字。我们的工程应该大概是这个 样子的: package com.droidnova.android.games.vortex; import android.app.Activity; import android.os.Bundle; public class Vortex extends Activity { private static final String LOG_TAG = Vortex.class.getSimpleName(); private VortexView _vortexView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); _vortexView = new VortexView(this); setContentView(_vortexView); } www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 } 复制代码 如上图所示,我们已经添加了 View。让我们看一下 VortexView 类。 package com.droidnova.android.games.vortex; import android.content.Context; import android.opengl.GLSurfaceView; public class VortexView extends GLSurfaceView { private static final String LOG_TAG = VortexView.class.getSimpleName(); private VortexRenderer _renderer; public VortexView(Context context) { super(context); _renderer = new VortexRenderer(); setRenderer(_renderer); } } 复制代码 如上所示,我们继承了GLSurfaceView是因为它会帮助我们画 3D图像。接下来 看VortexRenderer类。一个Renderer包含画一帧所必需的所有东西。 引用自 这儿references 。Renderer负责OpenGL call来render一个帧。 来看一下这个类: package com.droidnova.android.games.vortex; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.opengl.GLSurfaceView; public class VortexRenderer implements GLSurfaceView.Renderer { private static final String LOG_TAG = VortexRenderer.class.getSimpleName(); private float _red = 0.9f; private float _green = 0.2f; private float _blue = 0.2f; @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // Do nothing special. } www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 @Override public void onSurfaceChanged(GL10 gl, int w, int h) { gl.glViewport(0, 0, w, h); } @Override public void onDrawFrame(GL10 gl) { // define the color we want to be displayed as the "clipping wall" gl.glClearColor(_red, _green, _blue, 1.0f); // clear the color buffer to show the ClearColor we called above... gl.glClear(GL10.GL_COLOR_BUFFER_BIT); } } 复制代码 好,我们做了什么? 首先我们实现了 GLSurfaceView.Renderer 这个接口,主要是实现 3 个方法: onSurfaceCreated(), onSurfaceChanged() 和 onDrawFrame()。这些方 法很容易理解,第一个在 surface 创建以后调用,第二个是在 surface 发生改 变以后调用,例如从竖屏切换到横屏的时候,最后一个方法是当任何时候调用一 个画图方法的时候。 从 11 行到 13 行,我们用浮点数来定义 RGB 颜色系统中的每一个颜色。 在 28 行,我们通过 glClearColor()方法为底色定义了颜色。底色是在我们能看 到的所有东西的后面,所以所有在底色后面的东西都是不可见的。可以想象这种 东西为浓雾,挡住了所有的东西。然后我们将要为之设置距离来 show 一下它怎 么用的。那时候你就一定会明白它是怎么存在的了。 为了让颜色变化可见,我们必须调用 glClear()以及颜色缓冲的 Mask 来清空 buffer,然后为我们的底色使用新的底色。 为了能看到它在起作用,我们这里为 MotionEvent 创建一个 response,使 用它来改变颜色。首先在 VortexRenderer 中来创建一个设置颜色的函数。 public void setColor(float r, float g, float b) { _red = r; _green = g; _blue = b; } 复制代码 下面是 VortexView 类中创建的方法来处理 MotionEvent。 public boolean onTouchEvent(final MotionEvent event) { queueEvent(new Runnable() { public void run() { _renderer.setColor(event.getX() / getWidth(), event.getY() / getHeight(), 1.0f); } }); return true; www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 } 复制代码 我们创建了一个匿名的 Runnable 对象,这里的 run()方法调用 renderer 中的 setColor 方法。这有会根据 MotionEvent 坐标做一些小的计算。 现在我们已经有了一个小小的程序来使用 OpenGl 来改变我们的背景色了。 在德语中我们叫这种小 case 为“Mit Kanonen auf Spatzen schießen”,翻 译过来应该是“你在车轮上打死了一只苍蝇”。这说的恰到好处,这只是一个最最 最小的例子,要学习 OpenGL,你现在要准备更多更多的东西。 这部分最后提一下 OpenGL 的文档 documentation for OpenGL 。这个东西 虽然可用想不高,但是它最少是一个文档。 Eclipse 工程源代码 Vortex Part I 在这里下载: 免费下载地址在 http://linux.linuxidc.com/ 用户名与密码都是 www.linuxidc.com 具体下载目录在 /pub/2011/07/17/ 这里是几个截图: www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 ------------------------------------------------------------------ 这个系列的第二部分是关于如何添加一个三角形并可以旋转它。 第一件事情是初始化需要显示的三角形。我们来在 VortexRenderer 类中添加一 个方法 initTriangle()。 // new object variables we need // a raw buffer to hold indices private ShortBuffer _indexBuffer; // a raw buffer to hold the vertices private FloatBuffer _vertexBuffer; private short[] _indicesArray = {0, 1, 2}; private int _nrOfVertices = 3; // code snipped www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 private void initTriangle() { // float has 4 bytes ByteBuffer vbb = ByteBuffer.allocateDirect(_nrOfVertices * 3 * 4); vbb.order(ByteOrder.nativeOrder()); _vertexBuffer = vbb.asFloatBuffer(); // short has 2 bytes ByteBuffer ibb = ByteBuffer.allocateDirect(_nrOfVertices * 2); ibb.order(ByteOrder.nativeOrder()); _indexBuffer = ibb.asShortBuffer(); float[] coords = { -0.5f, -0.5f, 0f, // (x1, y1, z1) 0.5f, -0.5f, 0f, // (x2, y2, z2) 0f, 0.5f, 0f // (x3, y3, z3) }; _vertexBuffer.put(coords); _indexBuffer.put(_indicesArray); _vertexBuffer.position(0); _indexBuffer.position(0); } 复制代码 让我们从新的对象变量开始 . _vertexBuffer 为我们的三角形保存坐 标._indexBuffer 保存索引. _nrOfVertices 变量定义需要多少个顶点.对于一个 三角形来说,一共需要三个顶点. 这个方法首先为这里两个buffer分配必须的内存(14-22行). 接下来我们定 义一些坐标(24-28 行) 后面的注释对用途给予了说明. 在30行,我们将coords数组填充给_vertexBuffer . 同样在31行将 indices 数组填充给_indexBuffer 。最后将两个 buffer 都设置 position 为 0. 为了防止每次都对三角形进行初始化,我们仅仅在 onDrawFrame()之前的行数 调用它一次。一个比较好的选择就是在 onSurfaceCreated()函数中. @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // preparation gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); initTriangle(); } 复制代码 glEnableClientState() 设置OpenGL使用vertex数组来画。这是很重要的,因 为如果不这么设置OpenGL不知道如何处理我们的数据。接下来我们就要初始 化我们的三角形。 为什么我们不需使用不同的buffer? 在新的onDrawFrame()方法中我们必须 www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 添加一些新的OpenGL调用。 @Override public void onDrawFrame(GL10 gl) { // define the color we want to be displayed as the "clipping wall" gl.glClearColor(_red, _green, _blue, 1.0f); // clear the color buffer to show the ClearColor we called above... gl.glClear(GL10.GL_COLOR_BUFFER_BIT); // set the color of our element gl.glColor4f(0.5f, 0f, 0f, 0.5f); // define the vertices we want to draw gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer); // finally draw the vertices gl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBuffer); } 复制代码 好,一步一步地看。 glClearColor() 和 glClear() 在教程 I 部分已经提到过。在第 10 行使用 glColor4f(red, green, blue, alpha)设置三角形为暗红色 . 在第 13 行,我们使用 glVertexPointer()初始化 Vertex Pointer. 第一个参数是 大小,也是顶点的维数。我们使用的是 x,y,z 三维坐标。第二个参数,GL_FLOAT 定义 buffer 中使用的数据类型。第三个变量是 0,是因为我们的坐标是在数组 中紧凑的排列的,没有使用 offset。最后哦胡第四个参数顶点缓冲。 最后,glDrawElements()将所有这些元素画出来。第一个参数定义了什么样的 图元将被画出来。第二个参数定义有多少个元素,第三个是 indices 使用的数据 类型。最后一个是绘制顶点使用的索引缓冲。 当最后测试这个应用的使用,你会看到一个在屏幕中间静止的三角形。当你点击 屏幕的时候,屏幕的背景颜色还是会改变。 现在往里面添加对三角形的旋转。下面的代码是写在 VortexRenderer 类中的. private float _angle; public void setAngle(float angle) { _angle = angle; } 复制代码 glRotatef()方法在glColor4f()之前被onDrawFrame()调用. @Override public void onDrawFrame(GL10 gl) { // set rotation gl.glRotatef(_angle, 0f, 1f, 0f); www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 gl.glColor4f(0.5f, 0f, 0f, 0.5f); // code snipped } 复制代码 这时候我们可以绕 y 轴旋转。如果需要改变只需要改变 glRotate()方法中的 0f。 这个参数中的值 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 示一个向量,标志三角形绕着旋转的坐标轴。 要让它可用,我们必须在 VortexView 中的 onTouchEvent()中添加一个调用。 public boolean onTouchEvent(final MotionEvent event) { queueEvent(new Runnable() { public void run() { _renderer.setColor(event.getX() / getWidth(), event.getY() / getHeight(), 1.0f); _renderer.setAngle(event.getX() / 10); } }); return true; } 复制代码 上面代码中除以 10 是为了减小角度变换的速度。 现在编译运行这个程序。如果你在屏幕的最左边点击,你会看到三角形轻微旋转。 如果你将手指移到右边,旋转的速度就会变得很快。 Eclipse工程的源代码在这里下载(原链接): Vortex Part II www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 -------------------------------------------------------------------------- 在这个系列的第三部分给你show一下如何停止三角形的转动,并告诉你原来的 旋转其实只是在三角形上进行的旋转,而不是在摄像机“camera”上进行的旋 转。 我们希望能对旋转进行更多的控制。为此,在每次调用onDrawFrame()方法的 时候都会重置这个矩阵。这会重设三角形的角度以便其总是可以旋转到给定的角 度。 @Override public void onDrawFrame(GL10 gl) { // define the color we want to be displayed as the "clipping wall" gl.glClearColor(_red, _green, _blue, 1.0f); // reset the matrix - good to fix the rotation to a static angle gl.glLoadIdentity(); // clear the color buffer and the depth buffer to show the ClearColor // we called above... gl.glClear(GL10.GL_COLOR_BUFFER_BIT); www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 // code snipped } 复制代码 在 VortexView 类中,你应该删除“除以 10”以便其可以旋转范围更大一些。 _renderer.setAngle(event.getX()); 复制代码 如果尝试了这些,你将会看到旋转只会根据触摸的到的位置来旋转。如果没有触 摸屏幕,旋转不会发生改变。 下一件事情:我们旋转的是三角形本身,还是旋转的 view/camera? 为了验证它,最简单的办法是创建第二个不旋转的三角形进行对照。 最快也是最笨的办法是 copy&paste initTriangle()方法为一个新的方法 initStaticTriangle(),copy&paste 其中的两个 buffer,copy&paste 并修改 onDrawFrame()方法中的最后四行。 不要忘记了改变第二个三角形的颜色以及改变第二个三角形的坐标,这样方便我 们能看到两个三角形。我将每个地方的 0.5f 都改成了 0.4f. 这里是整个的类: package com.droidnova.android.games.vortex; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.ShortBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.opengl.GLSurfaceView; public class VortexRenderer implements GLSurfaceView.Renderer { private static final String LOG_TAG = VortexRenderer.class.getSimpleName(); private float _red = 0f; private float _green = 0f; private float _blue = 0f; // a raw buffer to hold indices allowing a reuse of points. private ShortBuffer _indexBuffer; private ShortBuffer _indexBufferStatic; // a raw buffer to hold the vertices private FloatBuffer _vertexBuffer; private FloatBuffer _vertexBufferStatic; www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 private short[] _indicesArray = {0, 1, 2}; private int _nrOfVertices = 3; private float _angle; @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // preparation gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); initTriangle(); initStaticTriangle(); } @Override public void onSurfaceChanged(GL10 gl, int w, int h) { gl.glViewport(0, 0, w, h); } public void setAngle(float angle) { _angle = angle; } @Override public void onDrawFrame(GL10 gl) { // define the color we want to be displayed as the "clipping wall" gl.glClearColor(_red, _green, _blue, 1.0f); // reset the matrix - good to fix the rotation to a static angle gl.glLoadIdentity(); // clear the color buffer to show the ClearColor we called above... gl.glClear(GL10.GL_COLOR_BUFFER_BIT); // draw the static triangle gl.glColor4f(0f, 0.5f, 0f, 0.5f); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBufferStatic); gl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBufferStatic); // set rotation for the non-static triangle gl.glRotatef(_angle, 0f, 1f, 0f); www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 gl.glColor4f(0.5f, 0f, 0f, 0.5f); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer); gl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBuffer); } private void initTriangle() { // float has 4 bytes ByteBuffer vbb = ByteBuffer.allocateDirect(_nrOfVertices * 3 * 4); vbb.order(ByteOrder.nativeOrder()); _vertexBuffer = vbb.asFloatBuffer(); // short has 4 bytes ByteBuffer ibb = ByteBuffer.allocateDirect(_nrOfVertices * 2); ibb.order(ByteOrder.nativeOrder()); _indexBuffer = ibb.asShortBuffer(); float[] coords = { -0.5f, -0.5f, 0f, // (x1, y1, z1) 0.5f, -0.5f, 0f, // (x2, y2, z2) 0f, 0.5f, 0f // (x3, y3, z3) }; _vertexBuffer.put(coords); _indexBuffer.put(_indicesArray); _vertexBuffer.position(0); _indexBuffer.position(0); } private void initStaticTriangle() { // float has 4 bytes ByteBuffer vbb = ByteBuffer.allocateDirect(_nrOfVertices * 3 * 4); vbb.order(ByteOrder.nativeOrder()); _vertexBufferStatic = vbb.asFloatBuffer(); // short has 4 bytes ByteBuffer ibb = ByteBuffer.allocateDirect(_nrOfVertices * 2); ibb.order(ByteOrder.nativeOrder()); _indexBufferStatic = ibb.asShortBuffer(); float[] coords = { www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 -0.4f, -0.4f, 0f, // (x1, y1, z1) 0.4f, -0.4f, 0f, // (x2, y2, z2) 0f, 0.4f, 0f // (x3, y3, z3) }; _vertexBufferStatic.put(coords); _indexBufferStatic.put(_indicesArray); _vertexBufferStatic.position(0); _indexBufferStatic.position(0); } public void setColor(float r, float g, float b) { _red = r; _green = g; _blue = b; } } 复制代码 如果作了以上这些,你会看到只有一个三角形可以旋转。如果你想两个都可以旋 转,只需要在“draw the static triangle”这个注释的旁边也给它加上一行代码 就可以了。 编译并运行这个程序,你可以看到绿色的三角形在旋转,同时红色的三角形还是 呆在原来的地方。 这也充分验证了我们的答案,我们旋转的只是三角形而不是整个场景。 Eclipse工程源代码在这里下载: Vortex Part III www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 ---------------------------------------------------------------- 这个系列的第四部分讲如何给三角形添加颜色。 在上一部分我们创建了第二个静态的三角形来验证我们旋转的是三角形而不是 整个场景。这里我们将这个静态的三角形删除掉。删除掉initStaticTriangle()函 数,删除两个buffer,_indexBufferStatic和_vertexBufferStatic。同时也要删 除原来初始静止三角形时用到的onDrawFrame()中的最后四行。 新的onDrawFrame()方法如下: @Override public void onDrawFrame(GL10 gl) { // define the color we want to be displayed as the "clipping wall" gl.glClearColor(_red, _green, _blue, 1.0f); // reset the matrix - good to fix the rotation to a static angle gl.glLoadIdentity(); // clear the color buffer to show the ClearColor we called above... gl.glClear(GL10.GL_COLOR_BUFFER_BIT); www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 // set rotation for the non-static triangle gl.glRotatef(_angle, 0f, 1f, 0f); gl.glColor4f(0.5f, 0f, 0f, 0.5f); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer); gl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBuffer); } 复制代码 现在我们为保存颜色信息创建一个新的 buffer。这个_colorBuffer 是一个对象变 量,但是我们需要在 initTriangle()方法中定义颜色并填充这个 buffer. // code snipped // a raw buffer to hold the colors private FloatBuffer _colorBuffer; // code snipped private void initTriangle() { // float has 4 bytes ByteBuffer vbb = ByteBuffer.allocateDirect(_nrOfVertices * 3 * 4); vbb.order(ByteOrder.nativeOrder()); _vertexBuffer = vbb.asFloatBuffer(); // short has 4 bytes ByteBuffer ibb = ByteBuffer.allocateDirect(_nrOfVertices * 2); ibb.order(ByteOrder.nativeOrder()); _indexBuffer = ibb.asShortBuffer(); // float has 4 bytes, 4 colors (RGBA) * number of vertices * 4 bytes ByteBuffer cbb = ByteBuffer.allocateDirect(4 * _nrOfVertices * 4); cbb.order(ByteOrder.nativeOrder()); _colorBuffer = cbb.asFloatBuffer(); float[] coords = { -0.5f, -0.5f, 0f, // (x1, y1, z1) 0.5f, -0.5f, 0f, // (x2, y2, z2) 0.5f, 0.5f, 0f // (x3, y3, z3) }; float[] colors = { 1f, 0f, 0f, 1f, // point 1 0f, 1f, 0f, 1f, // point 2 0f, 0f, 1f, 1f, // point 3 }; www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 _vertexBuffer.put(coords); _indexBuffer.put(_indicesArray); _colorBuffer.put(colors); _vertexBuffer.position(0); _indexBuffer.position(0); _colorBuffer.position(0); } 复制代码 我们创建了一个 FloatBuffer 类型的对象变量_colorBuffer(第四行)。在 initTriangle()方法中我们为新的颜色 buffer 分配了足够多的内存(19-21 行)。接 下来我们创建了一个 float 数组(23-27 行),每个顶点有 4 个值。 这个结构是 RGBA(Red,Green,Blue,alpha)的,所以第一个顶点是红颜色,第二个颜 色是绿色,第三个颜色是蓝色。最后两部和_vertexBuffer 相同。我们将颜色数 组放到 buffer 里面,将 buffer 的 position 设置为 0. 当这些准备工作都做完了以后,我们开始告诉 OpenGL ES 使用我们的颜色数 组。这通过 glEnableClientState(),以及 glColorPointer()来完成,和 vertexBuffer 类似。 @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // preparation gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_COLOR_ARRAY); initTriangle(); } // code snipped @Override public void onDrawFrame(GL10 gl) { // code snipped // gl.glColor4f(0.5f, 0f, 0f, 0.5f); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer); gl.glColorPointer(4, GL10.GL_FLOAT, 0, _colorBuffer); gl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBuffer); } 复制代码 第五行我们enable了color mode。在 17 行我们设置了颜色 pointer。参数 4 表示RGBA(RGBA刚好是四个值),其余的几个参数大家都比较熟悉了。 也许你也看到了,我们注释掉了 15 行,因为我们使用的是color mode,所以不 再需要glColor4f。它会覆盖,所以我们可以注注释掉或者删除掉他。 www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 Eclipse工程源代码参考: Vortex Part IV www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 --------------------------------------------------------------------------- 系列的第五部分讲如果创建你的第一个完整的 3D对象。这个case中是一个 4 面 的金字塔。 为了让我们接下来的开发更容易,这里需要做一些准备。 我们必须将计算buffer以及创建数组时的大变得更加动态。 private int _nrOfVertices = 0; private void initTriangle() { float[] coords = { // coodinates }; _nrOfVertices = coords.length; float[] colors = { // colors }; short[] indices = new short[] { www.linuxidc.com Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 // indices }; // float has 4 bytes, coordinate * 4 bytes ByteBuffer vbb = ByteBuffer.allocateDirect(coords.length * 4); vbb.order(ByteOrder.nativeOrder()); _vertexBuffer = vbb.asFloatBuffer(); // short has 2 bytes, indices * 2 bytes ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2); ibb.order(ByteOrder.nativeOrder()); _indexBuffer = ibb.asShortBuffer(); // float has 4 bytes, colors (RGBA) * 4 bytes ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4); cbb.order(ByteOrder.nativ
本文档为【Android 3D 游戏开发教程】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_917456
暂无简介~
格式:pdf
大小:575KB
软件:PDF阅读器
页数:39
分类:互联网
上传时间:2011-08-07
浏览量:19