| 导语 刚接触opengl矩阵时,大家都了解图形的缩放平移等变换是通过矩阵来实现的。但是到底应该怎么计算出这个矩阵值,应该乘大还是缩小,正值还是负值,我们就蒙了。记得我刚接触这块的时候也是一脸懵逼,所以,我们这里以fitcenter来看一下矩阵到底应该怎么算。
-
什么是fit-center?
[图片上传失败...(image-a569e7-1560862172048)]
如上图,是一种常见的视频/图片布局方式,表示长边撑满surface,而短边等比缩放(我们这里同时用高斯模糊填充了背景,这点可以忽略)
2. 怎么实现fit-center?
这里我们来看下opengl的代码:
int aPosition = GLES20.glGetAttribLocation(program, "aPosition");
int aTextureCoord = GLES20.glGetAttribLocation(program, "aTextureCoord");
int uMVPMatrix = GLES20.glGetUniformLocation(program, "uMVPMatrix");
GLES20.glVertexAttribPointer(aPosition, 2, 5126, false, 8, VERTEXT_BUF);
GLES20.glEnableVertexAttribArray(aPosition);
GLES20.glVertexAttribPointer(aTextureCoord, 2, 5126, false, 8, TEXTURE_BUF);
GLES20.glEnableVertexAttribArray(aTextureCoord);
//传入顶点变换的mvpmatrix
GLES20.glUniformMatrix4fv(uMVPMatrix, 1, false, mvpMatrix, 0);
int uTextureLoc = GLES20.glGetUniformLocation(program, "uTexture");
GLES20.glUniform1i(uTextureLoc, 0); //GL_TEXTURE0
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(this.mTextureType, textureId);
GLES20.glDrawArrays(5, 0, 4);
这里关键的代码是:
GLES20.glUniformMatrix4fv(uMVPMatrix, 1, false, mvpMatrix, 0);
最终matrix会被传入到vertex_shader(顶点着色器):
private static final String VERTEXT_SHADER =
"uniform mat4 uMVPMatrix;\n" +
"uniform mat4 uTextureMatrix;\n" +
"attribute vec4 aPosition;\n" +
"attribute vec4 aTextureCoord;\n" +
"varying vec2 vTextureCoord;\n" +
"void main() {\n" +
//uMVPMatrix 与顶点相乘
" gl_Position = uMVPMatrix * aPosition;\n" +
" vTextureCoord = (uTextureMatrix * aTextureCoord).xy;\n" +
"}\n";
我们可以看到,这里uMVPMatrix最终会与顶点坐标aPosition相乘,最终实现相应的缩放、平移等变换。
这里简单举个例子:
[图片上传失败...(image-e28198-1560862172048)]
大矩形是我们要绘制的目标surface(简单理解成屏幕),他有四个顶点ABCD
小矩形是我们内容所在的区域(可以理解成横屏视频渲染区域),他有四个顶点A'B'C'D'.
所以我们就要把A画到A', B->B',C->C',D->D'.
也就是我们要通过矩阵变换将ABCD四个点映射到A'B'C'D'.
那这个矩阵应该是怎样的呢,很明显就是Y方向缩小一半:
float[] mvpMatrix = new float[16];
Matrix.setIdentityM(mvpMatrix , 0);
float scaleX = 1.0F;
float scaleY = 0.5F;
Matrix.scaleM(mvpMatrix , 0, scaleX , scaleY, 1.0F);
最终生成的mvpMatrix就是我们需要的矩阵,就可以传到shader里面对顶点进行相应的变换了。
通过这个例子,我们就知道了:
opengl中的矩阵最终是作用到顶点的(当然还包括文理矩阵,这里不讨论)。所以如果是需要将图形缩小到屏幕上,就是在矩阵对应方向上缩小。最终作用到四个顶点上时,就将顶点限定在了相应的缩小区域,从而达到我们缩放图形的目的。
网友评论