Add interface for stereo display render targets, ref #43
--HG-- branch : multipass-stereo
This commit is contained in:
parent
85977755de
commit
85109102b2
4 changed files with 69 additions and 61 deletions
|
@ -42,6 +42,8 @@ class UCamera;
|
||||||
class CViewport;
|
class CViewport;
|
||||||
class CFrustum;
|
class CFrustum;
|
||||||
class IStereoDisplay;
|
class IStereoDisplay;
|
||||||
|
class UTexture;
|
||||||
|
class UDriver;
|
||||||
|
|
||||||
class IStereoDeviceFactory : public NLMISC::CRefCount
|
class IStereoDeviceFactory : public NLMISC::CRefCount
|
||||||
{
|
{
|
||||||
|
@ -88,6 +90,9 @@ class IStereoDisplay
|
||||||
public:
|
public:
|
||||||
IStereoDisplay();
|
IStereoDisplay();
|
||||||
virtual ~IStereoDisplay();
|
virtual ~IStereoDisplay();
|
||||||
|
|
||||||
|
/// Sets driver and generates necessary render targets
|
||||||
|
virtual void setDriver(NL3D::UDriver &driver) = 0;
|
||||||
|
|
||||||
/// Gets the required screen resolution for this device
|
/// Gets the required screen resolution for this device
|
||||||
virtual void getScreenResolution(uint &width, uint &height) = 0;
|
virtual void getScreenResolution(uint &width, uint &height) = 0;
|
||||||
|
@ -108,21 +113,18 @@ public:
|
||||||
virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const = 0;
|
virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const = 0;
|
||||||
|
|
||||||
/// At the start of a new render target
|
/// At the start of a new render target
|
||||||
virtual bool beginClear() = 0;
|
virtual bool wantClear() = 0;
|
||||||
// virtual void *getRenderTarget() const;
|
|
||||||
virtual void endClear() = 0;
|
|
||||||
|
|
||||||
/// The 3D scene
|
/// The 3D scene
|
||||||
virtual bool beginScene() = 0;
|
virtual bool wantScene() = 0;
|
||||||
virtual void endScene() = 0;
|
|
||||||
|
|
||||||
/// Interface within the 3D scene
|
/// Interface within the 3D scene
|
||||||
virtual bool beginInterface3D() = 0;
|
virtual bool wantInterface3D() = 0;
|
||||||
virtual void endInterface3D() = 0;
|
|
||||||
|
|
||||||
/// 2D Interface
|
/// 2D Interface
|
||||||
virtual bool beginInterface2D() = 0;
|
virtual bool wantInterface2D() = 0;
|
||||||
virtual void endInterface2D() = 0;
|
|
||||||
|
/// Returns non-NULL if a new render target was set
|
||||||
|
virtual UTexture *beginRenderTarget(bool set) = 0;
|
||||||
|
/// Returns true if a render target was fully drawn
|
||||||
|
virtual bool endRenderTarget(bool render) = 0;
|
||||||
|
|
||||||
static const char *getLibraryName(CStereoDeviceInfo::TStereoDeviceLibrary library);
|
static const char *getLibraryName(CStereoDeviceInfo::TStereoDeviceLibrary library);
|
||||||
static void listDevices(std::vector<CStereoDeviceInfo> &devicesOut);
|
static void listDevices(std::vector<CStereoDeviceInfo> &devicesOut);
|
||||||
|
|
|
@ -74,6 +74,8 @@ public:
|
||||||
CStereoOVR(const CStereoOVRDeviceHandle *handle);
|
CStereoOVR(const CStereoOVRDeviceHandle *handle);
|
||||||
virtual ~CStereoOVR();
|
virtual ~CStereoOVR();
|
||||||
|
|
||||||
|
/// Sets driver and generates necessary render targets
|
||||||
|
virtual void setDriver(NL3D::UDriver &driver);
|
||||||
|
|
||||||
/// Gets the required screen resolution for this device
|
/// Gets the required screen resolution for this device
|
||||||
virtual void getScreenResolution(uint &width, uint &height);
|
virtual void getScreenResolution(uint &width, uint &height);
|
||||||
|
@ -94,21 +96,18 @@ public:
|
||||||
virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const;
|
virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const;
|
||||||
|
|
||||||
/// At the start of a new render target
|
/// At the start of a new render target
|
||||||
virtual bool beginClear();
|
virtual bool wantClear();
|
||||||
// virtual void *getRenderTarget() const;
|
|
||||||
virtual void endClear();
|
|
||||||
|
|
||||||
/// The 3D scene
|
/// The 3D scene
|
||||||
virtual bool beginScene();
|
virtual bool wantScene();
|
||||||
virtual void endScene();
|
|
||||||
|
|
||||||
/// Interface within the 3D scene
|
/// Interface within the 3D scene
|
||||||
virtual bool beginInterface3D();
|
virtual bool wantInterface3D();
|
||||||
virtual void endInterface3D();
|
|
||||||
|
|
||||||
/// 2D Interface
|
/// 2D Interface
|
||||||
virtual bool beginInterface2D();
|
virtual bool wantInterface2D();
|
||||||
virtual void endInterface2D();
|
|
||||||
|
/// Returns non-NULL if a new render target was set, always NULL if not using render targets
|
||||||
|
virtual UTexture *beginRenderTarget(bool set);
|
||||||
|
/// Returns true if a render target was fully drawn, always false if not using render targets
|
||||||
|
virtual bool endRenderTarget(bool render);
|
||||||
|
|
||||||
|
|
||||||
/// Get the HMD orientation
|
/// Get the HMD orientation
|
||||||
|
@ -130,6 +129,7 @@ public:
|
||||||
private:
|
private:
|
||||||
CStereoOVRDevicePtr *m_DevicePtr;
|
CStereoOVRDevicePtr *m_DevicePtr;
|
||||||
int m_Stage;
|
int m_Stage;
|
||||||
|
int m_SubStage;
|
||||||
CViewport m_LeftViewport;
|
CViewport m_LeftViewport;
|
||||||
CViewport m_RightViewport;
|
CViewport m_RightViewport;
|
||||||
CFrustum m_ClippingFrustum[NL_STEREO_MAX_USER_CAMERAS];
|
CFrustum m_ClippingFrustum[NL_STEREO_MAX_USER_CAMERAS];
|
||||||
|
|
|
@ -155,7 +155,7 @@ public:
|
||||||
OVR::HMDInfo HMDInfo;
|
OVR::HMDInfo HMDInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_OrientationCached(false)
|
CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false)
|
||||||
{
|
{
|
||||||
++s_DeviceCounter;
|
++s_DeviceCounter;
|
||||||
m_DevicePtr = new CStereoOVRDevicePtr();
|
m_DevicePtr = new CStereoOVRDevicePtr();
|
||||||
|
@ -206,6 +206,11 @@ CStereoOVR::~CStereoOVR()
|
||||||
--s_DeviceCounter;
|
--s_DeviceCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CStereoOVR::setDriver(NL3D::UDriver &driver)
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
void CStereoOVR::getScreenResolution(uint &width, uint &height)
|
void CStereoOVR::getScreenResolution(uint &width, uint &height)
|
||||||
{
|
{
|
||||||
width = m_DevicePtr->HMDInfo.HResolution;
|
width = m_DevicePtr->HMDInfo.HResolution;
|
||||||
|
@ -220,7 +225,7 @@ void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera)
|
||||||
m_RightFrustum[cid] = m_LeftFrustum[cid];
|
m_RightFrustum[cid] = m_LeftFrustum[cid];
|
||||||
|
|
||||||
float viewCenter = m_DevicePtr->HMDInfo.HScreenSize * 0.25f;
|
float viewCenter = m_DevicePtr->HMDInfo.HScreenSize * 0.25f;
|
||||||
float eyeProjectionShift = viewCenter - m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f;
|
float eyeProjectionShift = viewCenter - m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; // docs say LensSeparationDistance, why not InterpupillaryDistance? related to how the lenses work?
|
||||||
float projectionCenterOffset = (eyeProjectionShift / (m_DevicePtr->HMDInfo.HScreenSize * 0.5f)) * (m_LeftFrustum[cid].Right - m_LeftFrustum[cid].Left); // used logic for this one, but it ends up being the same as the one i made up
|
float projectionCenterOffset = (eyeProjectionShift / (m_DevicePtr->HMDInfo.HScreenSize * 0.5f)) * (m_LeftFrustum[cid].Right - m_LeftFrustum[cid].Left); // used logic for this one, but it ends up being the same as the one i made up
|
||||||
nldebug("OVR: projectionCenterOffset = %f", projectionCenterOffset);
|
nldebug("OVR: projectionCenterOffset = %f", projectionCenterOffset);
|
||||||
|
|
||||||
|
@ -255,6 +260,7 @@ bool CStereoOVR::nextPass()
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
++m_Stage;
|
++m_Stage;
|
||||||
|
m_SubStage = 0;
|
||||||
// stage 1:
|
// stage 1:
|
||||||
// (initBloom)
|
// (initBloom)
|
||||||
// clear buffer
|
// clear buffer
|
||||||
|
@ -262,39 +268,46 @@ bool CStereoOVR::nextPass()
|
||||||
return true;
|
return true;
|
||||||
case 1:
|
case 1:
|
||||||
++m_Stage;
|
++m_Stage;
|
||||||
|
m_SubStage = 0;
|
||||||
// stage 2:
|
// stage 2:
|
||||||
// draw scene right
|
// draw scene right
|
||||||
return true;
|
return true;
|
||||||
case 2:
|
case 2:
|
||||||
++m_Stage;
|
++m_Stage;
|
||||||
|
m_SubStage = 0;
|
||||||
// stage 3:
|
// stage 3:
|
||||||
// (endBloom)
|
// (endBloom)
|
||||||
// draw interface 3d left
|
// draw interface 3d left
|
||||||
return true;
|
return true;
|
||||||
case 3:
|
case 3:
|
||||||
++m_Stage;
|
++m_Stage;
|
||||||
|
m_SubStage = 0;
|
||||||
// stage 4:
|
// stage 4:
|
||||||
// draw interface 3d right
|
// draw interface 3d right
|
||||||
return true;
|
return true;
|
||||||
case 4:
|
case 4:
|
||||||
++m_Stage;
|
++m_Stage;
|
||||||
|
m_SubStage = 0;
|
||||||
// stage 5:
|
// stage 5:
|
||||||
// (endInterfacesDisplayBloom)
|
// (endInterfacesDisplayBloom)
|
||||||
// draw interface 2d left
|
// draw interface 2d left
|
||||||
return true;
|
return true;
|
||||||
case 5:
|
case 5:
|
||||||
++m_Stage;
|
++m_Stage;
|
||||||
|
m_SubStage = 0;
|
||||||
// stage 6:
|
// stage 6:
|
||||||
// draw interface 2d right
|
// draw interface 2d right
|
||||||
return true;
|
return true;
|
||||||
case 6:
|
case 6:
|
||||||
m_Stage = 0;
|
m_Stage = 0;
|
||||||
|
m_SubStage = 0;
|
||||||
// present
|
// present
|
||||||
m_OrientationCached = false;
|
m_OrientationCached = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
nlassert(false);
|
nlerror("Invalid stage");
|
||||||
m_Stage = 0;
|
m_Stage = 0;
|
||||||
|
m_SubStage = 0;
|
||||||
m_OrientationCached = false;
|
m_OrientationCached = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -326,67 +339,68 @@ void CStereoOVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const
|
||||||
camera->setMatrix(m_CameraMatrix[cid] * translate);
|
camera->setMatrix(m_CameraMatrix[cid] * translate);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CStereoOVR::beginClear()
|
bool CStereoOVR::wantClear()
|
||||||
{
|
{
|
||||||
switch (m_Stage)
|
switch (m_Stage)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
|
m_SubStage = 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStereoOVR::endClear()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CStereoOVR::beginScene()
|
bool CStereoOVR::wantScene()
|
||||||
{
|
{
|
||||||
switch (m_Stage)
|
switch (m_Stage)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
|
m_SubStage = 2;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStereoOVR::endScene()
|
bool CStereoOVR::wantInterface3D()
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CStereoOVR::beginInterface3D()
|
|
||||||
{
|
{
|
||||||
switch (m_Stage)
|
switch (m_Stage)
|
||||||
{
|
{
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
|
m_SubStage = 3;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStereoOVR::endInterface3D()
|
bool CStereoOVR::wantInterface2D()
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CStereoOVR::beginInterface2D()
|
|
||||||
{
|
{
|
||||||
switch (m_Stage)
|
switch (m_Stage)
|
||||||
{
|
{
|
||||||
case 5:
|
case 5:
|
||||||
case 6:
|
case 6:
|
||||||
|
m_SubStage = 4;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStereoOVR::endInterface2D()
|
|
||||||
{
|
|
||||||
|
|
||||||
|
/// Returns non-NULL if a new render target was set
|
||||||
|
UTexture *CStereoOVR::beginRenderTarget(bool set)
|
||||||
|
{
|
||||||
|
// render target always set before driver clear
|
||||||
|
nlassert(m_SubStage == 1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if a render target was fully drawn
|
||||||
|
bool CStereoOVR::endRenderTarget( bool render)
|
||||||
|
{
|
||||||
|
// after rendering of course
|
||||||
|
nlassert(m_SubStage > 1);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NLMISC::CQuat CStereoOVR::getOrientation() const
|
NLMISC::CQuat CStereoOVR::getOrientation() const
|
||||||
|
|
|
@ -750,7 +750,7 @@ void loopIngame()
|
||||||
StereoHMD->getCurrentMatrix(0, &Camera);
|
StereoHMD->getCurrentMatrix(0, &Camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!StereoHMD || StereoHMD->beginClear())
|
if (!StereoHMD || StereoHMD->wantClear())
|
||||||
{
|
{
|
||||||
if (s_EnableBloom)
|
if (s_EnableBloom)
|
||||||
{
|
{
|
||||||
|
@ -761,11 +761,9 @@ void loopIngame()
|
||||||
|
|
||||||
// 01. Render Driver (background color)
|
// 01. Render Driver (background color)
|
||||||
Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering
|
Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering
|
||||||
|
|
||||||
if (StereoHMD) StereoHMD->endClear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!StereoHMD || StereoHMD->beginScene())
|
if (!StereoHMD || StereoHMD->wantScene())
|
||||||
{
|
{
|
||||||
// 02. Render Sky (sky scene)
|
// 02. Render Sky (sky scene)
|
||||||
updateSky(); // Render the sky scene before the main scene
|
updateSky(); // Render the sky scene before the main scene
|
||||||
|
@ -775,11 +773,9 @@ void loopIngame()
|
||||||
|
|
||||||
// 05. Render Effects (flare)
|
// 05. Render Effects (flare)
|
||||||
if (!StereoHMD) updateLensFlare(); // Render the lens flare (left eye stretched with stereo...)
|
if (!StereoHMD) updateLensFlare(); // Render the lens flare (left eye stretched with stereo...)
|
||||||
|
|
||||||
if (StereoHMD) StereoHMD->endScene();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!StereoHMD || StereoHMD->beginInterface3D())
|
if (!StereoHMD || StereoHMD->wantInterface3D())
|
||||||
{
|
{
|
||||||
if (s_EnableBloom && bloomStage == 1)
|
if (s_EnableBloom && bloomStage == 1)
|
||||||
{
|
{
|
||||||
|
@ -791,12 +787,10 @@ void loopIngame()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 06. Render Interface 3D (player names)
|
// 06. Render Interface 3D (player names)
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
if (StereoHMD) StereoHMD->endInterface3D();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!StereoHMD || StereoHMD->beginInterface2D())
|
if (!StereoHMD || StereoHMD->wantInterface2D())
|
||||||
{
|
{
|
||||||
if (s_EnableBloom && bloomStage == 2)
|
if (s_EnableBloom && bloomStage == 2)
|
||||||
{
|
{
|
||||||
|
@ -820,8 +814,6 @@ void loopIngame()
|
||||||
|
|
||||||
// 08. Render Debug (stuff for dev)
|
// 08. Render Debug (stuff for dev)
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
if (StereoHMD) StereoHMD->endInterface2D();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue