52
第第第 第第 第第

第七章 多媒体开发

  • Upload
    talib

  • View
    112

  • Download
    12

Embed Size (px)

DESCRIPTION

第七章 多媒体开发. 本章主要内容. 多媒体开发. 多媒体即 Multimedia ,含义: 在计算机系统中组合两种或两种以上媒体的一种人机交互式的信息交流 方式。 本章介绍 如何在 Android 上应用多媒体,达到让应用程序美观、易用并且具有吸引力的效果。. 多媒体开发. 音频. 原生 Android 系统所支持解码即播放的音频格有: AAC , AMR , WAV , MP3 , WMA , OGG , MIDI 及 FLAC ( 3.1+ )等等 ; 支持编码的音频格式有: AAC , AMR 。 - PowerPoint PPT Presentation

Citation preview

Page 1: 第七章  多媒体开发

第七章 多媒体开发

Page 2: 第七章  多媒体开发

本章主要内容

音频视频

使用 Path 类绘制 2D 图形使用 OpenGL ES 绘制 3D 图形

Page 3: 第七章  多媒体开发

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

多媒体开发

Page 4: 第七章  多媒体开发

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

多媒体开发音频

Page 5: 第七章  多媒体开发

多媒体开发播放音频

借助于 Android 提供的 MediaPlayer 类可以快速的完成播放一段音频的代码实现。

创建 MediaPlayer 对象的方式有两种,一是使用静态方法MediaPlayer.create 创建,通过参数使播放器与资源相关联起来,再使用 start() 方法开始播放指定的音频文件,代码如下:

MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.tmp);

mediaPlayer.start();

Page 6: 第七章  多媒体开发

多媒体开发播放音频

二是使用构造方法 MediaPlayer() 创建一个播放器对象,然后使用播放器的 setDataSource() 方法将音频资源相关联。代码如下:

MediaPlayer mp = new MediaPlayer();mp.setDataSource(PATH_TO_FILE);mp.prepare();mp.start();

Page 7: 第七章  多媒体开发

多媒体开发录制音频

录制音频资源最方便的方式是使用 MediaRecorder 类,通过设置录制音频来源(通常是设备默认的麦克风)就能方便的录制语音,具体包括如下一些步骤:1. new 一个 android.media.MediaRecorder 实例;2. 使用 MediaRecorder.setAudioSource() 方法来设置音频资

源;这将会很可能使用到MediaRecorder.AudioSource.MIC ;

3. 使用 MediaRecorder.setOutputFormat() 方法设置输出文件格式;

4. 用 MediaRecorder.setAudioEncoder() 方法来设置音频编码;

5. 使用 setOutputFile() 方法设置输出的音频文件;6. 最后,使用 prepare() 和 start() 方法开始录制音频,通过

stop() 和 release() 方法完成一段音频的录制。

Page 8: 第七章  多媒体开发

多媒体开发录制音频——代码示例

/* 实例化 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();

Page 9: 第七章  多媒体开发

多媒体开发录制音频

由于录制音频需要使用麦克风,因此需要在 AndroidManifest.xml

文件中声明使用麦克风的权限:<uses-permission

android:name="android.permission.RECORD_AUDIO"></uses-permission>

注意

Page 10: 第七章  多媒体开发

多媒体开发视频

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 类。

Page 11: 第七章  多媒体开发

多媒体开发播放视频

使用 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();

Page 12: 第七章  多媒体开发

多媒体开发录制视频—— 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);// 设置视图大小 } ……

Page 13: 第七章  多媒体开发

多媒体开发录制视频—— Preview类

surfaceCreated() 方法,初始化视频预览界面。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) { e.printStackTrace();}

}}

Page 14: 第七章  多媒体开发

多媒体开发录制视频—— Preview类

onKeyDown() 方法,处理键被按下的事件。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); }

Page 15: 第七章  多媒体开发

多媒体开发录制视频—— 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 即可。

Page 16: 第七章  多媒体开发

使用 Path 类绘制 2D 图形

Android 提供了 Path 类用于绘制 2D 图形。Path 类简单来说就是封装了一系列由线段(方形、多边形

等)、 2次曲线(圆、椭圆等)和 3次曲线复合而成的几何轨迹集合的类,借助于 Canvas 的 drawPath(path, paint) 方法可以将这些轨迹集合绘制出来,这里面另外一个 paint 参数则是用于设置画笔风格。

Page 17: 第七章  多媒体开发

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

使用 Path 类绘制 2D图形Path 类基本方法

Page 18: 第七章  多媒体开发

使用 Path 类绘制 2D图形Path 绘制 2D 图形示例

画出直线和圆初始界面 通过点击画曲线

Page 19: 第七章  多媒体开发

使用 Path 类绘制 2D图形Path 绘制 2D 图形代码示例

PathView 的代码如下: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 实例 }

Page 20: 第七章  多媒体开发

使用 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();}

Page 21: 第七章  多媒体开发

使用 Path 类绘制 2D图形Path 绘制 2D 图形代码示例

showPath() ,显示绘制的图形。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}

Page 22: 第七章  多媒体开发

使用 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); // 只更新矩形区域 } }

Page 23: 第七章  多媒体开发

使用 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>

界面实现的注意事项

Page 24: 第七章  多媒体开发

使用 OpenGL ES 绘制 3D 图形OpenGL 简介

Logo

OpenGL ( Open Graphics Library )OpenGL 是一个图形编程接口规范标准,用于生成二维、三维图像。特点: 跨编程语言 跨平台OpenGL 由近三百五十个不同的函数调用组成,用来从简单的图元绘制复杂的三维景象,它的主要用途在于: CAD

虚拟现实 科学可视化程序 游戏程序设计

Page 25: 第七章  多媒体开发

使用 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功能、隐蔽查询、非乘方纹理等。

Page 26: 第七章  多媒体开发

使用 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 版,通过改进程序增强了对最新可编程图形硬件的访问,还有更高效的顶点处理、扩展的纹理功能、更弹性的缓冲管理等等。

Page 27: 第七章  多媒体开发

使用 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仍是最新版本。

Page 28: 第七章  多媒体开发

使用 OpenGL ES 绘制 3D 图形OpenGL ES 简介

Logo

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 规范定义

Page 29: 第七章  多媒体开发

使用 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 系统之间的联系。

Page 30: 第七章  多媒体开发

使用 OpenGL ES 绘制 3D 图形Android OpenGL ES 支持列表

GL GL 10 GL 10 EXT GL 11 GL 11 EXT GL 11 ExtensionPack

Page 31: 第七章  多媒体开发

使用 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.

Page 32: 第七章  多媒体开发

使用 OpenGL ES 绘制 3D 图形Android OpenGL ES 开发入门

类:android.opengl概览

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

Page 33: 第七章  多媒体开发

使用 OpenGL ES 绘制 3D 图形Android OpenGL ES 开发入门

类(续):android.opengl概览

GLES20 OpenGL ES 2.0

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.

Page 34: 第七章  多媒体开发

使用 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);

Page 35: 第七章  多媒体开发

使用 OpenGL ES 绘制 3D 图形Android OpenGL 入门——GLSurfaceView

一个简单的 Renderer——矩形

GLSurfaceView

Renderer 的绘制结果

Page 36: 第七章  多媒体开发

使用 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 类都必须实现这个接口。

Page 37: 第七章  多媒体开发

使用 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)

Page 38: 第七章  多媒体开发

使用 OpenGL ES 绘制 3D 图形一个简单的 Renderer——矩形

要实现前面所示的白色矩形,我们通过实现 Renderer 接口来实现这个特定的 Renderer——OpenGLRenderer

为了让结构变得清晰,首先把矩形的具体实现放在一个单独的类中,命名为—— Square ,这个类主要包括: 构造方法 提供一个特定矩形的数值信息(如定点,边,面,颜色等) 实现一个方法 draw(GL10 gl) 供 OpenGLRenderer 调用

Page 39: 第七章  多媒体开发

使用 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

Page 40: 第七章  多媒体开发

使用 OpenGL ES 绘制 3D 图形一个简单的 Renderer——矩形

如图所示, OpenGL 默认的是逆时针的连接顶点来形成一个面,为此建立一个顶点序列数组:

将顶点组合成面

private short[] indices = { 0, 1, 2, 0, 2, 3 };

Page 41: 第七章  多媒体开发

使用 OpenGL ES 绘制 3D 图形一个简单的 Renderer——矩形

Square 构造方法—— public Square()

主要用途——为自身对象分配足够的缓存空间public Square() {

// 顶点为浮点型,占用 4 个字节,所以乘以 4ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);vbb.order(ByteOrder.nativeOrder());vertexBuffer = vbb.asFloatBuffer();vertexBuffer.put(vertices);vertexBuffer.position(0);// 序列用短整型保存,短整型占用 2 个字节,所以乘以 2ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);ibb.order(ByteOrder.nativeOrder());indexBuffer = ibb.asShortBuffer();indexBuffer.put(indices);indexBuffer.position(0);

}

Page 42: 第七章  多媒体开发

使用 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);}

Page 43: 第七章  多媒体开发

使用 OpenGL ES 绘制 3D 图形一个简单的 Renderer——矩形

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

Page 44: 第七章  多媒体开发

使用 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);}

Page 45: 第七章  多媒体开发

使用 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) :

Page 46: 第七章  多媒体开发

使用 OpenGL ES 绘制 3D 图形一个简单的 Renderer——矩形

OpenGLRenderer 实现后,只需要在主 Activity里面使用: GLSurfaceView view = new GLSurfaceView(this); view.setRenderer(new OpenGLRenderer()); setContentView(view);

将 GLSurfaceView 的 Renderer 设置为 OpenGLRenderer 即可实现Square 的绘制了。

Page 47: 第七章  多媒体开发

使用 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() 中,在每帧进行绘制时做对应的变换调整,达到动态的效果。

Page 48: 第七章  多媒体开发

使用 OpenGL ES 绘制 3D 图形延伸——对矩形进行平移、旋转和缩放

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;}

例如,在 onDrawFrame() 添加如下语句,可以实现矩形循环缩放的效果,截图见下页( move 为整形全局变量, flag 为全局布尔变量):

Page 49: 第七章  多媒体开发

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

Page 50: 第七章  多媒体开发

使用 OpenGL ES 绘制 3D 图形附—— Android OpenGL 3D 实例代码

可触摸旋转控制的 3D立方体(项目名称TestOpenGL_ES II )

注: TestOpenGL_ES I

是不可旋转的版本

Page 51: 第七章  多媒体开发

本章小结

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

Page 52: 第七章  多媒体开发

THE END