mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-29 16:25:42 +00:00
Basic fix for stereo rendering without a display device
This commit is contained in:
parent
8a55feebef
commit
efc47ed757
6 changed files with 104 additions and 30 deletions
|
|
@ -349,7 +349,13 @@ bool GameProcessCameraQuery(CameraQuery *query)
|
||||||
|
|
||||||
// Provide some default values
|
// Provide some default values
|
||||||
query->projectionOffset = Point2F::Zero;
|
query->projectionOffset = Point2F::Zero;
|
||||||
|
query->stereoTargets[0] = 0;
|
||||||
|
query->stereoTargets[1] = 0;
|
||||||
|
query->eyeOffset[0] = Point3F::Zero;
|
||||||
|
query->eyeOffset[1] = Point3F::Zero;
|
||||||
|
query->hasFovPort = false;
|
||||||
|
query->hasStereoTargets = false;
|
||||||
|
|
||||||
F32 cameraFov = 0.0f;
|
F32 cameraFov = 0.0f;
|
||||||
bool fovSet = false;
|
bool fovSet = false;
|
||||||
|
|
||||||
|
|
@ -383,6 +389,7 @@ bool GameProcessCameraQuery(CameraQuery *query)
|
||||||
{
|
{
|
||||||
display->getFovPorts(query->fovPort);
|
display->getFovPorts(query->fovPort);
|
||||||
fovSet = true;
|
fovSet = true;
|
||||||
|
query->hasFovPort = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab the latest overriding render view transforms
|
// Grab the latest overriding render view transforms
|
||||||
|
|
@ -391,6 +398,11 @@ bool GameProcessCameraQuery(CameraQuery *query)
|
||||||
display->getStereoViewports(query->stereoViewports);
|
display->getStereoViewports(query->stereoViewports);
|
||||||
display->getStereoTargets(query->stereoTargets);
|
display->getStereoTargets(query->stereoTargets);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
query->eyeTransforms[0] = query->cameraMatrix;
|
||||||
|
query->eyeTransforms[1] = query->cameraMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
// Use the connection's FOV settings if requried
|
// Use the connection's FOV settings if requried
|
||||||
if(!connection->getControlCameraFov(&cameraFov))
|
if(!connection->getControlCameraFov(&cameraFov))
|
||||||
|
|
|
||||||
|
|
@ -354,10 +354,10 @@ public:
|
||||||
void setStereoEyeTransforms(MatrixF *transforms) { dMemcpy(mStereoEyeTransforms, transforms, sizeof(mStereoEyeTransforms)); dMemcpy(mInverseStereoEyeTransforms, transforms, sizeof(mInverseStereoEyeTransforms)); mInverseStereoEyeTransforms[0].inverse(); mInverseStereoEyeTransforms[1].inverse(); }
|
void setStereoEyeTransforms(MatrixF *transforms) { dMemcpy(mStereoEyeTransforms, transforms, sizeof(mStereoEyeTransforms)); dMemcpy(mInverseStereoEyeTransforms, transforms, sizeof(mInverseStereoEyeTransforms)); mInverseStereoEyeTransforms[0].inverse(); mInverseStereoEyeTransforms[1].inverse(); }
|
||||||
|
|
||||||
/// Set the current eye offset used during stereo rendering. Assumes NumStereoPorts are available.
|
/// Set the current eye offset used during stereo rendering. Assumes NumStereoPorts are available.
|
||||||
void setFovPort(const FovPort *ports) { dMemcpy(mFovPorts, ports, sizeof(mFovPorts)); }
|
void setStereoFovPort(const FovPort *ports) { dMemcpy(mFovPorts, ports, sizeof(mFovPorts)); }
|
||||||
|
|
||||||
/// Get the current eye offset used during stereo rendering
|
/// Get the current eye offset used during stereo rendering
|
||||||
const FovPort* getSteroFovPort() { return mFovPorts; }
|
const FovPort* getStereoFovPort() { return mFovPorts; }
|
||||||
|
|
||||||
/// Sets stereo viewports
|
/// Sets stereo viewports
|
||||||
void setSteroViewports(const RectI *ports) { dMemcpy(mStereoViewports, ports, sizeof(RectI) * NumStereoPorts); }
|
void setSteroViewports(const RectI *ports) { dMemcpy(mStereoViewports, ports, sizeof(RectI) * NumStereoPorts); }
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,8 @@ GuiTSCtrl::GuiTSCtrl()
|
||||||
mLastCameraQuery.nearPlane = 0.01f;
|
mLastCameraQuery.nearPlane = 0.01f;
|
||||||
|
|
||||||
mLastCameraQuery.projectionOffset = Point2F::Zero;
|
mLastCameraQuery.projectionOffset = Point2F::Zero;
|
||||||
|
mLastCameraQuery.hasFovPort = false;
|
||||||
|
mLastCameraQuery.hasStereoTargets = false;
|
||||||
|
|
||||||
mLastCameraQuery.ortho = false;
|
mLastCameraQuery.ortho = false;
|
||||||
}
|
}
|
||||||
|
|
@ -312,6 +314,46 @@ F32 GuiTSCtrl::calculateViewDistance(F32 radius)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static FovPort CalculateFovPortForCanvas(const RectI viewport, const CameraQuery &cameraQuery)
|
||||||
|
{
|
||||||
|
F32 wwidth;
|
||||||
|
F32 wheight;
|
||||||
|
F32 renderWidth = viewport.extent.x;
|
||||||
|
F32 renderHeight = viewport.extent.y;
|
||||||
|
F32 aspectRatio = renderWidth / renderHeight;
|
||||||
|
|
||||||
|
// Use the FOV to calculate the viewport height scale
|
||||||
|
// then generate the width scale from the aspect ratio.
|
||||||
|
if(!cameraQuery.ortho)
|
||||||
|
{
|
||||||
|
wheight = /*cameraQuery.nearPlane * */ mTan(cameraQuery.fov / 2.0f);
|
||||||
|
wwidth = aspectRatio * wheight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wheight = cameraQuery.fov;
|
||||||
|
wwidth = aspectRatio * wheight;
|
||||||
|
}
|
||||||
|
|
||||||
|
F32 hscale = wwidth * 2.0f / renderWidth;
|
||||||
|
F32 vscale = wheight * 2.0f / renderHeight;
|
||||||
|
|
||||||
|
F32 left = 0.0f * hscale - wwidth;
|
||||||
|
F32 right = renderWidth * hscale - wwidth;
|
||||||
|
F32 top = wheight - vscale * 0.0f;
|
||||||
|
F32 bottom = wheight - vscale * renderHeight;
|
||||||
|
|
||||||
|
FovPort fovPort;
|
||||||
|
fovPort.upTan = top;
|
||||||
|
fovPort.downTan = -bottom;
|
||||||
|
fovPort.leftTan = -left;
|
||||||
|
fovPort.rightTan = right;
|
||||||
|
|
||||||
|
return fovPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
|
void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||||
{
|
{
|
||||||
// Save the current transforms so we can restore
|
// Save the current transforms so we can restore
|
||||||
|
|
@ -340,7 +382,25 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||||
GFX->setCurrentRenderStyle(GFXDevice::RS_StereoSideBySide);
|
GFX->setCurrentRenderStyle(GFXDevice::RS_StereoSideBySide);
|
||||||
GFX->setCurrentProjectionOffset(mLastCameraQuery.projectionOffset);
|
GFX->setCurrentProjectionOffset(mLastCameraQuery.projectionOffset);
|
||||||
GFX->setStereoEyeOffsets(mLastCameraQuery.eyeOffset);
|
GFX->setStereoEyeOffsets(mLastCameraQuery.eyeOffset);
|
||||||
GFX->setFovPort(mLastCameraQuery.fovPort); // NOTE: this specifies fov for BOTH eyes
|
|
||||||
|
if (!mLastCameraQuery.hasStereoTargets)
|
||||||
|
{
|
||||||
|
// Need to calculate our current viewport here
|
||||||
|
mLastCameraQuery.stereoViewports[0] = updateRect;
|
||||||
|
mLastCameraQuery.stereoViewports[0].extent.x /= 2;
|
||||||
|
mLastCameraQuery.stereoViewports[1] = mLastCameraQuery.stereoViewports[0];
|
||||||
|
mLastCameraQuery.stereoViewports[1].point.x += mLastCameraQuery.stereoViewports[1].extent.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mLastCameraQuery.hasFovPort)
|
||||||
|
{
|
||||||
|
// Need to make our own fovPort
|
||||||
|
mLastCameraQuery.fovPort[0] = CalculateFovPortForCanvas(mLastCameraQuery.stereoViewports[0], mLastCameraQuery);
|
||||||
|
mLastCameraQuery.fovPort[1] = CalculateFovPortForCanvas(mLastCameraQuery.stereoViewports[1], mLastCameraQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
GFX->setStereoFovPort(mLastCameraQuery.fovPort); // NOTE: this specifies fov for BOTH eyes
|
||||||
|
|
||||||
GFX->setSteroViewports(mLastCameraQuery.stereoViewports);
|
GFX->setSteroViewports(mLastCameraQuery.stereoViewports);
|
||||||
GFX->setStereoTargets(mLastCameraQuery.stereoTargets);
|
GFX->setStereoTargets(mLastCameraQuery.stereoTargets);
|
||||||
|
|
||||||
|
|
@ -402,29 +462,6 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||||
mLastCameraQuery.cameraMatrix.mul(rotMat);
|
mLastCameraQuery.cameraMatrix.mul(rotMat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up the camera and viewport stuff:
|
|
||||||
F32 wwidth;
|
|
||||||
F32 wheight;
|
|
||||||
F32 renderWidth = F32(renderSize.x);
|
|
||||||
F32 renderHeight = F32(renderSize.y);
|
|
||||||
F32 aspectRatio = renderWidth / renderHeight;
|
|
||||||
|
|
||||||
// Use the FOV to calculate the viewport height scale
|
|
||||||
// then generate the width scale from the aspect ratio.
|
|
||||||
if(!mLastCameraQuery.ortho)
|
|
||||||
{
|
|
||||||
wheight = mLastCameraQuery.nearPlane * mTan(mLastCameraQuery.fov / 2.0f);
|
|
||||||
wwidth = aspectRatio * wheight;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wheight = mLastCameraQuery.fov;
|
|
||||||
wwidth = aspectRatio * wheight;
|
|
||||||
}
|
|
||||||
|
|
||||||
F32 hscale = wwidth * 2.0f / renderWidth;
|
|
||||||
F32 vscale = wheight * 2.0f / renderHeight;
|
|
||||||
|
|
||||||
Frustum frustum;
|
Frustum frustum;
|
||||||
if(mRenderStyle == RenderStyleStereoSideBySide)
|
if(mRenderStyle == RenderStyleStereoSideBySide)
|
||||||
{
|
{
|
||||||
|
|
@ -433,6 +470,29 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// set up the camera and viewport stuff:
|
||||||
|
F32 wwidth;
|
||||||
|
F32 wheight;
|
||||||
|
F32 renderWidth = F32(renderSize.x);
|
||||||
|
F32 renderHeight = F32(renderSize.y);
|
||||||
|
F32 aspectRatio = renderWidth / renderHeight;
|
||||||
|
|
||||||
|
// Use the FOV to calculate the viewport height scale
|
||||||
|
// then generate the width scale from the aspect ratio.
|
||||||
|
if(!mLastCameraQuery.ortho)
|
||||||
|
{
|
||||||
|
wheight = mLastCameraQuery.nearPlane * mTan(mLastCameraQuery.fov / 2.0f);
|
||||||
|
wwidth = aspectRatio * wheight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wheight = mLastCameraQuery.fov;
|
||||||
|
wwidth = aspectRatio * wheight;
|
||||||
|
}
|
||||||
|
|
||||||
|
F32 hscale = wwidth * 2.0f / renderWidth;
|
||||||
|
F32 vscale = wheight * 2.0f / renderHeight;
|
||||||
|
|
||||||
F32 left = (updateRect.point.x - offset.x) * hscale - wwidth;
|
F32 left = (updateRect.point.x - offset.x) * hscale - wwidth;
|
||||||
F32 right = (updateRect.point.x + updateRect.extent.x - offset.x) * hscale - wwidth;
|
F32 right = (updateRect.point.x + updateRect.extent.x - offset.x) * hscale - wwidth;
|
||||||
F32 top = wheight - vscale * (updateRect.point.y - offset.y);
|
F32 top = wheight - vscale * (updateRect.point.y - offset.y);
|
||||||
|
|
@ -516,7 +576,7 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||||
|
|
||||||
Frustum originalFrustum = GFX->getFrustum();
|
Frustum originalFrustum = GFX->getFrustum();
|
||||||
GFXTextureObject *texObject = mStereoGuiTarget->getTexture(0);
|
GFXTextureObject *texObject = mStereoGuiTarget->getTexture(0);
|
||||||
const FovPort *currentFovPort = GFX->getSteroFovPort();
|
const FovPort *currentFovPort = GFX->getStereoFovPort();
|
||||||
const MatrixF *eyeTransforms = GFX->getStereoEyeTransforms();
|
const MatrixF *eyeTransforms = GFX->getStereoEyeTransforms();
|
||||||
const MatrixF *worldEyeTransforms = GFX->getInverseStereoEyeTransforms();
|
const MatrixF *worldEyeTransforms = GFX->getInverseStereoEyeTransforms();
|
||||||
const Point3F *eyeOffset = GFX->getStereoEyeOffsets();
|
const Point3F *eyeOffset = GFX->getStereoEyeOffsets();
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,8 @@ struct CameraQuery
|
||||||
Point3F eyeOffset[2];
|
Point3F eyeOffset[2];
|
||||||
MatrixF eyeTransforms[2];
|
MatrixF eyeTransforms[2];
|
||||||
bool ortho;
|
bool ortho;
|
||||||
|
bool hasFovPort;
|
||||||
|
bool hasStereoTargets;
|
||||||
MatrixF cameraMatrix;
|
MatrixF cameraMatrix;
|
||||||
RectI stereoViewports[2]; // destination viewports
|
RectI stereoViewports[2]; // destination viewports
|
||||||
GFXTextureTarget* stereoTargets[2];
|
GFXTextureTarget* stereoTargets[2];
|
||||||
|
|
|
||||||
|
|
@ -606,7 +606,7 @@ void PlaneReflector::updateReflection( const ReflectParams ¶ms )
|
||||||
RectI originalVP = GFX->getViewport();
|
RectI originalVP = GFX->getViewport();
|
||||||
|
|
||||||
Point2F projOffset = GFX->getCurrentProjectionOffset();
|
Point2F projOffset = GFX->getCurrentProjectionOffset();
|
||||||
const FovPort *currentFovPort = GFX->getSteroFovPort();
|
const FovPort *currentFovPort = GFX->getStereoFovPort();
|
||||||
MatrixF inverseEyeTransforms[2];
|
MatrixF inverseEyeTransforms[2];
|
||||||
|
|
||||||
// Calculate world transforms for eyes
|
// Calculate world transforms for eyes
|
||||||
|
|
|
||||||
|
|
@ -240,7 +240,7 @@ void SceneManager::renderScene( SceneRenderState* renderState, U32 objectMask, S
|
||||||
Frustum originalFrustum = GFX->getFrustum();
|
Frustum originalFrustum = GFX->getFrustum();
|
||||||
|
|
||||||
Point2F projOffset = GFX->getCurrentProjectionOffset();
|
Point2F projOffset = GFX->getCurrentProjectionOffset();
|
||||||
const FovPort *currentFovPort = GFX->getSteroFovPort();
|
const FovPort *currentFovPort = GFX->getStereoFovPort();
|
||||||
const MatrixF *eyeTransforms = GFX->getStereoEyeTransforms();
|
const MatrixF *eyeTransforms = GFX->getStereoEyeTransforms();
|
||||||
const MatrixF *worldEyeTransforms = GFX->getInverseStereoEyeTransforms();
|
const MatrixF *worldEyeTransforms = GFX->getInverseStereoEyeTransforms();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue