Improve openvr, also add a module for it.

This commit is contained in:
James Urquhart 2016-04-25 23:26:27 +01:00
parent ba91478fad
commit 126828131d
4 changed files with 199 additions and 14 deletions

View file

@ -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)

View file

@ -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 "

View file

@ -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;

View file

@ -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()