IVRCompositor允许应用程序用它来渲染3D内容。
vr::IVRCompositor接口提供访问Compositor子系统的接口。Compositor通过关注那些容易影响VR体验的操作比如畸变,预测,同步以及其他细微问题来简化显示图像到用户的流程。
应用程序调用WaitGetPoses来获得一系列姿态数据,用来渲染相机和其他追踪对象,像往常一样(使用IVRSystem接口提供的信息)渲染左右眼,同时最终将这些未畸变的纹理提交到Compositor(混合器)显示(在它自己的窗口显示)。
建议继续Present(呈现)应用程序自己的窗口,重复使用左或右眼相机渲染目标来绘制单个四边形(也许会裁剪到一个更低的视场角以便隐藏隐藏区域)
比如:
while Running:
WaitGetPoses
Render Left and Right cameras
Submit Left and Right render targets
Update game logic
另外,可能为了在整个相机共享单个渲染目标而串行化渲染,比如:
while Running:
WaitGetPoses
Render(L)
Submit(L)
Render(R)
Submit(R)
Update game logic
当应用程序退出时,或在一行内停止调用Submit超过10帧时,它淡退到一个空白格子场景中。这是为了避免让用户处在一个未追踪的环境中,以免用户翻倒或跑进墙里面去。当所有应用程序与混合器断开连接时,除非以命令行参数--keepalive启动,否则它会在2秒后自动退出。
枚举变量:
Compositor_DeviceType:为关联设备指定显卡API
enum Compositor_DeviceType
{
Compositor_DeviceType_None,
Compositor_DeviceType_D3D9,
Compositor_DeviceType_D3D9Ex,
Compositor_DeviceType_D3D10,
Compositor_DeviceType_D3D11,
Compositor_DeviceType_OpenGL
};
Compositor_FrameTiming:提供单个帧的时序信息到应用程序
始终为对应的版本将size变量设置为sizeof(Compositor_FrameTiming)以避免内存崩溃,在C#中使用方式如下:
(uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(Compositor_FrameTiming));
属性:
frameStart - 每帧的参考时间,这不一定是均匀分布的。
frameVSync - 从frameStart开始到下一个VSync时间。使用公式(current.frameStart + current.frameVSync)-(previous.frameStart + previouse.frameVSync)来计算帧间距。
droppedFrames - 自前一个帧开始由DXGI的GetFrameStatistics上报的droppedFrames(丢失帧)的数量。这是自最近一次调用它以来的一个PresentRefreshCount的delta值。它是无符号保存的,但是已知它是负的,因此在使用前需要先强制转换为int。
frameIndex - 每帧递增。可用低于更新的频率来调用GetFrameTiming遍历历史,直到看见认识的帧为止。
pose - 用于渲染该帧的Hmd姿态
struct Compositor_FrameTiming
{
uint32_t size; // sizeof(Compositor_FrameTiming)
double frameStart;
float frameVSync; // seconds from frame start
uint32_t droppedFrames;
uint32_t frameIndex;
vr::TrackedDevicePose_t pose;
};
Compositor_TextureBounds
运行应用程序控制要在帧缓冲中用到的纹理部分。
struct Compositor_TextureBounds
{
float uMin, vMin;
float uMax, vMax;
};
接口:
vr::IVRCompositor接口包含以下函数:
初始化:
GetLastError-返回混合器中最近发生的错误信息
virtual uint32_t GetLastError( VR_OUT_STRING() char* pchBuffer, uint32_t unBufferSize ) = 0;
核心函数:
WaitGetPoses:返回姿态信息以供渲染场景使用
virtual void WaitGetPoses( VR_ARRAY_COUNT(unPoseArrayCount) TrackedDevicePose_t* pPoseArray, uint32_t unPoseArrayCount ) = 0;
跟多关于姿态的信息,可参考IVRSystem::GetDeviceToAbsoluteTrackingPose
Submit:更新场景纹理到显示器,若pBounds为NULL,则整个纹理会被使用到。OpenGL dirty state:
glBindTexture
virtual void Submit( Hmd_Eye eEye, void* pTexture, Compositor_TextureBounds* pBounds ) = 0;
ClearLastSubmittedFrame:清除最后使用Submit提交的帧,这会引起混合器显示格子直到再次调用Submit。
virtual void ClearLastSubmittedFrame() = 0;
访问器:
SetGamma:给混合器窗口设置gamma值
virtual void SetGamma( float fGamma ) = 0;
GetGamma:获取混合器窗口的gamma值:
virtual float GetGamma() = 0;
SetTrackingSpace:设置由WaitGetPoses返回的追踪空间
virtual void SetTrackingSpace( TrackingUniverseOrigin eOrigin ) = 0;
GetTrackingSpace:获取由WaitGetPoses返回的当前追踪空间
virtual TrackingUniverseOrigin GetTrackingSpace() = 0;
SetVSync:开启或关闭混合器窗口的垂直同步功能
virtual void SetVSync( bool bVSync ) = 0;
GetVSync:若混合器窗口的垂直同步功能开启,则返回true
virtual bool GetVSync() = 0;
GetFrameTiming:若时序数据被设置则返回true。若nFramesAgo比保存历史大则设置最老的时序信息
确保在调用该函数前,设置timing.size = sizeof(Compositor_FrameTiming)。
历史缓冲当前保存最近128帧数据。
virtual bool GetFrameTiming( Compositor_FrameTiming *pTiming, uint32_t unFramesAgo = 0 ) = 0;
IsFullscreen:返回混合器是否全屏布尔值
virtual bool IsFullscreen() = 0;
淡化支持:
FadeToColor:将HMD视觉淡入到指定颜色。淡化接收参数fSeconds,介于0.0到1.0之间的颜色值。根据alpha参数该颜色在场景顶部淡化。设置FadeToColor(0.0, 0.0, 0.0, 0.0)则会删除淡化颜色。
virtual void FadeToColor( float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, bool bBackground = false ) = 0;
焦点:
CompositorBringToFront:将混合器窗口带到前面。这对覆盖在HMD上的任何窗口以达到朦胧效果很有用途。
virtual void CompositorBringToFront() = 0;
CompositorGoToBack:将混合器窗口推到后面去。这对允许其他应用程序要直接绘制到HMD很有帮助。
virtual void CompositorGoToBack() = 0;
CompositorQuit:告诉混合器进程要清空资源并退出了。shutdown时不一定要调用该函数。一般情况下,混合器会基于正在运行的应用程序来管理它自己的生命周期。
virtual void CompositorQuit() = 0;
参考网址