I try to write loading screen for my Android NDK game project – to preload all textures.
If create texture in other thread, i get values like texture width set correctly, but get just black sprite instead of textured one, even if glGetError return 0. In same thread everything works ok, so assume there are no errors in sprite or texture code.
I think that is because i try to call opengl es 2.0 functions from another thread, without context provided by EGL. But how then get opengl es 2.0 context from EGL, which created in Java (Android) and bind it to use in opengl es 2.0 functions in native C?
Java(Android)
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*/
To call OpenGL ES functions from another thread you have to create a shared OpenGL ES context between 2 threads.
There is an easier solution – send the event to the thread that owns the OpenGL ES context to update the texture as soon as it is loaded in the second thread.