Merge remote-tracking branch 'origin/master' into 1.13
# Conflicts: # Source/Engine/Graphics/Materials/DeformableMaterialShader.h # Source/Engine/Platform/Windows/WindowsWindow.cpp # Source/Engine/Platform/Windows/WindowsWindow.h
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using FlaxEditor.Content.Settings;
|
||||
using FlaxEditor.CustomEditors.Elements;
|
||||
using FlaxEditor.GUI;
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEngine;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
@@ -13,7 +15,11 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// </summary>
|
||||
public sealed class ActorLayerEditor : CustomEditor
|
||||
{
|
||||
private const string AddOrEditLayersOption = "Add or Edit Layers...";
|
||||
|
||||
private ComboBoxElement element;
|
||||
private int _layerCount;
|
||||
private bool _updatingItems;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override DisplayStyle Style => DisplayStyle.Inline;
|
||||
@@ -22,14 +28,63 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
element = layout.ComboBox();
|
||||
element.ComboBox.SetItems(LayersAndTagsSettings.GetCurrentLayers());
|
||||
element.ComboBox.SelectedIndex = (int)Values[0];
|
||||
UpdateLayerItems((int)Values[0]);
|
||||
element.ComboBox.PopupShowing += OnPopupShowing;
|
||||
element.ComboBox.PopupShown += OnPopupShown;
|
||||
element.ComboBox.SelectedIndexChanged += OnSelectedIndexChanged;
|
||||
}
|
||||
|
||||
private void OnPopupShowing(ComboBox comboBox)
|
||||
{
|
||||
UpdateLayerItems(HasDifferentValues ? -1 : (int)Values[0]);
|
||||
}
|
||||
|
||||
private void OnPopupShown(ComboBox comboBox)
|
||||
{
|
||||
var addOrEditLayersOption = (ContextMenuButton)comboBox.Popup.Items.FirstOrDefault(x => x is FlaxEditor.GUI.ContextMenu.ContextMenuButton b && b.Text == AddOrEditLayersOption);
|
||||
addOrEditLayersOption?.Icon = Editor.Instance.Icons.Settings12;
|
||||
}
|
||||
|
||||
private void UpdateLayerItems(int selectedIndex)
|
||||
{
|
||||
_updatingItems = true;
|
||||
var layers = LayersAndTagsSettings.GetCurrentLayers();
|
||||
_layerCount = layers.Length;
|
||||
element.ComboBox.SetItems(layers);
|
||||
element.ComboBox.AddItem(AddOrEditLayersOption);
|
||||
element.ComboBox.SelectedIndex = selectedIndex >= 0 && selectedIndex < _layerCount ? selectedIndex : -1;
|
||||
_updatingItems = false;
|
||||
}
|
||||
|
||||
private void SelectCurrentLayer()
|
||||
{
|
||||
UpdateLayerItems(HasDifferentValues ? -1 : (int)Values[0]);
|
||||
}
|
||||
|
||||
private void OpenLayersAndTagsSettings()
|
||||
{
|
||||
var asset = GameSettings.LoadAsset<LayersAndTagsSettings>();
|
||||
if (!asset)
|
||||
{
|
||||
GameSettings.Save(new LayersAndTagsSettings());
|
||||
asset = GameSettings.LoadAsset<LayersAndTagsSettings>();
|
||||
}
|
||||
if (asset)
|
||||
Editor.Instance.ContentEditing.Open(asset);
|
||||
}
|
||||
|
||||
private void OnSelectedIndexChanged(ComboBox comboBox)
|
||||
{
|
||||
if (_updatingItems)
|
||||
return;
|
||||
|
||||
int value = comboBox.SelectedIndex;
|
||||
if (value == _layerCount)
|
||||
{
|
||||
OpenLayersAndTagsSettings();
|
||||
SelectCurrentLayer();
|
||||
return;
|
||||
}
|
||||
if (value == -1)
|
||||
value = 0;
|
||||
|
||||
@@ -87,7 +142,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
}
|
||||
else
|
||||
{
|
||||
element.ComboBox.SelectedIndex = (int)Values[0];
|
||||
UpdateLayerItems((int)Values[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,6 +271,11 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
for (int i = 0; i < properties.Length; i++)
|
||||
{
|
||||
var p = properties[i];
|
||||
|
||||
// Indexed properties require arguments and cannot be represented by a normal property row (eg. IList.Item[index])
|
||||
if (p.Type is PropertyInfo managedProperty && managedProperty.GetIndexParameters().Length != 0)
|
||||
continue;
|
||||
|
||||
var attributes = p.GetAttributes(true);
|
||||
var showInEditor = attributes.Any(x => x is ShowInEditorAttribute);
|
||||
|
||||
|
||||
@@ -172,6 +172,11 @@ namespace FlaxEditor.GUI
|
||||
/// </summary>
|
||||
public event Action<ComboBox> PopupShowing;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when popup is shown (after event). Can be used to customize item controls collection after creation.
|
||||
/// </summary>
|
||||
public event Action<ComboBox> PopupShown;
|
||||
|
||||
/// <summary>
|
||||
/// Custom popup creation function.
|
||||
/// </summary>
|
||||
@@ -435,6 +440,8 @@ namespace FlaxEditor.GUI
|
||||
var position = _popupMenu.RootWindow.Window.Position;
|
||||
_popupMenu.RootWindow.Window.Position = new Float2(position.X, position.Y - Height);
|
||||
}
|
||||
|
||||
PopupShown?.Invoke(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -299,7 +299,9 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
PerformLayout();
|
||||
if (UseVisibilityControl)
|
||||
{
|
||||
#if !PLATFORM_SDL
|
||||
_previouslyFocused = parentWin.FocusedControl;
|
||||
#endif
|
||||
Focus();
|
||||
OnShow();
|
||||
}
|
||||
|
||||
@@ -287,6 +287,7 @@ namespace FlaxEditor.Modules
|
||||
case Options.InterfaceOptions.PlayModeFocus.None: break;
|
||||
|
||||
case Options.InterfaceOptions.PlayModeFocus.GameWindow:
|
||||
case Options.InterfaceOptions.PlayModeFocus.GameWindowThenRestoreEditor:
|
||||
gameWin.FocusGameViewport();
|
||||
break;
|
||||
|
||||
@@ -320,6 +321,11 @@ namespace FlaxEditor.Modules
|
||||
_previousWindow.Focus();
|
||||
}
|
||||
break;
|
||||
case Options.InterfaceOptions.PlayModeFocus.GameWindowThenRestoreEditor:
|
||||
var editorWin = Editor.Windows.EditWin;
|
||||
if (editorWin != null && !editorWin.IsDisposing)
|
||||
editorWin.Focus();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -179,6 +179,11 @@ namespace FlaxEditor.Options
|
||||
/// Focus the Game Window. On play mode end restore focus to the previous window.
|
||||
/// </summary>
|
||||
GameWindowThenRestore,
|
||||
|
||||
/// <summary>
|
||||
/// Focus the Game Window. On play mode end restore focus to the editor window.
|
||||
/// </summary>
|
||||
GameWindowThenRestoreEditor
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -520,9 +525,9 @@ namespace FlaxEditor.Options
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating what panel should be focused when play mode start.
|
||||
/// </summary>
|
||||
[DefaultValue(PlayModeFocus.GameWindow)]
|
||||
[DefaultValue(PlayModeFocus.GameWindowThenRestoreEditor)]
|
||||
[EditorDisplay("Play In-Editor", "Focus On Play"), EditorOrder(500), Tooltip("Set what panel to focus on play mode start.")]
|
||||
public PlayModeFocus FocusOnPlayMode { get; set; } = PlayModeFocus.GameWindow;
|
||||
public PlayModeFocus FocusOnPlayMode { get; set; } = PlayModeFocus.GameWindowThenRestoreEditor;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating what action should be taken upon pressing the play button.
|
||||
|
||||
@@ -809,10 +809,12 @@ namespace FlaxEditor.Viewport
|
||||
/// <inheritdoc />
|
||||
public override DragDropEffect OnDragMove(ref Float2 location, DragData data)
|
||||
{
|
||||
DragHandlers.ClearDragEffects();
|
||||
var result = base.OnDragMove(ref location, data);
|
||||
if (result != DragDropEffect.None)
|
||||
{
|
||||
DragHandlers.ClearDragEffects();
|
||||
return result;
|
||||
}
|
||||
return DragHandlers.DragEnter(ref location, data);
|
||||
}
|
||||
|
||||
|
||||
@@ -647,10 +647,12 @@ namespace FlaxEditor.Viewport
|
||||
/// <inheritdoc />
|
||||
public override DragDropEffect OnDragMove(ref Float2 location, DragData data)
|
||||
{
|
||||
DragHandlers.ClearDragEffects();
|
||||
var result = base.OnDragMove(ref location, data);
|
||||
if (result != DragDropEffect.None)
|
||||
{
|
||||
DragHandlers.ClearDragEffects();
|
||||
return result;
|
||||
}
|
||||
return DragHandlers.DragEnter(ref location, data);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace FlaxEditor.Viewport
|
||||
{
|
||||
if (_previewStaticModel)
|
||||
debugDrawData.HighlightModel(_previewStaticModel, _previewModelEntryIndex);
|
||||
if (_previewBrushSurface.Brush != null)
|
||||
if (_previewBrushSurface.Brush)
|
||||
debugDrawData.HighlightBrushSurface(_previewBrushSurface);
|
||||
}
|
||||
|
||||
@@ -120,10 +120,12 @@ namespace FlaxEditor.Viewport
|
||||
if (_dragAssets.HasValidDrag && _dragAssets.Objects[0].IsOfType<MaterialBase>())
|
||||
{
|
||||
GetHitLocation(ref location, out var hit, out _, out _);
|
||||
ClearDragEffects();
|
||||
var material = FlaxEngine.Content.LoadAsync<MaterialBase>(_dragAssets.Objects[0].ID);
|
||||
if (material.IsDecal)
|
||||
if (material && material.IsDecal)
|
||||
{
|
||||
ClearDragEffects();
|
||||
return;
|
||||
}
|
||||
|
||||
if (hit is StaticModelNode staticModelNode)
|
||||
{
|
||||
@@ -135,6 +137,14 @@ namespace FlaxEditor.Viewport
|
||||
{
|
||||
_previewBrushSurface = brushSurfaceNode.Surface;
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearDragEffects();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearDragEffects();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,8 @@ namespace FlaxEditor
|
||||
/// <param name="surface">The surface.</param>
|
||||
public void HighlightBrushSurface(BrushSurface surface)
|
||||
{
|
||||
if (surface.Brush == null)
|
||||
return;
|
||||
surface.Brush.GetVertices(surface.Index, out var vertices);
|
||||
if (vertices.Length > 0)
|
||||
{
|
||||
|
||||
@@ -768,9 +768,11 @@ namespace FlaxEditor.Windows
|
||||
_newElement.Dispose();
|
||||
_newElement = null;
|
||||
|
||||
#if !PLATFORM_SDL
|
||||
// Focus content window
|
||||
Focus();
|
||||
RootWindow?.Focus();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Refresh database and view now
|
||||
|
||||
@@ -147,21 +147,27 @@ namespace FlaxEditor.Windows
|
||||
new PlayModeFocusOptions
|
||||
{
|
||||
Name = "None",
|
||||
Tooltip = "Don't change focus.",
|
||||
Tooltip = "Don't change window focus when entering play mode.",
|
||||
FocusOption = InterfaceOptions.PlayModeFocus.None,
|
||||
},
|
||||
new PlayModeFocusOptions
|
||||
{
|
||||
Name = "Game Window",
|
||||
Tooltip = "Focus the Game Window.",
|
||||
Tooltip = "Focus the Game Window when entering play mode.",
|
||||
FocusOption = InterfaceOptions.PlayModeFocus.GameWindow,
|
||||
},
|
||||
new PlayModeFocusOptions
|
||||
{
|
||||
Name = "Game Window Then Restore",
|
||||
Tooltip = "Focus the Game Window. On play mode end restore focus to the previous window.",
|
||||
Tooltip = "Focus the Game Window when entering play mode. Restore focus to the previous window when exiting play mode.",
|
||||
FocusOption = InterfaceOptions.PlayModeFocus.GameWindowThenRestore,
|
||||
},
|
||||
new PlayModeFocusOptions
|
||||
{
|
||||
Name = "Game Window Then Restore Editor",
|
||||
Tooltip = "Focus the Game Window when entering play mode and then restore the focus to the editor window when exiting play mode.",
|
||||
FocusOption = InterfaceOptions.PlayModeFocus.GameWindowThenRestoreEditor
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -148,13 +148,13 @@ public:
|
||||
Quality GIQuality = Quality::High;
|
||||
|
||||
/// <summary>
|
||||
/// The Global Illumination probes spacing distance (in world units). Defines the quality of the GI resolution. Adjust to 200-500 to improve performance and lower frequency GI data.
|
||||
/// The global spacing between Global Illumination probes (in world units). Smaller values improve interior detail at a higher GPU cost. Values around 100-150 are a useful starting point for mixed interiors and exteriors; adjust to 200-500 for mostly outdoor scenes and lower-frequency GI. Changing this value recreates the DDGI probe resources and can change the automatic cascade layout.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(2120), Limit(50, 1000), EditorDisplay(\"Global Illumination\"), ValueCategory(Utils.ValueCategory.Distance)")
|
||||
float GIProbesSpacing = 100;
|
||||
|
||||
/// <summary>
|
||||
/// Enables cascades splits blending for Global Illumination.
|
||||
/// Enables smooth blending between Global Illumination cascade splits. If disabled, the transition uses dithering intended for temporal anti-aliasing. Smooth blending can expose rounded cascade boundaries when adjacent cascades contain significantly different lighting.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(2125), EditorDisplay(\"Global Illumination\", \"GI Cascades Blending\")")
|
||||
bool GICascadesBlending = false;
|
||||
|
||||
@@ -217,8 +217,6 @@ void Screen::SetGameWindowMode(GameWindowMode windowMode)
|
||||
switch (windowMode)
|
||||
{
|
||||
case GameWindowMode::Windowed:
|
||||
if (GetIsFullscreen())
|
||||
SetIsFullscreen(false);
|
||||
win->SetBorderless(false, false);
|
||||
break;
|
||||
case GameWindowMode::Fullscreen:
|
||||
@@ -279,7 +277,11 @@ void ScreenService::Draw()
|
||||
auto win = Engine::MainWindow;
|
||||
if (win)
|
||||
{
|
||||
win->SetClientSize(Size.GetValue());
|
||||
Float2 sizeDelta = Size.GetValue() - win->GetClientSize();
|
||||
Rectangle newBiunds(win->GetClientPosition(), Size.GetValue());
|
||||
if (!win->IsMaximized())
|
||||
newBiunds -= sizeDelta * 0.5f;
|
||||
win->SetClientBounds(newBiunds);
|
||||
}
|
||||
|
||||
Size.Reset();
|
||||
|
||||
@@ -112,6 +112,7 @@ bool DeformableMaterialShader::Load()
|
||||
auto psDesc = GPUPipelineState::Description::Default;
|
||||
psDesc.DepthEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthTest) == MaterialFeaturesFlags::None;
|
||||
psDesc.DepthWriteEnable = (_info.FeaturesFlags & MaterialFeaturesFlags::DisableDepthWrite) == MaterialFeaturesFlags::None;
|
||||
psDesc.VS = _shader->GetVS("VS_SplineModel");
|
||||
|
||||
#if GPU_ALLOW_TESSELLATION_SHADERS
|
||||
// Check if use tessellation (both material and runtime supports it)
|
||||
@@ -127,7 +128,6 @@ bool DeformableMaterialShader::Load()
|
||||
if (_shader->HasShader("PS_QuadOverdraw"))
|
||||
{
|
||||
// Quad Overdraw
|
||||
psDesc.VS = _shader->GetVS("VS_SplineModel");
|
||||
psDesc.PS = _shader->GetPS("PS_QuadOverdraw");
|
||||
_cache.QuadOverdraw.Init(psDesc);
|
||||
}
|
||||
@@ -142,7 +142,6 @@ bool DeformableMaterialShader::Load()
|
||||
psDesc.StencilPassOp = StencilOperation::Replace;
|
||||
|
||||
// GBuffer Pass
|
||||
psDesc.VS = _shader->GetVS("VS_SplineModel");
|
||||
psDesc.PS = _shader->GetPS("PS_GBuffer");
|
||||
_cache.Default.Init(psDesc);
|
||||
|
||||
@@ -154,7 +153,6 @@ bool DeformableMaterialShader::Load()
|
||||
_drawModes |= DrawPass::Forward;
|
||||
|
||||
// Forward Pass
|
||||
psDesc.VS = _shader->GetVS("VS_SplineModel");
|
||||
psDesc.PS = _shader->GetPS("PS_Forward");
|
||||
psDesc.DepthWriteEnable = false;
|
||||
psDesc.BlendMode = BlendingMode::AlphaBlend;
|
||||
@@ -171,6 +169,18 @@ bool DeformableMaterialShader::Load()
|
||||
break;
|
||||
}
|
||||
_cache.Default.Init(psDesc);
|
||||
|
||||
// Check if use transparent distortion pass
|
||||
if (_shader->HasShader("PS_Distortion"))
|
||||
{
|
||||
_drawModes |= DrawPass::Distortion;
|
||||
|
||||
// Accumulate Distortion Pass
|
||||
psDesc.PS = _shader->GetPS("PS_Distortion");
|
||||
psDesc.BlendMode = BlendingMode::Add;
|
||||
psDesc.DepthWriteEnable = false;
|
||||
_cache.Distortion.Init(psDesc);
|
||||
}
|
||||
}
|
||||
|
||||
// Depth Pass
|
||||
|
||||
@@ -14,6 +14,7 @@ private:
|
||||
{
|
||||
PipelineStateCache Default;
|
||||
PipelineStateCache Depth;
|
||||
PipelineStateCache Distortion;
|
||||
#if GPU_ENABLE_DEVELOPMENT
|
||||
PipelineStateCache QuadOverdraw;
|
||||
#endif
|
||||
@@ -29,6 +30,8 @@ private:
|
||||
case DrawPass::GlobalSurfaceAtlas:
|
||||
case DrawPass::Forward:
|
||||
return &Default;
|
||||
case DrawPass::Distortion:
|
||||
return &Distortion;
|
||||
#if GPU_ENABLE_DEVELOPMENT
|
||||
case DrawPass::QuadOverdraw:
|
||||
return &QuadOverdraw;
|
||||
@@ -42,6 +45,7 @@ private:
|
||||
{
|
||||
Default.Release();
|
||||
Depth.Release();
|
||||
Distortion.Release();
|
||||
#if GPU_ENABLE_DEVELOPMENT
|
||||
QuadOverdraw.Release();
|
||||
#endif
|
||||
|
||||
@@ -416,7 +416,7 @@ API_STRUCT() struct FLAXENGINE_API GlobalIlluminationSettings : ISerializable
|
||||
float TemporalResponse = 0.9f;
|
||||
|
||||
/// <summary>
|
||||
/// Draw distance of the Global Illumination effect. Scene outside the range will use fallback irradiance.
|
||||
/// Camera-centered draw distance of the Global Illumination effect. Scene outside the range will use fallback irradiance. DDGI automatically derives its cascade layout from this distance and the global probe spacing, so continuously blending this value can recreate probe resources and cause a visible lighting reset.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(30), Limit(1000), PostProcessSetting((int)GlobalIlluminationSettingsOverride.Distance), ValueCategory(Utils.ValueCategory.Distance)")
|
||||
float Distance = 20000.0f;
|
||||
|
||||
@@ -589,7 +589,18 @@ bool GPUDeviceDX11::Init()
|
||||
else
|
||||
#endif
|
||||
{
|
||||
VALIDATE_DIRECTX_CALL(D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, flags, &targetFeatureLevel, 1, D3D11_SDK_VERSION, &_device, &createdFeatureLevel, &_imContext));
|
||||
HRESULT createResult = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, flags, &targetFeatureLevel, 1, D3D11_SDK_VERSION, &_device, &createdFeatureLevel, &_imContext);
|
||||
#if GPU_ENABLE_DEBUG_LAYER
|
||||
if (createResult == DXGI_ERROR_SDK_COMPONENT_MISSING)
|
||||
{
|
||||
// The Direct3D debug layer is an optional Windows component
|
||||
flags &= ~D3D11_CREATE_DEVICE_DEBUG;
|
||||
createResult = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, flags, &targetFeatureLevel, 1, D3D11_SDK_VERSION, &_device, &createdFeatureLevel, &_imContext);
|
||||
if (SUCCEEDED(createResult))
|
||||
LOG(Warning, "Direct3D SDK debug layers were requested, but not available. Continuing without them.");
|
||||
}
|
||||
#endif
|
||||
VALIDATE_DIRECTX_CALL(createResult);
|
||||
}
|
||||
if (!_device || !_imContext)
|
||||
return true;
|
||||
|
||||
@@ -162,11 +162,8 @@ void GPUSwapChainDX11::Present(bool vsync)
|
||||
|
||||
bool GPUSwapChainDX11::Resize(int32 width, int32 height)
|
||||
{
|
||||
// Check if size won't change
|
||||
if (width == _width && height == _height)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_device->WaitForGPU();
|
||||
GPUDeviceLock lock(_device);
|
||||
@@ -174,6 +171,10 @@ bool GPUSwapChainDX11::Resize(int32 width, int32 height)
|
||||
_allowTearing = _device->_allowTearing;
|
||||
#endif
|
||||
_format = GPU_BACK_BUFFER_PIXEL_FORMAT;
|
||||
if (_memoryUsage != 0)
|
||||
{
|
||||
PROFILE_MEM_DEC(Graphics, _memoryUsage);
|
||||
}
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
DXGI_SWAP_CHAIN_DESC swapChainDesc;
|
||||
|
||||
@@ -1802,7 +1802,11 @@ const String& LinuxPlatform::GetHomeDirectory()
|
||||
|
||||
String LinuxPlatform::GetDisplayServer()
|
||||
{
|
||||
#if PLATFORM_SDL
|
||||
return SDLPlatform::GetDisplayServer();
|
||||
#else
|
||||
return xDisplay ? TEXT("X11") : TEXT("");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool LinuxPlatform::Is64BitPlatform()
|
||||
|
||||
@@ -297,12 +297,10 @@ namespace WaylandImpl
|
||||
textData.Text = *DraggingData;
|
||||
wl_data_source_add_listener(dataSource, &DataSourceListener, &textData);
|
||||
|
||||
// Begin dragging operation
|
||||
auto draggedWindow = Window->GetSDLWindow();
|
||||
auto dragStartWindow = DragSourceWindow != nullptr ? DragSourceWindow->GetSDLWindow() : draggedWindow;
|
||||
wl_surface* originSurface = static_cast<wl_surface*>(SDL_GetPointerProperty(SDL_GetWindowProperties(dragStartWindow), SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, nullptr));
|
||||
wl_surface* iconSurface = nullptr;
|
||||
wl_data_device_start_drag(WrappedDataDevice, dataSource, originSurface, iconSurface, DragSerial);
|
||||
|
||||
Platform::AtomicStore(&StartFlag, 1);
|
||||
|
||||
@@ -321,11 +319,13 @@ namespace WaylandImpl
|
||||
if (Platform::AtomicRead(&DragOverFlag) == 1 || Platform::AtomicRead(&Serial) != DragSerial)
|
||||
break;
|
||||
|
||||
// Attach the window to the ongoing drag operation
|
||||
// Begin dragging operation
|
||||
wrappedToplevel = static_cast<xdg_toplevel*>(wl_proxy_create_wrapper(toplevel));
|
||||
wl_proxy_set_queue(reinterpret_cast<wl_proxy*>(wrappedToplevel), EventQueue);
|
||||
toplevelDrag = xdg_toplevel_drag_manager_v1_get_xdg_toplevel_drag(DragManager, dataSource);
|
||||
|
||||
wl_data_device_start_drag(WrappedDataDevice, dataSource, originSurface, iconSurface, DragSerial);
|
||||
|
||||
// Attach the window to the ongoing drag operation
|
||||
Float2 scaledOffset = DragOffset / Window->GetDpiScale();
|
||||
xdg_toplevel_drag_v1_attach(toplevelDrag, wrappedToplevel, static_cast<int32>(scaledOffset.X), static_cast<int32>(scaledOffset.Y));
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "WindowsWindow.h"
|
||||
#include "WindowsPlatform.h"
|
||||
#include "WindowsInput.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Engine/Engine.h"
|
||||
#include "Engine/Core/Math/Math.h"
|
||||
#include "Engine/Core/Math/Color32.h"
|
||||
#include "Engine/Graphics/GPUSwapChain.h"
|
||||
@@ -267,8 +267,13 @@ void WindowsWindow::SetBorderless(bool isBorderless, bool maximized)
|
||||
{
|
||||
ASSERT(HasHWND());
|
||||
|
||||
Float2 preserveSize(0, 0);
|
||||
if (IsFullscreen())
|
||||
{
|
||||
if (_swapChain && !maximized)
|
||||
preserveSize = _swapChain->GetSize();
|
||||
SetIsFullscreen(false);
|
||||
}
|
||||
|
||||
// Fixes issue of borderless window not going full screen
|
||||
if (IsMaximized())
|
||||
@@ -303,6 +308,16 @@ void WindowsWindow::SetBorderless(bool isBorderless, bool maximized)
|
||||
{
|
||||
ShowWindow(_handle, SW_SHOW);
|
||||
}
|
||||
|
||||
// Maintain resolution when going out the fullscreen
|
||||
if (preserveSize != Float2::Zero)
|
||||
{
|
||||
Int4 monitorBounds;
|
||||
GetScreenInfo(monitorBounds.X, monitorBounds.Y, monitorBounds.Z, monitorBounds.W);
|
||||
monitorBounds.X += (monitorBounds.Z - (int32)preserveSize.X) / 2;
|
||||
monitorBounds.Y += (monitorBounds.W - (int32)preserveSize.Y) / 2;
|
||||
SetWindowPos(_handle, nullptr, monitorBounds.X, monitorBounds.Y, (int32)preserveSize.X, (int32)preserveSize.Y, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -315,13 +330,22 @@ void WindowsWindow::SetBorderless(bool isBorderless, bool maximized)
|
||||
if (_settings.HasSizingFrame)
|
||||
lStyle |= WS_THICKFRAME;
|
||||
lStyle |= WS_OVERLAPPED | WS_SYSMENU | WS_BORDER | WS_CAPTION;
|
||||
|
||||
SetWindowLong(_handle, GWL_STYLE, lStyle);
|
||||
|
||||
const Float2 clientSize = GetClientSize();
|
||||
const Float2 desktopSize = Platform::GetDesktopSize();
|
||||
// Move window and half size if it is larger than desktop size
|
||||
if (clientSize.X >= desktopSize.X && clientSize.Y >= desktopSize.Y)
|
||||
if (preserveSize != Float2::Zero)
|
||||
{
|
||||
// Maintain resolution when going out the fullscreen
|
||||
Int4 monitorBounds;
|
||||
GetScreenInfo(monitorBounds.X, monitorBounds.Y, monitorBounds.Z, monitorBounds.W);
|
||||
monitorBounds.X += (monitorBounds.Z - (int32)preserveSize.X) / 2;
|
||||
monitorBounds.Y += (monitorBounds.W - (int32)preserveSize.Y) / 2;
|
||||
SetWindowPos(_handle, nullptr, monitorBounds.X, monitorBounds.Y, (int32)preserveSize.X, (int32)preserveSize.Y, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
}
|
||||
else if (clientSize.X >= desktopSize.X && clientSize.Y >= desktopSize.Y)
|
||||
{
|
||||
// Move window and half size if it is larger than desktop size
|
||||
const Float2 halfSize = desktopSize * 0.5f;
|
||||
const Float2 middlePos = halfSize * 0.5f;
|
||||
SetWindowPos(_handle, nullptr, (int)middlePos.X, (int)middlePos.Y, (int)halfSize.X, (int)halfSize.Y, SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
@@ -411,6 +435,17 @@ void WindowsWindow::SetClientBounds(const Rectangle& clientArea)
|
||||
int32 width = (int32)clientArea.GetWidth();
|
||||
int32 height = (int32)clientArea.GetHeight();
|
||||
|
||||
// Resize during fullscreen
|
||||
if (changeSize && _swapChain && _swapChain->IsFullscreen())
|
||||
{
|
||||
// Go out fullscreen, resize, and then go back in
|
||||
_swapChain->SetFullscreen(false);
|
||||
_clientSize = clientArea.Size;
|
||||
OnResize(width, height);
|
||||
_swapChain->SetFullscreen(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (changeSize)
|
||||
{
|
||||
_clientSize = clientArea.Size;
|
||||
@@ -763,7 +798,7 @@ void WindowsWindow::DestroyCursorImage(void* image)
|
||||
::DestroyCursor((HCURSOR)image);
|
||||
}
|
||||
|
||||
void WindowsWindow::CheckForWindowResize()
|
||||
void WindowsWindow::CheckForWindowResize(bool force)
|
||||
{
|
||||
// Skip for minimized window (GetClientRect for minimized window returns 0)
|
||||
if (_minimized)
|
||||
@@ -798,7 +833,7 @@ void WindowsWindow::CheckForWindowResize()
|
||||
_clientSize = Float2(static_cast<float>(width), static_cast<float>(height));
|
||||
|
||||
// Check if window size has been changed
|
||||
if (width > 0 && height > 0 && (_swapChain == nullptr || width != _swapChain->GetWidth() || height != _swapChain->GetHeight()))
|
||||
if (width > 0 && height > 0 && (force || _swapChain == nullptr || width != _swapChain->GetWidth() || height != _swapChain->GetHeight()))
|
||||
{
|
||||
UpdateRegion();
|
||||
OnResize(width, height);
|
||||
@@ -926,16 +961,24 @@ LRESULT WindowsWindow::WndProc(UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
case WM_PAINT:
|
||||
{
|
||||
// Check if window is during resizing
|
||||
if (_isResizing && _swapChain)
|
||||
if ((_isResizing || _forceRedrawOnPaint) && _swapChain)
|
||||
{
|
||||
// Redraw window backbuffer on DX11
|
||||
switch (GPUDevice::Instance->GetRendererType())
|
||||
_forceRedrawOnPaint = false;
|
||||
if (GPUDevice::Instance && !GPUDevice::Instance->IsRendering() && GPUDevice::Instance->CanDraw())
|
||||
{
|
||||
case RendererType::DirectX10:
|
||||
case RendererType::DirectX10_1:
|
||||
case RendererType::DirectX11:
|
||||
_swapChain->Present(false);
|
||||
break;
|
||||
Engine::OnDraw();
|
||||
}
|
||||
else if (GPUDevice::Instance)
|
||||
{
|
||||
// Redraw window backbuffer on DX11
|
||||
switch (GPUDevice::Instance->GetRendererType())
|
||||
{
|
||||
case RendererType::DirectX10:
|
||||
case RendererType::DirectX10_1:
|
||||
case RendererType::DirectX11:
|
||||
_swapChain->Present(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1235,8 +1278,8 @@ LRESULT WindowsWindow::WndProc(UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
else if (_isResizing)
|
||||
{
|
||||
// If we're neither maximized nor minimized, the window size is changing by the user dragging the window edges.
|
||||
// In this case, we don't resize yet -- we wait until the user stops dragging, and a WM_EXITSIZEMOVE message comes.
|
||||
UpdateRegion();
|
||||
CheckForWindowResize();
|
||||
RedrawWindow(_handle, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW);
|
||||
}
|
||||
else if (_isSwitchingFullScreen)
|
||||
{
|
||||
@@ -1258,6 +1301,10 @@ LRESULT WindowsWindow::WndProc(UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
_dpiScale = (float)_dpi / (float)DefaultDPI;
|
||||
RECT* windowRect = (RECT*)lParam;
|
||||
SetWindowPos(_handle, nullptr, windowRect->left, windowRect->top, windowRect->right - windowRect->left, windowRect->bottom - windowRect->top, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
CheckForWindowResize(true);
|
||||
UpdateRegion();
|
||||
_forceRedrawOnPaint = true;
|
||||
RedrawWindow(_handle, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW);
|
||||
// TODO: Recalculate fonts
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ private:
|
||||
Windows::ULONG _refCount;
|
||||
#endif
|
||||
bool _isResizing = false;
|
||||
bool _forceRedrawOnPaint = false;
|
||||
bool _isSwitchingFullScreen = false;
|
||||
bool _trackingMouse = false;
|
||||
bool _clipCursorSet = false;
|
||||
@@ -87,7 +88,7 @@ public:
|
||||
Windows::LRESULT WndProc(Windows::UINT msg, Windows::WPARAM wParam, Windows::LPARAM lParam);
|
||||
|
||||
private:
|
||||
void CheckForWindowResize();
|
||||
void CheckForWindowResize(bool force = false);
|
||||
void UpdateCursor();
|
||||
void UpdateRegion();
|
||||
|
||||
|
||||
@@ -271,6 +271,7 @@ void PostProcessingPass::Render(RenderContext& renderContext, GPUTexture* input,
|
||||
int32 h4 = h2 >> 1;
|
||||
int32 h8 = h4 >> 1;
|
||||
int32 bloomMipCount = CalculateBloomMipCount(w1, h1);
|
||||
useLensFlares &= bloomMipCount > 1;
|
||||
|
||||
// Ensure to have valid data and if at least one effect should be applied
|
||||
if (!(useBloom || useToneMapping || useCameraArtifacts || colorGradingLUT) || checkIfSkipPass() || w8 <= 1 || h8 <= 1)
|
||||
@@ -451,7 +452,7 @@ void PostProcessingPass::Render(RenderContext& renderContext, GPUTexture* input,
|
||||
// Set bloom output
|
||||
context->UnBindSR(0);
|
||||
context->UnBindSR(1);
|
||||
context->BindSR(2, bloomBuffer2->View(0, 0));
|
||||
context->BindSR(2, (bloomMipCount > 1 ? bloomBuffer2 : bloomBuffer1)->View(0, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -246,7 +246,9 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo
|
||||
ADD_FEATURE(TessellationFeature);
|
||||
if (isOpaque)
|
||||
ADD_FEATURE(DeferredShadingFeature);
|
||||
if (materialInfo.BlendMode != MaterialBlendMode::Opaque)
|
||||
if (!isOpaque && (materialInfo.FeaturesFlags & MaterialFeaturesFlags::DisableDistortion) == MaterialFeaturesFlags::None)
|
||||
ADD_FEATURE(DistortionFeature);
|
||||
if (!isOpaque)
|
||||
ADD_FEATURE(ForwardShadingFeature);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -383,10 +383,12 @@ void CS_UpdateProbesInitArgs()
|
||||
{
|
||||
uint activeProbesCount = ActiveProbes.Load(0); // Counter at 0
|
||||
activeProbesCount = min(activeProbesCount, ProbesCount);
|
||||
// The CPU submits every allocated batch, so always overwrite all arguments to avoid
|
||||
// dispatching stale work left by a previous cascade or frame.
|
||||
uint arg = 0;
|
||||
for (uint probesOffset = 0; probesOffset < activeProbesCount; probesOffset += DDGI_TRACE_RAYS_PROBES_COUNT_LIMIT)
|
||||
for (uint probesOffset = 0; probesOffset < ProbesCount; probesOffset += DDGI_TRACE_RAYS_PROBES_COUNT_LIMIT)
|
||||
{
|
||||
uint probesBatchSize = min(activeProbesCount - probesOffset, DDGI_TRACE_RAYS_PROBES_COUNT_LIMIT);
|
||||
uint probesBatchSize = probesOffset < activeProbesCount ? min(activeProbesCount - probesOffset, DDGI_TRACE_RAYS_PROBES_COUNT_LIMIT) : 0;
|
||||
UpdateProbesInitArgs[arg++] = probesBatchSize;
|
||||
UpdateProbesInitArgs[arg++] = 1;
|
||||
UpdateProbesInitArgs[arg++] = 1;
|
||||
|
||||
Reference in New Issue
Block a user