我在android中的OpenGLES中有一个平面,我将相机帧渲染为纹理,我想升级纹理以保持纵横比

问题描述 投票:0回答:1

我有一个带有渲染器和多个着色器程序的 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 ;" +
                    "}";

这段代码会缩小我的几何形状,但确实有效。虽然我不想缩小飞机的几何形状,但保持原样。

android opengl-es glsl scaling aspect-ratio
1个回答
0
投票

我能够使用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 将其与位置向量相乘。

© www.soinside.com 2019 - 2024. All rights reserved.