Mix Ogre3D with Google VR SDK

Discussion of issues specific to mobile platforms such as iOS, Android, Symbian and Meego.
Post Reply
Icedev
Gnoblar
Posts: 8
Joined: Thu Sep 22, 2011 10:31 am

Mix Ogre3D with Google VR SDK

Post 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.
Icedev
Gnoblar
Posts: 8
Joined: Thu Sep 22, 2011 10:31 am

Re: Mix Ogre3D with Google VR SDK

Post 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
Post Reply