简介:
vr::IVRSystem接口可访问 显示配置信息,追踪数据,畸变函数,控制器状态(主要是按键信息),事件以及设备属性。它是OpenVR的主要接口,且它可以通过openvr::VR_Init函数来初始化与获取到。
在IVRSystem中许多函数使用追踪设备索引来区别插入到计算机的设备。定义的值如下:
typedef uint32_t TrackedDeviceIndex_t;
static const uint32_t k_unTrackedDeviceIndexInvalid = 0xFFFFFFFF;
static const uint32_t k_unMaxTrackedDeviceCount = 16;
static const uint32_t k_unTrackedDeviceIndex_Hmd = 0;
在一个给定时间内不允许激活超过k_unMaxTrackedDeviceCount 数量的设备。他们的索引会是0(HMD)和1~15(其他设备,比如手柄)。
每个追踪设备都会包含下面类中的一个:
TrackedDeviceClass_Invalid - 在该索引号上无对应设备
TrackedDeviceClass_HMD - 在该索引号上对应的是HMD设备
TrackedDeviceClass_Controller - 在该索引号上对应的是追踪设备
TrackedDeviceClass_TrackingReference - 该设备是一个摄像头,灯塔基站或者其他提供地面轨迹追踪的设备
接口函数:
vr::IVRSystem接口包含以下函数:
1.显示相关(Display)- 该系列函数有关于计算在哪儿放置一个窗口,怎样创建一个视窗以及怎样渲染目标,以及怎样将目标渲染进那些surface中。
1>.void GetRecommendedRenderTargetSize( uint32_t *pnWidth, uint32_t *pnHeight )
由于要在离屏渲染目标中使得像素拉伸最小化,该函数可以给游戏提供最小的像素尺寸。该像素的尺寸是与投射矩阵以及畸变函数相匹配的且会随着分辨率,畸变以及视场角变化而变化,从而导致显示也会随着这些量的变化而变化。
parameter:
pnWidth - 为离屏显示目标建议的像素宽度
pnHeight - 为离屏显示目标建议的像素高度
2>.HmdMatrix44_t GetProjectionMatrix( Hmd_Eye eEye, float fNearZ, float fFarZ )
为指定的眼睛返回投射矩阵
parameter:
eEye - Eye_Left或Eye_Right。指定需要返回投射矩阵的眼睛
fNearZ - 人眼到近剪裁平面的距离,以米为单位
fFarZ - 人眼到远剪裁平面的距离,以米为单位
关于剪裁平面,只有在近剪裁平面与远剪裁平面之间的对象才会被渲染显示。
3>.void GetProjectionRaw( Hmd_Eye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom )
为指定的眼睛返回投射raw值。大多数游戏应该使用了函数GetProjectionMatrix而不是这个方法,但是有时一个游戏必须使用它的投射来做一些花俏的事,且能够使用这些值去计算它自己的矩阵。
这些值代表来自于中心视角轴的半角正切。使用下面的函数能够将这些值转换成投射矩阵。
void ComposeProjection(float fLeft, float fRight, float fTop, float fBottom, float zNear, float zFar, HmdMatrix44_t *pmProj )
{float idx = 1.0f / (fRight - fLeft);float idy = 1.0f / (fBottom - fTop);float idz = 1.0f / (zFar - zNear);float sx = fRight + fLeft;float sy = fBottom + fTop;float (*p)[4] = pmProj->m;p[0][0] = 2*idx; p[0][1] = 0; p[0][2] = sx*idx; p[0][3] = 0;p[1][0] = 0; p[1][1] = 2*idy; p[1][2] = sy*idy; p[1][3] = 0;p[2][0] = 0; p[2][1] = 0; p[2][2] = -zFar*idz; p[2][3] = -zFar*zNear*idz;p[3][0] = 0; p[3][1] = 0; p[3][2] = -1.0f; p[3][3] = 0;
}
若使用OpenGL,可以通过调用函数glFrustum来完成这个事。要注意的是glFrustum(及其相似的API)通常接收left,right,top以及bottom值作为近剪裁面的坐标值。为了实现那个要求,还得将函数GetProjectionRaw返回的值乘以近剪裁平面的距离才行(就是在上面实例中的zNear)
eEye - Eye_Left或者Eye_Right。指定该函数为哪只眼睛返回投射
pfLeft - 从中心轴到左剪裁平面的半角正切值
pfRight - 从中心轴到右剪裁平面的半角正切值
pfTop - 从中心轴到上剪裁平面的半角正切值
pfBottom - 从中心轴到下剪裁平面的半角正切值
4>.bool ComputeDistortion( Hmd_Eye eEye, float fU, float fV, DistortionCoordinates_t *pDistortionCoordinates )
获取在畸变映射中所使用到的畸变值。输入的UV值是在单个眼睛的视窗中的,而输出UV值是要给到畸变着色器中的源渲染目标的。
成功则返回true,返回false,则表示该畸变值不合适。
eEye - Eye_Left或Eye_Right。指定该函数应该为哪只眼睛返回畸变值
fU - 视窗内输出像素的水平纹理坐标值
fV- 视窗内输出像素的垂直纹理坐标值
ComputeDistortion使用以下机构返回畸变值:
struct DistortionCoordinates_t
{
float rfRed[2];
float rfGreen[2];
float rfBlue[2];
};
rfRed包含红色通道的UV值,rfGreen包含绿色通道的UV值,rfBlue包含蓝色通道的UV值。
5>.HmdMatrix44_t GetEyeToHeadTransform( Hmd_Eye eEye )
返回观察空间和视觉空间的转换。视觉空间是观察空间每只眼睛的立体视觉差。该模型叉乘方式是Model*View*Eye*Project而不是Model*View*Project。通常在应用程序中View和Eye会相乘且将它们的结果视为View。
该矩阵包含用户的瞳距(IPD)
eEye-Eye_Left或Eye_Right。指定为哪只眼睛返回矩阵。
6>.bool GetTimeSinceLastVsync( float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter )
返回从最后一次垂直同步事件开始起的时间。该值还有可能来自于定时器内的垂直同步定时器事件或者如果在定时器内获取不到,也有可能获取来自于应用程序上报的时间。如果该函数中没有可用的垂直同步时间它将为垂直时间和帧数返回0,为该函数返回false。
pfSecondsSinceLastVsync - 从最后一次垂直同步事件开始的秒数。它不会超过单个帧的长度
pulFrameCounter - 从vrserver.exe服务启动开始以来的帧数。
7>.void GetDXGIOutputInfo( int32_t *pnAdapterIndex )
只适用于D3D10/11。
返回适配器的索引值,用户需要在DX10和DX11中传入EnumAdapter值去创建一个设备以及交换链。如果发生了错误,该索引值会被设置为-1
pnAdapterIndex - 为该显示返回适配器的索引值
8>.int32_t GetD3D9AdapterIndex()
只适用于D3D9
返回索引值,用户会将该值传入CreateDevice以设置D3D9,它在HMD上用这种方式进入全屏独占模式。如果发生错误返回-1。
2.tracking(追踪器) - 计算追踪设备姿态的函数
1>.void GetDeviceToAbsoluteTrackingPose(
TrackingUniverseOrigin eOrigin,
float fPredictedSecondsToPhotonsFromNow,
VR_ARRAY_COUNT(unTrackedDevicePoseArrayCount)
TrackedDevicePose_t *pTrackedDevicePoseArray,
uint32_t unTrackedDevicePoseArrayCount )
为所有设备计算更新的姿态。
eOrigin - 相对追踪时空返回的姿态。以下之一:
1>>.TrackingUniverseSeated 相对于零坐姿的姿态
2>>.TrackingUniverseStanding 相对于用户配置的安全边界的姿态
3>>.TrackingUniverseRaw 在坐标系统中由驱动提供的姿态,Y轴向上
float fPredictedSecondsToPhotonsFromNow - 从现在开始预测姿态的秒数。正数值表示未来, 传入0获取函数被调用时刻的状态。参考以下详细关于怎样计算一个好的值。
描述:
在指定秒数过后,追踪器认为HMD将会在未来进入的姿态量。传入0值会获得该方法调用时刻的状态。大多数时间应用程序会一直计算到显示器发射光子时的时间为止且将该时间传入该方法。
虽然许多游戏需要在头部姿态提供的旋转和变形上面再做一些额外的旋转或变形,但是在大多数应用程序中这大概类似于视觉矩阵的倒数。
对于将bPoseIsValid设置为true的设备而言,应用程序能够使用该姿态去校正定位有问题的设备。提供的数组大小最大为k_unMaxTrackedDeviceCount。
坐着时应该调用带有TrackingUniverseSeated的参数且获得相对于零坐姿的姿态。站着时应该调用带有TrackingUniverseStanding 的参数且获取相对于监护软边界的姿态。当只有再监护校准工具自身要使用姿态数据时才会使用参数TrackingUniverseRawAndUncalibrated ,且它的姿态数据是驱动中的相对于特定硬件坐标系的。
计算到光子发光时的秒数:
从当前时刻到下一个从HMD发射出来的光子的时刻之间的秒数是能够被自动计算出来的。这假设渲染管线没有任何额外的帧缓冲。
样例:
// for somebody asking for the default figure out the time from now to photons.
float fSecondsSinceLastVsync;
pVRSystem->GetTimeSinceLastVsync( &fSecondsSinceLastVsync, NULL );float fDisplayFrequency = pVRSystem->GetFloatTrackedDeviceProperty( vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_DisplayFrequency_Float );
float fFrameDuration = 1.f / fDisplayFrequency;
float fVsyncToPhotons = pVRSystem->GetFloatTrackedDeviceProperty( vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_SecondsFromVsyncToPhotons_Float );float fPredictedSecondsFromNow = fFrameDuration - fSecondsSinceLastVsync + fVsyncToPhotons;
2>.void ResetSeatedZeroPose()
设置当前位置以及HMD yaw值为零姿态(坐姿追踪系统中)。在ResetSeatedZeroPose之后,所有的GetDeviceToAbsoluteTrackingPose 调用都会传入TrackingUniverseSeated 参数作为原点且是相对于新的零姿态。新的零坐标系统不会改变现实世界Y轴向上的事实,因此下一个从GetDeviceToAbsoluteTrackingPose 返回的姿态,在调用ResetSeatedZeroPose之后也许不是一个单位矩阵。
3>.HmdMatrix34_t GetSeatedZeroPoseToStandingAbsoluteTrackingPose()
返回从零坐姿到站着的绝对追踪系统。这允许应用程序表示坐着时的原点或者将目标位置从一个坐标系转换到另外一个坐标系。坐着时原点可能会在或者不会在由IVRChaperone返回的软或硬边界内。它的位置信息依赖于用户在监护校准工具所设置好的以及之前对ResetSeatedZeroPose的调用。
3.Property属性函数 - 返回关于追踪设备的非追踪数据信息
1>. TrackedDeviceClass GetTrackedDeviceClass( vr::TrackedDeviceIndex_t unDeviceIndex )
返回追踪设备的设备类。
parameter:
vr::TrackedDeviceIndex unDeviceIndex - 为获取设备类的设备索引值
返回追踪设备的设备类。
当应用程序启动这个函数时,如果没有设备连接到这个插槽,那么它将返回TrackedDevice_Invalid值。对于之前检测到的设备,该函数将返回之前观察到的设备类。
为了判断是哪一个设备存在系统中,只要从0到k_unMaxTrackedDeviceCount循环检测设备类。每个除TrackedDevice_Invalid以外的设备都是与一个实际物理设备相关联的。
2>.bool IsTrackedDeviceConnected( vr::TrackedDeviceIndex_t unDeviceIndex )
如果有设备连接到插槽则返回true。
parameter:
vr::TrackedDeviceIndex unDeviceIndex - 测试连接状态的设备索引值
3>.IVRSystem::GetTrackedDeviceProperty
bool GetBoolTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, TrackedDeviceProperty prop, TrackedPropertyError *pError = 0L )
float GetFloatTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, TrackedDeviceProperty prop, TrackedPropertyError *pError = 0L )
int32_t GetInt32TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, TrackedDeviceProperty prop, TrackedPropertyError *pError = 0L )
uint64_t GetUint64TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, TrackedDeviceProperty prop, TrackedPropertyError *pError = 0L )
HmdMatrix34_t GetMatrix34TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, TrackedDeviceProperty prop, TrackedPropertyError *pError = 0L )
uint32_t GetStringTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, TrackedDeviceProperty prop, char *pchValue, uint32_t unBufferSize, TrackedPropertyError *pError = 0L )
parameter:
vr::TrackedDeviceIndex unDeviceIndex - 获取属性的设备的索引号
vr::TrackedDeviceProperty prop - 获取哪一个属性
vr::TrackedPropertyError *pError - 当尝试着获取该属性时返回的错误。如果调用者不关心属性的错误源,则返回NULL。
char *pchValue - 存储字符串属性的缓冲区。unBufferSize为该缓冲区的大小
uint32_t unBufferSize - 由pchValue指出的缓冲区大小
描述:
为追踪设备返回一个静态属性。不同类型的GetXTrackedDeviceProperty函数失败时返回的值如下:
GetBoolTrackedDeviceProperty - false
GetFloatTrackedDeviceProperty - 0.0
GetInt32TrackedDeviceProperty - 0
GetUint64TrackedDeviceProperty - 0
GetMatrix34TrackedDeviceProperty - identity matrix(单位矩阵)
GetStringTrackedDeviceProperty - 0 (and 0-length string)
字符串属性:
由于应用程序使用字符串属性区填充占有的缓冲区,所以获取到的字符属性会不同。GetStringTrackedDeviceProperty返回容纳字符串的字节数,包括尾部的null符号。若缓冲区不是足够大,它会返回一个错误TrackedProp_BufferTooSmall且不会将字符串填充到缓冲区中去。
字符串通常填充k_unTrackingStringSize大小的字符到缓冲区中。
属性错误码:
TrackedPropertyError会是以下之一:
TrackedProp_Success - 属性请求成功
TrackedProp_WrongDataType - 所请求的属性使用了错误的类型函数
TrackedProp_WrongDeviceClass - 对一个追踪设备所请求的属性使用了错误的类
TrackedProp_BufferTooSmall - 字符串属性不会填充进所提供的缓冲区中去,返回所需要的缓冲区尺寸大小
TrackedProp_UnknownProperty - 未知的属性枚举值
TrackedProp_InvalidDevice - 追踪设备索引值无效
TrackedProp_CouldNotContactServer - 对于该属性,OpenVR不能够联系到vrserver去查询该设备
TrackedProp_ValueNotProvidedByDevice - 该设备的驱动不为该设备提供该指定的属性
TrackedProp_StringExceedsMaximumLength - 驱动返回的字符串属性长度超过了32K的最大属性长度值
4>.const char *GetPropErrorNameFromEnum( TrackedPropertyError error )
返回一个和指定属性错误对应的字符串。该字符串将会是错误枚举值(都是所有的有效错误码)中的一个名字。
TrackedPropertyError error - 需要返回的字符串错误码。
4.事件方法 - 访问由追踪设备或系统本身产生的事件
bool PollNextEvent(VREvent_t*pEvent, uint32_t uncbVREvent ) )
bool PollNextEventWithPose( TrackingUniverseOrigin eOrigin, uint32_t uncbVREvent , vr::VREvent_t*pEvent, vr::TrackedDevicePose_t *pTrackedDevicePose )
返回队列中的下一个事件。
parameter:
VREvent_t*pEvent - 填充了下一个事件的事件结构体
uint32_t uncbVREvent - VREvent_t结构体的字节数
TrackingUniverseOrigin eOrigin - 返回事件姿态的追踪系统
TrackedDevicePose_t *pTrackedDevicePose - 一个姿态结构体,它使用返回事件的姿态去填充。必须是非NULL。
描述:
返回true且以队列中的下一个事件去填充pEvent。若没有等待着的事件,则PollNextEvent返回false。
当事件产生时,若应用程序需要准确的知道追踪设备在哪儿与该事件发生联系,可以使用PollNextEventWithPose函数。由该函数返回的pose信息总是比当前旧,因此不应该使用它去做渲染。对于没有与设备产生关联的事件,该函数返回无效pose信息。
参考VREvent_t
const char *GetEventTypeNameFromEnum( EVREventType eType ) :
返回EVREventType枚举的变量名。
EVREventType eType - 为该事件类型返回一个字符串
5.渲染辅助函数 - 渲染时的实用辅助函数
HiddenAreaMesh_t GetHiddenAreaMesh( Hmd_Eye eEye )
为当前HMD返回隐藏区的模板网格。
Hmd_Eye eEye - 指定为哪只眼获取隐藏区网格
描述:
为当前HMD返回隐藏区的模板网格。若该HMD没有模板网格,则顶点数据与数量分别为NULL与0。在渲染每只眼的视图之前,该网格意味着是要渲染到模板缓冲中去的(或是渲染到深度缓冲中以设置nearz变量的)。在基于平面的能见度且应用镜头畸变之后,由该网格所覆盖着的像素用户是无法看到的。通过在运行像素着色器之前,让GPU早期就拒绝用户永远都不会看到的像素的方式来改善性能。
注意:由于顶点的弯曲顺序每个HMD或每只眼都是不同的,所以使用背面淘汰渲染该网格被禁止。
6.控制器方法 - 与控制器进行交互的方法
1>.void TriggerHapticPulse( vr::TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec )
在控制器上触发单个触觉脉冲。
parameter:
vr::TrackedDeviceIndex_t unControllerDeviceIndex - 触发一个触觉脉冲的追踪设备控制器的索引号
uint32_t unAxisId - 触发一个触觉脉冲的坐标轴ID号
unsigned short usDurationMicroSec - 期望的触觉脉冲时长,以秒为单位
描述:
在控制器上触发单个触觉脉冲。
注意:
调用该函数之后,应用程序在5S内,在该控制器上可能不会再触发其他的触觉脉冲以及轴组合数据了。
2>.bool GetControllerState( vr::TrackedDeviceIndex_t unControllerDeviceIndex, vr::VRControllerState_t *pControllerState )
bool GetControllerStateWithPose( TrackingUniverseOrigin eOrigin, vr::TrackedDeviceIndex_t unControllerDeviceIndex, vr::VRControllerState_t *pControllerState, TrackedDevicePose_t *pTrackedDevicePose )
将当前控制器状态值填充到提供的结构体:
vr::TrackedDeviceIndex_t unControllerDeviceIndex - 获取状态值的追踪设备索引号
vr::VRControllerState_t *pControllerState - 填充控制器状态的结构体
TrackingUniverseOrigin eOrigin - 返回姿态的追踪坐标系
TrackedDevicePose_t *pTrackedDevicePose - 当最后的按键事件发生时,控制器的姿态填充姿态结构体
控制器当前状态填充所提供的结构体,若因为某些原因导致控制器索引无效或无法从控制器获取状态,则返回false。
当控制器按键状态在最近更新时,GetControllerStateWithPose 会使用控制器姿态填充提供的姿态结构体。当用户按下或释放按钮时,如果需要一个精确的控制器姿态作为应用程序的输入,则可使用该函数。该姿态数据总是比当前时刻的要旧,因此它不应该用于渲染。
控制器状态结构体:
/** Identifies what kind of axis is on the controller at index n. Read this type
* with pVRSystem->Get( nControllerDeviceIndex, Prop_Axis0Type_Int32 + n );
*/
/**标识控制器上的索引号n是所属哪一种类的axis。使用函数
*pVRSystem->Get( nControllerDeviceIndex, Prop_Axis0Type_Int32 + n )获取该类型。
*/
enum EVRControllerAxisType
{k_eControllerAxis_None = 0,k_eControllerAxis_TrackPad = 1,k_eControllerAxis_Joystick = 2,k_eControllerAxis_Trigger = 3, // Analog trigger data is in the X axis 扳机键的模拟数据从X轴获取
};/** contains information about one axis on the controller */
/**存储控制器上一个轴上的信息*/
struct VRControllerAxis_t
{float x; // Ranges from -1.0 to 1.0 for joysticks and track pads. Ranges from 0.0 to 1.0 for triggers were 0 is fully released.
//手柄和触摸板的x轴数据范围为-1.0~1.0,扳机键范围从0.0~1.0,当为0值时,完全释放。float y; // Ranges from -1.0 to 1.0 for joysticks and track pads. Is always 0.0 for triggers.
//手柄和触摸板的y轴数据范围为-1.0~1.0,扳机键一直为0值。
};/** the number of axes in the controller state */
/**控制器状态中的轴数量*/
static const uint32_t k_unControllerStateAxisCount = 5;/** Holds all the state of a controller at one moment in time. */
/**存储控制器某一时刻的所有状态*/
struct VRControllerState001_t
{// If packet num matches that on your prior call, then the controller state hasn't been changed since // your last call and there is no need to process it// 若包数量与前一次的调用相匹配,那么说明自最后一次调用以来,控制器状态没有改变过,因此不必对它进行处理。uint32_t unPacketNum;// bit flags for each of the buttons. Use ButtonMaskFromId to turn an ID into a mask// 每个按键的位标志。使用ButtonMaskFromId将一个ID号转换为一个掩码uint64_t ulButtonPressed;uint64_t ulButtonTouched;// 控制器模拟输入的轴数据// Axis data for the controller's analog inputsVRControllerAxis_t rAxis[ k_unControllerStateAxisCount ];
};typedef VRControllerState001_t VRControllerState_t;
3>.const char *GetButtonIdNameFromEnum( EVRButtonId eButtonId )
返回一个EVRButtonId枚举数值名
parameter:
EVRButtonId eButtonId - 返回名字的按钮ID号
4>.const char *GetControllerAxisTypeNameFromEnum( EVRControllerAxisType eAxisType )
返回一个EVRControllerAxisType枚举数值名
EVRControllerAxisType eAxisType - 需要返回名字的控制轴类型
5>.
bool HandleControllerOverlayInteractionAsMouse(
const vr::Compositor_OverlaySettings & overlaySettings,
vr::HmdVector2_t vecWindowClientPositionOnScreen,
vr::HmdVector2_t vecWindowClientSize,
vr::TrackedDeviceIndex_t unControllerDeviceIndex,
vr::EVRControllerEventOutputType eOutputType
)
处理来自控制器的输入,尽管它只是一个指向混合器overlay的鼠标。
parameter:
const vr::Compositor_OverlaySettings & overlaySettings - 把overlay设置当成一个窗口
vr::HmdVector2_t vecWindowClientPositionOnScreen - 屏幕上应用程序窗口的位置。只有当操作系统事件生成时才会使用。
vr::HmdVector2_t vecWindowClientSize - 应用程序窗口大小尺寸。虚拟鼠标位置将会被缩放到该尺寸
vr::TrackedDeviceIndex_t unControllerDeviceIndex - 要测试的针对该overlay的控制器的追踪设备索引号
vr::EVRControllerEventOutputType eOutputType - 决定输出应该怎样被呈现。必须是以下之一:
ControllerEventOutput_OSEvents - 在操作系统中该函数会生成事件,该事件将会被系统中激活的应用程序处理。
ControllerEventOutput_VREvents - 该函数会生成内部VR事件,该事件能够使用函数PollNextEvent查询到
处理来自控制器的输入,尽管它只是一个指向混合器overlay的鼠标。控制器类似于一个在Z轴上的激光指针。激光指针点与overlay相交的地方就是鼠标的位置,扳机就是鼠标的左键,追踪触摸板就是鼠标右键。
当使用系统事件输出时,调用者应该确保它已经激活了,为的是确保它可以接收到系统事件。
当控制器指向overlay以及一个事件产生时,它返回true。
6>.bool CaptureInputFocus()
告诉OpenVR该函数想要独占访问控制器按钮状态以及按钮事件。
使用一个VREvent_InputFocusCaptured事件通知其他App,它们已经丢失输入焦点了。
当输入焦点因为某些原因不能捕获时,返回false。
7>.void ReleaseInputFocus()
告诉OpenVR该函数不再想要独占访问控制器按钮状态以及按钮事件。
使用一个VREvent_InputFocusReleased事件通知其他App,输入焦点已经释放了。
8>.bool IsInputFocusCapturedByAnotherProcess()
如果输入焦点被其他进程捕获返回true
================================================20170918==========
virtual void GetOutputDevice( uint64_t *pnDevice, ETextureType textureType ) = 0;
若成功执行,则该函数返回textureType所指定纹理类型的显卡设备,该显卡设备由指针pnDevice返回;若执行失败,则pnDevice会被设置为0
参考地址:https://github.com/ValveSoftware/openvr/wiki/IVRSystem_Overview