|
@@ -38,8 +38,8 @@
|
|
#include "gfx/gfxDrawUtil.h"
|
|
#include "gfx/gfxDrawUtil.h"
|
|
#include "gfx/gfxDebugEvent.h"
|
|
#include "gfx/gfxDebugEvent.h"
|
|
#include "core/stream/fileStream.h"
|
|
#include "core/stream/fileStream.h"
|
|
-
|
|
|
|
-GFXTextureObject *gLastStereoTexture = NULL;
|
|
|
|
|
|
+#include "platform/output/IDisplayDevice.h"
|
|
|
|
+#include "T3D/gameBase/extended/extendedMove.h"
|
|
|
|
|
|
#define TS_OVERLAY_SCREEN_WIDTH 0.75
|
|
#define TS_OVERLAY_SCREEN_WIDTH 0.75
|
|
|
|
|
|
@@ -66,6 +66,7 @@ ImplementEnumType( GuiTSRenderStyles,
|
|
"@ingroup Gui3D" )
|
|
"@ingroup Gui3D" )
|
|
{ GuiTSCtrl::RenderStyleStandard, "standard" },
|
|
{ GuiTSCtrl::RenderStyleStandard, "standard" },
|
|
{ GuiTSCtrl::RenderStyleStereoSideBySide, "stereo side by side" },
|
|
{ GuiTSCtrl::RenderStyleStereoSideBySide, "stereo side by side" },
|
|
|
|
+ { GuiTSCtrl::RenderStyleStereoSeparate, "stereo separate" },
|
|
EndImplementEnumType;
|
|
EndImplementEnumType;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
@@ -353,32 +354,111 @@ static FovPort CalculateFovPortForCanvas(const RectI viewport, const CameraQuery
|
|
return fovPort;
|
|
return fovPort;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void GuiTSCtrl::_internalRender(RectI viewport, Frustum &frustum)
|
|
|
|
+{
|
|
|
|
+ GFXTransformSaver saver;
|
|
|
|
+ Point2I renderSize = viewport.extent;
|
|
|
|
+
|
|
|
|
+ if (mReflectPriority > 0)
|
|
|
|
+ {
|
|
|
|
+ // Get the total reflection priority.
|
|
|
|
+ F32 totalPriority = 0;
|
|
|
|
+ for (U32 i = 0; i < smAwakeTSCtrls.size(); i++)
|
|
|
|
+ if (smAwakeTSCtrls[i]->isVisible())
|
|
|
|
+ totalPriority += smAwakeTSCtrls[i]->mReflectPriority;
|
|
|
|
+
|
|
|
|
+ REFLECTMGR->update(mReflectPriority / totalPriority,
|
|
|
|
+ getExtent(),
|
|
|
|
+ mLastCameraQuery);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (mForceFOV != 0)
|
|
|
|
+ mLastCameraQuery.fov = mDegToRad(mForceFOV);
|
|
|
|
+
|
|
|
|
+ if (mCameraZRot)
|
|
|
|
+ {
|
|
|
|
+ MatrixF rotMat(EulerF(0, 0, mDegToRad(mCameraZRot)));
|
|
|
|
+ mLastCameraQuery.cameraMatrix.mul(rotMat);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ GFX->setViewport(viewport);
|
|
|
|
+
|
|
|
|
+ // Clear the zBuffer so GUI doesn't hose object rendering accidentally
|
|
|
|
+ GFX->clear(GFXClearZBuffer, ColorI(20, 20, 20), 1.0f, 0);
|
|
|
|
+
|
|
|
|
+ GFX->setFrustum(frustum);
|
|
|
|
+ mSaveProjection = GFX->getProjectionMatrix();
|
|
|
|
+
|
|
|
|
+ if (mLastCameraQuery.ortho)
|
|
|
|
+ {
|
|
|
|
+ mOrthoWidth = frustum.getWidth();
|
|
|
|
+ mOrthoHeight = frustum.getHeight();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // We're going to be displaying this render at size of this control in
|
|
|
|
+ // pixels - let the scene know so that it can calculate e.g. reflections
|
|
|
|
+ // correctly for that final display result.
|
|
|
|
+ gClientSceneGraph->setDisplayTargetResolution(renderSize);
|
|
|
|
+
|
|
|
|
+ // Set the GFX world matrix to the world-to-camera transform, but don't
|
|
|
|
+ // change the cameraMatrix in mLastCameraQuery. This is because
|
|
|
|
+ // mLastCameraQuery.cameraMatrix is supposed to contain the camera-to-world
|
|
|
|
+ // transform. In-place invert would save a copy but mess up any GUIs that
|
|
|
|
+ // depend on that value.
|
|
|
|
+ MatrixF worldToCamera = mLastCameraQuery.cameraMatrix;
|
|
|
|
+ worldToCamera.inverse();
|
|
|
|
+ GFX->setWorldMatrix(worldToCamera);
|
|
|
|
+
|
|
|
|
+ mSaveProjection = GFX->getProjectionMatrix();
|
|
|
|
+ mSaveModelview = GFX->getWorldMatrix();
|
|
|
|
+ mSaveViewport = viewport;
|
|
|
|
+ mSaveWorldToScreenScale = GFX->getWorldToScreenScale();
|
|
|
|
+ mSaveFrustum = GFX->getFrustum();
|
|
|
|
+ mSaveFrustum.setTransform(mLastCameraQuery.cameraMatrix);
|
|
|
|
+
|
|
|
|
+ // Set the default non-clip projection as some
|
|
|
|
+ // objects depend on this even in non-reflect cases.
|
|
|
|
+ gClientSceneGraph->setNonClipProjection(mSaveProjection);
|
|
|
|
+
|
|
|
|
+ // Give the post effect manager the worldToCamera, and cameraToScreen matrices
|
|
|
|
+ PFXMGR->setFrameMatrices(mSaveModelview, mSaveProjection);
|
|
|
|
+
|
|
|
|
+ renderWorld(viewport);
|
|
|
|
+ DebugDrawer::get()->render();
|
|
|
|
+
|
|
|
|
+ // Restore the previous matrix state before
|
|
|
|
+ // we begin rendering the child controls.
|
|
|
|
+ saver.restore();
|
|
|
|
+}
|
|
|
|
+
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
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
|
|
// it for child control rendering below.
|
|
// it for child control rendering below.
|
|
GFXTransformSaver saver;
|
|
GFXTransformSaver saver;
|
|
bool renderingToTarget = false;
|
|
bool renderingToTarget = false;
|
|
|
|
|
|
- if(!processCameraQuery(&mLastCameraQuery))
|
|
|
|
|
|
+ if (!processCameraQuery(&mLastCameraQuery))
|
|
{
|
|
{
|
|
// We have no camera, but render the GUI children
|
|
// We have no camera, but render the GUI children
|
|
// anyway. This makes editing GuiTSCtrl derived
|
|
// anyway. This makes editing GuiTSCtrl derived
|
|
// controls easier in the GuiEditor.
|
|
// controls easier in the GuiEditor.
|
|
- renderChildControls( offset, updateRect );
|
|
|
|
|
|
+ renderChildControls(offset, updateRect);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
GFXTargetRef origTarget = GFX->getActiveRenderTarget();
|
|
GFXTargetRef origTarget = GFX->getActiveRenderTarget();
|
|
|
|
+ U32 origStyle = GFX->getCurrentRenderStyle();
|
|
|
|
|
|
// Set up the appropriate render style
|
|
// Set up the appropriate render style
|
|
U32 prevRenderStyle = GFX->getCurrentRenderStyle();
|
|
U32 prevRenderStyle = GFX->getCurrentRenderStyle();
|
|
Point2F prevProjectionOffset = GFX->getCurrentProjectionOffset();
|
|
Point2F prevProjectionOffset = GFX->getCurrentProjectionOffset();
|
|
Point2I renderSize = getExtent();
|
|
Point2I renderSize = getExtent();
|
|
|
|
+ Frustum frustum;
|
|
|
|
|
|
- if(mRenderStyle == RenderStyleStereoSideBySide)
|
|
|
|
|
|
+ if (mRenderStyle == RenderStyleStereoSideBySide)
|
|
{
|
|
{
|
|
GFX->setCurrentRenderStyle(GFXDevice::RS_StereoSideBySide);
|
|
GFX->setCurrentRenderStyle(GFXDevice::RS_StereoSideBySide);
|
|
GFX->setCurrentProjectionOffset(mLastCameraQuery.projectionOffset);
|
|
GFX->setCurrentProjectionOffset(mLastCameraQuery.projectionOffset);
|
|
@@ -399,13 +479,13 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
|
|
mLastCameraQuery.fovPort[0] = CalculateFovPortForCanvas(mLastCameraQuery.stereoViewports[0], mLastCameraQuery);
|
|
mLastCameraQuery.fovPort[0] = CalculateFovPortForCanvas(mLastCameraQuery.stereoViewports[0], mLastCameraQuery);
|
|
mLastCameraQuery.fovPort[1] = CalculateFovPortForCanvas(mLastCameraQuery.stereoViewports[1], mLastCameraQuery);
|
|
mLastCameraQuery.fovPort[1] = CalculateFovPortForCanvas(mLastCameraQuery.stereoViewports[1], mLastCameraQuery);
|
|
}
|
|
}
|
|
-
|
|
|
|
- GFX->setStereoFovPort(mLastCameraQuery.fovPort); // NOTE: this specifies fov for BOTH eyes
|
|
|
|
|
|
|
|
|
|
+ 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);
|
|
|
|
|
|
MatrixF myTransforms[2];
|
|
MatrixF myTransforms[2];
|
|
|
|
+ Frustum frustum;
|
|
|
|
|
|
if (smUseLatestDisplayTransform)
|
|
if (smUseLatestDisplayTransform)
|
|
{
|
|
{
|
|
@@ -435,52 +515,109 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
|
|
renderSize = mLastCameraQuery.stereoViewports[0].extent;
|
|
renderSize = mLastCameraQuery.stereoViewports[0].extent;
|
|
renderingToTarget = true;
|
|
renderingToTarget = true;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // NOTE: these calculations are essentially overridden later by the fov port settings when rendering each eye.
|
|
|
|
+ MathUtils::makeFovPortFrustum(&frustum, mLastCameraQuery.ortho, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane, mLastCameraQuery.fovPort[0]);
|
|
|
|
+
|
|
|
|
+ GFX->activateStereoTarget(-1);
|
|
|
|
+ _internalRender(RectI(updateRect.point, updateRect.extent), frustum);
|
|
|
|
+
|
|
|
|
+ // Render preview
|
|
|
|
+ if (mLastCameraQuery.displayDevice)
|
|
|
|
+ {
|
|
|
|
+ GFXTexHandle previewTexture = mLastCameraQuery.displayDevice->getPreviewTexture();
|
|
|
|
+ if (!previewTexture.isNull())
|
|
|
|
+ {
|
|
|
|
+ GFX->setActiveRenderTarget(origTarget);
|
|
|
|
+ GFX->setCurrentRenderStyle(origStyle);
|
|
|
|
+ GFX->setClipRect(updateRect);
|
|
|
|
+ renderDisplayPreview(updateRect, previewTexture);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- else
|
|
|
|
|
|
+ else if (mRenderStyle == RenderStyleStereoSeparate && mLastCameraQuery.stereoTargets[0])
|
|
{
|
|
{
|
|
- GFX->setCurrentRenderStyle(GFXDevice::RS_Standard);
|
|
|
|
- }
|
|
|
|
|
|
+ // In this case we render the scene twice to different render targets, then
|
|
|
|
+ // render the final composite view
|
|
|
|
+ GFX->setCurrentRenderStyle(GFXDevice::RS_StereoSeparate);
|
|
|
|
+ GFX->setStereoEyeOffsets(mLastCameraQuery.eyeOffset);
|
|
|
|
+ GFX->setStereoFovPort(mLastCameraQuery.fovPort); // NOTE: this specifies fov for BOTH eyes
|
|
|
|
+ GFX->setSteroViewports(mLastCameraQuery.stereoViewports);
|
|
|
|
+ GFX->setStereoTargets(mLastCameraQuery.stereoTargets);
|
|
|
|
|
|
- if ( mReflectPriority > 0 )
|
|
|
|
- {
|
|
|
|
- // Get the total reflection priority.
|
|
|
|
- F32 totalPriority = 0;
|
|
|
|
- for ( U32 i=0; i < smAwakeTSCtrls.size(); i++ )
|
|
|
|
- if ( smAwakeTSCtrls[i]->isVisible() )
|
|
|
|
- totalPriority += smAwakeTSCtrls[i]->mReflectPriority;
|
|
|
|
|
|
+ MatrixF myTransforms[2];
|
|
|
|
|
|
- REFLECTMGR->update( mReflectPriority / totalPriority,
|
|
|
|
- getExtent(),
|
|
|
|
- mLastCameraQuery );
|
|
|
|
- }
|
|
|
|
|
|
+ if (smUseLatestDisplayTransform)
|
|
|
|
+ {
|
|
|
|
+ // Use the view matrix determined from the display device
|
|
|
|
+ myTransforms[0] = mLastCameraQuery.eyeTransforms[0];
|
|
|
|
+ myTransforms[1] = mLastCameraQuery.eyeTransforms[1];
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ // Use the view matrix determined from the control object
|
|
|
|
+ myTransforms[0] = mLastCameraQuery.cameraMatrix;
|
|
|
|
+ myTransforms[1] = mLastCameraQuery.cameraMatrix;
|
|
|
|
|
|
- if(mForceFOV != 0)
|
|
|
|
- mLastCameraQuery.fov = mDegToRad(mForceFOV);
|
|
|
|
|
|
+ QuatF qrot = mLastCameraQuery.cameraMatrix;
|
|
|
|
+ Point3F pos = mLastCameraQuery.cameraMatrix.getPosition();
|
|
|
|
+ Point3F rotEyePos;
|
|
|
|
|
|
- if(mCameraZRot)
|
|
|
|
- {
|
|
|
|
- MatrixF rotMat(EulerF(0, 0, mDegToRad(mCameraZRot)));
|
|
|
|
- mLastCameraQuery.cameraMatrix.mul(rotMat);
|
|
|
|
- }
|
|
|
|
|
|
+ myTransforms[0].setPosition(pos + qrot.mulP(mLastCameraQuery.eyeOffset[0], &rotEyePos));
|
|
|
|
+ myTransforms[1].setPosition(pos + qrot.mulP(mLastCameraQuery.eyeOffset[1], &rotEyePos));
|
|
|
|
+ }
|
|
|
|
|
|
- Frustum frustum;
|
|
|
|
- if(mRenderStyle == RenderStyleStereoSideBySide)
|
|
|
|
- {
|
|
|
|
- // NOTE: these calculations are essentially overridden later by the fov port settings when rendering each eye.
|
|
|
|
- MathUtils::makeFovPortFrustum(&frustum, mLastCameraQuery.ortho, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane, mLastCameraQuery.fovPort[0]);
|
|
|
|
|
|
+ MatrixF origMatrix = mLastCameraQuery.cameraMatrix;
|
|
|
|
+
|
|
|
|
+ // Left
|
|
|
|
+ MathUtils::makeFovPortFrustum(&frustum, mLastCameraQuery.ortho, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane, mLastCameraQuery.fovPort[0]);
|
|
|
|
+ mLastCameraQuery.cameraMatrix = myTransforms[0];
|
|
|
|
+ frustum.update();
|
|
|
|
+ GFX->activateStereoTarget(0);
|
|
|
|
+ _internalRender(RectI(Point2I(0, 0), mLastCameraQuery.stereoTargets[0]->getSize()), frustum);
|
|
|
|
+ GFX->getDeviceEventSignal().trigger(GFXDevice::deLeftStereoFrameRendered);
|
|
|
|
+
|
|
|
|
+ // Right
|
|
|
|
+ GFX->activateStereoTarget(1);
|
|
|
|
+ MathUtils::makeFovPortFrustum(&frustum, mLastCameraQuery.ortho, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane, mLastCameraQuery.fovPort[1]);
|
|
|
|
+ mLastCameraQuery.cameraMatrix = myTransforms[1];
|
|
|
|
+ frustum.update();
|
|
|
|
+ _internalRender(RectI(Point2I(0, 0), mLastCameraQuery.stereoTargets[1]->getSize()), frustum);
|
|
|
|
+ GFX->getDeviceEventSignal().trigger(GFXDevice::deRightStereoFrameRendered);
|
|
|
|
+
|
|
|
|
+ mLastCameraQuery.cameraMatrix = origMatrix;
|
|
|
|
+
|
|
|
|
+ // Render preview
|
|
|
|
+ if (mLastCameraQuery.displayDevice)
|
|
|
|
+ {
|
|
|
|
+ GFXTexHandle previewTexture = mLastCameraQuery.displayDevice->getPreviewTexture();
|
|
|
|
+ if (!previewTexture.isNull())
|
|
|
|
+ {
|
|
|
|
+ GFX->setActiveRenderTarget(origTarget);
|
|
|
|
+ GFX->setCurrentRenderStyle(origStyle);
|
|
|
|
+ GFX->setClipRect(updateRect);
|
|
|
|
+ renderDisplayPreview(updateRect, previewTexture);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
|
|
+#ifdef TORQUE_OS_MAC
|
|
|
|
+ Point2I screensize = getRoot()->getWindowSize();
|
|
|
|
+ tempRect.point.y = screensize.y - (tempRect.point.y + tempRect.extent.y);
|
|
|
|
+#endif
|
|
|
|
+ GFX->setCurrentRenderStyle(GFXDevice::RS_Standard);
|
|
|
|
+
|
|
// set up the camera and viewport stuff:
|
|
// set up the camera and viewport stuff:
|
|
F32 wwidth;
|
|
F32 wwidth;
|
|
F32 wheight;
|
|
F32 wheight;
|
|
F32 renderWidth = F32(renderSize.x);
|
|
F32 renderWidth = F32(renderSize.x);
|
|
F32 renderHeight = F32(renderSize.y);
|
|
F32 renderHeight = F32(renderSize.y);
|
|
F32 aspectRatio = renderWidth / renderHeight;
|
|
F32 aspectRatio = renderWidth / renderHeight;
|
|
-
|
|
|
|
|
|
+
|
|
// Use the FOV to calculate the viewport height scale
|
|
// Use the FOV to calculate the viewport height scale
|
|
// then generate the width scale from the aspect ratio.
|
|
// then generate the width scale from the aspect ratio.
|
|
- if(!mLastCameraQuery.ortho)
|
|
|
|
|
|
+ if (!mLastCameraQuery.ortho)
|
|
{
|
|
{
|
|
wheight = mLastCameraQuery.nearPlane * mTan(mLastCameraQuery.fov / 2.0f);
|
|
wheight = mLastCameraQuery.nearPlane * mTan(mLastCameraQuery.fov / 2.0f);
|
|
wwidth = aspectRatio * wheight;
|
|
wwidth = aspectRatio * wheight;
|
|
@@ -499,251 +636,33 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
|
|
F32 top = wheight - vscale * (updateRect.point.y - offset.y);
|
|
F32 top = wheight - vscale * (updateRect.point.y - offset.y);
|
|
F32 bottom = wheight - vscale * (updateRect.point.y + updateRect.extent.y - offset.y);
|
|
F32 bottom = wheight - vscale * (updateRect.point.y + updateRect.extent.y - offset.y);
|
|
|
|
|
|
- frustum.set( mLastCameraQuery.ortho, left, right, top, bottom, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane );
|
|
|
|
- }
|
|
|
|
|
|
+ frustum.set(mLastCameraQuery.ortho, left, right, top, bottom, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane);
|
|
|
|
|
|
- // Manipulate the frustum for tiled screenshots
|
|
|
|
- const bool screenShotMode = gScreenShot && gScreenShot->isPending();
|
|
|
|
- if ( screenShotMode )
|
|
|
|
- {
|
|
|
|
- gScreenShot->tileFrustum( frustum );
|
|
|
|
- GFX->setViewMatrix(MatrixF::Identity);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- RectI tempRect = updateRect;
|
|
|
|
-
|
|
|
|
- if (!renderingToTarget)
|
|
|
|
- {
|
|
|
|
- #ifdef TORQUE_OS_MAC
|
|
|
|
- Point2I screensize = getRoot()->getWindowSize();
|
|
|
|
- tempRect.point.y = screensize.y - (tempRect.point.y + tempRect.extent.y);
|
|
|
|
- #endif
|
|
|
|
-
|
|
|
|
- GFX->setViewport( tempRect );
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- // Activate stereo RT
|
|
|
|
- GFX->activateStereoTarget(-1);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Clear the zBuffer so GUI doesn't hose object rendering accidentally
|
|
|
|
- GFX->clear( GFXClearZBuffer , ColorI(20,20,20), 1.0f, 0 );
|
|
|
|
- //GFX->clear( GFXClearTarget, ColorI(255,0,0), 1.0f, 0);
|
|
|
|
-
|
|
|
|
- GFX->setFrustum( frustum );
|
|
|
|
- if(mLastCameraQuery.ortho)
|
|
|
|
- {
|
|
|
|
- mOrthoWidth = frustum.getWidth();
|
|
|
|
- mOrthoHeight = frustum.getHeight();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // We're going to be displaying this render at size of this control in
|
|
|
|
- // pixels - let the scene know so that it can calculate e.g. reflections
|
|
|
|
- // correctly for that final display result.
|
|
|
|
- gClientSceneGraph->setDisplayTargetResolution(renderSize);
|
|
|
|
-
|
|
|
|
- // Set the GFX world matrix to the world-to-camera transform, but don't
|
|
|
|
- // change the cameraMatrix in mLastCameraQuery. This is because
|
|
|
|
- // mLastCameraQuery.cameraMatrix is supposed to contain the camera-to-world
|
|
|
|
- // transform. In-place invert would save a copy but mess up any GUIs that
|
|
|
|
- // depend on that value.
|
|
|
|
- MatrixF worldToCamera = mLastCameraQuery.cameraMatrix;
|
|
|
|
- worldToCamera.inverse();
|
|
|
|
- GFX->setWorldMatrix( worldToCamera );
|
|
|
|
-
|
|
|
|
- mSaveProjection = GFX->getProjectionMatrix();
|
|
|
|
- mSaveModelview = GFX->getWorldMatrix();
|
|
|
|
- mSaveViewport = updateRect;
|
|
|
|
- mSaveWorldToScreenScale = GFX->getWorldToScreenScale();
|
|
|
|
- mSaveFrustum = GFX->getFrustum();
|
|
|
|
- mSaveFrustum.setTransform( mLastCameraQuery.cameraMatrix );
|
|
|
|
-
|
|
|
|
- // Set the default non-clip projection as some
|
|
|
|
- // objects depend on this even in non-reflect cases.
|
|
|
|
- gClientSceneGraph->setNonClipProjection( mSaveProjection );
|
|
|
|
-
|
|
|
|
- // Give the post effect manager the worldToCamera, and cameraToScreen matrices
|
|
|
|
- PFXMGR->setFrameMatrices( mSaveModelview, mSaveProjection );
|
|
|
|
-
|
|
|
|
- renderWorld(updateRect);
|
|
|
|
- DebugDrawer::get()->render();
|
|
|
|
-
|
|
|
|
- // Render the canvas overlay if its available
|
|
|
|
- if (false && mRenderStyle == RenderStyleStereoSideBySide && mStereoGuiTarget.getPointer())
|
|
|
|
- {
|
|
|
|
- GFXDEBUGEVENT_SCOPE( StereoGui_Render, ColorI( 255, 0, 0 ) );
|
|
|
|
- MatrixF proj(1);
|
|
|
|
-
|
|
|
|
- Frustum originalFrustum = GFX->getFrustum();
|
|
|
|
- GFXTextureObject *texObject = mStereoGuiTarget->getTexture(0);
|
|
|
|
- const FovPort *currentFovPort = GFX->getStereoFovPort();
|
|
|
|
- const MatrixF *eyeTransforms = GFX->getStereoEyeTransforms();
|
|
|
|
- const Point3F *eyeOffset = GFX->getStereoEyeOffsets();
|
|
|
|
- Frustum gfxFrustum = originalFrustum;
|
|
|
|
-
|
|
|
|
- for (U32 i=0; i<2; i++)
|
|
|
|
|
|
+ // Manipulate the frustum for tiled screenshots
|
|
|
|
+ const bool screenShotMode = gScreenShot && gScreenShot->isPending();
|
|
|
|
+ if (screenShotMode)
|
|
{
|
|
{
|
|
- GFX->activateStereoTarget(i);
|
|
|
|
- MathUtils::makeFovPortFrustum(&gfxFrustum, true, gfxFrustum.getNearDist(), gfxFrustum.getFarDist(), currentFovPort[i], eyeTransforms[i]);
|
|
|
|
- GFX->setFrustum(gfxFrustum);
|
|
|
|
-
|
|
|
|
- MatrixF eyeWorldTrans(1);
|
|
|
|
- eyeWorldTrans.setPosition(Point3F(eyeOffset[i].x,eyeOffset[i].y,eyeOffset[i].z));
|
|
|
|
- MatrixF eyeWorld(1);
|
|
|
|
- eyeWorld.mul(eyeWorldTrans);
|
|
|
|
- eyeWorld.inverse();
|
|
|
|
-
|
|
|
|
- GFX->setWorldMatrix(eyeWorld);
|
|
|
|
|
|
+ gScreenShot->tileFrustum(frustum);
|
|
GFX->setViewMatrix(MatrixF::Identity);
|
|
GFX->setViewMatrix(MatrixF::Identity);
|
|
-
|
|
|
|
- if (!mStereoOverlayVB.getPointer())
|
|
|
|
- {
|
|
|
|
- mStereoOverlayVB.set(GFX, 4, GFXBufferTypeStatic);
|
|
|
|
- GFXVertexPCT *verts = mStereoOverlayVB.lock(0, 4);
|
|
|
|
-
|
|
|
|
- F32 texLeft = 0.0f;
|
|
|
|
- F32 texRight = 1.0f;
|
|
|
|
- F32 texTop = 1.0f;
|
|
|
|
- F32 texBottom = 0.0f;
|
|
|
|
-
|
|
|
|
- F32 rectRatio = gfxFrustum.getWidth() / gfxFrustum.getHeight();
|
|
|
|
- F32 rectWidth = gfxFrustum.getWidth() * TS_OVERLAY_SCREEN_WIDTH;
|
|
|
|
- F32 rectHeight = rectWidth * rectRatio;
|
|
|
|
-
|
|
|
|
- F32 screenLeft = -rectWidth * 0.5;
|
|
|
|
- F32 screenRight = rectWidth * 0.5;
|
|
|
|
- F32 screenTop = -rectHeight * 0.5;
|
|
|
|
- F32 screenBottom = rectHeight * 0.5;
|
|
|
|
-
|
|
|
|
- const F32 fillConv = 0.0f;
|
|
|
|
- const F32 frustumDepthAdjusted = gfxFrustum.getNearDist() + 0.012;
|
|
|
|
- verts[0].point.set( screenLeft - fillConv, frustumDepthAdjusted, screenTop - fillConv );
|
|
|
|
- verts[1].point.set( screenRight - fillConv, frustumDepthAdjusted, screenTop - fillConv );
|
|
|
|
- verts[2].point.set( screenLeft - fillConv, frustumDepthAdjusted, screenBottom - fillConv );
|
|
|
|
- verts[3].point.set( screenRight - fillConv, frustumDepthAdjusted, screenBottom - fillConv );
|
|
|
|
-
|
|
|
|
- verts[0].color = verts[1].color = verts[2].color = verts[3].color = ColorI(255,255,255,255);
|
|
|
|
-
|
|
|
|
- verts[0].texCoord.set( texLeft, texTop );
|
|
|
|
- verts[1].texCoord.set( texRight, texTop );
|
|
|
|
- verts[2].texCoord.set( texLeft, texBottom );
|
|
|
|
- verts[3].texCoord.set( texRight, texBottom );
|
|
|
|
-
|
|
|
|
- mStereoOverlayVB.unlock();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (!mStereoGuiSB.getPointer())
|
|
|
|
- {
|
|
|
|
- // DrawBitmapStretchSR
|
|
|
|
- GFXStateBlockDesc bitmapStretchSR;
|
|
|
|
- bitmapStretchSR.setCullMode(GFXCullNone);
|
|
|
|
- bitmapStretchSR.setZReadWrite(false, false);
|
|
|
|
- bitmapStretchSR.setBlend(false , GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
|
|
|
|
- bitmapStretchSR.samplersDefined = true;
|
|
|
|
-
|
|
|
|
- bitmapStretchSR.samplers[0] = GFXSamplerStateDesc::getClampLinear();
|
|
|
|
- bitmapStretchSR.samplers[0].minFilter = GFXTextureFilterPoint;
|
|
|
|
- bitmapStretchSR.samplers[0].mipFilter = GFXTextureFilterPoint;
|
|
|
|
- bitmapStretchSR.samplers[0].magFilter = GFXTextureFilterPoint;
|
|
|
|
-
|
|
|
|
- mStereoGuiSB = GFX->createStateBlock(bitmapStretchSR);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- GFX->setVertexBuffer(mStereoOverlayVB);
|
|
|
|
- GFX->setStateBlock(mStereoGuiSB);
|
|
|
|
- GFX->setTexture( 0, texObject );
|
|
|
|
- GFX->setupGenericShaders( GFXDevice::GSModColorTexture );
|
|
|
|
- GFX->drawPrimitive( GFXTriangleStrip, 0, 2 );
|
|
|
|
}
|
|
}
|
|
- }
|
|
|
|
|
|
|
|
- // Restore the previous matrix state before
|
|
|
|
- // we begin rendering the child controls.
|
|
|
|
- saver.restore();
|
|
|
|
|
|
+ RectI tempRect = updateRect;
|
|
|
|
|
|
- // Restore the render style and any stereo parameters
|
|
|
|
- GFX->setActiveRenderTarget(origTarget);
|
|
|
|
- GFX->setCurrentRenderStyle(prevRenderStyle);
|
|
|
|
- GFX->setCurrentProjectionOffset(prevProjectionOffset);
|
|
|
|
|
|
+#ifdef TORQUE_OS_MAC
|
|
|
|
+ Point2I screensize = getRoot()->getWindowSize();
|
|
|
|
+ tempRect.point.y = screensize.y - (tempRect.point.y + tempRect.extent.y);
|
|
|
|
+#endif
|
|
|
|
|
|
- GFX->updateStates(true);
|
|
|
|
-
|
|
|
|
- if(mRenderStyle == RenderStyleStereoSideBySide && gLastStereoTexture)
|
|
|
|
- {
|
|
|
|
- GFX->setWorldMatrix(MatrixF(1));
|
|
|
|
- GFX->setViewMatrix(MatrixF::Identity);
|
|
|
|
- GFX->setClipRect(updateRect);
|
|
|
|
-
|
|
|
|
- GFX->getDrawUtil()->drawRectFill(RectI(Point2I(0,0), Point2I(1024, 768)), ColorI::BLACK);
|
|
|
|
- GFX->getDrawUtil()->drawRect(RectI(Point2I(0, 0), Point2I(1024, 768)), ColorI::RED);
|
|
|
|
-
|
|
|
|
- if (!mStereoOverlayVB.getPointer())
|
|
|
|
- {
|
|
|
|
- mStereoOverlayVB.set(GFX, 4, GFXBufferTypeStatic);
|
|
|
|
- GFXVertexPCT *verts = mStereoOverlayVB.lock(0, 4);
|
|
|
|
-
|
|
|
|
- F32 texLeft = 0.0f;
|
|
|
|
- F32 texRight = 1.0f;
|
|
|
|
- F32 texTop = 1.0f;
|
|
|
|
- F32 texBottom = 0.0f;
|
|
|
|
-
|
|
|
|
- F32 rectWidth = 1024.0;
|
|
|
|
- F32 rectHeight = 768.0;
|
|
|
|
-
|
|
|
|
- F32 screenLeft = 0;
|
|
|
|
- F32 screenRight = rectWidth;
|
|
|
|
- F32 screenTop = 0;
|
|
|
|
- F32 screenBottom = rectHeight;
|
|
|
|
-
|
|
|
|
- const F32 fillConv = 0.0f;
|
|
|
|
- const F32 frustumDepthAdjusted = 0.0f;
|
|
|
|
- verts[0].point.set(screenLeft - fillConv, screenTop - fillConv, 0.f);
|
|
|
|
- verts[1].point.set(screenRight - fillConv, screenTop - fillConv, 0.f);
|
|
|
|
- verts[2].point.set(screenLeft - fillConv, screenBottom - fillConv, 0.f);
|
|
|
|
- verts[3].point.set(screenRight - fillConv, screenBottom - fillConv, 0.f);
|
|
|
|
-
|
|
|
|
- verts[0].color = verts[1].color = verts[2].color = verts[3].color = ColorI(255,255,255,255);
|
|
|
|
-
|
|
|
|
- verts[0].texCoord.set(texLeft, texTop);
|
|
|
|
- verts[1].texCoord.set(texRight, texTop);
|
|
|
|
- verts[2].texCoord.set(texLeft, texBottom);
|
|
|
|
- verts[3].texCoord.set(texRight, texBottom);
|
|
|
|
-
|
|
|
|
- mStereoOverlayVB.unlock();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (!mStereoGuiSB.getPointer())
|
|
|
|
- {
|
|
|
|
- // DrawBitmapStretchSR
|
|
|
|
- GFXStateBlockDesc bitmapStretchSR;
|
|
|
|
- bitmapStretchSR.setCullMode(GFXCullNone);
|
|
|
|
- bitmapStretchSR.setZReadWrite(false, false);
|
|
|
|
- bitmapStretchSR.setBlend(false, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
|
|
|
|
- bitmapStretchSR.samplersDefined = true;
|
|
|
|
-
|
|
|
|
- bitmapStretchSR.samplers[0] = GFXSamplerStateDesc::getClampLinear();
|
|
|
|
- bitmapStretchSR.samplers[0].minFilter = GFXTextureFilterPoint;
|
|
|
|
- bitmapStretchSR.samplers[0].mipFilter = GFXTextureFilterPoint;
|
|
|
|
- bitmapStretchSR.samplers[0].magFilter = GFXTextureFilterPoint;
|
|
|
|
-
|
|
|
|
- mStereoGuiSB = GFX->createStateBlock(bitmapStretchSR);
|
|
|
|
- }
|
|
|
|
- //static GFXTexHandle texHandle("art/gui/splash", &GFXDefaultPersistentProfile, avar("%s() - mTextureNormal (line %d)", __FUNCTION__, __LINE__));
|
|
|
|
- GFX->setVertexBuffer(mStereoOverlayVB);
|
|
|
|
- GFX->setStateBlock(mStereoGuiSB);
|
|
|
|
- GFX->setTexture(0, gLastStereoTexture);// texHandle);// gLastStereoTexture);
|
|
|
|
- GFX->setupGenericShaders(GFXDevice::GSModColorTexture);
|
|
|
|
- GFX->drawPrimitive(GFXTriangleStrip, 0, 2);
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- //GFX->getDrawUtil()->drawBitmapStretch(gLastStereoTexture, updateRect);
|
|
|
|
|
|
+ _internalRender(tempRect, frustum);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // TODO: Some render to sort of overlay system?
|
|
|
|
+
|
|
// Allow subclasses to render 2D elements.
|
|
// Allow subclasses to render 2D elements.
|
|
|
|
+ GFX->setActiveRenderTarget(origTarget);
|
|
|
|
+ GFX->setCurrentRenderStyle(origStyle);
|
|
GFX->setClipRect(updateRect);
|
|
GFX->setClipRect(updateRect);
|
|
- renderGui( offset, updateRect );
|
|
|
|
|
|
+ renderGui(offset, updateRect);
|
|
|
|
|
|
if (shouldRenderChildControls())
|
|
if (shouldRenderChildControls())
|
|
{
|
|
{
|
|
@@ -779,12 +698,84 @@ void GuiTSCtrl::drawLineList( const Vector<Point3F> &points, const ColorI color,
|
|
drawLine( points[i], points[i+1], color, width );
|
|
drawLine( points[i], points[i+1], color, width );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
|
|
void GuiTSCtrl::setStereoGui(GuiOffscreenCanvas *canvas)
|
|
void GuiTSCtrl::setStereoGui(GuiOffscreenCanvas *canvas)
|
|
{
|
|
{
|
|
mStereoGuiTarget = canvas ? canvas->getTarget() : NULL;
|
|
mStereoGuiTarget = canvas ? canvas->getTarget() : NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
+
|
|
|
|
+void GuiTSCtrl::renderDisplayPreview(const RectI &updateRect, GFXTexHandle &previewTexture)
|
|
|
|
+{
|
|
|
|
+ GFX->setWorldMatrix(MatrixF(1));
|
|
|
|
+ GFX->setViewMatrix(MatrixF::Identity);
|
|
|
|
+ GFX->setClipRect(updateRect);
|
|
|
|
+
|
|
|
|
+ GFX->getDrawUtil()->drawRectFill(RectI(Point2I(0, 0), Point2I(1024, 768)), ColorI::BLACK);
|
|
|
|
+ GFX->getDrawUtil()->drawRect(RectI(Point2I(0, 0), Point2I(1024, 768)), ColorI::RED);
|
|
|
|
+
|
|
|
|
+ if (!mStereoPreviewVB.getPointer())
|
|
|
|
+ {
|
|
|
|
+ mStereoPreviewVB.set(GFX, 4, GFXBufferTypeStatic);
|
|
|
|
+ GFXVertexPCT *verts = mStereoPreviewVB.lock(0, 4);
|
|
|
|
+
|
|
|
|
+ F32 texLeft = 0.0f;
|
|
|
|
+ F32 texRight = 1.0f;
|
|
|
|
+ F32 texTop = 0.0f;
|
|
|
|
+ F32 texBottom = 1.0f;
|
|
|
|
+
|
|
|
|
+ F32 rectWidth = updateRect.extent.x;
|
|
|
|
+ F32 rectHeight = updateRect.extent.y;
|
|
|
|
+
|
|
|
|
+ F32 screenLeft = 0;
|
|
|
|
+ F32 screenRight = rectWidth;
|
|
|
|
+ F32 screenTop = 0;
|
|
|
|
+ F32 screenBottom = rectHeight;
|
|
|
|
+
|
|
|
|
+ const F32 fillConv = 0.0f;
|
|
|
|
+ const F32 frustumDepthAdjusted = 0.0f;
|
|
|
|
+ verts[0].point.set(screenLeft - fillConv, screenTop - fillConv, 0.f);
|
|
|
|
+ verts[1].point.set(screenRight - fillConv, screenTop - fillConv, 0.f);
|
|
|
|
+ verts[2].point.set(screenLeft - fillConv, screenBottom - fillConv, 0.f);
|
|
|
|
+ verts[3].point.set(screenRight - fillConv, screenBottom - fillConv, 0.f);
|
|
|
|
+
|
|
|
|
+ verts[0].color = verts[1].color = verts[2].color = verts[3].color = ColorI(255, 255, 255, 255);
|
|
|
|
+
|
|
|
|
+ verts[0].texCoord.set(texLeft, texTop);
|
|
|
|
+ verts[1].texCoord.set(texRight, texTop);
|
|
|
|
+ verts[2].texCoord.set(texLeft, texBottom);
|
|
|
|
+ verts[3].texCoord.set(texRight, texBottom);
|
|
|
|
+
|
|
|
|
+ mStereoPreviewVB.unlock();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!mStereoPreviewSB.getPointer())
|
|
|
|
+ {
|
|
|
|
+ // DrawBitmapStretchSR
|
|
|
|
+ GFXStateBlockDesc bitmapStretchSR;
|
|
|
|
+ bitmapStretchSR.setCullMode(GFXCullNone);
|
|
|
|
+ bitmapStretchSR.setZReadWrite(false, false);
|
|
|
|
+ bitmapStretchSR.setBlend(false, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
|
|
|
|
+ bitmapStretchSR.samplersDefined = true;
|
|
|
|
+
|
|
|
|
+ bitmapStretchSR.samplers[0] = GFXSamplerStateDesc::getClampLinear();
|
|
|
|
+ bitmapStretchSR.samplers[0].minFilter = GFXTextureFilterPoint;
|
|
|
|
+ bitmapStretchSR.samplers[0].mipFilter = GFXTextureFilterPoint;
|
|
|
|
+ bitmapStretchSR.samplers[0].magFilter = GFXTextureFilterPoint;
|
|
|
|
+
|
|
|
|
+ mStereoPreviewSB = GFX->createStateBlock(bitmapStretchSR);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ GFX->setVertexBuffer(mStereoPreviewVB);
|
|
|
|
+ GFX->setStateBlock(mStereoPreviewSB);
|
|
|
|
+ GFX->setTexture(0, previewTexture);
|
|
|
|
+ GFX->setupGenericShaders(GFXDevice::GSModColorTexture);
|
|
|
|
+ GFX->drawPrimitive(GFXTriangleStrip, 0, 2);
|
|
|
|
+}
|
|
|
|
+
|
|
//=============================================================================
|
|
//=============================================================================
|
|
// Console Methods.
|
|
// Console Methods.
|
|
//=============================================================================
|
|
//=============================================================================
|