我尝试为我的Android NDK游戏项目编写加载屏幕 - 预加载所有纹理。 如果在其他线程中创建纹理,我得到正确设置纹理宽度的值,但只获得黑色精灵而不是纹理的,即使glGetError返回0.在同一个线程中一切正常,所以假设精灵或纹理代码中没有错误。
我认为那是因为我尝试从另一个线程调用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);
}
C
#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*/
答案 0 :(得分:2)
要从另一个线程调用OpenGL ES函数,您必须在两个线程之间创建一个共享的OpenGL ES上下文。
有一个更简单的解决方案 - 将事件发送到拥有OpenGL ES上下文的线程,以便在第二个线程中加载纹理后立即更新纹理。
答案 1 :(得分:-1)
Android不支持共享OpenGL上下文,因此必须使用主上下文来创建纹理。您可以在后台线程上加载纹理数据,但必须使用主上下文创建包含该数据的纹理。谢尔盖建议在加载纹理数据后将事件发送到主线程是Android上的正确方法。