Basic fix for reflections in both stereo rendering modes

This commit is contained in:
James Urquhart 2016-06-08 22:50:10 +01:00
parent fa7697b13e
commit 1198932e87
6 changed files with 150 additions and 155 deletions

View file

@ -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?

View file

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

View file

@ -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.

View file

@ -533,19 +533,28 @@ void PlaneReflector::updateReflection( const ReflectParams &params )
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 &params )
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 &params )
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 &params )
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 &params )
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 &params )
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;

View file

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

View file

@ -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();