13
13
#include <windows.h>
14
14
#elif defined(__ANDROID__ )
15
15
#define XR_USE_PLATFORM_ANDROID
16
+ #include <android_native_app_glue.h>
16
17
#include <EGL/egl.h>
17
18
#include <jni.h>
18
19
#endif
19
20
#if defined(LOVR_GL )
20
21
#define XR_USE_GRAPHICS_API_OPENGL
21
22
#define GRAPHICS_EXTENSION "XR_KHR_opengl_enable"
22
23
#elif defined(LOVR_GLES )
23
- #define XR_USE_GRAPHICS_API_OPENGLES
24
+ #define XR_USE_GRAPHICS_API_OPENGL_ES
24
25
#define GRAPHICS_EXTENSION "XR_KHR_opengl_es_enable"
25
26
#endif
26
27
#define XR_NO_PROTOTYPES
27
28
#include <openxr/openxr.h>
28
29
#include <openxr/openxr_platform.h>
30
+ #ifdef __ANDROID__
31
+ #include <openxr/openxr_oculus.h>
32
+ #endif
29
33
#include "resources/openxr_actions.h"
30
34
31
35
#define XR (f ) handleResult(f, __FILE__, __LINE__)
38
42
HANDLE lovrPlatformGetWindow (void );
39
43
HGLRC lovrPlatformGetContext (void );
40
44
#elif defined(__ANDROID__ )
41
- EGLDisplay lovrPlatformGetEGLDisplay ();
42
- EGLContext lovrPlatformGetEGLContext ();
43
- EGLConfig lovrPlatformGetEGLConfig ();
45
+ struct ANativeActivity * lovrPlatformGetActivity (void );
46
+ EGLDisplay lovrPlatformGetEGLDisplay (void );
47
+ EGLContext lovrPlatformGetEGLContext (void );
48
+ EGLConfig lovrPlatformGetEGLConfig (void );
44
49
#endif
45
50
46
51
#define XR_FOREACH (X )\
@@ -146,6 +151,25 @@ static void openxr_destroy();
146
151
static bool openxr_init (float offset , uint32_t msaa ) {
147
152
state .msaa = msaa ;
148
153
154
+ #ifdef __ANDROID__
155
+ static PFN_xrInitializeLoaderKHR xrInitializeLoaderKHR ;
156
+ XR_LOAD (xrInitializeLoaderKHR );
157
+ if (!xrInitializeLoaderKHR ) {
158
+ return false;
159
+ }
160
+
161
+ ANativeActivity * activity = lovrPlatformGetActivity ();
162
+ XrLoaderInitInfoAndroidKHR loaderInfo = {
163
+ .type = XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR ,
164
+ .applicationVM = activity -> vm ,
165
+ .applicationContext = activity -> clazz
166
+ };
167
+
168
+ if (XR_FAILED (xrInitializeLoaderKHR ((XrLoaderInitInfoBaseHeaderKHR * ) & loaderInfo ))) {
169
+ return false;
170
+ }
171
+ #endif
172
+
149
173
{ // Instance
150
174
uint32_t extensionCount ;
151
175
xrEnumerateInstanceExtensionProperties (NULL , 0 , & extensionCount , NULL );
@@ -157,6 +181,10 @@ static bool openxr_init(float offset, uint32_t msaa) {
157
181
const char * enabledExtensionNames [4 ];
158
182
uint32_t enabledExtensionCount = 0 ;
159
183
184
+ #ifdef __ANDROID__
185
+ enabledExtensionNames [enabledExtensionCount ++ ] = XR_KHR_ANDROID_CREATE_INSTANCE_EXTENSION_NAME ;
186
+ #endif
187
+
160
188
enabledExtensionNames [enabledExtensionCount ++ ] = GRAPHICS_EXTENSION ;
161
189
162
190
if (hasExtension (extensions , extensionCount , XR_EXT_HAND_TRACKING_EXTENSION_NAME )) {
@@ -173,6 +201,13 @@ static bool openxr_init(float offset, uint32_t msaa) {
173
201
174
202
XrInstanceCreateInfo info = {
175
203
.type = XR_TYPE_INSTANCE_CREATE_INFO ,
204
+ #ifdef __ANDROID__
205
+ .next = & (XrInstanceCreateInfoAndroidKHR ) {
206
+ .type = XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR ,
207
+ .applicationVM = activity -> vm ,
208
+ .applicationActivity = activity -> clazz
209
+ },
210
+ #endif
176
211
.applicationInfo .engineName = "LÖVR" ,
177
212
.applicationInfo .engineVersion = (LOVR_VERSION_MAJOR << 24 ) + (LOVR_VERSION_MINOR << 16 ) + LOVR_VERSION_PATCH ,
178
213
.applicationInfo .applicationName = "LÖVR" ,
@@ -272,13 +307,13 @@ static bool openxr_init(float offset, uint32_t msaa) {
272
307
273
308
{ // Session
274
309
#if defined(LOVR_GL )
275
- XrGraphicsRequirementsOpenGLKHR requirements ;
310
+ XrGraphicsRequirementsOpenGLKHR requirements = { . type = XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR , NULL } ;
276
311
PFN_xrGetOpenGLGraphicsRequirementsKHR xrGetOpenGLGraphicsRequirementsKHR ;
277
312
XR_LOAD (xrGetOpenGLGraphicsRequirementsKHR );
278
313
XR_INIT (xrGetOpenGLGraphicsRequirementsKHR (state .instance , state .system , & requirements ));
279
314
// TODO validate OpenGL versions
280
315
#elif defined(LOVR_GLES )
281
- XrGraphicsRequirementsOpenGLESKHR requirements ;
316
+ XrGraphicsRequirementsOpenGLESKHR requirements = { . type = XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR , NULL } ;
282
317
PFN_xrGetOpenGLESGraphicsRequirementsKHR xrGetOpenGLESGraphicsRequirementsKHR ;
283
318
XR_LOAD (xrGetOpenGLESGraphicsRequirementsKHR );
284
319
XR_INIT (xrGetOpenGLESGraphicsRequirementsKHR (state .instance , state .system , & requirements ));
@@ -364,28 +399,43 @@ static bool openxr_init(float offset, uint32_t msaa) {
364
399
}
365
400
366
401
{ // Swapchain
402
+ #if defined(XR_USE_GRAPHICS_API_OPENGL )
403
+ TextureType textureType = TEXTURE_2D ;
404
+ uint32_t width = state .width * 2 ;
405
+ uint32_t arraySize = 1 ;
406
+ XrSwapchainImageOpenGLKHR images [MAX_IMAGES ];
407
+ for (uint32_t i = 0 ; i < MAX_IMAGES ; i ++ ) {
408
+ images [i ].type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR ;
409
+ images [i ].next = NULL ;
410
+ }
411
+ #elif defined(XR_USE_GRAPHICS_API_OPENGL_ES )
412
+ TextureType textureType = TEXTURE_ARRAY ;
413
+ uint32_t width = state .width ;
414
+ uint32_t arraySize = 2 ;
415
+ XrSwapchainImageOpenGLESKHR images [MAX_IMAGES ];
416
+ for (uint32_t i = 0 ; i < MAX_IMAGES ; i ++ ) {
417
+ images [i ].type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR ;
418
+ images [i ].next = NULL ;
419
+ }
420
+ #endif
421
+
367
422
XrSwapchainCreateInfo info = {
368
423
.type = XR_TYPE_SWAPCHAIN_CREATE_INFO ,
369
424
.usageFlags = XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_SAMPLED_BIT ,
370
425
.format = GL_SRGB8_ALPHA8 ,
371
- .width = state . width * 2 ,
426
+ .width = width ,
372
427
.height = state .height ,
373
428
.sampleCount = 1 ,
374
429
.faceCount = 1 ,
375
- .arraySize = 1 ,
430
+ .arraySize = arraySize ,
376
431
.mipCount = 1
377
432
};
378
433
379
- #if defined(XR_USE_GRAPHICS_API_OPENGL )
380
- XrSwapchainImageOpenGLKHR images [MAX_IMAGES ];
381
- #elif defined(XR_USE_GRAPHICS_API_OPENGLES )
382
- XrSwapchainImageOpenGLESKHR images [MAX_IMAGES ];
383
- #endif
384
434
XR_INIT (xrCreateSwapchain (state .session , & info , & state .swapchain ));
385
435
XR_INIT (xrEnumerateSwapchainImages (state .swapchain , MAX_IMAGES , & state .imageCount , (XrSwapchainImageBaseHeader * ) images ));
386
436
387
437
for (uint32_t i = 0 ; i < state .imageCount ; i ++ ) {
388
- state .textures [i ] = lovrTextureCreateFromHandle (images [i ].image , TEXTURE_2D , 1 , state .msaa );
438
+ state .textures [i ] = lovrTextureCreateFromHandle (images [i ].image , textureType , arraySize , state .msaa );
389
439
}
390
440
391
441
// Pre-init composition layer
@@ -402,14 +452,20 @@ static bool openxr_init(float offset, uint32_t msaa) {
402
452
.subImage = { state .swapchain , { { 0 , 0 }, { state .width , state .height } }, 0 }
403
453
};
404
454
405
- // Copy the left view to the right view and offset for side-by-side submission
455
+ // Copy the left view to the right view and offset either the viewport or array index
406
456
state .layerViews [1 ] = state .layerViews [0 ];
457
+ #if defined(XR_USE_GRAPHICS_API_OPENGL )
407
458
state .layerViews [1 ].subImage .imageRect .offset .x += state .width ;
459
+ #elif defined(XR_USE_GRAPHICS_API_OPENGL_ES )
460
+ state .layerViews [1 ].subImage .imageArrayIndex = 1 ;
461
+ #endif
408
462
}
409
463
410
464
state .clipNear = .1f ;
411
465
state .clipFar = 100.f ;
412
466
467
+ state .frameState .type = XR_TYPE_FRAME_STATE ;
468
+
413
469
return true;
414
470
}
415
471
@@ -475,7 +531,7 @@ static void getViews(XrView views[2], uint32_t* count) {
475
531
.space = state .referenceSpace
476
532
};
477
533
478
- XrViewState viewState ;
534
+ XrViewState viewState = { . type = XR_TYPE_VIEW_STATE } ;
479
535
XR (xrLocateViews (state .session , & viewLocateInfo , & viewState , 2 * sizeof (XrView ), count , views ));
480
536
}
481
537
@@ -725,7 +781,8 @@ static void openxr_renderTo(void (*callback)(void*), void* userdata) {
725
781
XrFrameEndInfo endInfo = {
726
782
.type = XR_TYPE_FRAME_END_INFO ,
727
783
.displayTime = state .frameState .predictedDisplayTime ,
728
- .environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE
784
+ .environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE ,
785
+ .layers = (const XrCompositionLayerBaseHeader * [1 ]) { (XrCompositionLayerBaseHeader * ) & state .layers [0 ] }
729
786
};
730
787
731
788
XR (xrBeginFrame (state .session , & beginInfo ));
@@ -769,8 +826,6 @@ static void openxr_renderTo(void (*callback)(void*), void* userdata) {
769
826
callback (userdata );
770
827
lovrGraphicsSetCamera (NULL , false);
771
828
772
- const XrCompositionLayerBaseHeader * layers [1 ] = { (XrCompositionLayerBaseHeader * ) & state .layers [0 ] };
773
- endInfo .layers = layers ;
774
829
endInfo .layerCount = 1 ;
775
830
state .layerViews [0 ].pose = views [0 ].pose ;
776
831
state .layerViews [0 ].fov = views [0 ].fov ;
@@ -822,7 +877,7 @@ static void openxr_update(float dt) {
822
877
bool wasFocused = state .sessionState == XR_SESSION_STATE_FOCUSED ;
823
878
bool isFocused = event -> state == XR_SESSION_STATE_FOCUSED ;
824
879
if (wasFocused != isFocused ) {
825
- lovrEventPush ((Event ) { .type = EVENT_FOCUS , .data .boolean = isFocused });
880
+ lovrEventPush ((Event ) { .type = EVENT_FOCUS , .data .boolean . value = isFocused });
826
881
}
827
882
828
883
state .sessionState = event -> state ;
0 commit comments