// Link a shared DirectX texture to an OpenGL texture // and create a GLDX interop object handle // // IN pSharedTexture Pointer to shared the DirectX texture // IN dxShareHandle Handle of the DirectX texture to be shared // IN glTextureID ID of the OpenGL texture that is to be linked to the shared DirectX texture // Returns Handle to the GL/DirectX interop object (the shared texture) // HANDLE spoutGLDXinterop::LinkGLDXtextures ( void* pDXdevice, void* pSharedTexture, HANDLE dxShareHandle, GLuint glTexture) { HANDLE hInteropObject; // Prepare the DirectX device for interoperability with OpenGL // The return value is a handle to a GL/DirectX interop device. if(!m_hInteropDevice) m_hInteropDevice = wglDXOpenDeviceNV(pDXdevice); if (m_hInteropDevice == NULL) return false; // prepare shared resource // wglDXSetResourceShareHandle does not need to be called for DirectX // version 10 and 11 resources. Calling this function for DirectX 10 // and 11 resources is not an error but has no effect. if (!wglDXSetResourceShareHandleNV(pSharedTexture, dxShareHandle)) return NULL; // Prepare the DirectX texture for use by OpenGL // register for interop and associate the opengl texture with the dx texture hInteropObject = wglDXRegisterObjectNV( m_hInteropDevice, pSharedTexture, // DX texture glTexture, // OpenGL texture GL_TEXTURE_2D, // Must be TEXTURE_2D WGL_ACCESS_READ_WRITE_NV); // We will write and the receiver will read return hInteropObject; }
bool D3DPresentEngine::createSharedTexture(int w, int h, int textureID) { _w = w; _h = h; if (gl_handleD3D == NULL ) gl_handleD3D = wglDXOpenDeviceNV(m_pDevice); if (!gl_handleD3D) { printf("ofxWMFVideoplayer : openning the shared device failed\nCreate SharedTexture Failed"); return false; } gl_name=textureID; HANDLE sharedHandle = NULL; //We need to create a shared handle for the ressource, otherwise the extension fails on ATI/Intel cards HRESULT hr = m_pDevice->CreateTexture(w,h,1,D3DUSAGE_RENDERTARGET,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&d3d_shared_texture,&sharedHandle); if (FAILED(hr)) { printf("ofxWMFVideoplayer : Error creating D3DTexture\n"); return false; } if (!sharedHandle) { printf("ofxWMFVideoplayer : Error creating D3D sahred handle\n"); return false; } wglDXSetResourceShareHandleNV(d3d_shared_texture,sharedHandle); d3d_shared_texture->GetSurfaceLevel(0,&d3d_shared_surface); gl_handle = wglDXRegisterObjectNV(gl_handleD3D, d3d_shared_texture, gl_name, GL_TEXTURE_RECTANGLE, WGL_ACCESS_READ_ONLY_NV); if (!gl_handle) { printf("ofxWMFVideoplayer : openning the shared texture failed\nCreate SharedTexture Failed"); return false; } return true; }
// LJ DEBUG - TODO - not working // Re-link a gl texture to the shared directX texture bool spoutGLDXinterop::LinkGLtexture(GLuint glTexture) { // printf("LinkGLtexture(%d)\n", glTexture); if(g_pd3dDevice == NULL || g_pSharedTexture == NULL || m_dxShareHandle == NULL) { // printf(" null handles\n"); return false; } if(m_hInteropDevice != NULL && m_hInteropObject != NULL) { // printf(" unregister\n"); wglDXUnregisterObjectNV(m_hInteropDevice, m_hInteropObject); m_hInteropObject = NULL; } // printf(" unregister OK\n"); if (m_hInteropDevice != NULL) { wglDXCloseDeviceNV(m_hInteropDevice); } // printf(" close device OK\n"); m_hInteropDevice = NULL; m_hInteropObject = NULL; m_hInteropDevice = wglDXOpenDeviceNV(g_pd3dDevice); if (m_hInteropDevice == NULL) { // printf(" open device fail\n"); return false; } // printf(" open device OK\n"); // Prepare the DirectX texture for use by OpenGL // register for interop and associate the opengl texture with the dx texture m_hInteropObject = wglDXRegisterObjectNV(g_pd3dDevice, g_pSharedTexture, // DX texture glTexture, // OpenGL texture GL_TEXTURE_2D, // Must be TEXTURE_2D WGL_ACCESS_READ_WRITE_NV); // We will write and the receiver will read if(!m_hInteropObject) { // printf(" null InteropObject\n"); return false; } // printf(" InteropObject OK\n"); return true; }
JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_WGLNVDXInterop_nwglDXOpenDeviceNV(JNIEnv *__env, jclass clazz, jlong dxDeviceAddress, jlong __functionAddress) { void *dxDevice = (void *)(intptr_t)dxDeviceAddress; wglDXOpenDeviceNVPROC wglDXOpenDeviceNV = (wglDXOpenDeviceNVPROC)(intptr_t)__functionAddress; UNUSED_PARAMS(__env, clazz) return (jlong)(intptr_t)wglDXOpenDeviceNV(dxDevice); }
RenderManager::OpenResults RenderManagerD3D11OpenGL::OpenDisplay(void) { // All public methods that use internal state should be guarded // by a mutex. std::lock_guard<std::mutex> lock(m_mutex); OpenResults ret; ret.status = FAILURE; if (!doingOkay()) { return ret; } //====================================================== // We need to call glewInit() so that we have access to // the wgl extensions needed below. This means that we // need to get an OpenGL context open. We use methods // in our OpenGL parent class to open the desired context. // We leave the context open so that we can get our // RenderBuffer names. GLContextParams p; p.visible = false; // Make the context invisible, to not distract if (!addOpenGLContext(p)) { std::cerr << "RenderManagerD3D11OpenGL::OpenDisplay: Can't open GL " "context" << std::endl; return ret; } glewExperimental = true; // Needed for core profile if (glewInit() != GLEW_OK) { removeOpenGLContexts(); std::cerr << "RenderManagerD3D11OpenGL::OpenDisplay: Can't " "initialize GLEW" << std::endl; return ret; } //====================================================== // Open the D3D display we're going to use and get a handle // on it to use to map our OpenGL objects. ret = m_D3D11Renderer->OpenDisplay(); if (ret.status == FAILURE) { std::cerr << "RenderManagerD3D11OpenGL::OpenDisplay: Can't open " "D3D11 display" << std::endl; m_doingOkay = false; return ret; } m_glD3DHandle = wglDXOpenDeviceNV(ret.library.D3D11->device); if (m_glD3DHandle == nullptr) { std::cerr << "RenderManagerD3D11OpenGL::OpenDisplay: Can't get GL " "device handle" << std::endl; ret.status = FAILURE; return ret; } //====================================================== // Construct the present buffers we're going to use when in Render() // mode, to // wrap the PresenMode interface. if (!constructRenderBuffers()) { removeOpenGLContexts(); std::cerr << "RenderManagerOpenGL::OpenDisplay: Could not " "construct present buffers to wrap Render() path" << std::endl; ret.status = FAILURE; return ret; } //====================================================== // Register the presentation buffers, which will cause them to // be associated with newly-constructed D3D buffers. if (!RegisterRenderBuffersInternal(m_colorBuffers)) { removeOpenGLContexts(); std::cerr << "RenderManagerOpenGL::OpenDisplay: Could not regsiter " "present buffers to wrap Render() path" << std::endl; ret.status = FAILURE; return ret; } // Fill in our library with the things the application may need to // use to do its graphics state set-up. ret.library = m_library; ret.buffers = m_buffers; m_displayOpen = true; return ret; }