Torque3D/Engine/source/scene/sceneRenderState.h
AzaezelX 022b87cac2 from user Ewyncat: adds invcameratrans, cameratoscrren, and screentocamera postfx and shader matrix interfaces.
also a bit of backend work to normalize those later once we've proof-of-concepted the calcs
2019-09-06 14:25:17 -05:00

335 lines
13 KiB
C++

//-----------------------------------------------------------------------------
// 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 _SCENERENDERSTATE_H_
#define _SCENERENDERSTATE_H_
#ifndef _COLOR_H_
#include "core/color.h"
#endif
#ifndef _SCENEMANAGER_H_
#include "scene/sceneManager.h"
#endif
#ifndef _SCENECULLINGSTATE_H_
#include "scene/culling/sceneCullingState.h"
#endif
#ifndef _UTIL_DELEGATE_H_
#include "core/util/delegate.h"
#endif
class SceneObject;
class RenderPassManager;
class BaseMatInstance;
/// The SceneRenderState describes the state of the scene being rendered.
///
/// It keeps track of the information that objects need to render properly with regard to
/// the camera position, any fog information, viewing frustum, the global environment
/// map for reflections, viewable distance, etc.
///
/// It also owns the current culling state.
class SceneRenderState
{
public:
/// The delegate used for material overrides.
/// @see getOverrideMaterial
typedef Delegate< BaseMatInstance*( BaseMatInstance* ) > MatDelegate;
protected:
/// SceneManager being rendered in this state.
SceneManager* mSceneManager;
/// The type of scene render pass we're doing.
ScenePassType mScenePassType;
/// The render style being performed
SceneRenderStyle mSceneRenderStyle;
/// The render pass which we are setting up with this scene state.
RenderPassManager* mRenderPass;
/// Culling state of the scene.
SceneCullingState mCullingState;
/// The optional material override delegate.
MatDelegate mMatDelegate;
///
MatrixF mDiffuseCameraTransform;
/// The world to screen space scalar used for LOD calculations.
Point2F mWorldToScreenScale;
/// The AABB that encloses the space in the scene that we render.
Box3F mRenderArea;
/// The camera vector normalized to 1 / far dist.
Point3F mVectorEye;
/// Global ambient light color.
LinearColorF mAmbientLightColor;
/// Forces bin based post effects to be disabled
/// during rendering with this scene state.
bool mUsePostEffects;
/// Disables AdvancedLighting bin draws during rendering with this scene state.
bool mDisableAdvancedLightingBins;
/// If true (default) lightmapped meshes should be rendered.
bool mRenderLightmappedMeshes;
/// If true (default) non-lightmapped meshes should be rendered.
bool mRenderNonLightmappedMeshes;
public:
/// Construct a new SceneRenderState.
///
/// @param sceneManager SceneManager rendered in this SceneRenderState.
/// @param passType Type of rendering pass that the SceneRenderState is for.
/// @param view The view that is being rendered
/// @param renderPass The render pass which is being set up by this SceneRenderState. If NULL,
/// then Scene::getDefaultRenderPass() is used.
/// @param usePostEffect Whether PostFX are enabled in the rendering pass.
SceneRenderState( SceneManager* sceneManager,
ScenePassType passType,
const SceneCameraState& view = SceneCameraState::fromGFX(),
RenderPassManager* renderPass = NULL,
bool usePostEffects = true );
~SceneRenderState();
/// Return the SceneManager that is being rendered in this SceneRenderState.
SceneManager* getSceneManager() const { return mSceneManager; }
/// If true then bin based post effects are disabled
/// during rendering with this scene state.
bool usePostEffects() const { return mUsePostEffects; }
void usePostEffects( bool value ) { mUsePostEffects = value; }
/// @name Culling
/// @{
/// Return the culling state for the scene.
const SceneCullingState& getCullingState() const { return mCullingState; }
SceneCullingState& getCullingState() { return mCullingState; }
/// Returns the root culling frustum.
const Frustum& getCullingFrustum() const { return getCullingState().getCullingFrustum(); }
/// Returns the root camera frustum.
const Frustum& getCameraFrustum() const { return getCullingState().getCameraFrustum(); }
/// @}
/// @name Rendering
/// @{
/// Get the AABB around the scene portion that we render.
const Box3F& getRenderArea() const { return mRenderArea; }
/// Set the AABB of the space that should be rendered.
void setRenderArea( const Box3F& area ) { mRenderArea = area; }
/// Batch the given objects to the render pass manager and then
/// render the batched instances.
///
/// @param objects List of objects.
/// @param numObjects Number of objects in @a objects.
void renderObjects( SceneObject** objects, U32 numObjects );
/// @}
/// @name Lighting
/// @{
/// Return the ambient light color to use for rendering the scene.
///
/// At the moment, we only support a single global ambient color with which
/// all objects in the scene are rendered. This is because when using
/// Advanced Lighting, we are not resolving light contribution on a per-surface
/// or per-object basis but rather do it globally by gathering light
/// contribution to the whole scene and since the ambient factor is decided
/// by the sun/vector light, it simply becomes a base light level onto which
/// shadowing/lighting is blended based on the shadow maps of the sun/vector
/// light.
///
/// @return The ambient light color for rendering.
LinearColorF getAmbientLightColor() const { return mAmbientLightColor; }
/// Set the global ambient light color to render with.
void setAmbientLightColor( const LinearColorF& color ) { mAmbientLightColor = color; }
/// If true then Advanced Lighting bin draws are disabled during rendering with
/// this scene state.
bool disableAdvancedLightingBins() const { return mDisableAdvancedLightingBins; }
void disableAdvancedLightingBins(bool enabled) { mDisableAdvancedLightingBins = enabled; }
bool renderLightmappedMeshes() const { return mRenderLightmappedMeshes; }
void renderLightmappedMeshes( bool enabled ) { mRenderLightmappedMeshes = enabled; }
bool renderNonLightmappedMeshes() const { return mRenderNonLightmappedMeshes; }
void renderNonLightmappedMeshes( bool enabled ) { mRenderNonLightmappedMeshes = enabled; }
/// @}
/// @name Passes
/// @{
/// Return the RenderPassManager that manages rendering objects batched
/// for this SceneRenderState.
RenderPassManager* getRenderPass() const { return mRenderPass; }
/// Returns the type of scene rendering pass that we're doing.
ScenePassType getScenePassType() const { return mScenePassType; }
/// Returns true if this is a diffuse scene rendering pass.
bool isDiffusePass() const { return mScenePassType == SPT_Diffuse; }
/// Returns true if this is a reflection scene rendering pass.
bool isReflectPass() const { return mScenePassType == SPT_Reflect; }
/// Returns true if this is a shadow scene rendering pass.
bool isShadowPass() const { return mScenePassType == SPT_Shadow; }
/// Returns true if this is not one of the other rendering passes.
bool isOtherPass() const { return mScenePassType >= SPT_Other; }
/// @}
/// @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; }
/// @}
/// @name Transforms, projections, and viewports.
/// @{
/// Return the screen-space viewport rectangle.
const RectI& getViewport() const { return getCullingState().getCameraState().getViewport(); }
/// Return the world->view transform matrix.
const MatrixF& getWorldViewMatrix() const;
/// Return the project transform matrix.
const MatrixF& getProjectionMatrix() const;
/// Return the inverse project transform matrix.
const MatrixF& getInvProjectionMatrix() const;
/// Returns the actual camera position.
/// @see getDiffuseCameraPosition
const Point3F& getCameraPosition() const { return getCullingState().getCameraState().getViewPosition(); }
/// Returns the camera transform (view->world) this SceneRenderState is using.
const MatrixF& getCameraTransform() const { return getCullingState().getCameraState().getViewWorldMatrix(); }
/// Returns the minimum distance something must be from the camera to not be culled.
F32 getNearPlane() const { return getCullingFrustum().getNearDist(); }
/// Returns the maximum distance something can be from the camera to not be culled.
F32 getFarPlane() const { return getCullingFrustum().getFarDist(); }
/// Returns the camera vector normalized to 1 / far distance.
const Point3F& getVectorEye() const { return mVectorEye; }
/// Returns the possibly overloaded world to screen scale.
/// @see projectRadius
const Point2F& getWorldToScreenScale() const { return mWorldToScreenScale; }
/// Set a new world to screen scale to overload
/// future screen metrics operations.
void setWorldToScreenScale( const Point2F& scale ) { mWorldToScreenScale = scale; }
/// Returns the pixel size of the radius projected to the screen at a desired distance.
///
/// Internally this uses the stored world to screen scale and viewport extents. This
/// allows the projection to be overloaded in special cases like when rendering shadows
/// or reflections.
///
/// @see getWorldToScreenScale
/// @see getViewportExtent
F32 projectRadius( F32 dist, F32 radius ) const
{
// We fixup any negative or zero distance
// so we don't get a divide by zero.
dist = dist > 0.0f ? dist : 0.001f;
return ( radius / dist ) * mWorldToScreenScale.y;
}
/// Returns the camera position used during the diffuse rendering pass which may be different
/// from the actual camera position.
///
/// This is useful when doing level of detail calculations that need to be relative to the
/// diffuse pass.
///
/// @see getCameraPosition
Point3F getDiffuseCameraPosition() const { return mDiffuseCameraTransform.getPosition(); }
const MatrixF& getDiffuseCameraTransform() const { return mDiffuseCameraTransform; }
/// Set a new diffuse camera transform.
/// @see getDiffuseCameraTransform
void setDiffuseCameraTransform( const MatrixF &mat ) { mDiffuseCameraTransform = mat; }
/// @}
/// @name Material Overrides
/// @{
/// When performing a special render pass like shadows this
/// returns a specialized override material. It can return
/// NULL if the override wants to disable rendering. If
/// there is no override in place then the input material is
/// returned unaltered.
BaseMatInstance* getOverrideMaterial( BaseMatInstance* matInst ) const
{
if ( !matInst || mMatDelegate.empty() )
return matInst;
return mMatDelegate( matInst );
}
/// Returns the optional material override delegate which is
/// used during some special render passes.
/// @see getOverrideMaterial
MatDelegate& getMaterialDelegate() { return mMatDelegate; }
const MatDelegate& getMaterialDelegate() const { return mMatDelegate; }
/// @}
};
#endif // _SCENERENDERSTATE_H_