3#define UNUSED_PARM(x) \
6#if defined(XR_USE_PLATFORM_WIN32)
8bool GL_INITIALIZED =
false;
10# define strcpy_s(dest, source) strncpy((dest), (source), sizeof(dest))
13#if defined(XR_USE_GRAPHICS_API_OPENGL)
14bool check_opengl_version(XrGraphicsRequirementsOpenGLKHR* opengl_reqs)
16 GLint major = GLVersion.major;
17 GLint minor = GLVersion.minor;
18#elif defined(XR_USE_GRAPHICS_API_OPENGL_ES)
19bool check_opengl_version(XrGraphicsRequirementsOpenGLESKHR* opengl_reqs)
23 glGetIntegerv(GL_MAJOR_VERSION, &major);
24 glGetIntegerv(GL_MINOR_VERSION, &minor);
27 const XrVersion desired_opengl_version = XR_MAKE_VERSION(major, minor, 0);
28 if (desired_opengl_version > opengl_reqs->maxApiVersionSupported || desired_opengl_version < opengl_reqs->minApiVersionSupported)
31 "[OPENXR]: We want OpenGL %d.%d.%d, but runtime only supports OpenGL %d.%d.%d - %d.%d.%d!\n",
32 XR_VERSION_MAJOR(desired_opengl_version), XR_VERSION_MINOR(desired_opengl_version),
33 XR_VERSION_PATCH(desired_opengl_version),
34 XR_VERSION_MAJOR(opengl_reqs->minApiVersionSupported),
35 XR_VERSION_MINOR(opengl_reqs->minApiVersionSupported),
36 XR_VERSION_PATCH(opengl_reqs->minApiVersionSupported),
37 XR_VERSION_MAJOR(opengl_reqs->maxApiVersionSupported),
38 XR_VERSION_MINOR(opengl_reqs->maxApiVersionSupported),
39 XR_VERSION_PATCH(opengl_reqs->maxApiVersionSupported));
47#ifdef XR_USE_GRAPHICS_API_OPENGL
50 virtual ~OpenGLRenderer()
override
52 for (
auto& frame_buffer : mFramebuffers)
54 glDeleteFramebuffers(frame_buffer.size(), frame_buffer.data());
56 mFramebuffers.clear();
59 const XrBaseInStructure* GetBindings()
const override {
return reinterpret_cast<const XrBaseInStructure*
>(&mGraphicsBinding); }
61 const char* GetExtension()
const override {
return XR_KHR_OPENGL_ENABLE_EXTENSION_NAME; }
65#if defined(XR_USE_PLATFORM_WIN32)
67 GL_INITIALIZED = gladLoadGLLoader(getProcAddress) ? true :
false;
71 MMechostr(MSKRUNTIME,
"sOpenXr initialize : Could not load OpenGL, creates a SO3Window first\n");
81 bool Check(XrSystemId systemId, XrInstance instance)
override
84 XrGraphicsRequirementsOpenGLKHR opengl_reqs = { XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR, NULL };
85 PFN_xrGetOpenGLGraphicsRequirementsKHR pfnGetOpenGLGraphicsRequirementsKHR = NULL;
86 result = xrGetInstanceProcAddr(instance,
"xrGetOpenGLGraphicsRequirementsKHR", (PFN_xrVoidFunction*)&pfnGetOpenGLGraphicsRequirementsKHR);
87 if (!xr_result(instance, result,
"Failed to get OpenGL graphics requirements function!"))
90 result = pfnGetOpenGLGraphicsRequirementsKHR(instance, systemId, &opengl_reqs);
91 if (!xr_result(instance, result,
"Failed to get OpenGL graphics requirements!"))
96 check_opengl_version(&opengl_reqs);
98# if defined(XR_USE_PLATFORM_WIN32)
99 mGraphicsBinding = XrGraphicsBindingOpenGLWin32KHR{ XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR };
100 mGraphicsBinding.hDC = wglGetCurrentDC();
101 mGraphicsBinding.hGLRC = wglGetCurrentContext();
104 MMechostr(MSKRUNTIME,
"[OPENXR]: Using OpenGL version: %s\n", glGetString(GL_VERSION));
105 MMechostr(MSKRUNTIME,
"[OPENXR]: Using OpenGL Renderer: %s\n", glGetString(GL_RENDERER));
109 bool GetSwapchainFormat(XrInstance instance, XrSession session, int64_t &format)
override
112 uint32_t swapchain_format_count;
113 result = xrEnumerateSwapchainFormats(session, 0, &swapchain_format_count, XR_NULL_HANDLE);
114 if (!xr_result(instance, result,
"Failed to get number of supported swapchain formats"))
117 MMechostr(MSKRUNTIME,
"[OPENXR]: Runtime supports %d swapchain formats\n", swapchain_format_count);
118 std::vector<int64_t> swapchain_formats(swapchain_format_count);
119 result = xrEnumerateSwapchainFormats(session, swapchain_format_count, &swapchain_format_count, swapchain_formats.data());
120 if (!xr_result(instance, result,
"Failed to enumerate swapchain formats"))
124 int64_t preferred_swapchain_format = GL_RGBA8;
125 format = swapchain_formats[0];
127 for (
auto& swapchain_format : swapchain_formats)
129 MMechostr(MSKRUNTIME,
"[OPENXR]: Supported GL format: %#lx\n", swapchain_format);
130 if (swapchain_format == preferred_swapchain_format)
132 format = swapchain_format;
133 MMechostr(MSKRUNTIME,
"[OPENXR]: Using preferred swapchain format %#lx\n", format);
137 if (format != preferred_swapchain_format)
138 MMechostr(MSKRUNTIME,
"[OPENXR]: Using non preferred swapchain format %#lx\n", format);
143 bool CreateSwapchainImage(XrInstance instance, uint32 viewCount, XrSwapchain swapchain, uint32_t pos)
override
148 mImages.resize(viewCount);
150 if (mFramebuffers.empty())
151 mFramebuffers.resize(viewCount);
154 uint32_t swapchain_length;
155 result = xrEnumerateSwapchainImages(swapchain, 0, &swapchain_length, XR_NULL_HANDLE);
156 if (!xr_result(instance, result,
"Failed to enumerate swapchains"))
159 mImages[pos].resize(swapchain_length, { XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR , NULL });
161 result = xrEnumerateSwapchainImages(swapchain, swapchain_length, &swapchain_length, (XrSwapchainImageBaseHeader*)mImages[pos].data());
162 if (!xr_result(instance, result,
"Failed to enumerate swapchain images"))
165 mFramebuffers[pos].resize(mImages[pos].size());
166 glGenFramebuffers(mFramebuffers[pos].size(), mFramebuffers[pos].data());
171 void UpdateTextures(SCOL_PTR_TYPE leftTexture, SCOL_PTR_TYPE rightTexture, uint32_t acquiredIndex, int32_t width, int32_t height, uint32_t pos)
override
174 GLuint glid = mImages[pos][acquiredIndex].image;
176 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldfb);
178 GLuint eyetex = (GLuint)((pos == 0) ? leftTexture : rightTexture);
180 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffers[pos][acquiredIndex]);
181 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, eyetex, 0);
184 glBindTexture(GL_TEXTURE_2D, glid);
185 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height);
212 glBindTexture(GL_TEXTURE_2D, 0);
213 glBindFramebuffer(GL_FRAMEBUFFER, oldfb);
217 XrGraphicsBindingOpenGLWin32KHR mGraphicsBinding;
218 std::vector<std::vector<XrSwapchainImageOpenGLKHR> > mImages;
219 std::vector<std::vector<GLuint>> mFramebuffers;
221std::shared_ptr<IRenderer> CreateOpenGLRenderer()
223 return std::make_shared<OpenGLRenderer>();
227#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
228struct OpenGLESRenderer :
public IRenderer {
229 OpenGLESRenderer() { }
230 virtual ~OpenGLESRenderer()
override
232 for (
auto& frame_buffer : mFramebuffers)
234 glDeleteFramebuffers(frame_buffer.size(), frame_buffer.data());
236 mFramebuffers.clear();
239 const XrBaseInStructure* GetBindings()
const override {
return reinterpret_cast<const XrBaseInStructure*
>(&mGraphicsBinding); }
241 const char* GetExtension()
const override {
return XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME; }
243 bool Setup()
override
245#if defined(XR_USE_PLATFORM_WIN32)
247 GL_INITIALIZED = gladLoadGLLoader(getProcAddress) ? true :
false;
251 MMechostr(MSKRUNTIME,
"sOpenXr initialize : Could not load OpenGL, creates a SO3Window first\n");
261 bool Check(XrSystemId systemId, XrInstance instance)
override
264 XrGraphicsRequirementsOpenGLESKHR opengl_reqs = { XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR, XR_NULL_HANDLE };
265 PFN_xrGetOpenGLESGraphicsRequirementsKHR pfnGetOpenGLESGraphicsRequirementsKHR = XR_NULL_HANDLE;
266 result = xrGetInstanceProcAddr(instance,
"xrGetOpenGLESGraphicsRequirementsKHR", (PFN_xrVoidFunction*)&pfnGetOpenGLESGraphicsRequirementsKHR);
267 if (!xr_result(instance, result,
"Failed to get OpenGL graphics requirements function!"))
270 result = pfnGetOpenGLESGraphicsRequirementsKHR(instance, systemId, &opengl_reqs);
271 if (!xr_result(instance, result,
"Failed to get OpenGL graphics requirements!"))
276 check_opengl_version(&opengl_reqs);
278# if defined(XR_USE_PLATFORM_ANDROID)
279 if ((eglGetCurrentContext() == EGL_NO_CONTEXT) || (eglGetCurrentSurface(EGL_DRAW) == EGL_NO_SURFACE))
282 mGraphicsBinding = XrGraphicsBindingOpenGLESAndroidKHR{ XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR };
283 mGraphicsBinding.display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
284 mGraphicsBinding.config = (EGLConfig)0;
285 mGraphicsBinding.context = eglGetCurrentContext();
288 MMechostr(MSKRUNTIME,
"[OPENXR]: Using OpenGL version: %s\n", glGetString(GL_VERSION));
289 MMechostr(MSKRUNTIME,
"[OPENXR]: Using OpenGL Renderer: %s\n", glGetString(GL_RENDERER));
293 bool GetSwapchainFormat(XrInstance instance, XrSession session, int64_t &format)
override
296 uint32_t swapchain_format_count;
297 result = xrEnumerateSwapchainFormats(session, 0, &swapchain_format_count, XR_NULL_HANDLE);
298 if (!xr_result(instance, result,
"Failed to get number of supported swapchain formats"))
301 MMechostr(MSKRUNTIME,
"[OPENXR]: Runtime supports %d swapchain formats\n", swapchain_format_count);
302 std::vector<int64_t> swapchain_formats(swapchain_format_count);
303 result = xrEnumerateSwapchainFormats(session, swapchain_format_count, &swapchain_format_count, swapchain_formats.data());
304 if (!xr_result(instance, result,
"Failed to enumerate swapchain formats"))
308 int64_t preferred_swapchain_format = GL_RGBA8;
309 format = swapchain_formats[0];
311 for (
auto& swapchain_format : swapchain_formats)
313 MMechostr(MSKRUNTIME,
"[OPENXR]: Supported GL format: %#lx\n", swapchain_format);
314 if (swapchain_format == preferred_swapchain_format)
316 format = swapchain_format;
317 MMechostr(MSKRUNTIME,
"[OPENXR]: Using preferred swapchain format %#lx\n", format);
321 if (format != preferred_swapchain_format)
322 MMechostr(MSKRUNTIME,
"[OPENXR]: Using non preferred swapchain format %#lx\n", format);
327 bool CreateSwapchainImage(XrInstance instance, uint32 viewCount, XrSwapchain swapchain, uint32_t pos)
override
332 mImages.resize(viewCount);
334 if (mFramebuffers.empty())
335 mFramebuffers.resize(viewCount);
337 uint32_t swapchain_length;
338 result = xrEnumerateSwapchainImages(swapchain, 0, &swapchain_length, XR_NULL_HANDLE);
339 if (!xr_result(instance, result,
"Failed to enumerate swapchains"))
342 mImages[pos].resize(swapchain_length, { XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR , NULL });
344 result = xrEnumerateSwapchainImages(swapchain, swapchain_length, &swapchain_length, (XrSwapchainImageBaseHeader*)mImages[pos].data());
345 if (!xr_result(instance, result,
"Failed to enumerate swapchain images"))
348 mFramebuffers[pos].resize(mImages[pos].size());
349 glGenFramebuffers(mFramebuffers[pos].size(), mFramebuffers[pos].data());
354 void UpdateTextures(SCOL_PTR_TYPE leftTexture, SCOL_PTR_TYPE rightTexture, uint32_t acquiredIndex, int32_t width, int32_t height, uint32_t pos)
override
357 GLuint glid = mImages[pos][acquiredIndex].image;
359 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldfb);
361 GLuint eyetex = (GLuint)((pos == 0) ? leftTexture : rightTexture);
363 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffers[pos][acquiredIndex]);
364 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, eyetex, 0);
366 if (err != GL_NO_ERROR)
369 glBindTexture(GL_TEXTURE_2D, glid);
370 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height);
373 if (err != GL_NO_ERROR)
376 glBindTexture(GL_TEXTURE_2D, 0);
377 glBindFramebuffer(GL_FRAMEBUFFER, oldfb);
381#ifdef XR_USE_PLATFORM_ANDROID
382 XrGraphicsBindingOpenGLESAndroidKHR mGraphicsBinding;
385 std::vector<std::vector<XrSwapchainImageOpenGLESKHR> > mImages;
386 std::vector<std::vector<GLuint>> mFramebuffers;
388std::shared_ptr<IRenderer> CreateOpenGLESRenderer()
390 return std::make_shared<OpenGLESRenderer>();
394#ifdef XR_USE_GRAPHICS_API_D3D11
396IDXGIAdapter1 *d3d_get_adapter(LUID &adapter_luid)
399 IDXGIAdapter1 *final_adapter =
nullptr;
400 IDXGIAdapter1 *curr_adapter =
nullptr;
401 IDXGIFactory1 *dxgi_factory;
402 DXGI_ADAPTER_DESC1 adapter_desc;
404 CreateDXGIFactory1(__uuidof(IDXGIFactory1), (
void **)(&dxgi_factory));
407 while (dxgi_factory->EnumAdapters1(curr++, &curr_adapter) == S_OK)
409 curr_adapter->GetDesc1(&adapter_desc);
411 if (memcmp(&adapter_desc.AdapterLuid, &adapter_luid,
sizeof(&adapter_luid)) == 0) {
412 final_adapter = curr_adapter;
415 curr_adapter->Release();
416 curr_adapter =
nullptr;
418 dxgi_factory->Release();
419 return final_adapter;
429 virtual ~D3D11Renderer()
override
433 const XrBaseInStructure* GetBindings()
const override {
return reinterpret_cast<const XrBaseInStructure*
>(&mGraphicsBinding); }
435 const char* GetExtension()
const override {
return XR_KHR_D3D11_ENABLE_EXTENSION_NAME; }
437 bool Setup()
override {
return true; }
439 bool Check(XrSystemId systemId, XrInstance instance)
override
443 PFN_xrGetD3D11GraphicsRequirementsKHR ext_xrGetD3D11GraphicsRequirementsKHR = NULL;
444 result = xrGetInstanceProcAddr(instance,
"xrGetD3D11GraphicsRequirementsKHR", (PFN_xrVoidFunction *)(&ext_xrGetD3D11GraphicsRequirementsKHR));
445 if (!xr_result(instance, result,
"Failed to get D3D11 graphics requirements function!"))
448 XrGraphicsRequirementsD3D11KHR requirement = { XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR };
449 result = ext_xrGetD3D11GraphicsRequirementsKHR(instance, systemId, &requirement);
450 if (!xr_result(instance, result,
"Failed to get OpenGL graphics requirements!"))
454 mDevice = (ID3D11Device*)(
void*(__cdecl *)())SCgetExtra(
"GetRenderDevice");
455 if (mDevice ==
nullptr)
458 mGraphicsBinding = XrGraphicsBindingD3D11KHR{ XR_TYPE_GRAPHICS_BINDING_D3D11_KHR };
459 mGraphicsBinding.device = mDevice;
463 bool GetSwapchainFormat(XrInstance instance, XrSession session, int64_t &format)
override
466 uint32_t swapchain_format_count;
467 result = xrEnumerateSwapchainFormats(session, 0, &swapchain_format_count, XR_NULL_HANDLE);
468 if (!xr_result(instance, result,
"Failed to get number of supported swapchain formats"))
471 MMechostr(MSKRUNTIME,
"[OPENXR]: Runtime supports %d swapchain formats\n", swapchain_format_count);
472 std::vector<int64_t> swapchain_formats(swapchain_format_count);
473 result = xrEnumerateSwapchainFormats(session, swapchain_format_count, &swapchain_format_count, swapchain_formats.data());
474 if (!xr_result(instance, result,
"Failed to enumerate swapchain formats"))
478 int64_t preferred_swapchain_format = DXGI_FORMAT_R8G8B8A8_UNORM;
479 format = swapchain_formats[0];
481 for (
auto& swapchain_format : swapchain_formats)
483 MMechostr(MSKRUNTIME,
"[OPENXR]: Supported DX format: %#lx\n", swapchain_format);
484 if (swapchain_format == preferred_swapchain_format)
486 format = swapchain_format;
487 MMechostr(MSKRUNTIME,
"[OPENXR]: Using preferred swapchain format %#lx\n", format);
491 if (format != preferred_swapchain_format)
492 MMechostr(MSKRUNTIME,
"[OPENXR]: Using non preferred swapchain format %#lx\n", format);
497 bool CreateSwapchainImage(XrInstance instance, uint32 viewCount, XrSwapchain swapchain, uint32_t pos)
override
502 mImages.resize(viewCount);
504 uint32_t swapchain_length;
505 result = xrEnumerateSwapchainImages(swapchain, 0, &swapchain_length, XR_NULL_HANDLE);
506 if (!xr_result(instance, result,
"Failed to enumerate swapchains"))
509 mImages[pos].resize(swapchain_length, { XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR , NULL });
511 result = xrEnumerateSwapchainImages(swapchain, swapchain_length, &swapchain_length, (XrSwapchainImageBaseHeader*)mImages[pos].data());
512 if (!xr_result(instance, result,
"Failed to enumerate swapchain images"))
518 void UpdateTextures(SCOL_PTR_TYPE leftTexture, SCOL_PTR_TYPE rightTexture, uint32_t acquiredIndex, int32_t width, int32_t height, uint32_t pos)
override
520 ID3D11DeviceContext* d3DContext =
nullptr;
521 mDevice->GetImmediateContext(&d3DContext);
522 d3DContext->CopyResource(mImages[pos][acquiredIndex].texture, (ID3D11Texture2D*)((pos == 0) ? leftTexture : rightTexture));
526 XrGraphicsBindingD3D11KHR mGraphicsBinding;
527 std::vector<std::vector<XrSwapchainImageD3D11KHR> > mImages;
528 ID3D11Device* mDevice;
530std::shared_ptr<IRenderer> CreateD3D11Renderer()
532 return std::make_shared<D3D11Renderer>();
536std::shared_ptr<IRenderer> CreateRenderer(RenderSystem rsys)
538#if defined(XR_USE_GRAPHICS_API_OPENGL)
539 if (rsys == XR_OPENGL_RENDERER)
540 return CreateOpenGLRenderer();
543#if defined(XR_USE_GRAPHICS_API_OPENGL_ES)
544 if (rsys == XR_OPENGL_RENDERER)
545 return CreateOpenGLESRenderer();
548#if defined(XR_USE_GRAPHICS_API_D3D11)
549 if (rsys == XR_DIRECTX11_RENDERER)
550 return CreateD3D11Renderer();