Add interface for stereo display render targets, ref #43

--HG--
branch : multipass-stereo
This commit is contained in:
kaetemi 2013-07-01 21:23:47 +02:00
parent 85977755de
commit 85109102b2
4 changed files with 69 additions and 61 deletions

View file

@ -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
{ {
@ -89,6 +91,9 @@ 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;
/// Set latest camera position etcetera /// Set latest camera position etcetera
@ -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);

View file

@ -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];

View file

@ -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::wantScene()
{
}
bool CStereoOVR::beginScene()
{ {
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

View file

@ -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)
{ {
@ -792,11 +788,9 @@ 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();
} }
} }