结合上一节的内容,分享完整代码。

先画一个cube,然后通过OnGestureListener去触发onFling使它旋转起来。

OnGestureListener相关的方法我已经都加了注释,可以参考注释去了解有关的方法是干什么的。

旋转相关随便复制了一个,主要说明OnGestureListener。

简单的触摸操作会用一些OnTouchListener复杂的还是需要用到OnGestureListener。

Acivity & Render:

  1. import javax.microedition.khronos.opengles.GL10;
  2. import javax.microedition.khronos.egl.EGLConfig;
  3. import android.app.Activity;
  4. import android.content.Context;
  5. import android.opengl.GLSurfaceView;
  6. import android.opengl.GLU;
  7. import android.os.Bundle;
  8. import android.view.GestureDetector;
  9. import android.view.GestureDetector.OnGestureListener;
  10. import android.view.MotionEvent;
  11. import android.view.Window;
  12.  
  13. public class OpenGL extends Activity implements OnGestureListener {
  14. // 定义旋转角度
  15. private float anglex = 0f;
  16. private float angley = 0f;
  17. static final float ROTATE_FACTOR = 180f;
  18. // 定义手势检测器实例
  19. GestureDetector detector;
  20.  
  21. @Override
  22. public void onCreate(Bundle savedInstanceState) {
  23. super.onCreate(savedInstanceState);
  24. // 去标题栏
  25. requestWindowFeature(Window.FEATURE_NO_TITLE);
  26. // 创建一个GLSurfaceView,用于显示OpenGL绘制的图形
  27. GLSurfaceView glView = new GLSurfaceView(this);
  28. // 创建GLSurfaceView的内容绘制器
  29. GLRenderer myRender = new GLRenderer(this);
  30. // 为GLSurfaceView设置绘制器
  31. glView.setRenderer(myRender);
  32. setContentView(glView);
  33. // 创建手势检测器
  34. detector = new GestureDetector(this);
  35. }
  36.  
  37. @Override
  38. public boolean onTouchEvent(MotionEvent event) {
  39. // 将该Activity上的触碰事件交给GestureDetector处理
  40. return detector.onTouchEvent(event);
  41. }
  42.  
  43. // 用户轻触触摸屏,由1个MotionEvent ACTION_DOWN触发
  44. public boolean onDown(MotionEvent e) {
  45. // TODO Auto-generated method stub
  46. System.out.println("onDown");
  47. return false;
  48. }
  49.  
  50. /*
  51. * 用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE,
  52. * 1个ACTION_UP触发(non-Javadoc)
  53. * Fling事件的处理代码:除了第一个触发Fling的ACTION_DOWN和最后一个ACTION_MOVE中包含的坐标等信息外
  54. * ,我们还可以根据用户在X轴或者Y轴上的移动速度作为条件
  55. * 比如下面的代码中我们就在用户移动超过100个像素,且X轴上每秒的移动速度大于200像素时才进行处理。
  56. *
  57. * @see android.view.GestureDetector.OnGestureListener#onFling(android.view.
  58. * MotionEvent, android.view.MotionEvent, float, float)
  59. * 这个例子中,tv.setLongClickable( true )是必须的,因为
  60. * 只有这样,view才能够处理不同于Tap(轻触)的hold(即ACTION_MOVE,或者多个ACTION_DOWN)
  61. * ,我们同样可以通过layout定义中的android:longClickable来做到这一点
  62. */
  63. public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
  64. float velocityY) {
  65. System.out.println("onFling");
  66. // 参数解释:
  67. // e1:第1个ACTION_DOWN MotionEvent
  68. // e2:最后一个ACTION_MOVE MotionEvent
  69. // velocityX:X轴上的移动速度,像素/秒
  70. // velocityY:Y轴上的移动速度,像素/秒
  71. velocityX = e1.getX() - e2.getX();
  72. velocityY = e1.getY() - e2.getY();
  73. velocityX = velocityX > 4000 ? 4000 : velocityX;
  74. velocityX = velocityX < -4000 ? -4000 : velocityX;
  75. velocityY = velocityY > 4000 ? 4000 : velocityY;
  76. velocityY = velocityY < -4000 ? -4000 : velocityY;
  77. // 根据横向上的速度计算沿Y轴旋转的角度
  78. angley += -velocityX * ROTATE_FACTOR / 4000;
  79. // 根据纵向上的速度计算沿X轴旋转的角度
  80. anglex += -velocityY * ROTATE_FACTOR / 4000;
  81. return true;
  82. }
  83.  
  84. // Touch了不移动一直Touch down时触发
  85. public void onLongPress(MotionEvent arg0) {
  86. // TODO Auto-generated method stub
  87. System.out.println("onLongPress");
  88. }
  89.  
  90. // 用户按下触摸屏,并拖动,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE触发
  91. public boolean onScroll(MotionEvent e1, MotionEvent e2, float velocityX,
  92. float velocityY) {
  93. // TODO Auto-generated method stub
  94. System.out.println("onScroll");
  95. return false;
  96. }
  97.  
  98. /*
  99. * Touch了还没有滑动时触发 (1)onDown只要Touch Down一定立刻触发 (2)Touch
  100. * Down后过一会没有滑动先触发onShowPress再触发onLongPress So: Touch Down后一直不滑动,onDown ->
  101. * onShowPress -> onLongPress这个顺序触发。
  102. */
  103. public void onShowPress(MotionEvent arg0) {
  104. // TODO Auto-generated method stub
  105. System.out.println("onShowPress");
  106. }
  107.  
  108. /*
  109. * 两个函数都是在Touch Down后又没有滑动(onScroll),又没有长按(onLongPress),然后Touch Up时触发
  110. * 点击一下非常快的(不滑动)Touch Up: onDown->onSingleTapUp->onSingleTapConfirmed
  111. * 点击一下稍微慢点的(不滑动)Touch Up://确认是单击事件触发
  112. * onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
  113. */
  114. public boolean onSingleTapUp(MotionEvent arg0) {
  115. // TODO Auto-generated method stub
  116. System.out.println("onSingleTopUp");
  117. return false;
  118. }
  119.  
  120. class GLRenderer implements GLSurfaceView.Renderer {
  121. private final Context context;
  122. private final GLCube cube = new GLCube();
  123.  
  124. GLRenderer(Context context) {
  125. this.context = context;
  126. }
  127.  
  128. public void onSurfaceCreated(GL10 gl, EGLConfig config) {
  129. // Define the lighting
  130. float lightAmbient[] = new float[] { 0.2f, 0.2f, 0.2f, 1 };
  131. float lightDiffuse[] = new float[] { 1, 1, 1, 1 };
  132. float[] lightPos = new float[] { 1, 1, 1, 1 };
  133. gl.glEnable(GL10.GL_LIGHTING);
  134. gl.glEnable(GL10.GL_LIGHT0);
  135. gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient, 0);
  136. gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse, 0);
  137. gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0);
  138.  
  139. // What is the cube made of?
  140. float matAmbient[] = new float[] { 1, 1, 1, 1 };
  141. float matDiffuse[] = new float[] { 1, 1, 1, 1 };
  142. gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT,
  143. matAmbient, 0);
  144. gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE,
  145. matDiffuse, 0);
  146.  
  147. // Set up any OpenGL options we need
  148. gl.glEnable(GL10.GL_DEPTH_TEST);
  149. gl.glDepthFunc(GL10.GL_LEQUAL);
  150. gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
  151.  
  152. gl.glDisable(GL10.GL_DEPTH_TEST);
  153. gl.glEnable(GL10.GL_BLEND);
  154. gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);
  155.  
  156. // Enable textures
  157. gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
  158. gl.glEnable(GL10.GL_TEXTURE_2D);
  159.  
  160. // Load the cube's texture from a bitmap
  161. GLCube.loadTexture(gl, context, R.drawable.android);
  162.  
  163. }
  164.  
  165. public void onSurfaceChanged(GL10 gl, int width, int height) {
  166. // Define the view frustum
  167. gl.glViewport(0, 0, width, height);
  168. gl.glMatrixMode(GL10.GL_PROJECTION);
  169. gl.glLoadIdentity();
  170. float ratio = (float) width / height;
  171. GLU.gluPerspective(gl, 45.0f, ratio, 1, 100f);
  172.  
  173. }
  174.  
  175. public void onDrawFrame(GL10 gl) {
  176. // Clear the screen to black
  177. gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
  178.  
  179. // Position model so we can see it
  180. gl.glMatrixMode(GL10.GL_MODELVIEW);
  181. gl.glLoadIdentity();
  182. gl.glTranslatef(0, 0, -3.0f);
  183.  
  184. gl.glRotatef(angley, 0, 1, 0);
  185. gl.glRotatef(anglex, 1, 0, 0);
  186.  
  187. // Draw the model
  188. cube.draw(gl);
  189. }
  190. }
  191. }

然后是一个Cube:

  1. import java.nio.ByteBuffer;
  2. import java.nio.ByteOrder;
  3. import java.nio.IntBuffer;
  4.  
  5. import javax.microedition.khronos.opengles.GL10;
  6.  
  7. import android.content.Context;
  8. import android.graphics.Bitmap;
  9. import android.graphics.BitmapFactory;
  10. import android.opengl.GLUtils;
  11.  
  12. class GLCube {
  13. private final IntBuffer mVertexBuffer;
  14.  
  15. private final IntBuffer mTextureBuffer;
  16.  
  17. public GLCube() {
  18.  
  19. int one = 65536;
  20. int half = one / 2;
  21. int vertices[] = {
  22. // FRONT
  23. -half, -half, half, half, -half, half,
  24. -half, half, half, half, half, half,
  25. // BACK
  26. -half, -half, -half, -half, half, -half,
  27. half, -half, -half, half, half, -half,
  28. // LEFT
  29. -half, -half, half, -half, half, half,
  30. -half, -half, -half, -half, half, -half,
  31. // RIGHT
  32. half, -half, -half, half, half, -half,
  33. half, -half, half, half, half, half,
  34. // TOP
  35. -half, half, half, half, half, half,
  36. -half, half, -half, half, half, -half,
  37. // BOTTOM
  38. -half, -half, half, -half, -half, -half,
  39. half, -half, half, half, -half, -half, };
  40.  
  41. int texCoords[] = {
  42. // FRONT
  43. 0, one, one, one, 0, 0, one, 0,
  44. // BACK
  45. one, one, one, 0, 0, one, 0, 0,
  46. // LEFT
  47. one, one, one, 0, 0, one, 0, 0,
  48. // RIGHT
  49. one, one, one, 0, 0, one, 0, 0,
  50. // TOP
  51. one, 0, 0, 0, one, one, 0, one,
  52. // BOTTOM
  53. 0, 0, 0, one, one, 0, one, one, };
  54.  
  55. ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
  56. vbb.order(ByteOrder.nativeOrder());
  57. mVertexBuffer = vbb.asIntBuffer();
  58. mVertexBuffer.put(vertices);
  59. mVertexBuffer.position(0);
  60.  
  61. ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4);
  62. tbb.order(ByteOrder.nativeOrder());
  63. mTextureBuffer = tbb.asIntBuffer();
  64. mTextureBuffer.put(texCoords);
  65. mTextureBuffer.position(0);
  66.  
  67. }
  68.  
  69. public void draw(GL10 gl) {
  70. gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
  71.  
  72. gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, mTextureBuffer);
  73.  
  74. gl.glColor4f(1, 1, 1, 1);
  75. gl.glNormal3f(0, 0, 1);
  76. gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
  77. gl.glNormal3f(0, 0, -1);
  78. gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4);
  79.  
  80. gl.glColor4f(1, 1, 1, 1);
  81. gl.glNormal3f(-1, 0, 0);
  82. gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4);
  83. gl.glNormal3f(1, 0, 0);
  84. gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4);
  85.  
  86. gl.glColor4f(1, 1, 1, 1);
  87. gl.glNormal3f(0, 1, 0);
  88. gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4);
  89. gl.glNormal3f(0, -1, 0);
  90. gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4);
  91. }
  92.  
  93. static void loadTexture(GL10 gl, Context context, int resource) {
  94. Bitmap bmp = BitmapFactory.decodeResource(
  95. context.getResources(), resource);
  96. GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
  97. gl.glTexParameterx(GL10.GL_TEXTURE_2D,
  98. GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
  99. gl.glTexParameterx(GL10.GL_TEXTURE_2D,
  100. GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
  101. bmp.recycle();
  102. }
  103.  
  104. }

运行:鼠标滑动屏幕,cube会旋转。

OpenGL完整实例的更多相关文章

  1. C# 调用第三方DLL完整实例

    C# 调用第三方DLL完整实例 分类: C/C++ 以下代码为本人在实际项目中编写的调用第三方DLL接口程序的完整代码. public class ExecuteDLL : Form { ...//忽 ...

  2. (转)多个mapreduce工作相互依赖处理方法完整实例(JobControl)

    多个mapreduce工作相互依赖处理方法完整实例(JobControl) 原文地址:http://mntms.iteye.com/blog/2096456?utm_source=tuicool&am ...

  3. 利用Div+CSS(嵌套+盒模型)布局页面完整实例流程

    Div+CSS(嵌套+盒模型)布局页面完整实例流程: <!DOCTYPE html><html> <head>  <meta charset="UT ...

  4. 微信小程序发送短信验证码完整实例

    微信小程序注册完整实例,发送短信验证码,带60秒倒计时功能,无需服务器端.效果图: 代码: index.wxml <!--index.wxml--> <view class=&quo ...

  5. PHP实现视频文件上传完整实例

    这篇文章主要介绍了PHP实现视频文件上传的技巧,包含了PHP配置信息的设计及大文件的处理,需要的朋友可以参考下    本文以一个完整实例的形式实现了视频文件上传的功能.虽然是比较基础的应用,仍有一定的 ...

  6. 超详细的php用户注册页面填写信息完整实例(附源码)

    这篇文章主要介绍了一个超详细的php用户注册页面填写信息完整实例,内容包括邮箱自动匹配.密码强度验证以及防止表单重复等,小编特别喜欢这篇文章,推荐给大家. 注册页面是大多数网站必备的页面,所以很有必要 ...

  7. 前后端API交互数据加密——AES与RSA混合加密完整实例

    前言 前段时间看到一篇文章讲如何保证API调用时数据的安全性(传送门:https://blog.csdn.net/ityouknow/article/details/80603617),文中讲到利用R ...

  8. Spring和ActiveMQ整合的完整实例

     Spring和ActiveMQ整合的完整实例 前言 这篇博文,我们基于Spring+JMS+ActiveMQ+Tomcat,做一个Spring4.1.0和ActiveMQ5.11.1整合实例,实现了 ...

  9. python测试mysql写入性能完整实例

    这篇文章主要介绍了python测试mysql写入性能完整实例,具有一定借鉴价值,需要的朋友可以参考下 本文主要研究的是python测试mysql写入性能,分享了一则完整代码,具体介绍如下. 测试环境: ...

随机推荐

  1. AS3深拷贝数据对象(2)深拷贝VO对象

    Topic:对于用户自定义的VO对象进行深拷贝,一种VO对象的某属性可能是另一种VO对象的实例. 方法1:通过传说中的“AS3隐藏特性——ByteArray.writeObject和readObjec ...

  2. C#之泛型

    泛型是C# 2.0版本才有的语言特性,是具有参数类型占位符的类.结构.接口和方法.这些占位符是类.结构.接口和方法所存储或使用的一个或多个占位符.简单来说,就是变量类型的参数化. 以下是详细demo: ...

  3. pycurl

    http://www.cnblogs.com/lonelycatcher/archive/2012/02/09/2344005.html http://ju.outofmemory.cn/entry/ ...

  4. 【linux】 静态库编译

    文件如下: root@ubuntu:/home/test# ll total drwxr-xr-x root root Sep : ./ drwxr-xr-x root root Sep : ../ ...

  5. 简短总结一下C#里跨线程更新UI

    摘自: http://my.oschina.net/sdqxcxh/blog/53707 跨线程更新UI是写多线程程序尤其是通信类的程序经常遇到的问题,这里面主要的问题是冲突,比如数据线程想要更新UI ...

  6. iOS键盘类型

    一.键盘风格 UIKit框架支持8种风格键盘. typedef enum { UIKeyboardTypeDefault,                // 默认键盘:支持所有字符 UIKeyboa ...

  7. LTE参考资料

    NETMANIAS TECHNICAL DOCUMENTS: http://www.netmanias.com/en/?m=board&id=techdocs

  8. CentOS学习笔记--MySQL安装

    MySQL安装 Linux中使用最广泛的数据库就是MySQL,使用在线yum的方式安装的版本落后MySQL网站好几个小版本,本节亲自测试安装新版的MySQL. 测试机器环境: VMware Works ...

  9. POJ C程序设计进阶 编程题#2:字符串中次数第2多的字母

    编程题#2:字符串中次数第2多的字母 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536k ...

  10. Pass Dynamic Value to a Grid Label

     A grid label is the blue (normally) colored grid header that you see on PeopleSoft pages. The grid ...