feat: add visionOS examples
This commit is contained in:
parent
3f3d3b4433
commit
a287cae764
34
examples/common/entry/entry_visionos.swift
Normal file
34
examples/common/entry/entry_visionos.swift
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import SwiftUI
|
||||||
|
import CompositorServices
|
||||||
|
|
||||||
|
// Default configuration
|
||||||
|
struct ContentStageConfiguration: CompositorLayerConfiguration {
|
||||||
|
func makeConfiguration(capabilities: LayerRenderer.Capabilities, configuration: inout LayerRenderer.Configuration) {
|
||||||
|
configuration.depthFormat = .depth32Float
|
||||||
|
configuration.colorFormat = .bgra8Unorm_srgb
|
||||||
|
|
||||||
|
let foveationEnabled = capabilities.supportsFoveation
|
||||||
|
configuration.isFoveationEnabled = foveationEnabled
|
||||||
|
|
||||||
|
let options: LayerRenderer.Capabilities.SupportedLayoutsOptions = foveationEnabled ? [.foveationEnabled] : []
|
||||||
|
let supportedLayouts = capabilities.supportedLayouts(options: options)
|
||||||
|
|
||||||
|
configuration.layout = supportedLayouts.contains(.layered) ? .layered : .dedicated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@main
|
||||||
|
struct ExampleApp: App {
|
||||||
|
var body: some Scene {
|
||||||
|
ImmersiveSpace {
|
||||||
|
CompositorLayer(configuration: ContentStageConfiguration()) { layerRenderer in
|
||||||
|
let renderThread = Thread {
|
||||||
|
var engine = BgfxAdapter(layerRenderer)
|
||||||
|
engine.renderLoop()
|
||||||
|
}
|
||||||
|
renderThread.name = "Render Thread"
|
||||||
|
renderThread.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
218
examples/common/entry/swift_adapter.cpp
Normal file
218
examples/common/entry/swift_adapter.cpp
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
#include "entry_p.h"
|
||||||
|
|
||||||
|
#if ENTRY_CONFIG_USE_NATIVE && BX_PLATFORM_VISIONOS
|
||||||
|
|
||||||
|
#include "swift_adapter.h"
|
||||||
|
|
||||||
|
#include <bgfx/platform.h>
|
||||||
|
#include <bx/uint32_t.h>
|
||||||
|
#include <bx/thread.h>
|
||||||
|
|
||||||
|
namespace entry
|
||||||
|
{
|
||||||
|
struct MainThreadEntry
|
||||||
|
{
|
||||||
|
int m_argc;
|
||||||
|
const char* const* m_argv;
|
||||||
|
|
||||||
|
static int32_t threadFunc(bx::Thread* _thread, void* _userData);
|
||||||
|
};
|
||||||
|
|
||||||
|
static WindowHandle s_defaultWindow = { 0 };
|
||||||
|
|
||||||
|
struct Context
|
||||||
|
{
|
||||||
|
Context(uint32_t _width, uint32_t _height)
|
||||||
|
{
|
||||||
|
static const char* const argv[] = { "visionos" };
|
||||||
|
m_mte.m_argc = BX_COUNTOF(argv);
|
||||||
|
m_mte.m_argv = argv;
|
||||||
|
|
||||||
|
m_eventQueue.postSizeEvent(s_defaultWindow, _width, _height);
|
||||||
|
|
||||||
|
|
||||||
|
// Prevent render thread creation.
|
||||||
|
bgfx::renderFrame();
|
||||||
|
|
||||||
|
m_thread.init(MainThreadEntry::threadFunc, &m_mte);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
~Context()
|
||||||
|
{
|
||||||
|
m_thread.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
MainThreadEntry m_mte;
|
||||||
|
bx::Thread m_thread;
|
||||||
|
void* m_window;
|
||||||
|
|
||||||
|
EventQueue m_eventQueue;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Context* s_ctx;
|
||||||
|
|
||||||
|
int32_t MainThreadEntry::threadFunc(bx::Thread* _thread, void* _userData)
|
||||||
|
{
|
||||||
|
BX_UNUSED(_thread);
|
||||||
|
|
||||||
|
if (_thread != NULL) {
|
||||||
|
_thread->setThreadName("Main Thread BGFX");
|
||||||
|
}
|
||||||
|
|
||||||
|
CFBundleRef mainBundle = CFBundleGetMainBundle();
|
||||||
|
if (mainBundle != nil)
|
||||||
|
{
|
||||||
|
CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
|
||||||
|
if (resourcesURL != nil)
|
||||||
|
{
|
||||||
|
char path[PATH_MAX];
|
||||||
|
if (CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8*)path, PATH_MAX) )
|
||||||
|
{
|
||||||
|
chdir(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(resourcesURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MainThreadEntry* self = (MainThreadEntry*)_userData;
|
||||||
|
int32_t result = main(self->m_argc, self->m_argv);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Event* poll()
|
||||||
|
{
|
||||||
|
return s_ctx->m_eventQueue.poll();
|
||||||
|
}
|
||||||
|
|
||||||
|
const Event* poll(WindowHandle _handle)
|
||||||
|
{
|
||||||
|
return s_ctx->m_eventQueue.poll(_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void release(const Event* _event)
|
||||||
|
{
|
||||||
|
s_ctx->m_eventQueue.release(_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowHandle createWindow(int32_t _x, int32_t _y, uint32_t _width, uint32_t _height, uint32_t _flags, const char* _title)
|
||||||
|
{
|
||||||
|
BX_UNUSED(_x, _y, _width, _height, _flags, _title);
|
||||||
|
WindowHandle handle = { UINT16_MAX };
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroyWindow(WindowHandle _handle)
|
||||||
|
{
|
||||||
|
BX_UNUSED(_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWindowPos(WindowHandle _handle, int32_t _x, int32_t _y)
|
||||||
|
{
|
||||||
|
BX_UNUSED(_handle, _x, _y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWindowSize(WindowHandle _handle, uint32_t _width, uint32_t _height)
|
||||||
|
{
|
||||||
|
BX_UNUSED(_handle, _width, _height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWindowTitle(WindowHandle _handle, const char* _title)
|
||||||
|
{
|
||||||
|
BX_UNUSED(_handle, _title);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWindowFlags(WindowHandle _handle, uint32_t _flags, bool _enabled)
|
||||||
|
{
|
||||||
|
BX_UNUSED(_handle, _flags, _enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void toggleFullscreen(WindowHandle _handle)
|
||||||
|
{
|
||||||
|
BX_UNUSED(_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMouseLock(WindowHandle _handle, bool _lock)
|
||||||
|
{
|
||||||
|
BX_UNUSED(_handle, _lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* getNativeWindowHandle(WindowHandle _handle)
|
||||||
|
{
|
||||||
|
if (kDefaultWindowHandle.idx == _handle.idx)
|
||||||
|
{
|
||||||
|
return s_ctx->m_window;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* getNativeDisplayHandle()
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bgfx::NativeWindowHandleType::Enum getNativeWindowHandleType()
|
||||||
|
{
|
||||||
|
return bgfx::NativeWindowHandleType::Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace entry
|
||||||
|
|
||||||
|
using namespace entry;
|
||||||
|
|
||||||
|
bool BgfxAdapter::initialize(void) {
|
||||||
|
if (!m_initialized) {
|
||||||
|
// Set context width and height to default visionOS resolution. It's different for the headset and device.
|
||||||
|
#if TARGET_OS_SIMULATOR
|
||||||
|
s_ctx = new Context(2732, 2048);
|
||||||
|
#else
|
||||||
|
s_ctx = new Context(1920, 1824);
|
||||||
|
#endif
|
||||||
|
s_ctx->m_window = m_layerRenderer;
|
||||||
|
m_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BgfxAdapter::shutdown(void) {
|
||||||
|
if (m_initialized) {
|
||||||
|
s_ctx->m_eventQueue.postExitEvent();
|
||||||
|
s_ctx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BgfxAdapter::render() {
|
||||||
|
if (!m_initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bgfx::renderFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BgfxAdapter::renderLoop() {
|
||||||
|
bool isRendering = true;
|
||||||
|
while (isRendering) {
|
||||||
|
switch (cp_layer_renderer_get_state(m_layerRenderer)) {
|
||||||
|
case cp_layer_renderer_state_paused:
|
||||||
|
cp_layer_renderer_wait_until_running(m_layerRenderer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case cp_layer_renderer_state_running:
|
||||||
|
this->initialize();
|
||||||
|
this->render();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case cp_layer_renderer_state_invalidated:
|
||||||
|
isRendering = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // BX_PLATFORM_VISIONOS
|
25
examples/common/entry/swift_adapter.h
Normal file
25
examples/common/entry/swift_adapter.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef SWIFT_ADAPTER_H_HEADER_GUARD
|
||||||
|
#define SWIFT_ADAPTER_H_HEADER_GUARD
|
||||||
|
|
||||||
|
#include <CompositorServices/CompositorServices.h>
|
||||||
|
|
||||||
|
class BgfxAdapter {
|
||||||
|
private:
|
||||||
|
bool m_initialized = false;
|
||||||
|
cp_layer_renderer_t m_layerRenderer = NULL;
|
||||||
|
void render(void);
|
||||||
|
|
||||||
|
public:
|
||||||
|
BgfxAdapter(cp_layer_renderer_t layerRenderer) : m_layerRenderer(layerRenderer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
~BgfxAdapter() {
|
||||||
|
shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool initialize(void);
|
||||||
|
void shutdown(void);
|
||||||
|
void renderLoop(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
33
examples/runtime/xros-info.plist
Normal file
33
examples/runtime/xros-info.plist
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>en</string>
|
||||||
|
<key>CFBundleDisplayName</key>
|
||||||
|
<string>Examples Debug</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>UIApplicationSceneManifest</key>
|
||||||
|
<dict>
|
||||||
|
<key>UIApplicationPreferredDefaultSceneSessionRole</key>
|
||||||
|
<string>CPSceneSessionRoleImmersiveSpaceApplication</string>
|
||||||
|
<key>UIApplicationSupportsMultipleScenes</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@ -95,6 +95,18 @@ project ("example-common")
|
|||||||
path.join(BGFX_DIR, "examples/common/**.mm"),
|
path.join(BGFX_DIR, "examples/common/**.mm"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configuration { "xros*" }
|
||||||
|
files {
|
||||||
|
path.join(BGFX_DIR, "examples/common/**.swift"),
|
||||||
|
path.join(BGFX_DIR, "examples/common/**.hpp"),
|
||||||
|
path.join(BGFX_DIR, "examples/common/**.modulemap"),
|
||||||
|
}
|
||||||
|
xcodeprojectopts {
|
||||||
|
SWIFT_VERSION = "5.0",
|
||||||
|
SWIFT_OBJC_BRIDGING_HEADER = path.join(BGFX_DIR, "examples/common/entry/swift_adapter.h"),
|
||||||
|
SWIFT_OBJC_INTEROP_MODE = "objcxx",
|
||||||
|
}
|
||||||
|
|
||||||
configuration { "winstore* or durango"}
|
configuration { "winstore* or durango"}
|
||||||
files {
|
files {
|
||||||
path.join(BGFX_DIR, "examples/common/**.cx"),
|
path.join(BGFX_DIR, "examples/common/**.cx"),
|
||||||
|
@ -408,8 +408,8 @@ function exampleProjectDefaults()
|
|||||||
"-weak_framework Metal",
|
"-weak_framework Metal",
|
||||||
}
|
}
|
||||||
|
|
||||||
configuration { "ios* or tvos*" }
|
configuration { "ios* or tvos* or xros*" }
|
||||||
kind "ConsoleApp"
|
kind "WindowedApp"
|
||||||
linkoptions {
|
linkoptions {
|
||||||
"-framework CoreFoundation",
|
"-framework CoreFoundation",
|
||||||
"-framework Foundation",
|
"-framework Foundation",
|
||||||
@ -419,6 +419,11 @@ function exampleProjectDefaults()
|
|||||||
"-framework UIKit",
|
"-framework UIKit",
|
||||||
"-weak_framework Metal",
|
"-weak_framework Metal",
|
||||||
}
|
}
|
||||||
|
xcodecopyresources {
|
||||||
|
{ "shaders/metal", {
|
||||||
|
os.matchfiles(path.join(BGFX_DIR, "examples/runtime/shaders/metal/**.bin"))
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
configuration { "xcode*", "ios" }
|
configuration { "xcode*", "ios" }
|
||||||
kind "WindowedApp"
|
kind "WindowedApp"
|
||||||
@ -432,6 +437,12 @@ function exampleProjectDefaults()
|
|||||||
path.join(BGFX_DIR, "examples/runtime/tvOS-Info.plist"),
|
path.join(BGFX_DIR, "examples/runtime/tvOS-Info.plist"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configuration { "xcode*", "xros" }
|
||||||
|
kind "WindowedApp"
|
||||||
|
files {
|
||||||
|
path.join(BGFX_DIR, "examples/runtime/xros-info.plist"),
|
||||||
|
}
|
||||||
|
|
||||||
configuration {}
|
configuration {}
|
||||||
|
|
||||||
strip()
|
strip()
|
||||||
|
Loading…
Reference in New Issue
Block a user