目的:
我使用SurfaceTexture来显示相机预览,并且需要通过从ndk获取gl上下文在曲面顶部绘制。我选择了SurfaceTexture方法,因为我可以避免摄像机帧缓冲区从java手动传递到ndk,以节省一些性能。

public class MainActivity extends Activity implements SurfaceTextureListener {

private Camera mCamera;
private TextureView mTextureView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mTextureView = new TextureView(this);
    mTextureView.setSurfaceTextureListener(this);

    setContentView(mTextureView);
}

@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
    mCamera = Camera.open();
    Camera.Size previewSize = mCamera.getParameters().getPreviewSize();
    mTextureView.setLayoutParams(new FrameLayout.LayoutParams(previewSize.width, previewSize.height, Gravity.CENTER));

    try {
        mCamera.setPreviewTexture(surface);
    } catch (IOException t) {
    }

    mCamera.startPreview();
}

@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
    // Ignored, the Camera does all the work for us
}

@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
    mCamera.stopPreview();
    mCamera.release();
    return true;
}

@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
    // Update your view here
}

我试过的:
我想SurfaceTexture内部使用gl功能来绘制上下文。从ndk获取默认显示失败,并出现BAD_DISPLAY错误。
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

当然,我可以初始化一个新的gl上下文并完成我的绘图,但我仍然希望保留背景中java代码显示的纹理。
问题:使用SurfaceTexture时,是否有可能从ndk获取gl上下文?
可能我必须在GLSurfaceView上使用,从java代码手动初始化gl上下文并从ndk获取它?

最佳答案

你的问题对我来说不完全有意义,所以让我提出几件事。
SurfaceTexture不会绘制任何内容。当相机作为一个生产者连接时,surfacetexture接收一个yuv帧,并使用egl函数将其设置为一个“外部”纹理。然后可以使用gles渲染该纹理。
egl上下文可以是一次一个线程中的“当前”上下文。指向当前上下文的指针保存在本机线程本地存储中。Java语言GLE绑定是围绕本地代码的一个薄薄包装,所以在与GLE协作时,Java和C++之间几乎没有概念上的区别。
surfacetexture的纹理将与创建对象时当前的上下文相关联,但可以使用attach/detach调用将其切换到其他上下文。你不能“抓取”surfacetexture的egl上下文,但是你可以告诉它你想要它使用哪一个。
SurfaceTexture(通常是Surface)只能有一个生成器。不能将相机帧发送到要使用gles渲染的曲面。可以在它们之间来回切换,但通常最好使用两个不同的曲面对象。
TextureView是具有嵌入的SurfaceTexture的视图。当要求重绘时,它使用gles从纹理进行渲染(这就是为什么禁用硬件渲染时根本看不到任何内容)。
如果我对你的问题理解正确,我想你想做的是:
将相机输出发送到在渲染器线程上创建的新SurfaceTexture。
为TextureView的SurfaceTexture创建一个eglsurface。
使用gles渲染到纹理视图上,使用相机中的纹理作为示例源。添加任何其他你想要的gles渲染。
可以在Grafika中找到各种示例,例如“来自照相机的纹理”活动。

关于android - 从NDK抓取SurfaceTexture的GL上下文,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33613192/

10-09 13:44