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.
@@ -40,7 +40,7 @@ void PS_GBuffer(
|
||||
#if MATERIAL_MASKED
|
||||
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
|
||||
#endif
|
||||
|
||||
|
||||
#if USE_LIGHTMAP
|
||||
float3 diffuseColor = GetDiffuseColor(material.Color, material.Metalness);
|
||||
float3 specularColor = GetSpecularColor(material.Color, material.Specular, material.Metalness);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -594,7 +594,7 @@ void PS_Depth(PixelInput input)
|
||||
ClipLODTransition(input);
|
||||
#endif
|
||||
|
||||
#if MATERIAL_MASKED || MATERIAL_BLEND != MATERIAL_BLEND_OPAQUE
|
||||
#if MATERIAL_MASKED || MATERIAL_BLEND != MATERIAL_BLEND_OPAQUE
|
||||
// Get material parameters
|
||||
MaterialInput materialInput = GetMaterialInput(input);
|
||||
Material material = GetMaterialPS(materialInput);
|
||||
|
||||
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
|
||||
{
|
||||
_showBoundsButton = ViewWidgetShowMenu.AddButton("Bounds", () => ShowBounds = !ShowBounds);
|
||||
_showOriginButton = ViewWidgetShowMenu.AddButton("Origin", () => ShowOrigin = !ShowOrigin);
|
||||
_showParticleCounterButton = ViewWidgetShowMenu.AddButton("Particles Counter", () => ShowParticlesCounter = !ShowParticlesCounter);
|
||||
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,9 +124,7 @@ public:
|
||||
FORCE_INLINE void Render(GPUContext* context)
|
||||
{
|
||||
for (int32 i = 0; i < Meshes.Count(); i++)
|
||||
{
|
||||
Meshes.Get()[i].Render(context);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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,9 +153,7 @@ 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>
|
||||
@@ -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);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user