ImageVerifierCode 换一换
格式:DOCX , 页数:46 ,大小:369.70KB ,
资源ID:1095676      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-1095676.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Android下Opengl ES导引.docx)为本站会员(b****1)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

Android下Opengl ES导引.docx

1、Android下Opengl ES导引Android下Opengl ES导引ch2zh1编译(2011-8-7)-第一部分这里打算写几篇关于Android手机上的openGL ES 导引文章。对于不同的设备,OpenGL ES的理论是相同的,所以,也可以很容易就把这个导引转换到其它平台上。我不能总记得我曾在什么地方找到过特殊信息,所以这里给出的参考文献就引文来讲可能并不总是正确的。如果你认为我这里引用了你的资料,而又忘记把你的名字添加到引用者中,请给我发邮件。在例子代码中,每一个函数都有两个不同的链接。一个链接是链接到Android资料,而后一个将链接到OpenGL资料。例如: gl.glCl

2、earColor(0.0f,0.0f,0.0f,0.5f);/OpenGL 资料。注:在翻译文档中,不考虑资料的链接,如果想查看原文,请收索OpenGL ES Tutorial for Android。现在就让我们开始吧。 在这个导引中我将向你展示怎样设置你的OpenGL观察控件,这总是一个最好的开始。设置OpenGL ES观察 设置OpenGL观察并不困难,而且在Android上它还相当容易。实际上你只需最两件事情就可以了。GLSurfaceViewGLSurfaceView 是Android1.5中一个API类,用于辅助编写OpenGL ES应用的。 提供胶粘代码来连接OpenGL ES到

3、Android的View观察系统。 提供胶粘代码来使OpenGL ES与活动的生命期一同工作。 使它易于选择一个适当的帧缓冲像素格式。 建立个管理单独的演播线程,使动画效果平滑。 提供易于使用的排错工具,跟踪OpenGL ES API的调用和检查错误。如果你想要快速的开发OpenGL ES应用,现在就应该可以开始了。唯一的一个你需要调用的函数是: Public void setRender(GLSurfaceView.Render renderer)请阅读GLSurfaceView来获得更多的帮助。 GLSurfaceView.Renderer GLSurfaceView.Renderer是一

4、个普通的演播器接口。在你自己的演播器实现中,应该包含所有演播一个帧的调用。有三个函数需要实现: /在表面建立时或再建立时调用的函数 public void onSurfacCreated(GL10 gl,EGLConfig config) /画当前帧时调用 public void onDrawFrame(GL10 gl) /表面尺寸改变时调用 Public void onSuraceChanged(GL10 gl,int width,int height)onSurfaceCreated 在这里通常设置演播期间不改变的所有东西。比如屏幕要清除到的颜色,允许Z-缓冲等。onDrawFrame 这

5、里是实际绘画发生的地方。onSurfaceChanged 如果你的设备支持水平和垂直翻转,当翻转发生时,这个函数则被调用。在这里你要做的是设置比率的变化。请阅读GLSurfaceView.Renderer来获得更多的帮助。把这些都穿连到一起 首先建立一个活动(activity),我们要保持它的清晰和简单。package se.jayway.opengl.tutorial;import android.app.Activity;import android.opengl.GLSurfaceView;import android.os.Bundle;public class TutorialPar

6、tI extends Activity /* Called when the activity is first created. */ Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); GLSurfaceView view = new GLSurfaceView(this); view.setRenderer(new OpenGLRenderer(); setContentView(view); 我们的演播器有一小点设置工作要做,代码如下,我们也更详细一点地

7、解释这些代码。package se.jayway.opengl.tutorial;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.opengl.GLU;import android.opengl.GLSurfaceView.Renderer;public class OpenGLRenderer implements Renderer /* * (non-Javadoc) * * see * android.opengl.

8、GLSurfaceView.Renderer#onSurfaceCreated(javax. * microedition.khronos.opengles.GL10, javax.microedition.khronos. * egl.EGLConfig) */public void onSurfaceCreated(GL10 gl, EGLConfig config) / 设置背景那个颜色到黑色( rgba ). gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); / OpenGL docs. / 允许阴影平滑, 默认也可以,不是必须的 gl.glShadeM

9、odel(GL10.GL_SMOOTH);/ OpenGL docs. / 深度缓冲设置 gl.glClearDepthf(1.0f);/ OpenGL docs. / 允许深度检测 gl.glEnable(GL10.GL_DEPTH_TEST);/ OpenGL docs. / 要做的深度检测类型 gl.glDepthFunc(GL10.GL_LEQUAL);/ OpenGL docs. / 真是细微的透视计算 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, / OpenGL docs. GL10.GL_NICEST); /* * (non-Ja

10、vadoc) * * see * android.opengl.GLSurfaceView.Renderer#onDrawFrame(javax. * microedition.khronos.opengles.GL10) */public void onDrawFrame(GL10 gl) / 清除屏幕和深度缓冲 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | / OpenGL docs. GL10.GL_DEPTH_BUFFER_BIT);/* * (non-Javadoc) * * see * android.opengl.GLSurfaceView.Rend

11、erer#onSurfaceChanged(javax.* microedition.khronos.opengles.GL10, int, int) */public void onSurfaceChanged(GL10 gl, int width, int height) / 设置当前视口到新尺寸 gl.glViewport(0, 0, width, height);/ OpenGL docs. / 选择投影矩阵 gl.glMatrixMode(GL10.GL_PROJECTION);/ OpenGL docs. / 重置投影矩阵 gl.glLoadIdentity();/ OpenGL

12、docs. / 计算窗口的外观比率 GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f, 100.0f); / 选择模式观察矩阵 gl.glMatrixMode(GL10.GL_MODELVIEW);/ OpenGL docs. / 重置模式观察矩阵 gl.glLoadIdentity();/ OpenGL docs.全屏显示把下面这些行代码加到OpenGLDemo类中,这将设置应用到全屏显示。 public void onCreate(Bundle savedInstanceState) super.onCre

13、ate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); / (NEW) getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); / (NEW) . /前面的代码 这无论在外观和运行上都漂亮得多。如果你编译并运行这个Demo,将会看到一个完美的黑色屏幕。-第二部分 前面的第一部分说明了怎样设置GLSurfaceView的所有技术。一定要仔

14、细阅读,这实际上是能够继续下去的重要条件。建立多边形 在这一节中我们将首先建立和演播一个多边形。建立3D模式使用较少的元素(顶点,边,表面,和多边形),这些都可以单独处理。顶点(Vertex)顶点(vertex/vertices)是3D模型的最小构建块。一个顶点就是一个点,在这一点上两个或多个边交接。在3D模型中,一个顶点可以在所有相关联的边、面和多边形中共享。顶点也可以是照相机或光源位置的表示。在下图中你可以看到用黄色标注的顶点。要在Android中定义顶点,我们使用浮点数组,把它们放进字节缓冲来获得较好的性能,请看右侧的图像,匹配顶点的代码如下:private float vertices

15、 = -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, 右上;/ 一个浮点是4个字节,因此要用顶点数乘以4。ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);vbb.order(ByteOrder.nativeOrder();FloatBuffer vertexBuffer = vbb.asFloatBuffer();vertexBuffer.put(vert

16、ices);vertexBuffer.position(0);不要忘了浮点是4字节,用顶点数乘以它来获得正确的缓冲尺寸。OpenGL ES在演播时有一种途径使用这些函数。默认情况下,绝大多数这些函数都是不被允许的,所以你必须记住要打开你可能要是用的函数。你也可能需要告诉这些函数所要做的工作。因此,在我们这个顶点的例子中,需要告诉OpenGL ES准备好了用我们建立的顶点缓冲来进行工作,我们还需要告诉它缓冲在哪儿。/ 在演播时允许顶点缓冲写入和使用。gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);/ OpenGL docs./ 指定顶点数组的位置和格式/

17、 演播时使用的坐标gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); / OpenGL docs.在使用完后一定不要忘了禁止它。/ 禁止顶点缓冲gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);/ OpenGL docs.边(Edge)边是在两个顶点之间的线段。它们是表面和多边形的边缘线。在3D模型中,便可以在两个邻近表面或多边形之间共享。转换一条边,影响所有相连接的顶点,面和多边形。在OpenGL ES中,我们不能定义边,你只能通过给定的顶点定义面,这将至少构建三条边。如果你想要修改一条边,你

18、应该改变产生这条边的两个顶点。在下图中,你可以看到用黄色标注的边。面(Face)面是一个三角形,面就是这三个角顶点和三个边所围成的表面,变换一个面影响所有关联的顶点,边和多边形。顺序的关系在环绕面的时候,重要都是右方向环绕,因为环绕方向定义了面的那一边是正面那一边是背面。为什么这很重要呢,因为要获得性能上的提高,我们不想画两个边,所以关闭了背面。一个好的方法是在整个工程中都使用相同的环绕方向。可以使用函数glFrontFace来改变哪个环绕方向定义正面。 gl.glFrontFace(GL10.GL_CCW); / OpenGL docs要使OpenGL ES跳过已经画在屏幕上的面,可以使用某

19、些称之为背面消隐的方法。这所要做的就是通过检查右序的环绕方向确定是否一个图形多边形对象是可视的。 gl.glEnable(GL10.GL_CULL_FACE); / OpenGL docs当然可以改变面的那一边应该被画出,或不被画出。 gl.glCullFace(GL10.GL_BACK); / OpenGL docs多边形(Polygon)在环绕面时,一定要记住我们已经确定使用默认的环绕方向,也就是说逆时针方向。如右图所示,下面的代码说明了怎样环绕这个方块的。private short indices = 0, 1, 2, 0, 2, 3 ;为了获得性能的提高,我们把这个也放到字节缓冲区中。

20、/短整数(short)占两个字节,因而我们用顶点数乘以2。ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);ibb.order(ByteOrder.nativeOrder();ShortBuffer indexBuffer = ibb.asShortBuffer();indexBuffer.put(indices);indexBuffer.position(0);不要忘了短整数占两个字节,所以用顶点数乘以2是字节缓冲的正确尺寸。演播器(Render)是要在屏幕上观察效果的时候了。有两个函数用来画图,我们必须确定使用哪一

21、个。这两个函数是:public abstract void glDrawArrays(int mode, int first, int count) / OpenGL docsglDrawArrays 函数使用我们在构造缓冲区verticesBuffer时的顶点顺序画顶点构图。public abstract void glDrawElements(int mode, int count, int type, / OpenGL docs Buffer indices) glDrawElements 函数需要稍微多一点参数才能画顶点构图。它需要知道所要画顶点的顺序,也就是一个索引缓冲(indice

22、sBuffer)。假设我们已经给出了一个索引缓冲(这是我们以后打算使用的方式)。这个函数所要做的是它不仅要知道它应该画的是什么,还需要知道演播的原始风格。由于有一些不同的方法来演播这种索引,并且有些方法对于排错而言是不错的方法,所以我们将这些方法统统讨论一遍。什么是演播的原始风格(primitives)GL_POINTS在屏幕上画不同的点。GL_LINE_STRIP一系列相连的线段。GL_LINE_LOOP有点类似于上面的只是增加了最后顶点到第一个顶点的线段,画一个不和曲线段。GL_LINES一对顶点被解释成不同的线段。GL_TRIANGLES顶点被解释成三角形。GL_TRIANGLE_STR

23、IP画一系列三角形 (三个边的多边形)使用顶点v0, v1, v2, 然后v2, v1, v3 (注意顺序), 然后v2, v3, v4, 等等。顺序是保证所画三角形的正面方向相同。这个带子能正确地形成表面的一部分。GL_TRIANGLE_FAN类似于GL_TRIANGLE_STRIP, 除了顶点的顺序是v0, v1, v2, 然后v0, v2, v3, 然后v0, v3, v4, 等等以外。我认为GL_TRIANGLES是是最容易使用的,所以我们现在就开始使用它。把这些都穿连到一起现在,我们把正方形放到一个类中。package se.jayway.opengl.tutorial;import

24、 java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import java.nio.ShortBuffer;import javax.microedition.khronos.opengles.GL10;public class Square / 顶点. 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

25、, / 3, 右上 ; / 我们想要连接这些顶点的顺序。 private short indices = 0, 1, 2, 0, 2, 3 ; / 顶点缓冲 private FloatBuffer vertexBuffer; / 索引缓冲 private ShortBuffer indexBuffer; public Square() / 一个浮点数有四个字节,因此需要用顶点数乘以4。 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); vbb.order(ByteOrder.nativeOrder(); verte

26、xBuffer = vbb.asFloatBuffer(); vertexBuffer.put(vertices); vertexBuffer.position(0); / 短整数占两个字节,因此需要用顶点数乘以2 /来得索引缓冲的正确尺寸 ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2); ibb.order(ByteOrder.nativeOrder(); indexBuffer = ibb.asShortBuffer(); indexBuffer.put(indices); indexBuffer.positio

27、n(0); /* * 这个函数画正方形到屏幕上。 * param gl */public void draw(GL10 gl) / 逆时针环绕。 gl.glFrontFace(GL10.GL_CCW); / OpenGL docs / 允许面遴选。 gl.glEnable(GL10.GL_CULL_FACE); / OpenGL docs / 什么样的遮蔽面被删除(指定背面)。 gl.glCullFace(GL10.GL_BACK); / OpenGL docs / 允许演播时顶点缓冲的写入操作。 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);/ O

28、penGL docs. / 指定演播时顶点数组中数据格式和位置坐标。 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, / OpenGL docs vertexBuffer); gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,/ OpenGL docs GL10.GL_UNSIGNED_SHORT, indexBuffer); / 禁止顶点缓冲。 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); / OpenGL docs / 禁止面遴选。 gl.glDisable

29、(GL10.GL_CULL_FACE); / OpenGL docs在OpenGLRenderer类中,我们必须要初始化这个方块。/ 初始化方块类。Square square = new Square();在画图函数中调用这个花方块的对象。public void onDrawFrame(GL10 gl) / 清除屏幕和深度缓冲。 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | / OpenGL docs. GL10.GL_DEPTH_BUFFER_BIT); / 画方块。 square.draw(gl); / ( NEW )现在,如果你运行这个应用,屏幕仍然是黑的。

30、为什么呢?因为OpenGL ES是从当前位置开始演播的。默认的位置是点:0,0,0这与观察口所定的位置相同。而且OpenGL ES不能演播任何太靠近观察口的东西。解决方法是在演播这个方块之前移动画图位置稍许进入到屏幕内部几步:/ 变换到屏幕内部4个单位。gl.glTranslatef(0, 0, -4); / OpenGL docs在随后的各节中我们将讲解各种不同的变换。再次运行这个应用,你将看到一个方块,但是很快就越来越远地移动到屏幕深处。OpenGL ES在各帧之间并不重置画图点,这需要你自己来做:/ 用同一性矩阵替换当前矩阵(画图点返回坐标原点)gl.glLoadIdentity(); / OpenGL docs现在如果运行这个应用,你就能在固定位置上看到一个方块。-第三部分 上一节我们构建了多边形的概念,这一节我们就讲解有关怎样移动多边形的变换。我们将继续使用前面构建的多边形概念,这样就可以继续使用上面给出的源代码或它的拷贝。 我并不打算用 数学知识来烦扰你,但是我确信了解OpenGL演播一个网栅物体时使用矩阵乘以这个网栅的所有定点是非常重要的

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2