Merge remote-tracking branch 'origin/master' into dotnet7
This commit is contained in:
BIN
Content/Editor/Camera/M_Camera.flax
(Stored with Git LFS)
BIN
Content/Editor/Camera/M_Camera.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/CubeTexturePreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/CubeTexturePreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/DDGIDebugProbes.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/DDGIDebugProbes.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Decal.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Decal.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Particle.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Particle.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Surface.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Surface.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Terrain.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Terrain.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DefaultFontMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/DefaultFontMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/FoliageBrushMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/FoliageBrushMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/MaterialWire.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/MaterialWire.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/SelectionOutlineMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/SelectionOutlineMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Highlight Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Highlight Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Icons/IconsMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Icons/IconsMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/IesProfilePreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/IesProfilePreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
@@ -33,9 +33,12 @@ DECLARE_LIGHTSHADOWDATA_ACCESS(DirectionalLightShadow);
|
||||
|
||||
// Pixel Shader function for Forward Pass
|
||||
META_PS(USE_FORWARD, FEATURE_LEVEL_ES2)
|
||||
float4 PS_Forward(PixelInput input) : SV_Target0
|
||||
void PS_Forward(
|
||||
in PixelInput input
|
||||
,out float4 output : SV_Target0
|
||||
)
|
||||
{
|
||||
float4 output = 0;
|
||||
output = 0;
|
||||
|
||||
#if USE_DITHERED_LOD_TRANSITION
|
||||
// LOD masking
|
||||
@@ -148,6 +151,4 @@ float4 PS_Forward(PixelInput input) : SV_Target0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
#define MATERIAL 1
|
||||
#define USE_PER_VIEW_CONSTANTS 1
|
||||
@3
|
||||
// Ribbons don't use sorted indices so overlap the segment distances buffer on the slot
|
||||
#define HAS_SORTED_INDICES (!defined(_VS_Ribbon))
|
||||
|
||||
#include "./Flax/Common.hlsl"
|
||||
#include "./Flax/MaterialCommon.hlsl"
|
||||
@@ -18,6 +16,14 @@ struct SpriteInput
|
||||
float2 TexCoord : TEXCOORD;
|
||||
};
|
||||
|
||||
struct RibbonInput
|
||||
{
|
||||
uint Order : TEXCOORD0;
|
||||
uint ParticleIndex : TEXCOORD1;
|
||||
uint PrevParticleIndex : TEXCOORD2;
|
||||
float Distance : TEXCOORD3;
|
||||
};
|
||||
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x4 WorldMatrix;
|
||||
@@ -45,13 +51,8 @@ float4x4 WorldMatrixInverseTransposed;
|
||||
// Particles attributes buffer
|
||||
ByteAddressBuffer ParticlesData : register(t0);
|
||||
|
||||
#if HAS_SORTED_INDICES
|
||||
// Sorted particles indices
|
||||
Buffer<uint> SortedIndices : register(t1);
|
||||
#else
|
||||
// Ribbon particles segments distances buffer
|
||||
Buffer<float> SegmentDistances : register(t1);
|
||||
#endif
|
||||
|
||||
// Shader resources
|
||||
@2
|
||||
@@ -320,13 +321,11 @@ VertexOutput VS_Sprite(SpriteInput input, uint particleIndex : SV_InstanceID)
|
||||
{
|
||||
VertexOutput output;
|
||||
|
||||
#if HAS_SORTED_INDICES
|
||||
// Sorted particles mapping
|
||||
if (SortedIndicesOffset != 0xFFFFFFFF)
|
||||
{
|
||||
particleIndex = SortedIndices[SortedIndicesOffset + particleIndex];
|
||||
}
|
||||
#endif
|
||||
|
||||
// Read particle data
|
||||
float3 particlePosition = GetParticleVec3(particleIndex, PositionOffset);
|
||||
@@ -457,13 +456,11 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
|
||||
{
|
||||
VertexOutput output;
|
||||
|
||||
#if HAS_SORTED_INDICES
|
||||
// Sorted particles mapping
|
||||
if (SortedIndicesOffset != 0xFFFFFFFF)
|
||||
{
|
||||
particleIndex = SortedIndices[SortedIndicesOffset + particleIndex];
|
||||
}
|
||||
#endif
|
||||
|
||||
// Read particle data
|
||||
float3 particlePosition = GetParticleVec3(particleIndex, PositionOffset);
|
||||
@@ -566,12 +563,16 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
|
||||
|
||||
// Vertex Shader function for Ribbon Rendering
|
||||
META_VS(true, FEATURE_LEVEL_ES2)
|
||||
VertexOutput VS_Ribbon(uint vertexIndex : SV_VertexID)
|
||||
META_VS_IN_ELEMENT(TEXCOORD, 0, R32_UINT, 0, 0, PER_VERTEX, 0, true)
|
||||
META_VS_IN_ELEMENT(TEXCOORD, 1, R32_UINT, 0, ALIGN, PER_VERTEX, 0, true)
|
||||
META_VS_IN_ELEMENT(TEXCOORD, 2, R32_UINT, 0, ALIGN, PER_VERTEX, 0, true)
|
||||
META_VS_IN_ELEMENT(TEXCOORD, 3, R32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
|
||||
VertexOutput VS_Ribbon(RibbonInput input, uint vertexIndex : SV_VertexID)
|
||||
{
|
||||
VertexOutput output;
|
||||
|
||||
// Get particle data
|
||||
uint particleIndex = vertexIndex / 2;
|
||||
uint particleIndex = input.ParticleIndex;
|
||||
int vertexSign = (((int)vertexIndex & 0x1) * 2) - 1;
|
||||
float3 position = GetParticlePosition(particleIndex);
|
||||
float ribbonWidth = RibbonWidthOffset != -1 ? GetParticleFloat(particleIndex, RibbonWidthOffset) : 20.0f;
|
||||
@@ -579,15 +580,13 @@ VertexOutput VS_Ribbon(uint vertexIndex : SV_VertexID)
|
||||
|
||||
// Calculate ribbon direction
|
||||
float3 direction;
|
||||
if (particleIndex == 0)
|
||||
if (input.Order == 0)
|
||||
{
|
||||
float3 nextParticlePos = GetParticlePosition(particleIndex + 1);
|
||||
direction = nextParticlePos - position;
|
||||
direction = GetParticlePosition(input.PrevParticleIndex) - position;
|
||||
}
|
||||
else
|
||||
{
|
||||
float3 previousParticlePos = GetParticlePosition(particleIndex - 1);
|
||||
direction = position - previousParticlePos;
|
||||
direction = position - GetParticlePosition(input.PrevParticleIndex);
|
||||
}
|
||||
|
||||
// Calculate particle orientation (tangent vectors)
|
||||
@@ -604,19 +603,16 @@ VertexOutput VS_Ribbon(uint vertexIndex : SV_VertexID)
|
||||
}
|
||||
|
||||
// Calculate texture coordinates
|
||||
float texCoordU;
|
||||
#ifdef _VS_Ribbon
|
||||
if (RibbonUVTilingDistance != 0.0f)
|
||||
{
|
||||
texCoordU = SegmentDistances[particleIndex] / RibbonUVTilingDistance;
|
||||
output.TexCoord.x = input.Distance / RibbonUVTilingDistance;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
texCoordU = (float)particleIndex / RibbonSegmentCount;
|
||||
output.TexCoord.x = (float)input.Order / (float)RibbonSegmentCount;
|
||||
}
|
||||
float texCoordV = (vertexIndex + 1) & 0x1;
|
||||
output.TexCoord = float2(texCoordU, texCoordV) * RibbonUVScale + RibbonUVOffset;
|
||||
output.TexCoord.y = (vertexIndex + 1) & 0x1;
|
||||
output.TexCoord = output.TexCoord * RibbonUVScale + RibbonUVOffset;
|
||||
|
||||
// Compute world space vertex position
|
||||
output.WorldPosition = position + tangentRight * vertexSign * (ribbonWidth.xxx * 0.5f);
|
||||
|
||||
BIN
Content/Editor/Particles/Particle Material Color.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Particle Material Color.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Particles/Smoke Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Smoke Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/SpriteMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/SpriteMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Terrain/Circle Brush Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Terrain/Circle Brush Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Terrain/Highlight Terrain Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Terrain/Highlight Terrain Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/TexturePreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/TexturePreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Wires Debug Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Wires Debug Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultDeformableMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultDeformableMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultTerrainMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultTerrainMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/SingleColorMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/SingleColorMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/SkyboxMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/SkyboxMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/GI/DDGI.flax
(Stored with Git LFS)
BIN
Content/Shaders/GI/DDGI.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/GI/GlobalSurfaceAtlas.flax
(Stored with Git LFS)
BIN
Content/Shaders/GI/GlobalSurfaceAtlas.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/GUI.flax
(Stored with Git LFS)
BIN
Content/Shaders/GUI.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/GlobalSignDistanceField.flax
(Stored with Git LFS)
BIN
Content/Shaders/GlobalSignDistanceField.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/ProbesFilter.flax
(Stored with Git LFS)
BIN
Content/Shaders/ProbesFilter.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/SSR.flax
(Stored with Git LFS)
BIN
Content/Shaders/SSR.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/TAA.flax
(Stored with Git LFS)
BIN
Content/Shaders/TAA.flax
(Stored with Git LFS)
Binary file not shown.
@@ -354,7 +354,7 @@ bool CookAssetsStep::Process(CookingData& data, CacheData& cache, Asset* asset)
|
||||
if (asset->WaitForLoaded())
|
||||
{
|
||||
LOG(Error, "Failed to load asset \'{0}\'", asset->ToString());
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Switch based on an asset type
|
||||
@@ -1132,7 +1132,10 @@ bool CookAssetsStep::Perform(CookingData& data)
|
||||
|
||||
// Cook asset
|
||||
if (Process(data, cache, assetRef.Get()))
|
||||
{
|
||||
cache.Save();
|
||||
return true;
|
||||
}
|
||||
data.Stats.CookedAssets++;
|
||||
|
||||
// Auto save build cache after every few cooked assets (reduces next build time if cooking fails later)
|
||||
|
||||
@@ -322,7 +322,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
internal static ContextMenuBase CreatePicker(Tag value, Tag[] values, PickerData pickerData)
|
||||
{
|
||||
// Initialize search popup
|
||||
var menu = Utilities.Utils.CreateSearchPopup(out var searchBox, out var tree, 40.0f);
|
||||
var menu = Utilities.Utils.CreateSearchPopup(out var searchBox, out var tree, 42.0f);
|
||||
|
||||
// Add tag drop panel
|
||||
var addTagDropPanel = new DropPanel
|
||||
@@ -333,6 +333,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
ArrowImageClosed = new SpriteBrush(FlaxEngine.GUI.Style.Current.ArrowRight),
|
||||
Parent = menu,
|
||||
HeaderTextMargin = new Margin(2.0f),
|
||||
HeaderHeight = 18.0f,
|
||||
AnchorPreset = AnchorPresets.TopLeft,
|
||||
Bounds = new Rectangle(2, 2, menu.Width - 4, 30),
|
||||
IsClosed = true,
|
||||
@@ -408,7 +409,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
var buttonAddTag = new Button
|
||||
{
|
||||
Parent = addButtonPanel,
|
||||
Size = new Float2(100, 20),
|
||||
Size = new Float2(100, 18),
|
||||
Text = "Add Tag",
|
||||
AnchorPreset = AnchorPresets.MiddleCenter,
|
||||
};
|
||||
|
||||
@@ -275,12 +275,16 @@ namespace FlaxEditor.CustomEditors
|
||||
// Workaround for DefaultValueAttribute that doesn't support certain value types storage
|
||||
if (Type.Type == typeof(sbyte))
|
||||
_defaultValue = Convert.ToSByte(_defaultValue);
|
||||
else if (Type.Type == typeof(short))
|
||||
_defaultValue = Convert.ToInt16(_defaultValue);
|
||||
else if (Type.Type == typeof(ushort))
|
||||
_defaultValue = Convert.ToUInt16(_defaultValue);
|
||||
else if (Type.Type == typeof(uint))
|
||||
_defaultValue = Convert.ToUInt32(_defaultValue);
|
||||
else if (Type.Type == typeof(ulong))
|
||||
_defaultValue = Convert.ToUInt64(_defaultValue);
|
||||
else if (Type.Type == typeof(long))
|
||||
_defaultValue = Convert.ToInt64(_defaultValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,8 @@ namespace FlaxEditor
|
||||
private bool _isAfterInit, _areModulesInited, _areModulesAfterInitEnd, _isHeadlessMode;
|
||||
private string _projectToOpen;
|
||||
private float _lastAutoSaveTimer;
|
||||
private AutoSavePopup _autoSavePopup;
|
||||
private Button _saveNowButton;
|
||||
private Button _cancelSaveButton;
|
||||
private bool _autoSaveNow;
|
||||
private Guid _startupSceneCmdLine;
|
||||
|
||||
@@ -498,28 +499,6 @@ namespace FlaxEditor
|
||||
{
|
||||
var timeSinceLastSave = Time.UnscaledGameTime - _lastAutoSaveTimer;
|
||||
var timeToNextSave = options.AutoSaveFrequency * 60.0f - timeSinceLastSave;
|
||||
var countDownDuration = 4.0f;
|
||||
|
||||
// Show auto save popup
|
||||
if (timeToNextSave <= options.AutoSaveReminderTime && timeToNextSave >= 0)
|
||||
{
|
||||
if (_autoSavePopup == null)
|
||||
{
|
||||
_autoSavePopup = AutoSavePopup.Show(Instance.Windows.MainWindow.GUI, timeToNextSave);
|
||||
_autoSavePopup.SaveNowButton.Clicked += () => _autoSaveNow = true;
|
||||
_autoSavePopup.CancelSaveButton.Clicked += () =>
|
||||
{
|
||||
Log("Auto save canceled");
|
||||
_autoSavePopup.HidePopup();
|
||||
_lastAutoSaveTimer = Time.UnscaledGameTime; // Reset timer
|
||||
};
|
||||
}
|
||||
else if (!_autoSavePopup.Visible && !_autoSavePopup.UserClosed)
|
||||
_autoSavePopup.ShowPopup();
|
||||
|
||||
if (_autoSavePopup.Visible)
|
||||
_autoSavePopup.UpdateTime(timeToNextSave);
|
||||
}
|
||||
|
||||
if (timeToNextSave <= 0.0f || _autoSaveNow)
|
||||
{
|
||||
@@ -530,14 +509,76 @@ namespace FlaxEditor
|
||||
if (options.AutoSaveContent)
|
||||
SaveContent();
|
||||
|
||||
// Hide auto save popup and reset user closed
|
||||
_autoSavePopup.HidePopup();
|
||||
_autoSavePopup.UserClosed = false;
|
||||
_autoSaveNow = false;
|
||||
|
||||
// Hide save now and cancel save buttons
|
||||
if (_saveNowButton != null && _cancelSaveButton != null)
|
||||
{
|
||||
_saveNowButton.Visible = false;
|
||||
_cancelSaveButton.Visible = false;
|
||||
}
|
||||
else if (timeToNextSave < countDownDuration)
|
||||
}
|
||||
else if (timeToNextSave <= options.AutoSaveReminderTime)
|
||||
{
|
||||
msg = string.Format("Auto save in {0}s...", Mathf.CeilToInt(timeToNextSave));
|
||||
|
||||
// Create save now and cancel save buttons if needed
|
||||
if (_saveNowButton == null)
|
||||
{
|
||||
_saveNowButton = new Button
|
||||
{
|
||||
Parent = UI.StatusBar,
|
||||
Height = 14,
|
||||
Width = 60,
|
||||
AnchorPreset = AnchorPresets.MiddleLeft,
|
||||
BackgroundColor = Color.Transparent,
|
||||
BorderColor = Color.Transparent,
|
||||
BackgroundColorHighlighted = Color.Transparent,
|
||||
BackgroundColorSelected = Color.Transparent,
|
||||
BorderColorHighlighted = Color.Transparent,
|
||||
Text = "Save Now",
|
||||
TooltipText = "Saves now and restarts the auto save timer."
|
||||
};
|
||||
_saveNowButton.LocalX += 120;
|
||||
_saveNowButton.Clicked += () => _autoSaveNow = true;
|
||||
_saveNowButton.HoverBegin += () => _saveNowButton.TextColor = Style.Current.BackgroundHighlighted;
|
||||
_saveNowButton.HoverEnd += () => _saveNowButton.TextColor = UI.StatusBar.TextColor;
|
||||
}
|
||||
|
||||
if (_cancelSaveButton == null)
|
||||
{
|
||||
_cancelSaveButton = new Button
|
||||
{
|
||||
Parent = UI.StatusBar,
|
||||
Height = 14,
|
||||
Width = 70,
|
||||
AnchorPreset = AnchorPresets.MiddleLeft,
|
||||
BackgroundColor = Color.Transparent,
|
||||
BorderColor = Color.Transparent,
|
||||
BackgroundColorHighlighted = Color.Transparent,
|
||||
BackgroundColorSelected = Color.Transparent,
|
||||
BorderColorHighlighted = Color.Transparent,
|
||||
Text = "Cancel",
|
||||
TooltipText = "Cancels this auto save."
|
||||
};
|
||||
_cancelSaveButton.LocalX += 180;
|
||||
_cancelSaveButton.Clicked += () =>
|
||||
{
|
||||
Log("Auto save canceled");
|
||||
_saveNowButton.Visible = false;
|
||||
_cancelSaveButton.Visible = false;
|
||||
_lastAutoSaveTimer = Time.UnscaledGameTime; // Reset timer
|
||||
};
|
||||
_cancelSaveButton.HoverBegin += () => _cancelSaveButton.TextColor = Style.Current.BackgroundHighlighted;
|
||||
_cancelSaveButton.HoverEnd += () => _cancelSaveButton.TextColor = UI.StatusBar.TextColor;
|
||||
}
|
||||
|
||||
// Show save now and cancel save buttons
|
||||
if (!_saveNowButton.Visible || !_cancelSaveButton.Visible)
|
||||
{
|
||||
_saveNowButton.Visible = true;
|
||||
_cancelSaveButton.Visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StateMachine.EditingSceneState.AutoSaveStatus != msg)
|
||||
@@ -545,6 +586,14 @@ namespace FlaxEditor
|
||||
StateMachine.EditingSceneState.AutoSaveStatus = msg;
|
||||
UI.UpdateStatusBar();
|
||||
}
|
||||
|
||||
if (UI?.StatusBar?.Text != null && !UI.StatusBar.Text.Contains("Auto") &&
|
||||
_saveNowButton != null && _cancelSaveButton != null &&
|
||||
(_saveNowButton.Visible || _cancelSaveButton.Visible))
|
||||
{
|
||||
_saveNowButton.Visible = false;
|
||||
_cancelSaveButton.Visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void InitProject()
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
|
||||
namespace FlaxEditor.GUI
|
||||
{
|
||||
/// <summary>
|
||||
/// Popup menu for reminding of an upcoming auto save.
|
||||
/// </summary>
|
||||
public class AutoSavePopup : ContainerControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the value for if the user has manually closed this popup.
|
||||
/// </summary>
|
||||
public bool UserClosed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The save now button. Used to skip the last remaining auto save time.
|
||||
/// </summary>
|
||||
public Button SaveNowButton => _saveNowButton;
|
||||
|
||||
/// <summary>
|
||||
/// Button that should be used to cancel the auto save.
|
||||
/// </summary>
|
||||
public Button CancelSaveButton => _cancelSaveButton;
|
||||
|
||||
private int _timeRemaining;
|
||||
private Panel _backgroundPanel;
|
||||
private Label _timeLabel;
|
||||
private Button _saveNowButton;
|
||||
private Button _cancelSaveButton;
|
||||
private Color _defaultTextColor;
|
||||
private bool _isMoved = false;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the AutoSavePopup.
|
||||
/// </summary>
|
||||
/// <param name="initialTime">The initial time to set the time label to.</param>
|
||||
public AutoSavePopup(float initialTime)
|
||||
{
|
||||
UpdateTime(initialTime);
|
||||
|
||||
_backgroundPanel = new Panel(ScrollBars.None)
|
||||
{
|
||||
Parent = this,
|
||||
AnchorPreset = AnchorPresets.StretchAll,
|
||||
BackgroundColor = Color.Transparent,
|
||||
};
|
||||
|
||||
_timeLabel = new Label(0, 0, 25, 10)
|
||||
{
|
||||
Parent = _backgroundPanel,
|
||||
Text = _timeRemaining.ToString(),
|
||||
HorizontalAlignment = TextAlignment.Near,
|
||||
VerticalAlignment = TextAlignment.Near,
|
||||
AutoWidth = true,
|
||||
Height = 14,
|
||||
AnchorPreset = AnchorPresets.MiddleLeft,
|
||||
};
|
||||
|
||||
_saveNowButton = new Button
|
||||
{
|
||||
Parent = _backgroundPanel,
|
||||
Height = 14,
|
||||
Width = 60,
|
||||
AnchorPreset = AnchorPresets.MiddleRight,
|
||||
BackgroundColor = Color.Transparent,
|
||||
BorderColor = Color.Transparent,
|
||||
BackgroundColorHighlighted = Color.Transparent,
|
||||
BackgroundColorSelected = Color.Transparent,
|
||||
BorderColorHighlighted = Color.Transparent,
|
||||
Text = "Save Now",
|
||||
TooltipText = "Saves now and restarts the auto save timer."
|
||||
};
|
||||
_saveNowButton.LocalX -= 85;
|
||||
|
||||
_cancelSaveButton = new Button
|
||||
{
|
||||
Parent = _backgroundPanel,
|
||||
Height = 14,
|
||||
Width = 70,
|
||||
AnchorPreset = AnchorPresets.MiddleRight,
|
||||
BackgroundColor = Color.Transparent,
|
||||
BorderColor = Color.Transparent,
|
||||
BackgroundColorHighlighted = Color.Transparent,
|
||||
BackgroundColorSelected = Color.Transparent,
|
||||
BorderColorHighlighted = Color.Transparent,
|
||||
Text = "Cancel Save",
|
||||
TooltipText = "Cancels this auto save."
|
||||
};
|
||||
_cancelSaveButton.LocalX -= 5;
|
||||
|
||||
_defaultTextColor = _saveNowButton.TextColor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the time label
|
||||
/// </summary>
|
||||
/// <param name="time">The time to change the label to.</param>
|
||||
public void UpdateTime(float time)
|
||||
{
|
||||
_timeRemaining = Mathf.CeilToInt(time);
|
||||
if (_timeLabel != null)
|
||||
_timeLabel.Text = "Auto Save in: " + _timeRemaining;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
if (IsMouseOver)
|
||||
{
|
||||
_saveNowButton.TextColor = _saveNowButton.IsMouseOver ? Style.Current.BackgroundHighlighted : _defaultTextColor;
|
||||
_cancelSaveButton.TextColor = _cancelSaveButton.IsMouseOver ? Style.Current.BackgroundHighlighted : _defaultTextColor;
|
||||
}
|
||||
|
||||
// Move if the progress bar is visible
|
||||
if (Editor.Instance.UI.ProgressVisible && !_isMoved)
|
||||
{
|
||||
_isMoved = true;
|
||||
LocalX -= 280;
|
||||
}
|
||||
else if (!Editor.Instance.UI.ProgressVisible && _isMoved)
|
||||
{
|
||||
LocalX += 280;
|
||||
_isMoved = false;
|
||||
}
|
||||
base.Update(deltaTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and shows the AutoSavePopup
|
||||
/// </summary>
|
||||
/// <param name="parentControl">The parent control.</param>
|
||||
/// <param name="initialTime">The time to start at.</param>
|
||||
/// <returns></returns>
|
||||
public static AutoSavePopup Show(ContainerControl parentControl, float initialTime)
|
||||
{
|
||||
var popup = new AutoSavePopup(initialTime)
|
||||
{
|
||||
Parent = parentControl,
|
||||
Height = Editor.Instance.UI.StatusBar.Height,
|
||||
Width = 250,
|
||||
AnchorPreset = AnchorPresets.BottomRight,
|
||||
};
|
||||
popup.ShowPopup();
|
||||
return popup;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows the popup by changing its visibility
|
||||
/// </summary>
|
||||
public void ShowPopup()
|
||||
{
|
||||
Visible = true;
|
||||
UserClosed = false;
|
||||
_saveNowButton.TextColor = _defaultTextColor;
|
||||
_cancelSaveButton.TextColor = _defaultTextColor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hides the popup by changing its visibility
|
||||
/// </summary>
|
||||
public void HidePopup()
|
||||
{
|
||||
Visible = false;
|
||||
if (_containsFocus)
|
||||
Defocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,6 +78,7 @@ void ViewportIconsRenderer::DrawIcons(RenderContext& renderContext, Actor* actor
|
||||
draw.PerInstanceRandom = 0;
|
||||
draw.LODBias = 0;
|
||||
draw.ForcedLOD = -1;
|
||||
draw.SortOrder = 0;
|
||||
draw.VertexColors = nullptr;
|
||||
|
||||
if (const auto scene = SceneObject::Cast<Scene>(actor))
|
||||
|
||||
@@ -1521,6 +1521,7 @@ namespace FlaxEditor.Viewport
|
||||
new ViewFlagOptions(ViewFlags.PointLights, "Point Lights"),
|
||||
new ViewFlagOptions(ViewFlags.SpotLights, "Spot Lights"),
|
||||
new ViewFlagOptions(ViewFlags.SkyLights, "Sky Lights"),
|
||||
new ViewFlagOptions(ViewFlags.Sky, "Sky"),
|
||||
new ViewFlagOptions(ViewFlags.Fog, "Fog"),
|
||||
new ViewFlagOptions(ViewFlags.SpecularLight, "Specular Light"),
|
||||
new ViewFlagOptions(ViewFlags.Decals, "Decals"),
|
||||
|
||||
@@ -428,8 +428,12 @@ namespace FlaxEditor.Viewport.Previews
|
||||
case KeyboardKeys.F:
|
||||
// Pay respect..
|
||||
ViewportCamera.SetArcBallView(_previewModel.Box);
|
||||
break;
|
||||
return true;
|
||||
case KeyboardKeys.Spacebar:
|
||||
PlayAnimation = !PlayAnimation;
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnKeyDown(key);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEditor.Viewport.Cameras;
|
||||
using FlaxEditor.Viewport.Widgets;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using System;
|
||||
using Object = FlaxEngine.Object;
|
||||
|
||||
namespace FlaxEditor.Viewport.Previews
|
||||
@@ -14,10 +16,12 @@ namespace FlaxEditor.Viewport.Previews
|
||||
/// <seealso cref="AssetPreview" />
|
||||
public class ParticleSystemPreview : AssetPreview
|
||||
{
|
||||
private bool _playSimulation = false;
|
||||
private ParticleEffect _previewEffect;
|
||||
private ContextMenuButton _showBoundsButton;
|
||||
private ContextMenuButton _showOriginButton;
|
||||
private ContextMenuButton _showParticleCounterButton;
|
||||
private ViewportWidgetButton _playPauseButton;
|
||||
private StaticModel _boundsModel;
|
||||
private StaticModel _originModel;
|
||||
private bool _showParticlesCounter;
|
||||
@@ -39,7 +43,25 @@ namespace FlaxEditor.Viewport.Previews
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to play the particles simulation in editor.
|
||||
/// </summary>
|
||||
public bool PlaySimulation { get; set; } = false;
|
||||
public bool PlaySimulation
|
||||
{
|
||||
get => _playSimulation;
|
||||
set
|
||||
{
|
||||
if (_playSimulation == value)
|
||||
return;
|
||||
_playSimulation = value;
|
||||
PlaySimulationChanged?.Invoke();
|
||||
|
||||
if (_playPauseButton != null)
|
||||
_playPauseButton.Icon = value ? Editor.Instance.Icons.Pause64 : Editor.Instance.Icons.Play64;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when particles simulation playback state gets changed.
|
||||
/// </summary>
|
||||
public event Action PlaySimulationChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to show particle effect bounding box.
|
||||
@@ -161,11 +183,22 @@ namespace FlaxEditor.Viewport.Previews
|
||||
// Link actors for rendering
|
||||
Task.AddCustomActor(_previewEffect);
|
||||
|
||||
if (useWidgets)
|
||||
{
|
||||
if (!useWidgets)
|
||||
return;
|
||||
_showBoundsButton = ViewWidgetShowMenu.AddButton("Bounds", () => ShowBounds = !ShowBounds);
|
||||
_showOriginButton = ViewWidgetShowMenu.AddButton("Origin", () => ShowOrigin = !ShowOrigin);
|
||||
_showParticleCounterButton = ViewWidgetShowMenu.AddButton("Particles Counter", () => ShowParticlesCounter = !ShowParticlesCounter);
|
||||
|
||||
// Play/Pause widget
|
||||
{
|
||||
var playPauseWidget = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
|
||||
_playPauseButton = new ViewportWidgetButton(null, Editor.Instance.Icons.Pause64)
|
||||
{
|
||||
TooltipText = "Simulation playback play (F5) or pause (F6)",
|
||||
Parent = playPauseWidget,
|
||||
};
|
||||
_playPauseButton.Clicked += button => PlaySimulation = !PlaySimulation;
|
||||
playPauseWidget.Parent = this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +233,7 @@ namespace FlaxEditor.Viewport.Previews
|
||||
// Manually update simulation
|
||||
if (PlaySimulation)
|
||||
{
|
||||
_previewEffect.UpdateSimulation();
|
||||
_previewEffect.UpdateSimulation(true);
|
||||
}
|
||||
|
||||
// Keep bounds matching the model
|
||||
@@ -228,6 +261,34 @@ namespace FlaxEditor.Viewport.Previews
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnKeyDown(KeyboardKeys key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case KeyboardKeys.F:
|
||||
ViewportCamera.SetArcBallView(_previewEffect.Box);
|
||||
return true;
|
||||
case KeyboardKeys.Spacebar:
|
||||
PlaySimulation = !PlaySimulation;
|
||||
return true;
|
||||
}
|
||||
|
||||
var inputOptions = Editor.Instance.Options.Options.Input;
|
||||
if (inputOptions.Play.Process(this, key))
|
||||
{
|
||||
PlaySimulation = true;
|
||||
return true;
|
||||
}
|
||||
if (inputOptions.Pause.Process(this, key))
|
||||
{
|
||||
PlaySimulation = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnKeyDown(key);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnDestroy()
|
||||
{
|
||||
@@ -239,6 +300,7 @@ namespace FlaxEditor.Viewport.Previews
|
||||
_showBoundsButton = null;
|
||||
_showOriginButton = null;
|
||||
_showParticleCounterButton = null;
|
||||
_playPauseButton = null;
|
||||
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
@@ -430,7 +430,7 @@ namespace FlaxEditor.Windows
|
||||
writer.WriteAttributeString("MovementSpeed", Viewport.MovementSpeed.ToString());
|
||||
writer.WriteAttributeString("OrthographicScale", Viewport.OrthographicScale.ToString());
|
||||
writer.WriteAttributeString("UseOrthographicProjection", Viewport.UseOrthographicProjection.ToString());
|
||||
writer.WriteAttributeString("ViewFlags", ((long)Viewport.Task.View.Flags).ToString());
|
||||
writer.WriteAttributeString("ViewFlags", ((ulong)Viewport.Task.View.Flags).ToString());
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -463,7 +463,7 @@ namespace FlaxEditor.Windows
|
||||
if (bool.TryParse(node.GetAttribute("UseOrthographicProjection"), out value1))
|
||||
Viewport.UseOrthographicProjection = value1;
|
||||
|
||||
if (long.TryParse(node.GetAttribute("ViewFlags"), out long value3))
|
||||
if (ulong.TryParse(node.GetAttribute("ViewFlags"), out ulong value3))
|
||||
Viewport.Task.ViewFlags = (ViewFlags)value3;
|
||||
|
||||
// Reset view flags if opening with different engine version (ViewFlags enum could be modified)
|
||||
|
||||
@@ -91,6 +91,10 @@ namespace
|
||||
void AudioSettings::Apply()
|
||||
{
|
||||
::MuteOnFocusLoss = MuteOnFocusLoss;
|
||||
if (AudioBackend::Instance != nullptr)
|
||||
{
|
||||
Audio::SetDopplerFactor(DopplerFactor);
|
||||
}
|
||||
}
|
||||
|
||||
AudioDevice* Audio::GetActiveDevice()
|
||||
|
||||
@@ -187,7 +187,7 @@ BoundingBox Model::GetBox(int32 lodIndex) const
|
||||
return LODs[lodIndex].GetBox();
|
||||
}
|
||||
|
||||
void Model::Draw(const RenderContext& renderContext, MaterialBase* material, const Matrix& world, StaticFlags flags, bool receiveDecals) const
|
||||
void Model::Draw(const RenderContext& renderContext, MaterialBase* material, const Matrix& world, StaticFlags flags, bool receiveDecals, int16 sortOrder) const
|
||||
{
|
||||
if (!CanBeRendered())
|
||||
return;
|
||||
@@ -203,7 +203,7 @@ void Model::Draw(const RenderContext& renderContext, MaterialBase* material, con
|
||||
lodIndex = ClampLODIndex(lodIndex);
|
||||
|
||||
// Draw
|
||||
LODs[lodIndex].Draw(renderContext, material, world, flags, receiveDecals);
|
||||
LODs[lodIndex].Draw(renderContext, material, world, flags, receiveDecals, DrawPass::Default, 0, sortOrder);
|
||||
}
|
||||
|
||||
template<typename ContextType>
|
||||
|
||||
@@ -181,7 +181,8 @@ public:
|
||||
/// <param name="world">The world transformation of the model.</param>
|
||||
/// <param name="flags">The object static flags.</param>
|
||||
/// <param name="receiveDecals">True if rendered geometry can receive decals, otherwise false.</param>
|
||||
API_FUNCTION() void Draw(API_PARAM(Ref) const RenderContext& renderContext, MaterialBase* material, API_PARAM(Ref) const Matrix& world, StaticFlags flags = StaticFlags::None, bool receiveDecals = true) const;
|
||||
/// <param name="sortOrder">Object sorting key.</param>
|
||||
API_FUNCTION() void Draw(API_PARAM(Ref) const RenderContext& renderContext, MaterialBase* material, API_PARAM(Ref) const Matrix& world, StaticFlags flags = StaticFlags::None, bool receiveDecals = true, int16 sortOrder = 0) const;
|
||||
|
||||
/// <summary>
|
||||
/// Draws the model.
|
||||
|
||||
@@ -267,6 +267,19 @@ namespace FlaxEngine
|
||||
/// <remarks>This method may be preferred to <see cref="Float2.Length" /> when only a relative length is needed and speed is of the essence.</remarks>
|
||||
public float LengthSquared => X * X + Y * Y;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the normalized vector. Returned vector has length equal 1.
|
||||
/// </summary>
|
||||
public Float2 Normalized
|
||||
{
|
||||
get
|
||||
{
|
||||
Float2 result = this;
|
||||
result.Normalize();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the vector into a unit vector.
|
||||
/// </summary>
|
||||
|
||||
@@ -301,6 +301,19 @@ namespace FlaxEngine
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the normalized vector. Returned vector has length equal 1.
|
||||
/// </summary>
|
||||
public Vector2 Normalized
|
||||
{
|
||||
get
|
||||
{
|
||||
Vector2 result = this;
|
||||
result.Normalize();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an array containing the elements of the vector.
|
||||
/// </summary>
|
||||
|
||||
@@ -223,6 +223,15 @@ public:
|
||||
return Vector2Base(-X, -Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a normalized vector that has length equal to 1.
|
||||
/// </summary>
|
||||
Vector2Base GetNormalized() const
|
||||
{
|
||||
const T rcp = 1.0f / Length();
|
||||
return Vector2Base(X * rcp, Y * rcp);
|
||||
}
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Performs vector normalization (scales vector up to unit length).
|
||||
|
||||
@@ -161,6 +161,11 @@ namespace FlaxEngine
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the aspect ratio used by the viewport.
|
||||
/// </summary>
|
||||
public float AspectRatio => !Mathf.IsZero(Height) ? Width / Height : 0f;
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="Viewport"/> is equal to this instance.
|
||||
/// </summary>
|
||||
@@ -326,21 +331,5 @@ namespace FlaxEngine
|
||||
vector /= w;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the aspect ratio used by the viewport.
|
||||
/// </summary>
|
||||
/// <value>The aspect ratio.</value>
|
||||
public float AspectRatio
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Mathf.IsZero(Height))
|
||||
{
|
||||
return Width / Height;
|
||||
}
|
||||
return 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,5 +164,12 @@ constexpr bool EnumHasAllFlags(T value, T flags)
|
||||
return ((__underlying_type(T))value & (__underlying_type(T))flags) == (__underlying_type(T))flags;
|
||||
}
|
||||
|
||||
// Returns true if given enum value has none of enum flags set
|
||||
template<typename T>
|
||||
constexpr bool EnumHasNoneFlags(T value, T flags)
|
||||
{
|
||||
return ((__underlying_type(T))value & (__underlying_type(T))flags) == 0;
|
||||
}
|
||||
|
||||
// Returns byte offset from the object pointer in vtable to the begin of the given inherited type implementation
|
||||
#define VTABLE_OFFSET(type, baseType) (((intptr)static_cast<baseType*>((type*)1))-1)
|
||||
|
||||
@@ -140,13 +140,13 @@ struct PsData
|
||||
|
||||
bool Create(GPUPipelineState::Description& desc)
|
||||
{
|
||||
desc.DepthTestEnable = true;
|
||||
desc.DepthEnable = true;
|
||||
desc.DepthWriteEnable = false;
|
||||
|
||||
Depth = GPUDevice::Instance->CreatePipelineState();
|
||||
if (Depth->Init(desc))
|
||||
return true;
|
||||
desc.DepthTestEnable = false;
|
||||
desc.DepthEnable = false;
|
||||
NoDepthTest = GPUDevice::Instance->CreatePipelineState();
|
||||
if (NoDepthTest->Init(desc))
|
||||
return false;
|
||||
@@ -156,7 +156,7 @@ struct PsData
|
||||
NoDepthTestDepthWrite = GPUDevice::Instance->CreatePipelineState();
|
||||
if (NoDepthTestDepthWrite->Init(desc))
|
||||
return false;
|
||||
desc.DepthTestEnable = true;
|
||||
desc.DepthEnable = true;
|
||||
DepthWrite = GPUDevice::Instance->CreatePipelineState();
|
||||
return DepthWrite->Init(desc);
|
||||
}
|
||||
|
||||
@@ -1173,6 +1173,7 @@ void Foliage::Draw(RenderContext& renderContext)
|
||||
draw.Flags = GetStaticFlags();
|
||||
draw.LODBias = 0;
|
||||
draw.ForcedLOD = -1;
|
||||
draw.SortOrder = 0;
|
||||
draw.VertexColors = nullptr;
|
||||
draw.Lightmap = _scene->LightmapsData.GetReadyLightmap(instance.Lightmap.TextureIndex);
|
||||
draw.LightmapUVs = &instance.Lightmap.UVsArea;
|
||||
|
||||
@@ -514,7 +514,7 @@ public:
|
||||
API_FIELD(ReadOnly) static BlendingMode Additive;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the alpha blending.
|
||||
/// Gets the alpha blending. Source alpha controls the output color (0 - use destination color, 1 - use source color).
|
||||
/// </summary>
|
||||
API_FIELD(ReadOnly) static BlendingMode AlphaBlend;
|
||||
|
||||
@@ -591,22 +591,22 @@ API_ENUM() enum class Quality : byte
|
||||
API_ENUM() enum class MaterialPostFxLocation : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// The after post processing pass using LDR input frame.
|
||||
/// The 'after' post processing pass using LDR input frame.
|
||||
/// </summary>
|
||||
AfterPostProcessingPass = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The before post processing pass using HDR input frame.
|
||||
/// The 'before' post processing pass using HDR input frame.
|
||||
/// </summary>
|
||||
BeforePostProcessingPass = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The before forward pass but after GBuffer with HDR input frame.
|
||||
/// The 'before' forward pass but after GBuffer with HDR input frame.
|
||||
/// </summary>
|
||||
BeforeForwardPass = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The after custom post effects.
|
||||
/// The 'after' custom post effects.
|
||||
/// </summary>
|
||||
AfterCustomPostEffects = 3,
|
||||
|
||||
@@ -620,6 +620,11 @@ API_ENUM() enum class MaterialPostFxLocation : byte
|
||||
/// </summary>
|
||||
AfterAntiAliasingPass = 5,
|
||||
|
||||
/// <summary>
|
||||
/// The 'after' forward pass but before any post processing.
|
||||
/// </summary>
|
||||
AfterForwardPass = 6,
|
||||
|
||||
API_ENUM(Attributes="HideInEditor")
|
||||
MAX,
|
||||
};
|
||||
@@ -635,7 +640,7 @@ API_ENUM() enum class PostProcessEffectLocation
|
||||
Default = 0,
|
||||
|
||||
/// <summary>
|
||||
///The 'before' in-build PostFx pass (bloom, color grading, etc.). After Forward Pass (transparency) and fog effects.
|
||||
/// The 'before' in-build PostFx pass (bloom, color grading, etc.). After Forward Pass (transparency) and fog effects.
|
||||
/// </summary>
|
||||
BeforePostProcessingPass = 1,
|
||||
|
||||
@@ -659,6 +664,16 @@ API_ENUM() enum class PostProcessEffectLocation
|
||||
/// </summary>
|
||||
CustomUpscale = 5,
|
||||
|
||||
/// <summary>
|
||||
/// The 'after' GBuffer rendering pass. Can be used to render custom geometry into GBuffer. Output is light buffer, single-target only (no output).
|
||||
/// </summary>
|
||||
AfterGBufferPass = 6,
|
||||
|
||||
/// <summary>
|
||||
/// The 'after' forward pass but before any post processing.
|
||||
/// </summary>
|
||||
AfterForwardPass = 7,
|
||||
|
||||
API_ENUM(Attributes="HideInEditor")
|
||||
MAX,
|
||||
};
|
||||
@@ -874,7 +889,7 @@ API_ENUM() enum class ViewMode
|
||||
/// <summary>
|
||||
/// Frame rendering flags used to switch between graphics features.
|
||||
/// </summary>
|
||||
API_ENUM(Attributes="Flags") enum class ViewFlags : int64
|
||||
API_ENUM(Attributes="Flags") enum class ViewFlags : uint64
|
||||
{
|
||||
/// <summary>
|
||||
/// Nothing.
|
||||
@@ -1011,20 +1026,25 @@ API_ENUM(Attributes="Flags") enum class ViewFlags : int64
|
||||
/// </summary>
|
||||
GlobalSDF = 1 << 25,
|
||||
|
||||
/// <summary>
|
||||
/// Shows/hides the Sky/Skybox rendering.
|
||||
/// </summary>
|
||||
Sky = 1 << 26,
|
||||
|
||||
/// <summary>
|
||||
/// Default flags for Game.
|
||||
/// </summary>
|
||||
DefaultGame = Reflections | DepthOfField | Fog | Decals | MotionBlur | SSR | AO | GI | DirectionalLights | PointLights | SpotLights | SkyLights | Shadows | SpecularLight | AntiAliasing | CustomPostProcess | Bloom | ToneMapping | EyeAdaptation | CameraArtifacts | LensFlares | ContactShadows | GlobalSDF,
|
||||
DefaultGame = Reflections | DepthOfField | Fog | Decals | MotionBlur | SSR | AO | GI | DirectionalLights | PointLights | SpotLights | SkyLights | Shadows | SpecularLight | AntiAliasing | CustomPostProcess | Bloom | ToneMapping | EyeAdaptation | CameraArtifacts | LensFlares | ContactShadows | GlobalSDF | Sky,
|
||||
|
||||
/// <summary>
|
||||
/// Default flags for Editor.
|
||||
/// </summary>
|
||||
DefaultEditor = Reflections | Fog | Decals | DebugDraw | SSR | AO | GI | DirectionalLights | PointLights | SpotLights | SkyLights | Shadows | SpecularLight | AntiAliasing | CustomPostProcess | Bloom | ToneMapping | EyeAdaptation | CameraArtifacts | LensFlares | EditorSprites | ContactShadows | GlobalSDF,
|
||||
DefaultEditor = Reflections | Fog | Decals | DebugDraw | SSR | AO | GI | DirectionalLights | PointLights | SpotLights | SkyLights | Shadows | SpecularLight | AntiAliasing | CustomPostProcess | Bloom | ToneMapping | EyeAdaptation | CameraArtifacts | LensFlares | EditorSprites | ContactShadows | GlobalSDF | Sky,
|
||||
|
||||
/// <summary>
|
||||
/// Default flags for materials/models previews generating.
|
||||
/// </summary>
|
||||
DefaultAssetPreview = Reflections | Decals | DirectionalLights | PointLights | SpotLights | SkyLights | SpecularLight | AntiAliasing | Bloom | ToneMapping | EyeAdaptation | CameraArtifacts | LensFlares | ContactShadows,
|
||||
DefaultAssetPreview = Reflections | Decals | DirectionalLights | PointLights | SpotLights | SkyLights | SpecularLight | AntiAliasing | Bloom | ToneMapping | EyeAdaptation | CameraArtifacts | LensFlares | ContactShadows | Sky,
|
||||
};
|
||||
|
||||
DECLARE_ENUM_OPERATORS(ViewFlags);
|
||||
|
||||
@@ -315,6 +315,12 @@ public:
|
||||
/// <param name="rts">The array with render targets to bind.</param>
|
||||
API_FUNCTION() virtual void SetRenderTarget(GPUTextureView* depthBuffer, const Span<GPUTextureView*>& rts) = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the blend factor that modulate values for a pixel shader, render target, or both.
|
||||
/// </summary>
|
||||
/// <param name="value">Blend factors, one for each RGBA component.</param>
|
||||
API_FUNCTION() virtual void SetBlendFactor(const Float4& value) = 0;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Unbinds all shader resource slots and flushes the change with the driver (used to prevent driver detection of resource hazards, eg. when down-scaling the texture).
|
||||
|
||||
@@ -76,7 +76,7 @@ bool GPUPipelineState::Init(const Description& desc)
|
||||
Complexity += tessCost;
|
||||
if (desc.DepthWriteEnable)
|
||||
Complexity += 5;
|
||||
if (desc.DepthTestEnable)
|
||||
if (desc.DepthEnable)
|
||||
Complexity += 5;
|
||||
if (desc.BlendMode.BlendEnable)
|
||||
Complexity += 20;
|
||||
|
||||
@@ -134,7 +134,7 @@ public:
|
||||
/// <summary>
|
||||
/// Quad rendering shader
|
||||
/// </summary>
|
||||
GPUShader* QuadShader;
|
||||
API_FIELD(ReadOnly) GPUShader* QuadShader;
|
||||
|
||||
/// <summary>
|
||||
/// The current task being executed.
|
||||
|
||||
@@ -24,16 +24,16 @@ public:
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_NO_SPAWN(Description);
|
||||
|
||||
/// <summary>
|
||||
/// Enable/disable depth (DepthFunc and DepthWriteEnable)
|
||||
/// </summary>
|
||||
API_FIELD() bool DepthEnable;
|
||||
|
||||
/// <summary>
|
||||
/// Enable/disable depth write
|
||||
/// </summary>
|
||||
API_FIELD() bool DepthWriteEnable;
|
||||
|
||||
/// <summary>
|
||||
/// Enable/disable depth test
|
||||
/// </summary>
|
||||
API_FIELD() bool DepthTestEnable;
|
||||
|
||||
/// <summary>
|
||||
/// Enable/disable depth clipping
|
||||
/// </summary>
|
||||
|
||||
@@ -137,8 +137,13 @@ void DeferredMaterialShader::Unload()
|
||||
bool DeferredMaterialShader::Load()
|
||||
{
|
||||
auto psDesc = GPUPipelineState::Description::Default;
|
||||
psDesc.DepthTestEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthTest) == MaterialFeaturesFlags::None;
|
||||
psDesc.DepthWriteEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthWrite) == MaterialFeaturesFlags::None;
|
||||
if (EnumHasAnyFlags(_info.FeaturesFlags, MaterialFeaturesFlags::DisableDepthTest))
|
||||
{
|
||||
psDesc.DepthFunc = ComparisonFunc::Always;
|
||||
if (!psDesc.DepthWriteEnable)
|
||||
psDesc.DepthEnable = false;
|
||||
}
|
||||
|
||||
// Check if use tessellation (both material and runtime supports it)
|
||||
const bool useTess = _info.TessellationMode != TessellationMethod::None && GPUDevice::Instance->Limits.HasTessellation;
|
||||
@@ -183,7 +188,7 @@ bool DeferredMaterialShader::Load()
|
||||
|
||||
// Motion Vectors pass
|
||||
psDesc.DepthWriteEnable = false;
|
||||
psDesc.DepthTestEnable = true;
|
||||
psDesc.DepthEnable = true;
|
||||
psDesc.DepthFunc = ComparisonFunc::LessEqual;
|
||||
psDesc.VS = _shader->GetVS("VS");
|
||||
psDesc.PS = _shader->GetPS("PS_MotionVectors");
|
||||
@@ -201,7 +206,7 @@ bool DeferredMaterialShader::Load()
|
||||
psDesc.CullMode = CullMode::TwoSided;
|
||||
psDesc.DepthClipEnable = false;
|
||||
psDesc.DepthWriteEnable = true;
|
||||
psDesc.DepthTestEnable = true;
|
||||
psDesc.DepthEnable = true;
|
||||
psDesc.DepthFunc = ComparisonFunc::Less;
|
||||
psDesc.HS = nullptr;
|
||||
psDesc.DS = nullptr;
|
||||
|
||||
@@ -112,7 +112,7 @@ bool DeformableMaterialShader::Load()
|
||||
{
|
||||
_drawModes = DrawPass::Depth | DrawPass::QuadOverdraw;
|
||||
auto psDesc = GPUPipelineState::Description::Default;
|
||||
psDesc.DepthTestEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthTest) == MaterialFeaturesFlags::None;
|
||||
psDesc.DepthEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthTest) == MaterialFeaturesFlags::None;
|
||||
psDesc.DepthWriteEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthWrite) == MaterialFeaturesFlags::None;
|
||||
|
||||
// Check if use tessellation (both material and runtime supports it)
|
||||
@@ -170,7 +170,7 @@ bool DeformableMaterialShader::Load()
|
||||
psDesc.CullMode = CullMode::TwoSided;
|
||||
psDesc.DepthClipEnable = false;
|
||||
psDesc.DepthWriteEnable = true;
|
||||
psDesc.DepthTestEnable = true;
|
||||
psDesc.DepthEnable = true;
|
||||
psDesc.DepthFunc = ComparisonFunc::Less;
|
||||
psDesc.HS = nullptr;
|
||||
psDesc.DS = nullptr;
|
||||
|
||||
@@ -130,7 +130,7 @@ bool ForwardMaterialShader::Load()
|
||||
_drawModes = DrawPass::Depth | DrawPass::Forward | DrawPass::QuadOverdraw;
|
||||
|
||||
auto psDesc = GPUPipelineState::Description::Default;
|
||||
psDesc.DepthTestEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthTest) == MaterialFeaturesFlags::None;
|
||||
psDesc.DepthEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthTest) == MaterialFeaturesFlags::None;
|
||||
psDesc.DepthWriteEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthWrite) == MaterialFeaturesFlags::None;
|
||||
|
||||
// Check if use tessellation (both material and runtime supports it)
|
||||
@@ -200,7 +200,7 @@ bool ForwardMaterialShader::Load()
|
||||
psDesc.CullMode = CullMode::TwoSided;
|
||||
psDesc.DepthClipEnable = false;
|
||||
psDesc.DepthWriteEnable = true;
|
||||
psDesc.DepthTestEnable = true;
|
||||
psDesc.DepthEnable = true;
|
||||
psDesc.DepthFunc = ComparisonFunc::Less;
|
||||
psDesc.HS = nullptr;
|
||||
psDesc.DS = nullptr;
|
||||
|
||||
@@ -89,13 +89,13 @@ bool GUIMaterialShader::Load()
|
||||
psDesc0.PS = _shader->GetPS("PS_GUI");
|
||||
psDesc0.BlendMode = BlendingMode::AlphaBlend;
|
||||
|
||||
psDesc0.DepthTestEnable = psDesc0.DepthWriteEnable = true;
|
||||
psDesc0.DepthEnable = psDesc0.DepthWriteEnable = true;
|
||||
_cache.Depth = GPUDevice::Instance->CreatePipelineState();
|
||||
_cache.NoDepth = GPUDevice::Instance->CreatePipelineState();
|
||||
|
||||
bool failed = _cache.Depth->Init(psDesc0);
|
||||
|
||||
psDesc0.DepthTestEnable = psDesc0.DepthWriteEnable = false;
|
||||
psDesc0.DepthEnable = psDesc0.DepthWriteEnable = false;
|
||||
failed |= _cache.NoDepth->Init(psDesc0);
|
||||
|
||||
if (failed)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
/// <summary>
|
||||
/// Current materials shader version.
|
||||
/// </summary>
|
||||
#define MATERIAL_GRAPH_VERSION 159
|
||||
#define MATERIAL_GRAPH_VERSION 161
|
||||
|
||||
class Material;
|
||||
class GPUShader;
|
||||
|
||||
@@ -154,9 +154,6 @@ void ParticleMaterialShader::Bind(BindParameters& params)
|
||||
materialData->RibbonUVOffset.Y = drawCall.Particle.Ribbon.UVOffsetY;
|
||||
materialData->RibbonSegmentCount = drawCall.Particle.Ribbon.SegmentCount;
|
||||
|
||||
if (drawCall.Particle.Ribbon.SegmentDistances)
|
||||
context->BindSR(1, drawCall.Particle.Ribbon.SegmentDistances->View());
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -189,7 +186,7 @@ bool ParticleMaterialShader::Load()
|
||||
{
|
||||
_drawModes = DrawPass::Depth | DrawPass::Forward | DrawPass::QuadOverdraw;
|
||||
GPUPipelineState::Description psDesc = GPUPipelineState::Description::Default;
|
||||
psDesc.DepthTestEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthTest) == MaterialFeaturesFlags::None;
|
||||
psDesc.DepthEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthTest) == MaterialFeaturesFlags::None;
|
||||
psDesc.DepthWriteEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthWrite) == MaterialFeaturesFlags::None;
|
||||
|
||||
auto vsSprite = _shader->GetVS("VS_Sprite");
|
||||
|
||||
@@ -133,7 +133,7 @@ void TerrainMaterialShader::Unload()
|
||||
bool TerrainMaterialShader::Load()
|
||||
{
|
||||
GPUPipelineState::Description psDesc = GPUPipelineState::Description::Default;
|
||||
psDesc.DepthTestEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthTest) == MaterialFeaturesFlags::None;
|
||||
psDesc.DepthEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthTest) == MaterialFeaturesFlags::None;
|
||||
psDesc.DepthWriteEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthWrite) == MaterialFeaturesFlags::None;
|
||||
|
||||
// Check if use tessellation (both material and runtime supports it)
|
||||
@@ -182,7 +182,7 @@ bool TerrainMaterialShader::Load()
|
||||
psDesc.BlendMode = BlendingMode::Opaque;
|
||||
psDesc.DepthClipEnable = false;
|
||||
psDesc.DepthWriteEnable = true;
|
||||
psDesc.DepthTestEnable = true;
|
||||
psDesc.DepthEnable = true;
|
||||
psDesc.DepthFunc = ComparisonFunc::Less;
|
||||
psDesc.HS = nullptr;
|
||||
psDesc.DS = nullptr;
|
||||
|
||||
@@ -408,7 +408,7 @@ void Mesh::Render(GPUContext* context) const
|
||||
context->DrawIndexedInstanced(_triangles * 3, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
void Mesh::Draw(const RenderContext& renderContext, MaterialBase* material, const Matrix& world, StaticFlags flags, bool receiveDecals, DrawPass drawModes, float perInstanceRandom) const
|
||||
void Mesh::Draw(const RenderContext& renderContext, MaterialBase* material, const Matrix& world, StaticFlags flags, bool receiveDecals, DrawPass drawModes, float perInstanceRandom, int16 sortOrder) const
|
||||
{
|
||||
if (!material || !material->IsSurface() || !IsInitialized())
|
||||
return;
|
||||
@@ -446,7 +446,7 @@ void Mesh::Draw(const RenderContext& renderContext, MaterialBase* material, cons
|
||||
#endif
|
||||
|
||||
// Push draw call to the render list
|
||||
renderContext.List->AddDrawCall(renderContext, drawModes, flags, drawCall, receiveDecals);
|
||||
renderContext.List->AddDrawCall(renderContext, drawModes, flags, drawCall, receiveDecals, sortOrder);
|
||||
}
|
||||
|
||||
void Mesh::Draw(const RenderContext& renderContext, const DrawInfo& info, float lodDitherFactor) const
|
||||
@@ -512,7 +512,7 @@ void Mesh::Draw(const RenderContext& renderContext, const DrawInfo& info, float
|
||||
#endif
|
||||
|
||||
// Push draw call to the render list
|
||||
renderContext.List->AddDrawCall(renderContext, drawModes, info.Flags, drawCall, entry.ReceiveDecals);
|
||||
renderContext.List->AddDrawCall(renderContext, drawModes, info.Flags, drawCall, entry.ReceiveDecals, info.SortOrder);
|
||||
}
|
||||
|
||||
void Mesh::Draw(const RenderContextBatch& renderContextBatch, const DrawInfo& info, float lodDitherFactor) const
|
||||
@@ -575,7 +575,7 @@ void Mesh::Draw(const RenderContextBatch& renderContextBatch, const DrawInfo& in
|
||||
const auto shadowsMode = entry.ShadowsMode & slot.ShadowsMode;
|
||||
const auto drawModes = info.DrawModes & material->GetDrawModes();
|
||||
if (drawModes != DrawPass::None)
|
||||
renderContextBatch.GetMainContext().List->AddDrawCall(renderContextBatch, drawModes, info.Flags, shadowsMode, info.Bounds, drawCall, entry.ReceiveDecals);
|
||||
renderContextBatch.GetMainContext().List->AddDrawCall(renderContextBatch, drawModes, info.Flags, shadowsMode, info.Bounds, drawCall, entry.ReceiveDecals, info.SortOrder);
|
||||
}
|
||||
|
||||
bool Mesh::DownloadDataGPU(MeshBufferType type, BytesContainer& result) const
|
||||
|
||||
@@ -6,14 +6,11 @@
|
||||
#include "ModelInstanceEntry.h"
|
||||
#include "Config.h"
|
||||
#include "Types.h"
|
||||
#include "Engine/Level/Types.h"
|
||||
#if USE_PRECISE_MESH_INTERSECTS
|
||||
#include "CollisionProxy.h"
|
||||
#endif
|
||||
|
||||
struct GeometryDrawStateData;
|
||||
class Lightmap;
|
||||
class GPUBuffer;
|
||||
|
||||
/// <summary>
|
||||
/// Represents part of the model that is made of vertices and can be rendered using custom material and transformation.
|
||||
@@ -275,72 +272,6 @@ public:
|
||||
/// <param name="drawCall">The draw call.</param>
|
||||
void GetDrawCallGeometry(DrawCall& drawCall) const;
|
||||
|
||||
/// <summary>
|
||||
/// Model instance drawing packed data.
|
||||
/// </summary>
|
||||
struct DrawInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The instance buffer to use during model rendering.
|
||||
/// </summary>
|
||||
ModelInstanceEntries* Buffer;
|
||||
|
||||
/// <summary>
|
||||
/// The world transformation of the model.
|
||||
/// </summary>
|
||||
Matrix* World;
|
||||
|
||||
/// <summary>
|
||||
/// The instance drawing state data container. Used for LOD transition handling and previous world transformation matrix updating.
|
||||
/// </summary>
|
||||
GeometryDrawStateData* DrawState;
|
||||
|
||||
/// <summary>
|
||||
/// The lightmap.
|
||||
/// </summary>
|
||||
const Lightmap* Lightmap;
|
||||
|
||||
/// <summary>
|
||||
/// The lightmap UVs.
|
||||
/// </summary>
|
||||
const Rectangle* LightmapUVs;
|
||||
|
||||
/// <summary>
|
||||
/// The model instance vertex colors buffers (per-lod all meshes packed in a single allocation, array length equal to model lods count).
|
||||
/// </summary>
|
||||
GPUBuffer** VertexColors;
|
||||
|
||||
/// <summary>
|
||||
/// The object static flags.
|
||||
/// </summary>
|
||||
StaticFlags Flags;
|
||||
|
||||
/// <summary>
|
||||
/// The object draw modes.
|
||||
/// </summary>
|
||||
DrawPass DrawModes;
|
||||
|
||||
/// <summary>
|
||||
/// The bounds of the model (used to select a proper LOD during rendering).
|
||||
/// </summary>
|
||||
BoundingSphere Bounds;
|
||||
|
||||
/// <summary>
|
||||
/// The per-instance random value.
|
||||
/// </summary>
|
||||
float PerInstanceRandom;
|
||||
|
||||
/// <summary>
|
||||
/// The LOD bias value.
|
||||
/// </summary>
|
||||
char LODBias;
|
||||
|
||||
/// <summary>
|
||||
/// The forced LOD to use. Value -1 disables this feature.
|
||||
/// </summary>
|
||||
char ForcedLOD;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Draws the mesh. Binds vertex and index buffers and invokes the draw call.
|
||||
/// </summary>
|
||||
@@ -357,7 +288,8 @@ public:
|
||||
/// <param name="receiveDecals">True if rendered geometry can receive decals, otherwise false.</param>
|
||||
/// <param name="drawModes">The draw passes to use for rendering this object.</param>
|
||||
/// <param name="perInstanceRandom">The random per-instance value (normalized to range 0-1).</param>
|
||||
API_FUNCTION() void Draw(API_PARAM(Ref) const RenderContext& renderContext, MaterialBase* material, API_PARAM(Ref) const Matrix& world, StaticFlags flags = StaticFlags::None, bool receiveDecals = true, DrawPass drawModes = DrawPass::Default, float perInstanceRandom = 0.0f) const;
|
||||
/// <param name="sortOrder">Object sorting key.</param>
|
||||
API_FUNCTION() void Draw(API_PARAM(Ref) const RenderContext& renderContext, MaterialBase* material, API_PARAM(Ref) const Matrix& world, StaticFlags flags = StaticFlags::None, bool receiveDecals = true, DrawPass drawModes = DrawPass::Default, float perInstanceRandom = 0.0f, int16 sortOrder = 0) const;
|
||||
|
||||
/// <summary>
|
||||
/// Draws the mesh.
|
||||
|
||||
@@ -5,12 +5,20 @@
|
||||
#include "Engine/Core/Math/BoundingBox.h"
|
||||
#include "Engine/Core/Math/BoundingSphere.h"
|
||||
#include "Engine/Core/Types/DataContainer.h"
|
||||
#include "Engine/Graphics/Enums.h"
|
||||
#include "Engine/Graphics/Models/Types.h"
|
||||
#include "Engine/Level/Types.h"
|
||||
#include "Engine/Scripting/ScriptingObject.h"
|
||||
|
||||
struct GeometryDrawStateData;
|
||||
struct RenderContext;
|
||||
struct RenderContextBatch;
|
||||
class Task;
|
||||
class ModelBase;
|
||||
struct RenderContextBatch;
|
||||
class Lightmap;
|
||||
class GPUBuffer;
|
||||
class SkinnedMeshDrawData;
|
||||
class BlendShapesInstance;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for model resources meshes.
|
||||
@@ -143,4 +151,95 @@ public:
|
||||
/// <param name="count">The amount of items inside the result buffer.</param>
|
||||
/// <returns>True if failed, otherwise false</returns>
|
||||
virtual bool DownloadDataCPU(MeshBufferType type, BytesContainer& result, int32& count) const = 0;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Model instance drawing packed data.
|
||||
/// </summary>
|
||||
struct DrawInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The instance buffer to use during model rendering
|
||||
/// </summary>
|
||||
ModelInstanceEntries* Buffer;
|
||||
|
||||
/// <summary>
|
||||
/// The world transformation of the model.
|
||||
/// </summary>
|
||||
Matrix* World;
|
||||
|
||||
/// <summary>
|
||||
/// The instance drawing state data container. Used for LOD transition handling and previous world transformation matrix updating.
|
||||
/// </summary>
|
||||
GeometryDrawStateData* DrawState;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/// <summary>
|
||||
/// The skinning.
|
||||
/// </summary>
|
||||
SkinnedMeshDrawData* Skinning;
|
||||
|
||||
/// <summary>
|
||||
/// The blend shapes.
|
||||
/// </summary>
|
||||
BlendShapesInstance* BlendShapes;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
/// <summary>
|
||||
/// The lightmap.
|
||||
/// </summary>
|
||||
const Lightmap* Lightmap;
|
||||
|
||||
/// <summary>
|
||||
/// The lightmap UVs.
|
||||
/// </summary>
|
||||
const Rectangle* LightmapUVs;
|
||||
};
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The model instance vertex colors buffers (per-lod all meshes packed in a single allocation, array length equal to model lods count).
|
||||
/// </summary>
|
||||
GPUBuffer** VertexColors;
|
||||
|
||||
/// <summary>
|
||||
/// The object static flags.
|
||||
/// </summary>
|
||||
StaticFlags Flags;
|
||||
|
||||
/// <summary>
|
||||
/// The object draw modes.
|
||||
/// </summary>
|
||||
DrawPass DrawModes;
|
||||
|
||||
/// <summary>
|
||||
/// The bounds of the model (used to select a proper LOD during rendering).
|
||||
/// </summary>
|
||||
BoundingSphere Bounds;
|
||||
|
||||
/// <summary>
|
||||
/// The per-instance random value.
|
||||
/// </summary>
|
||||
float PerInstanceRandom;
|
||||
|
||||
/// <summary>
|
||||
/// The LOD bias value.
|
||||
/// </summary>
|
||||
char LODBias;
|
||||
|
||||
/// <summary>
|
||||
/// The forced LOD to use. Value -1 disables this feature.
|
||||
/// </summary>
|
||||
char ForcedLOD;
|
||||
|
||||
/// <summary>
|
||||
/// The object sorting key.
|
||||
/// </summary>
|
||||
int16 SortOrder;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -124,10 +124,8 @@ public:
|
||||
FORCE_INLINE void Render(GPUContext* context)
|
||||
{
|
||||
for (int32 i = 0; i < Meshes.Count(); i++)
|
||||
{
|
||||
Meshes.Get()[i].Render(context);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the meshes from the model LOD.
|
||||
@@ -139,12 +137,11 @@ public:
|
||||
/// <param name="receiveDecals">True if rendered geometry can receive decals, otherwise false.</param>
|
||||
/// <param name="drawModes">The draw passes to use for rendering this object.</param>
|
||||
/// <param name="perInstanceRandom">The random per-instance value (normalized to range 0-1).</param>
|
||||
API_FUNCTION() void Draw(API_PARAM(Ref) const RenderContext& renderContext, MaterialBase* material, API_PARAM(Ref) const Matrix& world, StaticFlags flags = StaticFlags::None, bool receiveDecals = true, DrawPass drawModes = DrawPass::Default, float perInstanceRandom = 0.0f) const
|
||||
/// <param name="sortOrder">Object sorting key.</param>
|
||||
API_FUNCTION() void Draw(API_PARAM(Ref) const RenderContext& renderContext, MaterialBase* material, API_PARAM(Ref) const Matrix& world, StaticFlags flags = StaticFlags::None, bool receiveDecals = true, DrawPass drawModes = DrawPass::Default, float perInstanceRandom = 0.0f, int16 sortOrder = 0) const
|
||||
{
|
||||
for (int32 i = 0; i < Meshes.Count(); i++)
|
||||
{
|
||||
Meshes.Get()[i].Draw(renderContext, material, world, flags, receiveDecals, drawModes, perInstanceRandom);
|
||||
}
|
||||
Meshes.Get()[i].Draw(renderContext, material, world, flags, receiveDecals, drawModes, perInstanceRandom, sortOrder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -156,10 +153,8 @@ public:
|
||||
FORCE_INLINE void Draw(const RenderContext& renderContext, const Mesh::DrawInfo& info, float lodDitherFactor) const
|
||||
{
|
||||
for (int32 i = 0; i < Meshes.Count(); i++)
|
||||
{
|
||||
Meshes.Get()[i].Draw(renderContext, info, lodDitherFactor);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws all the meshes from the model LOD.
|
||||
@@ -170,8 +165,6 @@ public:
|
||||
FORCE_INLINE void Draw(const RenderContextBatch& renderContextBatch, const Mesh::DrawInfo& info, float lodDitherFactor) const
|
||||
{
|
||||
for (int32 i = 0; i < Meshes.Count(); i++)
|
||||
{
|
||||
Meshes.Get()[i].Draw(renderContextBatch, info, lodDitherFactor);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -119,28 +119,22 @@ bool SkinnedMesh::UpdateMesh(uint32 vertexCount, uint32 triangleCount, VB0Skinne
|
||||
bool SkinnedMesh::Intersects(const Ray& ray, const Matrix& world, Real& distance, Vector3& normal) const
|
||||
{
|
||||
// Transform points
|
||||
Vector3 min, max;
|
||||
Vector3::Transform(_box.Minimum, world, min);
|
||||
Vector3::Transform(_box.Maximum, world, max);
|
||||
BoundingBox transformedBox;
|
||||
Vector3::Transform(_box.Minimum, world, transformedBox.Minimum);
|
||||
Vector3::Transform(_box.Maximum, world, transformedBox.Maximum);
|
||||
|
||||
// Get transformed box
|
||||
BoundingBox transformedBox(min, max);
|
||||
|
||||
// Test ray on a box
|
||||
// Test ray on a transformed box
|
||||
return transformedBox.Intersects(ray, distance, normal);
|
||||
}
|
||||
|
||||
bool SkinnedMesh::Intersects(const Ray& ray, const Transform& transform, Real& distance, Vector3& normal) const
|
||||
{
|
||||
// Transform points
|
||||
Vector3 min, max;
|
||||
transform.LocalToWorld(_box.Minimum, min);
|
||||
transform.LocalToWorld(_box.Maximum, max);
|
||||
BoundingBox transformedBox;
|
||||
transform.LocalToWorld(_box.Minimum, transformedBox.Minimum);
|
||||
transform.LocalToWorld(_box.Maximum, transformedBox.Maximum);
|
||||
|
||||
// Get transformed box
|
||||
BoundingBox transformedBox(min, max);
|
||||
|
||||
// Test ray on a box
|
||||
// Test ray on a transformed box
|
||||
return transformedBox.Intersects(ray, distance, normal);
|
||||
}
|
||||
|
||||
@@ -216,7 +210,7 @@ void SkinnedMesh::Draw(const RenderContext& renderContext, const DrawInfo& info,
|
||||
drawCall.PerInstanceRandom = info.PerInstanceRandom;
|
||||
|
||||
// Push draw call to the render list
|
||||
renderContext.List->AddDrawCall(renderContext, drawModes, StaticFlags::None, drawCall, entry.ReceiveDecals);
|
||||
renderContext.List->AddDrawCall(renderContext, drawModes, StaticFlags::None, drawCall, entry.ReceiveDecals, info.SortOrder);
|
||||
}
|
||||
|
||||
void SkinnedMesh::Draw(const RenderContextBatch& renderContextBatch, const DrawInfo& info, float lodDitherFactor) const
|
||||
@@ -279,7 +273,7 @@ void SkinnedMesh::Draw(const RenderContextBatch& renderContextBatch, const DrawI
|
||||
const auto shadowsMode = entry.ShadowsMode & slot.ShadowsMode;
|
||||
const auto drawModes = info.DrawModes & material->GetDrawModes();
|
||||
if (drawModes != DrawPass::None)
|
||||
renderContextBatch.GetMainContext().List->AddDrawCall(renderContextBatch, drawModes, StaticFlags::None, shadowsMode, info.Bounds, drawCall, entry.ReceiveDecals);
|
||||
renderContextBatch.GetMainContext().List->AddDrawCall(renderContextBatch, drawModes, StaticFlags::None, shadowsMode, info.Bounds, drawCall, entry.ReceiveDecals, info.SortOrder);
|
||||
}
|
||||
|
||||
bool SkinnedMesh::DownloadDataGPU(MeshBufferType type, BytesContainer& result) const
|
||||
|
||||
@@ -6,11 +6,6 @@
|
||||
#include "Types.h"
|
||||
#include "BlendShape.h"
|
||||
|
||||
struct GeometryDrawStateData;
|
||||
struct RenderContext;
|
||||
class GPUBuffer;
|
||||
class SkinnedMeshDrawData;
|
||||
|
||||
/// <summary>
|
||||
/// Represents part of the skinned model that is made of vertices and can be rendered using custom material, transformation and skeleton bones hierarchy.
|
||||
/// </summary>
|
||||
@@ -170,62 +165,6 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Model instance drawing packed data.
|
||||
/// </summary>
|
||||
struct DrawInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The instance buffer to use during model rendering
|
||||
/// </summary>
|
||||
ModelInstanceEntries* Buffer;
|
||||
|
||||
/// <summary>
|
||||
/// The skinning.
|
||||
/// </summary>
|
||||
SkinnedMeshDrawData* Skinning;
|
||||
|
||||
/// <summary>
|
||||
/// The blend shapes.
|
||||
/// </summary>
|
||||
BlendShapesInstance* BlendShapes;
|
||||
|
||||
/// <summary>
|
||||
/// The world transformation of the model.
|
||||
/// </summary>
|
||||
Matrix* World;
|
||||
|
||||
/// <summary>
|
||||
/// The instance drawing state data container. Used for LOD transition handling and previous world transformation matrix updating.
|
||||
/// </summary>
|
||||
GeometryDrawStateData* DrawState;
|
||||
|
||||
/// <summary>
|
||||
/// The object draw modes.
|
||||
/// </summary>
|
||||
DrawPass DrawModes;
|
||||
|
||||
/// <summary>
|
||||
/// The bounds of the model (used to select a proper LOD during rendering).
|
||||
/// </summary>
|
||||
BoundingSphere Bounds;
|
||||
|
||||
/// <summary>
|
||||
/// The per-instance random value.
|
||||
/// </summary>
|
||||
float PerInstanceRandom;
|
||||
|
||||
/// <summary>
|
||||
/// The LOD bias value.
|
||||
/// </summary>
|
||||
char LODBias;
|
||||
|
||||
/// <summary>
|
||||
/// The forced LOD to use. Value -1 disables this feature.
|
||||
/// </summary>
|
||||
char ForcedLOD;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Draws the mesh. Binds vertex and index buffers and invokes the draw call.
|
||||
/// </summary>
|
||||
|
||||
@@ -128,6 +128,8 @@ void RenderBuffers::SetUseAlpha(bool value)
|
||||
|
||||
const RenderBuffers::CustomBuffer* RenderBuffers::FindCustomBuffer(const StringView& name) const
|
||||
{
|
||||
if (LinkedCustomBuffers)
|
||||
return LinkedCustomBuffers->FindCustomBuffer(name);
|
||||
for (const CustomBuffer* e : CustomBuffers)
|
||||
{
|
||||
if (e->Name == name)
|
||||
@@ -196,6 +198,7 @@ bool RenderBuffers::Init(int32 width, int32 height)
|
||||
void RenderBuffers::Release()
|
||||
{
|
||||
LastEyeAdaptationTime = 0;
|
||||
LinkedCustomBuffers = nullptr;
|
||||
|
||||
for (int32 i = 0; i < _resources.Count(); i++)
|
||||
_resources[i]->ReleaseGPU();
|
||||
|
||||
@@ -45,10 +45,14 @@ public:
|
||||
{
|
||||
struct
|
||||
{
|
||||
GPUTexture* GBuffer0;
|
||||
GPUTexture* GBuffer1;
|
||||
GPUTexture* GBuffer2;
|
||||
GPUTexture* GBuffer3;
|
||||
/// <summary>Gets the GBuffer texture 0. RGB: Color, A: AO</summary>
|
||||
API_FIELD(ReadOnly) GPUTexture* GBuffer0;
|
||||
/// <summary>Gets the GBuffer texture 1. RGB: Normal, A: ShadingModel</summary>
|
||||
API_FIELD(ReadOnly) GPUTexture* GBuffer1;
|
||||
/// <summary>Gets the GBuffer texture 2. R: Roughness, G: Metalness, B:Specular</summary>
|
||||
API_FIELD(ReadOnly) GPUTexture* GBuffer2;
|
||||
/// <summary>Gets the GBuffer texture 3. RGBA: Custom Data</summary>
|
||||
API_FIELD(ReadOnly) GPUTexture* GBuffer3;
|
||||
};
|
||||
|
||||
GPUTexture* GBuffer[4];
|
||||
@@ -174,6 +178,8 @@ public:
|
||||
template<class T>
|
||||
T* GetCustomBuffer(const StringView& name)
|
||||
{
|
||||
if (LinkedCustomBuffers)
|
||||
return LinkedCustomBuffers->GetCustomBuffer<T>(name);
|
||||
CustomBuffer* result = (CustomBuffer*)FindCustomBuffer(name);
|
||||
if (!result)
|
||||
{
|
||||
@@ -202,6 +208,11 @@ public:
|
||||
/// </remarks>
|
||||
API_FIELD(ReadOnly) GPUTexture* MotionVectors;
|
||||
|
||||
/// <summary>
|
||||
/// External Render Buffers used to redirect FindCustomBuffer/GetCustomBuffer calls. Can be linked to other rendering task (eg. main game viewport) to reuse graphics effect state from it (eg. use GI from main game view in in-game camera renderer).
|
||||
/// </summary>
|
||||
API_FIELD() RenderBuffers* LinkedCustomBuffers = nullptr;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Allocates the buffers.
|
||||
|
||||
@@ -154,7 +154,7 @@ void SceneRenderTask::CameraCut()
|
||||
|
||||
void SceneRenderTask::AddCustomActor(Actor* actor)
|
||||
{
|
||||
CustomActors.Add(actor);
|
||||
CustomActors.AddUnique(actor);
|
||||
}
|
||||
|
||||
void SceneRenderTask::RemoveCustomActor(Actor* actor)
|
||||
@@ -169,7 +169,7 @@ void SceneRenderTask::ClearCustomActors()
|
||||
|
||||
void SceneRenderTask::AddCustomPostFx(PostProcessEffect* fx)
|
||||
{
|
||||
CustomPostFx.Add(fx);
|
||||
CustomPostFx.AddUnique(fx);
|
||||
}
|
||||
|
||||
void SceneRenderTask::RemoveCustomPostFx(PostProcessEffect* fx)
|
||||
@@ -179,7 +179,7 @@ void SceneRenderTask::RemoveCustomPostFx(PostProcessEffect* fx)
|
||||
|
||||
void SceneRenderTask::AddGlobalCustomPostFx(PostProcessEffect* fx)
|
||||
{
|
||||
GlobalCustomPostFx.Add(fx);
|
||||
GlobalCustomPostFx.AddUnique(fx);
|
||||
}
|
||||
|
||||
void SceneRenderTask::RemoveGlobalCustomPostFx(PostProcessEffect* fx)
|
||||
|
||||
@@ -181,116 +181,75 @@ uint32 GetHash(const BlendingMode& key)
|
||||
return hash;
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
|
||||
BlendingMode BlendingMode::Opaque =
|
||||
{
|
||||
false,
|
||||
// AlphaToCoverageEnable
|
||||
false,
|
||||
// BlendEnable
|
||||
Blend::One,
|
||||
// SrcBlend
|
||||
Blend::Zero,
|
||||
// DestBlend
|
||||
Operation::Add,
|
||||
// BlendOp
|
||||
Blend::One,
|
||||
// SrcBlendAlpha
|
||||
Blend::Zero,
|
||||
// DestBlendAlpha
|
||||
Operation::Add,
|
||||
// BlendOpAlpha
|
||||
ColorWrite::All,
|
||||
// RenderTargetWriteMask
|
||||
false, // AlphaToCoverageEnable
|
||||
false, // BlendEnable
|
||||
Blend::One, // SrcBlend
|
||||
Blend::Zero, // DestBlend
|
||||
Operation::Add, // BlendOp
|
||||
Blend::One, // SrcBlendAlpha
|
||||
Blend::Zero, // DestBlendAlpha
|
||||
Operation::Add, // BlendOpAlpha
|
||||
ColorWrite::All, // RenderTargetWriteMask
|
||||
};
|
||||
|
||||
BlendingMode BlendingMode::Additive =
|
||||
{
|
||||
false,
|
||||
// AlphaToCoverageEnable
|
||||
true,
|
||||
// BlendEnable
|
||||
Blend::SrcAlpha,
|
||||
// SrcBlend
|
||||
Blend::One,
|
||||
// DestBlend
|
||||
Operation::Add,
|
||||
// BlendOp
|
||||
Blend::SrcAlpha,
|
||||
// SrcBlendAlpha
|
||||
Blend::One,
|
||||
// DestBlendAlpha
|
||||
Operation::Add,
|
||||
// BlendOpAlpha
|
||||
ColorWrite::All,
|
||||
// RenderTargetWriteMask
|
||||
false, // AlphaToCoverageEnable
|
||||
true, // BlendEnable
|
||||
Blend::SrcAlpha, // SrcBlend
|
||||
Blend::One, // DestBlend
|
||||
Operation::Add, // BlendOp
|
||||
Blend::SrcAlpha, // SrcBlendAlpha
|
||||
Blend::One, // DestBlendAlpha
|
||||
Operation::Add, // BlendOpAlpha
|
||||
ColorWrite::All, // RenderTargetWriteMask
|
||||
};
|
||||
|
||||
BlendingMode BlendingMode::AlphaBlend =
|
||||
{
|
||||
false,
|
||||
// AlphaToCoverageEnable
|
||||
true,
|
||||
// BlendEnable
|
||||
Blend::SrcAlpha,
|
||||
// SrcBlend
|
||||
Blend::InvSrcAlpha,
|
||||
// DestBlend
|
||||
Operation::Add,
|
||||
// BlendOp
|
||||
Blend::One,
|
||||
// SrcBlendAlpha
|
||||
Blend::InvSrcAlpha,
|
||||
// DestBlendAlpha
|
||||
Operation::Add,
|
||||
// BlendOpAlpha
|
||||
ColorWrite::All,
|
||||
// RenderTargetWriteMask
|
||||
false, // AlphaToCoverageEnable
|
||||
true, // BlendEnable
|
||||
Blend::SrcAlpha, // SrcBlend
|
||||
Blend::InvSrcAlpha, // DestBlend
|
||||
Operation::Add, // BlendOp
|
||||
Blend::One, // SrcBlendAlpha
|
||||
Blend::InvSrcAlpha, // DestBlendAlpha
|
||||
Operation::Add, // BlendOpAlpha
|
||||
ColorWrite::All, // RenderTargetWriteMask
|
||||
};
|
||||
|
||||
BlendingMode BlendingMode::Add =
|
||||
{
|
||||
false,
|
||||
// AlphaToCoverageEnable
|
||||
true,
|
||||
// BlendEnable
|
||||
Blend::One,
|
||||
// SrcBlend
|
||||
Blend::One,
|
||||
// DestBlend
|
||||
Operation::Add,
|
||||
// BlendOp
|
||||
Blend::One,
|
||||
// SrcBlendAlpha
|
||||
Blend::One,
|
||||
// DestBlendAlpha
|
||||
Operation::Add,
|
||||
// BlendOpAlpha
|
||||
ColorWrite::All,
|
||||
// RenderTargetWriteMask
|
||||
false, // AlphaToCoverageEnable
|
||||
true, // BlendEnable
|
||||
Blend::One, // SrcBlend
|
||||
Blend::One, // DestBlend
|
||||
Operation::Add, // BlendOp
|
||||
Blend::One, // SrcBlendAlpha
|
||||
Blend::One, // DestBlendAlpha
|
||||
Operation::Add, // BlendOpAlpha
|
||||
ColorWrite::All, // RenderTargetWriteMask
|
||||
};
|
||||
|
||||
BlendingMode BlendingMode::Multiply =
|
||||
{
|
||||
false,
|
||||
// AlphaToCoverageEnable
|
||||
true,
|
||||
// BlendEnable
|
||||
Blend::Zero,
|
||||
// SrcBlend
|
||||
Blend::SrcColor,
|
||||
// DestBlend
|
||||
Operation::Add,
|
||||
// BlendOp
|
||||
Blend::Zero,
|
||||
// SrcBlendAlpha
|
||||
Blend::SrcAlpha,
|
||||
// DestBlendAlpha
|
||||
Operation::Add,
|
||||
// BlendOpAlpha
|
||||
ColorWrite::All,
|
||||
// RenderTargetWriteMask
|
||||
false, // AlphaToCoverageEnable
|
||||
true, // BlendEnable
|
||||
Blend::Zero, // SrcBlend
|
||||
Blend::SrcColor, // DestBlend
|
||||
Operation::Add, // BlendOp
|
||||
Blend::Zero, // SrcBlendAlpha
|
||||
Blend::SrcAlpha, // DestBlendAlpha
|
||||
Operation::Add, // BlendOpAlpha
|
||||
ColorWrite::All, // RenderTargetWriteMask
|
||||
};
|
||||
|
||||
// @formatter:on
|
||||
|
||||
FeatureLevel RenderTools::GetFeatureLevel(ShaderProfile profile)
|
||||
{
|
||||
switch (profile)
|
||||
|
||||
@@ -84,6 +84,14 @@ void RenderView::PrepareCache(const RenderContext& renderContext, float width, f
|
||||
MainScreenSize = mainView->ScreenSize;
|
||||
}
|
||||
|
||||
void RenderView::SetUp(const Matrix& viewProjection)
|
||||
{
|
||||
// Copy data
|
||||
Matrix::Invert(viewProjection, IVP);
|
||||
Frustum.SetMatrix(viewProjection);
|
||||
CullingFrustum = Frustum;
|
||||
}
|
||||
|
||||
void RenderView::SetUp(const Matrix& view, const Matrix& projection)
|
||||
{
|
||||
// Copy data
|
||||
|
||||
@@ -255,13 +255,7 @@ public:
|
||||
public:
|
||||
// Set up view with custom params
|
||||
// @param viewProjection View * Projection matrix
|
||||
void SetUp(const Matrix& viewProjection)
|
||||
{
|
||||
// Copy data
|
||||
Matrix::Invert(viewProjection, IVP);
|
||||
Frustum.SetMatrix(viewProjection);
|
||||
CullingFrustum = Frustum;
|
||||
}
|
||||
void SetUp(const Matrix& viewProjection);
|
||||
|
||||
// Set up view with custom params
|
||||
// @param view View matrix
|
||||
|
||||
@@ -103,6 +103,7 @@ void GPUContextDX11::FrameBegin()
|
||||
CurrentPS = nullptr;
|
||||
CurrentCS = nullptr;
|
||||
CurrentPrimitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
||||
CurrentBlendFactor = Float4::One;
|
||||
|
||||
// Bind static samplers
|
||||
ID3D11SamplerState* samplers[] =
|
||||
@@ -267,6 +268,13 @@ void GPUContextDX11::SetRenderTarget(GPUTextureView* depthBuffer, const Span<GPU
|
||||
}
|
||||
}
|
||||
|
||||
void GPUContextDX11::SetBlendFactor(const Float4& value)
|
||||
{
|
||||
CurrentBlendFactor = value;
|
||||
if (CurrentBlendState)
|
||||
_context->OMSetBlendState(CurrentBlendState, CurrentBlendFactor.Raw, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
}
|
||||
|
||||
void GPUContextDX11::ResetSR()
|
||||
{
|
||||
_srDirtyFlag = false;
|
||||
@@ -420,6 +428,7 @@ void GPUContextDX11::Dispatch(GPUShaderProgramCS* shader, uint32 threadGroupCoun
|
||||
|
||||
void GPUContextDX11::DispatchIndirect(GPUShaderProgramCS* shader, GPUBuffer* bufferForArgs, uint32 offsetForArgs)
|
||||
{
|
||||
ASSERT(bufferForArgs && EnumHasAnyFlags(bufferForArgs->GetFlags(), GPUBufferFlags::Argument));
|
||||
CurrentCS = (GPUShaderProgramCSDX11*)shader;
|
||||
|
||||
auto bufferForArgsDX11 = (GPUBufferDX11*)bufferForArgs;
|
||||
@@ -560,8 +569,7 @@ void GPUContextDX11::SetState(GPUPipelineState* state)
|
||||
if (CurrentBlendState != blendState)
|
||||
{
|
||||
CurrentBlendState = blendState;
|
||||
FLOAT blendFactor[4] = { 1, 1, 1, 1 };
|
||||
_context->OMSetBlendState(blendState, blendFactor, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
_context->OMSetBlendState(blendState, CurrentBlendFactor.Raw, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
}
|
||||
if (CurrentVS != vs)
|
||||
{
|
||||
|
||||
@@ -61,6 +61,7 @@ private:
|
||||
GPUShaderProgramPSDX11* CurrentPS;
|
||||
GPUShaderProgramCSDX11* CurrentCS;
|
||||
D3D11_PRIMITIVE_TOPOLOGY CurrentPrimitiveTopology;
|
||||
Float4 CurrentBlendFactor;
|
||||
|
||||
public:
|
||||
|
||||
@@ -115,6 +116,7 @@ public:
|
||||
void SetRenderTarget(GPUTextureView* rt) override;
|
||||
void SetRenderTarget(GPUTextureView* depthBuffer, GPUTextureView* rt) override;
|
||||
void SetRenderTarget(GPUTextureView* depthBuffer, const Span<GPUTextureView*>& rts) override;
|
||||
void SetBlendFactor(const Float4& value) override;
|
||||
void ResetSR() override;
|
||||
void ResetUA() override;
|
||||
void ResetCB() override;
|
||||
|
||||
@@ -48,7 +48,7 @@ bool GPUPipelineStateDX11::Init(const Description& desc)
|
||||
PrimitiveTopology = (D3D11_PRIMITIVE_TOPOLOGY)((int32)D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + (HS->GetControlPointsCount() - 1));
|
||||
|
||||
// States
|
||||
DepthStencilStateIndex = static_cast<int32>(desc.DepthFunc) + (desc.DepthTestEnable ? 0 : 9) + (desc.DepthWriteEnable ? 0 : 18);
|
||||
DepthStencilStateIndex = static_cast<int32>(desc.DepthFunc) + (desc.DepthEnable ? 0 : 9) + (desc.DepthWriteEnable ? 0 : 18);
|
||||
RasterizerStateIndex = static_cast<int32>(desc.CullMode) + (desc.Wireframe ? 0 : 3) + (desc.DepthClipEnable ? 0 : 6);
|
||||
BlendState = _device->GetBlendState(desc.BlendMode);
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ bool GPUBufferDX12::OnInit()
|
||||
if (useUAV)
|
||||
resourceDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
||||
#if PLATFORM_XBOX_SCARLETT || PLATFORM_XBOX_ONE
|
||||
if (_desc.Flags & GPUBufferFlags::Argument)
|
||||
if (EnumHasAnyFlags(_desc.Flags, GPUBufferFlags::Argument))
|
||||
resourceDesc.Flags |= D3D12XBOX_RESOURCE_FLAG_ALLOW_INDIRECT_BUFFER;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -845,6 +845,11 @@ void GPUContextDX12::SetRenderTarget(GPUTextureView* depthBuffer, const Span<GPU
|
||||
}
|
||||
}
|
||||
|
||||
void GPUContextDX12::SetBlendFactor(const Float4& value)
|
||||
{
|
||||
_commandList->OMSetBlendFactor(value.Raw);
|
||||
}
|
||||
|
||||
void GPUContextDX12::ResetSR()
|
||||
{
|
||||
for (int32 slot = 0; slot < GPU_MAX_SR_BINDED; slot++)
|
||||
|
||||
@@ -166,6 +166,7 @@ public:
|
||||
void SetRenderTarget(GPUTextureView* rt) override;
|
||||
void SetRenderTarget(GPUTextureView* depthBuffer, GPUTextureView* rt) override;
|
||||
void SetRenderTarget(GPUTextureView* depthBuffer, const Span<GPUTextureView*>& rts) override;
|
||||
void SetBlendFactor(const Float4& value) override;
|
||||
void ResetSR() override;
|
||||
void ResetUA() override;
|
||||
void ResetCB() override;
|
||||
|
||||
@@ -172,7 +172,7 @@ bool GPUPipelineStateDX12::Init(const Description& desc)
|
||||
}
|
||||
|
||||
// Depth State
|
||||
psDesc.DepthStencilState.DepthEnable = !!desc.DepthTestEnable;
|
||||
psDesc.DepthStencilState.DepthEnable = !!desc.DepthEnable;
|
||||
psDesc.DepthStencilState.DepthWriteMask = desc.DepthWriteEnable ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO;
|
||||
psDesc.DepthStencilState.DepthFunc = static_cast<D3D12_COMPARISON_FUNC>(desc.DepthFunc);
|
||||
psDesc.DepthStencilState.StencilEnable = FALSE;
|
||||
|
||||
@@ -84,6 +84,10 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
void SetBlendFactor(const Float4& value) override
|
||||
{
|
||||
}
|
||||
|
||||
void ResetSR() override
|
||||
{
|
||||
}
|
||||
|
||||
@@ -966,6 +966,12 @@ void GPUContextVulkan::SetRenderTarget(GPUTextureView* depthBuffer, const Span<G
|
||||
}
|
||||
}
|
||||
|
||||
void GPUContextVulkan::SetBlendFactor(const Float4& value)
|
||||
{
|
||||
const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer();
|
||||
vkCmdSetBlendConstants(cmdBuffer->GetHandle(), value.Raw);
|
||||
}
|
||||
|
||||
void GPUContextVulkan::ResetSR()
|
||||
{
|
||||
Platform::MemoryClear(_srHandles, sizeof(_srHandles));
|
||||
|
||||
@@ -184,6 +184,7 @@ public:
|
||||
void SetRenderTarget(GPUTextureView* rt) override;
|
||||
void SetRenderTarget(GPUTextureView* depthBuffer, GPUTextureView* rt) override;
|
||||
void SetRenderTarget(GPUTextureView* depthBuffer, const Span<GPUTextureView*>& rts) override;
|
||||
void SetBlendFactor(const Float4& value) override;
|
||||
void ResetSR() override;
|
||||
void ResetUA() override;
|
||||
void ResetCB() override;
|
||||
|
||||
@@ -286,7 +286,7 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
|
||||
|
||||
// Depth Stencil
|
||||
RenderToolsVulkan::ZeroStruct(_descDepthStencil, VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO);
|
||||
_descDepthStencil.depthTestEnable = desc.DepthTestEnable;
|
||||
_descDepthStencil.depthTestEnable = desc.DepthEnable;
|
||||
_descDepthStencil.depthWriteEnable = desc.DepthWriteEnable;
|
||||
_descDepthStencil.depthCompareOp = RenderToolsVulkan::ToVulkanCompareOp(desc.DepthFunc);
|
||||
_desc.pDepthStencilState = &_descDepthStencil;
|
||||
|
||||
@@ -31,6 +31,15 @@ void Gamepad::ResetState()
|
||||
_mappedPrevState.Clear();
|
||||
}
|
||||
|
||||
bool Gamepad::IsAnyButtonDown() const
|
||||
{
|
||||
// TODO: optimize with SIMD
|
||||
bool result = false;
|
||||
for (auto e : _state.Buttons)
|
||||
result |= e;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Gamepad::Update(EventQueue& queue)
|
||||
{
|
||||
// Copy state
|
||||
|
||||
@@ -164,6 +164,11 @@ public:
|
||||
return _mappedState.Buttons[static_cast<int32>(button)] && !_mappedPrevState.Buttons[static_cast<int32>(button)];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if any gamepad button is currently pressed.
|
||||
/// </summary>
|
||||
API_PROPERTY() bool IsAnyButtonDown() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the gamepad button up state (true if was released during the current frame).
|
||||
/// </summary>
|
||||
|
||||
@@ -183,6 +183,15 @@ void Mouse::OnMouseDown(const Float2& position, const MouseButton button, Window
|
||||
e.MouseData.Position = position;
|
||||
}
|
||||
|
||||
bool Mouse::IsAnyButtonDown() const
|
||||
{
|
||||
// TODO: optimize with SIMD
|
||||
bool result = false;
|
||||
for (auto e : Mouse::_state.MouseButtons)
|
||||
result |= e;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Mouse::OnMouseUp(const Float2& position, const MouseButton button, Window* target)
|
||||
{
|
||||
Event& e = _queue.AddOne();
|
||||
|
||||
@@ -64,6 +64,11 @@ public:
|
||||
return _state.MousePosition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if any mouse button is currently pressed.
|
||||
/// </summary>
|
||||
API_PROPERTY() bool IsAnyButtonDown() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the delta position of the mouse in the screen-space coordinates.
|
||||
/// </summary>
|
||||
|
||||
@@ -737,6 +737,7 @@ void AnimatedModel::Draw(RenderContext& renderContext)
|
||||
draw.PerInstanceRandom = GetPerInstanceRandom();
|
||||
draw.LODBias = LODBias;
|
||||
draw.ForcedLOD = ForcedLOD;
|
||||
draw.SortOrder = SortOrder;
|
||||
|
||||
SkinnedModel->Draw(renderContext, draw);
|
||||
}
|
||||
@@ -777,6 +778,7 @@ void AnimatedModel::Draw(RenderContextBatch& renderContextBatch)
|
||||
draw.PerInstanceRandom = GetPerInstanceRandom();
|
||||
draw.LODBias = LODBias;
|
||||
draw.ForcedLOD = ForcedLOD;
|
||||
draw.SortOrder = SortOrder;
|
||||
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
if (ShadowsMode != ShadowsCastingMode::All)
|
||||
@@ -851,6 +853,7 @@ void AnimatedModel::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
SERIALIZE(CustomBounds);
|
||||
SERIALIZE(LODBias);
|
||||
SERIALIZE(ForcedLOD);
|
||||
SERIALIZE(SortOrder);
|
||||
SERIALIZE(DrawModes);
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
SERIALIZE(ShadowsMode);
|
||||
@@ -877,6 +880,7 @@ void AnimatedModel::Deserialize(DeserializeStream& stream, ISerializeModifier* m
|
||||
DESERIALIZE(CustomBounds);
|
||||
DESERIALIZE(LODBias);
|
||||
DESERIALIZE(ForcedLOD);
|
||||
DESERIALIZE(SortOrder);
|
||||
DESERIALIZE(DrawModes);
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
DESERIALIZE(ShadowsMode);
|
||||
|
||||
@@ -138,6 +138,12 @@ public:
|
||||
API_FIELD(Attributes="EditorOrder(100), DefaultValue(DrawPass.Default), EditorDisplay(\"Skinned Model\")")
|
||||
DrawPass DrawModes = DrawPass::Default;
|
||||
|
||||
/// <summary>
|
||||
/// The object sort order key used when sorting drawable objects during rendering. Use lower values to draw object before others, higher values are rendered later (on top). Can be use to control transparency drawing.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorDisplay(\"Skinned Model\"), EditorOrder(110), DefaultValue(0)")
|
||||
int16 SortOrder = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The shadows casting mode.
|
||||
/// [Deprecated on 26.10.2022, expires on 26.10.2024]
|
||||
|
||||
@@ -297,6 +297,7 @@ void Camera::Draw(RenderContext& renderContext)
|
||||
draw.PerInstanceRandom = GetPerInstanceRandom();
|
||||
draw.LODBias = 0;
|
||||
draw.ForcedLOD = -1;
|
||||
draw.SortOrder = 0;
|
||||
draw.VertexColors = nullptr;
|
||||
if (draw.DrawModes != DrawPass::None)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user