mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-15 16:44:36 +00:00
Merge pull request #324 from DavidWyand-GG/SideBySideRendering
Side by side rendering
This commit is contained in:
commit
2805ec81c8
28 changed files with 465 additions and 41 deletions
|
|
@ -219,6 +219,7 @@ GameConnection::GameConnection()
|
||||||
// first person
|
// first person
|
||||||
mFirstPerson = true;
|
mFirstPerson = true;
|
||||||
mUpdateFirstPerson = false;
|
mUpdateFirstPerson = false;
|
||||||
|
clearDisplayDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
GameConnection::~GameConnection()
|
GameConnection::~GameConnection()
|
||||||
|
|
@ -1729,6 +1730,13 @@ DefineEngineMethod( GameConnection, setControlObject, bool, (GameBase* ctrlObj),
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefineEngineMethod( GameConnection, clearDisplayDevice, void, (),,
|
||||||
|
"@brief Clear any display device.\n\n"
|
||||||
|
"A display device may define a number of properties that are used during rendering.\n\n")
|
||||||
|
{
|
||||||
|
object->clearDisplayDevice();
|
||||||
|
}
|
||||||
|
|
||||||
DefineEngineMethod( GameConnection, getControlObject, GameBase*, (),,
|
DefineEngineMethod( GameConnection, getControlObject, GameBase*, (),,
|
||||||
"@brief On the server, returns the object that the client is controlling."
|
"@brief On the server, returns the object that the client is controlling."
|
||||||
"By default the control object is an instance of the Player class, but can also be an instance "
|
"By default the control object is an instance of the Player class, but can also be an instance "
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ enum GameConnectionConstants
|
||||||
DataBlockQueueCount = 16
|
DataBlockQueueCount = 16
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class IDisplayDevice;
|
||||||
class SFXProfile;
|
class SFXProfile;
|
||||||
class MatrixF;
|
class MatrixF;
|
||||||
class MatrixF;
|
class MatrixF;
|
||||||
|
|
@ -86,6 +87,8 @@ private:
|
||||||
F32 mCameraFov; ///< Current camera fov (in degrees).
|
F32 mCameraFov; ///< Current camera fov (in degrees).
|
||||||
F32 mCameraPos; ///< Current camera pos (0-1).
|
F32 mCameraPos; ///< Current camera pos (0-1).
|
||||||
F32 mCameraSpeed; ///< Camera in/out speed.
|
F32 mCameraSpeed; ///< Camera in/out speed.
|
||||||
|
|
||||||
|
IDisplayDevice* mDisplayDevice; ///< Optional client display device that imposes rendering properties.
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -263,6 +266,10 @@ public:
|
||||||
|
|
||||||
void setFirstPerson(bool firstPerson);
|
void setFirstPerson(bool firstPerson);
|
||||||
|
|
||||||
|
bool hasDisplayDevice() const { return mDisplayDevice != NULL; }
|
||||||
|
const IDisplayDevice* getDisplayDevice() const { return mDisplayDevice; }
|
||||||
|
void setDisplayDevice(IDisplayDevice* display) { mDisplayDevice = display; }
|
||||||
|
void clearDisplayDevice() { mDisplayDevice = NULL; }
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
void detectLag();
|
void detectLag();
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
#include "math/mEase.h"
|
#include "math/mEase.h"
|
||||||
#include "core/module.h"
|
#include "core/module.h"
|
||||||
#include "console/engineAPI.h"
|
#include "console/engineAPI.h"
|
||||||
|
#include "platform/output/IDisplayDevice.h"
|
||||||
|
|
||||||
static void RegisterGameFunctions();
|
static void RegisterGameFunctions();
|
||||||
static void Process3D();
|
static void Process3D();
|
||||||
|
|
@ -82,6 +82,8 @@ static S32 gEaseBack = Ease::Back;
|
||||||
static S32 gEaseBounce = Ease::Bounce;
|
static S32 gEaseBounce = Ease::Bounce;
|
||||||
|
|
||||||
|
|
||||||
|
extern bool gEditingMission;
|
||||||
|
|
||||||
extern void ShowInit();
|
extern void ShowInit();
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
@ -354,9 +356,44 @@ bool GameProcessCameraQuery(CameraQuery *query)
|
||||||
sVisDistanceScale = mClampF( sVisDistanceScale, 0.01f, 1.0f );
|
sVisDistanceScale = mClampF( sVisDistanceScale, 0.01f, 1.0f );
|
||||||
query->farPlane = gClientSceneGraph->getVisibleDistance() * sVisDistanceScale;
|
query->farPlane = gClientSceneGraph->getVisibleDistance() * sVisDistanceScale;
|
||||||
|
|
||||||
F32 cameraFov;
|
// Provide some default values
|
||||||
if(!connection->getControlCameraFov(&cameraFov))
|
query->projectionOffset = Point2F::Zero;
|
||||||
|
query->eyeOffset = Point3F::Zero;
|
||||||
|
|
||||||
|
F32 cameraFov = 0.0f;
|
||||||
|
bool fovSet = false;
|
||||||
|
|
||||||
|
// Try to use the connection's display deivce, if any, but only if the editor
|
||||||
|
// is not open
|
||||||
|
if(!gEditingMission && connection->hasDisplayDevice())
|
||||||
|
{
|
||||||
|
const IDisplayDevice* display = connection->getDisplayDevice();
|
||||||
|
|
||||||
|
// The connection's display device may want to set the FOV
|
||||||
|
if(display->providesYFOV())
|
||||||
|
{
|
||||||
|
cameraFov = mRadToDeg(display->getYFOV());
|
||||||
|
fovSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The connection's display device may want to set the projection offset
|
||||||
|
if(display->providesProjectionOffset())
|
||||||
|
{
|
||||||
|
query->projectionOffset = display->getProjectionOffset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// The connection's display device may want to set the eye offset
|
||||||
|
if(display->providesEyeOffset())
|
||||||
|
{
|
||||||
|
query->eyeOffset = display->getEyeOffset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the connection's FOV settings if requried
|
||||||
|
if(!fovSet && !connection->getControlCameraFov(&cameraFov))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
query->fov = mDegToRad(cameraFov);
|
query->fov = mDegToRad(cameraFov);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -278,7 +278,11 @@ bool LightFlareData::_testVisibility(const SceneRenderState *state, LightFlareSt
|
||||||
// the last result.
|
// the last result.
|
||||||
const Point3F &lightPos = flareState->lightMat.getPosition();
|
const Point3F &lightPos = flareState->lightMat.getPosition();
|
||||||
const RectI &viewport = GFX->getViewport();
|
const RectI &viewport = GFX->getViewport();
|
||||||
bool onScreen = MathUtils::mProjectWorldToScreen( lightPos, outLightPosSS, viewport, GFX->getWorldMatrix(), state->getSceneManager()->getNonClipProjection() );
|
MatrixF projMatrix;
|
||||||
|
state->getFrustum().getProjectionMatrix(&projMatrix);
|
||||||
|
if( state->isReflectPass() )
|
||||||
|
projMatrix = state->getSceneManager()->getNonClipProjection();
|
||||||
|
bool onScreen = MathUtils::mProjectWorldToScreen( lightPos, outLightPosSS, viewport, GFX->getWorldMatrix(), projMatrix );
|
||||||
|
|
||||||
// It is onscreen, so raycast as a simple occlusion test.
|
// It is onscreen, so raycast as a simple occlusion test.
|
||||||
const LightInfo *lightInfo = flareState->lightInfo;
|
const LightInfo *lightInfo = flareState->lightInfo;
|
||||||
|
|
@ -452,13 +456,17 @@ void LightFlareData::prepRender( SceneRenderState *state, LightFlareState *flare
|
||||||
Point3F oneOverViewportExtent( 1.0f / (F32)viewport.extent.x, 1.0f / (F32)viewport.extent.y, 0.0f );
|
Point3F oneOverViewportExtent( 1.0f / (F32)viewport.extent.x, 1.0f / (F32)viewport.extent.y, 0.0f );
|
||||||
|
|
||||||
// Really convert it to screen space.
|
// Really convert it to screen space.
|
||||||
|
lightPosSS.x -= viewport.point.x;
|
||||||
lightPosSS.y -= viewport.point.y;
|
lightPosSS.y -= viewport.point.y;
|
||||||
lightPosSS *= oneOverViewportExtent;
|
lightPosSS *= oneOverViewportExtent;
|
||||||
lightPosSS = ( lightPosSS * 2.0f ) - Point3F::One;
|
lightPosSS = ( lightPosSS * 2.0f ) - Point3F::One;
|
||||||
lightPosSS.y = -lightPosSS.y;
|
lightPosSS.y = -lightPosSS.y;
|
||||||
lightPosSS.z = 0.0f;
|
lightPosSS.z = 0.0f;
|
||||||
|
|
||||||
Point3F flareVec( -lightPosSS );
|
// Take any projection offset into account so that the point where the flare's
|
||||||
|
// elements converge is at the 'eye' point rather than the center of the viewport.
|
||||||
|
const Point2F& projOffset = state->getFrustum().getProjectionOffset();
|
||||||
|
Point3F flareVec( -lightPosSS + Point3F(projOffset.x, projOffset.y, 0.0f) );
|
||||||
const F32 flareLength = flareVec.len();
|
const F32 flareLength = flareVec.len();
|
||||||
if ( flareLength > 0.0f )
|
if ( flareLength > 0.0f )
|
||||||
flareVec *= 1.0f / flareLength;
|
flareVec *= 1.0f / flareLength;
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,9 @@ GFXDevice::GFXDevice()
|
||||||
|
|
||||||
// misc
|
// misc
|
||||||
mAllowRender = true;
|
mAllowRender = true;
|
||||||
|
mCurrentRenderStyle = RS_Standard;
|
||||||
|
mCurrentProjectionOffset = Point2F::Zero;
|
||||||
|
mStereoEyeOffset = Point3F::Zero;
|
||||||
mCanCurrentlyRender = false;
|
mCanCurrentlyRender = false;
|
||||||
mInitialized = false;
|
mInitialized = false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -231,6 +231,13 @@ private:
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
// Core GFX interface
|
// Core GFX interface
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
public:
|
||||||
|
enum GFXDeviceRenderStyles
|
||||||
|
{
|
||||||
|
RS_Standard = 0,
|
||||||
|
RS_StereoSideBySide = (1<<0),
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// Adapter for this device.
|
/// Adapter for this device.
|
||||||
|
|
@ -254,6 +261,15 @@ protected:
|
||||||
/// Set if we're in a mode where we want rendering to occur.
|
/// Set if we're in a mode where we want rendering to occur.
|
||||||
bool mAllowRender;
|
bool mAllowRender;
|
||||||
|
|
||||||
|
/// The style of rendering that is to be performed, based on GFXDeviceRenderStyles
|
||||||
|
U32 mCurrentRenderStyle;
|
||||||
|
|
||||||
|
/// The current projection offset. May be used during side-by-side rendering, for example.
|
||||||
|
Point2F mCurrentProjectionOffset;
|
||||||
|
|
||||||
|
/// Eye offset used when using a stereo rendering style
|
||||||
|
Point3F mStereoEyeOffset;
|
||||||
|
|
||||||
/// This will allow querying to see if a device is initialized and ready to
|
/// This will allow querying to see if a device is initialized and ready to
|
||||||
/// have operations performed on it.
|
/// have operations performed on it.
|
||||||
bool mInitialized;
|
bool mInitialized;
|
||||||
|
|
@ -285,6 +301,24 @@ public:
|
||||||
|
|
||||||
inline bool allowRender() const { return mAllowRender; }
|
inline bool allowRender() const { return mAllowRender; }
|
||||||
|
|
||||||
|
/// Retrieve the current rendering style based on GFXDeviceRenderStyles
|
||||||
|
U32 getCurrentRenderStyle() const { return mCurrentRenderStyle; }
|
||||||
|
|
||||||
|
/// Set the current rendering style, based on GFXDeviceRenderStyles
|
||||||
|
void setCurrentRenderStyle(U32 style) { mCurrentRenderStyle = style; }
|
||||||
|
|
||||||
|
/// Set the current projection offset used during stereo rendering
|
||||||
|
const Point2F& getCurrentProjectionOffset() { return mCurrentProjectionOffset; }
|
||||||
|
|
||||||
|
/// Get the current projection offset used during stereo rendering
|
||||||
|
void setCurrentProjectionOffset(const Point2F& offset) { mCurrentProjectionOffset = offset; }
|
||||||
|
|
||||||
|
/// Get the current eye offset used during stereo rendering
|
||||||
|
const Point3F& getStereoEyeOffset() { return mStereoEyeOffset; }
|
||||||
|
|
||||||
|
/// Set the current eye offset used during stereo rendering
|
||||||
|
void setStereoEyeOffset(const Point3F& offset) { mStereoEyeOffset = offset; }
|
||||||
|
|
||||||
GFXCardProfiler* getCardProfiler() const { return mCardProfiler; }
|
GFXCardProfiler* getCardProfiler() const { return mCardProfiler; }
|
||||||
|
|
||||||
/// Returns active graphics adapter type.
|
/// Returns active graphics adapter type.
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,13 @@ ConsoleDocClass( GuiTSCtrl,
|
||||||
U32 GuiTSCtrl::smFrameCount = 0;
|
U32 GuiTSCtrl::smFrameCount = 0;
|
||||||
Vector<GuiTSCtrl*> GuiTSCtrl::smAwakeTSCtrls;
|
Vector<GuiTSCtrl*> GuiTSCtrl::smAwakeTSCtrls;
|
||||||
|
|
||||||
|
ImplementEnumType( GuiTSRenderStyles,
|
||||||
|
"Style of rendering for a GuiTSCtrl.\n\n"
|
||||||
|
"@ingroup Gui3D" )
|
||||||
|
{ GuiTSCtrl::RenderStyleStandard, "standard" },
|
||||||
|
{ GuiTSCtrl::RenderStyleStereoSideBySide, "stereo side by side" },
|
||||||
|
EndImplementEnumType;
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -131,6 +138,8 @@ GuiTSCtrl::GuiTSCtrl()
|
||||||
mForceFOV = 0;
|
mForceFOV = 0;
|
||||||
mReflectPriority = 1.0f;
|
mReflectPriority = 1.0f;
|
||||||
|
|
||||||
|
mRenderStyle = RenderStyleStandard;
|
||||||
|
|
||||||
mSaveModelview.identity();
|
mSaveModelview.identity();
|
||||||
mSaveProjection.identity();
|
mSaveProjection.identity();
|
||||||
mSaveViewport.set( 0, 0, 10, 10 );
|
mSaveViewport.set( 0, 0, 10, 10 );
|
||||||
|
|
@ -142,6 +151,9 @@ GuiTSCtrl::GuiTSCtrl()
|
||||||
mLastCameraQuery.farPlane = 10.0f;
|
mLastCameraQuery.farPlane = 10.0f;
|
||||||
mLastCameraQuery.nearPlane = 0.01f;
|
mLastCameraQuery.nearPlane = 0.01f;
|
||||||
|
|
||||||
|
mLastCameraQuery.projectionOffset = Point2F::Zero;
|
||||||
|
mLastCameraQuery.eyeOffset = Point3F::Zero;
|
||||||
|
|
||||||
mLastCameraQuery.ortho = false;
|
mLastCameraQuery.ortho = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -165,6 +177,9 @@ void GuiTSCtrl::initPersistFields()
|
||||||
"The reflect update priorities of all visible GuiTSCtrls are added together and each control is assigned "
|
"The reflect update priorities of all visible GuiTSCtrls are added together and each control is assigned "
|
||||||
"a share of the per-frame reflection update time according to its percentage of the total priority value." );
|
"a share of the per-frame reflection update time according to its percentage of the total priority value." );
|
||||||
|
|
||||||
|
addField("renderStyle", TYPEID< RenderStyles >(), Offset(mRenderStyle, GuiTSCtrl),
|
||||||
|
"Indicates how this control should render its contents." );
|
||||||
|
|
||||||
endGroup( "Rendering" );
|
endGroup( "Rendering" );
|
||||||
|
|
||||||
Parent::initPersistFields();
|
Parent::initPersistFields();
|
||||||
|
|
@ -256,7 +271,9 @@ F32 GuiTSCtrl::calculateViewDistance(F32 radius)
|
||||||
F32 fov = mLastCameraQuery.fov;
|
F32 fov = mLastCameraQuery.fov;
|
||||||
F32 wwidth;
|
F32 wwidth;
|
||||||
F32 wheight;
|
F32 wheight;
|
||||||
F32 aspectRatio = F32(getWidth()) / F32(getHeight());
|
F32 renderWidth = (mRenderStyle == RenderStyleStereoSideBySide) ? F32(getWidth())*0.5f : F32(getWidth());
|
||||||
|
F32 renderHeight = F32(getHeight());
|
||||||
|
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.
|
||||||
|
|
@ -321,10 +338,27 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||||
mLastCameraQuery.cameraMatrix.mul(rotMat);
|
mLastCameraQuery.cameraMatrix.mul(rotMat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up the appropriate render style
|
||||||
|
U32 prevRenderStyle = GFX->getCurrentRenderStyle();
|
||||||
|
Point2F prevProjectionOffset = GFX->getCurrentProjectionOffset();
|
||||||
|
Point3F prevEyeOffset = GFX->getStereoEyeOffset();
|
||||||
|
if(mRenderStyle == RenderStyleStereoSideBySide)
|
||||||
|
{
|
||||||
|
GFX->setCurrentRenderStyle(GFXDevice::RS_StereoSideBySide);
|
||||||
|
GFX->setCurrentProjectionOffset(mLastCameraQuery.projectionOffset);
|
||||||
|
GFX->setStereoEyeOffset(mLastCameraQuery.eyeOffset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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 aspectRatio = F32(getWidth()) / F32(getHeight());
|
F32 renderWidth = (mRenderStyle == RenderStyleStereoSideBySide) ? F32(getWidth())*0.5f : F32(getWidth());
|
||||||
|
F32 renderHeight = F32(getHeight());
|
||||||
|
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.
|
||||||
|
|
@ -339,16 +373,28 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||||
wwidth = aspectRatio * wheight;
|
wwidth = aspectRatio * wheight;
|
||||||
}
|
}
|
||||||
|
|
||||||
F32 hscale = wwidth * 2.0f / F32(getWidth());
|
F32 hscale = wwidth * 2.0f / renderWidth;
|
||||||
F32 vscale = wheight * 2.0f / F32(getHeight());
|
F32 vscale = wheight * 2.0f / renderHeight;
|
||||||
|
|
||||||
F32 left = (updateRect.point.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 bottom = wheight - vscale * (updateRect.point.y + updateRect.extent.y - offset.y);
|
|
||||||
|
|
||||||
Frustum frustum;
|
Frustum frustum;
|
||||||
frustum.set( mLastCameraQuery.ortho, left, right, top, bottom, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane );
|
if(mRenderStyle == RenderStyleStereoSideBySide)
|
||||||
|
{
|
||||||
|
F32 left = 0.0f * hscale - wwidth;
|
||||||
|
F32 right = renderWidth * hscale - wwidth;
|
||||||
|
F32 top = wheight - vscale * 0.0f;
|
||||||
|
F32 bottom = wheight - vscale * renderHeight;
|
||||||
|
|
||||||
|
frustum.set( mLastCameraQuery.ortho, left, right, top, bottom, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
F32 left = (updateRect.point.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 bottom = wheight - vscale * (updateRect.point.y + updateRect.extent.y - offset.y);
|
||||||
|
|
||||||
|
frustum.set( mLastCameraQuery.ortho, left, right, top, bottom, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane );
|
||||||
|
}
|
||||||
|
|
||||||
// Manipulate the frustum for tiled screenshots
|
// Manipulate the frustum for tiled screenshots
|
||||||
const bool screenShotMode = gScreenShot && gScreenShot->isPending();
|
const bool screenShotMode = gScreenShot && gScreenShot->isPending();
|
||||||
|
|
@ -412,6 +458,11 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||||
// we begin rendering the child controls.
|
// we begin rendering the child controls.
|
||||||
saver.restore();
|
saver.restore();
|
||||||
|
|
||||||
|
// Restore the render style and any stereo parameters
|
||||||
|
GFX->setCurrentRenderStyle(prevRenderStyle);
|
||||||
|
GFX->setCurrentProjectionOffset(prevProjectionOffset);
|
||||||
|
GFX->setStereoEyeOffset(prevEyeOffset);
|
||||||
|
|
||||||
// Allow subclasses to render 2D elements.
|
// Allow subclasses to render 2D elements.
|
||||||
GFX->setClipRect(updateRect);
|
GFX->setClipRect(updateRect);
|
||||||
renderGui( offset, updateRect );
|
renderGui( offset, updateRect );
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@ struct CameraQuery
|
||||||
F32 nearPlane;
|
F32 nearPlane;
|
||||||
F32 farPlane;
|
F32 farPlane;
|
||||||
F32 fov;
|
F32 fov;
|
||||||
|
Point2F projectionOffset;
|
||||||
|
Point3F eyeOffset;
|
||||||
bool ortho;
|
bool ortho;
|
||||||
MatrixF cameraMatrix;
|
MatrixF cameraMatrix;
|
||||||
};
|
};
|
||||||
|
|
@ -45,12 +47,17 @@ class GuiTSCtrl : public GuiContainer
|
||||||
{
|
{
|
||||||
typedef GuiContainer Parent;
|
typedef GuiContainer Parent;
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum RenderStyles {
|
||||||
|
RenderStyleStandard = 0,
|
||||||
|
RenderStyleStereoSideBySide = (1<<0),
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
static U32 smFrameCount;
|
static U32 smFrameCount;
|
||||||
F32 mCameraZRot;
|
F32 mCameraZRot;
|
||||||
F32 mForceFOV;
|
F32 mForceFOV;
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/// A list of GuiTSCtrl which are awake and
|
/// A list of GuiTSCtrl which are awake and
|
||||||
/// most likely rendering.
|
/// most likely rendering.
|
||||||
static Vector<GuiTSCtrl*> smAwakeTSCtrls;
|
static Vector<GuiTSCtrl*> smAwakeTSCtrls;
|
||||||
|
|
@ -59,8 +66,11 @@ protected:
|
||||||
/// update timeslice for this viewport to get.
|
/// update timeslice for this viewport to get.
|
||||||
F32 mReflectPriority;
|
F32 mReflectPriority;
|
||||||
|
|
||||||
F32 mOrthoWidth;
|
/// The current render type
|
||||||
F32 mOrthoHeight;
|
U32 mRenderStyle;
|
||||||
|
|
||||||
|
F32 mOrthoWidth;
|
||||||
|
F32 mOrthoHeight;
|
||||||
|
|
||||||
MatrixF mSaveModelview;
|
MatrixF mSaveModelview;
|
||||||
MatrixF mSaveProjection;
|
MatrixF mSaveProjection;
|
||||||
|
|
@ -150,4 +160,8 @@ public:
|
||||||
DECLARE_DESCRIPTION( "Abstract base class for controls that render a 3D viewport." );
|
DECLARE_DESCRIPTION( "Abstract base class for controls that render a 3D viewport." );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef GuiTSCtrl::RenderStyles GuiTSRenderStyles;
|
||||||
|
|
||||||
|
DefineEnumType( GuiTSRenderStyles );
|
||||||
|
|
||||||
#endif // _GUITSCONTROL_H_
|
#endif // _GUITSCONTROL_H_
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,6 @@
|
||||||
#include "math/util/matrixSet.h"
|
#include "math/util/matrixSet.h"
|
||||||
#include "console/consoleTypes.h"
|
#include "console/consoleTypes.h"
|
||||||
|
|
||||||
|
|
||||||
const RenderInstType AdvancedLightBinManager::RIT_LightInfo( "LightInfo" );
|
const RenderInstType AdvancedLightBinManager::RIT_LightInfo( "LightInfo" );
|
||||||
const String AdvancedLightBinManager::smBufferName( "lightinfo" );
|
const String AdvancedLightBinManager::smBufferName( "lightinfo" );
|
||||||
|
|
||||||
|
|
@ -49,7 +48,6 @@ ShadowFilterMode AdvancedLightBinManager::smShadowFilterMode = ShadowFilterMode_
|
||||||
bool AdvancedLightBinManager::smPSSMDebugRender = false;
|
bool AdvancedLightBinManager::smPSSMDebugRender = false;
|
||||||
bool AdvancedLightBinManager::smUseSSAOMask = false;
|
bool AdvancedLightBinManager::smUseSSAOMask = false;
|
||||||
|
|
||||||
|
|
||||||
ImplementEnumType( ShadowFilterMode,
|
ImplementEnumType( ShadowFilterMode,
|
||||||
"The shadow filtering modes for Advanced Lighting shadows.\n"
|
"The shadow filtering modes for Advanced Lighting shadows.\n"
|
||||||
"@ingroup AdvancedLighting" )
|
"@ingroup AdvancedLighting" )
|
||||||
|
|
@ -221,7 +219,7 @@ void AdvancedLightBinManager::addLight( LightInfo *light )
|
||||||
curBin.push_back( lEntry );
|
curBin.push_back( lEntry );
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvancedLightBinManager::clear()
|
void AdvancedLightBinManager::clearAllLights()
|
||||||
{
|
{
|
||||||
Con::setIntVariable("lightMetrics::activeLights", mLightBin.size());
|
Con::setIntVariable("lightMetrics::activeLights", mLightBin.size());
|
||||||
Con::setIntVariable("lightMetrics::culledLights", mNumLightsCulled);
|
Con::setIntVariable("lightMetrics::culledLights", mNumLightsCulled);
|
||||||
|
|
@ -454,6 +452,33 @@ void AdvancedLightBinManager::_setupPerFrameParameters( const SceneRenderState *
|
||||||
const Point3F *wsFrustumPoints = frustum.getPoints();
|
const Point3F *wsFrustumPoints = frustum.getPoints();
|
||||||
const Point3F& cameraPos = frustum.getPosition();
|
const Point3F& cameraPos = frustum.getPosition();
|
||||||
|
|
||||||
|
// Perform a camera offset. We need to manually perform this offset on the sun (or vector) light's
|
||||||
|
// polygon, which is at the far plane.
|
||||||
|
const Point2F& projOffset = frustum.getProjectionOffset();
|
||||||
|
Point3F cameraOffsetPos = cameraPos;
|
||||||
|
if(!projOffset.isZero())
|
||||||
|
{
|
||||||
|
// First we need to calculate the offset at the near plane. The projOffset
|
||||||
|
// given above can be thought of a percent as it ranges from 0..1 (or 0..-1).
|
||||||
|
F32 nearOffset = frustum.getNearRight() * projOffset.x;
|
||||||
|
|
||||||
|
// Now given the near plane distance from the camera we can solve the right
|
||||||
|
// triangle and calcuate the SIN theta for the offset at the near plane.
|
||||||
|
// SIN theta = x/y
|
||||||
|
F32 sinTheta = nearOffset / frustum.getNearDist();
|
||||||
|
|
||||||
|
// Finally, we can calcuate the offset at the far plane, which is where our sun (or vector)
|
||||||
|
// light's polygon is drawn.
|
||||||
|
F32 farOffset = frustum.getFarDist() * sinTheta;
|
||||||
|
|
||||||
|
// We can now apply this far plane offset to the far plane itself, which then compensates
|
||||||
|
// for the project offset.
|
||||||
|
MatrixF camTrans = frustum.getTransform();
|
||||||
|
VectorF offset = camTrans.getRightVector();
|
||||||
|
offset *= farOffset;
|
||||||
|
cameraOffsetPos += offset;
|
||||||
|
}
|
||||||
|
|
||||||
// Now build the quad for drawing full-screen vector light
|
// Now build the quad for drawing full-screen vector light
|
||||||
// passes.... this is a volatile VB and updates every frame.
|
// passes.... this is a volatile VB and updates every frame.
|
||||||
FarFrustumQuadVert verts[4];
|
FarFrustumQuadVert verts[4];
|
||||||
|
|
@ -461,18 +486,22 @@ void AdvancedLightBinManager::_setupPerFrameParameters( const SceneRenderState *
|
||||||
verts[0].point.set( wsFrustumPoints[Frustum::FarBottomLeft] - cameraPos );
|
verts[0].point.set( wsFrustumPoints[Frustum::FarBottomLeft] - cameraPos );
|
||||||
invCam.mulP( wsFrustumPoints[Frustum::FarBottomLeft], &verts[0].normal );
|
invCam.mulP( wsFrustumPoints[Frustum::FarBottomLeft], &verts[0].normal );
|
||||||
verts[0].texCoord.set( -1.0, -1.0 );
|
verts[0].texCoord.set( -1.0, -1.0 );
|
||||||
|
verts[0].tangent.set(wsFrustumPoints[Frustum::FarBottomLeft] - cameraOffsetPos);
|
||||||
|
|
||||||
verts[1].point.set( wsFrustumPoints[Frustum::FarTopLeft] - cameraPos );
|
verts[1].point.set( wsFrustumPoints[Frustum::FarTopLeft] - cameraPos );
|
||||||
invCam.mulP( wsFrustumPoints[Frustum::FarTopLeft], &verts[1].normal );
|
invCam.mulP( wsFrustumPoints[Frustum::FarTopLeft], &verts[1].normal );
|
||||||
verts[1].texCoord.set( -1.0, 1.0 );
|
verts[1].texCoord.set( -1.0, 1.0 );
|
||||||
|
verts[1].tangent.set(wsFrustumPoints[Frustum::FarTopLeft] - cameraOffsetPos);
|
||||||
|
|
||||||
verts[2].point.set( wsFrustumPoints[Frustum::FarTopRight] - cameraPos );
|
verts[2].point.set( wsFrustumPoints[Frustum::FarTopRight] - cameraPos );
|
||||||
invCam.mulP( wsFrustumPoints[Frustum::FarTopRight], &verts[2].normal );
|
invCam.mulP( wsFrustumPoints[Frustum::FarTopRight], &verts[2].normal );
|
||||||
verts[2].texCoord.set( 1.0, 1.0 );
|
verts[2].texCoord.set( 1.0, 1.0 );
|
||||||
|
verts[2].tangent.set(wsFrustumPoints[Frustum::FarTopRight] - cameraOffsetPos);
|
||||||
|
|
||||||
verts[3].point.set( wsFrustumPoints[Frustum::FarBottomRight] - cameraPos );
|
verts[3].point.set( wsFrustumPoints[Frustum::FarBottomRight] - cameraPos );
|
||||||
invCam.mulP( wsFrustumPoints[Frustum::FarBottomRight], &verts[3].normal );
|
invCam.mulP( wsFrustumPoints[Frustum::FarBottomRight], &verts[3].normal );
|
||||||
verts[3].texCoord.set( 1.0, -1.0 );
|
verts[3].texCoord.set( 1.0, -1.0 );
|
||||||
|
verts[3].tangent.set(wsFrustumPoints[Frustum::FarBottomRight] - cameraOffsetPos);
|
||||||
}
|
}
|
||||||
mFarFrustumQuadVerts.set( GFX, 4 );
|
mFarFrustumQuadVerts.set( GFX, 4 );
|
||||||
dMemcpy( mFarFrustumQuadVerts.lock(), verts, sizeof( verts ) );
|
dMemcpy( mFarFrustumQuadVerts.lock(), verts, sizeof( verts ) );
|
||||||
|
|
|
||||||
|
|
@ -107,12 +107,15 @@ public:
|
||||||
|
|
||||||
// RenderBinManager
|
// RenderBinManager
|
||||||
virtual void render(SceneRenderState *);
|
virtual void render(SceneRenderState *);
|
||||||
virtual void clear();
|
virtual void clear() {}
|
||||||
virtual void sort() {}
|
virtual void sort() {}
|
||||||
|
|
||||||
// Add a light to the bins
|
// Add a light to the bins
|
||||||
void addLight( LightInfo *light );
|
void addLight( LightInfo *light );
|
||||||
|
|
||||||
|
// Clear all lights from the bins
|
||||||
|
void clearAllLights();
|
||||||
|
|
||||||
virtual bool setTargetSize(const Point2I &newTargetSize);
|
virtual bool setTargetSize(const Point2I &newTargetSize);
|
||||||
|
|
||||||
// ConsoleObject interface
|
// ConsoleObject interface
|
||||||
|
|
@ -220,7 +223,7 @@ protected:
|
||||||
|
|
||||||
AdvancedLightBufferConditioner *mConditioner;
|
AdvancedLightBufferConditioner *mConditioner;
|
||||||
|
|
||||||
typedef GFXVertexPNT FarFrustumQuadVert;
|
typedef GFXVertexPNTT FarFrustumQuadVert;
|
||||||
GFXVertexBufferHandle<FarFrustumQuadVert> mFarFrustumQuadVerts;
|
GFXVertexBufferHandle<FarFrustumQuadVert> mFarFrustumQuadVerts;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -438,7 +438,7 @@ void AdvancedLightManager::unregisterAllLights()
|
||||||
Parent::unregisterAllLights();
|
Parent::unregisterAllLights();
|
||||||
|
|
||||||
if ( mLightBinManager )
|
if ( mLightBinManager )
|
||||||
mLightBinManager->clear();
|
mLightBinManager->clearAllLights();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdvancedLightManager::setTextureStage( const SceneData &sgData,
|
bool AdvancedLightManager::setTextureStage( const SceneData &sgData,
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,9 @@ Frustum::Frustum( bool isOrtho,
|
||||||
mNumTiles = 1;
|
mNumTiles = 1;
|
||||||
mCurrTile.set(0,0);
|
mCurrTile.set(0,0);
|
||||||
mTileOverlap.set(0.0f, 0.0f);
|
mTileOverlap.set(0.0f, 0.0f);
|
||||||
|
|
||||||
|
mProjectionOffset.zero();
|
||||||
|
mProjectionOffsetMatrix.identity();
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -433,12 +436,27 @@ void Frustum::mulL( const MatrixF& mat )
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void Frustum::setProjectionOffset(const Point2F& offsetMat)
|
||||||
|
{
|
||||||
|
mProjectionOffset = offsetMat;
|
||||||
|
mProjectionOffsetMatrix.identity();
|
||||||
|
mProjectionOffsetMatrix.setPosition(Point3F(mProjectionOffset.x, mProjectionOffset.y, 0.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void Frustum::getProjectionMatrix( MatrixF *proj, bool gfxRotate ) const
|
void Frustum::getProjectionMatrix( MatrixF *proj, bool gfxRotate ) const
|
||||||
{
|
{
|
||||||
if (mIsOrtho)
|
if (mIsOrtho)
|
||||||
|
{
|
||||||
MathUtils::makeOrthoProjection(proj, mNearLeft, mNearRight, mNearTop, mNearBottom, mNearDist, mFarDist, gfxRotate);
|
MathUtils::makeOrthoProjection(proj, mNearLeft, mNearRight, mNearTop, mNearBottom, mNearDist, mFarDist, gfxRotate);
|
||||||
|
proj->mulL(mProjectionOffsetMatrix);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
MathUtils::makeProjection(proj, mNearLeft, mNearRight, mNearTop, mNearBottom, mNearDist, mFarDist, gfxRotate);
|
MathUtils::makeProjection(proj, mNearLeft, mNearRight, mNearTop, mNearBottom, mNearDist, mFarDist, gfxRotate);
|
||||||
|
proj->mulL(mProjectionOffsetMatrix);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -246,6 +246,12 @@ class Frustum : public PolyhedronImpl< FrustumData >
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
/// Offset used for projection matrix calculations
|
||||||
|
Point2F mProjectionOffset;
|
||||||
|
|
||||||
|
/// The calculated projection offset matrix
|
||||||
|
MatrixF mProjectionOffsetMatrix;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// @name Constructors
|
/// @name Constructors
|
||||||
|
|
@ -403,9 +409,23 @@ class Frustum : public PolyhedronImpl< FrustumData >
|
||||||
/// points typically used for early rejection.
|
/// points typically used for early rejection.
|
||||||
const Box3F& getBounds() const { _update(); return mBounds; }
|
const Box3F& getBounds() const { _update(); return mBounds; }
|
||||||
|
|
||||||
|
/// Get the offset used when calculating the projection matrix
|
||||||
|
const Point2F& getProjectionOffset() const { return mProjectionOffset; }
|
||||||
|
|
||||||
|
/// Get the offset matrix used when calculating the projection matrix
|
||||||
|
const MatrixF& getProjectionOffsetMatrix() const { return mProjectionOffsetMatrix; }
|
||||||
|
|
||||||
|
/// Set the offset used when calculating the projection matrix
|
||||||
|
void setProjectionOffset(const Point2F& offsetMat);
|
||||||
|
|
||||||
|
/// Clear any offset used when calculating the projection matrix
|
||||||
|
void clearProjectionOffset() { mProjectionOffset.zero(); mProjectionOffsetMatrix.identity(); }
|
||||||
|
|
||||||
/// Generates a projection matrix from the frustum.
|
/// Generates a projection matrix from the frustum.
|
||||||
void getProjectionMatrix( MatrixF *proj, bool gfxRotate=true ) const;
|
void getProjectionMatrix( MatrixF *proj, bool gfxRotate=true ) const;
|
||||||
|
|
||||||
|
/// Will update the frustum if it is dirty
|
||||||
|
void update() { _update(); }
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// @name Culling
|
/// @name Culling
|
||||||
|
|
|
||||||
44
Engine/source/platform/output/IDisplayDevice.h
Normal file
44
Engine/source/platform/output/IDisplayDevice.h
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2012 GarageGames, LLC
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to
|
||||||
|
// deal in the Software without restriction, including without limitation the
|
||||||
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
// sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
// IN THE SOFTWARE.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef _IDISPLAYDEVICE_H_
|
||||||
|
#define _IDISPLAYDEVICE_H_
|
||||||
|
|
||||||
|
#include "console/consoleTypes.h"
|
||||||
|
|
||||||
|
// Defines a custom display device that requires particular rendering settings
|
||||||
|
// in order for a scene to display correctly.
|
||||||
|
|
||||||
|
class IDisplayDevice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool providesYFOV() const = 0;
|
||||||
|
virtual F32 getYFOV() const = 0;
|
||||||
|
|
||||||
|
virtual bool providesEyeOffset() const = 0;
|
||||||
|
virtual const Point3F& getEyeOffset() const = 0;
|
||||||
|
|
||||||
|
virtual bool providesProjectionOffset() const = 0;
|
||||||
|
virtual const Point2F& getProjectionOffset() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _IDISPLAYDEVICE_H_
|
||||||
|
|
@ -435,26 +435,53 @@ void PostEffect::_updateScreenGeometry( const Frustum &frustum,
|
||||||
const Point3F *frustumPoints = frustum.getPoints();
|
const Point3F *frustumPoints = frustum.getPoints();
|
||||||
const Point3F& cameraPos = frustum.getPosition();
|
const Point3F& cameraPos = frustum.getPosition();
|
||||||
|
|
||||||
|
// Perform a camera offset. We need to manually perform this offset on the postFx's
|
||||||
|
// polygon, which is at the far plane.
|
||||||
|
const Point2F& projOffset = frustum.getProjectionOffset();
|
||||||
|
Point3F cameraOffsetPos = cameraPos;
|
||||||
|
if(!projOffset.isZero())
|
||||||
|
{
|
||||||
|
// First we need to calculate the offset at the near plane. The projOffset
|
||||||
|
// given above can be thought of a percent as it ranges from 0..1 (or 0..-1).
|
||||||
|
F32 nearOffset = frustum.getNearRight() * projOffset.x;
|
||||||
|
|
||||||
|
// Now given the near plane distance from the camera we can solve the right
|
||||||
|
// triangle and calcuate the SIN theta for the offset at the near plane.
|
||||||
|
// SIN theta = x/y
|
||||||
|
F32 sinTheta = nearOffset / frustum.getNearDist();
|
||||||
|
|
||||||
|
// Finally, we can calcuate the offset at the far plane, which is where our sun (or vector)
|
||||||
|
// light's polygon is drawn.
|
||||||
|
F32 farOffset = frustum.getFarDist() * sinTheta;
|
||||||
|
|
||||||
|
// We can now apply this far plane offset to the far plane itself, which then compensates
|
||||||
|
// for the project offset.
|
||||||
|
MatrixF camTrans = frustum.getTransform();
|
||||||
|
VectorF offset = camTrans.getRightVector();
|
||||||
|
offset *= farOffset;
|
||||||
|
cameraOffsetPos += offset;
|
||||||
|
}
|
||||||
|
|
||||||
PFXVertex *vert = outVB->lock();
|
PFXVertex *vert = outVB->lock();
|
||||||
|
|
||||||
vert->point.set( -1.0, -1.0, 0.0 );
|
vert->point.set( -1.0, -1.0, 0.0 );
|
||||||
vert->texCoord.set( 0.0f, 1.0f );
|
vert->texCoord.set( 0.0f, 1.0f );
|
||||||
vert->wsEyeRay = frustumPoints[Frustum::FarBottomLeft] - cameraPos;
|
vert->wsEyeRay = frustumPoints[Frustum::FarBottomLeft] - cameraOffsetPos;
|
||||||
vert++;
|
vert++;
|
||||||
|
|
||||||
vert->point.set( -1.0, 1.0, 0.0 );
|
vert->point.set( -1.0, 1.0, 0.0 );
|
||||||
vert->texCoord.set( 0.0f, 0.0f );
|
vert->texCoord.set( 0.0f, 0.0f );
|
||||||
vert->wsEyeRay = frustumPoints[Frustum::FarTopLeft] - cameraPos;
|
vert->wsEyeRay = frustumPoints[Frustum::FarTopLeft] - cameraOffsetPos;
|
||||||
vert++;
|
vert++;
|
||||||
|
|
||||||
vert->point.set( 1.0, 1.0, 0.0 );
|
vert->point.set( 1.0, 1.0, 0.0 );
|
||||||
vert->texCoord.set( 1.0f, 0.0f );
|
vert->texCoord.set( 1.0f, 0.0f );
|
||||||
vert->wsEyeRay = frustumPoints[Frustum::FarTopRight] - cameraPos;
|
vert->wsEyeRay = frustumPoints[Frustum::FarTopRight] - cameraOffsetPos;
|
||||||
vert++;
|
vert++;
|
||||||
|
|
||||||
vert->point.set( 1.0, -1.0, 0.0 );
|
vert->point.set( 1.0, -1.0, 0.0 );
|
||||||
vert->texCoord.set( 1.0f, 1.0f );
|
vert->texCoord.set( 1.0f, 1.0f );
|
||||||
vert->wsEyeRay = frustumPoints[Frustum::FarBottomRight] - cameraPos;
|
vert->wsEyeRay = frustumPoints[Frustum::FarBottomRight] - cameraOffsetPos;
|
||||||
vert++;
|
vert++;
|
||||||
|
|
||||||
outVB->unlock();
|
outVB->unlock();
|
||||||
|
|
@ -710,6 +737,8 @@ void PostEffect::_setupConstants( const SceneRenderState *state )
|
||||||
MathUtils::mProjectWorldToScreen( lightPos, &sunPos, GFX->getViewport(), tmp, proj );
|
MathUtils::mProjectWorldToScreen( lightPos, &sunPos, GFX->getViewport(), tmp, proj );
|
||||||
|
|
||||||
// And normalize it to the 0 to 1 range.
|
// And normalize it to the 0 to 1 range.
|
||||||
|
sunPos.x -= (F32)GFX->getViewport().point.x;
|
||||||
|
sunPos.y -= (F32)GFX->getViewport().point.y;
|
||||||
sunPos.x /= (F32)GFX->getViewport().extent.x;
|
sunPos.x /= (F32)GFX->getViewport().extent.x;
|
||||||
sunPos.y /= (F32)GFX->getViewport().extent.y;
|
sunPos.y /= (F32)GFX->getViewport().extent.y;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -233,7 +233,70 @@ void SceneManager::renderScene( SceneRenderState* renderState, U32 objectMask, S
|
||||||
|
|
||||||
// Render the scene.
|
// Render the scene.
|
||||||
|
|
||||||
renderSceneNoLights( renderState, objectMask, baseObject, baseZone );
|
if(GFX->getCurrentRenderStyle() == GFXDevice::RS_StereoSideBySide)
|
||||||
|
{
|
||||||
|
// Store previous values
|
||||||
|
RectI originalVP = GFX->getViewport();
|
||||||
|
MatrixF originalWorld = GFX->getWorldMatrix();
|
||||||
|
|
||||||
|
Point2F projOffset = GFX->getCurrentProjectionOffset();
|
||||||
|
Point3F eyeOffset = GFX->getStereoEyeOffset();
|
||||||
|
|
||||||
|
// Render left half of display
|
||||||
|
RectI leftVP = originalVP;
|
||||||
|
leftVP.extent.x *= 0.5;
|
||||||
|
GFX->setViewport(leftVP);
|
||||||
|
|
||||||
|
MatrixF leftWorldTrans(true);
|
||||||
|
leftWorldTrans.setPosition(Point3F(eyeOffset.x, eyeOffset.y, eyeOffset.z));
|
||||||
|
MatrixF leftWorld(originalWorld);
|
||||||
|
leftWorld.mulL(leftWorldTrans);
|
||||||
|
GFX->setWorldMatrix(leftWorld);
|
||||||
|
|
||||||
|
Frustum gfxFrustum = GFX->getFrustum();
|
||||||
|
gfxFrustum.setProjectionOffset(Point2F(projOffset.x, projOffset.y));
|
||||||
|
GFX->setFrustum(gfxFrustum);
|
||||||
|
|
||||||
|
SceneCameraState cameraStateLeft = SceneCameraState::fromGFX();
|
||||||
|
SceneRenderState renderStateLeft( this, renderState->getScenePassType(), cameraStateLeft );
|
||||||
|
renderStateLeft.setSceneRenderStyle(SRS_SideBySide);
|
||||||
|
renderStateLeft.setSceneRenderField(0);
|
||||||
|
|
||||||
|
renderSceneNoLights( &renderStateLeft, objectMask, baseObject, baseZone );
|
||||||
|
|
||||||
|
// Render right half of display
|
||||||
|
RectI rightVP = originalVP;
|
||||||
|
rightVP.extent.x *= 0.5;
|
||||||
|
rightVP.point.x += rightVP.extent.x;
|
||||||
|
GFX->setViewport(rightVP);
|
||||||
|
|
||||||
|
MatrixF rightWorldTrans(true);
|
||||||
|
rightWorldTrans.setPosition(Point3F(-eyeOffset.x, eyeOffset.y, eyeOffset.z));
|
||||||
|
MatrixF rightWorld(originalWorld);
|
||||||
|
rightWorld.mulL(rightWorldTrans);
|
||||||
|
GFX->setWorldMatrix(rightWorld);
|
||||||
|
|
||||||
|
gfxFrustum = GFX->getFrustum();
|
||||||
|
gfxFrustum.setProjectionOffset(Point2F(-projOffset.x, projOffset.y));
|
||||||
|
GFX->setFrustum(gfxFrustum);
|
||||||
|
|
||||||
|
SceneCameraState cameraStateRight = SceneCameraState::fromGFX();
|
||||||
|
SceneRenderState renderStateRight( this, renderState->getScenePassType(), cameraStateRight );
|
||||||
|
renderStateRight.setSceneRenderStyle(SRS_SideBySide);
|
||||||
|
renderStateRight.setSceneRenderField(1);
|
||||||
|
|
||||||
|
renderSceneNoLights( &renderStateRight, objectMask, baseObject, baseZone );
|
||||||
|
|
||||||
|
// Restore previous values
|
||||||
|
GFX->setWorldMatrix(originalWorld);
|
||||||
|
gfxFrustum.clearProjectionOffset();
|
||||||
|
GFX->setFrustum(gfxFrustum);
|
||||||
|
GFX->setViewport(originalVP);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
renderSceneNoLights( renderState, objectMask, baseObject, baseZone );
|
||||||
|
}
|
||||||
|
|
||||||
// Trigger the post-render signal.
|
// Trigger the post-render signal.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,18 @@ enum ScenePassType
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// The type of scene render style
|
||||||
|
/// @see SceneRenderState
|
||||||
|
enum SceneRenderStyle
|
||||||
|
{
|
||||||
|
/// The regular style of rendering
|
||||||
|
SRS_Standard,
|
||||||
|
|
||||||
|
/// Side-by-side style rendering
|
||||||
|
SRS_SideBySide,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/// An object that manages the SceneObjects belonging to a scene.
|
/// An object that manages the SceneObjects belonging to a scene.
|
||||||
class SceneManager
|
class SceneManager
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,9 @@ SceneRenderState::SceneRenderState( SceneManager* sceneManager,
|
||||||
mUsePostEffects( usePostEffects ),
|
mUsePostEffects( usePostEffects ),
|
||||||
mDisableAdvancedLightingBins( false ),
|
mDisableAdvancedLightingBins( false ),
|
||||||
mRenderArea( view.getFrustum().getBounds() ),
|
mRenderArea( view.getFrustum().getBounds() ),
|
||||||
mAmbientLightColor( sceneManager->getAmbientLightColor() )
|
mAmbientLightColor( sceneManager->getAmbientLightColor() ),
|
||||||
|
mSceneRenderStyle( SRS_Standard ),
|
||||||
|
mRenderField( 0 )
|
||||||
{
|
{
|
||||||
// Setup the default parameters for the screen metrics methods.
|
// Setup the default parameters for the screen metrics methods.
|
||||||
mDiffuseCameraTransform = view.getViewWorldMatrix();
|
mDiffuseCameraTransform = view.getViewWorldMatrix();
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,12 @@ class SceneRenderState
|
||||||
/// The type of scene render pass we're doing.
|
/// The type of scene render pass we're doing.
|
||||||
ScenePassType mScenePassType;
|
ScenePassType mScenePassType;
|
||||||
|
|
||||||
|
/// The render style being performed
|
||||||
|
SceneRenderStyle mSceneRenderStyle;
|
||||||
|
|
||||||
|
/// When doing stereo rendering, the current field that is being rendered
|
||||||
|
S32 mRenderField;
|
||||||
|
|
||||||
/// The render pass which we are setting up with this scene state.
|
/// The render pass which we are setting up with this scene state.
|
||||||
RenderPassManager* mRenderPass;
|
RenderPassManager* mRenderPass;
|
||||||
|
|
||||||
|
|
@ -219,6 +225,23 @@ class SceneRenderState
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
/// @name Render Style
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/// Get the rendering style used for the scene
|
||||||
|
SceneRenderStyle getSceneRenderStyle() const { return mSceneRenderStyle; }
|
||||||
|
|
||||||
|
/// Set the rendering style used for the scene
|
||||||
|
void setSceneRenderStyle(SceneRenderStyle style) { mSceneRenderStyle = style; }
|
||||||
|
|
||||||
|
/// Get the stereo field being rendered
|
||||||
|
S32 getSceneRenderField() const { return mRenderField; }
|
||||||
|
|
||||||
|
/// Set the stereo field being rendered
|
||||||
|
void setSceneRenderField(S32 field) { mRenderField = field; }
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
/// @name Transforms, projections, and viewports.
|
/// @name Transforms, projections, and viewports.
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,9 @@ singleton PostEffect( LightRayPostFX )
|
||||||
isEnabled = false;
|
isEnabled = false;
|
||||||
allowReflectPass = false;
|
allowReflectPass = false;
|
||||||
|
|
||||||
renderTime = "PFXAfterDiffuse";
|
renderTime = "PFXBeforeBin";
|
||||||
renderPriority = 0.1;
|
renderBin = "EditorBin";
|
||||||
|
renderPriority = 10;
|
||||||
|
|
||||||
shader = LightRayOccludeShader;
|
shader = LightRayOccludeShader;
|
||||||
stateBlock = LightRayStateBlock;
|
stateBlock = LightRayStateBlock;
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,14 @@ struct VertexIn_PNT
|
||||||
float2 uv0 : TEXCOORD0;
|
float2 uv0 : TEXCOORD0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VertexIn_PNTT
|
||||||
|
{
|
||||||
|
float4 pos : POSITION;
|
||||||
|
float3 normal : NORMAL;
|
||||||
|
float3 tangent : TANGENT;
|
||||||
|
float2 uv0 : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
struct VertexIn_PNCT
|
struct VertexIn_PNCT
|
||||||
{
|
{
|
||||||
float4 pos : POSITION;
|
float4 pos : POSITION;
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
#include "farFrustumQuad.hlsl"
|
#include "farFrustumQuad.hlsl"
|
||||||
|
|
||||||
|
|
||||||
FarFrustumQuadConnectV main( VertexIn_PNT IN,
|
FarFrustumQuadConnectV main( VertexIn_PNTT IN,
|
||||||
uniform float4 rtParams0 )
|
uniform float4 rtParams0 )
|
||||||
{
|
{
|
||||||
FarFrustumQuadConnectV OUT;
|
FarFrustumQuadConnectV OUT;
|
||||||
|
|
@ -36,7 +36,7 @@ FarFrustumQuadConnectV main( VertexIn_PNT IN,
|
||||||
|
|
||||||
// Interpolators will generate eye rays the
|
// Interpolators will generate eye rays the
|
||||||
// from far-frustum corners.
|
// from far-frustum corners.
|
||||||
OUT.wsEyeRay = IN.pos.xyz;
|
OUT.wsEyeRay = IN.tangent.xyz;
|
||||||
OUT.vsEyeRay = IN.normal.xyz;
|
OUT.vsEyeRay = IN.normal.xyz;
|
||||||
|
|
||||||
return OUT;
|
return OUT;
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ float4 main( FarFrustumQuadConnectP IN,
|
||||||
|
|
||||||
// Use eye ray to get ws pos
|
// Use eye ray to get ws pos
|
||||||
float4 worldPos = float4(eyePosWorld + IN.wsEyeRay * depth, 1.0f);
|
float4 worldPos = float4(eyePosWorld + IN.wsEyeRay * depth, 1.0f);
|
||||||
|
|
||||||
// Get the light attenuation.
|
// Get the light attenuation.
|
||||||
float dotNL = dot(-lightDirection, normal);
|
float dotNL = dot(-lightDirection, normal);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,9 @@ singleton PostEffect( LightRayPostFX )
|
||||||
isEnabled = false;
|
isEnabled = false;
|
||||||
allowReflectPass = false;
|
allowReflectPass = false;
|
||||||
|
|
||||||
renderTime = "PFXAfterDiffuse";
|
renderTime = "PFXBeforeBin";
|
||||||
renderPriority = 0.1;
|
renderBin = "EditorBin";
|
||||||
|
renderPriority = 10;
|
||||||
|
|
||||||
shader = LightRayOccludeShader;
|
shader = LightRayOccludeShader;
|
||||||
stateBlock = LightRayStateBlock;
|
stateBlock = LightRayStateBlock;
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,14 @@ struct VertexIn_PNT
|
||||||
float2 uv0 : TEXCOORD0;
|
float2 uv0 : TEXCOORD0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VertexIn_PNTT
|
||||||
|
{
|
||||||
|
float4 pos : POSITION;
|
||||||
|
float3 normal : NORMAL;
|
||||||
|
float3 tangent : TANGENT;
|
||||||
|
float2 uv0 : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
struct VertexIn_PNCT
|
struct VertexIn_PNCT
|
||||||
{
|
{
|
||||||
float4 pos : POSITION;
|
float4 pos : POSITION;
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
#include "farFrustumQuad.hlsl"
|
#include "farFrustumQuad.hlsl"
|
||||||
|
|
||||||
|
|
||||||
FarFrustumQuadConnectV main( VertexIn_PNT IN,
|
FarFrustumQuadConnectV main( VertexIn_PNTT IN,
|
||||||
uniform float4 rtParams0 )
|
uniform float4 rtParams0 )
|
||||||
{
|
{
|
||||||
FarFrustumQuadConnectV OUT;
|
FarFrustumQuadConnectV OUT;
|
||||||
|
|
@ -36,7 +36,7 @@ FarFrustumQuadConnectV main( VertexIn_PNT IN,
|
||||||
|
|
||||||
// Interpolators will generate eye rays the
|
// Interpolators will generate eye rays the
|
||||||
// from far-frustum corners.
|
// from far-frustum corners.
|
||||||
OUT.wsEyeRay = IN.pos.xyz;
|
OUT.wsEyeRay = IN.tangent.xyz;
|
||||||
OUT.vsEyeRay = IN.normal.xyz;
|
OUT.vsEyeRay = IN.normal.xyz;
|
||||||
|
|
||||||
return OUT;
|
return OUT;
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ float4 main( FarFrustumQuadConnectP IN,
|
||||||
|
|
||||||
// Use eye ray to get ws pos
|
// Use eye ray to get ws pos
|
||||||
float4 worldPos = float4(eyePosWorld + IN.wsEyeRay * depth, 1.0f);
|
float4 worldPos = float4(eyePosWorld + IN.wsEyeRay * depth, 1.0f);
|
||||||
|
|
||||||
// Get the light attenuation.
|
// Get the light attenuation.
|
||||||
float dotNL = dot(-lightDirection, normal);
|
float dotNL = dot(-lightDirection, normal);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ switch( Generator::$platform )
|
||||||
addEngineSrcDir('platform/threads');
|
addEngineSrcDir('platform/threads');
|
||||||
addEngineSrcDir('platform/async');
|
addEngineSrcDir('platform/async');
|
||||||
addEngineSrcDir('platform/input');
|
addEngineSrcDir('platform/input');
|
||||||
|
addEngineSrcDir('platform/output');
|
||||||
addEngineSrcDir('app');
|
addEngineSrcDir('app');
|
||||||
addEngineSrcDir('app/net');
|
addEngineSrcDir('app/net');
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue