work on openxr controllers
This commit is contained in:
@@ -49,6 +49,7 @@ DECLARE_BUILD_STAGE(install_game)
|
|||||||
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "funnyassets/physics");
|
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "funnyassets/physics");
|
||||||
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "funnyassets/fonts");
|
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "funnyassets/fonts");
|
||||||
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "funnyassets/sounds");
|
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "funnyassets/sounds");
|
||||||
|
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "funnyassets/openxr");
|
||||||
filesystem2->CopyFile(CUtlString("%s/core/",szOutputDir.GetString()), "funnyassets/default.cfg");
|
filesystem2->CopyFile(CUtlString("%s/core/",szOutputDir.GetString()), "funnyassets/default.cfg");
|
||||||
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "build/funnygame/assets/shaders");
|
filesystem2->CopyDirectory(CUtlString("%s/core/",szOutputDir.GetString()), "build/funnygame/assets/shaders");
|
||||||
if (Target_t::DefaultTarget().kernel == TARGET_KERNEL_WINDOWS)
|
if (Target_t::DefaultTarget().kernel == TARGET_KERNEL_WINDOWS)
|
||||||
|
|||||||
@@ -9,6 +9,29 @@
|
|||||||
#include "tier0/lib.h"
|
#include "tier0/lib.h"
|
||||||
#include "tier1/utlvector.h"
|
#include "tier1/utlvector.h"
|
||||||
#include "materialsystem/imaterialsystem.h"
|
#include "materialsystem/imaterialsystem.h"
|
||||||
|
#include "tier1/utlstring.h"
|
||||||
|
#include "tier2/fileformats/json.h"
|
||||||
|
#include "tier2/ifilesystem.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static XrPath OpenXrGetPath( XrInstance i, const char *szString )
|
||||||
|
{
|
||||||
|
XrPath xrPath;
|
||||||
|
xrStringToPath(i, szString, &xrPath);
|
||||||
|
return xrPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CUtlString OpenXrGetString( XrInstance i, XrPath path )
|
||||||
|
{
|
||||||
|
uint32_t l;
|
||||||
|
char t[XR_MAX_PATH_LENGTH];
|
||||||
|
XrResult r = xrPathToString(i, path, XR_MAX_PATH_LENGTH, &l, t);
|
||||||
|
if (r)
|
||||||
|
return NULL;
|
||||||
|
return t;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
struct EyeSwapchain_t
|
struct EyeSwapchain_t
|
||||||
{
|
{
|
||||||
@@ -19,8 +42,37 @@ struct EyeSwapchain_t
|
|||||||
CUtlVector<IImage*> m_pImages;
|
CUtlVector<IImage*> m_pImages;
|
||||||
IImage *m_pUserImage;
|
IImage *m_pUserImage;
|
||||||
};
|
};
|
||||||
|
|
||||||
class COpenXRManager;
|
class COpenXRManager;
|
||||||
|
class COpenXRHeadset;
|
||||||
|
|
||||||
|
struct OpenXRAction
|
||||||
|
{
|
||||||
|
CUtlString m_szName;
|
||||||
|
XrAction m_action;
|
||||||
|
XrActionType m_eType;
|
||||||
|
XrSpace m_space;
|
||||||
|
};
|
||||||
|
|
||||||
|
class COpenXRController: public IXRController
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual EXRControllerType_t GetControllerType() override;
|
||||||
|
virtual EXRControllerSide_t GetControllerSide() override;
|
||||||
|
virtual IXRHeadset *GetHeadset() override;
|
||||||
|
virtual void SetInputCallback( XRInputCallbackFn fn ) override;
|
||||||
|
|
||||||
|
void Frame();
|
||||||
|
void ConfigureActionSets( const char *szDevice, const char *szProfile );
|
||||||
|
|
||||||
|
COpenXRHeadset *m_pHeadset;
|
||||||
|
EXRControllerType_t m_type;
|
||||||
|
EXRControllerSide_t m_side;
|
||||||
|
CUtlVector<OpenXRAction> m_actions;
|
||||||
|
XrActionSet m_actionSet;
|
||||||
|
|
||||||
|
XRInputCallbackFn m_callback = NULL;
|
||||||
|
};
|
||||||
|
|
||||||
class COpenXRHeadset: public IXRHeadset, public IAppSystem
|
class COpenXRHeadset: public IXRHeadset, public IAppSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -31,6 +83,9 @@ public:
|
|||||||
virtual XRRenderSurface_t GetSurface( uint32_t i ) override;
|
virtual XRRenderSurface_t GetSurface( uint32_t i ) override;
|
||||||
virtual void SetSurfaceImage( uint32_t i, IImage *pImage ) override;
|
virtual void SetSurfaceImage( uint32_t i, IImage *pImage ) override;
|
||||||
|
|
||||||
|
virtual uint32_t GetControllerCount() override;
|
||||||
|
virtual IXRController *GetController( uint32_t i ) override;
|
||||||
|
|
||||||
void Frame();
|
void Frame();
|
||||||
void BeforeRender();
|
void BeforeRender();
|
||||||
void AfterRender();
|
void AfterRender();
|
||||||
@@ -47,11 +102,15 @@ public:
|
|||||||
CUtlVector<XrView> m_views;
|
CUtlVector<XrView> m_views;
|
||||||
float m_fPredictedTime;
|
float m_fPredictedTime;
|
||||||
|
|
||||||
|
COpenXRController *m_pLeftHand;
|
||||||
|
COpenXRController *m_pRightHand;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class COpenXRController: public IXRController
|
enum EOpenXRAPI
|
||||||
{
|
{
|
||||||
|
OPENXR_API_VULKAN,
|
||||||
|
OPENXR_API_VULKAN2,
|
||||||
};
|
};
|
||||||
|
|
||||||
class COpenXRManager: public IXRManager
|
class COpenXRManager: public IXRManager
|
||||||
@@ -73,9 +132,191 @@ public:
|
|||||||
COpenXRHeadset m_headset;
|
COpenXRHeadset m_headset;
|
||||||
|
|
||||||
XrInstance m_instance;
|
XrInstance m_instance;
|
||||||
|
|
||||||
|
bool m_bIsDebugUtilsSupported = false;
|
||||||
|
bool m_bIsVulkanSupported = false;
|
||||||
|
bool m_bIsVulkan2Supported = false;
|
||||||
|
EOpenXRAPI m_gpuAPI;
|
||||||
|
|
||||||
};
|
};
|
||||||
EXPOSE_INTERFACE(COpenXRManager, IXRManager, OPEN_XR_INTERFACE_VERSION);
|
EXPOSE_INTERFACE(COpenXRManager, IXRManager, OPEN_XR_INTERFACE_VERSION);
|
||||||
|
|
||||||
|
EXRControllerType_t COpenXRController::GetControllerType()
|
||||||
|
{
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXRControllerSide_t COpenXRController::GetControllerSide()
|
||||||
|
{
|
||||||
|
return m_side;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
IXRHeadset *COpenXRController::GetHeadset()
|
||||||
|
{
|
||||||
|
return m_pHeadset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void COpenXRController::SetInputCallback( XRInputCallbackFn fn )
|
||||||
|
{
|
||||||
|
m_callback = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void COpenXRController::Frame()
|
||||||
|
{
|
||||||
|
for (auto &a: m_actions)
|
||||||
|
{
|
||||||
|
switch(a.m_eType)
|
||||||
|
{
|
||||||
|
|
||||||
|
case XR_ACTION_TYPE_BOOLEAN_INPUT:
|
||||||
|
{
|
||||||
|
XrActionStateGetInfo gi = {};
|
||||||
|
gi.type = XR_TYPE_ACTION_STATE_GET_INFO;
|
||||||
|
gi.action = a.m_action;
|
||||||
|
XrActionStateBoolean b = {};
|
||||||
|
b.type = XR_TYPE_ACTION_STATE_BOOLEAN;
|
||||||
|
xrGetActionStateBoolean(m_pHeadset->m_session, &gi, &b);
|
||||||
|
V_printf("%s %b\n", a.m_szName.GetString(), b.currentState);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XR_ACTION_TYPE_FLOAT_INPUT:
|
||||||
|
{
|
||||||
|
XrActionStateGetInfo gi = {};
|
||||||
|
gi.type = XR_TYPE_ACTION_STATE_GET_INFO;
|
||||||
|
gi.action = a.m_action;
|
||||||
|
XrActionStateFloat f32 = {};
|
||||||
|
f32.type = XR_TYPE_ACTION_STATE_FLOAT;
|
||||||
|
xrGetActionStateFloat(m_pHeadset->m_session, &gi, &f32);
|
||||||
|
V_printf("%s %f\n", a.m_szName.GetString(), f32.currentState);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XR_ACTION_TYPE_POSE_INPUT:
|
||||||
|
{
|
||||||
|
XrActionStateGetInfo gi = {};
|
||||||
|
gi.type = XR_TYPE_ACTION_STATE_GET_INFO;
|
||||||
|
gi.action = a.m_action;
|
||||||
|
XrActionStatePose pose = {};
|
||||||
|
pose.type = XR_TYPE_ACTION_STATE_POSE;
|
||||||
|
|
||||||
|
xrGetActionStatePose(m_pHeadset->m_session, &gi, &pose);
|
||||||
|
if (pose.isActive)
|
||||||
|
{
|
||||||
|
XrSpaceLocation s = {};
|
||||||
|
s.type = XR_TYPE_SPACE_LOCATION;
|
||||||
|
xrLocateSpace(a.m_space, m_pHeadset->m_space, m_pHeadset->m_fPredictedTime, &s);
|
||||||
|
EXRInputValue_t v;
|
||||||
|
v.type = k_EXRValue_Pose;
|
||||||
|
v.pose.pos = {s.pose.position.x, s.pose.position.y, s.pose.position.z};
|
||||||
|
if (m_callback)
|
||||||
|
m_callback( this, k_EXRInput_Grip, NULL, k_EXRInputAction_Pose, v );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void COpenXRController::ConfigureActionSets( const char *szDevice, const char *szProfile )
|
||||||
|
{
|
||||||
|
XrActionSetCreateInfo setci = {};
|
||||||
|
setci.type = XR_TYPE_ACTION_SET_CREATE_INFO;
|
||||||
|
strcpy(setci.actionSetName, "funny");
|
||||||
|
strcpy(setci.localizedActionSetName, "funny");
|
||||||
|
xrCreateActionSet(m_pHeadset->m_pManager->m_instance, &setci, &m_actionSet);
|
||||||
|
|
||||||
|
XrSessionActionSetsAttachInfo attachi = {};
|
||||||
|
attachi.type = XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO;
|
||||||
|
attachi.actionSets = &m_actionSet;
|
||||||
|
attachi.countActionSets = 1;
|
||||||
|
xrAttachSessionActionSets(m_pHeadset->m_session, &attachi);
|
||||||
|
|
||||||
|
CUtlString szPath = CUtlString("game/core/openxr%s.json", szProfile);
|
||||||
|
IFileHandle *pHandle = filesystem->Open(szPath, FILEMODE_READ);
|
||||||
|
const char *sz = filesystem->ReadString(pHandle);
|
||||||
|
IJSONValue *pVal = JSONManager()->ReadString(sz);
|
||||||
|
IJSONValue *pDevice = (*pVal)[szDevice];
|
||||||
|
IJSONValue *pInputs = (*pDevice)["inputs"];
|
||||||
|
if (!pInputs)
|
||||||
|
return;
|
||||||
|
for (uint32_t i = 0; i < pInputs->GetArray()->GetCount(); i++ )
|
||||||
|
{
|
||||||
|
IJSONValue *pInput = (*pInputs)[i];
|
||||||
|
CUtlString szInputName = (*pInput)["name"]->GetStringValue();
|
||||||
|
|
||||||
|
IJSONValue *pActions = (*pInput)["actions"];
|
||||||
|
for (uint32_t y = 0; y < pActions->GetArray()->GetCount(); y++ )
|
||||||
|
{
|
||||||
|
IJSONValue *pAction = (*pActions)[y];
|
||||||
|
CUtlString szType = pAction->GetStringValue();
|
||||||
|
XrActionType eType = XR_ACTION_TYPE_MAX_ENUM;
|
||||||
|
if (szType == "click")
|
||||||
|
eType = XR_ACTION_TYPE_BOOLEAN_INPUT;
|
||||||
|
if (szType == "touch")
|
||||||
|
eType = XR_ACTION_TYPE_BOOLEAN_INPUT;
|
||||||
|
if (szType == "force")
|
||||||
|
eType = XR_ACTION_TYPE_FLOAT_INPUT;
|
||||||
|
if (szType == "value")
|
||||||
|
eType = XR_ACTION_TYPE_FLOAT_INPUT;
|
||||||
|
if (szType == "x")
|
||||||
|
eType = XR_ACTION_TYPE_FLOAT_INPUT;
|
||||||
|
if (szType == "y")
|
||||||
|
eType = XR_ACTION_TYPE_FLOAT_INPUT;
|
||||||
|
if (szType == "twist")
|
||||||
|
eType = XR_ACTION_TYPE_FLOAT_INPUT;
|
||||||
|
if (szType == "pose")
|
||||||
|
eType = XR_ACTION_TYPE_POSE_INPUT;
|
||||||
|
|
||||||
|
XrAction a = XR_NULL_HANDLE;
|
||||||
|
XrActionCreateInfo aci = {};
|
||||||
|
aci.type = XR_TYPE_ACTION_CREATE_INFO;
|
||||||
|
aci.actionType = eType;
|
||||||
|
CUtlString szName = CUtlString("%s/input/%s/%s", szDevice, szInputName.GetString(), szType.GetString());
|
||||||
|
V_strncpy(aci.actionName, szName.GetString(), XR_MAX_ACTION_NAME_SIZE);
|
||||||
|
V_strncpy(aci.localizedActionName, szName.GetString(), XR_MAX_LOCALIZED_ACTION_NAME_SIZE);
|
||||||
|
XrResult r = xrCreateAction(m_actionSet, &aci, &a);
|
||||||
|
|
||||||
|
OpenXRAction action = {};
|
||||||
|
action.m_szName = szName;
|
||||||
|
action.m_action = a;
|
||||||
|
action.m_eType = eType;
|
||||||
|
if (eType == XR_ACTION_TYPE_POSE_INPUT)
|
||||||
|
{
|
||||||
|
XrActionSpaceCreateInfo asci = {};
|
||||||
|
asci.type = XR_TYPE_ACTION_SPACE_CREATE_INFO;
|
||||||
|
asci.poseInActionSpace = {{0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}};
|
||||||
|
asci.action = a;
|
||||||
|
XrResult r = xrCreateActionSpace(m_pHeadset->m_session, &asci, &action.m_space);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_actions.AppendTail(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CUtlVector<XrActionSuggestedBinding> suggestions = {};
|
||||||
|
suggestions.Reserve(m_actions.GetSize());
|
||||||
|
for ( auto &a: m_actions )
|
||||||
|
{
|
||||||
|
suggestions.AppendTail({a.m_action, OpenXrGetPath(m_pHeadset->m_pManager->m_instance, a.m_szName)});
|
||||||
|
}
|
||||||
|
|
||||||
|
XrInteractionProfileSuggestedBinding binding = {};
|
||||||
|
binding.type = XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING;
|
||||||
|
binding.interactionProfile = OpenXrGetPath(m_pHeadset->m_pManager->m_instance, szProfile);
|
||||||
|
binding.countSuggestedBindings = suggestions.GetSize();
|
||||||
|
binding.suggestedBindings = suggestions.GetData();
|
||||||
|
xrSuggestInteractionProfileBindings(m_pHeadset->m_pManager->m_instance, &binding);
|
||||||
|
JSONManager()->FreeValue(pVal);
|
||||||
|
V_free((void*)sz);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void COpenXRManager::Init()
|
void COpenXRManager::Init()
|
||||||
{
|
{
|
||||||
PFN_xrInitializeLoaderKHR fnInitLoader = NULL;
|
PFN_xrInitializeLoaderKHR fnInitLoader = NULL;
|
||||||
@@ -85,27 +326,66 @@ void COpenXRManager::Init()
|
|||||||
V_printf("Failed to load OpenXR, we are not running OpenXR\n");
|
V_printf("Failed to load OpenXR, we are not running OpenXR\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
XrApplicationInfo appInfo = {};
|
|
||||||
appInfo.apiVersion = XR_API_VERSION_1_1;
|
uint32_t nInstanceExtension = 0;
|
||||||
V_strncpy(appInfo.applicationName, "funny", XR_MAX_APPLICATION_NAME_SIZE);
|
xrEnumerateInstanceExtensionProperties(NULL, 0, &nInstanceExtension, NULL);
|
||||||
V_strncpy(appInfo.engineName, "funny", XR_MAX_ENGINE_NAME_SIZE);
|
CUtlVector<XrExtensionProperties> availableExts(nInstanceExtension);
|
||||||
if (r != XR_SUCCESS)
|
for (auto &e: availableExts)
|
||||||
Plat_FatalErrorFunc("Failed to load OpenXR\n");
|
e.type = XR_TYPE_EXTENSION_PROPERTIES;
|
||||||
const char *extensions[] = {
|
xrEnumerateInstanceExtensionProperties(NULL, nInstanceExtension, &nInstanceExtension, availableExts.GetData());
|
||||||
XR_EXT_DEBUG_UTILS_EXTENSION_NAME,
|
|
||||||
XR_KHR_VULKAN_ENABLE_EXTENSION_NAME,
|
CUtlVector<const char *> extensions = {};
|
||||||
};
|
for ( auto &e: availableExts )
|
||||||
|
{
|
||||||
|
if (!V_strncmp(XR_EXT_DEBUG_UTILS_EXTENSION_NAME, e.extensionName, XR_MAX_EXTENSION_NAME_SIZE))
|
||||||
|
{
|
||||||
|
extensions.AppendTail(XR_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||||
|
m_bIsDebugUtilsSupported = false;
|
||||||
|
}
|
||||||
|
if (!V_strncmp(XR_KHR_VULKAN_ENABLE_EXTENSION_NAME, e.extensionName, XR_MAX_EXTENSION_NAME_SIZE))
|
||||||
|
{
|
||||||
|
extensions.AppendTail(XR_KHR_VULKAN_ENABLE_EXTENSION_NAME);
|
||||||
|
m_bIsVulkanSupported = true;
|
||||||
|
}
|
||||||
|
if (!V_strncmp(XR_KHR_VULKAN_ENABLE2_EXTENSION_NAME, e.extensionName, XR_MAX_EXTENSION_NAME_SIZE))
|
||||||
|
{
|
||||||
|
extensions.AppendTail(XR_KHR_VULKAN_ENABLE2_EXTENSION_NAME);
|
||||||
|
m_bIsVulkan2Supported = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_pRenderContext->GetVulkanInstance() != NULL)
|
||||||
|
{
|
||||||
|
if (m_bIsVulkan2Supported) {
|
||||||
|
if (m_bIsVulkanSupported)
|
||||||
|
m_gpuAPI = OPENXR_API_VULKAN;
|
||||||
|
else
|
||||||
|
m_gpuAPI = OPENXR_API_VULKAN2;
|
||||||
|
}
|
||||||
|
if (m_bIsVulkanSupported)
|
||||||
|
{
|
||||||
|
m_gpuAPI = OPENXR_API_VULKAN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto &e: extensions)
|
||||||
|
V_printf("%s\n", e);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char *layers[] = {
|
const char *layers[] = {
|
||||||
"XR_APILAYER_LUNARG_core_validation"
|
"XR_APILAYER_LUNARG_core_validation"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
XrApplicationInfo appInfo = {};
|
||||||
|
appInfo.apiVersion = XR_API_VERSION_1_1;
|
||||||
|
V_strncpy(appInfo.applicationName, "funny", XR_MAX_APPLICATION_NAME_SIZE);
|
||||||
|
V_strncpy(appInfo.engineName, "funny", XR_MAX_ENGINE_NAME_SIZE);
|
||||||
|
|
||||||
XrInstanceCreateInfo createInfo = {};
|
XrInstanceCreateInfo createInfo = {};
|
||||||
createInfo.type = XR_TYPE_INSTANCE_CREATE_INFO;
|
createInfo.type = XR_TYPE_INSTANCE_CREATE_INFO;
|
||||||
createInfo.applicationInfo = appInfo;
|
createInfo.applicationInfo = appInfo;
|
||||||
createInfo.enabledExtensionCount = sizeof(extensions)/sizeof(*extensions);
|
createInfo.enabledExtensionCount = extensions.GetSize();
|
||||||
createInfo.enabledExtensionNames = extensions;
|
createInfo.enabledExtensionNames = extensions.GetData();
|
||||||
createInfo.enabledApiLayerCount = sizeof(layers)/sizeof(*layers);
|
createInfo.enabledApiLayerCount = sizeof(layers)/sizeof(*layers);
|
||||||
createInfo.enabledApiLayerNames = layers;
|
createInfo.enabledApiLayerNames = layers;
|
||||||
r = xrCreateInstance(&createInfo, &m_instance);
|
r = xrCreateInstance(&createInfo, &m_instance);
|
||||||
@@ -127,6 +407,7 @@ void COpenXRManager::Init()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void COpenXRManager::Shutdown()
|
void COpenXRManager::Shutdown()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -155,6 +436,15 @@ void COpenXRManager::CopySwapchain()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct OpenXRProfile_t {
|
||||||
|
const char *m_szName;
|
||||||
|
EXRControllerType_t m_eType;
|
||||||
|
};
|
||||||
|
|
||||||
|
const static CUtlVector<OpenXRProfile_t> s_interactionProfiles = {
|
||||||
|
{"/interaction_profiles/khr/simple_controller", k_EXR_HandController},
|
||||||
|
{"/interaction_profiles/oculus/touch_controller", k_EXR_HandController},
|
||||||
|
};
|
||||||
|
|
||||||
void COpenXRHeadset::Init()
|
void COpenXRHeadset::Init()
|
||||||
{
|
{
|
||||||
@@ -167,36 +457,85 @@ void COpenXRHeadset::Init()
|
|||||||
if (r != XR_SUCCESS)
|
if (r != XR_SUCCESS)
|
||||||
Plat_FatalErrorFunc("xrGetSystem\n");
|
Plat_FatalErrorFunc("xrGetSystem\n");
|
||||||
|
|
||||||
|
/* each backend requires its own shit */
|
||||||
|
|
||||||
XrGraphicsRequirementsVulkanKHR requirements = {};
|
switch (m_pManager->m_gpuAPI)
|
||||||
requirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR;
|
{
|
||||||
PFN_xrGetVulkanGraphicsRequirementsKHR fnVulkanRequirements = NULL;
|
case OPENXR_API_VULKAN:
|
||||||
xrGetInstanceProcAddr(m_pManager->m_instance, "xrGetVulkanGraphicsRequirementsKHR", (PFN_xrVoidFunction*)&fnVulkanRequirements);
|
{
|
||||||
if (r != XR_SUCCESS)
|
XrGraphicsRequirementsVulkanKHR requirements = {};
|
||||||
Plat_FatalErrorFunc("Failed to get xrGetVulkanGraphicsRequirementsKHR\n");
|
requirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR;
|
||||||
fnVulkanRequirements( m_pManager->m_instance, m_systemId, &requirements);
|
PFN_xrGetVulkanGraphicsRequirementsKHR fnVulkanRequirements = NULL;
|
||||||
|
xrGetInstanceProcAddr(m_pManager->m_instance, "xrGetVulkanGraphicsRequirementsKHR", (PFN_xrVoidFunction*)&fnVulkanRequirements);
|
||||||
|
if (r != XR_SUCCESS)
|
||||||
|
Plat_FatalErrorFunc("Failed to get xrGetVulkanGraphicsRequirementsKHR\n");
|
||||||
|
fnVulkanRequirements( m_pManager->m_instance, m_systemId, &requirements);
|
||||||
|
|
||||||
|
|
||||||
PFN_xrGetVulkanGraphicsDeviceKHR fnVulkanDevice = NULL;
|
PFN_xrGetVulkanGraphicsDeviceKHR fnVulkanDevice = NULL;
|
||||||
xrGetInstanceProcAddr(m_pManager->m_instance, "xrGetVulkanGraphicsDeviceKHR", (PFN_xrVoidFunction*)&fnVulkanDevice);
|
xrGetInstanceProcAddr(m_pManager->m_instance, "xrGetVulkanGraphicsDeviceKHR", (PFN_xrVoidFunction*)&fnVulkanDevice);
|
||||||
if (r != XR_SUCCESS)
|
if (r != XR_SUCCESS)
|
||||||
Plat_FatalErrorFunc("Failed to get xrGetVulkanGraphicsDeviceKHR\n");
|
Plat_FatalErrorFunc("Failed to get xrGetVulkanGraphicsDeviceKHR\n");
|
||||||
VkPhysicalDevice d = NULL;
|
VkPhysicalDevice d = NULL;
|
||||||
fnVulkanDevice(m_pManager->m_instance, m_systemId, (VkInstance)m_pManager->m_pRenderContext->GetVulkanInstance(), &d);
|
fnVulkanDevice(m_pManager->m_instance, m_systemId, (VkInstance)m_pManager->m_pRenderContext->GetVulkanInstance(), &d);
|
||||||
|
|
||||||
XrGraphicsBindingVulkan2KHR vkBinding = {};
|
XrGraphicsBindingVulkan2KHR vkBinding = {};
|
||||||
vkBinding.type = XR_TYPE_GRAPHICS_BINDING_VULKAN2_KHR;
|
vkBinding.type = XR_TYPE_GRAPHICS_BINDING_VULKAN2_KHR;
|
||||||
vkBinding.instance = (VkInstance)m_pManager->m_pRenderContext->GetVulkanInstance();
|
vkBinding.instance = (VkInstance)m_pManager->m_pRenderContext->GetVulkanInstance();
|
||||||
vkBinding.physicalDevice = (VkPhysicalDevice)m_pManager->m_pRenderContext->GetVulkanPhysicalDevice();
|
vkBinding.physicalDevice = (VkPhysicalDevice)m_pManager->m_pRenderContext->GetVulkanPhysicalDevice();
|
||||||
vkBinding.device = (VkDevice)m_pManager->m_pRenderContext->GetVulkanDevice();
|
vkBinding.device = (VkDevice)m_pManager->m_pRenderContext->GetVulkanDevice();
|
||||||
|
|
||||||
|
XrSessionCreateInfo sessionCreateInfo = {};
|
||||||
|
sessionCreateInfo.type = XR_TYPE_SESSION_CREATE_INFO;
|
||||||
|
sessionCreateInfo.next = &vkBinding;
|
||||||
|
sessionCreateInfo.systemId = m_systemId;
|
||||||
|
r = xrCreateSession(m_pManager->m_instance, &sessionCreateInfo, &m_session);
|
||||||
|
if (r != XR_SUCCESS)
|
||||||
|
Plat_FatalErrorFunc("xrCreateSession\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPENXR_API_VULKAN2:
|
||||||
|
{
|
||||||
|
XrGraphicsRequirementsVulkanKHR requirements = {};
|
||||||
|
requirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR;
|
||||||
|
PFN_xrGetVulkanGraphicsRequirements2KHR fnVulkanRequirements = NULL;
|
||||||
|
xrGetInstanceProcAddr(m_pManager->m_instance, "xrGetVulkanGraphicsRequirements2KHR", (PFN_xrVoidFunction*)&fnVulkanRequirements);
|
||||||
|
if (r != XR_SUCCESS)
|
||||||
|
Plat_FatalErrorFunc("Failed to get xrGetVulkanGraphicsRequirements2KHR\n");
|
||||||
|
fnVulkanRequirements( m_pManager->m_instance, m_systemId, &requirements);
|
||||||
|
|
||||||
|
|
||||||
|
PFN_xrGetVulkanGraphicsDevice2KHR fnVulkanDevice = NULL;
|
||||||
|
xrGetInstanceProcAddr(m_pManager->m_instance, "xrGetVulkanGraphicsDevice2KHR", (PFN_xrVoidFunction*)&fnVulkanDevice);
|
||||||
|
if (r != XR_SUCCESS)
|
||||||
|
Plat_FatalErrorFunc("Failed to get xrGetVulkanGraphicsDevice2KHR\n");
|
||||||
|
VkPhysicalDevice d = NULL;
|
||||||
|
XrVulkanGraphicsDeviceGetInfoKHR dgi = {};
|
||||||
|
dgi.type = XR_TYPE_VULKAN_GRAPHICS_DEVICE_GET_INFO_KHR;
|
||||||
|
dgi.systemId = m_systemId;
|
||||||
|
dgi.vulkanInstance = (VkInstance)m_pManager->m_pRenderContext->GetVulkanInstance();
|
||||||
|
fnVulkanDevice(m_pManager->m_instance, &dgi, &d);
|
||||||
|
|
||||||
|
XrGraphicsBindingVulkan2KHR vkBinding = {};
|
||||||
|
vkBinding.type = XR_TYPE_GRAPHICS_BINDING_VULKAN2_KHR;
|
||||||
|
vkBinding.instance = (VkInstance)m_pManager->m_pRenderContext->GetVulkanInstance();
|
||||||
|
vkBinding.physicalDevice = (VkPhysicalDevice)m_pManager->m_pRenderContext->GetVulkanPhysicalDevice();
|
||||||
|
vkBinding.device = (VkDevice)m_pManager->m_pRenderContext->GetVulkanDevice();
|
||||||
|
|
||||||
|
XrSessionCreateInfo sessionCreateInfo = {};
|
||||||
|
sessionCreateInfo.type = XR_TYPE_SESSION_CREATE_INFO;
|
||||||
|
sessionCreateInfo.next = &vkBinding;
|
||||||
|
sessionCreateInfo.systemId = m_systemId;
|
||||||
|
r = xrCreateSession(m_pManager->m_instance, &sessionCreateInfo, &m_session);
|
||||||
|
if (r != XR_SUCCESS)
|
||||||
|
Plat_FatalErrorFunc("xrCreateSession\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
XrSessionCreateInfo sessionCreateInfo = {};
|
|
||||||
sessionCreateInfo.type = XR_TYPE_SESSION_CREATE_INFO;
|
|
||||||
sessionCreateInfo.next = &vkBinding;
|
|
||||||
sessionCreateInfo.systemId = m_systemId;
|
|
||||||
r = xrCreateSession(m_pManager->m_instance, &sessionCreateInfo, &m_session);
|
|
||||||
if (r != XR_SUCCESS)
|
|
||||||
Plat_FatalErrorFunc("xrCreateSession\n");
|
|
||||||
|
|
||||||
/* create swapchains for rendering pipeline */
|
/* create swapchains for rendering pipeline */
|
||||||
|
|
||||||
@@ -215,7 +554,6 @@ void COpenXRHeadset::Init()
|
|||||||
VkFormat eSelectedFormat = preferedSurfaceFormats[0];
|
VkFormat eSelectedFormat = preferedSurfaceFormats[0];
|
||||||
for (auto &format: formats)
|
for (auto &format: formats)
|
||||||
{
|
{
|
||||||
V_printf("Format: %s\n", string_VkFormat((VkFormat)format));
|
|
||||||
for (int i = 0; i < sizeof(preferedSurfaceFormats)/sizeof(VkFormat); i++)
|
for (int i = 0; i < sizeof(preferedSurfaceFormats)/sizeof(VkFormat); i++)
|
||||||
{
|
{
|
||||||
if (format == preferedSurfaceFormats[i])
|
if (format == preferedSurfaceFormats[i])
|
||||||
@@ -271,6 +609,77 @@ formatPicked:
|
|||||||
uint32_t vc = m_views.GetSize();
|
uint32_t vc = m_views.GetSize();
|
||||||
xrLocateViews(m_session, &viewLocale, &viewState, vc, &vc, m_views.GetData());
|
xrLocateViews(m_session, &viewLocale, &viewState, vc, &vc, m_views.GetData());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (auto &p: s_interactionProfiles) {
|
||||||
|
/* load profile */
|
||||||
|
|
||||||
|
XrInteractionProfileSuggestedBinding bindings = {};
|
||||||
|
bindings.type = XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING;
|
||||||
|
bindings.interactionProfile = OpenXrGetPath(m_pManager->m_instance, p.m_szName);
|
||||||
|
xrSuggestInteractionProfileBindings(m_pManager->m_instance, &bindings);
|
||||||
|
}
|
||||||
|
|
||||||
|
CUtlVector<const char*> possibleControllers = {
|
||||||
|
"/user/hand/left",
|
||||||
|
"/user/hand/right",
|
||||||
|
};
|
||||||
|
|
||||||
|
XrActionSet quetySet = {};
|
||||||
|
XrActionSetCreateInfo setci = {};
|
||||||
|
setci.type = XR_TYPE_ACTION_SET_CREATE_INFO;
|
||||||
|
strcpy(setci.actionSetName, "funny");
|
||||||
|
strcpy(setci.localizedActionSetName, "funny");
|
||||||
|
xrCreateActionSet(m_pManager->m_instance, &setci, &quetySet);
|
||||||
|
XrSessionActionSetsAttachInfo attachi = {};
|
||||||
|
attachi.type = XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO;
|
||||||
|
attachi.actionSets = &quetySet;
|
||||||
|
attachi.countActionSets = 1;
|
||||||
|
xrAttachSessionActionSets(m_session, &attachi);
|
||||||
|
|
||||||
|
for ( auto &c: possibleControllers )
|
||||||
|
{
|
||||||
|
XrPath path = OpenXrGetPath(m_pManager->m_instance, c);
|
||||||
|
XrInteractionProfileState profile = {};
|
||||||
|
profile.type = XR_TYPE_INTERACTION_PROFILE_STATE;
|
||||||
|
XrResult r = xrGetCurrentInteractionProfile(m_session, path, &profile);
|
||||||
|
if (r)
|
||||||
|
{
|
||||||
|
V_printf("Controller not found: %s %i\n", c, r);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (profile.interactionProfile == XR_NULL_PATH)
|
||||||
|
continue;
|
||||||
|
CUtlString s = OpenXrGetString(m_pManager->m_instance, profile.interactionProfile);
|
||||||
|
if (!V_strcmp(c, "/user/hand/left"))
|
||||||
|
{
|
||||||
|
m_pLeftHand = new COpenXRController;
|
||||||
|
m_pLeftHand->m_side = k_EXRController_Left;
|
||||||
|
m_pLeftHand->m_pHeadset = this;
|
||||||
|
for ( auto &p: s_interactionProfiles )
|
||||||
|
if (s == p.m_szName)
|
||||||
|
{
|
||||||
|
m_pLeftHand->m_type = p.m_eType;
|
||||||
|
m_pLeftHand->ConfigureActionSets(c, p.m_szName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!V_strcmp(c, "/user/hand/right"))
|
||||||
|
{
|
||||||
|
m_pRightHand = new COpenXRController;
|
||||||
|
m_pRightHand->m_side = k_EXRController_Left;
|
||||||
|
m_pRightHand->m_pHeadset = this;
|
||||||
|
for ( auto &p: s_interactionProfiles )
|
||||||
|
if (s == p.m_szName)
|
||||||
|
{
|
||||||
|
m_pRightHand->m_type = p.m_eType;
|
||||||
|
m_pRightHand->ConfigureActionSets(c, p.m_szName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xrDestroyActionSet(quetySet);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
void COpenXRHeadset::Shutdown()
|
void COpenXRHeadset::Shutdown()
|
||||||
{
|
{
|
||||||
@@ -319,6 +728,16 @@ void COpenXRHeadset::Frame()
|
|||||||
m_fPredictedTime = frameState.predictedDisplayTime;
|
m_fPredictedTime = frameState.predictedDisplayTime;
|
||||||
|
|
||||||
|
|
||||||
|
XrActiveActionSet aas[2] = {};
|
||||||
|
aas[0].actionSet = m_pLeftHand->m_actionSet;
|
||||||
|
aas[1].actionSet = m_pRightHand->m_actionSet;
|
||||||
|
|
||||||
|
XrActionsSyncInfo si = {};
|
||||||
|
si.type = XR_TYPE_ACTIONS_SYNC_INFO;
|
||||||
|
si.activeActionSets = aas;
|
||||||
|
si.countActiveActionSets = 2;
|
||||||
|
xrSyncActions(m_session, &si);
|
||||||
|
|
||||||
m_views = m_eyeSwapchains.GetSize();
|
m_views = m_eyeSwapchains.GetSize();
|
||||||
m_projviews = m_eyeSwapchains.GetSize();
|
m_projviews = m_eyeSwapchains.GetSize();
|
||||||
for ( auto &v: m_views )
|
for ( auto &v: m_views )
|
||||||
@@ -341,6 +760,11 @@ void COpenXRHeadset::Frame()
|
|||||||
viewLocale.viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
|
viewLocale.viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
|
||||||
uint32_t viewCount = m_views.GetSize();
|
uint32_t viewCount = m_views.GetSize();
|
||||||
xrLocateViews(m_session, &viewLocale, &viewState, viewCount, &viewCount, m_views.GetData());
|
xrLocateViews(m_session, &viewLocale, &viewState, viewCount, &viewCount, m_views.GetData());
|
||||||
|
|
||||||
|
if (m_pLeftHand)
|
||||||
|
m_pLeftHand->Frame();
|
||||||
|
if (m_pRightHand)
|
||||||
|
m_pRightHand->Frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
void COpenXRHeadset::BeforeRender()
|
void COpenXRHeadset::BeforeRender()
|
||||||
@@ -381,7 +805,8 @@ void COpenXRHeadset::CopySwapchain()
|
|||||||
ImageSector_t sector = {};
|
ImageSector_t sector = {};
|
||||||
sector.m_iWidth = eye.m_uWidth;
|
sector.m_iWidth = eye.m_uWidth;
|
||||||
sector.m_iHeight = eye.m_uHeight;
|
sector.m_iHeight = eye.m_uHeight;
|
||||||
pList->BlitImageToImage(eye.m_pUserImage, sector, eye.m_pImages[eye.m_uImageIndex], sector);
|
if (eye.m_pUserImage)
|
||||||
|
pList->BlitImageToImage(eye.m_pUserImage, sector, eye.m_pImages[eye.m_uImageIndex], sector);
|
||||||
}
|
}
|
||||||
pList->EndRecording();
|
pList->EndRecording();
|
||||||
pCtx->SubmitCommandList(pList);
|
pCtx->SubmitCommandList(pList);
|
||||||
@@ -417,25 +842,51 @@ void COpenXRHeadset::AfterRender()
|
|||||||
|
|
||||||
uint32_t COpenXRHeadset::GetSurfaceCount()
|
uint32_t COpenXRHeadset::GetSurfaceCount()
|
||||||
{
|
{
|
||||||
V_printf("%i\n", m_eyeSwapchains.GetSize());
|
|
||||||
return m_eyeSwapchains.GetSize();
|
return m_eyeSwapchains.GetSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
XRRenderSurface_t COpenXRHeadset::GetSurface( uint32_t i )
|
XRRenderSurface_t COpenXRHeadset::GetSurface( uint32_t i )
|
||||||
{
|
{
|
||||||
XRRenderSurface_t surface = {};
|
XRRenderSurface_t surface = {};
|
||||||
surface.m_fFov = m_projviews[i].fov.angleLeft+m_projviews[i].fov.angleRight;
|
surface.m_fFov = m_views[i].fov.angleLeft-m_views[i].fov.angleRight;
|
||||||
surface.m_uWidth = m_eyeSwapchains[i].m_uWidth;
|
surface.m_uWidth = m_eyeSwapchains[i].m_uWidth;
|
||||||
surface.m_uHeight = m_eyeSwapchains[i].m_uHeight;
|
surface.m_uHeight = m_eyeSwapchains[i].m_uHeight;
|
||||||
|
|
||||||
|
surface.m_vPosition = (Vector){
|
||||||
|
m_views[i].pose.position.x,
|
||||||
|
m_views[i].pose.position.y,
|
||||||
|
m_views[i].pose.position.z
|
||||||
|
};
|
||||||
|
|
||||||
|
surface.m_vRotation = (Quat){
|
||||||
|
m_views[i].pose.orientation.x,
|
||||||
|
m_views[i].pose.orientation.y,
|
||||||
|
m_views[i].pose.orientation.z,
|
||||||
|
m_views[i].pose.orientation.w,
|
||||||
|
};
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
void COpenXRHeadset::SetSurfaceImage( uint32_t i, IImage *pImage )
|
void COpenXRHeadset::SetSurfaceImage( uint32_t i, IImage *pImage )
|
||||||
{
|
{
|
||||||
m_eyeSwapchains[i].m_pUserImage = pImage;
|
m_eyeSwapchains[i].m_pUserImage = pImage;
|
||||||
|
V_printf("%p\n", pImage);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t COpenXRHeadset::GetControllerCount()
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
IXRController *COpenXRHeadset::GetController( uint32_t i )
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
return m_pLeftHand;
|
||||||
|
if (i == 1)
|
||||||
|
return m_pRightHand;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void COpenXRHeadset::CreateSwapchainForEye( XrViewConfigurationView *pConf, VkFormat eVkFormat, EyeSwapchain_t *pEye )
|
void COpenXRHeadset::CreateSwapchainForEye( XrViewConfigurationView *pConf, VkFormat eVkFormat, EyeSwapchain_t *pEye )
|
||||||
{
|
{
|
||||||
XrSwapchainCreateInfo createInfo = {};
|
XrSwapchainCreateInfo createInfo = {};
|
||||||
@@ -456,17 +907,39 @@ void COpenXRHeadset::CreateSwapchainForEye( XrViewConfigurationView *pConf, VkFo
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t imageCount = 0;
|
uint32_t imageCount = 0;
|
||||||
xrEnumerateSwapchainImages(pEye->m_swapchain, 0, &imageCount, NULL);
|
CUtlVector<XrSwapchainImageVulkanKHR> images;
|
||||||
CUtlVector<XrSwapchainImageVulkan2KHR> images = imageCount;
|
|
||||||
for ( auto &i: images )
|
switch (m_pManager->m_gpuAPI)
|
||||||
{
|
{
|
||||||
i.type = XR_TYPE_SWAPCHAIN_IMAGE_VULKAN2_KHR;
|
case OPENXR_API_VULKAN:
|
||||||
|
{
|
||||||
|
xrEnumerateSwapchainImages(pEye->m_swapchain, 0, &imageCount, NULL);
|
||||||
|
images = imageCount;
|
||||||
|
pEye->m_pImages = imageCount;
|
||||||
|
for ( auto &i: images )
|
||||||
|
{
|
||||||
|
i.type = XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR;
|
||||||
|
}
|
||||||
|
xrEnumerateSwapchainImages(pEye->m_swapchain, imageCount, &imageCount, (XrSwapchainImageBaseHeader*)images.GetData());
|
||||||
|
pEye->m_pImages = imageCount;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OPENXR_API_VULKAN2:
|
||||||
|
{
|
||||||
|
xrEnumerateSwapchainImages(pEye->m_swapchain, 0, &imageCount, NULL);
|
||||||
|
images = imageCount;
|
||||||
|
pEye->m_pImages = imageCount;
|
||||||
|
for ( auto &i: images )
|
||||||
|
{
|
||||||
|
i.type = XR_TYPE_SWAPCHAIN_IMAGE_VULKAN2_KHR;
|
||||||
|
}
|
||||||
|
xrEnumerateSwapchainImages(pEye->m_swapchain, imageCount, &imageCount, (XrSwapchainImageBaseHeader*)images.GetData());
|
||||||
|
for ( auto &i: images )
|
||||||
|
V_printf("VkImage %p\n", i.image);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
xrEnumerateSwapchainImages(pEye->m_swapchain, imageCount, &imageCount, (XrSwapchainImageBaseHeader*)images.GetData());
|
|
||||||
pEye->m_pImages = imageCount;
|
|
||||||
|
|
||||||
EImageFormat eFormat = IMAGE_FORMAT_RGBA8_UNORM;
|
EImageFormat eFormat = IMAGE_FORMAT_RGBA8_UNORM;
|
||||||
switch(eVkFormat)
|
switch(eVkFormat)
|
||||||
@@ -501,7 +974,7 @@ IXRHeadset *COpenXRManager::GetHeadset( uint32_t i )
|
|||||||
{
|
{
|
||||||
if (i)
|
if (i)
|
||||||
return 0;
|
return 0;
|
||||||
if(bHasXR)
|
if(!bHasXR)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return &m_headset;
|
return &m_headset;
|
||||||
@@ -512,3 +985,4 @@ void COpenXRManager::ConnectInterface( void *pIface, const char *szName )
|
|||||||
if (!V_strcmp(szName, RENDER_CONTEXT_INTERFACE_VERSION))
|
if (!V_strcmp(szName, RENDER_CONTEXT_INTERFACE_VERSION))
|
||||||
m_pRenderContext = (IRenderContext*)pIface;
|
m_pRenderContext = (IRenderContext*)pIface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
external/funnystdlib
vendored
2
external/funnystdlib
vendored
Submodule external/funnystdlib updated: 4a2e606e2b...df40d74b9b
@@ -0,0 +1,70 @@
|
|||||||
|
{
|
||||||
|
"/user/hand/left":
|
||||||
|
{
|
||||||
|
"inputs":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "select",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"click"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "menu",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"click"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "grip",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"pose"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aim",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"pose"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"/user/hand/right":
|
||||||
|
{
|
||||||
|
"inputs":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "select",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"click"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "menu",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"click"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "grip",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"pose"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aim",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"pose"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
{
|
||||||
|
"/user/hand/left":
|
||||||
|
{
|
||||||
|
"inputs":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "x",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"click",
|
||||||
|
"touch"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "y",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"click",
|
||||||
|
"touch"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "menu",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"click"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "squeeze",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"value"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "thumbstick",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"x",
|
||||||
|
"y",
|
||||||
|
"click",
|
||||||
|
"touch"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "thumbrest",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"touch"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "grip",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"pose"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aim",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"pose"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"/user/hand/right":
|
||||||
|
{
|
||||||
|
"inputs":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "a",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"click",
|
||||||
|
"touch"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "b",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"click",
|
||||||
|
"touch"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "system",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"click"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "squeeze",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"value"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "thumbstick",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"x",
|
||||||
|
"y",
|
||||||
|
"click",
|
||||||
|
"touch"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "thumbrest",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"touch"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "grip",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"pose"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aim",
|
||||||
|
"actions":
|
||||||
|
[
|
||||||
|
"pose"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "netprotocol.h"
|
#include "netprotocol.h"
|
||||||
#include "userinput.h"
|
#include "userinput.h"
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
#include "cglm/euler.h"
|
||||||
#ifdef STEAM
|
#ifdef STEAM
|
||||||
#include "steam/isteamgameserver.h"
|
#include "steam/isteamgameserver.h"
|
||||||
#include "steam/steam_gameserver.h"
|
#include "steam/steam_gameserver.h"
|
||||||
@@ -36,6 +37,9 @@ IEngineBridge *EngineBridge()
|
|||||||
return &s_bridge;
|
return &s_bridge;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XRInputCallback( IXRController *pController, EXRInputType_t eType, const char *szType, EXRInputActionType_t action, EXRInputValue_t value );
|
||||||
|
|
||||||
|
|
||||||
EXPOSE_INTERFACE_FN(EngineBridge, IEngineBridge, ENGINE_BRIDGE_INTERFACE_VERSION)
|
EXPOSE_INTERFACE_FN(EngineBridge, IEngineBridge, ENGINE_BRIDGE_INTERFACE_VERSION)
|
||||||
|
|
||||||
void CFunnyGameBridge::Init()
|
void CFunnyGameBridge::Init()
|
||||||
@@ -101,6 +105,11 @@ void CFunnyGameBridge::Init()
|
|||||||
g_pRenderContext->DestroyCommandList(pDoSomething);
|
g_pRenderContext->DestroyCommandList(pDoSomething);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for ( uint32_t i = 0; i < pHeadSet->GetControllerCount(); i++ )
|
||||||
|
{
|
||||||
|
pHeadSet->GetController(i)->SetInputCallback(XRInputCallback);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFunnyGameBridge::Tick( float fDelta )
|
void CFunnyGameBridge::Tick( float fDelta )
|
||||||
@@ -145,6 +154,17 @@ void CFunnyGameBridge::Frame( float fDelta )
|
|||||||
|
|
||||||
TryToConnectToServer();
|
TryToConnectToServer();
|
||||||
|
|
||||||
|
|
||||||
|
g_pXRManager->Frame();
|
||||||
|
|
||||||
|
IXRHeadset *pHeadSet = g_pXRManager->GetHeadset(0);
|
||||||
|
if (pHeadSet) {
|
||||||
|
XRRenderSurface_t s = pHeadSet->GetSurface(0);
|
||||||
|
g_pWorldRenderer->SetCameraPosition(s.m_vPosition);
|
||||||
|
V_printf("%f\n", s.m_vPosition.y);
|
||||||
|
g_pWorldRenderer->SetCameraRotation(s.m_vRotation);
|
||||||
|
}
|
||||||
|
|
||||||
INetworkBase *pCurrentServer = g_pServerBridge;
|
INetworkBase *pCurrentServer = g_pServerBridge;
|
||||||
pCurrentServer = g_pServerBridge;
|
pCurrentServer = g_pServerBridge;
|
||||||
if (m_bIsConnectedToServer)
|
if (m_bIsConnectedToServer)
|
||||||
@@ -197,8 +217,6 @@ void CFunnyGameBridge::Frame( float fDelta )
|
|||||||
EntitySystem()->NetSendThink(pCurrentServer);
|
EntitySystem()->NetSendThink(pCurrentServer);
|
||||||
}
|
}
|
||||||
g_pWorldRenderer->Frame(fDelta);
|
g_pWorldRenderer->Frame(fDelta);
|
||||||
|
|
||||||
g_pXRManager->Frame();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFunnyGameBridge::Shutdown()
|
void CFunnyGameBridge::Shutdown()
|
||||||
|
|||||||
@@ -25,16 +25,11 @@ void C_MOBAPlayer::Think( float fDelta )
|
|||||||
|
|
||||||
if (pPlayerEntity == this)
|
if (pPlayerEntity == this)
|
||||||
{
|
{
|
||||||
Vector vCameraPos;
|
|
||||||
vCameraPos = GetAbsOrigin();
|
|
||||||
vCameraPos.z = 20;
|
|
||||||
vCameraPos.y+=3;
|
|
||||||
g_pWorldRenderer->SetCameraPosition(vCameraPos);
|
|
||||||
Quat vCameraRot;
|
|
||||||
glm_euler_yxz_quat((vec3){m_fPitch, m_fYaw, 0}, *(versor*)&vCameraRot);
|
|
||||||
g_pWorldRenderer->SetCameraRotation(vCameraRot);
|
|
||||||
}
|
}
|
||||||
|
m_pLeftHand = (C_MOBAPlayerHandController*)EntitySystem()->GetEntities()[m_leftHandId];
|
||||||
|
m_pRightHand = (C_MOBAPlayerHandController*)EntitySystem()->GetEntities()[m_rightHandId];
|
||||||
BaseClass::Think(fDelta);
|
BaseClass::Think(fDelta);
|
||||||
|
V_printf("device: %p %p\n", m_pLeftHand, m_pRightHand );
|
||||||
};
|
};
|
||||||
|
|
||||||
LINK_ENTITY_TO_CLASS(player, C_MOBAPlayer)
|
LINK_ENTITY_TO_CLASS(player, C_MOBAPlayer)
|
||||||
@@ -43,6 +38,8 @@ BEGIN_DATADESC(C_MOBAPlayer)
|
|||||||
END_DATADESC()
|
END_DATADESC()
|
||||||
|
|
||||||
IMPLEMENT_RECV_DT(C_MOBAPlayer)
|
IMPLEMENT_RECV_DT(C_MOBAPlayer)
|
||||||
|
NetPropInt(m_leftHandId),
|
||||||
|
NetPropInt(m_rightHandId),
|
||||||
END_RECV_DT()
|
END_RECV_DT()
|
||||||
|
|
||||||
IMPLEMENT_SEND_DT(C_MOBAPlayer)
|
IMPLEMENT_SEND_DT(C_MOBAPlayer)
|
||||||
@@ -162,3 +159,63 @@ void Game_OnGameAxisDiff( EInputDeviceType eDevice, EInputAxis eAxis, float fVal
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_MOBAPlayerHandController::Precache()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void C_MOBAPlayerHandController::Spawn()
|
||||||
|
{
|
||||||
|
BaseClass::Spawn();
|
||||||
|
SetThink(Think);
|
||||||
|
};
|
||||||
|
|
||||||
|
void C_MOBAPlayerHandController::Think( float fDelta )
|
||||||
|
{
|
||||||
|
V_printf("controller: %p %f %f %f\n", this, m_vDesiredHandPosition.x, m_vDesiredHandPosition.y, m_vDesiredHandPosition.z );
|
||||||
|
SetAbsOrigin(m_vDesiredHandPosition);
|
||||||
|
BaseClass::Think(fDelta);
|
||||||
|
};
|
||||||
|
|
||||||
|
LINK_ENTITY_TO_CLASS(player_hand_controller, C_MOBAPlayerHandController)
|
||||||
|
|
||||||
|
BEGIN_DATADESC(C_MOBAPlayerHandController)
|
||||||
|
END_DATADESC()
|
||||||
|
|
||||||
|
IMPLEMENT_RECV_DT(C_MOBAPlayerHandController)
|
||||||
|
END_RECV_DT()
|
||||||
|
|
||||||
|
IMPLEMENT_SEND_DT(C_MOBAPlayerHandController)
|
||||||
|
END_SEND_DT()
|
||||||
|
|
||||||
|
void XRInputCallback( IXRController *pController, EXRInputType_t eType, const char *szType, EXRInputActionType_t action, EXRInputValue_t value )
|
||||||
|
{
|
||||||
|
|
||||||
|
C_BaseEntity *pPlayer = UTIL_GetLocalPlayer();
|
||||||
|
if (!pPlayer)
|
||||||
|
return;
|
||||||
|
if (!dynamic_cast<C_MOBAPlayer*>(pPlayer))
|
||||||
|
return;
|
||||||
|
C_MOBAPlayer *p = (C_MOBAPlayer*)pPlayer;
|
||||||
|
C_MOBAPlayerHandController *pCon = NULL;
|
||||||
|
|
||||||
|
if (pController->GetControllerSide() == k_EXRController_Left)
|
||||||
|
pCon = p->m_pLeftHand;
|
||||||
|
|
||||||
|
if (pController->GetControllerSide() == k_EXRController_Right)
|
||||||
|
pCon = p->m_pRightHand;
|
||||||
|
|
||||||
|
if (pCon == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case k_EXRInputAction_Pose:
|
||||||
|
pCon->m_vDesiredHandPosition = value.pose.pos;
|
||||||
|
V_printf("callback: %p %f %f %f\n", pCon, pCon->m_vDesiredHandPosition.x, pCon->m_vDesiredHandPosition.y, pCon->m_vDesiredHandPosition.z );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,20 @@
|
|||||||
#define MILMOBA_PLAYER_H
|
#define MILMOBA_PLAYER_H
|
||||||
#include "basemodelentity.h"
|
#include "basemodelentity.h"
|
||||||
|
|
||||||
|
class C_MOBAPlayerHandController: public C_BaseModelEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS(C_MOBAPlayerHandController, C_BaseModelEntity);
|
||||||
|
DECLARE_DATADESC();
|
||||||
|
DECLARE_CLIENTCLASS();
|
||||||
|
|
||||||
|
virtual void Precache ( void ) override;
|
||||||
|
virtual void Spawn( void ) override;
|
||||||
|
void Think( float fDelta );
|
||||||
|
|
||||||
|
Vector m_vDesiredHandPosition = {};
|
||||||
|
Quat m_vDesiredHandRotation = {};
|
||||||
|
};
|
||||||
|
|
||||||
class C_MOBAPlayer: public C_BaseModelEntity
|
class C_MOBAPlayer: public C_BaseModelEntity
|
||||||
{
|
{
|
||||||
@@ -30,6 +44,12 @@ public:
|
|||||||
Vector m_vMovementVector;
|
Vector m_vMovementVector;
|
||||||
Vector m_vLocalMovementVector;
|
Vector m_vLocalMovementVector;
|
||||||
Vector vCameraPos;
|
Vector vCameraPos;
|
||||||
|
|
||||||
|
C_MOBAPlayerHandController *m_pLeftHand;
|
||||||
|
int m_leftHandId = 0;
|
||||||
|
C_MOBAPlayerHandController *m_pRightHand;
|
||||||
|
int m_rightHandId = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public:
|
|||||||
virtual void Spawn() override;
|
virtual void Spawn() override;
|
||||||
virtual void SetModel( const char *szName );
|
virtual void SetModel( const char *szName );
|
||||||
virtual void OnModelChanged( const char *szName );
|
virtual void OnModelChanged( const char *szName );
|
||||||
virtual void Think( float fDelta );
|
void Think( float fDelta );
|
||||||
char m_szModel[256] = {};
|
char m_szModel[256] = {};
|
||||||
private:
|
private:
|
||||||
char m_szCurrentModel[256] = {};
|
char m_szCurrentModel[256] = {};
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
CMOBAPlayer::CMOBAPlayer()
|
CMOBAPlayer::CMOBAPlayer()
|
||||||
{
|
{
|
||||||
m_hCuboid = g_pPhysics->CreateCube({1,1,1});
|
m_hCuboid = g_pPhysics->CreateCube({1,1,1});
|
||||||
|
m_pLeftHand = EntitySystem()->CreateByClassname("player_hand_controller", &m_leftHandId);
|
||||||
|
m_pRightHand = EntitySystem()->CreateByClassname("player_hand_controller", &m_rightHandId);
|
||||||
}
|
}
|
||||||
|
|
||||||
CMOBAPlayer::~CMOBAPlayer()
|
CMOBAPlayer::~CMOBAPlayer()
|
||||||
@@ -20,6 +21,9 @@ void CMOBAPlayer::Spawn()
|
|||||||
SetModel("game/core/models/sphere.fmdl");
|
SetModel("game/core/models/sphere.fmdl");
|
||||||
SetAbsOrigin({0,-11.5, 0});
|
SetAbsOrigin({0,-11.5, 0});
|
||||||
SetThink(Think);
|
SetThink(Think);
|
||||||
|
|
||||||
|
m_pLeftHand->Spawn();
|
||||||
|
m_pRightHand->Spawn();
|
||||||
};
|
};
|
||||||
|
|
||||||
bool CMOBAPlayer::CheckMask( HCollider hCollider )
|
bool CMOBAPlayer::CheckMask( HCollider hCollider )
|
||||||
@@ -52,8 +56,36 @@ BEGIN_DATADESC(CMOBAPlayer)
|
|||||||
END_DATADESC()
|
END_DATADESC()
|
||||||
|
|
||||||
IMPLEMENT_SEND_DT(CMOBAPlayer)
|
IMPLEMENT_SEND_DT(CMOBAPlayer)
|
||||||
|
NetPropInt(m_leftHandId),
|
||||||
|
NetPropInt(m_rightHandId),
|
||||||
END_SEND_DT()
|
END_SEND_DT()
|
||||||
|
|
||||||
IMPLEMENT_RECV_DT(CMOBAPlayer)
|
IMPLEMENT_RECV_DT(CMOBAPlayer)
|
||||||
NetPropFloat3(m_vMovementVector)
|
NetPropFloat3(m_vMovementVector),
|
||||||
|
END_RECV_DT()
|
||||||
|
|
||||||
|
CMOBAPlayerHandController::CMOBAPlayerHandController()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void CMOBAPlayerHandController::Spawn()
|
||||||
|
{
|
||||||
|
CBaseEntity::Spawn();
|
||||||
|
SetModel("game/core/models/sphere.fmdl");
|
||||||
|
SetScale(0.03);
|
||||||
|
SetThink(Think);
|
||||||
|
}
|
||||||
|
void CMOBAPlayerHandController::Think( float fDelta )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
LINK_ENTITY_TO_CLASS(player_hand_controller, CMOBAPlayerHandController)
|
||||||
|
|
||||||
|
BEGIN_DATADESC(CMOBAPlayerHandController)
|
||||||
|
END_DATADESC()
|
||||||
|
|
||||||
|
IMPLEMENT_SEND_DT(CMOBAPlayerHandController)
|
||||||
|
END_SEND_DT()
|
||||||
|
|
||||||
|
IMPLEMENT_RECV_DT(CMOBAPlayerHandController)
|
||||||
END_RECV_DT()
|
END_RECV_DT()
|
||||||
|
|||||||
@@ -20,6 +20,22 @@ private:
|
|||||||
Vector m_vMovementVector = {};
|
Vector m_vMovementVector = {};
|
||||||
|
|
||||||
HShape m_hCuboid = NULL;
|
HShape m_hCuboid = NULL;
|
||||||
|
|
||||||
|
CBaseEntity *m_pLeftHand;
|
||||||
|
int m_leftHandId;
|
||||||
|
CBaseEntity *m_pRightHand;
|
||||||
|
int m_rightHandId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CMOBAPlayerHandController: public CBaseModelEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS(CMOBAPlayerHandController, CBaseModelEntity);
|
||||||
|
DECLARE_DATADESC();
|
||||||
|
DECLARE_SERVERCLASS()
|
||||||
|
CMOBAPlayerHandController();
|
||||||
|
virtual void Spawn( void ) override;
|
||||||
|
void Think( float fDelta );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -276,10 +276,11 @@ void CVkRenderCommandList::DispatchCompute( uint32_t uX, uint32_t uY, uint32_t u
|
|||||||
SwitchRenderingStage(RENDERING_STAGE_POST_RASTER);
|
SwitchRenderingStage(RENDERING_STAGE_POST_RASTER);
|
||||||
|
|
||||||
CVkDispatchCommand *pCmd = CREATE_COMMAND(m_pCommandBufferManager, Dispatch);
|
CVkDispatchCommand *pCmd = CREATE_COMMAND(m_pCommandBufferManager, Dispatch);
|
||||||
|
|
||||||
|
FlushBarriers(pCmd);
|
||||||
pCmd->uX = uX;
|
pCmd->uX = uX;
|
||||||
pCmd->uY = uY;
|
pCmd->uY = uY;
|
||||||
pCmd->uZ = uZ;
|
pCmd->uZ = uZ;
|
||||||
FlushBarriers(pCmd);
|
|
||||||
m_pPostRaster->AddCommand(pCmd);
|
m_pPostRaster->AddCommand(pCmd);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,10 @@ CVkImage::CVkImage( uint32_t nWidth, uint32_t nHeight, uint32_t nDepth, EImageFo
|
|||||||
if (eFormat == IMAGE_FORMAT_D32_SFLOAT)
|
if (eFormat == IMAGE_FORMAT_D32_SFLOAT)
|
||||||
m_ePreferredLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
|
m_ePreferredLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
|
||||||
else
|
else
|
||||||
m_ePreferredLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
if (eUsage == VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
|
||||||
|
m_ePreferredLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
else
|
||||||
|
m_ePreferredLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||||
|
|
||||||
CreateImage(nWidth, nHeight, eFormat, eMultisampleType, eUsage);
|
CreateImage(nWidth, nHeight, eFormat, eMultisampleType, eUsage);
|
||||||
CreateImageView();
|
CreateImageView();
|
||||||
|
|||||||
@@ -59,6 +59,13 @@ VkPipelineStageFlags2 VulkanGetStageFlags( EDependencyMode eMode )
|
|||||||
case DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION: return VK_PIPELINE_STAGE_2_TRANSFER_BIT;
|
case DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION: return VK_PIPELINE_STAGE_2_TRANSFER_BIT;
|
||||||
case DEPENDENCY_MODE_IMAGE_PRESENT: return VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
|
case DEPENDENCY_MODE_IMAGE_PRESENT: return VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
|
||||||
|
case DEPENDENCY_MODE_SHADER_BUFFER_READ: return VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT;
|
||||||
|
case DEPENDENCY_MODE_SHADER_BUFFER_WRITE: return VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT;
|
||||||
|
case DEPENDENCY_MODE_SHADER_BUFFER_READ_WRITE: return VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT;
|
||||||
|
case DEPENDENCY_MODE_SHADER_IMAGE_READ: return VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT;
|
||||||
|
case DEPENDENCY_MODE_SHADER_IMAGE_WRITE: return VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT;
|
||||||
|
case DEPENDENCY_MODE_SHADER_IMAGE_READ_WRITE: return VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT;
|
||||||
|
|
||||||
case DEPENDENCY_MODE_BLIT_IMAGE_SOURCE:
|
case DEPENDENCY_MODE_BLIT_IMAGE_SOURCE:
|
||||||
case DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION:
|
case DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION:
|
||||||
return VK_PIPELINE_STAGE_2_BLIT_BIT;
|
return VK_PIPELINE_STAGE_2_BLIT_BIT;
|
||||||
|
|||||||
133
public/ixr.h
133
public/ixr.h
@@ -15,6 +15,131 @@ struct XRRenderSurface_t
|
|||||||
float m_fFov;
|
float m_fFov;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum EXRControllerType_t
|
||||||
|
{
|
||||||
|
k_EXR_HandController,
|
||||||
|
k_EXR_Hand,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum EXRControllerSide_t
|
||||||
|
{
|
||||||
|
k_EXRController_Left,
|
||||||
|
k_EXRController_Right,
|
||||||
|
};
|
||||||
|
/* defined by openxr + steam frame */
|
||||||
|
enum EXRInputType_t
|
||||||
|
{
|
||||||
|
k_EXRInput_FromString,
|
||||||
|
|
||||||
|
k_EXRInput_Trackpad,
|
||||||
|
k_EXRInput_Thumbstick,
|
||||||
|
k_EXRInput_Joystick,
|
||||||
|
k_EXRInput_Trigger,
|
||||||
|
k_EXRInput_Trackball,
|
||||||
|
k_EXRInput_Pedal,
|
||||||
|
k_EXRInput_System,
|
||||||
|
k_EXRInput_Dpad_Up,
|
||||||
|
k_EXRInput_Dpad_Down,
|
||||||
|
k_EXRInput_Dpad_Left,
|
||||||
|
k_EXRInput_Dpad_Right,
|
||||||
|
k_EXRInput_Diamond_Up,
|
||||||
|
k_EXRInput_Diamond_Down,
|
||||||
|
k_EXRInput_Diamond_Left,
|
||||||
|
k_EXRInput_Diamond_Right,
|
||||||
|
|
||||||
|
k_EXRInput_A,
|
||||||
|
k_EXRInput_B,
|
||||||
|
k_EXRInput_X,
|
||||||
|
k_EXRInput_Y,
|
||||||
|
k_EXRInput_Start,
|
||||||
|
k_EXRInput_Home,
|
||||||
|
k_EXRInput_End,
|
||||||
|
k_EXRInput_Select,
|
||||||
|
k_EXRInput_Volume_Up,
|
||||||
|
k_EXRInput_Volume_Down,
|
||||||
|
k_EXRInput_Mute_Mic,
|
||||||
|
k_EXRInput_Play_Pause,
|
||||||
|
k_EXRInput_Menu,
|
||||||
|
k_EXRInput_View,
|
||||||
|
k_EXRInput_Back,
|
||||||
|
k_EXRInput_ThumbRest,
|
||||||
|
k_EXRInput_Shoulder,
|
||||||
|
k_EXRInput_Squeeze,
|
||||||
|
k_EXRInput_Wheel,
|
||||||
|
k_EXRInput_ThumbRestingSurfaces,
|
||||||
|
|
||||||
|
|
||||||
|
k_EXRInput_Grip,
|
||||||
|
k_EXRInput_Aim,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum EXRInputActionType_t
|
||||||
|
{
|
||||||
|
k_EXRInputAction_Touch,
|
||||||
|
k_EXRInputAction_Click,
|
||||||
|
k_EXRInputAction_Force,
|
||||||
|
k_EXRInputAction_Value,
|
||||||
|
k_EXRInputAction_X,
|
||||||
|
k_EXRInputAction_Y,
|
||||||
|
k_EXRInputAction_Twist,
|
||||||
|
k_EXRInputAction_Pose,
|
||||||
|
k_EXRInputAction_Proximity,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum EXRValueType_t
|
||||||
|
{
|
||||||
|
k_EXRValue_Bool,
|
||||||
|
k_EXRValue_Float,
|
||||||
|
k_EXRValue_Vector2,
|
||||||
|
k_EXRValue_Pose,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
union EXRInputValue_t
|
||||||
|
{
|
||||||
|
EXRValueType_t type;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
EXRValueType_t type;
|
||||||
|
bool value;
|
||||||
|
} b;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
EXRValueType_t type;
|
||||||
|
float value;
|
||||||
|
} f32;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
EXRValueType_t type;
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
} f32x2;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
EXRInputType_t type;
|
||||||
|
Vector pos;
|
||||||
|
Quat rot;
|
||||||
|
} pose;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IXRController;
|
||||||
|
class IXRHeadset;
|
||||||
|
|
||||||
|
typedef void ( *XRInputCallbackFn )( IXRController *pController, EXRInputType_t eType, const char *szType, EXRInputActionType_t action, EXRInputValue_t value );
|
||||||
|
|
||||||
|
abstract_class IXRController
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual EXRControllerType_t GetControllerType() = 0;
|
||||||
|
virtual EXRControllerSide_t GetControllerSide() = 0;
|
||||||
|
virtual IXRHeadset *GetHeadset() = 0;
|
||||||
|
virtual void SetInputCallback( XRInputCallbackFn fn ) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
abstract_class IXRHeadset
|
abstract_class IXRHeadset
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -22,12 +147,8 @@ public:
|
|||||||
virtual XRRenderSurface_t GetSurface( uint32_t i ) = 0;
|
virtual XRRenderSurface_t GetSurface( uint32_t i ) = 0;
|
||||||
virtual void SetSurfaceImage( uint32_t i, IImage *pImage ) = 0;
|
virtual void SetSurfaceImage( uint32_t i, IImage *pImage ) = 0;
|
||||||
|
|
||||||
};
|
virtual uint32_t GetControllerCount() = 0;
|
||||||
|
virtual IXRController *GetController( uint32_t i ) = 0;
|
||||||
abstract_class IXRController
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
abstract_class IXRManager: public IAppSystem2
|
abstract_class IXRManager: public IAppSystem2
|
||||||
|
|||||||
BIN
shadercompiler/csMain
Normal file
BIN
shadercompiler/csMain
Normal file
Binary file not shown.
Reference in New Issue
Block a user