OpenGL知识点记录

OPenGL简介:

Android中OPenGL有两种:

OPenGL ES 1.X (主要有1.0和1.1),采用的是固定渲染管线。

OPenGL ES 2.0 采用的是可编程渲染管线。

渲染管线:由显示芯片(GPU)内部处理图形信号的并行单元组成。这些单元相互独立,一般独立处理单元越多,处理速速越快,性能越好。


片元:

OpenGL知识点记录_第1张图片


开发OPenGl会用到的英文描述:

attribute           属性(属性变量限定符)
uniform             一致(一致变量限定符)
varying             易变(易变变量限定符)
Matrix               矩阵
projection       投影
vertex              顶点
texture             纹理
shader            着色器
Circle              圆

fragment       片元



GLES20.glEnable(GLES20.GL_CULL_FACE);     //打开背面裁剪

作用:在渲染立体物体时,可以不绘制隐藏的部分,提高渲染效率,但是对于绘制一般的2D平面内容,并且正反两面都需要看的情况下建议不用该方法。

GLES20.glDisable(GLES20.GL_CULL_FACE);   //关闭背面裁剪


设置投影:

publicstaticvoidfrustumM(float[]m,intoffset,

        float left, float right, float bottom, float top,
        float near, float far)
        
float ratio = (float) width / height;
Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);

前两个参数不用多说,Javadoc 里面就有, m 是保存变换矩阵的数组, offset 是开始保存的下标偏移量。后面的 6 个参数就是那篇博客中提到的参数了,那我们为什么要为它们设置这样的值呢?

surface view 的宽高为 width 和 height ,我们要把 OpenGL 坐标系投影到 surface view 上。首先我们忽略坐标系的方向问题(方向问题由相机视觉解决),以 OpenGL 的方向为准,我们把坐标原点置于 view 中心,这样 view 的 y 轴范围就是 [- height / 2, height / 2] ,x 轴范围就是 [- width / 2, width / 2] 。

如果我们希望 OpenGL 坐标系 y 坐标范围充满 surface view 的高,那我们就需要让 [-1, 1] 和[- height / 2, height / 2] 映射起来。怎么做呢?除以 height/ 2 即可。此时 x 轴范围就变成了 [- width / height, width / height] ,也就是 [-ratio, ratio] 了。

我们当然可以把 x 坐标范围归一化为 [-1, 1] ,这时我们的矩阵代码需要变成这样:

float ratio = (float) height / width;
Matrix.frustumM(mProjectionMatrix, 0, -1, 1, -ratio, ratio, 3, 7);

Matrix.setLookAtM

public static void setLookAtM(float[] rm, int rmOffset,
        float eyeX, float eyeY, float eyeZ,
        float centerX, float centerY, float centerZ, float upX, float upY,
        float upZ)
        
Matrix.setLookAtM(mCameraMatrix, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0);

我们需要传入 9 个坐标值,(eyeX, eyeY, eyeX),(centerX, centerY, centerZ),(upX, upY, upZ)。eye 表示相机的坐标点,center 表示物体(目标,或者图形)的中心坐标点,up 表示方向向量。

通常情况下,我们都把 center 设置为坐标原点。而由于上节中介绍的投影变换是投影到 x, y 平面,所以相机都在 z 轴上,至于在 z 轴的哪个点,就要结合调用 Matrix.frustumM 时的 near 和far 参数了, near <= z <= far 时我们才能看到渲染的内容,否则屏幕上就是空白了。

而 up 向量的设置我们就需要先看一下 OpenGL 坐标系了:

OpenGL知识点记录_第2张图片

看清楚这幅图需要一点空间想象力 =_=

up 向量的长度无关紧要,重要的是方向。左图中,我们把 up 设置为 y 轴方向,即 (0, 1, 0),我们让 up 向量指向我们的正上方(这时不需要动),那此时我们看到的样式就是 OpenGL 渲染出来的样子。而在右图中,我们把 up 设置为 x 轴方向,即 (1, 0, 0),这时我们就需要先把图逆时针旋转 90°,所以 OpenGL 渲染出来的将是逆时针旋转 90° 之后的

投影及相机使用参考原文:https://blog.piasy.com/2016/06/07/Open-gl-es-android-2-part-1/?utm_source=tuicool&utm_medium=referral

个人理解:

Matrix.frustumM()决定了一个3D物体使用透视投影的方式将图形按照float left, float right, float bottom, float top(其实left,right相当于X轴长度,bottom,top相当于Y轴长度,这个参数的设定其实可以作为我们顶点坐标设定的一个参考)的方式投影到了我们目前看到的屏幕上
float near决定了照相机距离我们投射的图像的最近距离,far为最远距离。
Matrix.OrthoM()决定了一个3D物体使用正交投影的方式将图形按照float left, float right, float bottom, float top(其实left,right相当于X轴长度,bottom,top相当于Y轴长度,这个参数的设定其实可以作为我们顶点坐标设定的一个参考)的方式投影到了我们目前看到的屏幕上
float near决定了照相机距离我们投射的图像的最近距离,far为最远距离。

Matrix.setLookAtM()方法根据投影的不同方式最终显示在我们的屏幕上,X,Y轴是我们显示的屏幕,Z轴垂直于屏幕,所以float eyeX, float eyeY一般设置为0,float eyeZ设置为照相机距离图像的距离,eyeZ针对选择的投影方式有所区别,对于透视投影,它是“远大近小”原则eyeZ越大于near越接近far则显示的图像越小,对于正交投影,因为它显示的图像不会根据距离的大小产生变化,所有eyeZ的值只要在near和far之间显示出现的效果是一样大的。

float centerX, float centerY, float centerZ一般设置为原点坐标(0,0,0)

float upX, float upY,float upZ三个值可以想成照相机正对屏幕的方式,正常情况下UP方向与Y轴平行(设置成(0,1,0)),看到的就是我们正常看到的图形。



你可能感兴趣的:(OPenGL,ES2.0)