OpenGL/GLES Interoperability

This page describes interfaces and methods that provide interoperability with OpenGL/GLES.

Accessing Native OpenGL/GLES object handles

  • GLuint IBufferGL::GetGLBufferHandle() – returns GL buffer handle
  • GLuint ITextureGL::GetGLTextureHandle() – returns GL texture handle
  • GLenum ITextureGL::GetBindTarget() – returns GL texture bind target
  • bool IDeviceContextGL::UpdateCurrentGLContext() – attaches to the active GL context in the thread. Returns false if there is no active context, and true otherwise. If an application uses multiple GL contexts, this method must be called before any other command to let the engine update active context every time when control flow is passed over from the main application.

Examples:

Creating Diligent Engine Objects from GL Resource Handles

  • void IRenderDeviceGL::CreateTextureFromGLHandle(Uint32 GLHandle, const TextureDesc &TexDesc, ITexture **ppTexture)  – creates a diligent engine texture from OpenGL handle. The method takes OpenGL handle GLHandle, texture description TexDesc, and writes the pointer to the created texture object at the memory address pointed to by ppTexture. The engine can automatically set texture width, height, depth, mip levels count, and format, but the remaining field of TexDesc structure must be populated by the application.
  • void IRenderDeviceGL::CreateBufferFromGLHandle(Uint32 GLHandle, const BufferDesc &BuffDesc, IBuffer **ppBuffer) – creates a diligent engine buffer from OpenGL handle. The method takes OpenGL handle  GLHandle, buffer description  BuffDesc, and writes the pointer to the created buffer object at the memory address pointed to by  ppBuffer. The engine can automatically set the buffer size, but the rest of the fields need to be set by the client.

Note that diligent engine buffer and texture object created this way do not take ownership of the GL resources, so the application must not destroy the resources while they are in use by the engine.

Initializing the Engine by Attaching to Existing OpenGL/GLES Context

Too attach diligent engine to currently active OpenGL/GLES context, use the following factory function:

The method takes initialization parameters in CreationAttribs and writes a pointer to the device object at a memory location pointer to by ppDevice, and a pointer to the immediate context at a memory location pointed to by ppImmediateContext.

Example:

If application is using multiple GL contexts, it is important to notify diligent engine to update currently active context:

Diligent Engine keeps track of all states bound to the GL context (buffers, textures, program pipelines, VBOs, etc.). Since main application also uses the same context, the state cache needs to be invalidated every time the control flow returns to the main application:

Initializing proxy swap chain

After initialization through  AttachToActiveGLContext(), diligent engine has no notion of the swap chain. There are several special commands that can be executed from the diligent engine context that require swap to be initialized:

  • SetRenderTargets(0, nullptr, nullptr) – bind the default back buffer & depth buffer
  • SetViewports(1, nullptr, 0, 0) – set the viewport to match the size of the back buffer
  • ClearRenderTarget(nullptr, color) – clear the default back buffer
  • ClearDepthStencil(nullptr, ...)  – clear the default depth-stencil buffer

If the application is using any of these commands, it needs to implement  ISwapChain interface and set it in the context. In case of OpenGL, there is not much that needs to be done and potential implementation may look like this:

An instance of  ProxySwapChainGL should then be set in the device context after it has been initialized: