Diligent Graphics > Diligent Engine > Native API Interoperability > OpenGL/GLES Interoperability
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.
The current proposal by three southern California congressmen to impose a late night curfew 100mg viagra professional on air traffic at BUR and VNY initiates that both airports be sanctioned to circumvent the ANCA. Adding massage as a part of foreplay may help to increase feelings of desire, as well as man buy cialis without prescription threatened. Arsha: Tribulus helps to reduce symptoms of piles cheap viagra usa Hridroga : Gokshura is very useful in anemia. It offers effective cure for weakness, PE and impotence. india cialis online
Examples:
1 2 3 4 5 6 7 |
// Get GL buffer handle from IBuffer interface RefCntAutoPtr<IBufferGL> pBufferGL(pBuffer, IID_BufferGL); auto GLBufferHandle = pBufferGL->GetGLBufferHandle(); // Get GL texture handle from ITexture interface RefCntAutoPtr<ITextureGL> pTextureGL(pTexture, IID_TextureGL); auto GLHandle = pTextureGL->GetGLTextureHandle(); |
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:
1 2 3 |
void IEngineFactoryOpenGL::AttachToActiveGLContext(const EngineCreationAttribs& CreationAttribs, IRenderDevice **ppDevice, IDeviceContext **ppImmediateContext ); |
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:
1 2 3 |
auto *pFactoryGL = GetEngineFactoryOpenGL(); EngineCreationAttribs Attribs; pFactoryGL->AttachToActiveGLContext(Attribs, &m_Device, &m_Context); |
If application is using multiple GL contexts, it is important to notify diligent engine to update currently active context:
1 |
m_DeviceCtxGL->UpdateCurrentGLContext() |
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:
1 2 3 4 5 |
void EndRendering() { if (m_Context) m_Context->InvalidateState(); } |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
class ProxySwapChainGL : public SwapChainBase<ISwapChain> { public: using TBase = SwapChainBase<ISwapChain>; ProxySwapChainGL( IReferenceCounters *pRefCounters, IRenderDevice *pDevice, IDeviceContext *pDeviceContext, const SwapChainDesc& SCDesc ) : TBase(pRefCounters, pDevice, pDeviceContext,SCDesc) {} virtual void Present(Uint32 SyncInterval)override final { UNEXPECTED("Present is not expected to be called directly"); } virtual void SetFullscreenMode(const DisplayModeAttribs &DisplayMode)override final { UNEXPECTED("Fullscreen mode cannot be set through the proxy swap chain"); } virtual void SetWindowedMode()override final { UNEXPECTED("Windowed mode cannot be set through the proxy swap chain"); } virtual void Resize(Uint32 NewWidth, Uint32 NewHeight)override final { TBase::Resize(NewWidth, NewHeight, 0); } }; |
An instance of ProxySwapChainGL should then be set in the device context after it has been initialized:
1 2 3 4 5 6 7 |
auto &DefaultAllocator = DefaultRawMemoryAllocator::GetAllocator(); auto pProxySwapChainGL = NEW_RC_OBJ(DefaultAllocator, "ProxySwapChainGL instance", ProxySwapChainGL) (m_pDevice, m_pDeviceCtx, SCDesc); pProxySwapChainGL->QueryInterface(IID_SwapChain, reinterpret_cast<IObject**>(static_cast<ISwapChain**>(&m_pProxySwapChain))); m_Context->SetSwapChain(m_pProxySwapChain); |