Java 使用GLES20通过Android插件将位图发送到Unity

Java 使用GLES20通过Android插件将位图发送到Unity,java,android,unity3d,opengl-es,egl,Java,Android,Unity3d,Opengl Es,Egl,我试图使用UpdateExternalTexture和CreateExternalTexture将一个简单的位图图像从android插件传递到unity。在文档中,它说后者是为了与低级插件一起使用。我是上面的一层java代码 我在执行任何GLES20调用时遇到上下文错误: 在没有当前上下文的情况下调用OpenGL ES API(每个线程记录一次) 根据这一点,这是因为上下文不正确(或没有)。我按照那一页上的说明创建了一个上下文。然而,现在它们似乎指的是不同的资源“领域”。我得到的指针是“1”,u

我试图使用
UpdateExternalTexture
CreateExternalTexture
将一个简单的位图图像从android插件传递到unity。在文档中,它说后者是为了与低级插件一起使用。我是上面的一层java代码

我在执行任何GLES20调用时遇到上下文错误:

在没有当前上下文的情况下调用OpenGL ES API(每个线程记录一次)

根据这一点,这是因为上下文不正确(或没有)。我按照那一页上的说明创建了一个上下文。然而,现在它们似乎指的是不同的资源“领域”。我得到的指针是“1”,unity将其理解为“屏幕上的当前帧”,而不是我的位图。看起来是这样的:

这是我的一段代码。首先是统一部分。这将附加到场景中的游戏对象

// This function is called shortly after Start
private void TestingTransfer() {
    // get the current activity from unity
    AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    androidActivity = jc.GetStatic<AndroidJavaObject>("currentActivity");
    // create a link to the android plugin
    AndroidJavaObject obj = new AndroidJavaObject("com.test.pc.sample.SampleClass", androidActivity);
    // Make the call to put the bitmap in the graphic memory and get it's PTR
    Int32 texPtr = obj.Call<Int32>("PutBitmapInGraphicsCard");
    Debug.Log("texture pointer == " + texPtr); 
    // Stage the texture in unity
    Texture2D nativeTexture = Texture2D.CreateExternalTexture(100, 100, TextureFormat.ARGB32, false, false, (IntPtr)texPtr);
    // Update it with the new PTR
    nativeTexture.UpdateExternalTexture(nativeTexture.GetNativeTexturePtr());
    // Notify other things in unity that this updated (delegate)
    // I'm using this from another game object to pickup the new texture
    if (OnNewImageReported != null) OnNewImageReported(nativeTexture);
}
所以,如果我对这个问题的理解是正确的,那么我需要的是引用unity用来绘制场景的同一个上下文。有没有办法得到/使用这个


解决方案:

正如公认的答案所指出的,主要问题是我正在使用多线程渲染。对于我的用例来说,这没有什么区别

这与上面的代码不一样。需要注意的几点:

  • 如果你这样做了,就不要创建自己的上下文。它会破坏统一性并阻止曲面的任何更新(冻结任何图形)
  • 代码略有不同,不完全确定上面的代码为什么不起作用,但下面的代码起作用
[故意添加的行,因为StackOverflow无法在项目符号后呈现代码]

public int PutBitmapInGraphicsCard() {
    final int[] textureHandle = new int[1];
    GLES20.glGenTextures(1, textureHandle, 0);
    final Bitmap bitmap = GenerateTestImage();
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D,0, bitmap, 0);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
    return textureHandle[0];
}
基于此:

如果平台和可用CPU数量允许,Unity中的渲染可以是多线程的。使用多线程渲染时,渲染API命令发生在与运行单行为脚本的线程完全分离的线程上

您可能已启用多线程渲染,因此可能是这样。
你可以试着关掉它,看看它是否有什么不同。

是的,就是这样。我不得不对代码做一些小的调整。如果您遇到相同的问题,请不要创建自己的上下文,以供参考。如果这样做,将导致unity应用程序崩溃,并阻止从此处发生任何渲染。我也在更新上面的代码,以便记录我所做的更改。
public int PutBitmapInGraphicsCard() {
    final int[] textureHandle = new int[1];
    GLES20.glGenTextures(1, textureHandle, 0);
    final Bitmap bitmap = GenerateTestImage();
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D,0, bitmap, 0);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
    return textureHandle[0];
}