Add interface for stereo display render targets, ref #43

This commit is contained in:
kaetemi 2013-07-01 21:23:47 +02:00
parent 2b653d2904
commit f25a9da718
4 changed files with 69 additions and 61 deletions

View file

@ -42,6 +42,8 @@ class UCamera;
class CViewport;
class CFrustum;
class IStereoDisplay;
class UTexture;
class UDriver;
class IStereoDeviceFactory : public NLMISC::CRefCount
{
@ -89,6 +91,9 @@ public:
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
virtual void getScreenResolution(uint &width, uint &height) = 0;
/// Set latest camera position etcetera
@ -108,21 +113,18 @@ public:
virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const = 0;
/// At the start of a new render target
virtual bool beginClear() = 0;
// virtual void *getRenderTarget() const;
virtual void endClear() = 0;
virtual bool wantClear() = 0;
/// The 3D scene
virtual bool beginScene() = 0;
virtual void endScene() = 0;
virtual bool wantScene() = 0;
/// Interface within the 3D scene
virtual bool beginInterface3D() = 0;
virtual void endInterface3D() = 0;
virtual bool wantInterface3D() = 0;
/// 2D Interface
virtual bool beginInterface2D() = 0;
virtual void endInterface2D() = 0;
virtual bool wantInterface2D() = 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 void listDevices(std::vector<CStereoDeviceInfo> &devicesOut);

View file

@ -74,6 +74,8 @@ public:
CStereoOVR(const CStereoOVRDeviceHandle *handle);
virtual ~CStereoOVR();
/// Sets driver and generates necessary render targets
virtual void setDriver(NL3D::UDriver &driver);
/// Gets the required screen resolution for this device
virtual void getScreenResolution(uint &width, uint &height);
@ -94,21 +96,18 @@ public:
virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const;
/// At the start of a new render target
virtual bool beginClear();
// virtual void *getRenderTarget() const;
virtual void endClear();
virtual bool wantClear();
/// The 3D scene
virtual bool beginScene();
virtual void endScene();
virtual bool wantScene();
/// Interface within the 3D scene
virtual bool beginInterface3D();
virtual void endInterface3D();
virtual bool wantInterface3D();
/// 2D Interface
virtual bool beginInterface2D();
virtual void endInterface2D();
virtual bool wantInterface2D();
/// 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
@ -130,6 +129,7 @@ public:
private:
CStereoOVRDevicePtr *m_DevicePtr;
int m_Stage;
int m_SubStage;
CViewport m_LeftViewport;
CViewport m_RightViewport;
CFrustum m_ClippingFrustum[NL_STEREO_MAX_USER_CAMERAS];

View file

@ -155,7 +155,7 @@ public:
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;
m_DevicePtr = new CStereoOVRDevicePtr();
@ -206,6 +206,11 @@ CStereoOVR::~CStereoOVR()
--s_DeviceCounter;
}
void CStereoOVR::setDriver(NL3D::UDriver &driver)
{
// ...
}
void CStereoOVR::getScreenResolution(uint &width, uint &height)
{
width = m_DevicePtr->HMDInfo.HResolution;
@ -220,7 +225,7 @@ void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera)
m_RightFrustum[cid] = m_LeftFrustum[cid];
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
nldebug("OVR: projectionCenterOffset = %f", projectionCenterOffset);
@ -255,6 +260,7 @@ bool CStereoOVR::nextPass()
{
case 0:
++m_Stage;
m_SubStage = 0;
// stage 1:
// (initBloom)
// clear buffer
@ -262,39 +268,46 @@ bool CStereoOVR::nextPass()
return true;
case 1:
++m_Stage;
m_SubStage = 0;
// stage 2:
// draw scene right
return true;
case 2:
++m_Stage;
m_SubStage = 0;
// stage 3:
// (endBloom)
// draw interface 3d left
return true;
case 3:
++m_Stage;
m_SubStage = 0;
// stage 4:
// draw interface 3d right
return true;
case 4:
++m_Stage;
m_SubStage = 0;
// stage 5:
// (endInterfacesDisplayBloom)
// draw interface 2d left
return true;
case 5:
++m_Stage;
m_SubStage = 0;
// stage 6:
// draw interface 2d right
return true;
case 6:
m_Stage = 0;
m_SubStage = 0;
// present
m_OrientationCached = false;
return false;
}
nlassert(false);
nlerror("Invalid stage");
m_Stage = 0;
m_SubStage = 0;
m_OrientationCached = false;
return false;
}
@ -326,67 +339,68 @@ void CStereoOVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const
camera->setMatrix(m_CameraMatrix[cid] * translate);
}
bool CStereoOVR::beginClear()
bool CStereoOVR::wantClear()
{
switch (m_Stage)
{
case 1:
m_SubStage = 1;
return true;
}
return false;
}
void CStereoOVR::endClear()
{
}
bool CStereoOVR::beginScene()
bool CStereoOVR::wantScene()
{
switch (m_Stage)
{
case 1:
case 2:
m_SubStage = 2;
return true;
}
return false;
}
void CStereoOVR::endScene()
{
}
bool CStereoOVR::beginInterface3D()
bool CStereoOVR::wantInterface3D()
{
switch (m_Stage)
{
case 3:
case 4:
m_SubStage = 3;
return true;
}
return false;
}
void CStereoOVR::endInterface3D()
{
}
bool CStereoOVR::beginInterface2D()
bool CStereoOVR::wantInterface2D()
{
switch (m_Stage)
{
case 5:
case 6:
m_SubStage = 4;
return true;
}
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

View file

@ -750,7 +750,7 @@ void loopIngame()
StereoHMD->getCurrentMatrix(0, &Camera);
}
if (!StereoHMD || StereoHMD->beginClear())
if (!StereoHMD || StereoHMD->wantClear())
{
if (s_EnableBloom)
{
@ -761,11 +761,9 @@ void loopIngame()
// 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
if (StereoHMD) StereoHMD->endClear();
}
if (!StereoHMD || StereoHMD->beginScene())
if (!StereoHMD || StereoHMD->wantScene())
{
// 02. Render Sky (sky scene)
updateSky(); // Render the sky scene before the main scene
@ -775,11 +773,9 @@ void loopIngame()
// 05. Render Effects (flare)
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)
{
@ -792,11 +788,9 @@ void loopIngame()
// 06. Render Interface 3D (player names)
// ...
if (StereoHMD) StereoHMD->endInterface3D();
}
if (!StereoHMD || StereoHMD->beginInterface2D())
if (!StereoHMD || StereoHMD->wantInterface2D())
{
if (s_EnableBloom && bloomStage == 2)
{
@ -820,8 +814,6 @@ void loopIngame()
// 08. Render Debug (stuff for dev)
// ...
if (StereoHMD) StereoHMD->endInterface2D();
}
}