Page 1 of 1

Mix Ogre3D with Google VR SDK

Posted: Mon Aug 14, 2017 5:24 pm
by Icedev
Hi,

Does anyone try to mix Google VR SDK with Ogre3D?

From what I read, the Google VR SDK handle all the input settings and the lens distortion. The big problem is to render into a GLSurfaceView. Any hint how to do that will be really appreciated.

Re: Mix Ogre3D with Google VR SDK

Posted: Mon Sep 18, 2017 5:39 pm
by Icedev
After a lot of tests I am close to a solution.

Here are a few hints for people that will find that threa
1) there is a bug in Ogre3D 1.10.8 about retreiving the EGLConfig. The EGLConfig is directly casted to a configId. It should not. Here is a correction

Code: Select all

	/*!	\brief Convert an EGLConfig Id to an EGLConfig
		\param[in] glConfigId id to convert from eglQueryContext or eglQuerySurface
		\returns matching EGLConfig
	 */
	::EGLConfig EGLSupport::getGLConfigFromId(::EGLint glConfigId) const
	{
		::EGLConfig glConfig = 0;
		::EGLint num_config_dummy;

		// Convert config Id into EGLConfig
		EGLint attribute_list[] = {
			EGL_CONFIG_ID, 0,
			EGL_NONE
		};

		// Specify the config Id that should be returned by eglChooseConfig
		attribute_list[1] = glConfigId;

		eglChooseConfig(mGLDisplay, attribute_list, &glConfig, 1, &num_config_dummy);

		EGL_CHECK_ERROR
		return glConfig;
	}

    ::EGLConfig EGLSupport::getGLConfigFromContext(::EGLContext context)
    {
        ::EGLint glConfigId = 0;

        if (eglQueryContext(mGLDisplay, context, EGL_CONFIG_ID, (::EGLint *) &glConfigId) == EGL_FALSE)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                        "Fail to get config from context",
                        __FUNCTION__);
            return 0;
        }
        EGL_CHECK_ERROR
        return getGLConfigFromId(glConfigId);
    }

    ::EGLConfig EGLSupport::getGLConfigFromDrawable(::EGLSurface drawable,
                                                    unsigned int *w, unsigned int *h)
    {
        ::EGLConfig glConfig = 0;
        ::EGLint glConfigId;

        if (eglQuerySurface(mGLDisplay, drawable, EGL_CONFIG_ID, (EGLint *) &glConfigId) == EGL_FALSE)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                        "Fail to get config from drawable",
                        __FUNCTION__);
            return 0;
        }

		glConfig = getGLConfigFromId(glConfigId);

        EGL_CHECK_ERROR
        eglQuerySurface(mGLDisplay, drawable, EGL_WIDTH, (EGLint *) w);
        EGL_CHECK_ERROR
        eglQuerySurface(mGLDisplay, drawable, EGL_HEIGHT, (EGLint *) h);
        EGL_CHECK_ERROR
        return glConfig;
    }
2) You have to mix Ogre Bites android sample with treasure hunt NDK sample
3) The parameters to give to createRenderWindow() are :

Code: Select all

	Params["currentGLContext"] = Ogre::StringConverter::toString(reinterpret_cast<bool>(true));
	Params["externalWindowHandle"] = Ogre::StringConverter::toString(reinterpret_cast<size_t>(pNativeWnd));
	Params["androidConfig"] = Ogre::StringConverter::toString(reinterpret_cast<size_t>(pAConfig));
	// Optionally preserve the gl context, prevents reloading all resources, this is false by default
	Params["preserveContext"] = Ogre::StringConverter::toString(reinterpret_cast<bool>(true));
4) You have to create a specific render system that is really close to GLES2 but:
- You have to create a constructor in Ogre::EGLContext that looks like:

Code: Select all

	/*!	\brief Constructor used to handle a context created out of Ogre.
	 */
	EGLContext::EGLContext(EGLDisplay eglDisplay,
		const EGLSupport* glsupport,
		::EGLConfig glconfig,
		::EGLSurface drawable,
		::EGLContext context)
		: mGLSupport(glsupport),
		mContext(context)
	{
		assert(drawable);

		mDrawable = drawable;
		mConfig = glconfig;
		mEglDisplay = eglDisplay;

		if (!mContext)
		{
			OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
				"Unable to create a suitable EGLContext",
				"EGLContext::EGLContext");
		}
	}
- Modify the code of Ogre::AndroidEGLWindow::create to add a parameter of createEGLContext() call
- I have also created a Dummy render target that derives from Ogre::AndroidEGLWindow and set in the constructor

Code: Select all

mDepthBufferPoolId = DepthBuffer::POOL_NO_DEPTH;
- I have also patched "AndroidEGLSupport::newWindow" to return my dummy render target
5) Call Ogre render frame after the GVR frame bind

Code: Select all

	Frame.BindBuffer(0);

        ... // <= put ogre render here

	Frame.Unbind();
My version is not yet fully working has I have some problems with "FixedFunction" but that will be for another thread.

Hope this will help someone looking for google VR integration or at least sharing EGLContext with Ogre