cancel
Showing results for 
Search instead for 
Did you mean: 

Getting started with VrAppFramework-- raw opengl, when to do "work"?

mcc
Expert Protege
I have an existing OpenGL ES program I am porting to Oculus Mobile SDK (1.16.0). I can see there are two options, VrApp and VrAppFramework. I can see that VrApp is minimal and VrAppFramework provides nice things such as input, lifecycle management, and drawing routines, so I am currently using the VrCubeWorld_Framework program as a base. However, I do not need drawing routines. I have OpenGL ES calls already.

In the VrApi doc https://developer.oculus.com/documentation/mobilesdk/latest/concepts/mobile-vrapi/#mobile-vrapi it says that a VrApi app should just create its own EGLContext, which sounds like what I want. VrCubeWorld_Framework on the other hand has a Frame() callback where it fills out a series of ovrSurfaceDef objects, which seem to abstract single draw calls, and filling out an array in an ovrFrameResult object.

There are many classes in VrAppFramework and very few of them are documented. I do not find explanations of ovrSurfaceDef or ovrFrameResult by searching on the Oculus website. I find inside VrAppFramework, the critical drawing function seems to be AppLocal::DrawEyeViews, which draws the ovrSurfaceDefs using ovrSurfaceRender::RenderSurfaceList.

Here are some questions:

1. Is there documentation of ovrFrameResult/ovrSurfaceDef hiding somewhere I have just missed?

2. It seems to me that "what I want"-- if my goal is to get the advantages of VrAppFramework, but do my own OpenGL rendering-- is to either somehow replace AppLocal::DrawEyeViews and call my own rendering at that moment, or to somehow create a ovrSurfaceDef which gets a C callback called by RenderSurfaceList instead of RenderSurfaceList doing all the work itself. At the moment this appears to be impossible without modifying VrAppFramework. Is there a trap door for custom GL code I am missing?

(Yes, I realize I can render to a texture and then submit a draw of this texture as an ovrSurfaceDef, but this seems like simultaneously less efficient and more coding work.)

3. In the VrApiFramework documentation there is a document https://developer.oculus.com/documentation/mobilesdk/latest/concepts/mobile-runtime-threads/ describing the threading strategy of VrApiFramework and recommending creating a worker thread instead of doing hard work on the VR thread. Assuming a game has a core loop of an Update() which updates world state, and a Draw() which renders, what would be the recommended trigger for running Update() on the worker thread? Frame() is probably too late since the frame is due by then-- is there a time which VrApiFramework is capable of being notified at that would be more appropriate? For example, can one of my threads get woken up when the frame has completed being drawn by the hardware?
2 REPLIES 2

NelnoTheAmoeba
Explorer
Hi, mcc,

The feedback above is correct. VrAppFramework is deprecated internally at Oculus and only exists as a basis for samples until those samples can be rewritten. VrAppFramework was also used as a basis for some of the very first Gear VR applications, but those applications have since been rewritten entirely, leaving VrAppFramework as a somewhat overcomplicated base for samples.
I'll try to answer your questions.
1. No, there's no specific documentation for these other than what may be in the source itself. Basically ovrFrameResult is intended to be all of the output of your application that the framework needs to know about. For the most part this is the layers and surfaces to render. VrController has a simple Frame() method implementation that sets up a basic ovrFrameResult structure.
2. While VrAppFramework does provide some conveniences, probably the largest of them is rendering. Since you want to do your own rendering, you may be better served by starting with VrCubeWorld_NativeActivity as a base for lifecycle managment and bolting your own rendering into that framework. VrCubeWorld_NativeActivity exists entirely in a single .c file, but it can be built as C++ with minor changes. 
If you then want input management, I recommend looking at the VrController sample. VrAppFramework's input handling predates Gear VR and Go controllers and was really only written to handle input that comes through the normal Android input path (i.e. no VR-specific controllers). VrController uses the new vrapi_EnumerateInputDevice, vrapi_GetInputDeviceCapabilities and vrapi_GetCurrentInputState to handle controller, headset and gamepad input devices. You should be able to pull the ovrInputDevice_* classes out of that and have input up and running quickly in your application.
After that, you could cherry-pick support classes from VrAppFramework if they makes sense for your project.
3. You may want to check the documentation in VrApi.h under "Frame Timing". vrapi_SubmitFrame() only returns when the previous eye images have been consumed by the asynchronous time warp thread, and at least the specified minimum number of V-syncs have passed since the last call to vrapi_SubmitFrame(). In the case of VrAppFramework, the VRThread calls Frame() and then vrapi_SubmitFrame(). In a framework app, synchronization with other application threads would normally be done inside of the overloaded Frame() function and how you synchronize with your other threads is up to you. A common scenario might be to have a job manager that can spawn some number of threads that do bits of work (i.e. asynchronous image loading). At the beginning of the Frame() function, service any jobs that have completed and use their results in the current frame. Submit new jobs at some other point during Frame(). For some types of work you may need to block in your Frame() function until the other thread has completed.

mcc
Expert Protege
Hi @NelnoTheAmoeba @imperativity, thank you for the explanation. Re:

"If you then want input management, I recommend looking at the VrController sample. "

I notice around the time these posts were made, a new Oculus Mobile SDK 
1.18.0 was released which removed the VrAppFramework samples. I assume this is because VrAppFramewor...ovrVrController::Frame, for example, makes use of App::GetOvrMobile() from VrAppFramework to obtain the ovrMobile object, which means that this code cannot be immediately cut-pasted into (for example) the NativeActivity example.

I was able to figure out what I needed to do by examining the VrController code in conjunction with the VrAppFramework code, and I do not need further help on this at this time. But as a piece of feedback for the benefit of future users, if you are recommending the vrapi controller functions as an alternative to VrAppFramework, maybe it would be better if the vrapi example did not necessarily depend on VrAppFramework. It also might help if the written docs were more detailed about the structures passed to and returned from these functions. Thanks!