Hello,
My project uses Ogre for rendering and SDL 2 for input handling and possibly other features in the future. On linux and Windows I use SDL to create the window then pass its handle to Ogre to setup rendering. This has been working fine. However, recently I have been porting my game to android. Following the GLES2 Demo I can get rendering working on Android as a purely native app. From what I can tell though SDL wants to be used in a JNI app. I have not been able to get Ogre and SDL to coexist on this. Has anyone else had success combining these libraries on Android? If so I could use some pointers.
Thanks
Android and sdl
-
- Gnoblar
- Posts: 3
- Joined: Tue Dec 01, 2009 7:13 pm
Re: Android and sdl
I've managed to integrate ogre with libsdl2 on android, but some difficulties occured...
First of all I've modified OgreAndroidEGLWindow.cpp in GLES2RenderSystem:
Than I've rebuilded Ogre.
Here is some example code for Ogre Init on Android with SDL2:
And some example code for creation Ogre window on Android with SDL2:
It's worked for me with simple scene: cube with simple texturing shader and texture...
Until I've minimized and restored the app - after restoring there was some color flickering or ghost pixels, i don't know.
Finally I've managed to close and reopen ogre window on app mimize/restore and saw background color changes but not my simple scene
May be I should try to unload/reload all graphic resources like meshes, textures and shaders...
I didn`t try any hardcore stuff yet because I want to hear some comments from ogre gurus.
First of all I've modified OgreAndroidEGLWindow.cpp in GLES2RenderSystem:
Code: Select all
136 eglContext = eglGetCurrentContext();
[color=#FF0000]137[b]-[/b] if (eglContext)[/color]
[color=#00BF00]137[b]+[/b] if (!eglContext)[/color]
138 {
140 OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
141 "currentGLContext was specified with no current GL context",
142 "EGLWindow::create");
143 }
144
[color=#FF0000]145[b]-[/b] eglContext = eglGetCurrentContext();[/color]
146 mEglSurface = eglGetCurrentSurface(EGL_DRAW);
...
220 if (!mEglConfig)
221 {
222 _createInternalResources(mWindow, config);
223 mHwGamma = false;
224 }
225
[color=#00BF00][b]+++[/b] mEglDisplay = mGLSupport->getGLDisplay();[/color]
226 mContext = createEGLContext();
227 mContext->setCurrent();
Here is some example code for Ogre Init on Android with SDL2:
Code: Select all
m_ogre_root = new Ogre::Root("", "", "");
m_static_plugin_loader = OGRE_NEW Ogre::StaticPluginLoader();
m_static_plugin_loader->load();
m_render_system = m_ogre_root->getAvailableRenderers().at(0);
if ( !m_render_system )
error_app("No Ogre RenderSystem available");
m_ogre_root->setRenderSystem(m_render_system);
m_ogre_root->initialise(false);
JNIEnv* env = (JNIEnv*)SDL_AndroidGetJNIEnv();
jclass class_activity = env->FindClass("android/app/Activity");
jclass class_resources = env->FindClass("android/content/res/Resources");
jmethodID method_get_resources = env->GetMethodID(class_activity, "getResources", "()Landroid/content/res/Resources;");
jmethodID method_get_assets = env->GetMethodID(class_resources, "getAssets", "()Landroid/content/res/AssetManager;");
jobject raw_activity = (jobject)SDL_AndroidGetActivity();
jobject raw_resources = env->CallObjectMethod(raw_activity, method_get_resources);
jobject raw_asset_manager = env->CallObjectMethod(raw_resources, method_get_assets);
AAssetManager* asset_manager = AAssetManager_fromJava(env, raw_asset_manager);
if (asset_manager)
{
Ogre::ArchiveManager::getSingleton().addArchiveFactory( new Ogre::APKFileSystemArchiveFactory(asset_manager) );
Ogre::ArchiveManager::getSingleton().addArchiveFactory( new Ogre::APKZipArchiveFactory(asset_manager) );
}
Ogre::ResourceGroupManager& resGroupMan = Ogre::ResourceGroupManager::getSingleton();
Ogre::String defResGroup = Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME;
resGroupMan.addResourceLocation("/", "APKFileSystem", defResGroup);
Code: Select all
JNIEnv* env = (JNIEnv*)SDL_AndroidGetJNIEnv();
m_sdl_gl_context = SDL_GL_GetCurrentContext();
jclass class_sdl_activity = env->FindClass("org/libsdl/app/SDLActivity");
jmethodID method_get_native_surface = env->GetStaticMethodID(class_sdl_activity, "getNativeSurface", "()Landroid/view/Surface;");
jobject raw_surface = env->CallStaticObjectMethod(class_sdl_activity, method_get_native_surface);
ANativeWindow* native_window = ANativeWindow_fromSurface(env, raw_surface);
if ( !native_window )
return;
Ogre::NameValuePairList opt;
opt["currentGLContext"] = "true";
opt["externalWindowHandle"] = Ogre::StringConverter::toString( (int)native_window );
opt["externalGLContext"] = Ogre::StringConverter::toString( (int)m_sdl_gl_context );
m_ogre_window = Ogre::Root::getSingleton().createRenderWindow("OgreWindow", 0, 0, false, &opt);
Until I've minimized and restored the app - after restoring there was some color flickering or ghost pixels, i don't know.
Finally I've managed to close and reopen ogre window on app mimize/restore and saw background color changes but not my simple scene

May be I should try to unload/reload all graphic resources like meshes, textures and shaders...
I didn`t try any hardcore stuff yet because I want to hear some comments from ogre gurus.

-
- Greenskin
- Posts: 126
- Joined: Wed Jan 19, 2005 4:48 am
- x 9
Re: Android and sdl
JeriX,
Thanks for the tips. I managed to get it working where SDL creates the window and Ogre creates the GL context like on the other platforms. I didn't have to modify Ogre at all. I will try to post the code this weekend once I clean it up and fix a few bugs.
Presently it crashes when I switch to another app. I need to figure out how to tie the Ogre and SDL on pause/resume code together.
Thanks for the tips. I managed to get it working where SDL creates the window and Ogre creates the GL context like on the other platforms. I didn't have to modify Ogre at all. I will try to post the code this weekend once I clean it up and fix a few bugs.
Presently it crashes when I switch to another app. I need to figure out how to tie the Ogre and SDL on pause/resume code together.
-
- Gnoblar
- Posts: 3
- Joined: Tue Dec 01, 2009 7:13 pm
Re: Android and sdl
I look forward to look at your code connect this libs together, please, share the details as soon as you can 

-
- Greenskin
- Posts: 126
- Joined: Wed Jan 19, 2005 4:48 am
- x 9
Re: Android and sdl
Sorry for not responding sooner on this subject. Real life got in the way. Anyway, I recently began trying to use SDL's touch input support and found that I can't receive any events other than from the on screen keyboard. Have you seen this issue at all? I have tried everything I can think of and it appears that while OGRE is rendering fine, SDL is unable to grab input from the window.
-
- Beholder
- Posts: 1512
- Joined: Fri Feb 22, 2013 4:44 am
- Location: Deep behind enemy lines
- x 139
Re: Android and sdl
I just hit this issue myself. The problem here, from what I understand, is that SDL is forcing SDL_WINDOW_OPENGL on Android, meaning that it is going to create an egl surface for you whether you want one or not ... and you do not. In SDL_androidwindow.c you can see this behaviour in Android_CreateWindow where it calls SDL_EGL_CreateSurface (and of course it also destroys the surface in Android_DestroyWindow)
The easiest way forward seems to be just patching SDL not to create that surface for you. Let Ogre do that. Then you don't have to use the currentGLContext or externalGLContext rendersystem options, just pass in the externalWindowHandle. I have been able to pause and resume the app in android's lifecycle, but I haven't yet tested any scenes ... and some issues do remain. Multiple pause/unpauses seems to wreck me. But I do receive all my touch events correctly.
Anyway, just thought I would mention since this seems to be the only thread dealing with the issue of android + SDL + ogre
EDIT: turns out the issue with multiple pauses and resumes is actually in the SDL semaphore and unrelated to Ogre ... so I believe I do have a working integration as far as handling the window/surface/context stuff
The easiest way forward seems to be just patching SDL not to create that surface for you. Let Ogre do that. Then you don't have to use the currentGLContext or externalGLContext rendersystem options, just pass in the externalWindowHandle. I have been able to pause and resume the app in android's lifecycle, but I haven't yet tested any scenes ... and some issues do remain. Multiple pause/unpauses seems to wreck me. But I do receive all my touch events correctly.
Anyway, just thought I would mention since this seems to be the only thread dealing with the issue of android + SDL + ogre
EDIT: turns out the issue with multiple pauses and resumes is actually in the SDL semaphore and unrelated to Ogre ... so I believe I do have a working integration as far as handling the window/surface/context stuff