Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <OVR.h>
- #if defined(eiBUILD_ENABLE_PC_D3D9)
- # include "../src/gx/api_d9.h"
- #elif defined(eiBUILD_ENABLE_PC_D3D11)
- # include "../src/gx/api_d11.h"
- #elif defined(eiBUILD_ENABLE_PC_D3D12)
- # include "../src/gx/api_d12.h"
- #else
- # error "Unknown renderer"
- #endif
- #include<OVR_CAPI_D3D.h>
- #include <eight/core/alloc/new.h>
- #include <eight/core/alloc/scope.h>
- #include <eight/core/os/window.h>
- #include <eight/vr/ovr.h>
- #include <stdio.h>
- #include "eight/gx/device.h"
- #include "eight/gx/texture.h"
- #undef near
- #undef far
- //#pragma optimize("",off)//!!!!!
- using namespace OVR;
- using namespace eight;
- eiSTATIC_ASSERT(ovrEye_Count==2);
- namespace eight {
- namespace internal {
- void Dx11Device_PatchRtv( void* device, TextureId tex, void* view );
- }}
- extern bool g_vsync;//todo - hack
- class OculusDeviceImpl : NonCopyable
- {
- public:
- ~OculusDeviceImpl()
- {
- for( uint e = 0; e != 2; ++e )
- {
- for( uint i = 0, end=rtvs[e].size(); i != end; ++i )
- rtvs[e][i]->Release();
- if( swapSet[e] )
- ovr_DestroySwapTextureSet( session, swapSet[e] );
- }
- if( mirrorTexture )
- ovr_DestroyMirrorTexture( session, mirrorTexture );
- if( session )
- ovr_Destroy(session);
- }
- OculusDeviceImpl( Scope& a, OsWindowArgs* wnd, GpuInterface& gpu, bool& error )
- : isVisible(true)
- , session()
- , hmd()
- , mirrorTexture()
- {
- g_vsync = false;//hack
- for( uint e = 0; e != 2; ++e )
- swapSet[e] = 0;
- const char* detectionMessage = 0;
- int detectionResult = IDCONTINUE;
- do
- {
- ovrResult result = session ? ovrSuccess : ovr_Create(&session, &adapter);
- if(OVR_FAILURE(result))
- detectionMessage = "Oculus Rift not detected.";
- else
- {
- hmd = ovr_GetHmdDesc(session);
- if (hmd.Type == ovrHmd_None)
- detectionMessage = "Rift detected, display not enabled.";
- }
- if (detectionMessage)
- {
- /* String messageText(detectionMessage);
- messageText += "\n\n"
- "Press 'Try Again' to run retry detection.\n"
- "Press 'Continue' to run full-screen anyway.";*/
- detectionResult = ::MessageBoxA(0, detectionMessage, "Oculus Rift Detection",
- MB_CANCELTRYCONTINUE|MB_ICONWARNING);
- if (detectionResult == IDCANCEL)
- {
- error = true;
- return;
- }
- }
- } while (detectionResult != IDCONTINUE);
- //if( !hmd )
- //{
- // hmd = ovrHmd_CreateDebug(ovrHmd_DK2);
- // if( !hmd )
- // {
- // error = true;
- // return;
- // }
- //}
- //Configure Stereo settings.
- if (hmd.Type == ovrHmd_None)
- {
- texSize[0].w = 1280;
- texSize[0].h = 1440;
- texSize[1] = texSize[0];
- }
- else
- {
- extern float g_vrResScale;
- texSize[0] = ovr_GetFovTextureSize( session, ovrEye_Left, hmd.DefaultEyeFov[0], g_vrResScale );
- texSize[1] = ovr_GetFovTextureSize( session, ovrEye_Right, hmd.DefaultEyeFov[1], g_vrResScale );
- }
- renderTargetSize.w = max( texSize[0].w, texSize[1].w );
- renderTargetSize.h = max( texSize[0].h, texSize[1].h );
- eyeRenderViewport[0].Pos = Vector2i(0,0);
- eyeRenderViewport[0].Size = texSize[0];
- eyeRenderViewport[1].Pos = Vector2i(0, 0);
- eyeRenderViewport[1].Size = texSize[1];
- eyeRenderDesc[0] = ovr_GetRenderDesc( session, ovrEye_Left, hmd.DefaultEyeFov[0] );
- eyeRenderDesc[1] = ovr_GetRenderDesc( session, ovrEye_Right, hmd.DefaultEyeFov[1] );
- if( wnd )
- {
- if (hmd.Type != ovrHmd_None)
- {
- wnd->width = hmd.Resolution.w;
- wnd->height = hmd.Resolution.h;
- }
- }
- extern float g_DisplayHz;
- g_DisplayHz = hmd.DisplayRefreshRate;//todo - move
- }
- void GetRenderTargetSize( uint& w, uint& h ) const
- {
- w = renderTargetSize.w;
- h = renderTargetSize.h;
- }
- u32 GetRenderTargetFlags() const
- {
- return TextureFlags::MiddlewareGlue;
- }
- void Attach( OsWindow& window, GpuDevice& gpu, TextureId backbuffer, TextureId left, TextureId right, u32 width, u32 height )
- {
- gxBackbuffer = backbuffer;
- gxHmdTargets[0] = left;
- gxHmdTargets[1] = right;
- ovrResult result;
- #if defined(eiBUILD_ENABLE_PC_D3D11)
- ID3D11Device* device = (ID3D11Device*)gpu.NativeHandle();
- D3D11_TEXTURE2D_DESC desc ={};
- desc.Width = renderTargetSize.w;
- desc.Height = renderTargetSize.h;
- desc.MipLevels = 1;
- desc.ArraySize = 1;
- desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
- desc.SampleDesc.Count = 1;
- desc.SampleDesc.Quality = 0;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.CPUAccessFlags = 0;
- desc.MiscFlags = 0;
- desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
- for( uint e = 0; e != 2; ++e )
- {
- result = ovr_CreateSwapTextureSetD3D11( session, device, &desc, ovrSwapTextureSetD3D11_Typeless, &swapSet[e] );
- if( OVR_FAILURE( result ) )
- {
- eiASSERT( false );
- ovrErrorInfo errorInfo;
- ovr_GetLastErrorInfo( &errorInfo );
- if( !OVR_SUCCESS( errorInfo.Result ) )
- eiError( errorInfo.ErrorString );
- }
- }
- if( true )//todo - mirror option
- {
- desc.Width = width;
- desc.Height = height;
- result = ovr_CreateMirrorTextureD3D11( session, device, &desc, 0, &mirrorTexture );
- eiASSERT( OVR_SUCCESS( result ) );
- }
- for( uint e = 0; e != 2; ++e )
- {
- rtvs[e].reserve(swapSet[e]->TextureCount);
- for (int i = 0; i < swapSet[e]->TextureCount; ++i)
- {
- ovrD3D11Texture* tex = (ovrD3D11Texture*)&swapSet[e]->Textures[i];
- D3D11_RENDER_TARGET_VIEW_DESC rtvd = {};
- rtvd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- rtvd.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
- ID3D11RenderTargetView* result = 0;
- device->CreateRenderTargetView(tex->D3D11.pTexture, &rtvd, &result);
- rtvs[e].push_back(result);
- }
- internal::Dx11Device_PatchRtv( &gpu, gxHmdTargets[e], rtvs[e][0] );
- }
- #else
- #error
- #endif
- }
- void GetViewports( Viewport views[2] )
- {
- for (int i = 0; i != 2; ++i)
- {
- ovrRecti& rect = eyeRenderViewport[i];
- views[i].x = rect.Pos.x;
- views[i].y = rect.Pos.y;
- views[i].w = rect.Size.w;
- views[i].h = rect.Size.h;
- }
- }
- void GetViewData( ViewData views[2], float near, float far )
- {
- eiSTATIC_ASSERT( sizeof(Mat4) == sizeof(Matrix4f) );
- eiSTATIC_ASSERT( sizeof(Vec4) >= sizeof(ovrVector3f) );
- for (int i = 0; i != 2; ++i)
- {
- Matrix4f outOrient;
- ovrVector3f outTrans;
- outOrient = Matrix4f(eyeRenderPose[i].Orientation);
- outTrans.x = eyeRenderPose[i].Position.x;// + trackingState.LeveledCameraPose.Position.x;
- outTrans.y = eyeRenderPose[i].Position.y;// + trackingState.LeveledCameraPose.Position.y;
- outTrans.z = eyeRenderPose[i].Position.z;// + trackingState.LeveledCameraPose.Position.z;
- views[i].projection = Transpose((Mat4&)ovrMatrix4f_Projection(eyeRenderDesc[i].Fov, near, far, 0));
- views[i].orientation = Mat4::Scale(-1,-1,1) * ((Mat4&)outOrient) * Mat4::Translation(((Vec4&)outTrans)) * Mat4::Scale(-1,-1,1);
- }
- }
- bool BeginFrame( GpuDevice& gpu )
- {
- double frameTime = ovr_GetPredictedDisplayTime(session, 0);
- sensorSampleTime = ovr_GetTimeInSeconds();
- trackingState = ovr_GetTrackingState(session, frameTime, ovrTrue);
- ovrVector3f HmdToEyeViewOffset[2] = { eyeRenderDesc[0].HmdToEyeViewOffset,
- eyeRenderDesc[1].HmdToEyeViewOffset };
- ovr_CalcEyePoses(trackingState.HeadPose.ThePose, HmdToEyeViewOffset, eyeRenderPose);
- if(!isVisible)
- return false;
- for( uint e = 0; e != 2; ++e )
- {
- swapSet[e]->CurrentIndex = (swapSet[e]->CurrentIndex + 1) % swapSet[e]->TextureCount;
- int texIndex = swapSet[e]->CurrentIndex;
- internal::Dx11Device_PatchRtv( &gpu, gxHmdTargets[e], rtvs[e][texIndex] );
- }
- return true;
- }
- bool EndFrame(GpuDevice& gpu)
- {
- ovrLayerEyeFov ld = {};
- ld.Header.Type = ovrLayerType_EyeFov;
- ld.Header.Flags = ovrLayerFlag_HighQuality;
- for (int eye = 0; eye < 2; ++eye)
- {
- ld.ColorTexture[eye] = swapSet[eye];
- ld.Viewport[eye] = eyeRenderViewport[eye];
- ld.Fov[eye] = hmd.DefaultEyeFov[eye];
- ld.RenderPose[eye] = eyeRenderPose[eye];
- ld.SensorSampleTime = sensorSampleTime;
- }
- ovrLayerHeader* layers = &ld.Header;
- ovrResult result = ovr_SubmitFrame(session, 0, nullptr, &layers, 1);
- if (!OVR_SUCCESS(result))
- return false;
- GpuContext& ctx = gpu.GetImmediateContext();
- ctx.InvalidateCache();
- #if defined(eiBUILD_ENABLE_PC_D3D11)
- ID3D11DeviceContext* context = (ID3D11DeviceContext*)ctx.NativeHandle();
- if( mirrorTexture )
- {
- ovrD3D11Texture* tex = (ovrD3D11Texture*)mirrorTexture;
- context->CopyResource((ID3D11Resource*)gpu.NativeResourceHandle(gxBackbuffer), tex->D3D11.pTexture);
- g_vsync = false;//hack
- }
- gpu.Present(TextureId(0));
- #else
- #error asdf
- #endif
- return true;
- }
- void GetAdapter( GfxAdapterId& out ) const
- {
- out = &adapter;
- }
- private:
- bool isVisible;
- ovrSession session;
- ovrHmdDesc hmd;
- ovrGraphicsLuid adapter;
- ovrEyeRenderDesc eyeRenderDesc[2];
- Sizei texSize[2];
- Sizei renderTargetSize;
- ovrRecti eyeRenderViewport[2];
- ovrPosef eyeRenderPose[2];
- ovrSwapTextureSet* swapSet[2];
- ovrTexture* mirrorTexture;
- ovrTrackingState trackingState;
- double sensorSampleTime;
- TextureId gxBackbuffer;
- TextureId gxHmdTargets[2];
- rde::vector<ID3D11RenderTargetView*> rtvs[2];
- };
- class OculusSystemImpl : NonCopyable
- {
- public:
- OculusSystemImpl();
- ~OculusSystemImpl();
- OculusDevice* CreateDevice( Scope&, GpuInterface&, OsWindowArgs* );
- };
- eiImplementInterface( OculusSystem, OculusSystemImpl );
- eiInterfaceConstructor( OculusSystem, () );
- eiInterfaceFunction( OculusDevice*, OculusSystem, CreateDevice, (a,b,c), Scope& a, GpuInterface& b, OsWindowArgs* c );
- eiImplementInterface( OculusDevice, OculusDeviceImpl );
- eiInterfaceFunctionConst( void, OculusDevice, GetRenderTargetSize, (a,b), uint& a, uint& b );
- eiInterfaceFunctionConst( u32, OculusDevice, GetRenderTargetFlags, (), );
- 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 );
- eiInterfaceFunction( void, OculusDevice, GetViewports, (a), Viewport a[2] );
- eiInterfaceFunction( void, OculusDevice, GetViewData, (a,b,c), ViewData a[2], float b, float c );
- eiInterfaceFunction( bool, OculusDevice, BeginFrame, (a), GpuDevice& a );
- eiInterfaceFunction( bool, OculusDevice, EndFrame, (a), GpuDevice& a );
- eiInterfaceFunctionConst( void, OculusDevice, GetAdapter, (a), GfxAdapterId& a );
- static OculusSystemImpl* g_singleton = 0;
- eiInfoGroup(Ovr,true);
- void OVR_CDECL EiOvrLogCallback(uintptr_t userData, int level, const char* message)
- {
- switch(level)
- {
- #if eiDEBUG_LEVEL > 0
- case ovrLogLevel_Debug:
- #endif
- case ovrLogLevel_Info:
- eiInfo(Ovr,message);
- break;
- case ovrLogLevel_Error:
- eiError(message);
- break;
- };
- }
- OculusSystemImpl::OculusSystemImpl()
- {
- eiASSERT( g_singleton == NULL );
- ovrInitParams params = {};
- params.LogCallback = &EiOvrLogCallback;
- ovrResult ok = ovr_Initialize(¶ms);
- if(OVR_FAILURE(ok)) {
- ovrErrorInfo errorInfo;
- ovr_GetLastErrorInfo(&errorInfo);
- eiError("ovr_Initialize failed: %s", errorInfo.ErrorString);
- //todo!!
- eiASSERT( false );
- }
- else
- g_singleton = this;
- }
- OculusSystemImpl::~OculusSystemImpl()
- {
- if( g_singleton == this )
- {
- ovr_Shutdown();
- g_singleton = NULL;
- }
- }
- OculusDevice* OculusSystemImpl::CreateDevice( Scope& a, GpuInterface& gpu, OsWindowArgs* wnd )
- {
- bool error = false;
- OculusDeviceImpl* device = eiNew(a, OculusDeviceImpl)(a, wnd, gpu, error);
- return (OculusDevice*)(error ? 0 : device);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement