From b1aaf05bf6cf16e830780286d9cabfd287024552 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 5 Jul 2013 02:04:34 +0200 Subject: [PATCH] Init/release VR interfaces in ryzom client, ref #43 --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/stereo_debugger.h | 4 + code/nel/src/3d/stereo_debugger.cpp | 118 ++++++++++++++-------- code/nel/src/3d/stereo_ovr.cpp | 13 +-- code/ryzom/client/src/camera.cpp | 2 +- code/ryzom/client/src/client_cfg.cpp | 7 ++ code/ryzom/client/src/client_cfg.h | 5 + code/ryzom/client/src/global.cpp | 4 +- code/ryzom/client/src/global.h | 7 +- code/ryzom/client/src/init.cpp | 66 ++++++++++++ code/ryzom/client/src/main_loop.cpp | 2 +- code/ryzom/client/src/release.cpp | 10 ++ 11 files changed, 185 insertions(+), 53 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_debugger.h b/code/nel/include/nel/3d/stereo_debugger.h index b94ffaf6b..b07a9630c 100644 --- a/code/nel/include/nel/3d/stereo_debugger.h +++ b/code/nel/include/nel/3d/stereo_debugger.h @@ -65,6 +65,10 @@ public: /// Sets driver and generates necessary render targets virtual void setDriver(NL3D::UDriver *driver); + void releaseTextures(); + void initTextures(); + void setTextures(); + void verifyTextures(); /// Gets the required screen resolution for this device virtual bool getScreenResolution(uint &width, uint &height); diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp index c24bcdc93..036cb7e1b 100644 --- a/code/nel/src/3d/stereo_debugger.cpp +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -96,21 +96,13 @@ CStereoDebugger::CStereoDebugger() : m_Driver(NULL), m_Stage(0), m_SubStage(0), CStereoDebugger::~CStereoDebugger() { + releaseTextures(); + if (!m_Mat.empty()) { - m_Mat.getObjectPtr()->setTexture(0, NULL); - m_Mat.getObjectPtr()->setTexture(1, NULL); m_Driver->deleteMaterial(m_Mat); } - delete m_LeftTexU; - m_LeftTexU = NULL; - m_LeftTex = NULL; // CSmartPtr - - delete m_RightTexU; - m_RightTexU = NULL; - m_RightTex = NULL; // CSmartPtr - delete m_PixelProgram; m_PixelProgram = NULL; @@ -143,33 +135,7 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) { m_Driver = driver; - // todo: handle reso change! - - uint32 width, height; - driver->getWindowSize(width, height); - - m_LeftTex = new CTextureBloom(); - m_LeftTex->setRenderTarget(true); - m_LeftTex->setReleasable(false); - m_LeftTex->resize(width, height); - m_LeftTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); - m_LeftTex->setWrapS(ITexture::Clamp); - m_LeftTex->setWrapT(ITexture::Clamp); - drvInternal->setupTexture(*m_LeftTex); - m_LeftTexU = new CTextureUser(m_LeftTex); - nlassert(!drvInternal->isTextureRectangle(m_LeftTex)); // not allowed - - m_RightTex = new CTextureBloom(); - m_RightTex->setRenderTarget(true); - m_RightTex->setReleasable(false); - m_RightTex->resize(width, height); - m_RightTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); - m_RightTex->setWrapS(ITexture::Clamp); - m_RightTex->setWrapT(ITexture::Clamp); - drvInternal->setupTexture(*m_RightTex); - m_RightTexU = new CTextureUser(m_RightTex); - nlassert(!drvInternal->isTextureRectangle(m_RightTex)); // not allowed - + initTextures(); m_Mat = m_Driver->createMaterial(); m_Mat.initUnlit(); @@ -182,9 +148,8 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) mat->setZWrite(false); mat->setZFunc(CMaterial::always); mat->setDoubleSided(true); - mat->setTexture(0, m_LeftTex); - mat->setTexture(1, m_RightTex); - + + setTextures(); m_QuadUV.V0 = CVector(0.f, 0.f, 0.5f); m_QuadUV.V1 = CVector(1.f, 0.f, 0.5f); @@ -198,6 +163,79 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) } } +void CStereoDebugger::releaseTextures() +{ + if (!m_Mat.empty()) + { + m_Mat.getObjectPtr()->setTexture(0, NULL); + m_Mat.getObjectPtr()->setTexture(1, NULL); + m_Driver->deleteMaterial(m_Mat); + } + + delete m_LeftTexU; + m_LeftTexU = NULL; + m_LeftTex = NULL; // CSmartPtr + + delete m_RightTexU; + m_RightTexU = NULL; + m_RightTex = NULL; // CSmartPtr +} + +void CStereoDebugger::initTextures() +{ + uint32 width, height; + m_Driver->getWindowSize(width, height); + NL3D::IDriver *drvInternal = (static_cast(m_Driver))->getDriver(); + + m_LeftTex = new CTextureBloom(); + m_LeftTex->setRenderTarget(true); + m_LeftTex->setReleasable(false); + m_LeftTex->resize(width, height); + m_LeftTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); + m_LeftTex->setWrapS(ITexture::Clamp); + m_LeftTex->setWrapT(ITexture::Clamp); + drvInternal->setupTexture(*m_LeftTex); + m_LeftTexU = new CTextureUser(m_LeftTex); + nlassert(!drvInternal->isTextureRectangle(m_LeftTex)); // not allowed + + m_RightTex = new CTextureBloom(); + m_RightTex->setRenderTarget(true); + m_RightTex->setReleasable(false); + m_RightTex->resize(width, height); + m_RightTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); + m_RightTex->setWrapS(ITexture::Clamp); + m_RightTex->setWrapT(ITexture::Clamp); + drvInternal->setupTexture(*m_RightTex); + m_RightTexU = new CTextureUser(m_RightTex); + nlassert(!drvInternal->isTextureRectangle(m_RightTex)); // not allowed +} + +void CStereoDebugger::setTextures() +{ + NL3D::CMaterial *mat = m_Mat.getObjectPtr(); + mat->setTexture(0, m_LeftTex); + mat->setTexture(1, m_RightTex); +} + +void CStereoDebugger::verifyTextures() +{ + if (m_Driver) + { + uint32 width, height; + m_Driver->getWindowSize(width, height); + if (m_LeftTex->getWidth() != width + || m_RightTex->getWidth() != width + || m_LeftTex->getHeight() != height + || m_RightTex->getHeight() != height) + { + nldebug("Rebuild textures"); + releaseTextures(); + initTextures(); + setTextures(); + } + } +} + /// Gets the required screen resolution for this device bool CStereoDebugger::getScreenResolution(uint &width, uint &height) { diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index e58e82892..36f48c7e3 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -233,11 +233,6 @@ CStereoOVR::~CStereoOVR() void CStereoOVR::setDriver(NL3D::UDriver *driver) { - // Do not allow weird stuff. - uint32 width, height; - driver->getWindowSize(width, height); - nlassert(width == m_DevicePtr->HMDInfo.HResolution); - nlassert(height == m_DevicePtr->HMDInfo.VResolution); nlassert(!m_PixelProgram); NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); @@ -264,7 +259,7 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver) m_BarrelTex = new CTextureBloom(); // lol bloom m_BarrelTex->setRenderTarget(true); m_BarrelTex->setReleasable(false); - m_BarrelTex->resize(width, height); + m_BarrelTex->resize(m_DevicePtr->HMDInfo.HResolution, m_DevicePtr->HMDInfo.VResolution); m_BarrelTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); m_BarrelTex->setWrapS(ITexture::Clamp); m_BarrelTex->setWrapT(ITexture::Clamp); @@ -358,6 +353,12 @@ void CStereoOVR::updateCamera(uint cid, const NL3D::UCamera *camera) bool CStereoOVR::nextPass() { + // Do not allow weird stuff. + uint32 width, height; + m_Driver->getWindowSize(width, height); + nlassert(width == m_DevicePtr->HMDInfo.HResolution); + nlassert(height == m_DevicePtr->HMDInfo.VResolution); + switch (m_Stage) { case 0: diff --git a/code/ryzom/client/src/camera.cpp b/code/ryzom/client/src/camera.cpp index 66aac6f76..c409f9e58 100644 --- a/code/ryzom/client/src/camera.cpp +++ b/code/ryzom/client/src/camera.cpp @@ -17,7 +17,7 @@ #include #include "camera.h" -#include +#include #include "global.h" #include "misc.h" diff --git a/code/ryzom/client/src/client_cfg.cpp b/code/ryzom/client/src/client_cfg.cpp index 5bbd90e01..67016de37 100644 --- a/code/ryzom/client/src/client_cfg.cpp +++ b/code/ryzom/client/src/client_cfg.cpp @@ -302,6 +302,10 @@ CClientConfig::CClientConfig() Contrast = 0.f; // Default Monitor Contrast. Luminosity = 0.f; // Default Monitor Luminosity. Gamma = 0.f; // Default Monitor Gamma. + + VREnable = false; + VRDisplayDevice = "Auto"; + VRDisplayDeviceId = ""; Local = false; // Default is Net Mode. FSHost = ""; // Default Host. @@ -847,6 +851,9 @@ void CClientConfig::setValues() else cfgWarning ("Default value used for 'Driver3D' !!!"); + READ_BOOL_FV(VREnable) + READ_STRING_FV(VRDisplayDevice) + READ_STRING_FV(VRDisplayDeviceId) //////////// // INPUTS // diff --git a/code/ryzom/client/src/client_cfg.h b/code/ryzom/client/src/client_cfg.h index c76cfaf36..44ddf3891 100644 --- a/code/ryzom/client/src/client_cfg.h +++ b/code/ryzom/client/src/client_cfg.h @@ -146,6 +146,11 @@ struct CClientConfig /// Monitor Gamma [-1 ~ 1], default 0 float Gamma; + // VR + bool VREnable; + std::string VRDisplayDevice; + std::string VRDisplayDeviceId; + /// Client in Local mode or not. bool Local; /// Host. diff --git a/code/ryzom/client/src/global.cpp b/code/ryzom/client/src/global.cpp index bb60f5c04..2e3ba875a 100644 --- a/code/ryzom/client/src/global.cpp +++ b/code/ryzom/client/src/global.cpp @@ -26,8 +26,8 @@ using namespace NLMISC; // *************************************************************************** // Main System NL3D::UDriver *Driver = 0; // The main 3D Driver -NL3D::CStereoOVR *StereoDisplay = NULL; // Stereo display -NL3D::CStereoOVR *StereoHMD = NULL; // Head mount display +NL3D::IStereoDisplay *StereoDisplay = NULL; // Stereo display +NL3D::IStereoHMD *StereoHMD = NULL; // Head mount display CSoundManager *SoundMngr = 0; // the sound manager NL3D::UMaterial GenericMat; // Generic Material NL3D::UTextContext *TextContext = 0; // Context for all the text in the client. diff --git a/code/ryzom/client/src/global.h b/code/ryzom/client/src/global.h index 6ec3db7ec..9e5a294ae 100644 --- a/code/ryzom/client/src/global.h +++ b/code/ryzom/client/src/global.h @@ -40,7 +40,8 @@ namespace NL3D class UMaterial; class UTextContext; class UWaterEnvMap; - class CStereoOVR; + class IStereoDisplay; + class IStereoHMD; } class CEntityAnimationManager; @@ -78,8 +79,8 @@ const float ExtraZoneLoadingVision = 100.f; // *************************************************************************** // Main System extern NL3D::UDriver *Driver; // The main 3D Driver -extern NL3D::CStereoOVR *StereoDisplay; // Stereo display -extern NL3D::CStereoOVR *StereoHMD; +extern NL3D::IStereoDisplay *StereoDisplay; // Stereo display +extern NL3D::IStereoHMD *StereoHMD; // Head mount display extern CSoundManager *SoundMngr; // the sound manager extern NL3D::UMaterial GenericMat; // Generic Material extern NL3D::UTextContext *TextContext; // Context for all the text in the client. diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 9d515fabd..4c5cd1eca 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -39,6 +39,7 @@ #include "nel/3d/u_driver.h" #include "nel/3d/u_text_context.h" #include "nel/3d/u_shape_bank.h" +#include "nel/3d/stereo_hmd.h" // Net. #include "nel/net/email.h" // Ligo. @@ -46,6 +47,7 @@ // Std. #include +#include // Game Share #include "game_share/ryzom_version.h" // Client @@ -792,6 +794,59 @@ void prelogInit() // Check driver version checkDriverVersion(); + // 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(); + + // Create the driver (most important part of the client). nmsg = "Creating 3d driver..."; ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) ); @@ -860,6 +915,11 @@ void prelogInit() Driver->setSwapVBLInterval(1); else Driver->setSwapVBLInterval(0); + + if (StereoDisplay) + { + // override mode TODO + } // Set the mode of the window. if (!Driver->setDisplay (mode, false)) @@ -1102,6 +1162,12 @@ void prelogInit() // init bloom effect CBloomEffect::getInstance().init(driver != UDriver::Direct3d); + + if (StereoDisplay) + { + // Init stereo display resources + StereoDisplay->setDriver(Driver); + } nlinfo ("PROFILE: %d seconds for prelogInit", (uint32)(ryzomGetLocalTime ()-initStart)/1000); diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index e9f6312e8..ce42b3d8e 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -42,7 +42,7 @@ #include "nel/3d/u_material.h" #include "nel/3d/u_instance_material.h" #include "nel/3d/u_cloud_scape.h" -#include "nel/3d/stereo_ovr.h" +#include "nel/3d/stereo_hmd.h" // game share #include "game_share/brick_types.h" #include "game_share/light_cycle.h" diff --git a/code/ryzom/client/src/release.cpp b/code/ryzom/client/src/release.cpp index 0c975aebe..eea5c6ef9 100644 --- a/code/ryzom/client/src/release.cpp +++ b/code/ryzom/client/src/release.cpp @@ -35,6 +35,7 @@ #include "nel/3d/u_scene.h" #include "nel/3d/u_visual_collision_manager.h" #include "nel/3d/u_shape_bank.h" +#include "nel/3d/stereo_hmd.h" // Client #include "global.h" #include "release.h" @@ -559,6 +560,15 @@ void release() CEntityAnimationManager::delInstance(); EAM= NULL; + nldebug("VR [C]: VR Shutting down"); + if (StereoDisplay) + { + delete StereoDisplay; + StereoDisplay = NULL; + StereoHMD = NULL; + } + IStereoDisplay::releaseAllLibraries(); + // Delete the driver. if(Driver) {