我有一个带有渲染器和多个着色器程序的 GLSurfaceView。在其中一个着色器程序中,渲染方形几何体并使用纹理为几何体着色。这里使用的纹理实际上是来自camerax的具有最小尺寸的实时馈送。现在我想将相机框架升级到我的视口尺寸,同时保持纹理图像的纵横比。
顶点数据:
{
-1.0f, 1.0f, 0f,
-1.0f, -1.0f, 0f,
1.0f, -1.0f, 0f,
1.0f, 1.0f, 0f
}
抽奖订单:
{
0, 1, 2,
0, 2, 3
}
紫外线坐标:
{
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f
}
将视口尺寸和纹理图像尺寸视为任意。
我想升级着色器内的图像,就像我尝试使用 Android 的位图和画布升级图像一样,相对于实时摄像头输入来说,它需要太长时间。
此外,如果定义了这种升级逻辑,我还有其他着色器程序使用从相机输入图像推断出的复杂网格。因此,这样的逻辑还必须针对这些其他着色器程序进行转换和缩放(这些其他着色器及其网格已经有一个正在处理它们的转换矩阵)。
*注意:我没有使用透视相机,甚至没有使用正交相机。
我尝试使用以下方法获取缩放值:
float imgAspectRatio = (float) cameraFrameTexture.getWidth() / (float) cameraFrameTexture.getHeight();
float viewAspectRatio = (float) GLRenderer.rendererWidth / (float) GLRenderer.rendererHeight;
if (imgAspectRatio > viewAspectRatio) {
yScale = viewAspectRatio / imgAspectRatio;
} else {
xScale = imgAspectRatio / viewAspectRatio;
}
和
"uniform mat4 uMVPMatrix;" +
"uniform vec2 uScaleFactor;" +
"attribute vec2 uTexCoords;" +
"attribute vec3 vPosition;" +
"varying vec2 bTexCoords;" +
"void main() {" +
" vec4 pos = uMVPMatrix * vec4(vPosition.xyz,1.0);" +
" gl_Position = vec4(uScaleFactor * pos.xy,pos.z,1.0);" +
" bTexCoords = uTexCoords ;" +
"}";
这段代码会缩小我的几何形状,但确实有效。虽然我不想缩小飞机的几何形状,但保持原样。
我能够使用here的答案解决这个问题。
我使用的缩放逻辑如下:
float[] vPMatrix = new float[16];
Matrix.setIdentityM(vPMatrix, 0);
float textureAspectRatio = (float) texture.getWidth() / (float) texture.getHeight();
float viewAspectRatio =
(float) newWidth / (float) newHeight;
float scaleX = textureAspectRatio / viewAspectRatio ;
xScale = yScale = 1f;
if (scaleX >= 1f)
xScale = scaleX;
else
yScale = 1f / scaleX;
Matrix.scaleM(vPMatrix, 0, xScale, yScale, 1.0f);
使用顶点着色器中的 vPMatrix 将其与位置向量相乘。