Compare commits
60 Commits
emscripten
...
signalgame
| Author | SHA1 | Date | |
|---|---|---|---|
| 1f265bddf4 | |||
| 3237849132 | |||
| 2be4d2b717 | |||
| dc3a1e142a | |||
| b6d375e9a3 | |||
| 495b6d6abc | |||
| a49b398c7f | |||
| c8e893d2ec | |||
| 3a665199e7 | |||
| ca1aa89ba1 | |||
| d92aaeb2b0 | |||
| 5f950cbb7e | |||
| 8f613774cb | |||
| c5c440469e | |||
| 1e6ed32c63 | |||
| 3ee6bffef7 | |||
| 6105323ecc | |||
| 23f8707927 | |||
| 761c8415dc | |||
|
|
cdeb9a3b15 | ||
|
|
60e8d73079 | ||
|
|
cf23892bd4 | ||
|
|
25f3cef8c3 | ||
|
|
00f2a0b825 | ||
|
|
7342629a86 | ||
|
|
5f860db6a5 | ||
|
|
6233718b06 | ||
|
|
62444315de | ||
|
|
a532ea7b42 | ||
|
|
803249f126 | ||
|
|
4e65b76b8c | ||
|
|
890b2da108 | ||
|
|
eac1d19a09 | ||
|
|
c4949de28f | ||
|
|
340ef194d3 | ||
|
|
b4547ec4d2 | ||
|
|
89f7e442f7 | ||
|
|
e7bef5e880 | ||
|
|
ff7c986fb1 | ||
|
|
708fba5136 | ||
|
|
7d92779e99 | ||
|
|
4c8528dcae | ||
|
|
3efd1e4e84 | ||
|
|
0cc6669cbd | ||
|
|
8bd409e95d | ||
|
|
3d0d41ebff | ||
|
|
61323f8526 | ||
|
|
017def29d4 | ||
|
|
13a04c2941 | ||
|
|
bc9cdf5cdb | ||
|
|
f7470af42d | ||
|
|
5c356ec22a | ||
|
|
06a35da0a8 | ||
|
|
55af307c43 | ||
|
|
4ab572426d | ||
|
|
01d91bf102 | ||
|
|
2dfb1058b2 | ||
|
|
cdbb2cc813 | ||
|
|
0e00f1e0eb | ||
|
|
d13621e631 |
@@ -1,4 +1,4 @@
|
||||
# Redirect to our own Git LFS server
|
||||
[lfs]
|
||||
url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
|
||||
locksverify = false
|
||||
#url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
|
||||
locksverify = false
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -16,7 +16,6 @@
|
||||
#include "./Flax/ExponentialHeightFog.hlsl"
|
||||
@2// Forward Shading: Constants
|
||||
LightData DirectionalLight;
|
||||
LightShadowData DirectionalLightShadow;
|
||||
LightData SkyLight;
|
||||
ProbeData EnvironmentProbe;
|
||||
ExponentialHeightFogData ExponentialHeightFog;
|
||||
@@ -26,9 +25,9 @@ LightData LocalLights[MAX_LOCAL_LIGHTS];
|
||||
@3// Forward Shading: Resources
|
||||
TextureCube EnvProbe : register(t__SRV__);
|
||||
TextureCube SkyLightTexture : register(t__SRV__);
|
||||
Texture2DArray DirectionalLightShadowMap : register(t__SRV__);
|
||||
Buffer<float4> ShadowsBuffer : register(t__SRV__);
|
||||
Texture2D<float> ShadowMap : register(t__SRV__);
|
||||
@4// Forward Shading: Utilities
|
||||
DECLARE_LIGHTSHADOWDATA_ACCESS(DirectionalLightShadow);
|
||||
@5// Forward Shading: Shaders
|
||||
|
||||
// Pixel Shader function for Forward Pass
|
||||
@@ -80,11 +79,8 @@ void PS_Forward(
|
||||
|
||||
// Calculate lighting from a single directional light
|
||||
float4 shadowMask = 1.0f;
|
||||
if (DirectionalLight.CastShadows > 0)
|
||||
{
|
||||
LightShadowData directionalLightShadowData = GetDirectionalLightShadowData();
|
||||
shadowMask.r = SampleShadow(DirectionalLight, directionalLightShadowData, DirectionalLightShadowMap, gBuffer, shadowMask.g);
|
||||
}
|
||||
ShadowSample shadow = SampleDirectionalLightShadow(DirectionalLight, ShadowsBuffer, ShadowMap, gBuffer);
|
||||
shadowMask = GetShadowMask(shadow);
|
||||
float4 light = GetLighting(ViewPos, DirectionalLight, gBuffer, shadowMask, false, false);
|
||||
|
||||
// Calculate lighting from sky light
|
||||
|
||||
@@ -26,7 +26,7 @@ struct RibbonInput
|
||||
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x4 WorldMatrix;
|
||||
float4x3 WorldMatrix;
|
||||
uint SortedIndicesOffset;
|
||||
float PerInstanceRandom;
|
||||
int ParticleStride;
|
||||
@@ -45,7 +45,7 @@ int RibbonWidthOffset;
|
||||
int RibbonTwistOffset;
|
||||
int RibbonFacingVectorOffset;
|
||||
uint RibbonSegmentCount;
|
||||
float4x4 WorldMatrixInverseTransposed;
|
||||
float4x3 WorldMatrixInverseTransposed;
|
||||
@1META_CB_END
|
||||
|
||||
// Particles attributes buffer
|
||||
@@ -138,7 +138,7 @@ MaterialInput GetMaterialInput(PixelInput input)
|
||||
#if USE_INSTANCING
|
||||
#define GetInstanceTransform(input) float4x4(float4(input.InstanceTransform1.xyz, 0.0f), float4(input.InstanceTransform2.xyz, 0.0f), float4(input.InstanceTransform3.xyz, 0.0f), float4(input.InstanceOrigin.xyz, 1.0f))
|
||||
#else
|
||||
#define GetInstanceTransform(input) WorldMatrix;
|
||||
#define GetInstanceTransform(input) ToMatrix4x4(WorldMatrix);
|
||||
#endif
|
||||
|
||||
// Removes the scale vector from the local to world transformation matrix (supports instancing)
|
||||
@@ -264,12 +264,12 @@ float4 GetParticleVec4(uint particleIndex, int offset)
|
||||
|
||||
float3 TransformParticlePosition(float3 input)
|
||||
{
|
||||
return mul(float4(input, 1.0f), WorldMatrix).xyz;
|
||||
return mul(float4(input, 1.0f), ToMatrix4x4(WorldMatrix)).xyz;
|
||||
}
|
||||
|
||||
float3 TransformParticleVector(float3 input)
|
||||
{
|
||||
return mul(float4(input, 0.0f), WorldMatrixInverseTransposed).xyz;
|
||||
return mul(float4(input, 0.0f), ToMatrix4x4(WorldMatrixInverseTransposed)).xyz;
|
||||
}
|
||||
|
||||
@8
|
||||
@@ -333,7 +333,7 @@ VertexOutput VS_Sprite(SpriteInput input, uint particleIndex : SV_InstanceID)
|
||||
float2 spriteSize = GetParticleVec2(particleIndex, SpriteSizeOffset);
|
||||
int spriteFacingMode = SpriteFacingModeOffset != -1 ? GetParticleInt(particleIndex, SpriteFacingModeOffset) : -1;
|
||||
|
||||
float4x4 world = WorldMatrix;
|
||||
float4x4 world = ToMatrix4x4(WorldMatrix);
|
||||
float3x3 eulerMatrix = EulerMatrix(radians(particleRotation));
|
||||
float3x3 viewRot = transpose((float3x3)ViewMatrix);
|
||||
float3 position = mul(float4(particlePosition, 1), world).xyz;
|
||||
@@ -463,11 +463,12 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
|
||||
}
|
||||
|
||||
// Read particle data
|
||||
float4x4 worldMatrix = ToMatrix4x4(WorldMatrix);
|
||||
float3 particlePosition = GetParticleVec3(particleIndex, PositionOffset);
|
||||
float3 particleScale = GetParticleVec3(particleIndex, ScaleOffset);
|
||||
float3 particleRotation = GetParticleVec3(particleIndex, RotationOffset);
|
||||
int modelFacingMode = ModelFacingModeOffset != -1 ? GetParticleInt(particleIndex, ModelFacingModeOffset) : -1;
|
||||
float3 position = mul(float4(particlePosition, 1), WorldMatrix).xyz;
|
||||
float3 position = mul(float4(particlePosition, 1), worldMatrix).xyz;
|
||||
|
||||
// Compute final vertex position in the world
|
||||
float3x3 eulerMatrix = EulerMatrix(radians(particleRotation));
|
||||
@@ -506,7 +507,7 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
|
||||
world = mul(world, scaleMatrix);
|
||||
}
|
||||
world = transpose(world);
|
||||
world = mul(world, WorldMatrix);
|
||||
world = mul(world, worldMatrix);
|
||||
|
||||
// Calculate the vertex position in world space
|
||||
output.WorldPosition = mul(float4(input.Position, 1), world).xyz;
|
||||
@@ -520,12 +521,12 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
|
||||
#if USE_VERTEX_COLOR
|
||||
output.VertexColor = input.Color;
|
||||
#endif
|
||||
output.InstanceOrigin = WorldMatrix[3].xyz;
|
||||
output.InstanceOrigin = worldMatrix[3].xyz;
|
||||
output.InstanceParams = PerInstanceRandom;
|
||||
|
||||
// Calculate tanget space to world space transformation matrix for unit vectors
|
||||
half3x3 tangentToLocal = CalcTangentToLocal(input);
|
||||
half3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
|
||||
half3x3 tangentToWorld = CalcTangentToWorld(worldMatrix, tangentToLocal);
|
||||
output.TBN = tangentToWorld;
|
||||
|
||||
// Get material input params if need to evaluate any material property
|
||||
@@ -625,12 +626,13 @@ VertexOutput VS_Ribbon(RibbonInput input, uint vertexIndex : SV_VertexID)
|
||||
#if USE_VERTEX_COLOR
|
||||
output.VertexColor = 1;
|
||||
#endif
|
||||
output.InstanceOrigin = WorldMatrix[3].xyz;
|
||||
float4x4 world = ToMatrix4x4(WorldMatrix);
|
||||
output.InstanceOrigin = world[3].xyz;
|
||||
output.InstanceParams = PerInstanceRandom;
|
||||
|
||||
// Calculate tanget space to world space transformation matrix for unit vectors
|
||||
half3x3 tangentToLocal = float3x3(tangentRight, tangentUp, cross(tangentRight, tangentUp));
|
||||
half3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
|
||||
half3x3 tangentToWorld = CalcTangentToWorld(world, tangentToLocal);
|
||||
output.TBN = tangentToWorld;
|
||||
|
||||
// Get material input params if need to evaluate any material property
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
@7
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x4 WorldMatrix;
|
||||
float4x4 PrevWorldMatrix;
|
||||
float4x3 WorldMatrix;
|
||||
float4x3 PrevWorldMatrix;
|
||||
float2 Dummy0;
|
||||
float LODDitherFactor;
|
||||
float PerInstanceRandom;
|
||||
@@ -171,7 +171,7 @@ MaterialInput GetMaterialInput(PixelInput input)
|
||||
#if USE_INSTANCING
|
||||
#define CalculateInstanceTransform(input) float4x4 world = GetInstanceTransform(input); output.Geometry.InstanceTransform1 = input.InstanceTransform1.xyz; output.Geometry.InstanceTransform2 = input.InstanceTransform2.xyz; output.Geometry.InstanceTransform3 = input.InstanceTransform3.xyz;
|
||||
#else
|
||||
#define CalculateInstanceTransform(input) float4x4 world = WorldMatrix; output.Geometry.InstanceTransform1 = world[0].xyz; output.Geometry.InstanceTransform2 = world[1].xyz; output.Geometry.InstanceTransform3 = world[2].xyz;
|
||||
#define CalculateInstanceTransform(input) float4x4 world = ToMatrix4x4(WorldMatrix); output.Geometry.InstanceTransform1 = world[0].xyz; output.Geometry.InstanceTransform2 = world[1].xyz; output.Geometry.InstanceTransform3 = world[2].xyz;
|
||||
#endif
|
||||
|
||||
// Removes the scale vector from the local to world transformation matrix (supports instancing)
|
||||
@@ -328,7 +328,7 @@ VertexOutput VS(ModelInput input)
|
||||
// Compute world space vertex position
|
||||
CalculateInstanceTransform(input);
|
||||
output.Geometry.WorldPosition = mul(float4(input.Position.xyz, 1), world).xyz;
|
||||
output.Geometry.PrevWorldPosition = mul(float4(input.Position.xyz, 1), PrevWorldMatrix).xyz;
|
||||
output.Geometry.PrevWorldPosition = mul(float4(input.Position.xyz, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
|
||||
|
||||
// Compute clip space position
|
||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||
@@ -402,7 +402,7 @@ float4 VS_Depth(ModelInput_PosOnly input) : SV_Position
|
||||
#if USE_INSTANCING
|
||||
float4x4 world = GetInstanceTransform(input);
|
||||
#else
|
||||
float4x4 world = WorldMatrix;
|
||||
float4x4 world = ToMatrix4x4(WorldMatrix);
|
||||
#endif
|
||||
float3 worldPosition = mul(float4(input.Position.xyz, 1), world).xyz;
|
||||
float4 position = mul(float4(worldPosition, 1), ViewProjectionMatrix);
|
||||
@@ -508,9 +508,9 @@ VertexOutput VS_Skinned(ModelInput_Skinned input)
|
||||
output.Geometry.WorldPosition = mul(float4(position, 1), world).xyz;
|
||||
#if PER_BONE_MOTION_BLUR
|
||||
float3 prevPosition = SkinPrevPosition(input);
|
||||
output.Geometry.PrevWorldPosition = mul(float4(prevPosition, 1), PrevWorldMatrix).xyz;
|
||||
output.Geometry.PrevWorldPosition = mul(float4(prevPosition, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
|
||||
#else
|
||||
output.Geometry.PrevWorldPosition = mul(float4(position, 1), PrevWorldMatrix).xyz;
|
||||
output.Geometry.PrevWorldPosition = mul(float4(position, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
|
||||
#endif
|
||||
|
||||
// Compute clip space position
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
@7
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x4 WorldMatrix;
|
||||
float4x3 WorldMatrix;
|
||||
float3 WorldInvScale;
|
||||
float WorldDeterminantSign;
|
||||
float PerInstanceRandom;
|
||||
@@ -194,7 +194,7 @@ float3 TransformViewVectorToWorld(MaterialInput input, float3 viewVector)
|
||||
// Transforms a vector from local space to world space
|
||||
float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
|
||||
{
|
||||
float3x3 localToWorld = (float3x3)WorldMatrix;
|
||||
float3x3 localToWorld = (float3x3)ToMatrix4x4(WorldMatrix);
|
||||
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
|
||||
return mul(localVector, localToWorld);
|
||||
}
|
||||
@@ -202,7 +202,7 @@ float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
|
||||
// Transforms a vector from local space to world space
|
||||
float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
|
||||
{
|
||||
float3x3 localToWorld = (float3x3)WorldMatrix;
|
||||
float3x3 localToWorld = (float3x3)ToMatrix4x4(WorldMatrix);
|
||||
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
|
||||
return mul(localToWorld, worldVector);
|
||||
}
|
||||
@@ -210,7 +210,7 @@ float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
|
||||
// Gets the current object position
|
||||
float3 GetObjectPosition(MaterialInput input)
|
||||
{
|
||||
return WorldMatrix[3].xyz;
|
||||
return ToMatrix4x4(WorldMatrix)[3].xyz;
|
||||
}
|
||||
|
||||
// Gets the current object size
|
||||
@@ -365,7 +365,8 @@ VertexOutput VS(TerrainVertexInput input)
|
||||
float3 position = float3(positionXZ.x, height, positionXZ.y);
|
||||
|
||||
// Compute world space vertex position
|
||||
output.Geometry.WorldPosition = mul(float4(position, 1), WorldMatrix).xyz;
|
||||
float4x4 worldMatrix = ToMatrix4x4(WorldMatrix);
|
||||
output.Geometry.WorldPosition = mul(float4(position, 1), worldMatrix).xyz;
|
||||
|
||||
// Compute clip space position
|
||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||
@@ -389,7 +390,7 @@ VertexOutput VS(TerrainVertexInput input)
|
||||
|
||||
// Compute world space normal vector
|
||||
float3x3 tangentToLocal = CalcTangentBasisFromWorldNormal(normal);
|
||||
float3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
|
||||
float3x3 tangentToWorld = CalcTangentToWorld(worldMatrix, tangentToLocal);
|
||||
output.Geometry.WorldNormal = tangentToWorld[2];
|
||||
|
||||
// Get material input params if need to evaluate any material property
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x4 InverseViewProjectionMatrix;
|
||||
float4x4 WorldMatrix;
|
||||
float4x4 WorldMatrixInverseTransposed;
|
||||
float4x3 WorldMatrix;
|
||||
float4x3 WorldMatrixInverseTransposed;
|
||||
float3 GridSize;
|
||||
float PerInstanceRandom;
|
||||
float Dummy0;
|
||||
@@ -49,7 +49,7 @@ struct MaterialInput
|
||||
#endif
|
||||
};
|
||||
|
||||
#define GetInstanceTransform(input) WorldMatrix;
|
||||
#define GetInstanceTransform(input) ToMatrix4x4(WorldMatrix);
|
||||
|
||||
// Removes the scale vector from the local to world transformation matrix (supports instancing)
|
||||
float3x3 RemoveScaleFromLocalToWorld(float3x3 localToWorld)
|
||||
@@ -170,12 +170,12 @@ float4 GetParticleVec4(uint particleIndex, int offset)
|
||||
|
||||
float3 TransformParticlePosition(float3 input)
|
||||
{
|
||||
return mul(float4(input, 1.0f), WorldMatrix).xyz;
|
||||
return mul(float4(input, 1.0f), ToMatrix4x4(WorldMatrix)).xyz;
|
||||
}
|
||||
|
||||
float3 TransformParticleVector(float3 input)
|
||||
{
|
||||
return mul(float4(input, 0.0f), WorldMatrixInverseTransposed).xyz;
|
||||
return mul(float4(input, 0.0f), ToMatrix4x4(WorldMatrixInverseTransposed)).xyz;
|
||||
}
|
||||
|
||||
@8
|
||||
@@ -219,7 +219,7 @@ void PS_VolumetricFog(Quad_GS2PS input, out float4 VBufferA : SV_Target0, out fl
|
||||
materialInput.ParticleIndex = ParticleIndex;
|
||||
materialInput.TBN = float3x3(float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1));
|
||||
materialInput.TwoSidedSign = 1.0f;
|
||||
materialInput.InstanceOrigin = WorldMatrix[3].xyz;
|
||||
materialInput.InstanceOrigin = ToMatrix4x4(WorldMatrix)[3].xyz;
|
||||
materialInput.InstanceParams = PerInstanceRandom;
|
||||
materialInput.SvPosition = clipPos;
|
||||
Material material = GetMaterialPS(materialInput);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/Shaders/Lights.flax
LFS
BIN
Content/Shaders/Lights.flax
LFS
Binary file not shown.
BIN
Content/Shaders/Quad.flax
LFS
BIN
Content/Shaders/Quad.flax
LFS
Binary file not shown.
BIN
Content/Shaders/Shadows.flax
LFS
BIN
Content/Shaders/Shadows.flax
LFS
Binary file not shown.
Binary file not shown.
@@ -2,9 +2,9 @@
|
||||
"Name": "Flax",
|
||||
"Version": {
|
||||
"Major": 1,
|
||||
"Minor": 8,
|
||||
"Revision": 1,
|
||||
"Build": 6511
|
||||
"Minor": 9,
|
||||
"Revision": 0,
|
||||
"Build": 6601
|
||||
},
|
||||
"Company": "Flax",
|
||||
"Copyright": "Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.",
|
||||
|
||||
@@ -377,6 +377,10 @@ namespace FlaxEditor.CustomEditors
|
||||
else if (Values.HasDefaultValue && CanRevertDefaultValue)
|
||||
color = Color.Yellow * 0.8f;
|
||||
LinkedLabel.HighlightStripColor = color;
|
||||
|
||||
// Grey out deprecated members
|
||||
if (Values.IsObsolete)
|
||||
LinkedLabel.TextColor = LinkedLabel.TextColorHighlighted = FlaxEngine.GUI.Style.Current.ForegroundGrey;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,7 +663,7 @@ namespace FlaxEditor.CustomEditors
|
||||
}
|
||||
}
|
||||
|
||||
if (obj == null || Values.Type.IsInstanceOfType(obj))
|
||||
if ((obj == null && !Values.Type.IsValueType) || Values.Type.IsInstanceOfType(obj))
|
||||
{
|
||||
result = obj;
|
||||
return true;
|
||||
@@ -671,20 +675,7 @@ namespace FlaxEditor.CustomEditors
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether can paste value from the system clipboard to the property value container.
|
||||
/// </summary>
|
||||
public bool CanPaste
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return GetClipboardObject(out _, false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
public bool CanPaste => !string.IsNullOrEmpty(Clipboard.Text);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value from the system clipboard.
|
||||
|
||||
@@ -474,32 +474,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
}
|
||||
if (layout.Editors.Count != 0)
|
||||
{
|
||||
var sb = Clipboard.Text;
|
||||
if (!string.IsNullOrEmpty(sb))
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = JsonSerializer.Deserialize<string[]>(sb);
|
||||
if (data == null || data.Length != layout.Editors.Count)
|
||||
return false;
|
||||
for (var i = 0; i < layout.Editors.Count; i++)
|
||||
{
|
||||
Clipboard.Text = data[i];
|
||||
if (!layout.Editors[i].CanPaste)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Clipboard.Text = sb;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return !string.IsNullOrEmpty(Clipboard.Text);
|
||||
}
|
||||
if (layout.Children.Any(x => x is LayoutElementsContainer))
|
||||
{
|
||||
|
||||
@@ -139,6 +139,11 @@ namespace FlaxEditor.CustomEditors
|
||||
/// </summary>
|
||||
public bool IsArray => Type != ScriptType.Null && Type.IsArray;
|
||||
|
||||
/// <summary>
|
||||
/// True if member or type has <see cref="System.ObsoleteAttribute"/> that marks it as obsolete.
|
||||
/// </summary>
|
||||
public bool IsObsolete { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the values types array (without duplicates).
|
||||
/// </summary>
|
||||
@@ -160,6 +165,7 @@ namespace FlaxEditor.CustomEditors
|
||||
{
|
||||
Info = info;
|
||||
Type = Info.ValueType;
|
||||
IsObsolete = Info.HasAttribute(typeof(ObsoleteAttribute), true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -175,13 +175,6 @@ namespace FlaxEditor.Options
|
||||
[EditorDisplay("Interface", "New Window Location"), EditorOrder(150), Tooltip("Define the opening method for new windows, open in a new tab by default.")]
|
||||
public DockStateProxy NewWindowLocation { get; set; } = DockStateProxy.Float;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the timestamps prefix mode for debug log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(TimestampsFormats.None)]
|
||||
[EditorDisplay("Interface"), EditorOrder(210), Tooltip("The timestamps prefix mode for debug log messages.")]
|
||||
public TimestampsFormats DebugLogTimestampsFormat { get; set; } = TimestampsFormats.None;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the editor icons scale. Editor restart required.
|
||||
/// </summary>
|
||||
@@ -211,23 +204,72 @@ namespace FlaxEditor.Options
|
||||
public bool SeparateValueAndUnit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the timestamps prefix mode for output log messages.
|
||||
/// Gets or sets the timestamps prefix mode for debug log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(TimestampsFormats.TimeSinceStartup)]
|
||||
[EditorDisplay("Output Log", "Timestamps Format"), EditorOrder(300), Tooltip("The timestamps prefix mode for output log messages.")]
|
||||
public TimestampsFormats OutputLogTimestampsFormat { get; set; } = TimestampsFormats.TimeSinceStartup;
|
||||
[DefaultValue(TimestampsFormats.None)]
|
||||
[EditorDisplay("Debug Log"), EditorOrder(300), Tooltip("The timestamps prefix mode for debug log messages.")]
|
||||
public TimestampsFormats DebugLogTimestampsFormat { get; set; } = TimestampsFormats.None;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the clear on play for debug log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Debug Log", "Clear on Play"), EditorOrder(310), Tooltip("Clears all log entries on enter playmode.")]
|
||||
public bool DebugLogClearOnPlay { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the collapse mode for debug log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Debug Log"), EditorOrder(312), Tooltip("Collapses similar or repeating log entries.")]
|
||||
public bool DebugLogCollapse { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the automatic pause on error for debug log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
[EditorDisplay("Debug Log", "Pause on Error"), EditorOrder(314), Tooltip("Performs auto pause on error.")]
|
||||
public bool DebugLogPauseOnError { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the automatic pause on error for debug log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Debug Log", "Show error messages"), EditorOrder(320), Tooltip("Shows/hides error messages.")]
|
||||
public bool DebugLogShowErrorMessages { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the automatic pause on error for debug log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Debug Log", "Show warning messages"), EditorOrder(322), Tooltip("Shows/hides warning messages.")]
|
||||
public bool DebugLogShowWarningMessages { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the automatic pause on error for debug log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Debug Log", "Show info messages"), EditorOrder(324), Tooltip("Shows/hides info messages.")]
|
||||
public bool DebugLogShowInfoMessages { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the timestamps prefix mode for output log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(TimestampsFormats.TimeSinceStartup)]
|
||||
[EditorDisplay("Output Log", "Timestamps Format"), EditorOrder(400), Tooltip("The timestamps prefix mode for output log messages.")]
|
||||
public TimestampsFormats OutputLogTimestampsFormat { get; set; } = TimestampsFormats.TimeSinceStartup;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the log type prefix mode for output log messages.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Output Log", "Show Log Type"), EditorOrder(310), Tooltip("Determines whether show log type prefix in output log messages.")]
|
||||
[EditorDisplay("Output Log", "Show Log Type"), EditorOrder(410), Tooltip("Determines whether show log type prefix in output log messages.")]
|
||||
public bool OutputLogShowLogType { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the output log text font.
|
||||
/// </summary>
|
||||
[EditorDisplay("Output Log", "Text Font"), EditorOrder(320), Tooltip("The output log text font.")]
|
||||
[EditorDisplay("Output Log", "Text Font"), EditorOrder(420), Tooltip("The output log text font.")]
|
||||
public FontReference OutputLogTextFont
|
||||
{
|
||||
get => _outputLogFont;
|
||||
@@ -246,63 +288,70 @@ namespace FlaxEditor.Options
|
||||
/// Gets or sets the output log text color.
|
||||
/// </summary>
|
||||
[DefaultValue(typeof(Color), "1,1,1,1")]
|
||||
[EditorDisplay("Output Log", "Text Color"), EditorOrder(330), Tooltip("The output log text color.")]
|
||||
[EditorDisplay("Output Log", "Text Color"), EditorOrder(430), Tooltip("The output log text color.")]
|
||||
public Color OutputLogTextColor { get; set; } = Color.White;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the output log text shadow color.
|
||||
/// </summary>
|
||||
[DefaultValue(typeof(Color), "0,0,0,0.5")]
|
||||
[EditorDisplay("Output Log", "Text Shadow Color"), EditorOrder(340), Tooltip("The output log text shadow color.")]
|
||||
[EditorDisplay("Output Log", "Text Shadow Color"), EditorOrder(440), Tooltip("The output log text shadow color.")]
|
||||
public Color OutputLogTextShadowColor { get; set; } = new Color(0, 0, 0, 0.5f);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the output log text shadow offset. Set to 0 to disable this feature.
|
||||
/// </summary>
|
||||
[DefaultValue(typeof(Float2), "1,1")]
|
||||
[EditorDisplay("Output Log", "Text Shadow Offset"), EditorOrder(340), Tooltip("The output log text shadow offset. Set to 0 to disable this feature.")]
|
||||
[EditorDisplay("Output Log", "Text Shadow Offset"), EditorOrder(445), Tooltip("The output log text shadow offset. Set to 0 to disable this feature.")]
|
||||
public Float2 OutputLogTextShadowOffset { get; set; } = new Float2(1);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether auto-focus output log window on code compilation error.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Output Log", "Focus Output Log On Compilation Error"), EditorOrder(350), Tooltip("Determines whether auto-focus output log window on code compilation error.")]
|
||||
[EditorDisplay("Output Log", "Focus Output Log On Compilation Error"), EditorOrder(450), Tooltip("Determines whether auto-focus output log window on code compilation error.")]
|
||||
public bool FocusOutputLogOnCompilationError { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether auto-focus output log window on game build error.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Output Log", "Focus Output Log On Game Build Error"), EditorOrder(360), Tooltip("Determines whether auto-focus output log window on game build error.")]
|
||||
[EditorDisplay("Output Log", "Focus Output Log On Game Build Error"), EditorOrder(460), Tooltip("Determines whether auto-focus output log window on game build error.")]
|
||||
public bool FocusOutputLogOnGameBuildError { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value for automatic scroll to bottom in output log.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Output Log", "Scroll to bottom"), EditorOrder(470), Tooltip("Scroll the output log view to bottom automatically after new lines are added.")]
|
||||
public bool OutputLogScrollToBottom { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether auto-focus game window on play mode start.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
[EditorDisplay("Play In-Editor", "Focus Game Window On Play"), EditorOrder(400), Tooltip("Determines whether auto-focus game window on play mode start.")]
|
||||
[EditorDisplay("Play In-Editor", "Focus Game Window On Play"), EditorOrder(500), Tooltip("Determines whether auto-focus game window on play mode start.")]
|
||||
public bool FocusGameWinOnPlay { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating what action should be taken upon pressing the play button.
|
||||
/// </summary>
|
||||
[DefaultValue(PlayAction.PlayScenes)]
|
||||
[EditorDisplay("Play In-Editor", "Play Button Action"), EditorOrder(410)]
|
||||
[EditorDisplay("Play In-Editor", "Play Button Action"), EditorOrder(510)]
|
||||
public PlayAction PlayButtonAction { get; set; } = PlayAction.PlayScenes;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating how the game window should be displayed when the game is launched.
|
||||
/// </summary>
|
||||
[DefaultValue(GameWindowMode.Docked)]
|
||||
[EditorDisplay("Play In-Editor", "Game Window Mode"), EditorOrder(420), Tooltip("Determines how the game window is displayed when the game is launched.")]
|
||||
[EditorDisplay("Play In-Editor", "Game Window Mode"), EditorOrder(520), Tooltip("Determines how the game window is displayed when the game is launched.")]
|
||||
public GameWindowMode DefaultGameWindowMode { get; set; } = GameWindowMode.Docked;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating the number of game clients to launch when building and/or running cooked game.
|
||||
/// </summary>
|
||||
[DefaultValue(1), Range(1, 4)]
|
||||
[EditorDisplay("Cook & Run"), EditorOrder(500)]
|
||||
[EditorDisplay("Cook & Run"), EditorOrder(600)]
|
||||
public int NumberOfGameClientsToLaunch = 1;
|
||||
|
||||
private static FontAsset DefaultFont => FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.PrimaryFont);
|
||||
@@ -317,13 +366,13 @@ namespace FlaxEditor.Options
|
||||
/// <summary>
|
||||
/// The list of fallback fonts to use when main text font is missing certain characters. Empty to use fonts from GraphicsSettings.
|
||||
/// </summary>
|
||||
[EditorDisplay("Fonts"), EditorOrder(650)]
|
||||
[EditorDisplay("Fonts"), EditorOrder(750)]
|
||||
public FontAsset[] FallbackFonts = new FontAsset[1] { FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.FallbackFont) };
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the title font for editor UI.
|
||||
/// </summary>
|
||||
[EditorDisplay("Fonts"), EditorOrder(600), Tooltip("The title font for editor UI.")]
|
||||
[EditorDisplay("Fonts"), EditorOrder(700), Tooltip("The title font for editor UI.")]
|
||||
public FontReference TitleFont
|
||||
{
|
||||
get => _titleFont;
|
||||
@@ -341,7 +390,7 @@ namespace FlaxEditor.Options
|
||||
/// <summary>
|
||||
/// Gets or sets the large font for editor UI.
|
||||
/// </summary>
|
||||
[EditorDisplay("Fonts"), EditorOrder(610), Tooltip("The large font for editor UI.")]
|
||||
[EditorDisplay("Fonts"), EditorOrder(710), Tooltip("The large font for editor UI.")]
|
||||
public FontReference LargeFont
|
||||
{
|
||||
get => _largeFont;
|
||||
@@ -359,7 +408,7 @@ namespace FlaxEditor.Options
|
||||
/// <summary>
|
||||
/// Gets or sets the medium font for editor UI.
|
||||
/// </summary>
|
||||
[EditorDisplay("Fonts"), EditorOrder(620), Tooltip("The medium font for editor UI.")]
|
||||
[EditorDisplay("Fonts"), EditorOrder(720), Tooltip("The medium font for editor UI.")]
|
||||
public FontReference MediumFont
|
||||
{
|
||||
get => _mediumFont;
|
||||
@@ -377,7 +426,7 @@ namespace FlaxEditor.Options
|
||||
/// <summary>
|
||||
/// Gets or sets the small font for editor UI.
|
||||
/// </summary>
|
||||
[EditorDisplay("Fonts"), EditorOrder(630), Tooltip("The small font for editor UI.")]
|
||||
[EditorDisplay("Fonts"), EditorOrder(730), Tooltip("The small font for editor UI.")]
|
||||
public FontReference SmallFont
|
||||
{
|
||||
get => _smallFont;
|
||||
|
||||
@@ -190,15 +190,7 @@ namespace FlaxEditor.Surface
|
||||
if (data == null || data.Length < 2)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
var model = JsonConvert.DeserializeObject<DataModel>(data);
|
||||
return model?.Nodes != null && model.Nodes.Length != 0;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -215,7 +207,15 @@ namespace FlaxEditor.Surface
|
||||
try
|
||||
{
|
||||
// Load Mr Json
|
||||
var model = FlaxEngine.Json.JsonSerializer.Deserialize<DataModel>(data);
|
||||
DataModel model;
|
||||
try
|
||||
{
|
||||
model = FlaxEngine.Json.JsonSerializer.Deserialize<DataModel>(data);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (model.Nodes == null)
|
||||
model.Nodes = new DataModelNode[0];
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
enum class PixelFormat : unsigned;
|
||||
enum class DirectorySearchOption;
|
||||
class TextureData;
|
||||
struct TextureData;
|
||||
|
||||
/// <summary>
|
||||
/// Helper functions for the editor.
|
||||
|
||||
@@ -471,7 +471,13 @@ namespace FlaxEditor.Viewport
|
||||
trans.SetRotation(ref world);
|
||||
trans.Translation += world.TranslationVector;
|
||||
}
|
||||
obj.Transform = trans;
|
||||
if (obj is ActorNode actorNode)
|
||||
{
|
||||
actorNode.Actor.Position = trans.Translation;
|
||||
actorNode.Actor.Orientation = trans.Orientation;
|
||||
}
|
||||
else
|
||||
obj.Transform = trans;
|
||||
}
|
||||
TransformGizmo.EndTransforming();
|
||||
}
|
||||
@@ -520,7 +526,9 @@ namespace FlaxEditor.Viewport
|
||||
/// <param name="scaleDelta">The scale delta.</param>
|
||||
public void ApplyTransform(List<SceneGraphNode> selection, ref Vector3 translationDelta, ref Quaternion rotationDelta, ref Vector3 scaleDelta)
|
||||
{
|
||||
bool applyTranslation = !translationDelta.IsZero;
|
||||
bool applyRotation = !rotationDelta.IsIdentity;
|
||||
bool applyScale = !scaleDelta.IsZero;
|
||||
bool useObjCenter = TransformGizmo.ActivePivot == TransformGizmoBase.PivotType.ObjectCenter;
|
||||
Vector3 gizmoPosition = TransformGizmo.Position;
|
||||
|
||||
@@ -555,13 +563,29 @@ namespace FlaxEditor.Viewport
|
||||
}
|
||||
|
||||
// Apply scale
|
||||
const float scaleLimit = 99_999_999.0f;
|
||||
trans.Scale = Float3.Clamp(trans.Scale + scaleDelta, new Float3(-scaleLimit), new Float3(scaleLimit));
|
||||
if (applyScale)
|
||||
{
|
||||
const float scaleLimit = 99_999_999.0f;
|
||||
trans.Scale = Float3.Clamp(trans.Scale + scaleDelta, new Float3(-scaleLimit), new Float3(scaleLimit)); ;
|
||||
}
|
||||
|
||||
// Apply translation
|
||||
trans.Translation += translationDelta;
|
||||
if (applyTranslation)
|
||||
{
|
||||
trans.Translation += translationDelta;
|
||||
}
|
||||
|
||||
obj.Transform = trans;
|
||||
if (obj is ActorNode actorNode)
|
||||
{
|
||||
if (applyTranslation)
|
||||
actorNode.Actor.Position = trans.Translation;
|
||||
if (applyRotation)
|
||||
actorNode.Actor.Orientation = trans.Orientation;
|
||||
if (applyScale)
|
||||
actorNode.Actor.Scale = trans.Scale;
|
||||
}
|
||||
else
|
||||
obj.Transform = trans;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -357,7 +357,9 @@ namespace FlaxEditor.Viewport
|
||||
/// <param name="scaleDelta">The scale delta.</param>
|
||||
public void ApplyTransform(List<SceneGraphNode> selection, ref Vector3 translationDelta, ref Quaternion rotationDelta, ref Vector3 scaleDelta)
|
||||
{
|
||||
bool applyTranslation = !translationDelta.IsZero;
|
||||
bool applyRotation = !rotationDelta.IsIdentity;
|
||||
bool applyScale = !scaleDelta.IsZero;
|
||||
bool useObjCenter = TransformGizmo.ActivePivot == TransformGizmoBase.PivotType.ObjectCenter;
|
||||
Vector3 gizmoPosition = TransformGizmo.Position;
|
||||
|
||||
@@ -387,13 +389,29 @@ namespace FlaxEditor.Viewport
|
||||
}
|
||||
|
||||
// Apply scale
|
||||
const float scaleLimit = 99_999_999.0f;
|
||||
trans.Scale = Float3.Clamp(trans.Scale + scaleDelta, new Float3(-scaleLimit), new Float3(scaleLimit));
|
||||
if (applyScale)
|
||||
{
|
||||
const float scaleLimit = 99_999_999.0f;
|
||||
trans.Scale = Float3.Clamp(trans.Scale + scaleDelta, new Float3(-scaleLimit), new Float3(scaleLimit));
|
||||
}
|
||||
|
||||
// Apply translation
|
||||
trans.Translation += translationDelta;
|
||||
if (applyTranslation)
|
||||
{
|
||||
trans.Translation += translationDelta;
|
||||
}
|
||||
|
||||
obj.Transform = trans;
|
||||
if (obj is ActorNode actorNode)
|
||||
{
|
||||
if (applyTranslation)
|
||||
actorNode.Actor.Position = trans.Translation;
|
||||
if (applyRotation)
|
||||
actorNode.Actor.Orientation = trans.Orientation;
|
||||
if (applyScale)
|
||||
actorNode.Actor.Scale = trans.Scale;
|
||||
}
|
||||
else
|
||||
obj.Transform = trans;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -318,7 +318,6 @@ namespace FlaxEditor.Windows
|
||||
{
|
||||
Title = "Debug Log";
|
||||
Icon = IconInfo;
|
||||
OnEditorOptionsChanged(Editor.Options.Options);
|
||||
FlaxEditor.Utilities.Utils.SetupCommonInputActions(this);
|
||||
|
||||
// Toolstrip
|
||||
@@ -327,14 +326,42 @@ namespace FlaxEditor.Windows
|
||||
Parent = this,
|
||||
};
|
||||
toolstrip.AddButton("Clear", Clear).LinkTooltip("Clears all log entries");
|
||||
_clearOnPlayButton = (ToolStripButton)toolstrip.AddButton("Clear on Play").SetAutoCheck(true).SetChecked(true).LinkTooltip("Clears all log entries on enter playmode");
|
||||
_collapseLogsButton = (ToolStripButton)toolstrip.AddButton("Collapse").SetAutoCheck(true).SetChecked(true).LinkTooltip("Collapses similar logs.");
|
||||
_pauseOnErrorButton = (ToolStripButton)toolstrip.AddButton("Pause on Error").SetAutoCheck(true).LinkTooltip("Performs auto pause on error");
|
||||
_clearOnPlayButton = (ToolStripButton)toolstrip.AddButton("Clear on Play", () =>
|
||||
{
|
||||
editor.Options.Options.Interface.DebugLogClearOnPlay = _clearOnPlayButton.Checked;
|
||||
editor.Options.Apply(editor.Options.Options);
|
||||
}).SetAutoCheck(true).LinkTooltip("Clears all log entries on enter playmode");
|
||||
_collapseLogsButton = (ToolStripButton)toolstrip.AddButton("Collapse", () =>
|
||||
{
|
||||
editor.Options.Options.Interface.DebugLogCollapse = _collapseLogsButton.Checked;
|
||||
editor.Options.Apply(editor.Options.Options);
|
||||
}).SetAutoCheck(true).LinkTooltip("Collapses similar logs.");
|
||||
_pauseOnErrorButton = (ToolStripButton)toolstrip.AddButton("Pause on Error", () =>
|
||||
{
|
||||
editor.Options.Options.Interface.DebugLogPauseOnError = _pauseOnErrorButton.Checked;
|
||||
editor.Options.Apply(editor.Options.Options);
|
||||
}).SetAutoCheck(true).LinkTooltip("Performs auto pause on error");
|
||||
toolstrip.AddSeparator();
|
||||
_groupButtons[0] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Error32, () => UpdateLogTypeVisibility(LogGroup.Error, _groupButtons[0].Checked)).SetAutoCheck(true).SetChecked(true).LinkTooltip("Shows/hides error messages");
|
||||
_groupButtons[1] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Warning32, () => UpdateLogTypeVisibility(LogGroup.Warning, _groupButtons[1].Checked)).SetAutoCheck(true).SetChecked(true).LinkTooltip("Shows/hides warning messages");
|
||||
_groupButtons[2] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Info32, () => UpdateLogTypeVisibility(LogGroup.Info, _groupButtons[2].Checked)).SetAutoCheck(true).SetChecked(true).LinkTooltip("Shows/hides info messages");
|
||||
_groupButtons[0] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Error32, () =>
|
||||
{
|
||||
UpdateLogTypeVisibility(LogGroup.Error, _groupButtons[0].Checked);
|
||||
editor.Options.Options.Interface.DebugLogShowErrorMessages = _groupButtons[0].Checked;
|
||||
editor.Options.Apply(editor.Options.Options);
|
||||
}).SetAutoCheck(true).LinkTooltip("Shows/hides error messages");
|
||||
_groupButtons[1] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Warning32, () =>
|
||||
{
|
||||
UpdateLogTypeVisibility(LogGroup.Warning, _groupButtons[1].Checked);
|
||||
editor.Options.Options.Interface.DebugLogShowWarningMessages = _groupButtons[1].Checked;
|
||||
editor.Options.Apply(editor.Options.Options);
|
||||
}).SetAutoCheck(true).LinkTooltip("Shows/hides warning messages");
|
||||
_groupButtons[2] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Info32, () =>
|
||||
{
|
||||
UpdateLogTypeVisibility(LogGroup.Info, _groupButtons[2].Checked);
|
||||
editor.Options.Options.Interface.DebugLogShowInfoMessages = _groupButtons[2].Checked;
|
||||
editor.Options.Apply(editor.Options.Options);
|
||||
}).SetAutoCheck(true).LinkTooltip("Shows/hides info messages");
|
||||
UpdateCount();
|
||||
OnEditorOptionsChanged(Editor.Options.Options);
|
||||
|
||||
// Split panel
|
||||
_split = new SplitPanel(Orientation.Vertical, ScrollBars.Vertical, ScrollBars.Both)
|
||||
@@ -380,6 +407,12 @@ namespace FlaxEditor.Windows
|
||||
private void OnEditorOptionsChanged(EditorOptions options)
|
||||
{
|
||||
_timestampsFormats = options.Interface.DebugLogTimestampsFormat;
|
||||
_clearOnPlayButton.Checked = options.Interface.DebugLogClearOnPlay;
|
||||
_collapseLogsButton.Checked = options.Interface.DebugLogCollapse;
|
||||
_pauseOnErrorButton.Checked = options.Interface.DebugLogPauseOnError;
|
||||
_groupButtons[0].Checked = options.Interface.DebugLogShowErrorMessages;
|
||||
_groupButtons[1].Checked = options.Interface.DebugLogShowWarningMessages;
|
||||
_groupButtons[2].Checked = options.Interface.DebugLogShowInfoMessages;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -162,7 +162,7 @@ namespace FlaxEditor.Windows
|
||||
|
||||
Editor.Options.Apply(_options);
|
||||
|
||||
ClearDirtyFlag();
|
||||
GatherData();
|
||||
}
|
||||
|
||||
private void SetupCustomTabs()
|
||||
@@ -234,6 +234,18 @@ namespace FlaxEditor.Windows
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnShow()
|
||||
{
|
||||
if (!_isDataDirty)
|
||||
{
|
||||
// Refresh the data, skip when data is modified during window docking
|
||||
GatherData();
|
||||
}
|
||||
|
||||
base.OnShow();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool OnClosing(ClosingReason reason)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using FlaxEditor.CustomEditors;
|
||||
using FlaxEngine;
|
||||
@@ -96,14 +95,6 @@ namespace FlaxEditor.Windows
|
||||
set => Graphics.ShadowMapsQuality = value;
|
||||
}
|
||||
|
||||
[DefaultValue(false)]
|
||||
[EditorOrder(1320), EditorDisplay("Quality", "Allow CSM Blending"), Tooltip("Enables cascades splits blending for directional light shadows.")]
|
||||
public bool AllowCSMBlending
|
||||
{
|
||||
get => Graphics.AllowCSMBlending;
|
||||
set => Graphics.AllowCSMBlending = value;
|
||||
}
|
||||
|
||||
[NoSerialize, DefaultValue(1.0f), Limit(0.05f, 5, 0)]
|
||||
[EditorOrder(1400), EditorDisplay("Quality")]
|
||||
[Tooltip("The scale of the rendering resolution relative to the output dimensions. If lower than 1 the scene and postprocessing will be rendered at a lower resolution and upscaled to the output backbuffer.")]
|
||||
|
||||
@@ -526,7 +526,7 @@ namespace FlaxEditor.Windows.Profiler
|
||||
}
|
||||
row.Depth = e.Depth;
|
||||
row.Width = _table.Width;
|
||||
row.Visible = e.Depth < 2;
|
||||
row.Visible = e.Depth < 10;
|
||||
row.BackgroundColor = i % 2 == 0 ? rowColor2 : Color.Transparent;
|
||||
row.Parent = _table;
|
||||
}
|
||||
|
||||
@@ -370,7 +370,7 @@ namespace FlaxEditor.Windows.Profiler
|
||||
}
|
||||
row.Depth = e.Depth;
|
||||
row.Width = _table.Width;
|
||||
row.Visible = e.Depth < 3;
|
||||
row.Visible = e.Depth < 13;
|
||||
row.BackgroundColor = i % 2 == 0 ? rowColor2 : Color.Transparent;
|
||||
row.Parent = _table;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.InteropServices.Marshalling;
|
||||
using FlaxEngine.Interop;
|
||||
|
||||
namespace FlaxEngine
|
||||
{
|
||||
|
||||
@@ -428,23 +428,23 @@ void AudioSource::Update()
|
||||
// Handle streaming buffers queue submit (ensure that clip has loaded the first chunk with audio data)
|
||||
if (_needToUpdateStreamingBuffers && clip->Buffers[_streamingFirstChunk] != AUDIO_BUFFER_ID_INVALID)
|
||||
{
|
||||
// Clear flag
|
||||
_needToUpdateStreamingBuffers = false;
|
||||
|
||||
// Get buffers in a queue count
|
||||
int32 numQueuedBuffers;
|
||||
AudioBackend::Source::GetQueuedBuffersCount(this, numQueuedBuffers);
|
||||
|
||||
// Queue missing buffers
|
||||
// Queue missing buffers, make sure there is at least two buffers in queue to avoid gaps in playback
|
||||
uint32 bufferId;
|
||||
if (numQueuedBuffers < 1 && (bufferId = clip->Buffers[_streamingFirstChunk]) != AUDIO_BUFFER_ID_INVALID)
|
||||
for (int i = numQueuedBuffers; i < 2; i++)
|
||||
{
|
||||
AudioBackend::Source::QueueBuffer(this, bufferId);
|
||||
int bufferIndex = (_streamingFirstChunk + i) % clip->Buffers.Count();
|
||||
if ((bufferId = clip->Buffers[bufferIndex]) != AUDIO_BUFFER_ID_INVALID)
|
||||
AudioBackend::Source::QueueBuffer(this, bufferId);
|
||||
else
|
||||
_needToUpdateStreamingBuffers = true; // The buffer has not been streamed yet, try again later
|
||||
}
|
||||
if (numQueuedBuffers < 2 && _streamingFirstChunk + 1 < clip->Buffers.Count() && (bufferId = clip->Buffers[_streamingFirstChunk + 1]) != AUDIO_BUFFER_ID_INVALID)
|
||||
{
|
||||
AudioBackend::Source::QueueBuffer(this, bufferId);
|
||||
}
|
||||
|
||||
// Clear flag
|
||||
_needToUpdateStreamingBuffers = false;
|
||||
|
||||
// Play it if need to
|
||||
if (!_isActuallyPlayingSth)
|
||||
@@ -469,18 +469,25 @@ void AudioSource::Update()
|
||||
// Move the chunk pointer (AudioStreamingHandler will request new chunks streaming)
|
||||
_streamingFirstChunk += numProcessedBuffers;
|
||||
|
||||
if (GetIsLooping())
|
||||
{
|
||||
int32 numQueuedBuffers;
|
||||
AudioBackend::Source::GetQueuedBuffersCount(this, numQueuedBuffers);
|
||||
if (numQueuedBuffers < 1)
|
||||
{
|
||||
// Audio engine unexpectedly stopped playing the clip after queue emptied, restart the clip
|
||||
_isActuallyPlayingSth = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if reached the end
|
||||
if (_streamingFirstChunk >= clip->Buffers.Count())
|
||||
{
|
||||
// Loop over the clip or end play
|
||||
if (GetIsLooping())
|
||||
{
|
||||
// Move to the begin
|
||||
// Move to the beginning
|
||||
_streamingFirstChunk = 0;
|
||||
|
||||
// Stop audio and request buffers re-sync and then play continue
|
||||
Stop();
|
||||
Play();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -686,8 +686,6 @@ void AudioBackendXAudio2::Source_DequeueProcessedBuffers(AudioSource* source)
|
||||
auto aSource = XAudio2::GetSource(source);
|
||||
if (aSource && aSource->Voice)
|
||||
{
|
||||
const HRESULT hr = aSource->Voice->FlushSourceBuffers();
|
||||
XAUDIO2_CHECK_ERROR(FlushSourceBuffers);
|
||||
aSource->BuffersProcessed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1336,6 +1336,11 @@ FileReadStream* FlaxStorage::OpenFile()
|
||||
|
||||
bool FlaxStorage::CloseFileHandles()
|
||||
{
|
||||
// Early out if no handles are opened
|
||||
Array<FileReadStream*> streams;
|
||||
_file.GetValues(streams);
|
||||
if (streams.IsEmpty() && Platform::AtomicRead(&_chunksLock) == 0)
|
||||
return false;
|
||||
PROFILE_CPU();
|
||||
|
||||
// Note: this is usually called by the content manager when this file is not used or on exit
|
||||
@@ -1367,7 +1372,7 @@ bool FlaxStorage::CloseFileHandles()
|
||||
return true; // Failed, someone is still accessing the file
|
||||
|
||||
// Close file handles (from all threads)
|
||||
Array<FileReadStream*> streams;
|
||||
streams.Clear();
|
||||
_file.GetValues(streams);
|
||||
for (FileReadStream* stream : streams)
|
||||
{
|
||||
|
||||
@@ -61,9 +61,10 @@ public:
|
||||
|
||||
/// <summary>
|
||||
/// Enables cascades splits blending for directional light shadows.
|
||||
/// [Deprecated in v1.9]
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1320), DefaultValue(false), EditorDisplay(\"Quality\", \"Allow CSM Blending\")")
|
||||
bool AllowCSMBlending = false;
|
||||
DEPRECATED bool AllowCSMBlending = false;
|
||||
|
||||
/// <summary>
|
||||
/// Default probes cubemap resolution (use for Environment Probes, can be overriden per-actor).
|
||||
|
||||
@@ -23,3 +23,8 @@
|
||||
#define OUT_OF_MEMORY Platform::OutOfMemory(__LINE__, __FILE__)
|
||||
#define MISSING_CODE(info) Platform::MissingCode(__LINE__, __FILE__, info)
|
||||
#define NON_COPYABLE(type) type(type&&) = delete; type(const type&) = delete; type& operator=(const type&) = delete; type& operator=(type&&) = delete;
|
||||
#define POD_COPYABLE(type) \
|
||||
type(const type& other) { Platform::MemoryCopy(this, &other, sizeof(type)); } \
|
||||
type(type&& other) noexcept { Platform::MemoryCopy(this, &other, sizeof(type)); } \
|
||||
type& operator=(const type& other) { Platform::MemoryCopy(this, &other, sizeof(type)); return *this; } \
|
||||
type& operator=(type&& other) noexcept { Platform::MemoryCopy(this, &other, sizeof(type)); return *this; }
|
||||
|
||||
@@ -51,7 +51,11 @@ bool BoundingSphere::Intersects(const BoundingBox& box) const
|
||||
|
||||
bool BoundingSphere::Intersects(const BoundingSphere& sphere) const
|
||||
{
|
||||
return CollisionsHelper::SphereIntersectsSphere(*this, sphere);
|
||||
const Real radiisum = Radius + sphere.Radius;
|
||||
const Real x = Center.X - sphere.Center.X;
|
||||
const Real y = Center.Y - sphere.Center.Y;
|
||||
const Real z = Center.Z - sphere.Center.Z;
|
||||
return x * x + y * y + z * z <= radiisum * radiisum;
|
||||
}
|
||||
|
||||
ContainmentType BoundingSphere::Contains(const Vector3& point) const
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Matrix.h"
|
||||
#include "Matrix3x3.h"
|
||||
#include "Matrix3x4.h"
|
||||
#include "Vector2.h"
|
||||
#include "Quaternion.h"
|
||||
#include "Transform.h"
|
||||
@@ -887,3 +888,39 @@ Float4 Matrix::TransformPosition(const Matrix& m, const Float4& v)
|
||||
m.Values[0][3] * v.Raw[0] + m.Values[1][3] * v.Raw[1] + m.Values[2][3] * v.Raw[2] + m.Values[3][3] * v.Raw[3]
|
||||
);
|
||||
}
|
||||
|
||||
void Matrix3x4::SetMatrix(const Matrix& m)
|
||||
{
|
||||
const float* src = m.Raw;
|
||||
float* dst = Raw;
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[2];
|
||||
dst[3] = src[3];
|
||||
dst[4] = src[4];
|
||||
dst[5] = src[5];
|
||||
dst[6] = src[6];
|
||||
dst[7] = src[7];
|
||||
dst[8] = src[8];
|
||||
dst[9] = src[9];
|
||||
dst[10] = src[10];
|
||||
dst[11] = src[11];
|
||||
}
|
||||
|
||||
void Matrix3x4::SetMatrixTranspose(const Matrix& m)
|
||||
{
|
||||
const float* src = m.Raw;
|
||||
float* dst = Raw;
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[4];
|
||||
dst[2] = src[8];
|
||||
dst[3] = src[12];
|
||||
dst[4] = src[1];
|
||||
dst[5] = src[5];
|
||||
dst[6] = src[9];
|
||||
dst[7] = src[13];
|
||||
dst[8] = src[2];
|
||||
dst[9] = src[6];
|
||||
dst[10] = src[10];
|
||||
dst[11] = src[14];
|
||||
}
|
||||
|
||||
@@ -890,7 +890,7 @@ public:
|
||||
/// <param name="translation">The translation.</param>
|
||||
/// <param name="rotation">Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.</param>
|
||||
/// <param name="scaling">The scaling.</param>
|
||||
/// <param name="result">When the method completes, contains the created rotation matrix.</param>
|
||||
/// <param name="result">When the method completes, contains the created transformation matrix.</param>
|
||||
static void Transformation(const Float3& scaling, const Quaternion& rotation, const Float3& translation, Matrix& result);
|
||||
|
||||
// Creates a 3D affine transformation matrix.
|
||||
|
||||
@@ -9,43 +9,14 @@
|
||||
/// </summary>
|
||||
struct FLAXENGINE_API Matrix3x4
|
||||
{
|
||||
float M[3][4];
|
||||
|
||||
void SetMatrix(const Matrix& m)
|
||||
union
|
||||
{
|
||||
const float* src = m.Raw;
|
||||
float* dst = &M[0][0];
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[2];
|
||||
dst[3] = src[3];
|
||||
dst[4] = src[4];
|
||||
dst[5] = src[5];
|
||||
dst[6] = src[6];
|
||||
dst[7] = src[7];
|
||||
dst[8] = src[8];
|
||||
dst[9] = src[9];
|
||||
dst[10] = src[10];
|
||||
dst[11] = src[11];
|
||||
}
|
||||
float Values[3][4];
|
||||
float Raw[12];
|
||||
};
|
||||
|
||||
void SetMatrixTranspose(const Matrix& m)
|
||||
{
|
||||
const float* src = m.Raw;
|
||||
float* dst = &M[0][0];
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[4];
|
||||
dst[2] = src[8];
|
||||
dst[3] = src[12];
|
||||
dst[4] = src[1];
|
||||
dst[5] = src[5];
|
||||
dst[6] = src[9];
|
||||
dst[7] = src[13];
|
||||
dst[8] = src[2];
|
||||
dst[9] = src[6];
|
||||
dst[10] = src[10];
|
||||
dst[11] = src[14];
|
||||
}
|
||||
void SetMatrix(const Matrix& m);
|
||||
void SetMatrixTranspose(const Matrix& m);
|
||||
};
|
||||
|
||||
template<>
|
||||
|
||||
@@ -1010,9 +1010,6 @@ namespace FlaxEngine.Interop
|
||||
{
|
||||
#if FLAX_EDITOR
|
||||
// Clear all caches which might hold references to assemblies in collectible ALC
|
||||
typeCache.Clear();
|
||||
|
||||
// Release all references in collectible ALC
|
||||
cachedDelegatesCollectible.Clear();
|
||||
foreach (var pair in managedTypesCollectible)
|
||||
pair.Value.handle.Free();
|
||||
|
||||
@@ -31,8 +31,6 @@ namespace FlaxEngine.Interop
|
||||
|
||||
private static bool firstAssemblyLoaded = false;
|
||||
|
||||
private static Dictionary<string, Type> typeCache = new();
|
||||
|
||||
private static IntPtr boolTruePtr = ManagedHandle.ToIntPtr(ManagedHandle.Alloc((int)1, GCHandleType.Pinned));
|
||||
private static IntPtr boolFalsePtr = ManagedHandle.ToIntPtr(ManagedHandle.Alloc((int)0, GCHandleType.Pinned));
|
||||
|
||||
@@ -279,44 +277,6 @@ namespace FlaxEngine.Interop
|
||||
return dst;
|
||||
}
|
||||
|
||||
private static Type FindType(string typeName)
|
||||
{
|
||||
if (typeCache.TryGetValue(typeName, out Type type))
|
||||
return type;
|
||||
|
||||
type = Type.GetType(typeName, ResolveAssembly, null);
|
||||
if (type == null)
|
||||
type = ResolveSlow(typeName);
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
string fullTypeName = typeName;
|
||||
typeName = typeName.Substring(0, typeName.IndexOf(','));
|
||||
type = Type.GetType(typeName, ResolveAssembly, null);
|
||||
if (type == null)
|
||||
type = ResolveSlow(typeName);
|
||||
|
||||
typeName = fullTypeName;
|
||||
}
|
||||
|
||||
typeCache.Add(typeName, type);
|
||||
|
||||
return type;
|
||||
|
||||
static Type ResolveSlow(string typeName)
|
||||
{
|
||||
foreach (var assembly in scriptingAssemblyLoadContext.Assemblies)
|
||||
{
|
||||
var type = assembly.GetType(typeName);
|
||||
if (type != null)
|
||||
return type;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static Assembly ResolveAssembly(AssemblyName name) => ResolveScriptingAssemblyByName(name, allowPartial: false);
|
||||
}
|
||||
|
||||
/// <summary>Find <paramref name="assemblyName"/> among the scripting assemblies.</summary>
|
||||
/// <param name="assemblyName">The name to find</param>
|
||||
/// <param name="allowPartial">If true, partial names should be allowed to be resolved.</param>
|
||||
@@ -378,18 +338,15 @@ namespace FlaxEngine.Interop
|
||||
/// </summary>
|
||||
internal static Type GetInternalType(Type type)
|
||||
{
|
||||
string[] splits = type.AssemblyQualifiedName.Split(',');
|
||||
string @namespace = string.Join('.', splits[0].Split('.').SkipLast(1));
|
||||
string className = @namespace.Length > 0 ? splits[0].Substring(@namespace.Length + 1) : splits[0];
|
||||
string parentClassName = "";
|
||||
if (className.Contains('+'))
|
||||
{
|
||||
parentClassName = className.Substring(0, className.LastIndexOf('+') + 1);
|
||||
className = className.Substring(parentClassName.Length);
|
||||
}
|
||||
string marshallerName = className + "Marshaller";
|
||||
string internalAssemblyQualifiedName = $"{@namespace}.{parentClassName}{marshallerName}+{className}Internal,{String.Join(',', splits.Skip(1))}";
|
||||
return FindType(internalAssemblyQualifiedName);
|
||||
Type marshallerType = type.GetCustomAttribute<System.Runtime.InteropServices.Marshalling.NativeMarshallingAttribute>()?.NativeType;
|
||||
if (marshallerType == null)
|
||||
return null;
|
||||
|
||||
Type internalType = marshallerType.GetNestedType($"{type.Name}Internal");
|
||||
if (internalType == null)
|
||||
return null;
|
||||
|
||||
return internalType;
|
||||
}
|
||||
|
||||
internal class ReferenceTypePlaceholder { }
|
||||
@@ -1338,7 +1295,7 @@ namespace FlaxEngine.Interop
|
||||
if (invokeDelegate == null && !method.DeclaringType.IsValueType)
|
||||
{
|
||||
// Thread-safe creation
|
||||
lock (typeCache)
|
||||
lock (method)
|
||||
{
|
||||
if (invokeDelegate == null)
|
||||
{
|
||||
|
||||
@@ -94,7 +94,7 @@ bool Time::TickData::OnTickBegin(double time, float targetFps, float maxDeltaTim
|
||||
|
||||
if (targetFps > ZeroTolerance)
|
||||
{
|
||||
int skip = (int)(1 + (time - NextBegin) * targetFps);
|
||||
const int skip = (int)(1 + (time - NextBegin) * targetFps);
|
||||
NextBegin += (1.0 / targetFps) * skip;
|
||||
}
|
||||
}
|
||||
@@ -132,14 +132,12 @@ bool Time::FixedStepTickData::OnTickBegin(double time, float targetFps, float ma
|
||||
if (FixedDeltaTimeEnable)
|
||||
{
|
||||
deltaTime = (double)FixedDeltaTimeValue;
|
||||
minDeltaTime = deltaTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (time < NextBegin)
|
||||
return false;
|
||||
|
||||
minDeltaTime = targetFps > ZeroTolerance ? 1.0 / targetFps : 0.0;
|
||||
deltaTime = Math::Max((time - LastBegin), 0.0);
|
||||
if (deltaTime > maxDeltaTime)
|
||||
{
|
||||
@@ -149,21 +147,10 @@ bool Time::FixedStepTickData::OnTickBegin(double time, float targetFps, float ma
|
||||
|
||||
if (targetFps > ZeroTolerance)
|
||||
{
|
||||
int skip = (int)(1 + (time - NextBegin) * targetFps);
|
||||
NextBegin += (1.0 / targetFps) * skip;
|
||||
deltaTime = 1.0 / targetFps;
|
||||
NextBegin += 1.0 / targetFps;
|
||||
}
|
||||
}
|
||||
Samples.Add(deltaTime);
|
||||
|
||||
// Check if last few ticks were not taking too long so it's running slowly
|
||||
const bool isRunningSlowly = Samples.Average() > 1.5 * minDeltaTime;
|
||||
if (!isRunningSlowly)
|
||||
{
|
||||
// Make steps fixed size
|
||||
const double diff = deltaTime - minDeltaTime;
|
||||
time -= diff;
|
||||
deltaTime = minDeltaTime;
|
||||
}
|
||||
|
||||
// Update data
|
||||
Advance(time, deltaTime);
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "Engine/Core/Types/TimeSpan.h"
|
||||
#include "Engine/Core/Types/DateTime.h"
|
||||
#include "Engine/Scripting/ScriptingType.h"
|
||||
#include "Engine/Core/Collections/SamplesBuffer.h"
|
||||
|
||||
/// <summary>
|
||||
/// Game ticking and timing system.
|
||||
@@ -89,12 +88,7 @@ public:
|
||||
class FixedStepTickData : public TickData
|
||||
{
|
||||
public:
|
||||
/// <summary>
|
||||
/// The last few ticks delta times. Used to check if can use fixed steps or whenever is running slowly so should use normal stepping.
|
||||
/// </summary>
|
||||
SamplesBuffer<double, 4> Samples;
|
||||
|
||||
public:
|
||||
// [TickData]
|
||||
bool OnTickBegin(double time, float targetFps, float maxDeltaTime) override;
|
||||
};
|
||||
|
||||
5
Source/Engine/Engine/Units.h
Normal file
5
Source/Engine/Engine/Units.h
Normal file
@@ -0,0 +1,5 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#define METERS_TO_UNITS(meters) (meters * 100.0f)
|
||||
@@ -252,7 +252,7 @@ API_ENUM() enum class PartitionMode
|
||||
Logarithmic = 1,
|
||||
|
||||
/// <summary>
|
||||
/// PSSM cascade splits.
|
||||
/// Parallel-Split Shadow Maps cascade splits.
|
||||
/// </summary>
|
||||
PSSM = 2,
|
||||
};
|
||||
|
||||
@@ -186,7 +186,8 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="depthBuffer">The depth buffer to clear.</param>
|
||||
/// <param name="depthValue">The clear depth value.</param>
|
||||
API_FUNCTION() virtual void ClearDepth(GPUTextureView* depthBuffer, float depthValue = 1.0f) = 0;
|
||||
/// <param name="stencilValue">The clear stencil value.</param>
|
||||
API_FUNCTION() virtual void ClearDepth(GPUTextureView* depthBuffer, float depthValue = 1.0f, uint8 stencilValue = 0) = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Clears an unordered access buffer with a float value.
|
||||
|
||||
@@ -65,7 +65,6 @@ void GraphicsSettings::Apply()
|
||||
Graphics::VolumetricFogQuality = VolumetricFogQuality;
|
||||
Graphics::ShadowsQuality = ShadowsQuality;
|
||||
Graphics::ShadowMapsQuality = ShadowMapsQuality;
|
||||
Graphics::AllowCSMBlending = AllowCSMBlending;
|
||||
Graphics::GlobalSDFQuality = GlobalSDFQuality;
|
||||
Graphics::GIQuality = GIQuality;
|
||||
Graphics::PostProcessSettings = ::PostProcessSettings();
|
||||
|
||||
@@ -50,8 +50,9 @@ public:
|
||||
|
||||
/// <summary>
|
||||
/// Enables cascades splits blending for directional light shadows.
|
||||
/// [Deprecated in v1.9]
|
||||
/// </summary>
|
||||
API_FIELD() static bool AllowCSMBlending;
|
||||
API_FIELD() DEPRECATED static bool AllowCSMBlending;
|
||||
|
||||
/// <summary>
|
||||
/// The Global SDF quality. Controls the volume texture resolution and amount of cascades to use.
|
||||
|
||||
@@ -34,8 +34,7 @@ void DecalMaterialShader::Bind(BindParameters& params)
|
||||
ASSERT_LOW_LAYER(cb.Length() >= sizeof(DecalMaterialShaderData));
|
||||
auto materialData = reinterpret_cast<DecalMaterialShaderData*>(cb.Get());
|
||||
cb = Span<byte>(cb.Get() + sizeof(DecalMaterialShaderData), cb.Length() - sizeof(DecalMaterialShaderData));
|
||||
int32 srv = 0;
|
||||
const bool isCameraInside = OrientedBoundingBox(Vector3::Half, params.FirstDrawCall->World).Contains(view.Position) == ContainmentType::Contains;
|
||||
const bool isCameraInside = OrientedBoundingBox(Vector3::Half, drawCall.World).Contains(view.Position) == ContainmentType::Contains;
|
||||
|
||||
// Setup parameters
|
||||
MaterialParameter::BindMeta bindMeta;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "DeferredMaterialShader.h"
|
||||
#include "MaterialShaderFeatures.h"
|
||||
#include "MaterialParams.h"
|
||||
#include "Engine/Core/Math/Matrix3x4.h"
|
||||
#include "Engine/Graphics/RenderBuffers.h"
|
||||
#include "Engine/Graphics/RenderView.h"
|
||||
#include "Engine/Renderer/DrawCall.h"
|
||||
@@ -17,8 +18,8 @@
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
|
||||
PACK_STRUCT(struct DeferredMaterialShaderData {
|
||||
Matrix WorldMatrix;
|
||||
Matrix PrevWorldMatrix;
|
||||
Matrix3x4 WorldMatrix;
|
||||
Matrix3x4 PrevWorldMatrix;
|
||||
Float2 Dummy0;
|
||||
float LODDitherFactor;
|
||||
float PerInstanceRandom;
|
||||
@@ -70,8 +71,8 @@ void DeferredMaterialShader::Bind(BindParameters& params)
|
||||
|
||||
// Setup material constants
|
||||
{
|
||||
Matrix::Transpose(drawCall.World, materialData->WorldMatrix);
|
||||
Matrix::Transpose(drawCall.Surface.PrevWorld, materialData->PrevWorldMatrix);
|
||||
materialData->WorldMatrix.SetMatrixTranspose(drawCall.World);
|
||||
materialData->PrevWorldMatrix.SetMatrixTranspose(drawCall.Surface.PrevWorld);
|
||||
materialData->WorldDeterminantSign = drawCall.WorldDeterminantSign;
|
||||
materialData->LODDitherFactor = drawCall.Surface.LODDitherFactor;
|
||||
materialData->PerInstanceRandom = drawCall.PerInstanceRandom;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "ForwardMaterialShader.h"
|
||||
#include "MaterialShaderFeatures.h"
|
||||
#include "MaterialParams.h"
|
||||
#include "Engine/Core/Math/Matrix3x4.h"
|
||||
#include "Engine/Graphics/GPUContext.h"
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Graphics/GPULimits.h"
|
||||
@@ -18,8 +19,8 @@
|
||||
#endif
|
||||
|
||||
PACK_STRUCT(struct ForwardMaterialShaderData {
|
||||
Matrix WorldMatrix;
|
||||
Matrix PrevWorldMatrix;
|
||||
Matrix3x4 WorldMatrix;
|
||||
Matrix3x4 PrevWorldMatrix;
|
||||
Float2 Dummy0;
|
||||
float LODDitherFactor;
|
||||
float PerInstanceRandom;
|
||||
@@ -76,8 +77,8 @@ void ForwardMaterialShader::Bind(BindParameters& params)
|
||||
|
||||
// Setup material constants
|
||||
{
|
||||
Matrix::Transpose(drawCall.World, materialData->WorldMatrix);
|
||||
Matrix::Transpose(drawCall.Surface.PrevWorld, materialData->PrevWorldMatrix);
|
||||
materialData->WorldMatrix.SetMatrixTranspose(drawCall.World);
|
||||
materialData->PrevWorldMatrix.SetMatrixTranspose(drawCall.Surface.PrevWorld);
|
||||
materialData->WorldDeterminantSign = drawCall.WorldDeterminantSign;
|
||||
materialData->LODDitherFactor = drawCall.Surface.LODDitherFactor;
|
||||
materialData->PerInstanceRandom = drawCall.PerInstanceRandom;
|
||||
|
||||
@@ -119,7 +119,7 @@ public:
|
||||
struct InstancingHandler
|
||||
{
|
||||
void (*GetHash)(const DrawCall& drawCall, uint32& batchKey);
|
||||
bool (*CanBatch)(const DrawCall& a, const DrawCall& b);
|
||||
bool (*CanBatch)(const DrawCall& a, const DrawCall& b, DrawPass pass);
|
||||
void (*WriteDrawCall)(struct InstanceData* instanceData, const DrawCall& drawCall);
|
||||
};
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
/// <summary>
|
||||
/// Current materials shader version.
|
||||
/// </summary>
|
||||
#define MATERIAL_GRAPH_VERSION 162
|
||||
#define MATERIAL_GRAPH_VERSION 165
|
||||
|
||||
class Material;
|
||||
class GPUShader;
|
||||
|
||||
@@ -21,7 +21,8 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
|
||||
ASSERT_LOW_LAYER(cb.Length() >= sizeof(Data));
|
||||
const int32 envProbeShaderRegisterIndex = srv + 0;
|
||||
const int32 skyLightShaderRegisterIndex = srv + 1;
|
||||
const int32 dirLightShaderRegisterIndex = srv + 2;
|
||||
const int32 shadowsBufferRegisterIndex = srv + 2;
|
||||
const int32 shadowMapShaderRegisterIndex = srv + 3;
|
||||
const bool canUseShadow = view.Pass != DrawPass::Depth;
|
||||
|
||||
// Set fog input
|
||||
@@ -39,31 +40,26 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
|
||||
if (cache->DirectionalLights.HasItems())
|
||||
{
|
||||
const auto& dirLight = cache->DirectionalLights.First();
|
||||
const auto shadowPass = ShadowsPass::Instance();
|
||||
const bool useShadow = shadowPass->LastDirLightIndex == 0 && canUseShadow;
|
||||
if (useShadow)
|
||||
{
|
||||
data.DirectionalLightShadow = shadowPass->LastDirLight;
|
||||
params.GPUContext->BindSR(dirLightShaderRegisterIndex, shadowPass->LastDirLightShadowMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
params.GPUContext->UnBindSR(dirLightShaderRegisterIndex);
|
||||
}
|
||||
dirLight.SetupLightData(&data.DirectionalLight, useShadow);
|
||||
GPUTexture* shadowMapAtlas;
|
||||
GPUBufferView* shadowsBuffer;
|
||||
ShadowsPass::GetShadowAtlas(params.RenderContext.Buffers, shadowMapAtlas, shadowsBuffer);
|
||||
const bool useShadow = shadowMapAtlas && canUseShadow && dirLight.HasShadow;
|
||||
dirLight.SetShaderData(data.DirectionalLight, useShadow);
|
||||
params.GPUContext->BindSR(shadowsBufferRegisterIndex, shadowsBuffer);
|
||||
params.GPUContext->BindSR(shadowMapShaderRegisterIndex, shadowMapAtlas);
|
||||
}
|
||||
else
|
||||
{
|
||||
data.DirectionalLight.Color = Float3::Zero;
|
||||
data.DirectionalLight.CastShadows = 0.0f;
|
||||
params.GPUContext->UnBindSR(dirLightShaderRegisterIndex);
|
||||
Platform::MemoryClear(&data.DirectionalLight, sizeof(data.DirectionalLight));
|
||||
params.GPUContext->UnBindSR(shadowsBufferRegisterIndex);
|
||||
params.GPUContext->UnBindSR(shadowMapShaderRegisterIndex);
|
||||
}
|
||||
|
||||
// Set sky light
|
||||
if (cache->SkyLights.HasItems())
|
||||
{
|
||||
auto& skyLight = cache->SkyLights.First();
|
||||
skyLight.SetupLightData(&data.SkyLight, false);
|
||||
skyLight.SetShaderData(data.SkyLight, false);
|
||||
const auto texture = skyLight.Image ? skyLight.Image->GetTexture() : nullptr;
|
||||
params.GPUContext->BindSR(skyLightShaderRegisterIndex, GET_TEXTURE_VIEW_SAFE(texture));
|
||||
}
|
||||
@@ -74,24 +70,21 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
|
||||
}
|
||||
|
||||
// Set reflection probe data
|
||||
EnvironmentProbe* probe = nullptr;
|
||||
bool noEnvProbe = true;
|
||||
// TODO: optimize env probe searching for a transparent material - use spatial cache for renderer to find it
|
||||
const BoundingSphere objectBoundsWorld(drawCall.ObjectPosition + view.Origin, drawCall.ObjectRadius);
|
||||
const BoundingSphere objectBounds(drawCall.ObjectPosition, drawCall.ObjectRadius);
|
||||
for (int32 i = 0; i < cache->EnvironmentProbes.Count(); i++)
|
||||
{
|
||||
const auto p = cache->EnvironmentProbes[i];
|
||||
if (CollisionsHelper::SphereIntersectsSphere(objectBoundsWorld, p->GetSphere()))
|
||||
const RenderEnvironmentProbeData& probe = cache->EnvironmentProbes.Get()[i];
|
||||
if (objectBounds.Intersects(BoundingSphere(probe.Position, probe.Radius)))
|
||||
{
|
||||
probe = p;
|
||||
noEnvProbe = false;
|
||||
probe.SetShaderData(data.EnvironmentProbe);
|
||||
params.GPUContext->BindSR(envProbeShaderRegisterIndex, probe.Texture);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (probe && probe->GetProbe())
|
||||
{
|
||||
probe->SetupProbeData(params.RenderContext, &data.EnvironmentProbe);
|
||||
params.GPUContext->BindSR(envProbeShaderRegisterIndex, probe->GetProbe());
|
||||
}
|
||||
else
|
||||
if (noEnvProbe)
|
||||
{
|
||||
data.EnvironmentProbe.Data1 = Float4::Zero;
|
||||
params.GPUContext->UnBindSR(envProbeShaderRegisterIndex);
|
||||
@@ -99,23 +92,22 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
|
||||
|
||||
// Set local lights
|
||||
data.LocalLightsCount = 0;
|
||||
const BoundingSphere objectBounds(drawCall.ObjectPosition, drawCall.ObjectRadius);
|
||||
// TODO: optimize lights searching for a transparent material - use spatial cache for renderer to find it
|
||||
for (int32 i = 0; i < cache->PointLights.Count() && data.LocalLightsCount < MaxLocalLights; i++)
|
||||
{
|
||||
const auto& light = cache->PointLights[i];
|
||||
if (CollisionsHelper::SphereIntersectsSphere(objectBounds, BoundingSphere(light.Position, light.Radius)))
|
||||
if (objectBounds.Intersects(BoundingSphere(light.Position, light.Radius)))
|
||||
{
|
||||
light.SetupLightData(&data.LocalLights[data.LocalLightsCount], false);
|
||||
light.SetShaderData(data.LocalLights[data.LocalLightsCount], false);
|
||||
data.LocalLightsCount++;
|
||||
}
|
||||
}
|
||||
for (int32 i = 0; i < cache->SpotLights.Count() && data.LocalLightsCount < MaxLocalLights; i++)
|
||||
{
|
||||
const auto& light = cache->SpotLights[i];
|
||||
if (CollisionsHelper::SphereIntersectsSphere(objectBounds, BoundingSphere(light.Position, light.Radius)))
|
||||
if (objectBounds.Intersects(BoundingSphere(light.Position, light.Radius)))
|
||||
{
|
||||
light.SetupLightData(&data.LocalLights[data.LocalLightsCount], false);
|
||||
light.SetShaderData(data.LocalLights[data.LocalLightsCount], false);
|
||||
data.LocalLightsCount++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,18 +23,17 @@ struct ForwardShadingFeature : MaterialShaderFeature
|
||||
{
|
||||
enum { MaxLocalLights = 4 };
|
||||
|
||||
enum { SRVs = 3 };
|
||||
enum { SRVs = 4 };
|
||||
|
||||
PACK_STRUCT(struct Data
|
||||
{
|
||||
LightData DirectionalLight;
|
||||
LightShadowData DirectionalLightShadow;
|
||||
LightData SkyLight;
|
||||
ProbeData EnvironmentProbe;
|
||||
ExponentialHeightFogData ExponentialHeightFog;
|
||||
ShaderLightData DirectionalLight;
|
||||
ShaderLightData SkyLight;
|
||||
ShaderEnvProbeData EnvironmentProbe;
|
||||
ShaderExponentialHeightFogData ExponentialHeightFog;
|
||||
Float3 Dummy2;
|
||||
uint32 LocalLightsCount;
|
||||
LightData LocalLights[MaxLocalLights];
|
||||
ShaderLightData LocalLights[MaxLocalLights];
|
||||
});
|
||||
|
||||
static void Bind(MaterialShader::BindParameters& params, Span<byte>& cb, int32& srv);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "ParticleMaterialShader.h"
|
||||
#include "MaterialShaderFeatures.h"
|
||||
#include "MaterialParams.h"
|
||||
#include "Engine/Core/Math/Matrix3x4.h"
|
||||
#include "Engine/Renderer/DrawCall.h"
|
||||
#include "Engine/Renderer/RenderList.h"
|
||||
#include "Engine/Graphics/RenderView.h"
|
||||
@@ -15,7 +16,7 @@
|
||||
#include "Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.h"
|
||||
|
||||
PACK_STRUCT(struct ParticleMaterialShaderData {
|
||||
Matrix WorldMatrix;
|
||||
Matrix3x4 WorldMatrix;
|
||||
uint32 SortedIndicesOffset;
|
||||
float PerInstanceRandom;
|
||||
int32 ParticleStride;
|
||||
@@ -34,7 +35,7 @@ PACK_STRUCT(struct ParticleMaterialShaderData {
|
||||
int32 RibbonTwistOffset;
|
||||
int32 RibbonFacingVectorOffset;
|
||||
uint32 RibbonSegmentCount;
|
||||
Matrix WorldMatrixInverseTransposed;
|
||||
Matrix3x4 WorldMatrixInverseTransposed;
|
||||
});
|
||||
|
||||
DrawPass ParticleMaterialShader::GetDrawModes() const
|
||||
@@ -101,7 +102,7 @@ void ParticleMaterialShader::Bind(BindParameters& params)
|
||||
static StringView ParticleScaleOffset(TEXT("Scale"));
|
||||
static StringView ParticleModelFacingModeOffset(TEXT("ModelFacingMode"));
|
||||
|
||||
Matrix::Transpose(drawCall.World, materialData->WorldMatrix);
|
||||
materialData->WorldMatrix.SetMatrixTranspose(drawCall.World);
|
||||
materialData->SortedIndicesOffset = drawCall.Particle.Particles->GPU.SortedIndices && params.RenderContext.View.Pass != DrawPass::Depth ? sortedIndicesOffset : 0xFFFFFFFF;
|
||||
materialData->PerInstanceRandom = drawCall.PerInstanceRandom;
|
||||
materialData->ParticleStride = drawCall.Particle.Particles->Stride;
|
||||
@@ -113,7 +114,9 @@ void ParticleMaterialShader::Bind(BindParameters& params)
|
||||
materialData->RotationOffset = drawCall.Particle.Particles->Layout->FindAttributeOffset(ParticleRotationOffset, ParticleAttribute::ValueTypes::Float3, -1);
|
||||
materialData->ScaleOffset = drawCall.Particle.Particles->Layout->FindAttributeOffset(ParticleScaleOffset, ParticleAttribute::ValueTypes::Float3, -1);
|
||||
materialData->ModelFacingModeOffset = drawCall.Particle.Particles->Layout->FindAttributeOffset(ParticleModelFacingModeOffset, ParticleAttribute::ValueTypes::Int, -1);
|
||||
Matrix::Invert(drawCall.World, materialData->WorldMatrixInverseTransposed);
|
||||
Matrix worldMatrixInverseTransposed;
|
||||
Matrix::Invert(drawCall.World, worldMatrixInverseTransposed);
|
||||
materialData->WorldMatrixInverseTransposed.SetMatrix(worldMatrixInverseTransposed);
|
||||
}
|
||||
|
||||
// Select pipeline state based on current pass and render mode
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "TerrainMaterialShader.h"
|
||||
#include "MaterialShaderFeatures.h"
|
||||
#include "MaterialParams.h"
|
||||
#include "Engine/Core/Math/Matrix3x4.h"
|
||||
#include "Engine/Graphics/GPUContext.h"
|
||||
#include "Engine/Graphics/GPULimits.h"
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
@@ -16,7 +17,7 @@
|
||||
#include "Engine/Terrain/TerrainPatch.h"
|
||||
|
||||
PACK_STRUCT(struct TerrainMaterialShaderData {
|
||||
Matrix WorldMatrix;
|
||||
Matrix3x4 WorldMatrix;
|
||||
Float3 WorldInvScale;
|
||||
float WorldDeterminantSign;
|
||||
float PerInstanceRandom;
|
||||
@@ -66,7 +67,7 @@ void TerrainMaterialShader::Bind(BindParameters& params)
|
||||
|
||||
// Setup material constants
|
||||
{
|
||||
Matrix::Transpose(drawCall.World, materialData->WorldMatrix);
|
||||
materialData->WorldMatrix.SetMatrixTranspose(drawCall.World);
|
||||
const float scaleX = Float3(drawCall.World.M11, drawCall.World.M12, drawCall.World.M13).Length();
|
||||
const float scaleY = Float3(drawCall.World.M21, drawCall.World.M22, drawCall.World.M23).Length();
|
||||
const float scaleZ = Float3(drawCall.World.M31, drawCall.World.M32, drawCall.World.M33).Length();
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "VolumeParticleMaterialShader.h"
|
||||
#include "MaterialShaderFeatures.h"
|
||||
#include "MaterialParams.h"
|
||||
#include "Engine/Core/Math/Matrix3x4.h"
|
||||
#include "Engine/Renderer/DrawCall.h"
|
||||
#include "Engine/Renderer/VolumetricFogPass.h"
|
||||
#include "Engine/Renderer/RenderList.h"
|
||||
@@ -16,8 +17,8 @@
|
||||
|
||||
PACK_STRUCT(struct VolumeParticleMaterialShaderData {
|
||||
Matrix InverseViewProjectionMatrix;
|
||||
Matrix WorldMatrix;
|
||||
Matrix WorldMatrixInverseTransposed;
|
||||
Matrix3x4 WorldMatrix;
|
||||
Matrix3x4 WorldMatrixInverseTransposed;
|
||||
Float3 GridSize;
|
||||
float PerInstanceRandom;
|
||||
float Dummy0;
|
||||
@@ -76,8 +77,10 @@ void VolumeParticleMaterialShader::Bind(BindParameters& params)
|
||||
// Setup material constants
|
||||
{
|
||||
Matrix::Transpose(view.IVP, materialData->InverseViewProjectionMatrix);
|
||||
Matrix::Transpose(drawCall.World, materialData->WorldMatrix);
|
||||
Matrix::Invert(drawCall.World, materialData->WorldMatrixInverseTransposed);
|
||||
materialData->WorldMatrix.SetMatrixTranspose(drawCall.World);
|
||||
Matrix worldMatrixInverseTransposed;
|
||||
Matrix::Invert(drawCall.World, worldMatrixInverseTransposed);
|
||||
materialData->WorldMatrixInverseTransposed.SetMatrix(worldMatrixInverseTransposed);
|
||||
materialData->GridSize = customData->GridSize;
|
||||
materialData->PerInstanceRandom = drawCall.PerInstanceRandom;
|
||||
materialData->VolumetricFogMaxDistance = customData->VolumetricFogMaxDistance;
|
||||
|
||||
@@ -337,14 +337,14 @@ void RenderTools::ComputePitch(PixelFormat format, int32 width, int32 height, ui
|
||||
case PixelFormat::ASTC_8x8_UNorm_sRGB:
|
||||
case PixelFormat::ASTC_10x10_UNorm:
|
||||
case PixelFormat::ASTC_10x10_UNorm_sRGB:
|
||||
{
|
||||
const int32 blockSize = PixelFormatExtensions::ComputeBlockSize(format);
|
||||
uint32 nbw = Math::Max<uint32>(1, Math::DivideAndRoundUp(width, blockSize));
|
||||
uint32 nbh = Math::Max<uint32>(1, Math::DivideAndRoundUp(height, blockSize));
|
||||
rowPitch = nbw * 16; // All ASTC blocks use 128 bits
|
||||
slicePitch = rowPitch * nbh;
|
||||
}
|
||||
break;
|
||||
{
|
||||
const int32 blockSize = PixelFormatExtensions::ComputeBlockSize(format);
|
||||
uint32 nbw = Math::Max<uint32>(1, Math::DivideAndRoundUp(width, blockSize));
|
||||
uint32 nbh = Math::Max<uint32>(1, Math::DivideAndRoundUp(height, blockSize));
|
||||
rowPitch = nbw * 16; // All ASTC blocks use 128 bits
|
||||
slicePitch = rowPitch * nbh;
|
||||
}
|
||||
break;
|
||||
case PixelFormat::R8G8_B8G8_UNorm:
|
||||
case PixelFormat::G8R8_G8B8_UNorm:
|
||||
ASSERT(PixelFormatExtensions::IsPacked(format));
|
||||
@@ -552,6 +552,14 @@ void RenderTools::ComputeCascadeUpdateFrequency(int32 cascadeIndex, int32 cascad
|
||||
}
|
||||
}
|
||||
|
||||
float RenderTools::ComputeTemporalTime()
|
||||
{
|
||||
const float time = Time::Draw.UnscaledTime.GetTotalSeconds();
|
||||
const float scale = 10;
|
||||
const float integral = roundf(time / scale) * scale;
|
||||
return time - integral;
|
||||
}
|
||||
|
||||
void RenderTools::CalculateTangentFrame(FloatR10G10B10A2& resultNormal, FloatR10G10B10A2& resultTangent, const Float3& normal)
|
||||
{
|
||||
// Calculate tangent
|
||||
@@ -579,6 +587,23 @@ void RenderTools::CalculateTangentFrame(FloatR10G10B10A2& resultNormal, FloatR10
|
||||
resultTangent = Float1010102(tangent * 0.5f + 0.5f, sign);
|
||||
}
|
||||
|
||||
void RenderTools::ComputeSphereModelDrawMatrix(const RenderView& view, const Float3& position, float radius, Matrix& resultWorld, bool& resultIsViewInside)
|
||||
{
|
||||
// Construct world matrix
|
||||
constexpr float sphereModelScale = 0.0205f; // Manually tweaked for 'Engine/Models/Sphere' with some slack
|
||||
const float scaling = radius * sphereModelScale;
|
||||
resultWorld = Matrix::Identity;
|
||||
resultWorld.M11 = scaling;
|
||||
resultWorld.M22 = scaling;
|
||||
resultWorld.M33 = scaling;
|
||||
resultWorld.M41 = position.X;
|
||||
resultWorld.M42 = position.Y;
|
||||
resultWorld.M43 = position.Z;
|
||||
|
||||
// Check if view is inside the sphere
|
||||
resultIsViewInside = Float3::DistanceSquared(view.Position, position) < Math::Square(radius * 1.1f); // Manually tweaked bias
|
||||
}
|
||||
|
||||
int32 MipLevelsCount(int32 width, bool useMipLevels)
|
||||
{
|
||||
if (!useMipLevels)
|
||||
@@ -636,22 +661,6 @@ int32 MipLevelsCount(int32 width, int32 height, int32 depth, bool useMipLevels)
|
||||
return result;
|
||||
}
|
||||
|
||||
float ViewToCenterLessRadius(const RenderView& view, const Float3& center, float radius)
|
||||
{
|
||||
// Calculate distance from view to sphere center
|
||||
float viewToCenter = Float3::Distance(view.Position, center);
|
||||
|
||||
// Check if need to fix the radius
|
||||
//if (radius + viewToCenter > view.Far)
|
||||
{
|
||||
// Clamp radius
|
||||
//radius = view.Far - viewToCenter;
|
||||
}
|
||||
|
||||
// Calculate result
|
||||
return viewToCenter - radius;
|
||||
}
|
||||
|
||||
void MeshBase::SetMaterialSlotIndex(int32 value)
|
||||
{
|
||||
if (value < 0 || value >= _model->MaterialSlots.Count())
|
||||
|
||||
@@ -121,8 +121,14 @@ public:
|
||||
return (frameIndex % updateFrequency == updatePhrase) || updateForce;
|
||||
}
|
||||
|
||||
// Calculates temporal offset in the dithering factor that gets cleaned out by TAA.
|
||||
// Returns 0-1 value based on unscaled draw time for temporal effects to reduce artifacts from screen-space dithering when using Temporal Anti-Aliasing.
|
||||
static float ComputeTemporalTime();
|
||||
|
||||
static void CalculateTangentFrame(FloatR10G10B10A2& resultNormal, FloatR10G10B10A2& resultTangent, const Float3& normal);
|
||||
static void CalculateTangentFrame(FloatR10G10B10A2& resultNormal, FloatR10G10B10A2& resultTangent, const Float3& normal, const Float3& tangent);
|
||||
|
||||
static void ComputeSphereModelDrawMatrix(const RenderView& view, const Float3& position, float radius, Matrix& resultWorld, bool& resultIsViewInside);
|
||||
};
|
||||
|
||||
// Calculate mip levels count for a texture 1D
|
||||
@@ -145,12 +151,3 @@ extern int32 MipLevelsCount(int32 width, int32 height, bool useMipLevels = true)
|
||||
// @param useMipLevels True if use mip levels, otherwise false (use only 1 mip)
|
||||
// @returns Mip levels count
|
||||
extern int32 MipLevelsCount(int32 width, int32 height, int32 depth, bool useMipLevels = true);
|
||||
|
||||
/// <summary>
|
||||
/// Calculate distance from view center to the sphere center less sphere radius, clamped to fit view far plane
|
||||
/// </summary>
|
||||
/// <param name="view">Render View</param>
|
||||
/// <param name="center">Sphere center</param>
|
||||
/// <param name="radius">Sphere radius</param>
|
||||
/// <returns>Distance from view center to the sphere center less sphere radius</returns>
|
||||
extern float ViewToCenterLessRadius(const RenderView& view, const Float3& center, float radius);
|
||||
|
||||
@@ -127,6 +127,11 @@ public:
|
||||
/// </summary>
|
||||
API_FIELD() StaticFlags StaticFlagsMask = StaticFlags::None;
|
||||
|
||||
/// <summary>
|
||||
/// The static flags mask comparision rhs. Allows to draw objects that don't pass the static flags mask. Objects are checked with the following formula: (ObjectStaticFlags and StaticFlagsMask) == StaticFlagsMaskCompare.
|
||||
/// </summary>
|
||||
API_FIELD() StaticFlags StaticFlagsCompare = StaticFlags::None;
|
||||
|
||||
/// <summary>
|
||||
/// The view flags.
|
||||
/// </summary>
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
class GPUContext;
|
||||
class GPUTask;
|
||||
class TextureMipData;
|
||||
class TextureData;
|
||||
struct TextureMipData;
|
||||
struct TextureData;
|
||||
template<typename T>
|
||||
class DataContainer;
|
||||
typedef DataContainer<byte> BytesContainer;
|
||||
@@ -533,7 +533,7 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="result">The result data.</param>
|
||||
/// <returns>True if cannot download data, otherwise false.</returns>
|
||||
bool DownloadData(TextureData& result);
|
||||
API_FUNCTION() bool DownloadData(API_PARAM(Out) TextureData& result);
|
||||
|
||||
/// <summary>
|
||||
/// Creates GPU async task that will gather texture data from the GPU.
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
#include "Engine/Content/BinaryAsset.h"
|
||||
#include "StreamingTexture.h"
|
||||
|
||||
class TextureData;
|
||||
class TextureMipData;
|
||||
struct TextureData;
|
||||
struct TextureMipData;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for <see cref="Texture"/>, <see cref="SpriteAtlas"/>, <see cref="IESProfile"/> and other assets that can contain texture data.
|
||||
|
||||
@@ -10,13 +10,21 @@
|
||||
/// <summary>
|
||||
/// Single texture mip map entry data.
|
||||
/// </summary>
|
||||
class FLAXENGINE_API TextureMipData
|
||||
API_STRUCT() struct FLAXENGINE_API TextureMipData
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(TextureMipData);
|
||||
public:
|
||||
uint32 RowPitch;
|
||||
uint32 DepthPitch;
|
||||
uint32 Lines;
|
||||
BytesContainer Data;
|
||||
// The row pitch.
|
||||
API_FIELD() uint32 RowPitch;
|
||||
|
||||
// The depth pitch.
|
||||
API_FIELD() uint32 DepthPitch;
|
||||
|
||||
// The number of lines.
|
||||
API_FIELD() uint32 Lines;
|
||||
|
||||
// The data.
|
||||
API_FIELD(ReadOnly) BytesContainer Data;
|
||||
|
||||
TextureMipData();
|
||||
TextureMipData(const TextureMipData& other);
|
||||
@@ -40,22 +48,39 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct TIsPODType<TextureMipData>
|
||||
{
|
||||
enum { Value = true };
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Single entry of the texture array. Contains collection of mip maps.
|
||||
/// </summary>
|
||||
API_STRUCT(NoDefault) struct FLAXENGINE_API TextureDataArrayEntry
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(TextureDataArrayEntry);
|
||||
|
||||
/// <summary>
|
||||
/// The mip maps collection.
|
||||
/// </summary>
|
||||
API_FIELD(ReadOnly) Array<TextureMipData, FixedAllocation<GPU_MAX_TEXTURE_MIP_LEVELS>> Mips;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct TIsPODType<TextureDataArrayEntry>
|
||||
{
|
||||
enum { Value = false };
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Texture data container (used to keep data downloaded from the GPU).
|
||||
/// </summary>
|
||||
class FLAXENGINE_API TextureData
|
||||
API_STRUCT() struct FLAXENGINE_API TextureData
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(TextureData);
|
||||
public:
|
||||
/// <summary>
|
||||
/// Single entry of the texture array. Contains collection of mip maps.
|
||||
/// </summary>
|
||||
struct FLAXENGINE_API ArrayEntry
|
||||
{
|
||||
/// <summary>
|
||||
/// The mip maps collection.
|
||||
/// </summary>
|
||||
Array<TextureMipData, FixedAllocation<GPU_MAX_TEXTURE_MIP_LEVELS>> Mips;
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
@@ -76,27 +101,27 @@ public:
|
||||
/// <summary>
|
||||
/// Top level texture width (in pixels).
|
||||
/// </summary>
|
||||
int32 Width = 0;
|
||||
API_FIELD() int32 Width = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Top level texture height (in pixels).
|
||||
/// </summary>
|
||||
int32 Height = 0;
|
||||
API_FIELD() int32 Height = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Top level texture depth (in pixels).
|
||||
/// </summary>
|
||||
int32 Depth = 0;
|
||||
API_FIELD() int32 Depth = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The texture data format.
|
||||
/// </summary>
|
||||
PixelFormat Format = PixelFormat::Unknown;
|
||||
API_FIELD() PixelFormat Format = PixelFormat::Unknown;
|
||||
|
||||
/// <summary>
|
||||
/// The items collection (depth slices or array slices).
|
||||
/// </summary>
|
||||
Array<ArrayEntry, InlinedAllocation<6>> Items;
|
||||
API_FIELD() Array<TextureDataArrayEntry, InlinedAllocation<6>> Items;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
@@ -145,3 +170,9 @@ public:
|
||||
Items.Resize(0, false);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct TIsPODType<TextureData>
|
||||
{
|
||||
enum { Value = false };
|
||||
};
|
||||
|
||||
@@ -120,7 +120,7 @@ void GPUContextDX11::FrameBegin()
|
||||
_device->_samplerLinearWrap,
|
||||
_device->_samplerPointWrap,
|
||||
_device->_samplerShadow,
|
||||
_device->_samplerShadowPCF
|
||||
_device->_samplerShadowLinear
|
||||
};
|
||||
_context->VSSetSamplers(0, ARRAY_COUNT(samplers), samplers);
|
||||
#if GPU_ALLOW_TESSELLATION_SHADERS
|
||||
@@ -159,21 +159,19 @@ bool GPUContextDX11::IsDepthBufferBinded()
|
||||
void GPUContextDX11::Clear(GPUTextureView* rt, const Color& color)
|
||||
{
|
||||
auto rtDX11 = static_cast<GPUTextureViewDX11*>(rt);
|
||||
|
||||
if (rtDX11)
|
||||
{
|
||||
_context->ClearRenderTargetView(rtDX11->RTV(), color.Raw);
|
||||
}
|
||||
}
|
||||
|
||||
void GPUContextDX11::ClearDepth(GPUTextureView* depthBuffer, float depthValue)
|
||||
void GPUContextDX11::ClearDepth(GPUTextureView* depthBuffer, float depthValue, uint8 stencilValue)
|
||||
{
|
||||
auto depthBufferDX11 = static_cast<GPUTextureViewDX11*>(depthBuffer);
|
||||
|
||||
if (depthBufferDX11)
|
||||
{
|
||||
ASSERT(depthBufferDX11->DSV());
|
||||
_context->ClearDepthStencilView(depthBufferDX11->DSV(), D3D11_CLEAR_DEPTH, depthValue, 0xff);
|
||||
_context->ClearDepthStencilView(depthBufferDX11->DSV(), D3D11_CLEAR_DEPTH, depthValue, stencilValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ public:
|
||||
void* GetNativePtr() const override;
|
||||
bool IsDepthBufferBinded() override;
|
||||
void Clear(GPUTextureView* rt, const Color& color) override;
|
||||
void ClearDepth(GPUTextureView* depthBuffer, float depthValue) override;
|
||||
void ClearDepth(GPUTextureView* depthBuffer, float depthValue, uint8 stencilValue) override;
|
||||
void ClearUA(GPUBuffer* buf, const Float4& value) override;
|
||||
void ClearUA(GPUBuffer* buf, const uint32 value[4]) override;
|
||||
void ClearUA(GPUTexture* texture, const uint32 value[4]) override;
|
||||
|
||||
@@ -227,16 +227,7 @@ GPUDevice* GPUDeviceDX11::Create()
|
||||
|
||||
GPUDeviceDX11::GPUDeviceDX11(IDXGIFactory* dxgiFactory, GPUAdapterDX* adapter)
|
||||
: GPUDeviceDX(getRendererType(adapter), getShaderProfile(adapter), adapter)
|
||||
, _device(nullptr)
|
||||
, _imContext(nullptr)
|
||||
, _factoryDXGI(dxgiFactory)
|
||||
, _mainContext(nullptr)
|
||||
, _samplerLinearClamp(nullptr)
|
||||
, _samplerPointClamp(nullptr)
|
||||
, _samplerLinearWrap(nullptr)
|
||||
, _samplerPointWrap(nullptr)
|
||||
, _samplerShadow(nullptr)
|
||||
, _samplerShadowPCF(nullptr)
|
||||
{
|
||||
Platform::MemoryClear(RasterizerStates, sizeof(RasterizerStates));
|
||||
Platform::MemoryClear(DepthStencilStates, sizeof(DepthStencilStates));
|
||||
@@ -450,14 +441,17 @@ bool GPUDeviceDX11::Init()
|
||||
{
|
||||
D3D11_SAMPLER_DESC samplerDesc;
|
||||
Platform::MemoryClear(&samplerDesc, sizeof(samplerDesc));
|
||||
samplerDesc.MinLOD = 0;
|
||||
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
|
||||
samplerDesc.MipLODBias = 0.0f;
|
||||
samplerDesc.MaxAnisotropy = 1;
|
||||
samplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL;
|
||||
|
||||
// Linear Clamp
|
||||
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
samplerDesc.MinLOD = 0;
|
||||
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
|
||||
result = _device->CreateSamplerState(&samplerDesc, &_samplerLinearClamp);
|
||||
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
|
||||
|
||||
@@ -466,8 +460,6 @@ bool GPUDeviceDX11::Init()
|
||||
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
samplerDesc.MinLOD = 0;
|
||||
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
|
||||
result = _device->CreateSamplerState(&samplerDesc, &_samplerPointClamp);
|
||||
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
|
||||
|
||||
@@ -476,8 +468,6 @@ bool GPUDeviceDX11::Init()
|
||||
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
samplerDesc.MinLOD = 0;
|
||||
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
|
||||
result = _device->CreateSamplerState(&samplerDesc, &_samplerLinearWrap);
|
||||
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
|
||||
|
||||
@@ -486,8 +476,6 @@ bool GPUDeviceDX11::Init()
|
||||
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
samplerDesc.MinLOD = 0;
|
||||
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
|
||||
result = _device->CreateSamplerState(&samplerDesc, &_samplerPointWrap);
|
||||
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
|
||||
|
||||
@@ -496,26 +484,15 @@ bool GPUDeviceDX11::Init()
|
||||
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
samplerDesc.MipLODBias = 0.0f;
|
||||
samplerDesc.MaxAnisotropy = 1;
|
||||
samplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL;
|
||||
samplerDesc.MinLOD = 0;
|
||||
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
|
||||
result = _device->CreateSamplerState(&samplerDesc, &_samplerShadow);
|
||||
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
|
||||
|
||||
// Shadow PCF
|
||||
// Shadow Linear
|
||||
samplerDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR;
|
||||
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
samplerDesc.MipLODBias = 0.0f;
|
||||
samplerDesc.MaxAnisotropy = 1;
|
||||
samplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL;
|
||||
samplerDesc.BorderColor[0] = samplerDesc.BorderColor[1] = samplerDesc.BorderColor[2] = samplerDesc.BorderColor[3] = 0;
|
||||
samplerDesc.MinLOD = 0;
|
||||
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
|
||||
result = _device->CreateSamplerState(&samplerDesc, &_samplerShadowPCF);
|
||||
result = _device->CreateSamplerState(&samplerDesc, &_samplerShadowLinear);
|
||||
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
|
||||
}
|
||||
|
||||
@@ -616,7 +593,7 @@ void GPUDeviceDX11::Dispose()
|
||||
SAFE_RELEASE(_samplerLinearWrap);
|
||||
SAFE_RELEASE(_samplerPointWrap);
|
||||
SAFE_RELEASE(_samplerShadow);
|
||||
SAFE_RELEASE(_samplerShadowPCF);
|
||||
SAFE_RELEASE(_samplerShadowLinear);
|
||||
//
|
||||
for (auto i = BlendStates.Begin(); i.IsNotEnd(); ++i)
|
||||
{
|
||||
|
||||
@@ -24,20 +24,20 @@ class GPUDeviceDX11 : public GPUDeviceDX
|
||||
private:
|
||||
|
||||
// Private Stuff
|
||||
ID3D11Device* _device;
|
||||
ID3D11DeviceContext* _imContext;
|
||||
ID3D11Device* _device = nullptr;
|
||||
ID3D11DeviceContext* _imContext = nullptr;
|
||||
IDXGIFactory* _factoryDXGI;
|
||||
|
||||
GPUContextDX11* _mainContext;
|
||||
GPUContextDX11* _mainContext = nullptr;
|
||||
bool _allowTearing = false;
|
||||
|
||||
// Static Samplers
|
||||
ID3D11SamplerState* _samplerLinearClamp;
|
||||
ID3D11SamplerState* _samplerPointClamp;
|
||||
ID3D11SamplerState* _samplerLinearWrap;
|
||||
ID3D11SamplerState* _samplerPointWrap;
|
||||
ID3D11SamplerState* _samplerShadow;
|
||||
ID3D11SamplerState* _samplerShadowPCF;
|
||||
ID3D11SamplerState* _samplerLinearClamp = nullptr;
|
||||
ID3D11SamplerState* _samplerPointClamp = nullptr;
|
||||
ID3D11SamplerState* _samplerLinearWrap = nullptr;
|
||||
ID3D11SamplerState* _samplerPointWrap = nullptr;
|
||||
ID3D11SamplerState* _samplerShadow = nullptr;
|
||||
ID3D11SamplerState* _samplerShadowLinear = nullptr;
|
||||
|
||||
// Shared data for pipeline states
|
||||
CriticalSection BlendStatesWriteLocker;
|
||||
|
||||
@@ -703,7 +703,6 @@ bool GPUContextDX12::IsDepthBufferBinded()
|
||||
void GPUContextDX12::Clear(GPUTextureView* rt, const Color& color)
|
||||
{
|
||||
auto rtDX12 = static_cast<GPUTextureViewDX12*>(rt);
|
||||
|
||||
if (rtDX12)
|
||||
{
|
||||
SetResourceState(rtDX12->GetResourceOwner(), D3D12_RESOURCE_STATE_RENDER_TARGET, rtDX12->SubresourceIndex);
|
||||
@@ -713,16 +712,15 @@ void GPUContextDX12::Clear(GPUTextureView* rt, const Color& color)
|
||||
}
|
||||
}
|
||||
|
||||
void GPUContextDX12::ClearDepth(GPUTextureView* depthBuffer, float depthValue)
|
||||
void GPUContextDX12::ClearDepth(GPUTextureView* depthBuffer, float depthValue, uint8 stencilValue)
|
||||
{
|
||||
auto depthBufferDX12 = static_cast<GPUTextureViewDX12*>(depthBuffer);
|
||||
|
||||
if (depthBufferDX12)
|
||||
{
|
||||
SetResourceState(depthBufferDX12->GetResourceOwner(), D3D12_RESOURCE_STATE_DEPTH_WRITE, depthBufferDX12->SubresourceIndex);
|
||||
flushRBs();
|
||||
|
||||
_commandList->ClearDepthStencilView(depthBufferDX12->DSV(), D3D12_CLEAR_FLAG_DEPTH, depthValue, 0xff, 0, nullptr);
|
||||
_commandList->ClearDepthStencilView(depthBufferDX12->DSV(), D3D12_CLEAR_FLAG_DEPTH, depthValue, stencilValue, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ public:
|
||||
void* GetNativePtr() const override;
|
||||
bool IsDepthBufferBinded() override;
|
||||
void Clear(GPUTextureView* rt, const Color& color) override;
|
||||
void ClearDepth(GPUTextureView* depthBuffer, float depthValue) override;
|
||||
void ClearDepth(GPUTextureView* depthBuffer, float depthValue, uint8 stencilValue) override;
|
||||
void ClearUA(GPUBuffer* buf, const Float4& value) override;
|
||||
void ClearUA(GPUBuffer* buf, const uint32 value[4]) override;
|
||||
void ClearUA(GPUTexture* texture, const uint32 value[4]) override;
|
||||
|
||||
@@ -568,7 +568,6 @@ bool GPUDeviceDX12::Init()
|
||||
// Static samplers
|
||||
D3D12_STATIC_SAMPLER_DESC staticSamplers[6];
|
||||
static_assert(GPU_STATIC_SAMPLERS_COUNT == ARRAY_COUNT(staticSamplers), "Update static samplers setup.");
|
||||
// TODO: describe visibilities for the static samples, maybe use all pixel? or again pixel + all combo?
|
||||
// Linear Clamp
|
||||
staticSamplers[0].Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
staticSamplers[0].AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||
@@ -650,8 +649,6 @@ bool GPUDeviceDX12::Init()
|
||||
staticSamplers[5].RegisterSpace = 0;
|
||||
staticSamplers[5].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
|
||||
// TODO: static samplers for the shadow pass change into bindable samplers or sth?
|
||||
|
||||
// Init
|
||||
D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc;
|
||||
rootSignatureDesc.NumParameters = ARRAY_COUNT(rootParameters);
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
void ClearDepth(GPUTextureView* depthBuffer, float depthValue) override
|
||||
void ClearDepth(GPUTextureView* depthBuffer, float depthValue, uint8 stencilValue) override
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -797,10 +797,9 @@ void GPUContextVulkan::Clear(GPUTextureView* rt, const Color& color)
|
||||
}
|
||||
}
|
||||
|
||||
void GPUContextVulkan::ClearDepth(GPUTextureView* depthBuffer, float depthValue)
|
||||
void GPUContextVulkan::ClearDepth(GPUTextureView* depthBuffer, float depthValue, uint8 stencilValue)
|
||||
{
|
||||
const auto rtVulkan = static_cast<GPUTextureViewVulkan*>(depthBuffer);
|
||||
|
||||
if (rtVulkan)
|
||||
{
|
||||
// TODO: detect if inside render pass and use ClearAttachments
|
||||
@@ -815,7 +814,7 @@ void GPUContextVulkan::ClearDepth(GPUTextureView* depthBuffer, float depthValue)
|
||||
|
||||
VkClearDepthStencilValue clear;
|
||||
clear.depth = depthValue;
|
||||
clear.stencil = 0;
|
||||
clear.stencil = stencilValue;
|
||||
vkCmdClearDepthStencilImage(cmdBuffer->GetHandle(), rtVulkan->Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear, 1, &rtVulkan->Info.subresourceRange);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ public:
|
||||
void* GetNativePtr() const override;
|
||||
bool IsDepthBufferBinded() override;
|
||||
void Clear(GPUTextureView* rt, const Color& color) override;
|
||||
void ClearDepth(GPUTextureView* depthBuffer, float depthValue) override;
|
||||
void ClearDepth(GPUTextureView* depthBuffer, float depthValue, uint8 stencilValue) override;
|
||||
void ClearUA(GPUBuffer* buf, const Float4& value) override;
|
||||
void ClearUA(GPUBuffer* buf, const uint32 value[4]) override;
|
||||
void ClearUA(GPUTexture* texture, const uint32 value[4]) override;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user