Showing results for 
Search instead for 
Did you mean: 

How to correctly use SRGB on Oculus Mobile Native (C++)?

Level 4
This is a Go+Quest question. I have a Oculus Mobile C++ app forked from the VRCubeWorld_NativeActivity example in the Oculus Mobile native SDK. I hooked in my own code in `ovrRenderer_RenderFrame`, so right after the framebuffer and the eye matrices are set up I call my own rendering code. This rendering code is shared with desktop, it enables `GL_FRAMEBUFFER_SRGB` and it exclusively draws the SRGB color space.

I am trying to figure out how to convert VRCubeWorld_NativeActivity from RGB to SRGB. I want the SRGB drawn by my rendering code to be correctly treated by the NativeActivity.cpp's framebuffer and EGL surface. I have found a way that "works" (I see the colors I expect) but I do not know if it is correct. You can see my exact NativeActivity code here (it is open source).

What I did:
  • Pass `GL_SRGB8_ALPHA8` instead of `GL_RGBA8` in ovrFramebuffer_Create
  • Set `VRAPI_MODE_FLAG_FRONT_BUFFER_SRGB` in `parms.flags` when we call `vrapi_EnterVrMode`()
What I did NOT do— because I tried these things and they had no effect:
  • Call `setEGLattrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);` after calling `eglCreateContext()` (I think we do this in our glfw version, and it is recommended in a long comment in VrApi_Types.h).
  • Comment out the many `VRAPI_FRAME_LAYER_FLAG_INHIBIT_SRGB_FRAMEBUFFER` lines left over from the sample code.
What I need to know: 
  • Am I doing something wrong or unsafe, or incurring any penalty (like unnecessary conversions RGB->SRGB and back again) by failing to explicitly set the EGL_GL_COLORSPACE_SRGB_KHR egl attrib?
  • What do the various VRAPI_FRAME_LAYER_FLAG_INHIBIT_SRGB_FRAMEBUFFER flags do? What does this "layer" code (the "black layer" and "loading icon layer") do, and can I safely remove it? (I have removed a lot of the code from the NativeActivity example because I was sure I did not need it, but there are other parts I did not understand so I have left it in. Because there is not really any comments/documentation on the sample code it is hard to tell what is necessary and what Oculus merely left for us as a convenience.)

Level 2

Did you ever figure out the correct way to do this. My render output seems MUCH darker in the oculus version compared to the desktop version of the same render engine.

Hi anders.rein. The instructions I list above actually did wind up giving me the colors I wanted.

You can actually inspect my code if you want because I contributed it to the open source project LOVR.

The final version based on the "CubeWorld" example is here, this version is a year old.

This was later simplified by the LOVR core dev into this, the current (0.14 and 0.15/master) version.

Looking at the code, it appears we are still using the method in my post above (`GL_SRGB8_ALPHA8` calling `vrapi_CreateTextureSwapChain3`, plus `VRAPI_MODE_FLAG_FRONT_BUFFER_SRGB` calling `vrapi_EnterVrMode`). We also have a `glEnable(GL_FRAMEBUFFER_SRGB);` in our (non-platform-specific) opengl code.


If you are doing these things and the colors still look dark, the problem may be color space rather than srgb. The Quest supports multiple color spaces and Oculus documents an API for choosing color spaces here. The color space differences are not nearly so intense as the difference between interpreting data as SRGB and non-SRGB, but they are still pretty intense. By default they will use REC.2020 which is the "widest" color space— which is good if you're developing your assets for it, but if you developed your assets on a PC monitor they will look unnaturally deep when interpreted as REC.2020. Notice the VRAPI_COLORSPACE_RIFT_CV1 option in the doc, which I think should match the colors with Oculus Rift on desktop.


(Postscript: There is also a feature to set your color space in the AndroidManifest.xml file, however, this is not in the current documentation. Oculus posted a document about this at one point and then took it down. I am still using it in my in-development game however and it still works, for now. The way to do that was to put `<meta-data android:name="com.oculus.application.colorspace" android:value="Rec.709"/>` (or something) inside the `<application>` tag. The accepted values for "value" I know of are "Rec.709", "Rec.2020", "DCI-P3" or "Adobe". I use Rec.709 because my game started development on the Oculus Go and that value gave me the closest colors to what I saw on the Go. Using the `vrapi_SetClientColorDesc` function is probably better because it is officially documented and appears to support more color spaces.)