Android插件中的SurfaceTexture在Unity中不起作用

问题描述 投票:5回答:2

我无法将纹理绑定到SurfaceTexture以在Unity中显示。

更新4:基于更新1中的管道(表面 - >外部纹理通过表面纹理 - > fbo - >纹理2d)我知道SurfaceTexture没有正确地将其表面转换为纹理。我可以通过pixelcopy从其表面获得正确的绘制图片,我可以确认我的FBO绘图到texture2d管道使用一些测试颜色。所以问题是,为什么SurfaceTexture不能将其表面转换为纹理?

我在Java中生成一个Texture并将其指针传递回Unity:

public void initGLTexture()
{
    Log.d("Unity", "initGLTexture");
    int textures[] = new int[1];
    GLES20.glGenTextures(1, textures, 0);
    mTextureId = textures[0];

    GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureId);
    GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}

我从id(在Java中)创建了一个SurfaceTexture

mSurfaceTexture = new SurfaceTexture(mTextureId);
mSurfaceTexture.setDefaultBufferSize(512, 512);

我使用第三方库GeckoView渲染到SurfaceTexture的Surface上。我从Unity的OnRenderObject()调用以下方法来保持所有GL渲染在同一个线程上:

mSurfaceTexture.updateTexImage();

我知道上面的代码可以正确地绘制到表面上。

我在Unity中调用以下内容来加载纹理:

_imageTexture2D = Texture2D.CreateExternalTexture(
        512,512,TextureFormat.RGBA32,false,true,(IntPtr) mTextureId);
_rawImage.texture = _imageTexture2D;

为什么应用纹理的RawImage只显示这个精灵外观的东西,它应该是一个网页?

texture

更新1:所以我一直在研究以下假设:使用Gecko绘制到Surface,并使用SurfaceTexture将此表面渲染为GL_TEXTURE_EXTERNAL_OES。因为我无法在Unity上显示它(不确定原因)我将此纹理绘制到帧缓冲区并将帧缓冲区中的像素复制到GL_TEXTURE_2D。我在texture_2d中获得了一个网页(在带有imageview和glReadPixels的模拟器中)。但是,当我将工作导入Unity以测试管道是否可以到目前为止我只是得到一个黑屏。我可以通过PixelCopy api获得表面图像。

这是我的FBO概述代码 - 我的渲染代码来自grafika的texture2D program

    // bind display buffer
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFrameBufferId);
    GlUtil.checkGlError("glbindframebuffer");

    // unbind external texture to make sure it's fresh
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0);
    GlUtil.checkGlError("glunbindexternaltex");

   // bind source texture (done in drawFrame as well )
    GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mOffscreenTextureId);
    GlUtil.checkGlError("glBindFramebuffer");

    // draw to frame buffer
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);    // again, only really need to
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);     //  clear pixels outside rect

    mFullScreen.drawFrame(mOffscreenTextureId, mIdentityMatrix);

    // unbind source texture
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,0);
    GlUtil.checkGlError("glBindTexture2d");

    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0);
    GlUtil.checkGlError("glunbindexternaltex");

    // make sure we're still bound to fbo
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFrameBufferId);
    GlUtil.checkGlError("glBindTexture2d");

    // copy pixels from frame buffer to display texture
     GLES20.glCopyTexImage2D(GLES20.GL_TEXTURE_2D,0,GLES20.GL_RGBA,0,0,512,512,0);

    // read pixels from the display buffer to imageview for debugging
    BitmapDisplay.mBitmap = SavePixels(0,0,512,512);

    // unbind texture
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,0); 

这是我的播放器设置>其他:settings

更新2:可能尝试的管道:通过this接口在C ++中调用外部纹理的绘制函数到FBO(附加到Unity的texture_2d)。

更新3:从本机代码调用Java函数,负责通过GL.IssuePluginEvent将纹理从SurfaceTexture绘制到FBO到Unity的纹理,产生第一次更新中的黑色纹理。它将在模拟器中显示图像,但在Unity中不显示。

android unity3d opengl-es textureview android-unity-plugin
2个回答
2
投票

几个月前我不得不做类似的任务,发现正确的管道是在Unity中创建纹理,在C中获取本机指针,最后在Java层中更新它。

请看一下这个示例项目,它应该给你一个不同的视角。

https://github.com/robsondepaula/unity-android-native-camera

问候

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