mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-15 16:44:36 +00:00
Basic fix for reflections in both stereo rendering modes
This commit is contained in:
parent
fa7697b13e
commit
1198932e87
6 changed files with 150 additions and 155 deletions
|
|
@ -353,10 +353,12 @@ static FovPort CalculateFovPortForCanvas(const RectI viewport, const CameraQuery
|
||||||
return fovPort;
|
return fovPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiTSCtrl::_internalRender(RectI viewport, Frustum &frustum)
|
void GuiTSCtrl::_internalRender(RectI guiViewport, RectI renderViewport, Frustum &frustum)
|
||||||
{
|
{
|
||||||
GFXTransformSaver saver;
|
GFXTransformSaver saver;
|
||||||
Point2I renderSize = viewport.extent;
|
Point2I renderSize = renderViewport.extent;
|
||||||
|
GFXTarget *origTarget = GFX->getActiveRenderTarget();
|
||||||
|
S32 origStereoTarget = GFX->getCurrentStereoTarget();
|
||||||
|
|
||||||
if (mForceFOV != 0)
|
if (mForceFOV != 0)
|
||||||
mLastCameraQuery.fov = mDegToRad(mForceFOV);
|
mLastCameraQuery.fov = mDegToRad(mForceFOV);
|
||||||
|
|
@ -380,7 +382,9 @@ void GuiTSCtrl::_internalRender(RectI viewport, Frustum &frustum)
|
||||||
mLastCameraQuery);
|
mLastCameraQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
GFX->setViewport(viewport);
|
GFX->setActiveRenderTarget(origTarget);
|
||||||
|
GFX->setCurrentStereoTarget(origStereoTarget);
|
||||||
|
GFX->setViewport(renderViewport);
|
||||||
|
|
||||||
// Clear the zBuffer so GUI doesn't hose object rendering accidentally
|
// Clear the zBuffer so GUI doesn't hose object rendering accidentally
|
||||||
GFX->clear(GFXClearZBuffer, ColorI(20, 20, 20), 1.0f, 0);
|
GFX->clear(GFXClearZBuffer, ColorI(20, 20, 20), 1.0f, 0);
|
||||||
|
|
@ -410,7 +414,7 @@ void GuiTSCtrl::_internalRender(RectI viewport, Frustum &frustum)
|
||||||
|
|
||||||
mSaveProjection = GFX->getProjectionMatrix();
|
mSaveProjection = GFX->getProjectionMatrix();
|
||||||
mSaveModelview = GFX->getWorldMatrix();
|
mSaveModelview = GFX->getWorldMatrix();
|
||||||
mSaveViewport = viewport;
|
mSaveViewport = guiViewport;
|
||||||
mSaveWorldToScreenScale = GFX->getWorldToScreenScale();
|
mSaveWorldToScreenScale = GFX->getWorldToScreenScale();
|
||||||
mSaveFrustum = GFX->getFrustum();
|
mSaveFrustum = GFX->getFrustum();
|
||||||
mSaveFrustum.setTransform(mLastCameraQuery.cameraMatrix);
|
mSaveFrustum.setTransform(mLastCameraQuery.cameraMatrix);
|
||||||
|
|
@ -422,7 +426,7 @@ void GuiTSCtrl::_internalRender(RectI viewport, Frustum &frustum)
|
||||||
// Give the post effect manager the worldToCamera, and cameraToScreen matrices
|
// Give the post effect manager the worldToCamera, and cameraToScreen matrices
|
||||||
PFXMGR->setFrameMatrices(mSaveModelview, mSaveProjection);
|
PFXMGR->setFrameMatrices(mSaveModelview, mSaveProjection);
|
||||||
|
|
||||||
renderWorld(viewport);
|
renderWorld(guiViewport);
|
||||||
|
|
||||||
DebugDrawer* debugDraw = DebugDrawer::get();
|
DebugDrawer* debugDraw = DebugDrawer::get();
|
||||||
if (mRenderStyle == RenderStyleStereoSideBySide && debugDraw->willDraw())
|
if (mRenderStyle == RenderStyleStereoSideBySide && debugDraw->willDraw())
|
||||||
|
|
@ -445,97 +449,6 @@ void GuiTSCtrl::_internalRender(RectI viewport, Frustum &frustum)
|
||||||
debugDraw->render();
|
debugDraw->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the canvas overlay if its available
|
|
||||||
if (mStereoCanvas.getPointer() && mStereoGuiTarget.getPointer() && mStereoCanvas->size() != 0)
|
|
||||||
{
|
|
||||||
GFXDEBUGEVENT_SCOPE(StereoGui_Render, ColorI(255, 0, 0));
|
|
||||||
MatrixF proj(1);
|
|
||||||
|
|
||||||
Frustum originalFrustum = frustum;
|
|
||||||
GFXTextureObject *texObject = mStereoGuiTarget->getTexture(0);
|
|
||||||
const FovPort *currentFovPort = GFX->getStereoFovPort();
|
|
||||||
const MatrixF *eyeTransforms = GFX->getStereoEyeTransforms();
|
|
||||||
const Point3F *eyeOffset = GFX->getStereoEyeOffsets();
|
|
||||||
Frustum gfxFrustum = originalFrustum;
|
|
||||||
|
|
||||||
GFX->setClipRect(viewport);
|
|
||||||
GFX->setViewport(viewport);
|
|
||||||
GFX->setFrustum(frustum);
|
|
||||||
|
|
||||||
MatrixF eyeWorldTrans(1);
|
|
||||||
if (mLastCameraQuery.currentEye != -1)
|
|
||||||
{
|
|
||||||
eyeWorldTrans.setPosition(Point3F(eyeOffset[mLastCameraQuery.currentEye].x, eyeOffset[mLastCameraQuery.currentEye].y, eyeOffset[mLastCameraQuery.currentEye].z));
|
|
||||||
}
|
|
||||||
MatrixF eyeWorld(1);
|
|
||||||
eyeWorld.mul(eyeWorldTrans);
|
|
||||||
eyeWorld.inverse();
|
|
||||||
|
|
||||||
GFX->setWorldMatrix(eyeWorld);
|
|
||||||
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(true, 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->setPrimitiveBuffer(NULL);
|
|
||||||
GFX->setVertexBuffer(mStereoOverlayVB);
|
|
||||||
GFX->setStateBlock(mStereoGuiSB);
|
|
||||||
GFX->setTexture(0, texObject);
|
|
||||||
GFX->setupGenericShaders(GFXDevice::GSModColorTexture);
|
|
||||||
GFX->drawPrimitive(GFXTriangleStrip, 0, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
saver.restore();
|
saver.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -659,7 +572,7 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||||
// Allow render size to originate from the render target
|
// Allow render size to originate from the render target
|
||||||
if (mLastCameraQuery.stereoTargets[0])
|
if (mLastCameraQuery.stereoTargets[0])
|
||||||
{
|
{
|
||||||
renderSize = mLastCameraQuery.stereoViewports[0].extent;
|
renderSize = mLastCameraQuery.stereoTargets[0]->getSize();
|
||||||
renderingToTarget = true;
|
renderingToTarget = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -667,7 +580,7 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||||
MathUtils::makeFovPortFrustum(&frustum, mLastCameraQuery.ortho, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane, mLastCameraQuery.fovPort[0]);
|
MathUtils::makeFovPortFrustum(&frustum, mLastCameraQuery.ortho, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane, mLastCameraQuery.fovPort[0]);
|
||||||
|
|
||||||
GFX->activateStereoTarget(-1);
|
GFX->activateStereoTarget(-1);
|
||||||
_internalRender(RectI(updateRect.point, updateRect.extent), frustum);
|
_internalRender(RectI(updateRect.point, updateRect.extent), RectI(Point2I(0,0), renderSize), frustum);
|
||||||
|
|
||||||
// Notify device we've rendered the right, thus the last stereo frame.
|
// Notify device we've rendered the right, thus the last stereo frame.
|
||||||
GFX->getDeviceEventSignal().trigger(GFXDevice::deRightStereoFrameRendered);
|
GFX->getDeviceEventSignal().trigger(GFXDevice::deRightStereoFrameRendered);
|
||||||
|
|
@ -726,17 +639,21 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||||
frustum.update();
|
frustum.update();
|
||||||
GFX->activateStereoTarget(0);
|
GFX->activateStereoTarget(0);
|
||||||
mLastCameraQuery.currentEye = 0;
|
mLastCameraQuery.currentEye = 0;
|
||||||
_internalRender(RectI(Point2I(0, 0), mLastCameraQuery.stereoTargets[0]->getSize()), frustum);
|
GFX->beginField();
|
||||||
|
_internalRender(RectI(Point2I(0, 0), mLastCameraQuery.stereoTargets[0]->getSize()), RectI(Point2I(0, 0), mLastCameraQuery.stereoTargets[0]->getSize()), frustum);
|
||||||
GFX->getDeviceEventSignal().trigger(GFXDevice::deLeftStereoFrameRendered);
|
GFX->getDeviceEventSignal().trigger(GFXDevice::deLeftStereoFrameRendered);
|
||||||
|
GFX->endField();
|
||||||
|
|
||||||
// Right
|
// Right
|
||||||
GFX->activateStereoTarget(1);
|
GFX->activateStereoTarget(1);
|
||||||
mLastCameraQuery.currentEye = 1;
|
mLastCameraQuery.currentEye = 1;
|
||||||
MathUtils::makeFovPortFrustum(&frustum, mLastCameraQuery.ortho, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane, mLastCameraQuery.fovPort[1]);
|
MathUtils::makeFovPortFrustum(&frustum, mLastCameraQuery.ortho, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane, mLastCameraQuery.fovPort[1]);
|
||||||
mLastCameraQuery.cameraMatrix = myTransforms[1];
|
mLastCameraQuery.cameraMatrix = myTransforms[1];
|
||||||
frustum.update();
|
frustum.update();
|
||||||
_internalRender(RectI(Point2I(0, 0), mLastCameraQuery.stereoTargets[1]->getSize()), frustum);
|
GFX->beginField();
|
||||||
GFX->getDeviceEventSignal().trigger(GFXDevice::deRightStereoFrameRendered);
|
_internalRender(RectI(Point2I(0, 0), mLastCameraQuery.stereoTargets[1]->getSize()), RectI(Point2I(0, 0), mLastCameraQuery.stereoTargets[0]->getSize()), frustum);
|
||||||
|
GFX->getDeviceEventSignal().trigger(GFXDevice::deRightStereoFrameRendered);
|
||||||
|
GFX->endField();
|
||||||
|
|
||||||
mLastCameraQuery.cameraMatrix = origMatrix;
|
mLastCameraQuery.cameraMatrix = origMatrix;
|
||||||
|
|
||||||
|
|
@ -805,7 +722,7 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||||
tempRect.point.y = screensize.y - (tempRect.point.y + tempRect.extent.y);
|
tempRect.point.y = screensize.y - (tempRect.point.y + tempRect.extent.y);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_internalRender(tempRect, frustum);
|
_internalRender(tempRect, tempRect, frustum);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Some render to sort of overlay system?
|
// TODO: Some render to sort of overlay system?
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ public:
|
||||||
GuiTSCtrl();
|
GuiTSCtrl();
|
||||||
|
|
||||||
void onPreRender();
|
void onPreRender();
|
||||||
void _internalRender(RectI viewport, Frustum &frustum);
|
void _internalRender(RectI guiViewport, RectI renderViewport, Frustum &frustum);
|
||||||
void onRender(Point2I offset, const RectI &updateRect);
|
void onRender(Point2I offset, const RectI &updateRect);
|
||||||
virtual bool processCameraQuery(CameraQuery *query);
|
virtual bool processCameraQuery(CameraQuery *query);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,9 +95,9 @@ ReflectionManager::ReflectionManager()
|
||||||
void ReflectionManager::initConsole()
|
void ReflectionManager::initConsole()
|
||||||
{
|
{
|
||||||
Con::addVariable( "$pref::Reflect::refractTexScale", TypeF32, &ReflectionManager::smRefractTexScale, "RefractTex has dimensions equal to the active render target scaled in both x and y by this float.\n"
|
Con::addVariable( "$pref::Reflect::refractTexScale", TypeF32, &ReflectionManager::smRefractTexScale, "RefractTex has dimensions equal to the active render target scaled in both x and y by this float.\n"
|
||||||
"@ingroup Rendering");
|
"@ingroup Rendering");
|
||||||
Con::addVariable( "$pref::Reflect::frameLimitMS", TypeS32, &ReflectionManager::smFrameReflectionMS, "ReflectionManager tries not to spend more than this amount of time updating reflections per frame.\n"
|
Con::addVariable( "$pref::Reflect::frameLimitMS", TypeS32, &ReflectionManager::smFrameReflectionMS, "ReflectionManager tries not to spend more than this amount of time updating reflections per frame.\n"
|
||||||
"@ingroup Rendering");
|
"@ingroup Rendering");
|
||||||
}
|
}
|
||||||
|
|
||||||
ReflectionManager::~ReflectionManager()
|
ReflectionManager::~ReflectionManager()
|
||||||
|
|
@ -136,22 +136,49 @@ void ReflectionManager::update( F32 timeSlice,
|
||||||
// visibility of reflectors.
|
// visibility of reflectors.
|
||||||
Frustum culler;
|
Frustum culler;
|
||||||
|
|
||||||
|
// jamesu - normally we just need a frustum which covers the current ports, however for SBS mode
|
||||||
|
// we need something which covers both viewports.
|
||||||
S32 stereoTarget = GFX->getCurrentStereoTarget();
|
S32 stereoTarget = GFX->getCurrentStereoTarget();
|
||||||
if (stereoTarget != -1)
|
if (stereoTarget != -1)
|
||||||
{
|
{
|
||||||
MathUtils::makeFovPortFrustum(&culler, false, query.nearPlane, query.farPlane, query.fovPort[stereoTarget]);
|
// In this case we're rendering in stereo using a specific eye
|
||||||
|
MathUtils::makeFovPortFrustum(&culler, false, query.nearPlane, query.farPlane, query.fovPort[stereoTarget], query.headMatrix);
|
||||||
|
}
|
||||||
|
else if (GFX->getCurrentRenderStyle() == GFXDevice::RS_StereoSideBySide)
|
||||||
|
{
|
||||||
|
// Calculate an ideal culling size here, we'll just assume double fov based on the first fovport based on
|
||||||
|
// the head position.
|
||||||
|
FovPort port = query.fovPort[0];
|
||||||
|
F32 leftSize = query.nearPlane * port.leftTan;
|
||||||
|
F32 rightSize = query.nearPlane * port.rightTan;
|
||||||
|
F32 upSize = query.nearPlane * port.upTan;
|
||||||
|
F32 downSize = query.nearPlane * port.downTan;
|
||||||
|
|
||||||
|
F32 left = -leftSize;
|
||||||
|
F32 right = rightSize;
|
||||||
|
F32 top = upSize;
|
||||||
|
F32 bottom = -downSize;
|
||||||
|
|
||||||
|
F32 fovInRadians = mAtan2((top - bottom) / 2.0f, query.nearPlane) * 3.0f;
|
||||||
|
|
||||||
|
culler.set(false,
|
||||||
|
fovInRadians,
|
||||||
|
(F32)(query.stereoViewports[0].extent.x + query.stereoViewports[1].extent.x) / (F32)query.stereoViewports[0].extent.y,
|
||||||
|
query.nearPlane,
|
||||||
|
query.farPlane,
|
||||||
|
query.headMatrix);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
culler.set(false,
|
// Normal culling
|
||||||
query.fov,
|
culler.set(false,
|
||||||
(F32)resolution.x / (F32)resolution.y,
|
query.fov,
|
||||||
query.nearPlane,
|
(F32)resolution.x / (F32)resolution.y,
|
||||||
query.farPlane,
|
query.nearPlane,
|
||||||
query.cameraMatrix);
|
query.farPlane,
|
||||||
|
query.cameraMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Manipulate the frustum for tiled screenshots
|
// Manipulate the frustum for tiled screenshots
|
||||||
const bool screenShotMode = gScreenShot && gScreenShot->isPending();
|
const bool screenShotMode = gScreenShot && gScreenShot->isPending();
|
||||||
if ( screenShotMode )
|
if ( screenShotMode )
|
||||||
|
|
@ -170,6 +197,7 @@ void ReflectionManager::update( F32 timeSlice,
|
||||||
refparams.viewportExtent = resolution;
|
refparams.viewportExtent = resolution;
|
||||||
refparams.culler = culler;
|
refparams.culler = culler;
|
||||||
refparams.startOfUpdateMs = startOfUpdateMs;
|
refparams.startOfUpdateMs = startOfUpdateMs;
|
||||||
|
refparams.eyeId = stereoTarget;
|
||||||
|
|
||||||
// Update the reflection score.
|
// Update the reflection score.
|
||||||
ReflectorList::iterator reflectorIter = mReflectors.begin();
|
ReflectorList::iterator reflectorIter = mReflectors.begin();
|
||||||
|
|
@ -184,6 +212,7 @@ void ReflectionManager::update( F32 timeSlice,
|
||||||
mTimer->getElapsedMs();
|
mTimer->getElapsedMs();
|
||||||
mTimer->reset();
|
mTimer->reset();
|
||||||
U32 numUpdated = 0;
|
U32 numUpdated = 0;
|
||||||
|
U32 currentTarget = stereoTarget >= 0 ? stereoTarget : 0;
|
||||||
reflectorIter = mReflectors.begin();
|
reflectorIter = mReflectors.begin();
|
||||||
for ( ; reflectorIter != mReflectors.end(); reflectorIter++ )
|
for ( ; reflectorIter != mReflectors.end(); reflectorIter++ )
|
||||||
{
|
{
|
||||||
|
|
@ -193,7 +222,12 @@ void ReflectionManager::update( F32 timeSlice,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
(*reflectorIter)->updateReflection( refparams );
|
(*reflectorIter)->updateReflection( refparams );
|
||||||
(*reflectorIter)->lastUpdateMs = startOfUpdateMs;
|
|
||||||
|
if (stereoTarget != 0) // only update MS if we're not rendering the left eye in separate mode
|
||||||
|
{
|
||||||
|
(*reflectorIter)->lastUpdateMs = startOfUpdateMs;
|
||||||
|
}
|
||||||
|
|
||||||
numUpdated++;
|
numUpdated++;
|
||||||
|
|
||||||
// If we run out of update time then stop.
|
// If we run out of update time then stop.
|
||||||
|
|
|
||||||
|
|
@ -533,19 +533,28 @@ void PlaneReflector::updateReflection( const ReflectParams ¶ms )
|
||||||
texDim = getMin( texDim, params.viewportExtent.x );
|
texDim = getMin( texDim, params.viewportExtent.x );
|
||||||
texDim = getMin( texDim, params.viewportExtent.y );
|
texDim = getMin( texDim, params.viewportExtent.y );
|
||||||
|
|
||||||
bool texResize = ( texDim != mLastTexSize );
|
S32 currentTarget = params.eyeId >= 0 ? params.eyeId : 0;
|
||||||
mLastTexSize = texDim;
|
|
||||||
|
|
||||||
const Point2I texSize( texDim, texDim );
|
const Point2I texSize = Point2I(texDim, texDim);
|
||||||
|
|
||||||
|
bool texResize = (texSize != mLastTexSize);
|
||||||
|
mLastTexSize = texSize;
|
||||||
|
|
||||||
if ( texResize ||
|
if ( texResize ||
|
||||||
reflectTex.isNull() ||
|
innerReflectTex[currentTarget].isNull() ||
|
||||||
|
innerReflectTex[currentTarget]->getSize() != texSize ||
|
||||||
reflectTex->getFormat() != REFLECTMGR->getReflectFormat() )
|
reflectTex->getFormat() != REFLECTMGR->getReflectFormat() )
|
||||||
{
|
{
|
||||||
reflectTex = REFLECTMGR->allocRenderTarget( texSize );
|
innerReflectTex[currentTarget] = REFLECTMGR->allocRenderTarget( texSize );
|
||||||
depthBuff = LightShadowMap::_getDepthTarget( texSize.x, texSize.y );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( texResize || depthBuff.isNull() )
|
||||||
|
{
|
||||||
|
depthBuff = LightShadowMap::_getDepthTarget(texSize.x, texSize.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
reflectTex = innerReflectTex[currentTarget];
|
||||||
|
|
||||||
// store current matrices
|
// store current matrices
|
||||||
GFXTransformSaver saver;
|
GFXTransformSaver saver;
|
||||||
|
|
||||||
|
|
@ -554,17 +563,17 @@ void PlaneReflector::updateReflection( const ReflectParams ¶ms )
|
||||||
S32 stereoTarget = GFX->getCurrentStereoTarget();
|
S32 stereoTarget = GFX->getCurrentStereoTarget();
|
||||||
if (stereoTarget != -1)
|
if (stereoTarget != -1)
|
||||||
{
|
{
|
||||||
MathUtils::makeFovPortFrustum(&frustum, false, params.query->nearPlane, params.query->farPlane, params.query->fovPort[stereoTarget]);
|
MathUtils::makeFovPortFrustum(&frustum, false, params.query->nearPlane, params.query->farPlane, params.query->fovPort[stereoTarget]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Point2I viewport(params.viewportExtent);
|
Point2I viewport(params.viewportExtent);
|
||||||
if (GFX->getCurrentRenderStyle() == GFXDevice::RS_StereoSideBySide)
|
if (GFX->getCurrentRenderStyle() == GFXDevice::RS_StereoSideBySide)
|
||||||
{
|
{
|
||||||
viewport.x *= 0.5f;
|
viewport.x *= 0.5f;
|
||||||
}
|
}
|
||||||
F32 aspectRatio = F32(viewport.x) / F32(viewport.y);
|
F32 aspectRatio = F32(viewport.x) / F32(viewport.y);
|
||||||
frustum.set(false, params.query->fov, aspectRatio, params.query->nearPlane, params.query->farPlane);
|
frustum.set(false, params.query->fov, aspectRatio, params.query->nearPlane, params.query->farPlane);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manipulate the frustum for tiled screenshots
|
// Manipulate the frustum for tiled screenshots
|
||||||
|
|
@ -587,7 +596,7 @@ void PlaneReflector::updateReflection( const ReflectParams ¶ms )
|
||||||
|
|
||||||
if(reflectTarget.isNull())
|
if(reflectTarget.isNull())
|
||||||
reflectTarget = GFX->allocRenderToTextureTarget();
|
reflectTarget = GFX->allocRenderToTextureTarget();
|
||||||
reflectTarget->attachTexture( GFXTextureTarget::Color0, reflectTex );
|
reflectTarget->attachTexture( GFXTextureTarget::Color0, innerReflectTex[currentTarget] );
|
||||||
reflectTarget->attachTexture( GFXTextureTarget::DepthStencil, depthBuff );
|
reflectTarget->attachTexture( GFXTextureTarget::DepthStencil, depthBuff );
|
||||||
GFX->pushActiveRenderTarget();
|
GFX->pushActiveRenderTarget();
|
||||||
GFX->setActiveRenderTarget( reflectTarget );
|
GFX->setActiveRenderTarget( reflectTarget );
|
||||||
|
|
@ -615,8 +624,18 @@ void PlaneReflector::updateReflection( const ReflectParams ¶ms )
|
||||||
MatrixF origNonClipProjection = gClientSceneGraph->getNonClipProjection();
|
MatrixF origNonClipProjection = gClientSceneGraph->getNonClipProjection();
|
||||||
PFXFrameState origPFXState = PFXMGR->getFrameState();
|
PFXFrameState origPFXState = PFXMGR->getFrameState();
|
||||||
|
|
||||||
const FovPort *currentFovPort = GFX->getStereoFovPort();
|
const FovPort *currentFovPort = params.query->fovPort;
|
||||||
MatrixF inverseEyeTransforms[2];
|
MatrixF inverseEyeTransforms[2];
|
||||||
|
Frustum gfxFrustum;
|
||||||
|
|
||||||
|
// Calculate viewport based on texture size
|
||||||
|
RectI stereoViewports[2];
|
||||||
|
stereoViewports[0] = params.query->stereoViewports[0];
|
||||||
|
stereoViewports[1] = params.query->stereoViewports[1];
|
||||||
|
stereoViewports[0].extent.x = stereoViewports[1].extent.x = texSize.x / 2;
|
||||||
|
stereoViewports[0].extent.y = stereoViewports[1].extent.y = texSize.y;
|
||||||
|
stereoViewports[0].point.x = 0;
|
||||||
|
stereoViewports[1].point.x = stereoViewports[0].extent.x;
|
||||||
|
|
||||||
// Calculate world transforms for eyes
|
// Calculate world transforms for eyes
|
||||||
inverseEyeTransforms[0] = params.query->eyeTransforms[0];
|
inverseEyeTransforms[0] = params.query->eyeTransforms[0];
|
||||||
|
|
@ -624,50 +643,64 @@ void PlaneReflector::updateReflection( const ReflectParams ¶ms )
|
||||||
inverseEyeTransforms[0].inverse();
|
inverseEyeTransforms[0].inverse();
|
||||||
inverseEyeTransforms[1].inverse();
|
inverseEyeTransforms[1].inverse();
|
||||||
|
|
||||||
Frustum originalFrustum = GFX->getFrustum();
|
//
|
||||||
|
|
||||||
// Render left half of display
|
// Render left half of display
|
||||||
GFX->activateStereoTarget(0);
|
//
|
||||||
GFX->setWorldMatrix(params.query->eyeTransforms[0]);
|
|
||||||
|
|
||||||
Frustum gfxFrustum = originalFrustum;
|
GFX->setViewport(stereoViewports[0]);
|
||||||
MathUtils::makeFovPortFrustum(&gfxFrustum, gfxFrustum.isOrtho(), gfxFrustum.getNearDist(), gfxFrustum.getFarDist(), currentFovPort[0], inverseEyeTransforms[0]);
|
GFX->setCurrentStereoTarget(0);
|
||||||
|
MathUtils::makeFovPortFrustum(&gfxFrustum, params.query->ortho, params.query->nearPlane, params.query->farPlane, params.query->fovPort[0]);
|
||||||
|
gfxFrustum.update();
|
||||||
GFX->setFrustum(gfxFrustum);
|
GFX->setFrustum(gfxFrustum);
|
||||||
|
|
||||||
setGFXMatrices( params.query->eyeTransforms[0] );
|
setGFXMatrices( params.query->eyeTransforms[0] );
|
||||||
|
|
||||||
SceneCameraState cameraStateLeft = SceneCameraState::fromGFX();
|
SceneRenderState renderStateLeft
|
||||||
SceneRenderState renderStateLeft( gClientSceneGraph, SPT_Reflect, cameraStateLeft );
|
(
|
||||||
|
gClientSceneGraph,
|
||||||
|
SPT_Reflect,
|
||||||
|
SceneCameraState::fromGFX()
|
||||||
|
);
|
||||||
|
|
||||||
renderStateLeft.setSceneRenderStyle(SRS_SideBySide);
|
renderStateLeft.setSceneRenderStyle(SRS_SideBySide);
|
||||||
renderStateLeft.getMaterialDelegate().bind( REFLECTMGR, &ReflectionManager::getReflectionMaterial );
|
renderStateLeft.getMaterialDelegate().bind( REFLECTMGR, &ReflectionManager::getReflectionMaterial );
|
||||||
renderStateLeft.setDiffuseCameraTransform( params.query->headMatrix );
|
renderStateLeft.setDiffuseCameraTransform(params.query->headMatrix);
|
||||||
|
//renderStateLeft.disableAdvancedLightingBins(true);
|
||||||
|
|
||||||
gClientSceneGraph->renderSceneNoLights( &renderStateLeft, objTypeFlag );
|
gClientSceneGraph->renderSceneNoLights( &renderStateLeft, objTypeFlag );
|
||||||
|
|
||||||
|
//
|
||||||
// Render right half of display
|
// Render right half of display
|
||||||
GFX->activateStereoTarget(1);
|
//
|
||||||
GFX->setWorldMatrix(params.query->eyeTransforms[1]);
|
|
||||||
|
|
||||||
gfxFrustum = originalFrustum;
|
GFX->setViewport(stereoViewports[1]);
|
||||||
MathUtils::makeFovPortFrustum(&gfxFrustum, gfxFrustum.isOrtho(), gfxFrustum.getNearDist(), gfxFrustum.getFarDist(), currentFovPort[1], inverseEyeTransforms[1]);
|
GFX->setCurrentStereoTarget(1);
|
||||||
|
MathUtils::makeFovPortFrustum(&gfxFrustum, params.query->ortho, params.query->nearPlane, params.query->farPlane, params.query->fovPort[1]);
|
||||||
|
gfxFrustum.update();
|
||||||
GFX->setFrustum(gfxFrustum);
|
GFX->setFrustum(gfxFrustum);
|
||||||
|
|
||||||
setGFXMatrices( params.query->eyeTransforms[1] );
|
setGFXMatrices( params.query->eyeTransforms[1] );
|
||||||
|
|
||||||
SceneCameraState cameraStateRight = SceneCameraState::fromGFX();
|
SceneRenderState renderStateRight
|
||||||
SceneRenderState renderStateRight( gClientSceneGraph, SPT_Reflect, cameraStateRight );
|
(
|
||||||
|
gClientSceneGraph,
|
||||||
|
SPT_Reflect,
|
||||||
|
SceneCameraState::fromGFX()
|
||||||
|
);
|
||||||
|
|
||||||
renderStateRight.setSceneRenderStyle(SRS_SideBySide);
|
renderStateRight.setSceneRenderStyle(SRS_SideBySide);
|
||||||
renderStateRight.getMaterialDelegate().bind( REFLECTMGR, &ReflectionManager::getReflectionMaterial );
|
renderStateRight.getMaterialDelegate().bind( REFLECTMGR, &ReflectionManager::getReflectionMaterial );
|
||||||
renderStateRight.setDiffuseCameraTransform( params.query->headMatrix );
|
renderStateRight.setDiffuseCameraTransform( params.query->headMatrix );
|
||||||
renderStateRight.disableAdvancedLightingBins(true);
|
//renderStateRight.disableAdvancedLightingBins(true);
|
||||||
|
|
||||||
gClientSceneGraph->renderSceneNoLights( &renderStateRight, objTypeFlag );
|
gClientSceneGraph->renderSceneNoLights( &renderStateRight, objTypeFlag );
|
||||||
|
|
||||||
// Restore previous values
|
// Restore previous values
|
||||||
GFX->setFrustum(gfxFrustum);
|
GFX->setFrustum(frustum);
|
||||||
GFX->setViewport(originalVP);
|
GFX->setViewport(originalVP);
|
||||||
gClientSceneGraph->setNonClipProjection(origNonClipProjection);
|
gClientSceneGraph->setNonClipProjection(origNonClipProjection);
|
||||||
PFXMGR->setFrameState(origPFXState);
|
PFXMGR->setFrameState(origPFXState);
|
||||||
|
GFX->setCurrentStereoTarget(-1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -690,6 +723,14 @@ void PlaneReflector::updateReflection( const ReflectParams ¶ms )
|
||||||
reflectTarget->resolve();
|
reflectTarget->resolve();
|
||||||
GFX->popActiveRenderTarget();
|
GFX->popActiveRenderTarget();
|
||||||
|
|
||||||
|
#ifdef DEBUG_REFLECT_TEX
|
||||||
|
static U32 reflectStage = 0;
|
||||||
|
char buf[128]; dSprintf(buf, 128, "F:\\REFLECT-OUT%i.PNG", reflectStage);
|
||||||
|
//reflectTex->dumpToDisk("PNG", buf);
|
||||||
|
reflectStage++;
|
||||||
|
if (reflectStage > 1) reflectStage = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Restore detail adjust amount.
|
// Restore detail adjust amount.
|
||||||
TSShapeInstance::smDetailAdjust = detailAdjustBackup;
|
TSShapeInstance::smDetailAdjust = detailAdjustBackup;
|
||||||
|
|
||||||
|
|
@ -803,7 +844,7 @@ MatrixF PlaneReflector::getFrustumClipProj( MatrixF &modelview )
|
||||||
// as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
|
// as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
|
||||||
// transform it into camera space by multiplying it
|
// transform it into camera space by multiplying it
|
||||||
// by the inverse of the projection matrix
|
// by the inverse of the projection matrix
|
||||||
Vector4F q;
|
Vector4F q;
|
||||||
q.x = sgn(clipPlane.x) / proj(0,0);
|
q.x = sgn(clipPlane.x) / proj(0,0);
|
||||||
q.y = sgn(clipPlane.y) / proj(1,1);
|
q.y = sgn(clipPlane.y) / proj(1,1);
|
||||||
q.z = -1.0F;
|
q.z = -1.0F;
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ struct ReflectParams
|
||||||
Point2I viewportExtent;
|
Point2I viewportExtent;
|
||||||
Frustum culler;
|
Frustum culler;
|
||||||
U32 startOfUpdateMs;
|
U32 startOfUpdateMs;
|
||||||
|
S8 eyeId;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -191,7 +192,7 @@ public:
|
||||||
{
|
{
|
||||||
refplane.set( Point3F(0,0,0), Point3F(0,0,1) );
|
refplane.set( Point3F(0,0,0), Point3F(0,0,1) );
|
||||||
objectSpace = false;
|
objectSpace = false;
|
||||||
mLastTexSize = 0;
|
mLastTexSize = Point2I(0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~PlaneReflector() {}
|
virtual ~PlaneReflector() {}
|
||||||
|
|
@ -213,7 +214,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
U32 mLastTexSize;
|
Point2I mLastTexSize;
|
||||||
|
|
||||||
// The camera position at the last update.
|
// The camera position at the last update.
|
||||||
Point3F mLastPos;
|
Point3F mLastPos;
|
||||||
|
|
@ -224,7 +225,9 @@ protected:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GFXTextureTargetRef reflectTarget;
|
GFXTextureTargetRef reflectTarget;
|
||||||
GFXTexHandle reflectTex;
|
|
||||||
|
GFXTexHandle innerReflectTex[2]; /// < Textures we actually render to
|
||||||
|
GFXTexHandle reflectTex; ///< Last texture we rendered to
|
||||||
GFXTexHandle depthBuff;
|
GFXTexHandle depthBuff;
|
||||||
PlaneF refplane;
|
PlaneF refplane;
|
||||||
bool objectSpace;
|
bool objectSpace;
|
||||||
|
|
|
||||||
|
|
@ -256,7 +256,7 @@ void SceneManager::renderScene( SceneRenderState* renderState, U32 objectMask, S
|
||||||
GFX->setWorldMatrix(worldEyeTransforms[0]);
|
GFX->setWorldMatrix(worldEyeTransforms[0]);
|
||||||
|
|
||||||
Frustum gfxFrustum = originalFrustum;
|
Frustum gfxFrustum = originalFrustum;
|
||||||
MathUtils::makeFovPortFrustum(&gfxFrustum, gfxFrustum.isOrtho(), gfxFrustum.getNearDist(), gfxFrustum.getFarDist(), currentFovPort[0], eyeTransforms[0]);
|
MathUtils::makeFovPortFrustum(&gfxFrustum, gfxFrustum.isOrtho(), gfxFrustum.getNearDist(), gfxFrustum.getFarDist(), currentFovPort[0]);
|
||||||
GFX->setFrustum(gfxFrustum);
|
GFX->setFrustum(gfxFrustum);
|
||||||
|
|
||||||
SceneCameraState cameraStateLeft = SceneCameraState::fromGFX();
|
SceneCameraState cameraStateLeft = SceneCameraState::fromGFX();
|
||||||
|
|
@ -277,7 +277,7 @@ void SceneManager::renderScene( SceneRenderState* renderState, U32 objectMask, S
|
||||||
GFX->setWorldMatrix(worldEyeTransforms[1]);
|
GFX->setWorldMatrix(worldEyeTransforms[1]);
|
||||||
|
|
||||||
gfxFrustum = originalFrustum;
|
gfxFrustum = originalFrustum;
|
||||||
MathUtils::makeFovPortFrustum(&gfxFrustum, gfxFrustum.isOrtho(), gfxFrustum.getNearDist(), gfxFrustum.getFarDist(), currentFovPort[1], eyeTransforms[1]);
|
MathUtils::makeFovPortFrustum(&gfxFrustum, gfxFrustum.isOrtho(), gfxFrustum.getNearDist(), gfxFrustum.getFarDist(), currentFovPort[1]);
|
||||||
GFX->setFrustum(gfxFrustum);
|
GFX->setFrustum(gfxFrustum);
|
||||||
|
|
||||||
SceneCameraState cameraStateRight = SceneCameraState::fromGFX();
|
SceneCameraState cameraStateRight = SceneCameraState::fromGFX();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue