diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/game_config.lua b/code/ryzom/client/data/gamedev/interfaces_v3/game_config.lua
index 82ca4e48d..b5ed493d7 100644
--- a/code/ryzom/client/data/gamedev/interfaces_v3/game_config.lua
+++ b/code/ryzom/client/data/gamedev/interfaces_v3/game_config.lua
@@ -111,7 +111,7 @@ function game:configHideAll()
local uiList = {
'explanation', 'general', 'landscape', 'fx', 'char', 'hud', 'language', 'alpha_colors',
'chat_colors', 'entity_colors', 'in_scene_user', 'in_scene_friend', 'in_scene_enemy',
- 'in_scene_chat_messages', 'win_colors', 'win_colors_r2', 'mouse', 'keyb', 'sound', 'landmark_colors', 'help'
+ 'in_scene_chat_messages', 'win_colors', 'win_colors_r2', 'mouse', 'keyb', 'vr', 'sound', 'landmark_colors', 'help'
};
for k,v in pairs(uiList) do
diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/game_config.xml b/code/ryzom/client/data/gamedev/interfaces_v3/game_config.xml
index 0a5c3c085..ad5060a81 100644
--- a/code/ryzom/client/data/gamedev/interfaces_v3/game_config.xml
+++ b/code/ryzom/client/data/gamedev/interfaces_v3/game_config.xml
@@ -429,6 +429,9 @@
+
@@ -694,6 +697,12 @@
params="game:configShowOne('fx')"
fontsize="10"
y_decal="-1" />
+
+
+
+
+
+
+
+
+
+
+
+
> VRDeviceCache;
+
/// Ring main page
string RingMainURL;
diff --git a/code/ryzom/client/src/global.h b/code/ryzom/client/src/global.h
index 9e5a294ae..5879eeaec 100644
--- a/code/ryzom/client/src/global.h
+++ b/code/ryzom/client/src/global.h
@@ -120,6 +120,10 @@ extern bool ConnectionReadySent;
extern bool PermanentlyBanned;
extern bool IgnoreEntityDbUpdates;
+// VR
+extern std::vector > VRDeviceCache;
+
extern std::string Cookie, FSAddr;
extern std::string RingMainURL;
extern bool FreeTrial;
diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp
index 4c5cd1eca..1c4fe76e9 100644
--- a/code/ryzom/client/src/init.cpp
+++ b/code/ryzom/client/src/init.cpp
@@ -575,6 +575,89 @@ static std::string replaceApplicationDirToken(const std::string &dir)
return dir;
}
+void listStereoDisplayDevices(std::vector &devices)
+{
+ bool cache = VRDeviceCache.empty();
+ nldebug("VR [C]: List devices");
+ if (cache)
+ {
+ VRDeviceCache.push_back(std::pair("Auto", "0"));
+ }
+ IStereoDisplay::listDevices(devices);
+ for (std::vector::iterator it(devices.begin()), end(devices.end()); it != end; ++it)
+ {
+ std::stringstream name;
+ name << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName;
+ std::stringstream fullname;
+ fullname << std::string("[") << name << "] [" << it->Serial << "]";
+ nlinfo("VR [C]: Stereo Display: %s", name.str().c_str());
+ if (cache)
+ {
+ VRDeviceCache.push_back(std::pair(name.str(), it->Serial)); // VR_CONFIG
+ }
+ }
+}
+
+void cacheStereoDisplayDevices() // VR_CONFIG
+{
+ if (VRDeviceCache.empty())
+ {
+ std::vector devices;
+ listStereoDisplayDevices(devices);
+ }
+}
+
+void initStereoDisplayDevice()
+{
+ if (ClientCfg.VREnable)
+ {
+ // VR_CONFIG
+ nldebug("VR [C]: Enabled");
+ std::vector devices;
+ listStereoDisplayDevices(devices);
+ CStereoDeviceInfo *deviceInfo = NULL;
+ if (ClientCfg.VRDisplayDevice == std::string("Auto")
+ && devices.begin() != devices.end())
+ {
+ deviceInfo = &devices[0];
+ }
+ else
+ {
+ for (std::vector::iterator it(devices.begin()), end(devices.end()); it != end; ++it)
+ {
+ std::stringstream name;
+ name << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName;
+ if (name.str() == ClientCfg.VRDisplayDevice)
+ deviceInfo = &(*it);
+ if (ClientCfg.VRDisplayDeviceId == it->Serial)
+ break;
+ }
+ }
+ if (deviceInfo)
+ {
+ nlinfo("VR [C]: Create VR stereo display device");
+ StereoDisplay = IStereoDisplay::createDevice(*deviceInfo);
+ if (StereoDisplay)
+ {
+ if (deviceInfo->Class == CStereoDeviceInfo::StereoHMD)
+ {
+ nlinfo("VR [C]: Stereo display device is a HMD");
+ StereoHMD = static_cast(StereoDisplay);
+ }
+ if (Driver) // VR_DRIVER
+ {
+ StereoDisplay->setDriver(Driver);
+ }
+ }
+ }
+ }
+ else
+ {
+ nldebug("VR [C]: NOT Enabled");
+ }
+ IStereoDisplay::releaseUnusedLibraries();
+}
+
void addSearchPaths(IProgressCallback &progress)
{
// Add search path of UI addon. Allow only a subset of files.
@@ -797,55 +880,7 @@ void prelogInit()
// Initialize the VR devices (even more important than the most important part of the client)
nmsg = "Initializing VR devices...";
ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
- if (ClientCfg.VREnable)
- {
- nldebug("VR [C]: Enabled");
- std::vector devices;
- IStereoDisplay::listDevices(devices);
- for (std::vector::iterator it(devices.begin()), end(devices.end()); it != end; ++it)
- {
- std::stringstream name;
- name << std::string("[") << it->Serial << "] [" << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName << "]";
- nlinfo("VR [C]: Stereo Display: %s", name.str().c_str());
- }
- CStereoDeviceInfo *deviceInfo = NULL;
- if (ClientCfg.VRDisplayDevice == std::string("Auto")
- && devices.begin() != devices.end())
- {
- deviceInfo = &devices[0];
- }
- else
- {
- for (std::vector::iterator it(devices.begin()), end(devices.end()); it != end; ++it)
- {
- std::stringstream name;
- name << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName;
- if (name.str() == ClientCfg.VRDisplayDevice)
- deviceInfo = &(*it);
- if (ClientCfg.VRDisplayDeviceId == it->Serial)
- break;
- }
- }
- if (deviceInfo)
- {
- nlinfo("VR [C]: Create VR stereo display device");
- StereoDisplay = IStereoDisplay::createDevice(*deviceInfo);
- if (StereoDisplay)
- {
- if (deviceInfo->Class == CStereoDeviceInfo::StereoHMD)
- {
- nlinfo("VR [C]: Stereo display device is a HMD");
- StereoHMD = static_cast(StereoDisplay);
- }
- }
- }
- }
- else
- {
- nldebug("VR [C]: NOT Enabled");
- }
- IStereoDisplay::releaseUnusedLibraries();
-
+ initStereoDisplayDevice(); // VR_CONFIG
// Create the driver (most important part of the client).
nmsg = "Creating 3d driver...";
@@ -916,7 +951,7 @@ void prelogInit()
else
Driver->setSwapVBLInterval(0);
- if (StereoDisplay)
+ if (StereoDisplay) // VR_CONFIG // VR_DRIVER
{
// override mode TODO
}
@@ -1163,10 +1198,10 @@ void prelogInit()
// init bloom effect
CBloomEffect::getInstance().init(driver != UDriver::Direct3d);
- if (StereoDisplay)
+ if (StereoDisplay) // VR_CONFIG
{
// Init stereo display resources
- StereoDisplay->setDriver(Driver);
+ StereoDisplay->setDriver(Driver); // VR_DRIVER
}
nlinfo ("PROFILE: %d seconds for prelogInit", (uint32)(ryzomGetLocalTime ()-initStart)/1000);
diff --git a/code/ryzom/client/src/interface_v3/action_handler_game.cpp b/code/ryzom/client/src/interface_v3/action_handler_game.cpp
index 5d886a8ee..4efbfbf81 100644
--- a/code/ryzom/client/src/interface_v3/action_handler_game.cpp
+++ b/code/ryzom/client/src/interface_v3/action_handler_game.cpp
@@ -19,6 +19,8 @@
#include "stdpch.h"
+#include
+
// Interface includes
#include "interface_manager.h"
#include "nel/gui/action_handler.h"
@@ -2919,6 +2921,10 @@ static vector VideoModes;
// We allow only this RGB depth to be taken
#define GAME_CONFIG_VIDEO_DEPTH_REQ 32
+// VR_CONFIG
+#define GAME_CONFIG_VR_DEVICES_COMBO "ui:interface:game_config:content:vr:vr_devices"
+#define GAME_CONFIG_VR_DEVICE_DB "UI:TEMP:VR_DEVICE"
+
// The combo for Texture Mode selected
#define GAME_CONFIG_TEXTURE_MODE_COMBO "ui:interface:game_config:content:general:texture_mode:combo"
#define GAME_CONFIG_TEXTURE_MODE_DB "UI:TEMP:TEXTURE_MODE"
@@ -2926,6 +2932,50 @@ static vector VideoModes;
// The 3 possible modes editable (NB: do not allow client.cfg HDEntityTexture==1 and DivideTextureSizeBy2=2
enum TTextureMode {LowTextureMode= 0, NormalTextureMode= 1, HighTextureMode= 2};
+void cacheStereoDisplayDevices(); // from init.cpp
+
+void updateVRDevicesComboUI()
+{
+ // VR_CONFIG
+ nldebug("Init VR device name list from cache into UI");
+ // init vr device name list from cache
+ CDBGroupComboBox *pCB = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(GAME_CONFIG_VR_DEVICES_COMBO));
+ if (pCB)
+ {
+ pCB->setActive(ClientCfg.VREnable);
+ if (ClientCfg.VREnable)
+ {
+ nldebug("pCB ok");
+ cacheStereoDisplayDevices();
+ pCB->resetTexts();
+ sint32 selectedDevice = -1;
+ for (uint i = 0; i < VRDeviceCache.size(); ++i)
+ {
+ std::stringstream displayname;
+ displayname << std::string("[") << VRDeviceCache[i].first << "] [" << VRDeviceCache[i].second << "]";
+ pCB->addText(ucstring(displayname.str()));
+ if (ClientCfg.VRDisplayDevice == VRDeviceCache[i].first)
+ {
+ if (selectedDevice == -1 || ClientCfg.VRDisplayDeviceId == VRDeviceCache[i].second)
+ {
+ selectedDevice = i;
+ }
+ }
+ }
+ if (selectedDevice == -1)
+ {
+ // configured device not found, add a dummy
+ std::stringstream displayname;
+ displayname << std::string("[") << ClientCfg.VRDisplayDevice << "] [" << ClientCfg.VRDisplayDeviceId<< "] [DEVICE NOT FOUND]";
+ pCB->addText(ucstring(displayname.str()));
+ selectedDevice = VRDeviceCache.size();
+ }
+ NLGUI::CDBManager::getInstance()->getDbProp(GAME_CONFIG_VR_DEVICE_DB)->setValue32(-1);
+ NLGUI::CDBManager::getInstance()->getDbProp(GAME_CONFIG_VR_DEVICE_DB)->setValue32(selectedDevice);
+ }
+ }
+}
+
// ***************************************************************************
class CHandlerGameConfigInit : public IActionHandler
{
@@ -2975,6 +3025,9 @@ public:
pCB->addText(CI18N::get("uigcHighTextureMode"));
}
+ // VR_CONFIG
+ updateVRDevicesComboUI();
+
// init the mode in DB
TTextureMode texMode;
if(ClientCfg.DivideTextureSizeBy2)
@@ -3025,7 +3078,7 @@ class CHandlerGameConfigMode : public IActionHandler
sint oldVideoMode= NLGUI::CDBManager::getInstance()->getDbProp( GAME_CONFIG_VIDEO_MODE_DB )->getOldValue32();
sint nVideModeNb = NLGUI::CDBManager::getInstance()->getDbProp( GAME_CONFIG_VIDEO_MODE_DB )->getValue32();
- if (nVideModeNb == -1) return;
+ if (nVideModeNb == -1 || oldVideoMode == -1) return;
CDBGroupComboBox *pCB= dynamic_cast(CWidgetManager::getInstance()->getElementFromId( GAME_CONFIG_VIDEO_MODES_COMBO ));
if( pCB == NULL ) return;
@@ -3204,6 +3257,29 @@ class CHandlerGameConfigFullscreen : public IActionHandler
};
REGISTER_ACTION_HANDLER (CHandlerGameConfigFullscreen, "game_config_change_vid_fullscreen");
+// ***************************************************************************
+class CHandlerGameConfigVRDevice : public IActionHandler
+{
+ virtual void execute (CCtrlBase *pCaller, const string &/* Params */)
+ {
+ // VR_CONFIG
+
+ sint oldDevice = NLGUI::CDBManager::getInstance()->getDbProp(GAME_CONFIG_VR_DEVICE_DB)->getOldValue32();
+ sint newDevice = NLGUI::CDBManager::getInstance()->getDbProp(GAME_CONFIG_VR_DEVICE_DB)->getValue32();
+
+ if (oldDevice != -1 && newDevice != -1 && pCaller)
+ {
+ // nldebug("TODO_VR switch vr device (from combo box)");
+
+ CDDXManager *pDM = CDDXManager::getInstance();
+ CInterfaceDDX *pDDX = pDM->get(GAME_CONFIG_DDX);
+ if(pDDX)
+ pDDX->validateApplyButton();
+ }
+ }
+};
+REGISTER_ACTION_HANDLER (CHandlerGameConfigVRDevice, "game_config_change_vr_device");
+
// ***************************************************************************
class CHandlerGameConfigApply : public IActionHandler
{
@@ -3297,6 +3373,16 @@ class CHandlerGameConfigApply : public IActionHandler
}
}
+ if (ClientCfg.VREnable)
+ {
+ // store the new config variables
+ sint deviceIdx = NLGUI::CDBManager::getInstance()->getDbProp(GAME_CONFIG_VR_DEVICE_DB)->getValue32();
+ ClientCfg.VRDisplayDevice = VRDeviceCache[deviceIdx].first;
+ ClientCfg.VRDisplayDeviceId = VRDeviceCache[deviceIdx].second;
+ ClientCfg.writeString("VRDisplayDevice", VRDeviceCache[deviceIdx].first);
+ ClientCfg.writeString("VRDisplayDeviceId", VRDeviceCache[deviceIdx].second);
+ }
+
bool requestReboot = false;
// **** Apply the texture mode
diff --git a/code/ryzom/client/src/main_loop_utilities.cpp b/code/ryzom/client/src/main_loop_utilities.cpp
index 7afba0a9f..e7b9a3d27 100644
--- a/code/ryzom/client/src/main_loop_utilities.cpp
+++ b/code/ryzom/client/src/main_loop_utilities.cpp
@@ -38,6 +38,10 @@
using namespace NLMISC;
using namespace NL3D;
+void updateVRDevicesComboUI(); // from action_handler_game.cpp
+void initStereoDisplayDevice(); // from init.cpp
+void releaseStereoDisplayDevice(); // from release.cpp
+
//---------------------------------------------------
// Compare ClientCfg and LastClientCfg to know what we must update
//---------------------------------------------------
@@ -75,6 +79,27 @@ void updateFromClientCfg()
Driver->setSwapVBLInterval(0);
}
+ if (ClientCfg.VREnable != LastClientCfg.VREnable)
+ {
+ // VR_CONFIG
+
+ // switch visibility of list & reload
+ updateVRDevicesComboUI();
+ }
+ else
+ {
+ if (((StereoDisplay != NULL) != ClientCfg.VREnable)
+ || (ClientCfg.VREnable && (
+ ClientCfg.VRDisplayDevice != LastClientCfg.VRDisplayDevice
+ || ClientCfg.VRDisplayDeviceId != LastClientCfg.VRDisplayDeviceId
+ )))
+ {
+ nldebug("Apply VR device change");
+ releaseStereoDisplayDevice();
+ initStereoDisplayDevice();
+ }
+ }
+
// GRAPHICS - LANDSCAPE
//---------------------------------------------------
if (ClientCfg.LandscapeThreshold != LastClientCfg.LandscapeThreshold)
diff --git a/code/ryzom/client/src/release.cpp b/code/ryzom/client/src/release.cpp
index eea5c6ef9..42427830c 100644
--- a/code/ryzom/client/src/release.cpp
+++ b/code/ryzom/client/src/release.cpp
@@ -514,6 +514,17 @@ void releaseOutGame()
ContinentMngr.reset();
}
+void releaseStereoDisplayDevice()
+{
+ if (StereoDisplay)
+ {
+ delete StereoDisplay;
+ StereoDisplay = NULL;
+ StereoHMD = NULL;
+ }
+ IStereoDisplay::releaseAllLibraries();
+}
+
// ***************************************************************************
// final release : Release before exit.
void release()
@@ -561,13 +572,7 @@ void release()
EAM= NULL;
nldebug("VR [C]: VR Shutting down");
- if (StereoDisplay)
- {
- delete StereoDisplay;
- StereoDisplay = NULL;
- StereoHMD = NULL;
- }
- IStereoDisplay::releaseAllLibraries();
+ releaseStereoDisplayDevice();
// Delete the driver.
if(Driver)