第七章 多媒体开发.

Slides:



Advertisements
Similar presentations
单元二:面向对象程序设计 任务二:借书卡程序设计.
Advertisements

第四章 类、对象和接口.
3.2 Java的类 Java 类库的概念 语言规则——程序的书写规范 Java语言 类库——已有的有特定功能的Java程序模块
项目6 通用堆栈.
第13章 繪圖與多媒體 13-1 顯示圖檔-行動相簿 13-2 音樂播放-音樂播放器 13-3 影片播放-視訊播放器
MVC Servlet与MVC设计模式.
動畫與遊戲設計 遊戲開發工具 程于芳 老師
算法设计与分析 Algorithm Design and Analysis
實驗五:多媒體播放器選單介面.
项目:贪吃蛇游戏设计 工作任务一:系统设计(system design) 工作任务二:豆类(Bean)设计
位置與地圖應用 此投影片為講解Android如何取得定位經緯度和使用Google Map地圖.
设计模式可以帮助我们改善系统的设计,增强 系统的健壮性、可扩展性,为以后铺平道路。
第二章 JAVA语言基础.
第二部分 Java语言基础篇 第4章 Java语言与面向对象 (之一).
第八章 分析與設計階段 – 物件導向設計(OOD)
AOP实践 演讲人:陈思荣.
厦门大学数据库实验室 报告人:谢荣东 导师:林子雨 2014年8月30日
Chapter 13 Android 實戰演練.
Android + JUnit 單元測試 建國科技大學資管系 饒瑞佶 2012/8/19V4.
2.1 基本資料型別 2.2 變數 2.3 運算式與運算子 2.4 輸出與輸入資料 2.5 資料型別轉換 2.6 實例
计算机图形学 讲 授:董兰芳 研究方向:科学计算可视化 图形、图像处理 模式识别 中国科学技术大学 视觉计算与可视化实验室
第5章 面向对象程序设计 本章要点 5.1 面向对象程序设计概述 5.2 Java语言的面向对象程序设计 5.3 方法的使用和对象数组
API设计实例分析 通用IO API.
第10章 App微信分享的实现 倚动实验室.
第8章 Android内容提供者(ContentProvider)应用
Chapter 6 Advanced UI Design.
第四次课后作业 1 问题描述: 将谜题定义为:包含一个初始位置,一个目标位置,以及用于判断是否是有效移动的规则集。
ANDROID 中的 3D 繪圖 作者:陳鍾誠.
本單元介紹何謂變數,及說明變數的宣告方式。
Chapter 6 進階UI設計.
西南科技大学网络教育系列课程 高级语程序设计(Java) 第五章 继承、接口与范型.
ANDROID PROGRAMMING2.
程式設計實作.
OpenGL使用简介.
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
Android + Service 建國科技大學 資管系 饒瑞佶.
Java语言程序设计 第五部分 Java异常处理.
實驗十四:顯示與控制地圖.
王豐緒 銘傳大學資訊工程學系 問題:JAVA 物件檔輸出入.
Introduction to OpenGL (1)
中国矿大计算机学院杨东平 第5章 接口和包 中国矿大计算机学院杨东平
第8章 Service解析.
第一次课后作业 1. C/C++/Java 哪些值不是头等程序对象 2. C/C++/Java 哪些机制采用的是动态束定
3.1 数据类型 3.2 标识符与关键字 3.3 常量 3.4 变量 3.5 运算符与表达式 3.6 一个编程实例
2019/1/16 Java语言程序设计-类与对象 教师:段鹏飞.
2019/1/17 Java语言程序设计-程序流程 教师:段鹏飞.
异常及处理.
平面繪圖與動畫.
Java程序设计 第2章 基本数据类型及操作.
生活智慧王 樹德科技大學 資訊工程系 指導教授 : 陳毓璋 教授 小組成員: 劉上緯 翁維廷 洪文財.
C/C++/Java 哪些值不是头等程序对象
Animation(動畫) 靜宜大學資工系 蔡奇偉 副教授
JAVA 编 程 技 术 主编 贾振华 2010年1月.
《JAVA程序设计》 语音答疑 辅导老师:高旻.
第二章Java基本程序设计.
Chapter 5 Basic UI Design.
實驗九:延續實驗八, 製作一個完整音樂播放器
Location Based Services - LBS
進階UI元件:Spinner與接合器 靜宜大學資管系 楊子青
第二章 Java基本语法 讲师:复凡.
第五次课后作业 1 问题描述: 将谜题定义为:包含一个初始位置,一个目标位置,以及用于判断是否是有效移动的规则集。
第二章 Java语法基础.
#include <iostream.h>
第二章 Java基本语法 讲师:复凡.
JAVA 程式設計與資料結構 第三章 物件的設計.
第2章 Java语言基础.
第9章 BroadcastReceiver的使用
第二章 Java基础语法 北京传智播客教育
進階UI元件:Spinner與接合器 靜宜大學資管系 楊子青
Summary
Presentation transcript:

第七章 多媒体开发

本章主要内容 音频 视频 使用Path类绘制2D图形 使用OpenGL ES绘制3D图形

多媒体开发 多媒体即Multimedia,含义:在计算机系统中组合两种或两种以上媒体的一种人机交互式的信息交流方式。 本章介绍如何在Android上应用多媒体,达到让应用程序美观、易用并且具有吸引力的效果。

多媒体开发 音频 原生Android系统所支持解码即播放的音频格有:AAC,AMR,WAV,MP3,WMA,OGG,MIDI及FLAC(3.1+)等等;支持编码的音频格式有:AAC,AMR。 而对于Android模拟器来说,暂时只支持解码OGG,WAV和MP3三种格式。

多媒体开发 播放音频 借助于Android提供的MediaPlayer类可以快速的完成播放一段音频的代码实现。 创建MediaPlayer对象的方式有两种,一是使用静态方法MediaPlayer.create创建,通过参数使播放器与资源相关联起来,再使用start()方法开始播放指定的音频文件,代码如下: MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.tmp); mediaPlayer.start();

多媒体开发 播放音频 二是使用构造方法MediaPlayer()创建一个播放器对象,然后使用播放器的setDataSource()方法将音频资源相关联。 代码如下: MediaPlayer mp = new MediaPlayer(); mp.setDataSource(PATH_TO_FILE); mp.prepare(); mp.start();

多媒体开发 录制音频 录制音频资源最方便的方式是使用MediaRecorder类,通过设置录制音频来源(通常是设备默认的麦克风)就能方便的录制语音,具体包括如下一些步骤: new一个android.media.MediaRecorder实例; 使用MediaRecorder.setAudioSource()方法来设置音频资源;这将会很可能使用到MediaRecorder.AudioSource.MIC; 使用MediaRecorder.setOutputFormat()方法设置输出文件格式; 用MediaRecorder.setAudioEncoder()方法来设置音频编码; 使用setOutputFile()方法设置输出的音频文件; 最后,使用prepare()和start()方法开始录制音频,通过stop()和release()方法完成一段音频的录制。

多媒体开发 录制音频——代码示例 /* 实例化MediaRecorder对象 */ recorder = new MediaRecorder(); /* 设置麦克风 */ recorder.setAudioSource(MediaRecorder.AudioSource.MIC); /* 设置输出文件的格式 */ recorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); /* 设置音频文件的编码 */ recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); /* 设置输出文件的路径 */ recorder.setOutputFile(mRecAudioFile.getAbsolutePath()); /* 准备 */ recorder.prepare(); /* 开始 */ recorder.start(); /* 停止录音 */ recorder.stop(); /* 释放MediaRecorder */ recorder.release();

注意 多媒体开发 由于录制音频需要使用麦克风,因此需要在AndroidManifest.xml文件中声明使用麦克风的权限: 录制音频 <uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>

多媒体开发 视频 Android原生系统所支持解码的视频编码格式有:H.263(后缀.3gp和.mp4)、H.264 AVC(3.0+版本,后缀.3gp和.mp4等等)、MPEG-4 SP(后缀.3gp)和VP8(2.3.3+版本,后缀.webm),其中H.263和H.264是Android支持的编码格式。 与音频的使用方式的不同点是音频本身并不会表现为用户界面,而视频则需要成为用户界面的一部分,视频播放只要使用VideoView类就可以实现,而视频录制也是借助于MediaRecorder类。

多媒体开发 使用VideoView播放视屏的代码如下: 播放视频 Context context = getApplicationContext(); VideoView mVideoView = new VideoView(context); mVideoView = (VideoView) findViewById(R.id.surface_view); mVideoView.setVideoURI(Uri.parse(path)); MediaController mc = new MediaController(this); mc.setAnchorView(mVideoView); mVideoView.setMediaController(mc); mVideoView.requestFocus(); mVideoView.start();

多媒体开发 录制视频——Preview类 Preview类主要就是实现了SurfaceHolder.Callback接口的三个回调方法,并且加入了用于监听开始录制和停止录制的按键事件方法,以及用于控制视频开始录制和停止录制的方法。下面是Preview类的一些变量和构造函数。 public class Preview extends SurfaceView implements SurfaceHolder.Callback{ private SurfaceHolder holder = null; private static boolean isRecording = false; /* 录制的视频文件名及存放路径 */ private File mRecVideoFile; private File mRecVideoPath; /* MediaRecorder对象 */ private MediaRecorder mMediaRecorder; /* 录制视频文件名的前缀 */ private String strTempFile = "A_VideoRecordTest_"; public Preview(Context context) { super(context); holder = this.getHolder();//获取SurfaceHolder对象 holder.addCallback(this);//添加回调接口 holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//缓冲类型 holder.setFixedSize(400, 300);//设置视图大小 } ……

多媒体开发 surfaceCreated()方法,初始化视频预览界面。 录制视频——Preview类 public void surfaceCreated(SurfaceHolder holder) { if(mMediaRecorder==null){ mRecVideoFile = new File("/mnt/sdcard/VideoRecordTempFile.3gp"); mMediaRecorder = new MediaRecorder(); mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263); mMediaRecorder.setOutputFile(mRecVideoFile.getAbsolutePath()); mMediaRecorder.setPreviewDisplay(holder.getSurface()); try { mMediaRecorder.prepare(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { }

多媒体开发 onKeyDown()方法,处理键被按下的事件。 录制视频——Preview类 public boolean onKeyDown(int keyCode, KeyEvent event) { switch(keyCode){ case KeyEvent.KEYCODE_DPAD_CENTER:{ //方向导航键中键 if(mMediaRecorder !=null){ if(isRecording){ finishRecordVideo(); isRecording = false; } else{ startRecordVideo(); isRecording = true; } break; case KeyEvent.KEYCODE_BACK:{ System.exit(0); return super.onKeyDown(keyCode, event);

多媒体开发 startRecordVideo()方法,开始录制视频(保存视频文件)。 录制视频——Preview类 startRecordVideo()方法,开始录制视频(保存视频文件)。 public void startRecordVideo(){ try{ /* 创建视频文件 */ mRecVideoFile = File.createTempFile(strTempFile, ".3gp", mRecVideoPath); /* 设置输出文件的路径 */ mMediaRecorder.setOutputFile(mRecVideoFile.getAbsolutePath()); mMediaRecorder.setPreviewDisplay(holder.getSurface()); /* 准备 */ mMediaRecorder.prepare(); /* 开始 */ mMediaRecorder.start(); } catch (IOException e) { e.printStackTrace(); } 实现了Preview之后,在主Activity中使用setContentView()方法将视图设置为Preview即可。

使用Path类绘制2D图形 Android提供了Path类用于绘制2D图形。 Path类简单来说就是封装了一系列由线段(方形、多边形等)、2次曲线(圆、椭圆等)和3次曲线复合而成的几何轨迹集合的类,借助于Canvas的drawPath(path, paint)方法可以将这些轨迹集合绘制出来,这里面另外一个paint参数则是用于设置画笔风格。

Path提供了很多绘制基本图形的方法,例如: 使用Path类绘制2D图形 Path类基本方法 Path提供了很多绘制基本图形的方法,例如: addArc():用于绘制一段圆弧; addCircle():用于绘制圆形; addOval():用于绘制椭圆; addPath():用于绘制一组轨迹; addRect():用于绘制矩形; addRoundRect():用于绘制圆角矩形; 可以使用这些提供好的方法为基础通过组合绘制出各种图形。另外Path还提供了一些直接操作元线段的方法,例如moveTo()、lineTo()等方法。

使用Path类绘制2D图形 Path绘制2D图形示例 初始界面 画出直线和圆 通过点击画曲线

使用Path类绘制2D图形 PathView的代码如下: Path绘制2D图形代码示例 public class PathView extends View { private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); //抗锯齿 private Path mPath;//声明Path类对象 private boolean mCurDown;//指示屏幕是否被按下(点击) private int mCurX;//被点击点的坐标 private int mCurY; private final Rect mRect = new Rect();//该矩形用于控制局部更新区域 public PathView(Context context, AttributeSet attrs) { super(context, attrs); setFocusable(true); //设置视图可获得焦点 setFocusableInTouchMode(true);//设置视图可获取触摸事件 mPaint.setStyle(Paint.Style.STROKE);//绘制成线 mPaint.setStrokeWidth(3);//设置绘制线宽 mPath = new Path();//创建Path实例 }

drawLine(),用于绘制直线的方法。 使用Path类绘制2D图形 Path绘制2D图形代码示例 drawLine(),用于绘制直线的方法。 public void drawLine(){//向Path中添加一条线段供绘制 mPath.moveTo(20, 20); mPath.lineTo(120, 1200); invalidate();//立即更新视图 } drawCircle(),用于绘制圆圈的方法。 public void drawCircle(){//向Path中添加一个圆形供绘制 mPath.addCircle(180, 180, 45, Path.Direction.CCW); invalidate(); }

使用Path类绘制2D图形 showPath(),显示绘制的图形。 onDraw(),用于更新显示。 Path绘制2D图形代码示例 private void showPath(Canvas canvas, int x, int y, Path.FillType ft, Paint paint) { canvas.translate(x, y); canvas.clipRect(0, 0, 280, 300);//可以绘制图形的区域 canvas.drawColor(Color.WHITE);//为该区域着色 mPath.setFillType(ft);//设置fill方式 canvas.drawPath(mPath, paint);//绘制Path } onDraw(),用于更新显示。 protected void onDraw(Canvas canvas) { Paint paint = mPaint; canvas.drawColor(0xFFCCCCCC);//为Canvas着色 canvas.translate(20, 20);//Canvas向左下方向偏移(20,20) paint.setAntiAlias(true);//抗锯齿 paint.setColor(Color.BLACK);//设置画笔颜色 paint.setPathEffect(null);//不采用特效 showPath(canvas, 0, 0, Path.FillType.WINDING, paint }

onTouchEvent(),处理触摸事件;drawPoint(),画点。 使用Path类绘制2D图形 Path绘制2D图形代码示例 onTouchEvent(),处理触摸事件;drawPoint(),画点。 public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); mCurDown = action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE; int N = event.getHistorySize(); for (int i=0; i<N; i++) { drawPoint(event.getHistoricalX(i), event.getHistoricalY(i)); } drawPoint(event.getX(), event.getY());//添加当前被触摸的点 return true; private void drawPoint(float x, float y) { mCurX = (int)x - 20; mCurY = (int)y - 20; if (mCurDown) {//添加当前被触摸点并刷新视图显示 mPath.addCircle(mCurX, mCurY, 1, Path.Direction.CCW); mRect.set((int)x-3, (int)y-3, (int)x+3, (int)y+3); invalidate(mRect); //只更新矩形区域

界面实现的注意事项 使用Path类绘制2D图形 Path绘制2D图形 由于该示例中还需要在Activity中添加一些其他的UI控件,所以需要在布局文件中将PathView作为一个控件元素使用,使之成为界面组成的一部分。 <FrameLayout android:layout_width="fill_parent" android:layout_height="wrap_content“ android:layout_weight="1"> <com.android.example.pathdraw.PathView android:id="@+id/pathdrawview" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </FrameLayout>

使用OpenGL ES绘制3D图形 Logo OpenGL 简介 OpenGL(Open Graphics Library) 跨编程语言 跨平台 OpenGL由近三百五十个不同的函数调用组成,用来从简单的图元绘制复杂的三维景象,它的主要用途在于: CAD 虚拟现实 科学可视化程序 游戏程序设计 Logo

OpenGL进化自SGI的早期3D接口IRIS GL。 使用OpenGL ES绘制3D图形 OpenGL 发展历程 OpenGL进化自SGI的早期3D接口IRIS GL。 1992年7月 发布了 OpenGL 1.0 版本,并与微软共同推出 Windows NT 版本的 OpenGL 。 1995年 OpenGL 1.1 版本面市,加入了新功能,并引入了纹理特性等等。 2003年的7月28日,SGI和ARB公布了OpenGL 1.5。OpenGL 1.5的新功能包括:顶点Buffer Object、Shadow功能、隐蔽查询、非乘方纹理等。

使用OpenGL ES绘制3D图形 OpenGL 发展历程 2004年8月,OpenGL2.0版本由3Dlabs发布。opengl2.0支持OpenGL Shading Language、新的shader扩展特性以及其他多项增强特性。 2008年Khronos工作组推出OpenGL 3,增加了新版本的shader语言, OpenGL着色语言GLSL 1.30,可以充分发挥当前可编程图形硬件的潜能。 2009年3月公布了升级版新规范OpenGL 3.1, OpenGL着色语言“GLSL”从1.30版升级到了1.40版,通过改进程序增强了对最新可编程图形硬件的访问,还有更高效的顶点处理、扩展的纹理功能、更弹性的缓冲管理等等。

使用OpenGL ES绘制3D图形 OpenGL 发展历程 2009年8月Khronos小组发布了OpenGL 3.2。OpenGL3.2版本提升了性能表现、改进了视觉质量、提高了几何图形处理速度,而且使Direct3D程序更容易移植为OpenGL。 2010年3月10日, OpenGL同时推出了3.3和4.0版本,同年7月26日又发布了4.1版本,OpenGL4.1提高视觉密集型应用OpenCL™的互操作性,并继续加速计算剖面为核心的支持和兼容性,到目前(2011/6/11)OpenGL4.1仍是最新版本。

Logo 使用OpenGL ES绘制3D图形 OpenGL ES (OpenGL for Embedded Systems) 它是OpenGL用于嵌入式系统的API库 是 OpenGL三维图形API的子集 针对手机、PDA和游戏主机等嵌入式设备而设计 OpenGL ES 与OpenGL的联系 OpenGL ES 是从 OpenGL 裁剪定制而来的 去除了复杂图元等许多非绝对必要的特性 OpenGL ES 1.0 以 OpenGL 1.3 规范为基础 OpenGL ES 1.1 以 OpenGL 1.5 规范为基础 OpenGL ES 2.0 则是参照 OpenGL 2.0 规范定义 Logo

Android系统通过OpenGL ES API来提供对高性能3D图形的支持。 Android 3D 图形系统分为两部分: Java 框架 使用OpenGL ES绘制3D图形 Android OpenGL ES 简介 Android系统通过OpenGL ES API来提供对高性能3D图形的支持。 Android 3D 图形系统分为两部分: Java 框架 本地代码 本地代码主要实现的 OpenGL 接口的库,在 Java框架层,javax.microedition.khronos.opengles 是 java 标准的 OpenGL 包,android.opengl包提供了 OpenGL 系统和 Android GUI 系统之间的联系。

GL GL 10 GL 10 EXT GL 11 GL 11 EXT GL 11 ExtensionPack 使用OpenGL ES绘制3D图形 Android OpenGL ES 支持列表 GL GL 10 GL 10 EXT GL 11 GL 11 EXT GL 11 ExtensionPack

Android OpenGL API——android.opengl 使用OpenGL ES绘制3D图形 Android OpenGL ES 开发入门 Android OpenGL API——android.opengl 接口: GLSurfaceView.EGLConfigChooser An interface for choosing an EGLConfig configuration from a list of potential configurations.  GLSurfaceView.EGLContextFactory An interface for customizing the eglCreateContext and eglDestroyContext calls.  GLSurfaceView.EGLWindowSurfaceFactory An interface for customizing the eglCreateWindowSurface and eglDestroySurface calls.  GLSurfaceView.GLWrapper An interface used to wrap a GL interface.  GLSurfaceView.Renderer A generic renderer interface. 

android.opengl概览 使用OpenGL ES绘制3D图形 类: Android OpenGL ES 开发入门 ETC1 Methods for encoding and decoding ETC1 textures.  ETC1Util Utility methods for using ETC1 compressed textures.  ETC1Util.ETC1Texture A utility class encapsulating a compressed ETC1 texture.  GLDebugHelper A helper class for debugging OpenGL ES applications.  GLES10   GLES10Ext GLES11 GLES11Ext

android.opengl概览 使用OpenGL ES绘制3D图形 类(续): Android OpenGL ES 开发入门 GLES20 GLSurfaceView An implementation of SurfaceView that uses the dedicated surface for displaying OpenGL rendering.  GLU A set of GL utilities inspired by the OpenGL Utility Toolkit.  GLUtils Utility class to help bridging OpenGL ES and Android APIs.  Matrix Matrix math utilities.  Visibility A collection of utility methods for computing the visibility of triangle meshes.  GLException An exception class for OpenGL errors. 

使用OpenGL ES绘制3D图形 Android OpenGL入门——GLSurfaceView 要在Android设备上显示opengl图像,首先需要在布局中加入一个用于显示opengl图形的视图(View)。 类似于其他的一些View例如,GridView、ListView、MapView等等,Android提供了GLSurfaceView用于显示opengl图像。 我们可以通过继承GLSurfaceView来实现自己的用于opengl的View,当然,最简单的用法是直接使用它。用法如下,在对应Activity的onCreate()方法中加入: GLSurfaceView view = new GLSurfaceView(this); view.setRenderer(new OpenGLRenderer()); setContentView(view);

一个简单的Renderer——矩形 使用OpenGL ES绘制3D图形 GLSurfaceView Renderer的绘制结果 Android OpenGL入门——GLSurfaceView 一个简单的Renderer——矩形 GLSurfaceView Renderer的绘制结果

GLSurfaceView.Renderer是Android提供的一个接口,所有用于绘制图像的Renderer类都必须实现这个接口。 使用OpenGL ES绘制3D图形 Android OpenGL入门——Renderer GLSurfaceView view = new GLSurfaceView(this); view.setRenderer(new OpenGLRenderer()); setContentView(view); GLSurfaceView只是在布局中加入了一块View用于绘制图形,而Renderer类就是用于绘制具体的图形了,如上段代码的第二句就是给GLSurfaceView设置了一个用于绘图的Renderer。 GLSurfaceView.Renderer是Android提供的一个接口,所有用于绘制图像的Renderer类都必须实现这个接口。

实现Renderer接口需要实现如下三个方法: 使用OpenGL ES绘制3D图形 Android OpenGL入门——Renderer 实现Renderer接口需要实现如下三个方法: 该函数在视图需要创建的时候调用。一些用于初始化的绘制代码通常放在这里。 public void onSurfaceCreated(GL10 gl, EGLConfig config) 该函数内是实现具体绘制业务的代码。 public void onDrawFrame(GL10 gl) 该函数在屏幕尺寸发生变化时调用,用于适应屏幕的调整。 public void onSurfaceChanged(GL10 gl, int width, int height)

要实现前面所示的白色矩形,我们通过实现Renderer接口来实现这个特定的Renderer——OpenGLRenderer 使用OpenGL ES绘制3D图形 一个简单的Renderer——矩形 要实现前面所示的白色矩形,我们通过实现Renderer接口来实现这个特定的Renderer——OpenGLRenderer 为了让结构变得清晰,首先把矩形的具体实现放在一个单独的类中,命名为——Square,这个类主要包括: 构造方法 提供一个特定矩形的数值信息(如定点,边,面,颜色等) 实现一个方法draw(GL10 gl)供OpenGLRenderer调用

如图所示,一个简单的矩形包括了四个顶点(v0, v1, v2, v3),通过一个数组来记录: 使用OpenGL ES绘制3D图形 一个简单的Renderer——矩形 如图所示,一个简单的矩形包括了四个顶点(v0, v1, v2, v3),通过一个数组来记录: private float vertices[] = { -1.0f, 1.0f, 0.0f, // v0 -1.0f, -1.0f, 0.0f, // v1 1.0f, -1.0f, 0.0f, // v2 1.0f, 1.0f, 0.0f, // v3 }; 注:三维坐标,z轴全为0

如图所示,OpenGL默认的是逆时针的连接顶点来形成一个面,为此建立一个顶点序列数组: 使用OpenGL ES绘制3D图形 一个简单的Renderer——矩形 将顶点组合成面 如图所示,OpenGL默认的是逆时针的连接顶点来形成一个面,为此建立一个顶点序列数组: private short[] indices = { 0, 1, 2, 0, 2, 3 };

Square构造方法——public Square() 主要用途——为自身对象分配足够的缓存空间 使用OpenGL ES绘制3D图形 一个简单的Renderer——矩形 Square构造方法——public Square() 主要用途——为自身对象分配足够的缓存空间 public Square() { // 顶点为浮点型,占用4个字节,所以乘以4 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); vbb.order(ByteOrder.nativeOrder()); vertexBuffer = vbb.asFloatBuffer(); vertexBuffer.put(vertices); vertexBuffer.position(0); // 序列用短整型保存,短整型占用2个字节,所以乘以2 ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2); ibb.order(ByteOrder.nativeOrder()); indexBuffer = ibb.asShortBuffer(); indexBuffer.put(indices); indexBuffer.position(0); }

Square的draw(GL10 gl)方法——绘制矩形 使用OpenGL ES绘制3D图形 一个简单的Renderer——矩形 Square的draw(GL10 gl)方法——绘制矩形 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); // 指定序列缓存的位置以及序列数据的类型 gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer); // 清除顶点缓存 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); // 停止面淘汰机制 gl.glDisable(GL10.GL_CULL_FACE); }

完成了Square类,就可以在OpenGLRenderer中使用它了 OpenGLRenderer主要包括如下一些方法: 构造方法 使用OpenGL ES绘制3D图形 一个简单的Renderer——矩形 完成了Square类,就可以在OpenGLRenderer中使用它了 OpenGLRenderer主要包括如下一些方法: 构造方法 三个实现Renderer接口的方法 本例中,构造方法很简单,如下: public OpenGLRenderer() { // 初始化待绘制的矩形对象. square = new Square(); }

OpenGLRenderer. onSurfaceCreated(GL10 gl, EGLConfig config): 使用OpenGL ES绘制3D图形 一个简单的Renderer——矩形 OpenGLRenderer. onSurfaceCreated(GL10 gl, EGLConfig config): public void onSurfaceCreated(GL10 gl, EGLConfig config) { // 设置背景颜色为黑色 gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // 使能平滑阴影效果. gl.glShadeModel(GL10.GL_SMOOTH); // 设置深度缓存. gl.glClearDepthf(1.0f); // 使能深度测试. gl.glEnable(GL10.GL_DEPTH_TEST); // 设置深度测试的方式. gl.glDepthFunc(GL10.GL_LEQUAL); // 设置成最好的显示效果. gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); }

OpenGLRenderer. onDrawFrame(GL10 gl) : 使用OpenGL ES绘制3D图形 一个简单的Renderer——矩形 OpenGLRenderer. onDrawFrame(GL10 gl) : public void onDrawFrame(GL10 gl) { // 清屏并且清除深度缓存. gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // 重新载入绘图矩阵 gl.glLoadIdentity(); // 使用向量(0,0,-5)平移图像,使绘制结果便于观察 gl.glTranslatef(0, 0, - 5); // 绘制矩形. square.draw(gl); } OpenGLRenderer. onSurfaceChanged(GL10 gl, int width, int height):

OpenGLRenderer实现后,只需要在主Activity里面使用: 使用OpenGL ES绘制3D图形 一个简单的Renderer——矩形 OpenGLRenderer实现后,只需要在主Activity里面使用: GLSurfaceView view = new GLSurfaceView(this); view.setRenderer(new OpenGLRenderer()); setContentView(view); 将GLSurfaceView的Renderer设置为OpenGLRenderer即可实现Square的绘制了。

在OpenGL中要实现动态的图形效果,通常需要对图形模型进行平移,旋转和缩放等操作。这三个操作涉及如下三个方法: 使用OpenGL ES绘制3D图形 延伸——对矩形进行平移、旋转和缩放 在OpenGL中要实现动态的图形效果,通常需要对图形模型进行平移,旋转和缩放等操作。这三个操作涉及如下三个方法: glTranslatef(float x, float y, float z)——以向量(x,y,z)平移 glRotatef(float angle, float x, float y, float z)——围绕向量(x,y,z)逆时针方向旋转angle度 glScalef(float x, float y, float z)——分别将图形在对应坐标维度缩放x,y,z倍 这些方法主要用在Renderer的onDrawFrame()中,在每帧进行绘制时做对应的变换调整,达到动态的效果。

使用OpenGL ES绘制3D图形 延伸——对矩形进行平移、旋转和缩放 例如,在onDrawFrame()添加如下语句,可以实现矩形循环缩放的效果,截图见下页(move为整形全局变量,flag为全局布尔变量): if(flag) { move--; } if(!flag) { move++; gl.glScalef(0.01f * move, 0.01f * move, 0.01f * move); if(move == 0){ flag = false; if(move == 100) { flag = true;

使用OpenGL ES绘制3D图形 Android OpenGL示例——TestOpenGL_ES

可触摸旋转控制的3D立方体(项目名称TestOpenGL_ES II) 使用OpenGL ES绘制3D图形 附——Android OpenGL 3D实例代码 可触摸旋转控制的3D立方体(项目名称TestOpenGL_ES II) 注:TestOpenGL_ES I是不可旋转的版本

本章小结 这一章学习了如何在Android程序中进行多媒体开发,包括了实现音频和视频的播放和录制,以及如何绘制2D和3D图形,有了这些元素,应用程序将变得更加丰富多彩。

The end