[IOS] Ogre 1.9.0 + SDL2 issues

Problems building or running the engine, queries about how to use features etc.
Post Reply
sabotage3d
Gnoblar
Posts: 15
Joined: Sun Jul 20, 2014 10:01 pm

[IOS] Ogre 1.9.0 + SDL2 issues

Post by sabotage3d »

Hi guys,

I am fairly new to Ogre3d. So far I have SDL2 and Ogre 1.9.0 compiled for IOS 7.1 and according to the tutorials in the wiki I have passed externalWindowHandle from SDL to Ogre. But I cannot get any input or window events from SDL
When I start them together, the only event that I can get is SDL_APP_DIDENTERFOREGROUND.
Another problem is that my FPS goes from 8 to 2 which is drastic decrease in performance.
I would really appreciate any help as I am stuck on the problems above.

These are my additions to the original IOS Template project:

SDL and Ogre initialization

Code: Select all

//SDL
    if (SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        printf("Could not initialize SDL\n");
        return 1;
    }
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_EGL, 1);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
    
    SDL_DisplayMode displayMode;
    SDL_GetDesktopDisplayMode(0, &displayMode);
    
    /* create window and renderer */
    SDL_Window* window = SDL_CreateWindow(NULL, 0, 0, displayMode.w, displayMode.h, SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN | SDL_WINDOW_RESIZABLE);
    
    SDL_GLContext glContext = SDL_GL_CreateContext(window);
    
    SDL_SysWMinfo wmInfo;
    SDL_VERSION(&wmInfo.version);
    SDL_GetWindowWMInfo(window,&wmInfo);

    m_pLog = Ogre::LogManager::getSingleton().createLog("OgreLogfile.log", true, true, false);
    m_pLog->setDebugOutputEnabled(true);

    String pluginsPath;
    m_pRoot = new Ogre::Root(pluginsPath, Ogre::macBundlePath() + "/ogre.cfg");
    m_StaticPluginLoader.load();
    
    m_pRenderWnd = m_pRoot->initialise(false, wndTitle);
    
    size_t winHandle = reinterpret_cast<size_t>(wmInfo.info.uikit.window);
    size_t glHandle = reinterpret_cast<size_t>(glContext);
    
    Ogre::NameValuePairList params;
    params["externalWindowHandle"] = Ogre::StringConverter::toString((unsigned long)winHandle);
    params["externalGLContext"] =   Ogre::StringConverter::toString((unsigned long)glHandle);
    params["externalGLControl"] = String("True");

    m_pRenderWnd = m_pRoot->createRenderWindow("", displayMode.w/2, displayMode.h/2, false,  &params);

This is the main loop:

Code: Select all

    DemoApp demo;
    demo.startDemo();

    bool done = false;
    
    SDL_Event event;
    
    double mStartTime;
    double mLastFrameTime;

    while (!done)
    {
        
		mStartTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU();
		OgreFramework::getSingletonPtr()->updateOgre(mLastFrameTime);
		OgreFramework::getSingletonPtr()->m_pRoot->renderOneFrame();
		mLastFrameTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU() - mStartTime;
        
        
        while (SDL_PollEvent(&event))
        {
            switch (event.type)
            {
                case SDL_FINGERMOTION:
                    SDL_Log("Finger Motion");
                    break;

                case SDL_FINGERDOWN:
                    SDL_Log("Finger Down");
                    break;
           
                case SDL_FINGERUP:
                    SDL_Log("Finger Up");
                    break;

                case SDL_QUIT:
                    done = true;
                    break;
                    
                case SDL_APP_DIDENTERFOREGROUND:
                    SDL_Log("SDL_APP_DIDENTERFOREGROUND");
                    break;
                    
                case SDL_APP_DIDENTERBACKGROUND:
                    SDL_Log("SDL_APP_DIDENTERBACKGROUND");
                    break;
                    
                case SDL_APP_LOWMEMORY:
                    SDL_Log("SDL_APP_LOWMEMORY");
                    break;
                    
                case SDL_APP_TERMINATING:
                    SDL_Log("SDL_APP_TERMINATING");
                    break;
                    
                case SDL_APP_WILLENTERBACKGROUND:
                    SDL_Log("SDL_APP_WILLENTERBACKGROUND");
                    break;
                    
                case SDL_APP_WILLENTERFOREGROUND:
                    SDL_Log("SDL_APP_WILLENTERFOREGROUND");
                    break;
                    
                case SDL_WINDOWEVENT:
                {
                    switch (event.window.event)
                    {
                    
                        case SDL_WINDOWEVENT_RESIZED:
                        {
                            SDL_Log("Window %d resized to %dx%d", event.window.windowID, event.window.data1, event.window.data2);
                            
                            break;
                        }
                    }
                }
            }
        }

User avatar
c6burns
Beholder
Posts: 1512
Joined: Fri Feb 22, 2013 4:44 am
Location: Deep behind enemy lines
x 138

Re: [IOS] Ogre 1.9.0 + SDL2 issues

Post by c6burns »

Hey I kept coming across questions like this while implementing SDL + iOS + Ogre for myself. I'm reposting my Stack Exchange answer here in the hopes it helps someone like me, who found only dead ends through googling :) I can't speak to your performance issues ... I haven't got that far yet in my implementation

The problem is that you are replacing SDL's UIView (SDL_uikitview) with Ogre's UIView (OgreEAGL2View) and so you are no longer going to receive any touch input or any of the features implemented via SDL_uikitviewcontroller or SDL_uikitview. This replacement is taking place inside the GLES2 RenderSystem (specifically in OgreEAGL2Window.mm)

The way I solved this for myself is to create my own UIViewController and UIView, and then put that view behind SDL's view. You can then receive touch input from SDL's view, while rendering into Ogre's view. This will require creating an Objective-C compilation unit and the code would look something like:

Code: Select all

#include "OgreEAGL2View.h"
#import <UIKit/UIWindow.h>
#import <UIKit/UIDevice.h>
// other includes

// call this from your C++ framework
// pass it your startup params
void setupMyiOSViews(Ogre::NameValuePairList &params)
{
    // grab the UIWindow (you must have called SDL_createwindow before calling this)
    SDL_SysWMinfo wmInfo;
    SDL_Window *sdlWindow;
    SDL_VERSION(&wmInfo.version);
    SDL_GetWindowWMInfo(sdlWindow, &wmInfo);
    UIWindow *w = wmInfo.info.uikit.window;

    // get a rectangle with the screen dimensions
    CGRect rect = [[UIScreen mainScreen] applicationFrame];
    // instantiate a view controller of Ogre's subclass of UIViewController
    EAGL2ViewController *myViewController = [[EAGL2ViewController alloc] init];
    // instantiate a view of Ogre's subclass of UIView
    EAGL2View *myView = [[EAGL2View alloc] initWithFrame:rect];
    // make sure it's not transparent
    myView.opaque = YES;
    // attach the view to the viewcontroller
    myViewController.view = myView;
    // add the view to the current window
    [w addSubview:myView];
    // put the view *behind* the SDL view
    [w sendSubviewToBack:myView];

    // add the window, viewcontroller, and view to the proper parameters
    // UIWindow maps to param: externalWindowHandle
    // UIViewController maps to param: externalViewControllerHandle
    // UIView maps to param: externalViewHandle
    Ogre::String str_w = Ogre::StringConverter::toString((unsigned long)w);
    Ogre::String str_vc = Ogre::StringConverter::toString((unsigned long)myViewController);
    Ogre::String str_v = Ogre::StringConverter::toString((unsigned long)myView);

    params["externalWindowHandle"] = str_w;
    params["externalViewControllerHandle"] = str_vc;
    params["externalViewHandle"] = str_v;

    Ogre::LogManager::getSingleton().logMessage("externalWindowHandle: " + str_w);
    Ogre::LogManager::getSingleton().logMessage("externalViewControllerHandle: " + str_vc);
    Ogre::LogManager::getSingleton().logMessage("externalViewHandle: " + str_v);

// now pass params into Ogre::Root::createRenderWindow
}
Note that there is no need to even create an context with SDL. Ogre will now be rendering into it's own view and viewcontroller
Post Reply