如何在Android上不缩小或重复显示缩小的GL ES纹理 [英] How to display a scaled down GL ES texture without clamp or repeat on android

查看:94
本文介绍了如何在Android上不缩小或重复显示缩小的GL ES纹理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用Android上的GL ES 2.0将相机预览渲染到SurfaceTexture,使用opengl渲染它,然后将其传输到媒体编解码器的输入表面进行记录.它以表面视图的形式显示给用户,并且通过设置该表面视图的纵横比,不会使相机预览根据屏幕尺寸而失真.

I am currently rendering a camera preview using GL ES 2.0 on android to a SurfaceTexture, rendering it with opengl, then transferring it to a media codec's input surface to for recording. It is displayed to the user in a surface view and by setting that surface view's aspect ratio the camera preview is not distorted based on screen size.

录制是纵向的,但是到了某个时候,进入的纹理将开始进入横向,在这一点上,我想缩小并显示为电影",将其拉宽以适合屏幕边缘横向并在顶部和底部带有黑条,以保持纹理的长宽比.

The recording is in portrait, but at some point the incoming texture will start coming in landscape, at which point I'd like to zoom out and display it as a "movie" stretched wide to fit to the edge of the screen horizonatally with black bars on the top and bottom to maintain the aspect ratio of the texture.

在onDrawFrame中绘制代码非常简单.该链接包含着色器等的其余设置代码,但只是设置了要绘制的三角形条.

The drawing code in onDrawFrame is pretty simple. The link has the rest of the setup code for shaders and the like but it's just setting up a triangle strip to draw.

private final float[] mTriangleVerticesData = {
        // X, Y, Z, U, V
        -1.f, -1.f, 0, 0.f, 0.f,
        1.f, -1.f, 0, 1.f, 0.f,
        -1.f,  1.f, 0, 0.f, 1.f,
        1.f,  1.f, 0, 1.f, 1.f,
};
    public static final String VERTEX_SHADER =
        "uniform mat4 uMVPMatrix;\n" +
                "uniform mat4 uSTMatrix;\n" +
                "attribute vec4 aPosition;\n" +
                "attribute vec4 aTextureCoord;\n" +
                "varying vec2 vTextureCoord;\n" +
                "void main() {\n" +
                "  gl_Position = uMVPMatrix * aPosition;\n" +
                "  vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" +
                "}\n";

private float[] mMVPMatrix = new float[16];
private float[] mSTMatrix = new float[16];


    public TextureManager() {
    mTriangleVertices = ByteBuffer.allocateDirect(
            mTriangleVerticesData.length * FLOAT_SIZE_BYTES)
            .order(ByteOrder.nativeOrder()).asFloatBuffer();
    mTriangleVertices.put(mTriangleVerticesData).position(0);

    mTriangleHalfVertices = ByteBuffer.allocateDirect(
            mTriangleVerticesHalfData.length * FLOAT_SIZE_BYTES)
            .order(ByteOrder.nativeOrder()).asFloatBuffer();
    mTriangleHalfVertices.put(mTriangleVerticesHalfData).position(0);

    Matrix.setIdentityM(mSTMatrix, 0);
}

    onDrawFrame(){
    mSurfaceTexture.getTransformMatrix(mSTMatrix);

    GLES20.glUseProgram(mProgram);
    checkGlError("glUseProgram");

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0);
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);

    mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
    GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,
            TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
    checkGlError("glVertexAttribPointer maPosition");
    GLES20.glEnableVertexAttribArray(maPositionHandle);
    checkGlError("glEnableVertexAttribArray maPositionHandle");

    mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
    GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false,
            TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
    checkGlError("glVertexAttribPointer maTextureHandle");
    GLES20.glEnableVertexAttribArray(maTextureHandle);
    checkGlError("glEnableVertexAttribArray maTextureHandle");

    Matrix.setIdentityM(mMVPMatrix, 0);
    GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
    GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);

    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
    checkGlError("glDrawArrays");
    GLES20.glFinish();`
}

我尝试过的尚未完全解决的问题:缩放mMVPMatrix或mSTMatrix进行缩放.我可以进行缩放,因此可以显示风景视频的中心片段"而不会失真,但这会中断视频中40%的巨大部分,因此这不是一个很好的解决方案.通过缩放这些矩阵进行缩小会导致纹理重复边缘上的像素,这是由于对边缘的钳制.

Things I've tried that haven't quite worked: Scaling mMVPMatrix or mSTMatrix to zoom in. I can zoom in, so I can get the "center slice" of the landscape video to display without distortion, but this cuts off a huge 40% portion of the video, so it isn't a great solution. Zooming out by scaling these matricies causes the texture to repeat the pixel on the edge because of the clamp to edge behavior.

将mTriangleVerticesData的x,y,z部分减半可以得到所需的行为 some ,如下面的屏幕快照所示,但不包括确切的长宽比.图片的中心部分按预​​期方式减半并居中.但是,纹理在左,右和底部重复,并且左上角有变形.我想要是原样的中心,周围没有黑色/任何东西.

Halving the x,y,z parts of mTriangleVerticesData gives some of the desired behavior as seen in the screenshot below, exact aspect ratio aside. The center part of the picture is halved and centered, as expected. However, the texture is repeated to the left, right, and bottom, and there is distortion to the top left. What I want is the center to be as it is, with black/nothing surrounding it.

我可以向外缩放,然后翻译mMVPMatrix或mSTMatrix,然后更改着色器以将黑色显示为(0,1)以外的任何颜色,但最终我想将多个纹理彼此叠加,例如完整尺寸的背景和局部尺寸前景纹理.为此,我必须最终弄清楚如何仅在可用空间的一部分中显示纹理,而不仅仅是操纵纹理,以使事情看起来像是发生了这种事情.

I could scale out then translate mMVPMatrix or mSTMatrix and then change my shader to display black for anything outside (0,1) but eventually I want to overlay multiple textures on top of one another, like a full size background and partial size foreground texture. To do this I must eventually figure out how to only display a texture in a portion of the available space, not just manipulate the texture so it looks like that's what's happening.

感谢您阅读所有内容.任何帮助,建议或大胆的猜测都是值得的.

Thanks for reading all that. Any help, suggestions, or wild guesses are appreciated.

推荐答案

重复的图像块看起来像是GPU切片工件,而不是纹理重复.添加glClear()调用以擦除背景.

The repeated image chunks look like GPU tiling artifacts, not texture repeating. Add a glClear() call to erase the background.

这篇关于如何在Android上不缩小或重复显示缩小的GL ES纹理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆