OpenGL的画笔工具GL10

news/2025/1/31 1:10:53/

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

上一篇文章介绍了OpenGL绘制三维图形的流程,其实没有传说中的那么玄乎,只要放平常心把它当作一个普通控件就好了,接下来继续介绍OpenGL具体的绘图操作,这项工作得靠三维图形的画笔GL10来完成了。

GL10作为三维空间的画笔,它所描绘的三维物体却要显示在二维平面上,显而易见这不是一个简单的伙计。为了理顺物体从三维空间到二维平面的变换关系,有必要搞清楚OpenGL关于三维空间的几个基本概念。下面就概括介绍一下GL10编码的三类常见方法:

一、颜色的取值范围

Android中的三原色,不管是红色还是绿色还是蓝色,取值范围都是0到255,对应的十六进制数值则为00到FF,颜色数值越小表示亮度越弱,数值越大表示亮度越强。但在OpenGL之中,颜色的取值范围却是0.0到1.0,其中0.0对应Android标准的0,1.0对应Android标准的255,同理,OpenGL值为0.5的颜色对应Android标准的128。
GL10与颜色有关的方法主要有两个,说明如下:
glClearColor : 设置背景颜色。以下代码表示给三维空间设置白色背景:

        // 设置白色背景。四个参数依次为透明度alpha、红色red、绿色green、蓝色bluegl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

glColor4f : 设置画笔颜色。以下代码表示把画笔颜色设置为橙色:

        // 设置画笔颜色为橙色gl.glColor4f(0.0f, 1.0f, 1.0f, 0.0f);

二、三维坐标系

三维空间用来表达立体形状,需要三个方向的坐标,分别为水平方向的x轴和y轴,以及垂直方向的z轴。如下图的三维坐标系所示,三维空间有个M点,该点在x轴上的投影为P点,在y轴上的投影为Q点,在z轴上的投影为R点,因此M点的坐标位置就是(P, Q, R)。

既然三维空间中的每个点都存在x、y、z三个方向的坐标值,那么与物体位置有关的方法均需提供x、y、z三方向的数值。比如物体的旋转方法glRotatef、平移方法glTranslatef、缩放方法glScalef,要分别指定物体在三个坐标轴上的旋转方向、平移距离、缩放倍率。具体的方法调用例子如下所示:

        // 沿着y轴的负方向旋转90度gl.glRotatef(90, 0, -1, 0);// 沿x轴方向移动1个单位gl.glTranslatef(1, 0, 0);// x,y,z三方向各缩放0.1倍gl.glScalef(0.1f, 0.1f, 0.1f);

三、坐标矩阵变换

有了三维坐标系,还要把三维物体投影到二维平面上,才能在手机屏幕中绘制三维图形。这个投影操作主要有三个步骤,下面分别展开叙述:

1、设置绘图区域

前面说过OpenGL使用GLSurfaceView这个控件作为绘图场所,于是允许绘制的区域范围自然落在GLSurfaceView内部。设置绘图区域的方法是glViewport,它指定了该区域左上角的平面坐标,以及区域的宽度和高度。当然一般OpenGL的绘图范围与GLSurfaceView的大小重合,所以倘若GLSurfaceView控件的宽度为width,高度为height,则设置绘图区域的方法调用示例如下:

        // 设置输出屏幕大小gl.glViewport(0, 0, width, height);

2、调整镜头参数

框住了绘图区域,还要把三维物体在二维平面上的投影一点一点描绘进去才行,这中间的坐标变换计算由OpenGL内部自行完成,开发者无需关注具体的运算逻辑。好比日常生活中的拍照,用户只管拿起手机咔嚓一下,根本不用关心摄像头怎么生成照片。用户所关心的照片效果,不外乎景物是大还是小,是远还是近;用专业一点的术语来讲,景物的大小由镜头的焦距决定,景物的远近由镜头的视距决定。
对于镜头的焦距而言,拍摄同样尺寸的照片,广角镜头看到的景物比标准镜头看到的景物更多,这意味着单个景物在广角镜头中会比较小,从而照片面积不增大、容纳的景物却变多了。
对于镜头的视距而言,它表示镜头的视力好坏,即最近能看到多近的景物,最远能看到多远的景物。在日常生活当中,每个人的睫毛离自己的眼睛太近了,这么近的东西能看得清楚吗?所以必须规定一下,最近只能看清楚比如离眼睛十厘米的物体。很遥远的景物自然也是看不清楚的,所以也要规定一下,比如最远只能看到一公里之内的人影。这个能看清景物的最近距离和最远距离,就构成了镜头的视距。
所以,镜头的焦距是横向的,它反映了画面的广度;而镜头的视距是纵向的,它反映了画面的深度。在OpenGL中,这些镜头参数的调节依赖于GL10的gluPerspective方法,具体的参数调整代码举例如下:

        // 设置投影矩阵,对应gluPerspective(调整相机参数)、glFrustumf(调整透视投影)、glOrthof(调整正投影)gl.glMatrixMode(GL10.GL_PROJECTION);// 重置投影矩阵,即去掉所有的参数调整操作gl.glLoadIdentity();// 设置透视图视窗大小。第二个参数是焦距的角度,第四个参数是能看清的最近距离,第五个参数是能看清的最远距离GLU.gluPerspective(gl, 40, (float) width / height, 0.1f, 20.0f);

3、挪动观测方位

调整好了镜头的拍照参数,要不要再摆个POSE,来个花式摄影?比如用户跃上好几级台阶,居高临下拍摄;也可俯下身子,从下向上拍摄;还能把手机横过来拍或者倒过来拍。要是怕摄影家累坏了,不妨叫摆拍的模特自己挪动身影,或者走进或者走远,往左靠一点或者往右靠一点,还可以躺下来甚至倒立过来。
因此,不管是挪动相机的位置,还是挪动物体的位置,都会让照片里的景物发生变化。挪动相机的位置,依靠的是GL10的gluLookAt方法;至于挪动物体的位置,依靠的则是旋转方法glRotatef、平移方法glTranslatef,以及缩放方法glScalef了。下面是OpenGL挪动相机位置的方法调用代码:

        // 选择模型观察矩阵,对应gluLookAt(人动)、glTranslatef/glScalef/glRotatef(物动)gl.glMatrixMode(GL10.GL_MODELVIEW);// 重置模型矩阵,即去掉所有的位置挪动操作gl.glLoadIdentity();// 设置镜头的方位。第二到第四个参数为相机的位置坐标,第五到第七个参数为相机画面中心点的坐标,第八到第十个参数为朝上的坐标方向,比如第八个参数为1表示x轴朝上,第九个参数为1表示y轴朝上,第十个参数为1表示z轴朝上GLU.gluLookAt(gl, 10.0f, 8.0f, 6.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);

注意到前面调整相机参数和挪动相机位置这两个动作,都事先调用了glMatrixMode与glLoadIdentity方法,这是什么缘故呢?其实这两个方法结合起来只不过是状态重置操作,好比把手机恢复出厂设置,接下来重新进行状态设置。glMatrixMode方法的参数指定了重置操作的类型,像GL10.GL_PROJECTION类型涵盖了所有的镜头参数调整方法,包括gluPerspective(调整相机参数)、glFrustumf(调整透视投影)、glOrthof(调整正投影)三种方法,每次重置GL10.GL_PROJECTION类型,意味着之前的这三种参数设置统统失效。而GL10.GL_MODELVIEW类型涵盖的是位置变换的相关方法,包括挪动相机的gluLookAt方法,以及挪动物体的glTranslatef/glScalef/glRotatef方法,每次重置GL10.GL_MODELVIEW类型,意味着之前的位置挪动统统失效。

现在了解了以上的三维绘图的常见方法,接下来再看OpenGL的应用代码就会比较轻松了。先来看看一个最简单的三维立方体是如何实现的,下面是OpenGL绘制立方体的代码例子片段:

public class GlCubeActivity extends Activity {private final static String TAG = "GlCubeActivity";private GLSurfaceView glsv_content;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_gl_cube);initVertexs(); // 初始化立方体的顶点集合,具体说明详见下一篇文章glsv_content = (GLSurfaceView) findViewById(R.id.glsv_content);// 注册渲染器glsv_content.setRenderer(new GLRender());}private class GLRender implements GLSurfaceView.Renderer {@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {// 背景:白色gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);// 启动阴影平滑gl.glShadeModel(GL10.GL_SMOOTH);}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {// 设置输出屏幕大小gl.glViewport(0, 0, width, height);// 设置投影矩阵,对应gluPerspective(调整相机)、glFrustumf(调整透视投影)、glOrthof(调整正投影)gl.glMatrixMode(GL10.GL_PROJECTION);// 重置投影矩阵,即去掉所有的平移、缩放、旋转操作gl.glLoadIdentity();// 设置透视图视窗大小GLU.gluPerspective(gl, 40, (float) width / height, 0.1f, 20.0f);// 选择模型观察矩阵,对应gluLookAt(人动)、glTranslatef/glScalef/glRotatef(物动)gl.glMatrixMode(GL10.GL_MODELVIEW);// 重置模型矩阵gl.glLoadIdentity();}@Overridepublic void onDrawFrame(GL10 gl) {// 清除屏幕和深度缓存gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);// 重置当前的模型观察矩阵gl.glLoadIdentity();// 设置画笔颜色gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);// 设置镜头的方位GLU.gluLookAt(gl, 10.0f, 8.0f, 6.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);// 旋转图形//gl.glRotatef(angle, 0, 0, -1);//gl.glRotatef(angle, 0, -1, 0);// 沿x轴方向移动1个单位//gl.glTranslatef(1, 0, 0);// x,y,z方向缩放0.1倍//gl.glScalef(0.1f, 0.1f, 0.1f);// 绘制一个立方体,具体说明详见下一篇文章drawCube(gl);}}
}

 

转载于:https://my.oschina.net/ouysh1981/blog/1611608


http://www.ppmy.cn/news/550480.html

相关文章

马克笔字体软件测试,广东文艺职业学院2017年公开招聘专业技能测试试题

美术系教师岗-A01 考核内容: 结合会展专业特点,根据指定项目设计一个可行性策划方案并现场宣讲,时间为15分钟以内。 备注:指定项目考前10分钟提供。 音乐系教师A岗-A02 (音乐传播、视音频录音编辑制作) 考核内容: 1.现…

iphone图片编辑画笔_iPhone手机最好的图片编辑软件有哪些?

895675713 2019-07-20 17:16 1046 随着Dennis强势入手iPhone之后,编辑部群里面每天增加了一项固定话题——关于iPhone的种种讨论。虽然iPhone拍照能力的确赶不上现在的卡片相机,但在各种各样强大的软件支持下,iPhone能够变成一个非常有趣的随拍武器。而且有些效果是卡片机无…

远心镜头运用目的

工业智能相机远心镜头目的就是消除由于被测物体(或CCD芯片)离镜头距离的远近不一致,造成放大倍率不一样。分为:物方远心镜头、像方远心镜头和双侧远心镜头。物方远心镜头,通过在像方焦平面上放置孔径光阑,使…

使用画笔绘制飘雪效果

制作飘雪效果的方法有很多,比如: (一)用雪花素材进行叠加。通常只要将图层混合模式改为滤色即可,最简单; (二)滤镜法:使用点状化滤镜、晶格化滤镜等产生雪花点&#xff0…

机器视觉——工业镜头保养知识

文章目录 相机镜头为什么要镀膜? 有何弊端UV镜工业镜头清洗保养小技巧 相机镜头为什么要镀膜? 有何弊端 从光学常识知道,当光线通过一个透镜时,总有一部分光线被反射和吸收,被反射和吸收的量分别占5%和2&a…

钢笔朝花夕拾录————一位钢笔玩家的入坑至出坑心路历程

文章目录 0 简介1 笔记1.1 百乐的P-5001.2 三菱UM1511.3 百乐juice up1.4 百乐卡佛利亚1.5 凌美LX1.6 凌美joy1.7 百乐88g1.8 百乐741.9 凌美20001.10 英雄1001.11 英雄鼎新1001.12 写乐大型21k犁地1.13 百利金白乌龟m4001.14 万宝龙1461.15 百乐845(全套&#xff1…

多少秒算长镜头_《长安十二时辰》开篇一个长镜头126秒,究竟埋下了多少伏笔?...

《长安十二时辰》这部良心制造,第一集就用几个非常有代表性的长镜头,把观众带进了大唐长安惊险刺激的那一天 给海米留下最深印象的当属开篇的第一个镜头,时长126秒,然而全剧最有代表性的元素都被融入到了这个画面里面 那么我们就一…

相机镜头_如何保持相机镜头清洁

相机镜头 I’ve stressed time and time again here on How-To Geek: the lens is as important, if not more important, than the camera to which it’s attached. If your photos are blurry because there are smudges on your lens, there’s nothing you can do to fix …