Skip to content

Commit

Permalink
Refactor|Stereo 3D: Removed some of the public variables from VRConfig
Browse files Browse the repository at this point in the history
The client handles these as cvars and updates VRConfig as necessary.
  • Loading branch information
skyjake committed Feb 7, 2014
1 parent 663640b commit 505632e
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 54 deletions.
51 changes: 39 additions & 12 deletions doomsday/client/src/render/vr.cpp
Expand Up @@ -20,12 +20,17 @@
#include "de_console.h"
#include "render/vr.h"

de::VRConfig vrCfg; // global
using namespace de;

static float vrRiftFovX = 114.8f;
static float vrNonRiftFovX = 95.f;
static float riftLatency = .030f;
static byte autoLoadRiftParams = 1;
VRConfig vrCfg; // global

static int vrMode = VRConfig::Mono;
static float vrRiftFovX = 114.8f;
static float vrIpd;
static int vrRiftFBSamples;
static float vrNonRiftFovX = 95.f;
static float riftLatency = .030f;
static byte autoLoadRiftParams = 1;

float VR_RiftFovX()
{
Expand All @@ -37,18 +42,32 @@ static void vrLatencyChanged()
vrCfg.oculusRift().setPredictionLatency(riftLatency);
}

static void vrIpdChanged()
{
vrCfg.setInterpupillaryDistance(vrIpd);
}

static void vrFBSamplesChanged()
{
vrCfg.setRiftFramebufferSampleCount(vrRiftFBSamples);
}

// Interplay among vrNonRiftFovX, vrRiftFovX, and cameraFov depends on vrMode
// see also rend_main.cpp
static void vrModeChanged()
{
vrCfg.setMode(VRConfig::StereoMode(vrMode));

if(ClientWindow::mainExists())
{
// The logical UI size may need to be changed.
ClientWindow &win = ClientWindow::main();
win.updateRootSize();
win.updateCanvasFormat(); // possibly changes pixel format
}
if(vrCfg.mode() == de::VRConfig::OculusRift)

// Update FOV cvar accordingly.
if(vrMode == VRConfig::OculusRift)
{
if(Con_GetFloat("rend-camera-fov") != vrRiftFovX)
Con_SetFloat("rend-camera-fov", vrRiftFovX);
Expand All @@ -65,7 +84,7 @@ static void vrModeChanged()

static void vrRiftFovXChanged()
{
if(vrCfg.mode() == de::VRConfig::OculusRift)
if(vrCfg.mode() == VRConfig::OculusRift)
{
if(Con_GetFloat("rend-camera-fov") != vrRiftFovX)
Con_SetFloat("rend-camera-fov", vrRiftFovX);
Expand All @@ -74,7 +93,7 @@ static void vrRiftFovXChanged()

static void vrNonRiftFovXChanged()
{
if(vrCfg.mode() != de::VRConfig::OculusRift)
if(vrCfg.mode() != VRConfig::OculusRift)
{
if(Con_GetFloat("rend-camera-fov") != vrNonRiftFovX)
Con_SetFloat("rend-camera-fov", vrNonRiftFovX);
Expand All @@ -88,17 +107,25 @@ D_CMD(LoadRiftParams)

void VR_ConsoleRegister()
{
vrIpd = vrCfg.interpupillaryDistance();
vrRiftFBSamples = vrCfg.riftFramebufferSampleCount();

/**
* @todo When old-style console variables become obsolete, VRConfig should expose
* these settings as a Record that can be attached under Config.
*/

C_VAR_BYTE ("rend-vr-autoload-rift-params", &autoLoadRiftParams, 0, 0, 1);
C_VAR_FLOAT2("rend-vr-nonrift-fovx", &vrNonRiftFovX, 0, 5.0f, 270.0f, vrNonRiftFovXChanged);
C_VAR_FLOAT2("rend-vr-rift-fovx", &vrRiftFovX, 0, 5.0f, 270.0f, vrRiftFovXChanged);
C_VAR_FLOAT2("rend-vr-rift-latency", &riftLatency, 0, 0.0f, 0.100f, vrLatencyChanged);

C_VAR_FLOAT ("rend-vr-dominant-eye", &vrCfg.dominantEye, 0, -1.0f, 1.0f);
C_VAR_FLOAT ("rend-vr-hud-distance", &vrCfg.hudDistance, 0, 0.01f, 40.0f);
C_VAR_FLOAT ("rend-vr-ipd", &vrCfg.ipd, 0, 0.02f, 0.1f);
C_VAR_INT2 ("rend-vr-mode", &vrCfg.vrMode, 0, 0, de::VRConfig::NUM_STEREO_MODES - 1, vrModeChanged);
C_VAR_FLOAT2("rend-vr-ipd", &vrIpd, 0, 0.02f, 0.1f, vrIpdChanged);
C_VAR_INT2 ("rend-vr-mode", &vrMode, 0, 0, VRConfig::NUM_STEREO_MODES - 1, vrModeChanged);
C_VAR_FLOAT ("rend-vr-player-height", &vrCfg.playerHeight, 0, 1.0f, 2.4f);
C_VAR_INT ("rend-vr-rift-samples", &vrCfg.riftFramebufferSamples, 0, 1, 4);
C_VAR_INT2 ("rend-vr-rift-samples", &vrRiftFBSamples, 0, 1, 4, vrFBSamplesChanged);
C_VAR_BYTE ("rend-vr-swap-eyes", &vrCfg.swapEyes, 0, 0, 1);

C_CMD("loadriftparams", NULL, LoadRiftParams);
Expand All @@ -114,7 +141,7 @@ bool VR_LoadRiftParameters()

if(ovr.isReady())
{
Con_SetFloat("rend-vr-ipd", ovr.interpupillaryDistance());
Con_SetFloat("rend-vr-ipd", ovr.interpupillaryDistance()); // from Oculus SDK
Con_SetFloat("rend-vr-rift-fovx", ovr.fovX());

// I think this field of view is unreliable... CMB
Expand Down
2 changes: 1 addition & 1 deletion doomsday/client/src/ui/dialogs/vrsettingsdialog.cpp
Expand Up @@ -129,7 +129,7 @@ VRSettingsDialog::VRSettingsDialog(String const &name)

ovrLabel->margins().setTop("gap");

layout.setCellAlignment(Vector2i(0, 5), ui::AlignLeft);
layout.setCellAlignment(Vector2i(0, 6), ui::AlignLeft);

layout.append(*ovrLabel, 2);
layout << *latencyLabel << *d->riftPredictionLatency
Expand Down
2 changes: 1 addition & 1 deletion doomsday/client/src/ui/vrwindowtransform.cpp
Expand Up @@ -135,7 +135,7 @@ DENG2_PIMPL(VRWindowTransform)
// Use a little bit of multisampling to smooth out the magnified jagged edges.
// Note: Independent of the vid-fsaa setting because this is beneficial even when
// vid-fsaa is disabled.
unwarpedFB.setSampleCount(vrCfg.riftFramebufferSamples);
unwarpedFB.setSampleCount(vrCfg.riftFramebufferSampleCount());
unwarpedFB.colorTexture().setFilter(gl::Linear, gl::Linear, gl::MipNone);

// Set render target to offscreen temporarily.
Expand Down
3 changes: 3 additions & 0 deletions doomsday/libappfw/include/de/vr/oculusrift.h
Expand Up @@ -55,6 +55,9 @@ class LIBAPPFW_PUBLIC OculusRift

float predictionLatency() const;

/**
* Returns the IPD configured in the Oculus Rift preferences.
*/
float interpupillaryDistance() const;

// Use screen size instead of resolution in case non-square pixels?
Expand Down
37 changes: 22 additions & 15 deletions doomsday/libappfw/include/de/vr/vrconfig.h
Expand Up @@ -56,18 +56,12 @@ class LIBAPPFW_PUBLIC VRConfig
public:
VRConfig();

de::OculusRift &oculusRift();
de::OculusRift const &oculusRift() const;

/**
* Currently active stereo rendering mode.
*/
StereoMode mode() const;

bool needsStereoGLFormat() const;
void setMode(StereoMode newMode);

void setEyeHeightInMapUnits(float eyeHeightInMapUnits);

void setInterpupillaryDistance(float ipd);

enum Eye {
NeitherEye,
LeftEye,
Expand All @@ -76,33 +70,46 @@ class LIBAPPFW_PUBLIC VRConfig

void setCurrentEye(Eye eye);

void enableFrustumShift(bool enable = true);

void setRiftFramebufferSampleCount(int samples);

/**
* Currently active stereo rendering mode.
*/
StereoMode mode() const;

bool needsStereoGLFormat() const;

float interpupillaryDistance() const;

/// Local viewpoint relative eye position in map units.
float eyeShift() const;

void enableFrustumShift(bool enable = true);

/**
* Determines if frustum shift is enabled.
*/
bool frustumShift() const;

/// Multisampling used in unwarped Rift framebuffer.
int riftFramebufferSampleCount() const;

de::OculusRift &oculusRift();
de::OculusRift const &oculusRift() const;

public:
static bool modeNeedsStereoGLFormat(StereoMode mode);

private:
DENG2_PRIVATE(d)

public:
int vrMode;
float ipd; ///< Interpupillary distance in meters
float playerHeight; ///< Human player's real world height in meters
float dominantEye; ///< Kludge for aim-down-weapon-sight modes
bool swapEyes; ///< When true, inverts stereoscopic effect

float hudDistance; // Distance from player character to screen, in map units (not used in Rift mode, because it's used by frustum shift)
float weaponDistance; // (UNUSED) Distance from player character to weapon sprite, in map units

int riftFramebufferSamples; // Multisampling used in unwarped Rift framebuffer
};

} // namespace de
Expand Down
78 changes: 53 additions & 25 deletions doomsday/libappfw/src/vr/vrconfig.cpp
Expand Up @@ -23,9 +23,12 @@ namespace de {

DENG2_PIMPL(VRConfig)
{
StereoMode mode;
de::OculusRift ovr;
float ipd;
float eyeHeightInMapUnits;
float eyeShift;
int riftFramebufferSamples; // Multisampling used in unwarped Rift framebuffer

/**
* Unlike most 3D modes, Oculus Rift typically uses no frustum shift. (or if we did,
Expand All @@ -35,8 +38,11 @@ DENG2_PIMPL(VRConfig)

Instance(Public *i)
: Base(i)
, mode(Mono)
, ipd(.064f) // average male IPD
, eyeHeightInMapUnits(41)
, eyeShift(0)
, riftFramebufferSamples(2)
, frustumShift(true)
{
ovr.init();
Expand All @@ -45,29 +51,54 @@ DENG2_PIMPL(VRConfig)

VRConfig::VRConfig()
: d(new Instance(this))
, vrMode(Mono)
, ipd(.064f) // average male IPD
, playerHeight(1.75f)
, dominantEye(0.0f)
, swapEyes(false)
, hudDistance(20.0f)
, weaponDistance(10)
, riftFramebufferSamples(2)
{}

OculusRift &VRConfig::oculusRift()
void VRConfig::setMode(StereoMode newMode)
{
return d->ovr;
d->mode = newMode;
}

OculusRift const &VRConfig::oculusRift() const
void VRConfig::setEyeHeightInMapUnits(float eyeHeightInMapUnits)
{
return d->ovr;
d->eyeHeightInMapUnits = eyeHeightInMapUnits;
}

void VRConfig::setInterpupillaryDistance(float ipd)
{
d->ipd = ipd;
}

void VRConfig::setCurrentEye(Eye eye)
{
float eyePos = (eye == NeitherEye? 0 : eye == LeftEye? -1 : 1);

// 0.95 because eyes are not at top of head
float mapUnitsPerMeter = d->eyeHeightInMapUnits / (0.95 * playerHeight);
d->eyeShift = mapUnitsPerMeter * (eyePos - dominantEye) * 0.5 * d->ipd;
if(swapEyes)
{
d->eyeShift *= -1;
}
}

void VRConfig::enableFrustumShift(bool enable)
{
d->frustumShift = enable;
}

void VRConfig::setRiftFramebufferSampleCount(int samples)
{
d->riftFramebufferSamples = samples;
}

VRConfig::StereoMode VRConfig::mode() const
{
return (StereoMode) vrMode;
return d->mode;
}

bool VRConfig::needsStereoGLFormat() const
Expand All @@ -80,37 +111,34 @@ bool VRConfig::modeNeedsStereoGLFormat(StereoMode mode)
return mode == QuadBuffered;
}

void VRConfig::setEyeHeightInMapUnits(float eyeHeightInMapUnits)
float VRConfig::interpupillaryDistance() const
{
d->eyeHeightInMapUnits = eyeHeightInMapUnits;
return d->ipd;
}

void VRConfig::setCurrentEye(Eye eye)
float VRConfig::eyeShift() const
{
float eyePos = (eye == NeitherEye? 0 : eye == LeftEye? -1 : 1);
return d->eyeShift;
}

// 0.95 because eyes are not at top of head
float mapUnitsPerMeter = d->eyeHeightInMapUnits / (0.95 * playerHeight);
d->eyeShift = mapUnitsPerMeter * (eyePos - dominantEye) * 0.5 * ipd;
if(swapEyes)
{
d->eyeShift *= -1;
}
bool VRConfig::frustumShift() const
{
return d->frustumShift;
}

float VRConfig::eyeShift() const
int VRConfig::riftFramebufferSampleCount() const
{
return d->eyeShift;
return d->riftFramebufferSamples;
}

void VRConfig::enableFrustumShift(bool enable)
OculusRift &VRConfig::oculusRift()
{
d->frustumShift = enable;
return d->ovr;
}

bool VRConfig::frustumShift() const
OculusRift const &VRConfig::oculusRift() const
{
return d->frustumShift;
return d->ovr;
}

} // namespace de

0 comments on commit 505632e

Please sign in to comment.