前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android开发笔记(一百五十三)OpenGL绘制三维图形的流程

Android开发笔记(一百五十三)OpenGL绘制三维图形的流程

作者头像
aqi00
发布2019-01-18 15:16:15
1.7K0
发布2019-01-18 15:16:15
举报
文章被收录于专栏:老欧说安卓老欧说安卓

从这篇文章开始,接下来会连载一系列的OpenGL相关博文,好好探讨如何在Android中进行OpenGL开发。 OpenGL的全称是“Open Graphics Library”,意思是开放图形库,它定义了一个跨语言、跨平台的图形图像程序接口。对于Android开发者来说,OpenGL就是用来绘制三维图形的技术手段,当然OpenGL并不仅限于展示静止的三维图形,也能用来播放运动着的三维动画。不管是三维图形还是三维动画,都是力求在二维的手机屏幕上面展现模拟的真实世界场景,这个OpenGL的应用方向说到底,可不就是时下大热的虚拟现实么?

看起来OpenGL是很高大上的样子,其实Android系统早已集成了相关的API,只要开发者按照函数要求依次调用,就能一步一步在手机屏幕上画出各式各样的三维物体了。不过对于初次接触OpenGL的开发者来说,三维绘图的概念可能过于抽象,所以为了方便读者理解,下面就以Android上的二维图形绘制为参考,亦步亦趋地逐步消化OpenGL的相关知识点。 从前面的学习可以得知,每个Android界面上的控件,其实都是在某个视图上绘制规定的文字(如TextView),或者绘制指定的图像(如ImageView)。而TextView和ImageView都继承自基本视图View,这意味着首先要有一个专门的绘图场所,比如现实生活中的黑板、画板和桌子。然后还要有绘画作品的载体,比如显示生活中黑板的漆面,以及用于国画的宣纸、用于油画的油布等等,在Android系统中,这个绘画载体便是画布Canvas。有了绘图场所和绘画载体,还得有一把绘图工具,不管是勾勒线条还是涂抹颜料都少不了它,如果是写黑板报则有粉笔,如果是画国画则有毛笔,如果是画油画则有油画笔,如果是画Android控件则有画笔Paint。 所以,只要具备了绘图场所、绘画载体、绘图工具,即可挥毫泼墨进行绘画创作啦。正如前面介绍的Android自定义控件那样,有了视图View、画布Canvas、画笔Paint,方能绘制炫彩多姿的各种控件。那么对于OpenGL的三维绘图来说,也同样需要具备这三种要素,分别是GLSurfaceView、GLSurfaceView.Renderer和GL10,其中GLSurfaceView继承自表面视图SurfaceView,对应于二维绘图的View;GLSurfaceView.Renderer是三维图形的渲染器,对应于二维绘图的Canvas;最后一个GL10自然相当于二维绘图的Paint了。有了GLSurfaceView、GLRender和GL10这三驾马车,Android才能实现OpenGL的三维图形渲染功能。 具体到App编码上面,还得将GLSurfaceView、GLSurfaceView.Renderer和GL10这三个类有机结合起来,即通过函数调用关联它们三个小伙伴。首先从布局文件获得GLSurfaceView的控件对象,然后调用该对象的setRenderer方法设置三维渲染器,这个三维渲染器实现了GLSurfaceView.Renderer定义的三个视图函数,分别是onSurfaceCreated、onSurfaceChanged和onDrawFrame,这三个函数的输入参数都包含GL10,也就是说这三个函数都持有画笔对象。如此一来,绘图三要素的GLSurfaceView、GLSurfaceView.Renderer和GL10就互相关联了起来。 可是,Renderer接口定义的onSurfaceCreated、onSurfaceChanged和onDrawFrame三个函数很是陌生,它们之间又有什么区别呢?为方便理解,接下来不妨继续套用Android二维绘图的有关概念,从Android自定义控件的主要流程得知,自定义一个二维控件,主要有以下四个步骤: 1、声明自定义控件的构造函数,可在此进行控件属性初始赋值等初始化操作; 2、重写onMeasure函数,可在此测量控件的宽度和高度; 3、重写onLayout函数,可在此挪动控件的位置; 4、重写onDraw函数,可在此绘制控件的形状、颜色、文字以及图案等等; 于是前面提到Renderer接口定义的三个函数,它们的用途对照说明如下: 1、onSurfaceCreated函数在GLSurfaceView创建时调用,相当于自定义控件的构造函数,一样可在此进行三维绘图的初始化操作; 2、onSurfaceChanged函数在GLSurfaceView创建、恢复与改变时调用,在这里不但要定义三维空间的大小,还要定义三维物体的方位,所以该函数相当于完成了自定义控件的onMeasure和onLayout两个函数的功能; 3、onDrawFrame顾名思义跟自定义控件的onDraw函数差不多,onDraw函数用于绘制二维图形的具体形状,而onDrawFrame函数用于绘制三维图形的具体形状; 下面来个最简单的OpenGL例子,在布局文件中放置一个android.opengl.GLSurfaceView节点,后续的三维绘图动作将在该视图上开展。布局文件内容示例如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <!-- 注意这里要使用控件的全路径android.opengl.GLSurfaceView -->

    <android.opengl.GLSurfaceView
        android:id="@+id/glsv_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

接着在Activity代码中获取这个GLSurfaceView对象,并给它注册一个三维图形的渲染器GLRender,此时自定义的渲染器GLRender必须重载onSurfaceCreated、onSurfaceChanged和onDrawFrame这三个函数。下面是对应的Activity代码框架例子:

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_gl_cub);
		GLSurfaceView glsv_content = (GLSurfaceView) findViewById(R.id.glsv_content);
		// 注册渲染器
		glsv_content.setRenderer(new GLRender());
	}

	private class GLRender implements GLSurfaceView.Renderer {
		@Override
		public void onSurfaceCreated(GL10 gl, EGLConfig config) {
			// 这里进行三维绘图的初始化操作
		}

		@Override
		public void onSurfaceChanged(GL10 gl, int width, int height) {
			// 这里要定义三维空间的大小,还要定义三维物体的方位
		}

		@Override
		public void onDrawFrame(GL10 gl) {
			// 这里绘制三维图形的具体形状
		}
	}

点此查看Android开发笔记的完整目录

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年01月22日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档