From f2274d23785493cdccf817d6c92dae128c2e45ac Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 4 Aug 2014 19:19:15 +0200 Subject: [PATCH] OVR: Iterate devices --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/stereo_display.h | 1 + code/nel/include/nel/3d/stereo_ovr_04.h | 7 +- code/nel/src/3d/stereo_ovr_04.cpp | 193 ++++++++++-------- code/nel/src/3d/stereo_ovr_04_program.h | 247 +---------------------- code/ryzom/client/src/init.cpp | 12 +- 5 files changed, 121 insertions(+), 339 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_display.h b/code/nel/include/nel/3d/stereo_display.h index 78db78e07..f796bccfe 100644 --- a/code/nel/include/nel/3d/stereo_display.h +++ b/code/nel/include/nel/3d/stereo_display.h @@ -130,6 +130,7 @@ public: virtual bool endRenderTarget() = 0; static const char *getLibraryName(CStereoDeviceInfo::TStereoDeviceLibrary library); + // List all devices. Device creation factories are no longer valid after re-calling this function static void listDevices(std::vector &devicesOut); static IStereoDisplay *createDevice(const CStereoDeviceInfo &deviceInfo); static void releaseUnusedLibraries(); diff --git a/code/nel/include/nel/3d/stereo_ovr_04.h b/code/nel/include/nel/3d/stereo_ovr_04.h index 655424dfc..40ef4955b 100644 --- a/code/nel/include/nel/3d/stereo_ovr_04.h +++ b/code/nel/include/nel/3d/stereo_ovr_04.h @@ -64,8 +64,7 @@ namespace NL3D { class ITexture; class CTextureUser; -class CStereoOVRDevicePtr; -class CStereoOVRDeviceHandle; +class CStereoOVRDeviceFactory; /*class CPixelProgramOVR;*/ #define NL_STEREO_MAX_USER_CAMERAS 8 @@ -79,7 +78,7 @@ class CStereoOVRDeviceHandle; class CStereoOVR : public IStereoHMD { public: - CStereoOVR(const CStereoOVRDeviceHandle *handle); + CStereoOVR(const CStereoOVRDeviceFactory *handle); virtual ~CStereoOVR(); /// Sets driver and generates necessary render targets @@ -150,7 +149,7 @@ public: static void releaseLibrary(); private: - CStereoOVRDevicePtr *m_DevicePtr; + // CStereoOVRDevicePtr *m_DevicePtr; int m_Stage; int m_SubStage; CViewport m_RegularViewport; diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp index 5751af285..d31d1a82e 100644 --- a/code/nel/src/3d/stereo_ovr_04.cpp +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -70,87 +70,70 @@ using namespace std; namespace NL3D { -/*extern const char *g_StereoOVR_fp40; -extern const char *g_StereoOVR_arbfp1; -extern const char *g_StereoOVR_ps_2_0; -extern const char *g_StereoOVR_glsl330f;*/ - namespace { -/* -class CStereoOVRLog : public OVR::Log -{ -public: - CStereoOVRLog(unsigned logMask = OVR::LogMask_All) : OVR::Log(logMask) - { - } - - virtual void LogMessageVarg(OVR::LogMessageType messageType, const char* fmt, va_list argList) - { - if (NLMISC::INelContext::isContextInitialised()) - { - char buffer[MaxLogBufferMessageSize]; - FormatLog(buffer, MaxLogBufferMessageSize, messageType, fmt, argList); - if (IsDebugMessage(messageType)) - NLMISC::INelContext::getInstance().getDebugLog()->displayNL("OVR: %s", buffer); - else - NLMISC::INelContext::getInstance().getInfoLog()->displayNL("OVR: %s", buffer); - } - } -}; - -CStereoOVRLog *s_StereoOVRLog = NULL; -OVR::Ptr s_DeviceManager; +#include "stereo_ovr_04_program.h" class CStereoOVRSystem { public: - ~CStereoOVRSystem() + CStereoOVRSystem() : m_InitOk(false) { - Release(); + } - void Init() + ~CStereoOVRSystem() { - if (!s_StereoOVRLog) + if (m_InitOk) { - nldebug("Initialize OVR"); - s_StereoOVRLog = new CStereoOVRLog(); + nlwarning("OVR: Not all resources were released before exit"); + Release(); } - if (!OVR::System::IsInitialized()) - OVR::System::Init(s_StereoOVRLog); - if (!s_DeviceManager) - s_DeviceManager = OVR::DeviceManager::Create(); + } + + bool Init() + { + if (!m_InitOk) + { + nldebug("OVR: Initialize"); + m_InitOk = ovr_Initialize(); + nlassert(m_InitOk); + } + + return m_InitOk; } void Release() { - if (s_DeviceManager) + if (m_InitOk) { - nldebug("Release OVR"); - s_DeviceManager->Release(); + nldebug("OVR: Release"); + ovr_Shutdown(); + m_InitOk = false; } - s_DeviceManager.Clear(); - if (OVR::System::IsInitialized()) - OVR::System::Destroy(); - if (s_StereoOVRLog) - nldebug("Release OVR Ok"); - delete s_StereoOVRLog; - s_StereoOVRLog = NULL; } + +private: + bool m_InitOk; + }; CStereoOVRSystem s_StereoOVRSystem; sint s_DeviceCounter = 0; -*/ +uint s_DetectId = 0; + } -/* -class CStereoOVRDeviceHandle : public IStereoDeviceFactory + +class CStereoOVRDeviceFactory : public IStereoDeviceFactory { public: - // fixme: virtual destructor??? - OVR::DeviceEnumerator DeviceHandle; + uint DeviceIndex; + uint DetectId; + + bool DebugDevice; + ovrHmdType DebugDeviceType; + IStereoDisplay *createDevice() const { CStereoOVR *stereo = new CStereoOVR(this); @@ -161,6 +144,7 @@ public: } }; +/* class CStereoOVRDevicePtr { public: @@ -170,7 +154,8 @@ public: OVR::HMDInfo HMDInfo; }; */ -CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), /*m_SceneTexture(NULL),*/ m_GUITexture(NULL), /*m_PixelProgram(NULL),*/ m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) + +CStereoOVR::CStereoOVR(const CStereoOVRDeviceFactory *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), /*m_SceneTexture(NULL),*/ m_GUITexture(NULL), /*m_PixelProgram(NULL),*/ m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) { /*++s_DeviceCounter; m_DevicePtr = new CStereoOVRDevicePtr(); @@ -958,48 +943,84 @@ void CStereoOVR::setScale(float s) m_Scale = s; } + + void CStereoOVR::listDevices(std::vector &devicesOut) { - /* - s_StereoOVRSystem.Init(); - OVR::DeviceEnumerator devices = s_DeviceManager->EnumerateDevices(); - uint id = 1; - do - { - CStereoDeviceInfo deviceInfoOut; - OVR::DeviceInfo deviceInfo; - if (devices.IsAvailable()) - { - devices.GetDeviceInfo(&deviceInfo); - CStereoOVRDeviceHandle *handle = new CStereoOVRDeviceHandle(); - deviceInfoOut.Factory = static_cast(handle); - handle->DeviceHandle = devices; - deviceInfoOut.Class = CStereoDeviceInfo::StereoHMD; // 1; // OVR::HMDDevice - deviceInfoOut.Library = CStereoDeviceInfo::OVR; // "Oculus SDK"; - deviceInfoOut.Manufacturer = deviceInfo.Manufacturer; - deviceInfoOut.ProductName = deviceInfo.ProductName; - deviceInfoOut.AllowAuto = true; - stringstream ser; - ser << id; - deviceInfoOut.Serial = ser.str(); // can't get the real serial from the sdk... - devicesOut.push_back(deviceInfoOut); - ++id; - } + if (!s_StereoOVRSystem.Init()) + return; - } while (devices.Next());*/ + ++s_DetectId; + uint hmdDetect = ovrHmd_Detect(); + nldebug("OVR: Detected %u HMDs", hmdDetect); + + for (uint i = 0; i < hmdDetect; ++i) + { + devicesOut.resize(devicesOut.size() + 1); + CStereoDeviceInfo &deviceInfoOut = devicesOut[devicesOut.size() - 1]; + ovrHmd hmd = ovrHmd_Create(i); + CStereoOVRDeviceFactory *factory = new CStereoOVRDeviceFactory(); + factory->DetectId = s_DetectId; + factory->DeviceIndex = i; + factory->DebugDevice = false; + deviceInfoOut.Factory = factory; + deviceInfoOut.Class = CStereoDeviceInfo::StereoHMD; + deviceInfoOut.Library = CStereoDeviceInfo::OVR; + deviceInfoOut.Manufacturer = hmd->Manufacturer; + deviceInfoOut.ProductName = hmd->ProductName; + deviceInfoOut.AllowAuto = true; + deviceInfoOut.Serial = hmd->SerialNumber; + ovrHmd_Destroy(hmd); + } + +#if !FINAL_VERSION + // Debug DK1 + { + devicesOut.resize(devicesOut.size() + 1); + CStereoDeviceInfo &deviceInfoOut = devicesOut[devicesOut.size() - 1]; + ovrHmd hmd = ovrHmd_CreateDebug(ovrHmd_DK1); + CStereoOVRDeviceFactory *factory = new CStereoOVRDeviceFactory(); + factory->DebugDevice = true; + factory->DebugDeviceType = ovrHmd_DK1; + deviceInfoOut.Factory = factory; + deviceInfoOut.Class = CStereoDeviceInfo::StereoHMD; + deviceInfoOut.Library = CStereoDeviceInfo::OVR; + deviceInfoOut.Manufacturer = hmd->Manufacturer; + deviceInfoOut.ProductName = hmd->ProductName; + deviceInfoOut.AllowAuto = false; + deviceInfoOut.Serial = "OVR-DK1-DEBUG"; + ovrHmd_Destroy(hmd); + } + // Debug DK2 + { + devicesOut.resize(devicesOut.size() + 1); + CStereoDeviceInfo &deviceInfoOut = devicesOut[devicesOut.size() - 1]; + ovrHmd hmd = ovrHmd_CreateDebug(ovrHmd_DK2); + CStereoOVRDeviceFactory *factory = new CStereoOVRDeviceFactory(); + factory->DebugDevice = true; + factory->DebugDeviceType = ovrHmd_DK2; + deviceInfoOut.Factory = factory; + deviceInfoOut.Class = CStereoDeviceInfo::StereoHMD; + deviceInfoOut.Library = CStereoDeviceInfo::OVR; + deviceInfoOut.Manufacturer = hmd->Manufacturer; + deviceInfoOut.ProductName = hmd->ProductName; + deviceInfoOut.AllowAuto = false; + deviceInfoOut.Serial = "OVR-DK2-DEBUG"; + ovrHmd_Destroy(hmd); + } +#endif } bool CStereoOVR::isLibraryInUse() { - /*nlassert(s_DeviceCounter >= 0); - return s_DeviceCounter > 0;*/ - return false; + nlassert(s_DeviceCounter >= 0); + return s_DeviceCounter > 0; } void CStereoOVR::releaseLibrary() { - /*nlassert(s_DeviceCounter == 0); - s_StereoOVRSystem.Release();*/ + nlassert(s_DeviceCounter == 0); + s_StereoOVRSystem.Release(); } bool CStereoOVR::isDeviceCreated() diff --git a/code/nel/src/3d/stereo_ovr_04_program.h b/code/nel/src/3d/stereo_ovr_04_program.h index 940be0bfe..f8c253aeb 100644 --- a/code/nel/src/3d/stereo_ovr_04_program.h +++ b/code/nel/src/3d/stereo_ovr_04_program.h @@ -1,249 +1,4 @@ -/************************************************************************************ -Filename : stereo_ovf_fp.cpp -Content : Barrel fragment program compiled to a blob of assembly -Created : July 01, 2013 -Modified by : Jan Boon (Kaetemi) - -Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -namespace NL3D { -const char *g_StereoOVR_fp40 = - "!!ARBfp1.0\n" - "OPTION NV_fragment_program2;\n" - //# cgc version 3.1.0013, build date Apr 18 2012 - //# command line args: -profile fp40 - //# source file: pp_oculus_vr.cg - //#vendor NVIDIA Corporation - //#version 3.1.0.13 - //#profile fp40 - //#program pp_oculus_vr - //#semantic pp_oculus_vr.cLensCenter - //#semantic pp_oculus_vr.cScreenCenter - //#semantic pp_oculus_vr.cScale - //#semantic pp_oculus_vr.cScaleIn - //#semantic pp_oculus_vr.cHmdWarpParam - //#semantic pp_oculus_vr.cTex0 : TEX0 - //#var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 - //#var float2 cLensCenter : : c[0] : 1 : 1 - //#var float2 cScreenCenter : : c[1] : 2 : 1 - //#var float2 cScale : : c[2] : 3 : 1 - //#var float2 cScaleIn : : c[3] : 4 : 1 - //#var float4 cHmdWarpParam : : c[4] : 5 : 1 - //#var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 - //#var float4 oCol : $vout.COLOR : COL : 7 : 1 - //#const c[5] = 0.25 0.5 0 - "PARAM c[6] = { program.env[0..4],\n" // program.local->program.env! - " { 0.25, 0.5, 0 } };\n" - "TEMP R0;\n" - "TEMP R1;\n" - "SHORT TEMP H0;\n" - "TEMP RC;\n" - "TEMP HC;\n" - "OUTPUT oCol = result.color;\n" - "ADDR R0.xy, fragment.texcoord[0], -c[0];\n" - "MULR R0.xy, R0, c[3];\n" - "MULR R0.z, R0.y, R0.y;\n" - "MADR R1.x, R0, R0, R0.z;\n" - "MULR R0.zw, R1.x, c[4].xywz;\n" - "MADR R1.y, R1.x, c[4], c[4].x;\n" - "MADR R0.w, R0, R1.x, R1.y;\n" - "MULR R0.z, R0, R1.x;\n" - "MADR R0.z, R0, R1.x, R0.w;\n" - "MULR R1.xy, R0, R0.z;\n" - "MOVR R0.xy, c[5];\n" - "ADDR R1.zw, R0.xyxy, c[1].xyxy;\n" - "MOVR R0.zw, c[0].xyxy;\n" - "MADR R0.zw, R1.xyxy, c[2].xyxy, R0;\n" - "MINR R1.xy, R0.zwzw, R1.zwzw;\n" - "ADDR R0.xy, -R0, c[1];\n" - "MAXR R0.xy, R0, R1;\n" - "SEQR H0.xy, R0, R0.zwzw;\n" - "MULXC HC.x, H0, H0.y;\n" - "IF EQ.x;\n" - "MOVR oCol, c[5].z;\n" - "ELSE;\n" - "TEX oCol, R0.zwzw, texture[0], 2D;\n" - "ENDIF;\n" - "END\n"; - //# 24 instructions, 2 R-regs, 1 H-regs - -const char *g_StereoOVR_arbfp1 = - "!!ARBfp1.0\n" - //# cgc version 3.1.0013, build date Apr 18 2012 - //# command line args: -profile arbfp1 - //# source file: pp_oculus_vr.cg - //#vendor NVIDIA Corporation - //#version 3.1.0.13 - //#profile arbfp1 - //#program pp_oculus_vr - //#semantic pp_oculus_vr.cLensCenter - //#semantic pp_oculus_vr.cScreenCenter - //#semantic pp_oculus_vr.cScale - //#semantic pp_oculus_vr.cScaleIn - //#semantic pp_oculus_vr.cHmdWarpParam - //#semantic pp_oculus_vr.cTex0 : TEX0 - //#var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 - //#var float2 cLensCenter : : c[0] : 1 : 1 - //#var float2 cScreenCenter : : c[1] : 2 : 1 - //#var float2 cScale : : c[2] : 3 : 1 - //#var float2 cScaleIn : : c[3] : 4 : 1 - //#var float4 cHmdWarpParam : : c[4] : 5 : 1 - //#var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 - //#var float4 oCol : $vout.COLOR : COL : 7 : 1 - //#const c[5] = 0.25 0.5 0 1 - "PARAM c[6] = { program.env[0..4],\n" - " { 0.25, 0.5, 0, 1 } };\n" - "TEMP R0;\n" - "TEMP R1;\n" - "ADD R0.xy, fragment.texcoord[0], -c[0];\n" - "MUL R0.xy, R0, c[3];\n" - "MUL R0.z, R0.y, R0.y;\n" - "MAD R0.z, R0.x, R0.x, R0;\n" - "MUL R0.w, R0.z, c[4];\n" - "MUL R0.w, R0, R0.z;\n" - "MAD R1.y, R0.z, c[4], c[4].x;\n" - "MUL R1.x, R0.z, c[4].z;\n" - "MAD R1.x, R0.z, R1, R1.y;\n" - "MAD R0.z, R0.w, R0, R1.x;\n" - "MUL R0.xy, R0, R0.z;\n" - "MOV R0.zw, c[5].xyxy;\n" - "ADD R1.xy, R0.zwzw, c[1];\n" - "MUL R0.xy, R0, c[2];\n" - "ADD R0.xy, R0, c[0];\n" - "MIN R1.xy, R1, R0;\n" - "ADD R0.zw, -R0, c[1].xyxy;\n" - "MAX R0.zw, R0, R1.xyxy;\n" - "ADD R0.zw, R0, -R0.xyxy;\n" - "ABS R0.zw, R0;\n" - "CMP R0.zw, -R0, c[5].z, c[5].w;\n" - "MUL R0.z, R0, R0.w;\n" - "ABS R0.z, R0;\n" - "CMP R0.z, -R0, c[5], c[5].w;\n" - "ABS R1.x, R0.z;\n" - "TEX R0, R0, texture[0], 2D;\n" - "CMP R1.x, -R1, c[5].z, c[5].w;\n" - "CMP result.color, -R1.x, R0, c[5].z;\n" - "END\n"; - //# 28 instructions, 2 R-regs - -const char *g_StereoOVR_ps_2_0 = - "ps_2_0\n" - // cgc version 3.1.0013, build date Apr 18 2012 - // command line args: -profile ps_2_0 - // source file: pp_oculus_vr.cg - //vendor NVIDIA Corporation - //version 3.1.0.13 - //profile ps_2_0 - //program pp_oculus_vr - //semantic pp_oculus_vr.cLensCenter - //semantic pp_oculus_vr.cScreenCenter - //semantic pp_oculus_vr.cScale - //semantic pp_oculus_vr.cScaleIn - //semantic pp_oculus_vr.cHmdWarpParam - //semantic pp_oculus_vr.cTex0 : TEX0 - //var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 - //var float2 cLensCenter : : c[0] : 1 : 1 - //var float2 cScreenCenter : : c[1] : 2 : 1 - //var float2 cScale : : c[2] : 3 : 1 - //var float2 cScaleIn : : c[3] : 4 : 1 - //var float4 cHmdWarpParam : : c[4] : 5 : 1 - //var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 - //var float4 oCol : $vout.COLOR : COL : 7 : 1 - //const c[5] = -0.25 -0.5 0.25 0.5 - //const c[6] = 1 0 - "dcl_2d s0\n" - "def c5, -0.25000000, -0.50000000, 0.25000000, 0.50000000\n" - "def c6, 1.00000000, 0.00000000, 0, 0\n" - "dcl t0.xy\n" - "add r0.xy, t0, -c0\n" - "mul r4.xy, r0, c3\n" - "mul r0.x, r4.y, r4.y\n" - "mad r0.x, r4, r4, r0\n" - "mul r1.x, r0, c4.w\n" - "mul r1.x, r1, r0\n" - "mad r3.x, r0, c4.y, c4\n" - "mul r2.x, r0, c4.z\n" - "mad r2.x, r0, r2, r3\n" - "mad r0.x, r1, r0, r2\n" - "mul r0.xy, r4, r0.x\n" - "mul r0.xy, r0, c2\n" - "add r3.xy, r0, c0\n" - "mov r1.x, c5.z\n" - "mov r1.y, c5.w\n" - "mov r2.xy, c1\n" - "add r2.xy, r1, r2\n" - "mov r1.xy, c1\n" - "min r2.xy, r2, r3\n" - "add r1.xy, c5, r1\n" - "max r1.xy, r1, r2\n" - "add r1.xy, r1, -r3\n" - "abs r1.xy, r1\n" - "cmp r1.xy, -r1, c6.x, c6.y\n" - "mul_pp r1.x, r1, r1.y\n" - "abs_pp r1.x, r1\n" - "cmp_pp r1.x, -r1, c6, c6.y\n" - "abs_pp r1.x, r1\n" - "texld r0, r3, s0\n" - "cmp r0, -r1.x, r0, c6.y\n" - "mov oC0, r0\n"; - -const char *g_StereoOVR_glsl330f = - "#version 330\n" - "\n" - "bool _TMP2;\n" - "bvec2 _TMP1;\n" - "vec2 _TMP3;\n" - "uniform vec2 cLensCenter;\n" - "uniform vec2 cScreenCenter;\n" - "uniform vec2 cScale;\n" - "uniform vec2 cScaleIn;\n" - "uniform vec4 cHmdWarpParam;\n" - "uniform sampler2D nlTex0;\n" - "vec2 _TMP10;\n" - "vec2 _b0011;\n" - "vec2 _a0011;\n" - "in vec4 nlTexCoord0;\n" - "out vec4 nlCol;\n" - "\n" - "void main()\n" - "{\n" - " vec2 _theta;\n" - " float _rSq;\n" - " vec2 _theta1;\n" - " vec2 _tc;\n" - "\n" - " _theta = (nlTexCoord0.xy - cLensCenter)*cScaleIn;\n" - " _rSq = _theta.x*_theta.x + _theta.y*_theta.y;\n" - " _theta1 = _theta*(cHmdWarpParam.x + cHmdWarpParam.y*_rSq + cHmdWarpParam.z*_rSq*_rSq + cHmdWarpParam.w*_rSq*_rSq*_rSq);\n" - " _tc = cLensCenter + cScale*_theta1;\n" - " _a0011 = cScreenCenter - vec2( 0.25, 0.5);\n" - " _b0011 = cScreenCenter + vec2( 0.25, 0.5);\n" - " _TMP3 = min(_b0011, _tc);\n" - " _TMP10 = max(_a0011, _TMP3);\n" - " _TMP1 = bvec2(_TMP10.x == _tc.x, _TMP10.y == _tc.y);\n" - " _TMP2 = _TMP1.x && _TMP1.y;\n" - " if (!_TMP2) {\n" - " nlCol = vec4(0, 0, 0, 0);\n" - " } else {\n" - " nlCol = texture(nlTex0, _tc);\n" - " }\n" - "}\n"; - -} +// TODO /* end of file */ diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 5f0da0136..1644f7e2d 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -616,10 +616,16 @@ void initStereoDisplayDevice() std::vector devices; listStereoDisplayDevices(devices); CStereoDeviceInfo *deviceInfo = NULL; - if (ClientCfg.VRDisplayDevice == std::string("Auto") - && devices.begin() != devices.end()) + if (ClientCfg.VRDisplayDevice == std::string("Auto")) { - deviceInfo = &devices[0]; + for (std::vector::iterator it(devices.begin()), end(devices.end()); it != end; ++it) + { + if ((*it).AllowAuto) + { + deviceInfo = &(*it); + break; + } + } } else {