gpt4 book ai didi

java - 使用 GLES20 通过 Android 插件获取位图到 Unity

转载 作者:行者123 更新时间:2023-11-30 10:21:33 26 4
gpt4 key购买 nike

我正在尝试使用 UpdateExternalTextureCreateExternalTexture 将一个简单的位图图像从 android 插件传递到 unity。在文档中它说后者是为了与低级插件一起使用。我使用 Java 代码在其之上。

当我进行任何 GLES20 调用时,我遇到上下文错误:

call to OpenGL ES API with no current context (logged once per thread)

根据这个excellent question这是因为上下文不正确(或没有)。我按照该页面上的说明进行操作,并设法创建了一个上下文。但是,现在他们似乎指的是不同的资源“区域”。我得到的指针是“1”,统一理解为“屏幕上的当前帧”而不是我的位图。所以看起来像这样:

enter image description here

这是我的代码 fragment 。首先是 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);
}

现在是 Java 方面。 Unity 通过 AAR 文件使用此代码。

private int PutBitmapInGraphicsCard() {
final int[] textureHandle = new int[1];
final Bitmap bitmap = GenerateTestImage(); // this creates a simple bitmap, blank with a blue circle in the center, works fine in android.
CreateContext(); // look below, it's defined there
GLES20.glGenTextures(1, textureHandle, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
return textureHandle[0];
}

// This function is a (almost) direct copy from the question linked above
public void CreateContext(){
// gets hold of the display
EGLDisplay dpy = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
int[] vers = new int[2];
EGL14.eglInitialize(dpy, vers, 0, vers, 1);
// get some basic configs going
int[] configAttr = {
EGL14.EGL_COLOR_BUFFER_TYPE, EGL14.EGL_RGB_BUFFER,
EGL14.EGL_LEVEL, 0,
EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
EGL14.EGL_SURFACE_TYPE, EGL14.EGL_PBUFFER_BIT,
EGL14.EGL_NONE
};
EGLConfig[] configs = new EGLConfig[1];
int[] numConfig = new int[1];
EGL14.eglChooseConfig(dpy, configAttr, 0,
configs, 0, 1, numConfig, 0);
if (numConfig[0] == 0) {
Log.e("GLEDB-Error", "Could not find/create config!!");
}
EGLConfig config = configs[0];
// creating an offscreen (PBuffer) surface to render stuff
int[] surfAttr = {
EGL14.EGL_WIDTH, 100,
EGL14.EGL_HEIGHT, 100,
EGL14.EGL_NONE
};
EGLSurface surf = EGL14.eglCreatePbufferSurface(dpy, config, surfAttr, 0);
// create the context
int[] ctxAttrib = {
EGL14.EGL_CONTEXT_CLIENT_VERSION, 2,
EGL14.EGL_NONE
};
EGLContext ctx = EGL14.eglCreateContext(dpy, config, EGL14.EGL_NO_CONTEXT, ctxAttrib, 0);
// connect all these things together
EGL14.eglMakeCurrent(dpy, surf, surf, ctx);
}

因此,如果我对问题的理解是正确的,那么我需要的是引用 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];
}

最佳答案

基于此Manual :

Rendering in Unity can be multithreaded if the platform and number of available CPUs will allow for it. When multithreaded rendering is used, the rendering API commands happen on a thread which is completely separate from the one that runs MonoBehaviour scripts.

您可能打开了多线程渲染,所以可能是这种情况。您可以尝试将其关闭,看看是否有所不同。

关于java - 使用 GLES20 通过 Android 插件获取位图到 Unity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47779970/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com