20HMODULE GHOST_ContextD3D::s_d3d_lib =
nullptr;
21PFN_D3D11_CREATE_DEVICE GHOST_ContextD3D::s_D3D11CreateDeviceFn =
nullptr;
31 m_device_ctx->ClearState();
32 m_device_ctx->Release();
52 if (s_d3d_lib ==
nullptr) {
53 s_d3d_lib = LoadLibraryA(
"d3d11.dll");
55 WIN32_CHK(s_d3d_lib !=
nullptr);
57 if (s_d3d_lib ==
nullptr) {
58 fprintf(stderr,
"LoadLibrary(\"d3d11.dll\") failed!\n");
63 if (s_D3D11CreateDeviceFn ==
nullptr) {
64 s_D3D11CreateDeviceFn = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(s_d3d_lib,
67 WIN32_CHK(s_D3D11CreateDeviceFn !=
nullptr);
69 if (s_D3D11CreateDeviceFn ==
nullptr) {
70 fprintf(stderr,
"GetProcAddress(s_d3d_lib, \"D3D11CreateDevice\") failed!\n");
84 HRESULT hres = s_D3D11CreateDeviceFn(
86 D3D_DRIVER_TYPE_HARDWARE,
100 WIN32_CHK(hres == S_OK);
114 HANDLE render_target{
nullptr};
117 enum RenderTarget { TARGET_RENDERBUF, TARGET_TEX2D };
121 ID3D11DeviceContext *device_ctx,
125 ID3D11RenderTargetView *render_target =
nullptr)
126 : m_device(device), m_device_ctx(device_ctx), m_cur_width(width), m_cur_height(height)
128 if (!render_target) {
129 D3D11_TEXTURE2D_DESC texDesc{};
130 D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc{};
131 ID3D11Texture2D *
tex;
133 texDesc.Width = width;
134 texDesc.Height = height;
136 texDesc.SampleDesc.Count = 1;
137 texDesc.ArraySize = 1;
138 texDesc.MipLevels = 1;
139 texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
141 device->CreateTexture2D(&texDesc,
nullptr, &
tex);
145 fprintf(stderr,
"Error creating texture for shared DirectX-OpenGL resource\n");
149 renderTargetViewDesc.Format = texDesc.Format;
150 renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
151 renderTargetViewDesc.Texture2D.MipSlice = 0;
153 device->CreateRenderTargetView(
tex, &renderTargetViewDesc, &render_target);
160 ID3D11Resource *backbuffer_res =
nullptr;
162 if (backbuffer_res) {
164 backbuffer_res->Release();
169 fprintf(stderr,
"Error creating render target for shared DirectX-OpenGL resource\n");
183 if (m_is_initialized) {
185 if (m_shared.render_target
190 && !m_use_gl_texture2d
193 wglDXUnregisterObjectNV(m_shared.device, m_shared.render_target);
195 if (m_shared.device) {
196 wglDXCloseDeviceNV(m_shared.device);
198 glDeleteFramebuffers(1, &m_shared.fbo);
199 if (m_use_gl_texture2d) {
200 glDeleteTextures(1, &m_gl_render_target);
203 glDeleteRenderbuffers(1, &m_gl_render_target);
206 glDeleteFramebuffers(1, &m_shared.fbo);
207 if (m_use_gl_texture2d) {
208 glDeleteTextures(1, &m_gl_render_target);
217 if (m_shared.render_target) {
218 wglDXUnregisterObjectNV(m_shared.device, m_shared.render_target);
225 if (target == TARGET_TEX2D) {
226 glTexImage2D(GL_TEXTURE_2D,
237 m_shared.render_target = wglDXRegisterObjectNV(m_shared.device,
240 (target == TARGET_TEX2D) ? GL_TEXTURE_2D :
242 WGL_ACCESS_READ_WRITE_NV);
243 if (!m_shared.render_target) {
244 fprintf(stderr,
"Error registering shared object using wglDXRegisterObjectNV()\n");
253 m_shared.device = wglDXOpenDeviceNV(m_device);
254 if (m_shared.device ==
nullptr) {
255 fprintf(stderr,
"Error opening shared device using wglDXOpenDeviceNV()\n");
260 glGenRenderbuffers(1, &m_gl_render_target);
261 glBindRenderbuffer(GL_RENDERBUFFER, m_gl_render_target);
264 glBindRenderbuffer(GL_RENDERBUFFER, 0);
265 if (m_gl_render_target) {
266 glDeleteRenderbuffers(1, &m_gl_render_target);
269 m_use_gl_texture2d =
true;
270 glGenTextures(1, &m_gl_render_target);
271 glBindTexture(GL_TEXTURE_2D, m_gl_render_target);
277 glGenFramebuffers(1, &m_shared.fbo);
278 glBindFramebuffer(GL_FRAMEBUFFER, m_shared.fbo);
279 if (m_use_gl_texture2d) {
280 glFramebufferTexture2D(
281 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_gl_render_target, 0);
284 glFramebufferRenderbuffer(
285 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_gl_render_target);
287 m_is_initialized =
true;
294 if (m_is_initialized ==
false) {
298 if ((m_cur_width != width) || (m_cur_height != height)) {
300 m_cur_height = height;
308 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &fbo);
317 const float clear_col[] = {0.8f, 0.5f, 1.0f, 1.0f};
324 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_shared.fbo);
325 GLenum err = glCheckFramebufferStatus(GL_FRAMEBUFFER);
326 if (err != GL_FRAMEBUFFER_COMPLETE) {
328 stderr,
"Error: Framebuffer for shared DirectX-OpenGL resource incomplete %u\n", err);
333 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
334 glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
336 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
349 wglDXLockObjectsNV(m_shared.device, 1, &m_shared.render_target);
353 wglDXUnlockObjectsNV(m_shared.device, 1, &m_shared.render_target);
356 ID3D11Device *m_device;
357 ID3D11DeviceContext *m_device_ctx;
358 GLuint m_gl_render_target;
359 unsigned int m_cur_width, m_cur_height;
360 bool m_is_initialized{
false};
361 bool m_use_gl_texture2d{
false};
368 ID3D11RenderTargetView *render_target)
370 if (!(WGL_NV_DX_interop && WGL_NV_DX_interop2)) {
372 "Error: Can't render OpenGL framebuffer using Direct3D. NV_DX_interop extension not "
377 m_device, m_device_ctx, width, height,
format, render_target);
397 return shared_res->
blit(width, height);
GHOST_TSuccess activateDrawingContext()
GHOST_TSuccess releaseNativeHandles()
GHOST_TSuccess swapBuffers()
GHOST_ContextD3D(bool stereoVisual, HWND hWnd)
GHOST_TSuccess blitFromOpenGLContext(class GHOST_SharedOpenGLResource *shared_res, unsigned int width, unsigned int height)
ID3D11Texture2D * getSharedTexture2D(class GHOST_SharedOpenGLResource *shared_res)
class GHOST_SharedOpenGLResource * createSharedOpenGLResource(unsigned int width, unsigned int height, DXGI_FORMAT format, ID3D11RenderTargetView *render_target)
GHOST_TSuccess initializeDrawingContext()
void disposeSharedOpenGLResource(class GHOST_SharedOpenGLResource *shared_res)
GHOST_TSuccess releaseDrawingContext()
void ensureUpdated(unsigned int width, unsigned int height)
GHOST_TSuccess blit(unsigned int width, unsigned int height)
GHOST_TSuccess initialize()
~GHOST_SharedOpenGLResource()
GHOST_SharedOpenGLResource(ID3D11Device *device, ID3D11DeviceContext *device_ctx, unsigned int width, unsigned int height, DXGI_FORMAT format, ID3D11RenderTargetView *render_target=nullptr)
bool reregisterSharedObject(RenderTarget target)
ID3D11RenderTargetView * m_render_target
ID3D11Texture2D * m_render_target_tex