Page 1 of 1

Ogre 1.10.12 inside Qt5

Posted: Tue May 29, 2018 1:46 pm
by Ezerg
Hey everyone,
I'm trying to embed Ogre 1.10.12 inside a QWindow, my goal is to make it run on ARM board (rockchip 3288 SoC), openglES3, running Ubuntu but without X server, this is, using EGLFS as a backend (the same backend that uses Qt).

I know that this is possible using Ogre1.9 (I've seen it working).

Code that I'm using as a guide:
https://github.com/golgobot/qmlogre - Minimal example for embedding an Ogre window inside a QML object. Most importatn
https://bitbucket.org/bigianb/ogre/commits/all - This is an Ogre 1.9 fork that gets rid of X server and adds new classes (all derived from: eglSupport, eglContext, eglWindow respectively) that allows using Qt as glcontext "manager". I've applied almost the same changes on branch 1.10.12.

So far I was able to:
- Run Sample Browser on my ARM board using EGLFS.
- Run QmlOgre app on PC (Ogre 1.10.12 vainilla, no EGLFS add-ons).

But I still cannot get QmlOgre app properly run on ARM:
App loads fine, Ogre log doesn't show any error regarding glcontext or such. But a visual glitch is very noticeable: its like if Ogre and Qt were "fightning" for the current glsurface and you can see Ogre's window flickering on top of Qt's background. Maybe this is because something obvious that I'm missing (I have zero experience with egl, opengl).

Ogre's render window gets created inside my EGLFSWindow with this code:

Code: Select all

void EGLFSWindow::create(const String& name, uint width, uint height,
        bool fullScreen, const NameValuePairList *miscParams)
        {
          std::cout << __FUNCTION__ << "Creating a new EGLFS window" << '\n';
          String title = name;
          uint samples = 0;
          int gamma;
          short frequency = 0;
          bool vsync = false;
          ::EGLContext eglContext = 0;
          int left = 0;
          int top  = 0;


          mIsFullScreen = fullScreen;

          if (miscParams)
          {
            NameValuePairList::const_iterator opt;
            NameValuePairList::const_iterator end = miscParams->end();

            if ((opt = miscParams->find("currentGLContext")) != end &&
            StringConverter::parseBool(opt->second))
            {
              eglContext = eglGetCurrentContext();
              EGL_CHECK_ERROR
              if (eglContext == (::EGLContext) 0)
              {
                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                  "currentGLContext was specified with no current GL context",
                  "EGLWindow::create");
              }
                std::cout << __FUNCTION__ << "Valid EGL context found!" << '\n';
                eglContext = eglGetCurrentContext();
                EGL_CHECK_ERROR
                mEglSurface = eglGetCurrentSurface(EGL_DRAW);
                EGL_CHECK_ERROR
                mIsExternalGLControl = true;
              }

              // Note: Some platforms support AA inside ordinary windows
              if ((opt = miscParams->find("FSAA")) != end)
              {
                samples = StringConverter::parseUnsignedInt(opt->second);
              }

              if ((opt = miscParams->find("displayFrequency")) != end)
              {
                frequency = (short)StringConverter::parseInt(opt->second);
              }

              if ((opt = miscParams->find("vsync")) != end)
              {
                vsync = StringConverter::parseBool(opt->second);
              }

              if ((opt = miscParams->find("gamma")) != end)
              {
                gamma = StringConverter::parseBool(opt->second);
              }

              if ((opt = miscParams->find("left")) != end)
              {
                left = StringConverter::parseInt(opt->second);
              }

              if ((opt = miscParams->find("top")) != end)
              {
                top = StringConverter::parseInt(opt->second);
              }

              if ((opt = miscParams->find("title")) != end)
              {
                title = opt->second;
              }

              if ((opt = miscParams->find("externalGLControl")) != end)
              {
                mIsExternalGLControl = StringConverter::parseBool(opt->second);
              }
            }

            initNativeCreatedWindow(miscParams);

            if (mEglSurface)
            {
              mEglConfig = mGLSupport->getGLConfigFromDrawable(mEglSurface, &width, &height);
            }

            if (!mEglConfig && eglContext)
            {
              mEglConfig = mGLSupport->getGLConfigFromContext(eglContext);

              if (!mEglConfig)
              {
                // This should never happen.
                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                  "Unexpected failure to determine a EGLFBConfig",
                  "EGLWindow::create");
                }
              }

              mIsExternal = (mEglSurface != 0);

              if (!mIsTopLevel)
              {
                mIsFullScreen = false;
                left = top = 0;
              }

              if (mIsFullScreen)
              {
                mGLSupport->switchMode (width, height, frequency);
              }

              if (!mIsExternal)
              {
                createNativeWindow(left, top, width, height, title);
              }

              if (!mIsExternalGLControl) {
                mContext = createEGLContext();

                ::EGLSurface oldDrawableDraw = eglGetCurrentSurface(EGL_DRAW);
                EGL_CHECK_ERROR
                ::EGLSurface oldDrawableRead = eglGetCurrentSurface(EGL_READ);
                EGL_CHECK_ERROR
                ::EGLContext oldContext  = eglGetCurrentContext();
                EGL_CHECK_ERROR

                int glConfigID;

                mGLSupport->getGLConfigAttrib(mEglConfig, EGL_CONFIG_ID, &glConfigID);
                LogManager::getSingleton().logMessage("EGLWindow::create used FBConfigID = " + StringConverter::toString(glConfigID));
              }

              mName = name;
              mWidth = width;
              mHeight = height;
              mLeft = left;
              mTop = top;
              mActive = true;
              mVisible = true;

              mClosed = false;
            }

          }

Any clue/hint that any of you guys can throw me will be much appreciated!!

Edit: Maybe the following picture can clarify my problem a little bit
Image

Main problem is that ogre render window is not binded to the corresponding Qwindow, and when dragging any element on screen, ogre's window flickers.

Re: Ogre 1.10.12 inside Qt5

Posted: Thu May 31, 2018 6:01 pm
by Ezerg
I've just noticed that when I create a manual texture with:

Code: Select all

    rtt_texture = Ogre::TextureManager::getSingleton().createManual("RttTex",
                                                                    Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
                                                                    Ogre::TEX_TYPE_2D,
                                                                    m_size.width(),
                                                                    m_size.height(),
                                                                    0,
                                                                    Ogre::PF_A1R5G5B5,
                                                                    Ogre::TU_RENDERTARGET);//, 0, false,
                                                                    //m_AAEnabled ? m_samples : 0);

    rtt_texture->createInternalResources();

    m_renderTexture = static_cast<Ogre::GLES2FBORenderTexture *>(rtt_texture->getBuffer()->getRenderTarget());
And then try to retrieve the FBO Id with:

Code: Select all

    if (!m_renderTexture)
        return 0;
    Ogre::GLES2FrameBufferObject *ogreFbo = 0;
    m_renderTexture->getCustomAttribute("FBO", &ogreFbo);
    Ogre::GLES2FBOManager *manager = ogreFbo->getManager();
    manager->bind(m_renderTexture);

    GLint id;
    glGetIntegerv(GL_FRAMEBUFFER_BINDING, &id);

    return id;
    
Id is equal to 0!
this means that my Ogre window, which is being rendered as a texture, is binded to the main frame buffer instead of having it's own FBO??