浏览代码

Improve openvr, also add a module for it.

James Urquhart 9 年之前
父节点
当前提交
126828131d

+ 11 - 11
Engine/source/gfx/gfxInit.cpp

@@ -293,19 +293,19 @@ GFXAdapter *GFXInit::getBestAdapterChoice()
    // Get the user's preference for device...
    const String   renderer   = Con::getVariable("$pref::Video::displayDevice");
    const String   outputDevice = Con::getVariable("$pref::Video::displayOutputDevice");
-	const String   adapterDevice = Con::getVariable("$Video::forceDisplayAdapter");
+   const String   adapterDevice = Con::getVariable("$Video::forceDisplayAdapter");
 
-	GFXAdapterType adapterType = getAdapterTypeFromName(renderer.c_str());;
-	GFXAdapter     *adapter;
+   GFXAdapterType adapterType = getAdapterTypeFromName(renderer.c_str());;
+   GFXAdapter     *adapter;
 
-	if (adapterDevice.isEmpty())
-	{
-		adapter = chooseAdapter(adapterType, outputDevice.c_str());
-	}
-	else
-	{
-		adapter = chooseAdapter(adapterType, dAtoi(adapterDevice.c_str()));
-	}
+   if (adapterDevice.isEmpty())
+   {
+      adapter = chooseAdapter(adapterType, outputDevice.c_str());
+   }
+   else if (dAtoi(adapterDevice.c_str()) != -1)
+   {
+      adapter = chooseAdapter(adapterType, dAtoi(adapterDevice.c_str()));
+   }
 
    // Did they have one? Return it.
    if(adapter)

+ 115 - 3
Engine/source/platform/input/openVR/openVRProvider.cpp

@@ -11,6 +11,11 @@
 #include "gfx/D3D11/gfxD3D11EnumTranslate.h"
 #include "gfx/gfxStringEnumTranslate.h"
 
+
+#include "gfx/D3D9/gfxD3D9Device.h"
+#include "gfx/D3D9/gfxD3D9TextureObject.h"
+#include "gfx/D3D9/gfxD3D9EnumTranslate.h"
+
 /*
 #include "gfx/gl/gfxGLDevice.h"
 #include "gfx/gl/gfxGLTextureObject.h"
@@ -20,6 +25,8 @@
 #include "platform/input/oculusVR/oculusVRUtil.h"
 
 
+//------------------------------------------------------------
+
 U32 OpenVRProvider::OVR_SENSORROT[vr::k_unMaxTrackedDeviceCount] = { 0 };
 U32 OpenVRProvider::OVR_SENSORROTANG[vr::k_unMaxTrackedDeviceCount] = { 0 };
 U32 OpenVRProvider::OVR_SENSORVELOCITY[vr::k_unMaxTrackedDeviceCount] = { 0 };
@@ -108,6 +115,9 @@ bool OpenVRRenderState::setupRenderTargets(U32 mode)
 
    mEyeRT[0] = mEyeRT[1] = mStereoRT;
 
+   mOutputEyeTextures[0].init(newRTSize.x, newRTSize.y, GFXFormatR8G8B8A8, &VRTextureProfile, "OpenVR Stereo RT Color OUTPUT");
+   mOutputEyeTextures[1].init(newRTSize.x, newRTSize.y, GFXFormatR8G8B8A8, &VRTextureProfile, "OpenVR Stereo RT Color OUTPUT");
+
    return true;
 }
 
@@ -272,6 +282,9 @@ void OpenVRRenderState::reset(vr::IVRSystem* hmd)
    mDistortionVerts = NULL;
    mDistortionInds = NULL;
 
+   mOutputEyeTextures[0].clear();
+   mOutputEyeTextures[1].clear();
+
    if (!mHMD)
       return;
 
@@ -303,6 +316,7 @@ OpenVRProvider::OpenVRProvider() :
    buildInputCodeTable();
    GFXDevice::getDeviceEventSignal().notify(this, &OpenVRProvider::_handleDeviceEvent);
    INPUTMGR->registerDevice(this);
+   dMemset(&mLUID, '\0', sizeof(mLUID));
 }
 
 OpenVRProvider::~OpenVRProvider()
@@ -334,6 +348,49 @@ bool OpenVRProvider::enable()
       return false;
    }
 
+   dMemset(&mLUID, '\0', sizeof(mLUID));
+
+#ifdef TORQUE_OS_WIN32
+
+   // For windows we need to lookup the DXGI record for this and grab the LUID for the display adapter. We need the LUID since 
+   // T3D uses EnumAdapters1 not EnumAdapters whereas openvr uses EnumAdapters.
+   int32_t AdapterIdx;
+   IDXGIAdapter* EnumAdapter;
+   IDXGIFactory1* DXGIFactory;
+   mHMD->GetDXGIOutputInfo(&AdapterIdx);
+   // Get the LUID of the device
+
+   HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&DXGIFactory));
+
+   if (FAILED(hr))
+	   AssertFatal(false, "OpenVRProvider::enable -> CreateDXGIFactory1 call failure");
+
+   hr = DXGIFactory->EnumAdapters(AdapterIdx, &EnumAdapter);
+
+   if (FAILED(hr))
+   {
+	   Con::warnf("VR: HMD device has an invalid adapter.");
+   }
+   else
+   {
+	   DXGI_ADAPTER_DESC desc;
+	   hr = EnumAdapter->GetDesc(&desc);
+	   if (FAILED(hr))
+	   {
+		   Con::warnf("VR: HMD device has an invalid adapter.");
+	   }
+	   else
+	   {
+		   dMemcpy(&mLUID, &desc.AdapterLuid, sizeof(mLUID));
+	   }
+	   SAFE_RELEASE(EnumAdapter);
+   }
+
+   SAFE_RELEASE(DXGIFactory);
+#endif
+
+
+
    mRenderModels = (vr::IVRRenderModels *)vr::VR_GetGenericInterface(vr::IVRRenderModels_Version, &eError);
    if (!mRenderModels)
    {
@@ -441,6 +498,9 @@ bool OpenVRProvider::process()
    if (!mHMD)
       return true;
 
+   if (!vr::VRCompositor())
+	   return true;
+
    // Process SteamVR events
    vr::VREvent_t event;
    while (mHMD->PollNextEvent(&event, sizeof(event)))
@@ -570,7 +630,7 @@ void OpenVRProvider::setDrawCanvas(GuiCanvas *canvas)
 
    if (!vr::VRCompositor())
    {
-      printf("Compositor initialization failed. See log file for details\n");
+      Con::errorf("VR: Compositor initialization failed. See log file for details\n");
       return;
    }
 
@@ -614,16 +674,30 @@ void OpenVRProvider::onEyeRendered(U32 index)
    if (!mHMD)
       return;
 
+   vr::EVRCompositorError err = vr::VRCompositorError_None;
+
+   GFXTexHandle eyeTex = mHMDRenderState.mOutputEyeTextures[index].getTextureHandle();
+   mHMDRenderState.mEyeRT[0]->resolveTo(eyeTex);
+   mHMDRenderState.mOutputEyeTextures[index].advance();
+
    if (GFX->getAdapterType() == Direct3D11)
    {
-      vr::Texture_t eyeTexture = { (void*)static_cast<GFXD3D11TextureObject*>(mHMDRenderState.mStereoRenderTextures[index].getPointer())->get2DTex(), vr::API_DirectX, vr::ColorSpace_Gamma };
-      vr::VRCompositor()->Submit((vr::EVREye)(vr::Eye_Left + index), &eyeTexture);
+	  GFXFormat fmt1 = eyeTex->getFormat();
+      vr::Texture_t eyeTexture = { (void*)static_cast<GFXD3D11TextureObject*>(eyeTex.getPointer())->get2DTex(), vr::API_DirectX, vr::ColorSpace_Gamma };
+      err = vr::VRCompositor()->Submit((vr::EVREye)(vr::Eye_Left + index), &eyeTexture);
+   }
+   else if (GFX->getAdapterType() == Direct3D9)
+   {
+	   //vr::Texture_t eyeTexture = { (void*)static_cast<GFXD3D9TextureObject*>(mHMDRenderState.mStereoRenderTextures[index].getPointer())->get2DTex(), vr::API_DirectX, vr::ColorSpace_Gamma };
+	   //err = vr::VRCompositor()->Submit((vr::EVREye)(vr::Eye_Left + index), &eyeTexture);
    }
    else if (GFX->getAdapterType() == OpenGL)
    {/*
       vr::Texture_t eyeTexture = { (void*)static_cast<GFXGLTextureObject*>(mHMDRenderState.mStereoRenderTextures[index].getPointer())->getHandle(), vr::API_OpenGL, vr::ColorSpace_Gamma };
       vr::VRCompositor()->Submit((vr::EVREye)(vr::Eye_Left + index), &eyeTexture);*/
    }
+
+   AssertFatal(err != vr::VRCompositorError_None, "VR compositor error!");
 }
 
 bool OpenVRProvider::_handleDeviceEvent(GFXDevice::GFXDeviceEventType evt)
@@ -675,6 +749,29 @@ bool OpenVRProvider::_handleDeviceEvent(GFXDevice::GFXDeviceEventType evt)
    return true;
 }
 
+S32 OpenVRProvider::getDisplayDeviceId() const
+{
+	return -1;
+#ifdef TORQUE_OS_WIN32
+	if (GFX->getAdapterType() == Direct3D11)
+	{
+		Vector<GFXAdapter*> adapterList;
+		GFXD3D11Device::enumerateAdapters(adapterList);
+
+		for (U32 i = 0, sz = adapterList.size(); i < sz; i++)
+		{
+			GFXAdapter* adapter = adapterList[i];
+			if (dMemcmp(&adapter->mLUID, &mLUID, sizeof(mLUID)) == 0)
+			{
+				return adapter->mIndex;
+			}
+		}
+	}
+#endif
+
+	return -1;
+}
+
 void OpenVRProvider::processVREvent(const vr::VREvent_t & event)
 {
    switch (event.eventType)
@@ -870,6 +967,21 @@ DefineEngineFunction(setOpenVRHMDAsGameConnectionDisplayDevice, bool, (GameConne
    return true;
 }
 
+
+DefineEngineFunction(OpenVRGetDisplayDeviceId, S32, (), ,
+	"@brief MacOS display ID.\n\n"
+	"@param index The HMD index.\n"
+	"@return The ID of the HMD display device, if any.\n"
+	"@ingroup Game")
+{
+	if (!ManagedSingleton<OpenVRProvider>::instanceOrNull())
+	{
+		return -1;
+	}
+
+	return ManagedSingleton<OpenVRProvider>::instance()->getDisplayDeviceId();
+}
+
 DefineEngineFunction(OpenVRResetSensors, void, (), ,
    "@brief Resets all Oculus VR sensors.\n\n"
    "This resets all sensor orientations such that their 'normal' rotation "

+ 43 - 0
Engine/source/platform/input/openVR/openVRProvider.h

@@ -20,6 +20,44 @@
 
 class OpenVRHMDDevice;
 
+class VRTextureSet
+{
+public:
+	static const int TextureCount = 2;
+	GFXTexHandle mTextures[2];
+	U32 mIndex;
+
+	VRTextureSet() : mIndex(0)
+	{
+	}
+
+	void init(U32 width, U32 height, GFXFormat fmt, GFXTextureProfile *profile, const String &desc)
+	{
+		for (U32 i = 0; i < TextureCount; i++)
+		{
+			mTextures[i].set(width, height, fmt, profile, desc);
+		}
+	}
+
+	void clear()
+	{
+		for (U32 i = 0; i < TextureCount; i++)
+		{
+			mTextures[i] = NULL;
+		}
+	}
+
+	void advance()
+	{
+		mIndex = (mIndex + 1) & TextureCount;
+	}
+
+	GFXTexHandle& getTextureHandle()
+	{
+		return mTextures[mIndex];
+	}
+};
+
 struct OpenVRRenderState
 {
    vr::IVRSystem *mHMD;
@@ -38,6 +76,8 @@ struct OpenVRRenderState
    GFXVertexBufferHandle<GFXVertexPTTT> mDistortionVerts;
    GFXPrimitiveBufferHandle mDistortionInds;
 
+   VRTextureSet mOutputEyeTextures[2];
+
    bool setupRenderTargets(U32 mode);
    void setupDistortion();
 
@@ -114,6 +154,8 @@ public:
    virtual void onEyeRendered(U32 index);
 
    bool _handleDeviceEvent(GFXDevice::GFXDeviceEventType evt);
+
+   S32 getDisplayDeviceId() const;
    /// }
 
    /// @name OpenVR handling
@@ -140,6 +182,7 @@ public:
    char mDeviceClassChar[vr::k_unMaxTrackedDeviceCount];
 
    OpenVRRenderState mHMDRenderState;
+   GFXAdapterLUID mLUID;
    /// }
 
    GuiCanvas* mDrawCanvas;

+ 30 - 0
Tools/CMake/modules/module_openvr.cmake

@@ -0,0 +1,30 @@
+
+# module openvr
+
+option(TORQUE_OPENVR "Enable openvr module" OFF)
+mark_as_advanced(TORQUE_OPENVR)
+if(TORQUE_OPENVR)
+	if(TORQUE_OCULUSVR_SDK_PATH STREQUAL "")
+		set(TORQUE_OPENVR_SDK_PATH "" CACHE PATH "openvr library path" FORCE)
+	endif()
+else() # hide variable
+    set(TORQUE_OPENVR_SDK_PATH "" CACHE INTERNAL "" FORCE) 
+endif() 
+ 
+if(TORQUE_OPENVR)
+	# Source
+	addPathRec( "${srcDir}/platform/input/openvr" )
+
+	# Includes
+	addInclude( "${TORQUE_OPENVR_SDK_PATH}/headers" )
+	 
+	# Libs
+	if( WIN32 ) 
+		if( TORQUE_CPU_X64 )
+		link_directories( "${TORQUE_OPENVR_SDK_PATH}/lib/win64" )
+		else()
+		link_directories( "${TORQUE_OPENVR_SDK_PATH}/lib/win32" )
+		endif()
+		addLib( "openvr_api" )
+	endif()
+endif()