Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Pure gold. Thanks for the technical deep dive. Sadly I definitely don't have the expertise to roll out my own solution as you have done. Is it something you would consider putting up on github?

There's really not too much more than is in the extension's sample (https://www.khronos.org/registry/OpenGL/extensions/QCOM/QCOM_texture_foveated.tx...) One odd thing I do is that I send the setup for a few frames, as I noticed that Oculus changes it. I could be wrong and it might be unnecessary but as it works, I keep it.

I would need to either modify an existing sample. Although I would still need to put it into Visual Studio project) or create a new one as how it is done in my engine, requires lots of other steps (like loading config files, checking for various things, there are implementations of multiple VR systems.

The easiest way to test it by yourself is to get OpenXR from Oculus https://developer.oculus.com/documentation/native/android/mobile-openxr/ get XrCompositor_NativeActivity sample, go to ovrRenderer_RenderFrame and setup foveated rendering before ovrFramebuffer_SetCurrent(frameBuffer); using (1) and (3) samples from extension's specs, just replace foveatedTexture with frameBuffer->ColorSwapChainImage[frameBuffer->TextureSwapChainIndex].image, it should look something like that:

...
ovrFramebuffer_Acquire(frameBuffer);
GLuint foveatedTexture = frameBuffer->ColorSwapChainImage[frameBuffer->TextureSwapChainIndex].image;
glBindTexture(GL_TEXTURE_2D, foveatedTexture);
// Set texture as foveated
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM,
  GL_FOVEATION_ENABLE_BIT_QCOM | GL_FOVEATION_SCALED_BIN_METHOD_BIT_QCOM);
glBindTexture(GL_TEXTURE_2D, 0);
// Set foveation parameters on texture
float focalX = 0.0f;
float focalY = 0.0f;
float gainX  = 8.0f;
float gainY  = 8.0f;
float foveArea = 20.0f;
glTextureFoveationParametersQCOM(foveatedTexture, 0, 0, focalX, focalY, gainX, gainY, foveArea);

You may need to add this as well somewhere before

#define GL_FOVEATION_ENABLE_BIT_QCOM 0x01
#define GL_FOVEATION_SCALED_BIN_METHOD_BIT_QCOM 0x02
#define GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM 0x8BFB
#define GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM 0x8BFD
#define GL_FRAMEBUFFER_INCOMPLETE_FOVEATION_QCOM 0x8BFF
#define GL_TEXTURE_FOVEATED_MIN_PIXEL_DENSITY_QCOM 0x8BFC
#define GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM 0x8BFE
typedef void (GL_APIENTRY* PFNGLTEXTUREFOVEATIONPARAMETERSQCOMPROC) (GLint texture, GLint layer, GLint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea);
// this in some init function
PFNGLTEXTUREFOVEATIONPARAMETERSQCOMPROC glTextureFoveationParametersQCOM = (VideoGLExtensions::PFNGLTEXTUREFOVEATIONPARAMETERSQCOMPROC)glGetProcAddress("glTextureFoveationParametersQCOM");

This will only work if opengl/es supports this extension (Quest, some Android devices).

(+1)

Thank you! Way out of my depth here, but that may be a good way to learn to swim...