You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Gems/RenderToTexture/Code/Source/RenderToTextureComponent.cpp

264 lines
10 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "RenderToTexture_precompiled.h"
#if AZ_RENDER_TO_TEXTURE_GEM_ENABLED
#include "RenderToTextureComponent.h"
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Component/TransformBus.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/Math/Transform.h>
#include <MathConversion.h>
#include <IRenderer.h>
#include <I3DEngine.h>
#include <IViewSystem.h>
#include <AzFramework/Components/CameraBus.h>
#include <RTTBus.h>
namespace AzRTT
{
void RenderContextConfig::Reflect(AZ::ReflectContext* reflection)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection);
if (serializeContext)
{
serializeContext->Class<RenderContextConfig>()
->Version(1)
->Field("Width", &RenderContextConfig::m_width)
->Field("Height", &RenderContextConfig::m_height)
->Field("Enable Gamma", &RenderContextConfig::m_sRGBWrite)
->Field("Alpha Output Mode", &RenderContextConfig::m_alphaMode)
->Field("Enable Ocean", &RenderContextConfig::m_oceanEnabled)
->Field("Enable Terrain", &RenderContextConfig::m_terrainEnabled)
->Field("Enable Vegetation", &RenderContextConfig::m_vegetationEnabled)
->Field("Enable Shadows", &RenderContextConfig::m_shadowsEnabled)
->Field("GSM LODs", &RenderContextConfig::m_shadowsNumCascades)
->Field("GSM Range", &RenderContextConfig::m_shadowsGSMRange)
->Field("GSM Range Step", &RenderContextConfig::m_shadowsGSMRangeStep)
->Field("Antialiasing Mode", &RenderContextConfig::m_aaMode)
->Field("Enable Depth Of Field", &RenderContextConfig::m_depthOfFieldEnabled)
->Field("Enable Motion Blur", &RenderContextConfig::m_motionBlurEnabled)
;
}
}
}
namespace RenderToTexture
{
/// BahaviorContext forwarder for RenderToTextureNotificationBus
class BehaviorRenderToTextureNotificationBusHandler : public RenderToTexture::RenderToTextureNotificationBus::Handler, public AZ::BehaviorEBusHandler
{
public:
AZ_EBUS_BEHAVIOR_BINDER(BehaviorRenderToTextureNotificationBusHandler, "{8E5D1D55-317B-42FA-A8A4-AC410B671C87}", AZ::SystemAllocator,
OnPreRenderToTexture, OnPostRenderToTexture);
void OnPreRenderToTexture() override
{
Call(FN_OnPreRenderToTexture);
}
void OnPostRenderToTexture() override
{
Call(FN_OnPostRenderToTexture);
}
};
void RenderToTextureConfig::Reflect(AZ::ReflectContext* reflection)
{
AzRTT::RenderContextConfig::Reflect(reflection);
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection);
if (serializeContext)
{
serializeContext->Class<RenderToTextureConfig>()
->Version(1)
->Field("Enabled", &RenderToTextureConfig::m_enabled)
->Field("Camera", &RenderToTextureConfig::m_camera)
->Field("Texture Name", &RenderToTextureConfig::m_textureName)
->Field("Max FPS", &RenderToTextureConfig::m_maxFPS)
->Field("Render Context Config", &RenderToTextureConfig::m_renderContextConfig)
->Field("Display Debug Image", &RenderToTextureConfig::m_displayDebugImage);
}
}
void RenderToTextureComponent::Reflect(AZ::ReflectContext* reflection)
{
RenderToTextureBase::Reflect(reflection);
RenderToTextureConfig::Reflect(reflection);
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection);
if (serializeContext)
{
serializeContext->Class<RenderToTextureComponent, AZ::Component, RenderToTextureBase>()
->Version(1)
->Field("Config", &RenderToTextureComponent::m_config);
}
AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflection);
if (behaviorContext)
{
behaviorContext->EBus<RenderToTextureRequestBus>("RenderToTextureRequestBus")
->Attribute(AZ::Script::Attributes::Category, "Rendering")
->Event("GetTextureResourceId", &RenderToTextureRequestBus::Events::GetTextureResourceId)
->Event("SetCamera", &RenderToTextureRequestBus::Events::SetCamera, { { { "Camera" , "The entity ID of the camera to use for rendering" } } })
->Event("SetEnabled", &RenderToTextureRequestBus::Events::SetEnabled, { { { "Enabled" , "Enable or disable rendering to texture" } } })
->Event("SetMaxFPS", &RenderToTextureRequestBus::Events::SetMaxFPS, { { { "FPS" , "Limit how often the scene is re-rendered and the render target is updated" } } })
->Event("SetWriteGamma", &RenderToTextureRequestBus::Events::SetWriteSRGBEnabled, { { { "Enabled" , "Enable or disable gamma application in the render target output." } } })
->Event("SetAlphaMode", &RenderToTextureRequestBus::Events::SetAlphaMode, { { { "Mode" , "Set the alpha mode (0 = disabled, 1 = opaque, 2 = depth based)" } } });
behaviorContext->EBus<RenderToTextureNotificationBus>("RenderToTextureNotificationBus")
->Attribute(AZ::Script::Attributes::Category, "Rendering")
->Handler<BehaviorRenderToTextureNotificationBusHandler>();
}
}
void RenderToTextureComponent::Activate()
{
if (gEnv->IsDedicated())
{
AZ_WarningOnce("RenderToTextureComponent", gEnv->IsDedicated(), "$2RenderToTexture is not supported in dedicated server mode.");
return;
}
if (!m_config.m_camera.IsValid())
{
m_config.m_camera = GetEntityId();
}
AzRTT::RTTRequestBus::BroadcastResult(m_config.m_renderContextId, &AzRTT::RTTRequestBus::Events::CreateContext, m_config.m_renderContextConfig);
if (m_config.m_renderContextId.IsNull())
{
AZ_Printf("RenderToTextureComponent", "$2Failed to create render context.");
}
else if (gEnv->pRenderer)
{
m_renderTargetHandle = gEnv->pRenderer->CreateRenderTarget(m_config.m_textureName.c_str(), m_config.m_renderContextConfig.m_width, m_config.m_renderContextConfig.m_height, Clr_Unknown, eTF_R8G8B8A8);
if (m_renderTargetHandle <= 0)
{
AZ_Printf("RenderToTextureComponent", "$2Failed to create render target.");
}
else if (m_config.m_enabled)
{
AZ::TickBus::Handler::BusConnect();
#ifndef _RELEASE
// validate cvar settings
ValidateCVars();
#endif // ifndef _RELEASE
}
}
RenderToTextureRequestBus::Handler::BusConnect(GetEntityId());
}
void RenderToTextureComponent::Deactivate()
{
if (!m_config.m_renderContextId.IsNull())
{
AzRTT::RTTRequestBus::Broadcast(&AzRTT::RTTRequestBus::Events::DestroyContext, m_config.m_renderContextId);
}
if (m_renderTargetHandle >= 0)
{
if (gEnv->pRenderer)
{
gEnv->pRenderer->DestroyRenderTarget(m_renderTargetHandle);
}
m_renderTargetHandle = -1;
}
RenderToTextureRequestBus::Handler::BusDisconnect();
AZ::TickBus::Handler::BusDisconnect();
}
int RenderToTextureComponent::GetTickOrder()
{
return AZ::TICK_LAST;
}
void RenderToTextureComponent::OnTick(float deltaTime, AZ::ScriptTimePoint time)
{
// push the changes from the component's RenderContextConfig to our RenderContext
// do this here before we render so we avoid threading issues.
if (m_configDirty && !m_config.m_renderContextId.IsNull())
{
AzRTT::RTTRequestBus::Broadcast(&AzRTT::RTTRequestBus::Events::SetContextConfig, m_config.m_renderContextId, m_config.m_renderContextConfig);
m_configDirty = false;
}
Render(m_renderTargetHandle, m_config, GetEntityId());
}
bool RenderToTextureComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig)
{
if (auto config = azrtti_cast<const RenderToTextureConfig*>(baseConfig))
{
m_config = *config;
return true;
}
return false;
}
bool RenderToTextureComponent::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const
{
if (auto outConfig = azrtti_cast<RenderToTextureConfig*>(outBaseConfig))
{
*outConfig = m_config;
return true;
}
return false;
}
int RenderToTextureComponent::GetTextureResourceId() const
{
return m_renderTargetHandle;
}
void RenderToTextureComponent::SetEnabled(bool enabled)
{
if (enabled != m_config.m_enabled)
{
m_config.m_enabled = enabled;
}
}
void RenderToTextureComponent::SetWriteSRGBEnabled(bool enabled)
{
m_config.m_renderContextConfig.m_sRGBWrite = enabled;
m_configDirty = true;
}
void RenderToTextureComponent::SetAlphaMode(AzRTT::AlphaMode mode)
{
m_config.m_renderContextConfig.m_alphaMode = mode;
m_configDirty = true;
}
void RenderToTextureComponent::SetCamera(const AZ::EntityId& id)
{
m_config.m_camera = id;
m_configDirty = true;
}
void RenderToTextureComponent::SetMaxFPS(double fps)
{
m_config.m_maxFPS = fps;
m_configDirty = true;
}
}
#endif // if AZ_RENDER_TO_TEXTURE_GEM_ENABLED