19 HMODULE GHOST_ContextD3D::s_d3d_lib =
NULL;
20 PFN_D3D11_CREATE_DEVICE GHOST_ContextD3D::s_D3D11CreateDeviceFn =
NULL;
30 m_device_ctx->ClearState();
31 m_device_ctx->Release();
51 if (s_d3d_lib ==
NULL) {
52 s_d3d_lib = LoadLibraryA(
"d3d11.dll");
54 WIN32_CHK(s_d3d_lib !=
NULL);
56 if (s_d3d_lib ==
NULL) {
57 fprintf(stderr,
"LoadLibrary(\"d3d11.dll\") failed!\n");
62 if (s_D3D11CreateDeviceFn ==
NULL) {
63 s_D3D11CreateDeviceFn = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(s_d3d_lib,
66 WIN32_CHK(s_D3D11CreateDeviceFn !=
NULL);
68 if (s_D3D11CreateDeviceFn ==
NULL) {
69 fprintf(stderr,
"GetProcAddress(s_d3d_lib, \"D3D11CreateDevice\") failed!\n");
83 HRESULT hres = s_D3D11CreateDeviceFn(
85 D3D_DRIVER_TYPE_HARDWARE,
99 WIN32_CHK(hres == S_OK);
113 HANDLE render_target{
nullptr};
116 enum RenderTarget { TARGET_RENDERBUF, TARGET_TEX2D };
120 ID3D11DeviceContext *device_ctx,
124 ID3D11RenderTargetView *render_target =
nullptr)
125 : m_device(device), m_device_ctx(device_ctx), m_cur_width(
width), m_cur_height(
height)
127 ID3D11Resource *backbuffer_res;
129 if (!render_target) {
130 D3D11_TEXTURE2D_DESC texDesc{};
131 D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc{};
132 ID3D11Texture2D *
tex;
134 texDesc.Width =
width;
137 texDesc.SampleDesc.Count = 1;
138 texDesc.ArraySize = 1;
139 texDesc.MipLevels = 1;
140 texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
142 device->CreateTexture2D(&texDesc,
NULL, &
tex);
146 fprintf(stderr,
"Error creating texture for shared DirectX-OpenGL resource\n");
150 renderTargetViewDesc.Format = texDesc.Format;
151 renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
152 renderTargetViewDesc.Texture2D.MipSlice = 0;
154 device->CreateRenderTargetView(
tex, &renderTargetViewDesc, &render_target);
163 if (backbuffer_res) {
165 backbuffer_res->Release();
169 fprintf(stderr,
"Error creating render target for shared DirectX-OpenGL resource\n");
183 if (m_is_initialized) {
184 if (m_shared.render_target
189 && !m_use_gl_texture2d
192 wglDXUnregisterObjectNV(m_shared.device, m_shared.render_target);
194 if (m_shared.device) {
195 wglDXCloseDeviceNV(m_shared.device);
197 glDeleteFramebuffers(1, &m_shared.fbo);
198 if (m_use_gl_texture2d) {
199 glDeleteTextures(1, &m_gl_render_target);
202 glDeleteRenderbuffers(1, &m_gl_render_target);
210 if (m_shared.render_target) {
211 wglDXUnregisterObjectNV(m_shared.device, m_shared.render_target);
218 if (target == TARGET_TEX2D) {
219 glTexImage2D(GL_TEXTURE_2D,
230 m_shared.render_target = wglDXRegisterObjectNV(m_shared.device,
233 (target == TARGET_TEX2D) ? GL_TEXTURE_2D :
235 WGL_ACCESS_READ_WRITE_NV);
236 if (!m_shared.render_target) {
237 fprintf(stderr,
"Error registering shared object using wglDXRegisterObjectNV()\n");
246 m_shared.device = wglDXOpenDeviceNV(m_device);
247 if (m_shared.device ==
NULL) {
248 fprintf(stderr,
"Error opening shared device using wglDXOpenDeviceNV()\n");
253 glGenRenderbuffers(1, &m_gl_render_target);
254 glBindRenderbuffer(GL_RENDERBUFFER, m_gl_render_target);
257 glBindRenderbuffer(GL_RENDERBUFFER, 0);
258 if (m_gl_render_target) {
259 glDeleteRenderbuffers(1, &m_gl_render_target);
262 m_use_gl_texture2d =
true;
263 glGenTextures(1, &m_gl_render_target);
264 glBindTexture(GL_TEXTURE_2D, m_gl_render_target);
270 glGenFramebuffers(1, &m_shared.fbo);
271 glBindFramebuffer(GL_FRAMEBUFFER, m_shared.fbo);
272 if (m_use_gl_texture2d) {
273 glFramebufferTexture2D(
274 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_gl_render_target, 0);
277 glFramebufferRenderbuffer(
278 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_gl_render_target);
280 m_is_initialized =
true;
287 if (m_is_initialized ==
false) {
291 if ((m_cur_width !=
width) || (m_cur_height !=
height)) {
301 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &fbo);
310 const float clear_col[] = {0.8f, 0.5f, 1.0f, 1.0f};
317 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_shared.fbo);
318 GLenum
err = glCheckFramebufferStatus(GL_FRAMEBUFFER);
319 if (
err != GL_FRAMEBUFFER_COMPLETE) {
321 stderr,
"Error: Framebuffer for shared DirectX-OpenGL resource incomplete %u\n",
err);
326 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
329 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
342 wglDXLockObjectsNV(m_shared.device, 1, &m_shared.render_target);
346 wglDXUnlockObjectsNV(m_shared.device, 1, &m_shared.render_target);
349 ID3D11Device *m_device;
350 ID3D11DeviceContext *m_device_ctx;
351 GLuint m_gl_render_target;
352 unsigned int m_cur_width, m_cur_height;
353 bool m_is_initialized{
false};
354 bool m_use_gl_texture2d{
false};
361 ID3D11RenderTargetView *render_target)
363 if (!(WGL_NV_DX_interop && WGL_NV_DX_interop2)) {
365 "Error: Can't render OpenGL framebuffer using Direct3D. NV_DX_interop extension not "
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
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