Android OpenGL ES以宽高比全屏显示图像

维旺迪

我想在我的OpenGL应用程序中全屏显示图像,而不会失去其宽高比。我知道我可以将图像作为纹理绘制到“立方体”或2d平面上。但是当我只想显示2D图像时,我不确定这是否是最好的方法。

尤其是因为我希望此图像全屏显示而不损失其宽高比。我知道使用ImageView很容易。但我的OpenGL ES应用程序中需要此功能。

但是我不知道该怎么做。有人知道吗?

雷托·科拉迪(Reto Koradi)

由于图像的纵横比和视图的纵横比通常会有所不同,因此有两种情况。宽高比定义为宽度/高度:

  1. 如果图像的纵横比大于视图的纵横比,则顶部和底部都需要黑条。
  2. 如果图像的长宽比小于视图的长宽比,则左右各需要黑条。

在不应用任何变换的情况下,OpenGL使用的坐标系在x和y方向上的范围均为[-1.0,1.0]。因此,如果您在两个方向上绘制一个覆盖[-1.0,1.0]的四边形,它将填充整个视图。由于我们不想在两个方向之一上填充整个范围,因此需要在情况1中按比例缩小y坐标,在情况2中按比例缩小x坐标。所需的缩放比例对应于方向2之间的比例。两个纵横比。

具有以下值:

float imgAspectRatio = (float)imgWidth / (float)imgHeight;
float viewAspectRatio = (float)viewWidth / (float)viewHeight;

我们将x和y的比例因子计算为:

float xScale = 1.0f;
float yScale = 1.0f;
if (imgAspectRatio > viewAspectRatio) {
    yScale = viewAspectRatio / imgAspectRatio;
} else {
    xScale = imgAspectRatio / viewAspectRatio;
}

现在剩下的就是在渲染时应用这些比例因子。有多种方法可以做到这一点。您可以将它们用作输入坐标,并绘制一个四边形,该四边形在x方向上跨越[-xScale,xScale],在y方向上跨越[-yScale,yScale]。或者,您可以在着色器中应用缩放,我认为它稍微更优雅一些。在这种情况下,您仍将在两个方向上绘制一个范围为[-1.0,1.0]的四边形,并使用如下所示的顶点着色器:

#version 100
uniform vec2 ScaleFact;
attribute vec2 Position;
varying vec2 TexCoord;
void main() {
    gl_Position = vec4(ScaleFact * Position, 0.0, 1.0);
    TexCoord = 0.5 * Position + 0.5;
}

还有一个片段着色器,可以简单地对纹理进行采样:

#version 100
precision mediump float;
uniform sampler2D Tex;
varying vec2 TexCoord;
void main() {
    gl_FragColor = texture2D(Tex, TexCoord);
}

您传入xScale/yScale我们上面计算出的ScaleFact统一值的值,按照通常的方式设置属性位置和其他所有内容,然后渲染[-1.0,1.0] x [-1.0,1.0]四边形。

在着色器中进行缩放的优点在于,您仍然可以轻松地从单个输入属性中获取位置和纹理坐标。如果传递缩放位置,则可能需要一个单独的属性传递纹理坐标。这样做也是一件非常好的事情。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章