Advertisement
Guest User

ovr.cpp

a guest
Apr 21st, 2016
314
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.56 KB | None | 0 0
  1.  
  2. #include <OVR.h>
  3.  
  4. #if defined(eiBUILD_ENABLE_PC_D3D9)
  5. #   include "../src/gx/api_d9.h"
  6. #elif defined(eiBUILD_ENABLE_PC_D3D11)
  7. #   include "../src/gx/api_d11.h"
  8. #elif defined(eiBUILD_ENABLE_PC_D3D12)
  9. #   include "../src/gx/api_d12.h"
  10. #else
  11. #   error "Unknown renderer"
  12. #endif
  13.  
  14. #include<OVR_CAPI_D3D.h>
  15. #include <eight/core/alloc/new.h>
  16. #include <eight/core/alloc/scope.h>
  17. #include <eight/core/os/window.h>
  18. #include <eight/vr/ovr.h>
  19. #include <stdio.h>
  20. #include "eight/gx/device.h"
  21. #include "eight/gx/texture.h"
  22.  
  23. #undef near
  24. #undef far
  25.  
  26. //#pragma optimize("",off)//!!!!!
  27.  
  28. using namespace OVR;
  29. using namespace eight;
  30.  
  31. eiSTATIC_ASSERT(ovrEye_Count==2);
  32.  
  33. namespace eight {
  34.     namespace internal {
  35.         void Dx11Device_PatchRtv( void* device, TextureId tex, void* view );
  36. }}
  37. extern bool g_vsync;//todo - hack
  38.  
  39. class OculusDeviceImpl : NonCopyable
  40. {
  41. public:
  42.     ~OculusDeviceImpl()
  43.     {
  44.         for( uint e = 0; e != 2; ++e )
  45.         {
  46.             for( uint i = 0, end=rtvs[e].size(); i != end; ++i )
  47.                 rtvs[e][i]->Release();
  48.             if( swapSet[e] )
  49.                 ovr_DestroySwapTextureSet( session, swapSet[e] );
  50.         }
  51.         if( mirrorTexture )
  52.             ovr_DestroyMirrorTexture( session, mirrorTexture );
  53.         if( session )
  54.             ovr_Destroy(session);
  55.     }
  56.     OculusDeviceImpl( Scope& a, OsWindowArgs* wnd, GpuInterface& gpu, bool& error )
  57.         : isVisible(true)
  58.         , session()
  59.         , hmd()
  60.         , mirrorTexture()
  61.     {
  62.         g_vsync = false;//hack
  63.         for( uint e = 0; e != 2; ++e )
  64.             swapSet[e] = 0;
  65.  
  66.         const char* detectionMessage = 0;
  67.         int         detectionResult = IDCONTINUE;
  68.         do
  69.         {
  70.             ovrResult result = session ? ovrSuccess : ovr_Create(&session, &adapter);
  71.             if(OVR_FAILURE(result))
  72.                 detectionMessage = "Oculus Rift not detected.";
  73.             else
  74.             {
  75.                 hmd = ovr_GetHmdDesc(session);
  76.                 if (hmd.Type == ovrHmd_None)
  77.                     detectionMessage = "Rift detected, display not enabled.";
  78.             }
  79.  
  80.             if (detectionMessage)
  81.             {
  82.             /*  String messageText(detectionMessage);
  83.                 messageText += "\n\n"
  84.                     "Press 'Try Again' to run retry detection.\n"
  85.                     "Press 'Continue' to run full-screen anyway.";*/
  86.  
  87.                 detectionResult = ::MessageBoxA(0, detectionMessage, "Oculus Rift Detection",
  88.                     MB_CANCELTRYCONTINUE|MB_ICONWARNING);
  89.  
  90.                 if (detectionResult == IDCANCEL)
  91.                 {
  92.                     error = true;
  93.                     return;
  94.                 }
  95.             }
  96.         } while (detectionResult != IDCONTINUE);
  97.  
  98.         //if( !hmd )
  99.         //{
  100.         //  hmd = ovrHmd_CreateDebug(ovrHmd_DK2);
  101.         //  if( !hmd )
  102.         //  {
  103.         //      error = true;
  104.         //      return;
  105.         //  }
  106.         //}
  107.  
  108.         //Configure Stereo settings.
  109.         if (hmd.Type == ovrHmd_None)
  110.         {
  111.             texSize[0].w = 1280;
  112.             texSize[0].h = 1440;
  113.             texSize[1] = texSize[0];
  114.         }
  115.         else
  116.         {
  117.             extern float g_vrResScale;
  118.             texSize[0] = ovr_GetFovTextureSize( session, ovrEye_Left,  hmd.DefaultEyeFov[0], g_vrResScale );
  119.             texSize[1] = ovr_GetFovTextureSize( session, ovrEye_Right, hmd.DefaultEyeFov[1], g_vrResScale );
  120.         }
  121.         renderTargetSize.w = max( texSize[0].w, texSize[1].w );
  122.         renderTargetSize.h = max( texSize[0].h, texSize[1].h );
  123.  
  124.         eyeRenderViewport[0].Pos  = Vector2i(0,0);
  125.         eyeRenderViewport[0].Size = texSize[0];
  126.         eyeRenderViewport[1].Pos  = Vector2i(0, 0);
  127.         eyeRenderViewport[1].Size = texSize[1];
  128.  
  129.         eyeRenderDesc[0] = ovr_GetRenderDesc( session, ovrEye_Left,  hmd.DefaultEyeFov[0] );
  130.         eyeRenderDesc[1] = ovr_GetRenderDesc( session, ovrEye_Right, hmd.DefaultEyeFov[1] );
  131.  
  132.         if( wnd )
  133.         {
  134.             if (hmd.Type != ovrHmd_None)
  135.             {
  136.                 wnd->width = hmd.Resolution.w;
  137.                 wnd->height = hmd.Resolution.h;
  138.             }
  139.         }
  140.         extern float g_DisplayHz;
  141.         g_DisplayHz = hmd.DisplayRefreshRate;//todo - move
  142.     }
  143.     void GetRenderTargetSize( uint& w, uint& h ) const
  144.     {
  145.         w = renderTargetSize.w;
  146.         h = renderTargetSize.h;
  147.     }
  148.     u32 GetRenderTargetFlags() const
  149.     {
  150.         return TextureFlags::MiddlewareGlue;
  151.     }
  152.     void Attach( OsWindow& window, GpuDevice& gpu, TextureId backbuffer, TextureId left, TextureId right, u32 width, u32 height )
  153.     {
  154.         gxBackbuffer = backbuffer;
  155.         gxHmdTargets[0] = left;
  156.         gxHmdTargets[1] = right;
  157.  
  158.         ovrResult result;
  159. #if defined(eiBUILD_ENABLE_PC_D3D11)
  160.         ID3D11Device* device = (ID3D11Device*)gpu.NativeHandle();
  161.  
  162.         D3D11_TEXTURE2D_DESC desc ={};
  163.         desc.Width = renderTargetSize.w;
  164.         desc.Height = renderTargetSize.h;
  165.         desc.MipLevels = 1;
  166.         desc.ArraySize = 1;
  167.         desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
  168.         desc.SampleDesc.Count = 1;
  169.         desc.SampleDesc.Quality = 0;
  170.         desc.Usage = D3D11_USAGE_DEFAULT;
  171.         desc.CPUAccessFlags = 0;
  172.         desc.MiscFlags = 0;
  173.         desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
  174.         for( uint e = 0; e != 2; ++e )
  175.         {
  176.             result = ovr_CreateSwapTextureSetD3D11( session, device, &desc, ovrSwapTextureSetD3D11_Typeless, &swapSet[e] );
  177.             if( OVR_FAILURE( result ) )
  178.             {
  179.                 eiASSERT( false );
  180.                 ovrErrorInfo errorInfo;
  181.                 ovr_GetLastErrorInfo( &errorInfo );
  182.                 if( !OVR_SUCCESS( errorInfo.Result ) )
  183.                     eiError( errorInfo.ErrorString );
  184.             }
  185.         }
  186.  
  187.         if( true )//todo - mirror option
  188.         {
  189.             desc.Width = width;
  190.             desc.Height = height;
  191.             result = ovr_CreateMirrorTextureD3D11( session, device, &desc, 0, &mirrorTexture );
  192.             eiASSERT( OVR_SUCCESS( result ) );
  193.         }
  194.  
  195.         for( uint e = 0; e != 2; ++e )
  196.         {
  197.             rtvs[e].reserve(swapSet[e]->TextureCount);
  198.             for (int i = 0; i < swapSet[e]->TextureCount; ++i)
  199.             {
  200.                 ovrD3D11Texture* tex = (ovrD3D11Texture*)&swapSet[e]->Textures[i];
  201.                 D3D11_RENDER_TARGET_VIEW_DESC rtvd = {};
  202.                 rtvd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  203.                 rtvd.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
  204.                 ID3D11RenderTargetView* result = 0;
  205.                 device->CreateRenderTargetView(tex->D3D11.pTexture, &rtvd, &result);
  206.                 rtvs[e].push_back(result);
  207.             }
  208.             internal::Dx11Device_PatchRtv( &gpu, gxHmdTargets[e], rtvs[e][0] );
  209.         }
  210.        
  211. #else
  212. #error
  213. #endif
  214.     }
  215.     void GetViewports( Viewport views[2] )
  216.     {
  217.         for (int i = 0; i != 2; ++i)
  218.         {
  219.             ovrRecti& rect = eyeRenderViewport[i];
  220.             views[i].x = rect.Pos.x;
  221.             views[i].y = rect.Pos.y;
  222.             views[i].w = rect.Size.w;
  223.             views[i].h = rect.Size.h;
  224.         }
  225.     }
  226.     void GetViewData( ViewData views[2], float near, float far )
  227.     {
  228.         eiSTATIC_ASSERT( sizeof(Mat4) == sizeof(Matrix4f) );
  229.         eiSTATIC_ASSERT( sizeof(Vec4) >= sizeof(ovrVector3f) );
  230.         for (int i = 0; i != 2; ++i)
  231.         {
  232.             Matrix4f outOrient;
  233.             ovrVector3f outTrans;
  234.             outOrient = Matrix4f(eyeRenderPose[i].Orientation);
  235.             outTrans.x = eyeRenderPose[i].Position.x;// + trackingState.LeveledCameraPose.Position.x;
  236.             outTrans.y = eyeRenderPose[i].Position.y;// + trackingState.LeveledCameraPose.Position.y;
  237.             outTrans.z = eyeRenderPose[i].Position.z;// + trackingState.LeveledCameraPose.Position.z;
  238.             views[i].projection = Transpose((Mat4&)ovrMatrix4f_Projection(eyeRenderDesc[i].Fov, near, far, 0));
  239.             views[i].orientation = Mat4::Scale(-1,-1,1) * ((Mat4&)outOrient) * Mat4::Translation(((Vec4&)outTrans)) * Mat4::Scale(-1,-1,1);
  240.         }
  241.     }
  242.     bool BeginFrame( GpuDevice& gpu )
  243.     {
  244.         double frameTime = ovr_GetPredictedDisplayTime(session, 0);
  245.         sensorSampleTime = ovr_GetTimeInSeconds();
  246.         trackingState = ovr_GetTrackingState(session, frameTime, ovrTrue);
  247.         ovrVector3f HmdToEyeViewOffset[2] = { eyeRenderDesc[0].HmdToEyeViewOffset,
  248.                                               eyeRenderDesc[1].HmdToEyeViewOffset };
  249.         ovr_CalcEyePoses(trackingState.HeadPose.ThePose, HmdToEyeViewOffset, eyeRenderPose);
  250.  
  251.         if(!isVisible)
  252.             return false;
  253.  
  254.         for( uint e = 0; e != 2; ++e )
  255.         {
  256.             swapSet[e]->CurrentIndex = (swapSet[e]->CurrentIndex + 1) % swapSet[e]->TextureCount;
  257.             int texIndex = swapSet[e]->CurrentIndex;
  258.  
  259.             internal::Dx11Device_PatchRtv( &gpu, gxHmdTargets[e], rtvs[e][texIndex] );
  260.         }
  261.  
  262.         return true;
  263.     }
  264.     bool EndFrame(GpuDevice& gpu)
  265.     {      
  266.         ovrLayerEyeFov ld = {};
  267.         ld.Header.Type = ovrLayerType_EyeFov;
  268.         ld.Header.Flags = ovrLayerFlag_HighQuality;
  269.        
  270.         for (int eye = 0; eye < 2; ++eye)
  271.         {
  272.             ld.ColorTexture[eye] = swapSet[eye];
  273.             ld.Viewport[eye] = eyeRenderViewport[eye];
  274.             ld.Fov[eye] = hmd.DefaultEyeFov[eye];
  275.             ld.RenderPose[eye] = eyeRenderPose[eye];
  276.             ld.SensorSampleTime = sensorSampleTime;
  277.         }
  278.  
  279.         ovrLayerHeader* layers = &ld.Header;
  280.         ovrResult result = ovr_SubmitFrame(session, 0, nullptr, &layers, 1);
  281.         if (!OVR_SUCCESS(result))
  282.             return false;
  283.        
  284.         GpuContext& ctx = gpu.GetImmediateContext();
  285.         ctx.InvalidateCache();
  286. #if defined(eiBUILD_ENABLE_PC_D3D11)
  287.         ID3D11DeviceContext* context = (ID3D11DeviceContext*)ctx.NativeHandle();
  288.         if( mirrorTexture )
  289.         {
  290.             ovrD3D11Texture* tex = (ovrD3D11Texture*)mirrorTexture;
  291.             context->CopyResource((ID3D11Resource*)gpu.NativeResourceHandle(gxBackbuffer), tex->D3D11.pTexture);
  292.             g_vsync = false;//hack
  293.         }
  294.         gpu.Present(TextureId(0));
  295. #else
  296. #error asdf
  297. #endif
  298.         return true;
  299.     }
  300.     void GetAdapter( GfxAdapterId& out ) const
  301.     {
  302.         out = &adapter;
  303.     }
  304. private:
  305.     bool isVisible;
  306.     ovrSession         session;
  307.     ovrHmdDesc         hmd;
  308.     ovrGraphicsLuid    adapter;
  309.     ovrEyeRenderDesc   eyeRenderDesc[2];
  310.     Sizei              texSize[2];
  311.     Sizei              renderTargetSize;
  312.     ovrRecti           eyeRenderViewport[2];
  313.     ovrPosef           eyeRenderPose[2];
  314.     ovrSwapTextureSet* swapSet[2];
  315.     ovrTexture*        mirrorTexture;
  316.     ovrTrackingState   trackingState;
  317.     double             sensorSampleTime;
  318.     TextureId          gxBackbuffer;
  319.     TextureId          gxHmdTargets[2];
  320.     rde::vector<ID3D11RenderTargetView*> rtvs[2];
  321. };
  322.  
  323. class OculusSystemImpl : NonCopyable
  324. {
  325. public:
  326.     OculusSystemImpl();
  327.     ~OculusSystemImpl();
  328.     OculusDevice* CreateDevice( Scope&, GpuInterface&, OsWindowArgs* );
  329. };
  330.  
  331. eiImplementInterface( OculusSystem, OculusSystemImpl );
  332. eiInterfaceConstructor( OculusSystem, () );
  333. eiInterfaceFunction( OculusDevice*, OculusSystem, CreateDevice, (a,b,c), Scope& a, GpuInterface& b, OsWindowArgs* c );
  334.  
  335. eiImplementInterface( OculusDevice, OculusDeviceImpl );
  336. eiInterfaceFunctionConst( void, OculusDevice, GetRenderTargetSize, (a,b), uint& a, uint& b );
  337. eiInterfaceFunctionConst( u32, OculusDevice, GetRenderTargetFlags, (), );
  338. eiInterfaceFunction( void, OculusDevice, Attach, (a, b, c, d, e, f, g), OsWindow& a, GpuDevice& b, TextureId c, TextureId d, TextureId e, u32 f, u32 g );
  339. eiInterfaceFunction( void, OculusDevice, GetViewports, (a), Viewport a[2] );
  340. eiInterfaceFunction( void, OculusDevice, GetViewData, (a,b,c), ViewData a[2], float b, float c );
  341. eiInterfaceFunction( bool, OculusDevice, BeginFrame, (a), GpuDevice& a );
  342. eiInterfaceFunction( bool, OculusDevice, EndFrame, (a), GpuDevice& a );
  343. eiInterfaceFunctionConst( void, OculusDevice, GetAdapter, (a), GfxAdapterId& a );
  344.  
  345. static OculusSystemImpl* g_singleton = 0;
  346.  
  347. eiInfoGroup(Ovr,true);
  348. void OVR_CDECL EiOvrLogCallback(uintptr_t userData, int level, const char* message)
  349. {
  350.     switch(level)
  351.     {
  352. #if eiDEBUG_LEVEL > 0
  353.         case ovrLogLevel_Debug:
  354. #endif
  355.         case ovrLogLevel_Info:
  356.             eiInfo(Ovr,message);
  357.             break;
  358.         case ovrLogLevel_Error:
  359.             eiError(message);
  360.             break;
  361.     };
  362. }
  363.  
  364. OculusSystemImpl::OculusSystemImpl()
  365. {
  366.     eiASSERT( g_singleton == NULL );
  367.     ovrInitParams params = {};
  368.     params.LogCallback = &EiOvrLogCallback;
  369.     ovrResult ok = ovr_Initialize(&params);
  370.     if(OVR_FAILURE(ok)) {
  371.         ovrErrorInfo errorInfo;
  372.         ovr_GetLastErrorInfo(&errorInfo);
  373.         eiError("ovr_Initialize failed: %s", errorInfo.ErrorString);
  374.         //todo!!
  375.         eiASSERT( false );
  376.     }
  377.     else
  378.         g_singleton = this;
  379. }
  380.  
  381. OculusSystemImpl::~OculusSystemImpl()
  382. {
  383.     if( g_singleton == this )
  384.     {
  385.         ovr_Shutdown();
  386.         g_singleton = NULL;
  387.     }
  388. }
  389.  
  390. OculusDevice* OculusSystemImpl::CreateDevice( Scope& a, GpuInterface& gpu, OsWindowArgs* wnd )
  391. {
  392.     bool error = false;
  393.     OculusDeviceImpl* device = eiNew(a, OculusDeviceImpl)(a, wnd, gpu, error);
  394.     return (OculusDevice*)(error ? 0 : device);
  395. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement