Android NDK - 从其他线程加载纹理

问题描述:

我尝试为我的Android NDK游戏项目编写加载屏幕 - 预加载所有纹理。 如果在其他线程中创建纹理,我会得到类似于正确设置纹理宽度的值,但即使glGetError返回0,也只是得到黑色精灵而不是纹理值。在同一线程中,一切正常,因此假设精灵或纹理中没有错误码。Android NDK - 从其他线程加载纹理

我认为这是因为我尝试从另一个线程调用opengl es 2.0函数,没有EGL提供的上下文。但是,如何从EGL中获得opengl ES 2.0上下文,这是使用Java(Android)创建的,并将其绑定到本地C中的opengl es 2.0函数中?

的Java(机器人)

public class OGLES2View extends GLSurfaceView 
{ 
private static final int OGLES_VERSION = 2; 

public OGLES2View(Context context) 
{ 
    super(context); 
    setEGLContextClientVersion(OGLES_VERSION); 
    setRenderer(new OGLES2Renderer()); 
} 

private GLSurfaceView ogles2SurfaceView = null; 

@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    ogles2SurfaceView = new OGLES2View(this); 
    setContentView(ogles2SurfaceView); 
} 

Ç

#define TRUE 1 
#define FALSE 0 

typedef unsigned char bool; 

typedef struct game_data 
{ 
bool loaded; 
tex* t; 
}game_data; 

static void* loader_thread_func(void* arg) 
{ 
JavaVM* jvm = get_java_vm(); //get java VM to detach in the end 
JNIEnv* env = get_jni_env(); //== attach current thread 
game_data* to_load = (game_data*) arg; 
to_load->t = malloc(sizeof(tex)); 
set_tex(to_load->t,"textures/bonus.png");//textures width and height set correctly 
to_load->loaded = TRUE; 
(*jvm)->DetachCurrentThread(jvm); 
return NULL; 
} 

void load_game_data(game_data* res) 
{ 
pthread_t loader_thread; 
pthread_create(&loader_thread, NULL, loader_thread_func, res); 
} 

/*in render manager file*/ 
static game_data* g_d = NULL; 

/*in onInit func*/ 
g_d = malloc(sizeof(game_data)); 
g_d->loaded = FALSE; 
load_game_data(g_d); 

/*in onDraw function*/ 
if(g_d->loaded) 
/*draw sprite*/ 

要从必须创建2个线程之间的共享的OpenGL ES上下文另一个线程调用OpenGL ES的功能。

有一个更简单的解决方案 - 将事件发送到拥有OpenGL ES上下文的线程,以便在第二个线程中加载后立即更新纹理。

Android不支持共享OpenGL上下文,因此您必须使用主上下文来创建纹理。您可以将纹理数据加载到后台线程上,但使用该数据创建纹理必须使用主要上下文来完成。在加载纹理数据之后,Sergey建议将事件发送到主线程是Android上的正确方法。

+0

自从GLES20以来,Android肯定支持共享上下文。任何使用GLSurfaceView卡住的人都必须使用共享上下文才能访问GLES30函数(如位块传输)。使用GLES30,真正的缓冲区对象可以打包,并用于异步传输纹理到GL线程。 – 2015-12-23 18:09:15