Android and sdl

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
libolt
Greenskin
Posts: 126
Joined: Wed Jan 19, 2005 4:48 am
x 9

Android and sdl

Post by libolt »

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
User avatar
JeriX
Gnoblar
Posts: 3
Joined: Tue Dec 01, 2009 7:13 pm

Re: Android and sdl

Post by JeriX »

I've managed to integrate ogre with libsdl2 on android, but some difficulties occured...
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();

Than I've rebuilded Ogre.

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);
And some example code for creation Ogre window on Android with SDL2:

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);
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. :)
libolt
Greenskin
Posts: 126
Joined: Wed Jan 19, 2005 4:48 am
x 9

Re: Android and sdl

Post by libolt »

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.
User avatar
JeriX
Gnoblar
Posts: 3
Joined: Tue Dec 01, 2009 7:13 pm

Re: Android and sdl

Post by JeriX »

I look forward to look at your code connect this libs together, please, share the details as soon as you can :)
libolt
Greenskin
Posts: 126
Joined: Wed Jan 19, 2005 4:48 am
x 9

Re: Android and sdl

Post by libolt »

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.
User avatar
c6burns
Beholder
Posts: 1512
Joined: Fri Feb 22, 2013 4:44 am
Location: Deep behind enemy lines
x 139

Re: Android and sdl

Post by c6burns »

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