Editor gui v2 (#843)

This commit is contained in:
Turánszki János
2024-05-17 08:04:05 +02:00
committed by GitHub
parent 92c199fe9d
commit 1c38d93304
77 changed files with 4283 additions and 3365 deletions
+2 -2
View File
@@ -21,7 +21,7 @@ void AnimationWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 80;
@@ -922,7 +922,7 @@ void AnimationWindow::Create(EditorComponent* _editor)
}
scene.names.Create(retarget_entity) = name;
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
}
});
AddWidget(&retargetCombo);
+2 -2
View File
@@ -22,7 +22,7 @@ void ArmatureWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 60;
@@ -217,7 +217,7 @@ void ArmatureWindow::Create(EditorComponent* _editor)
// record NEW selection state...
editor->RecordSelection(archive);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
AddWidget(&boneList);
-1
View File
@@ -38,7 +38,6 @@ set (SOURCE_FILES
HierarchyWindow.cpp
ExpressionWindow.cpp
ArmatureWindow.cpp
OptionsWindow.cpp
ComponentsWindow.cpp
TerrainWindow.cpp
HumanoidWindow.cpp
+1 -1
View File
@@ -81,7 +81,7 @@ void CameraComponentWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 140;
+6 -6
View File
@@ -33,11 +33,13 @@ void CameraWindow::ResetCam()
void CameraWindow::Create(EditorComponent* _editor)
{
editor = _editor;
wi::gui::Window::Create("Camera", wi::gui::Window::WindowControls::COLLAPSE);
wi::gui::Window::Create("Camera", wi::gui::Window::WindowControls::CLOSE | wi::gui::Window::WindowControls::RESIZE_RIGHT);
SetText("Camera " ICON_CAMERAOPTIONS);
editor->GetCurrentEditorScene().camera_transform.MatrixTransform(editor->GetCurrentEditorScene().camera.GetInvView());
editor->GetCurrentEditorScene().camera_transform.UpdateTransform();
SetSize(XMFLOAT2(320, 390));
SetSize(XMFLOAT2(300, 390));
float x = 140;
float y = 0;
@@ -257,7 +259,7 @@ void CameraWindow::Create(EditorComponent* _editor)
editor->RecordSelection(archive);
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
SetEntity(entity);
});
AddWidget(&proxyButton);
@@ -277,9 +279,7 @@ void CameraWindow::Create(EditorComponent* _editor)
SetEntity(INVALID_ENTITY);
SetPos(XMFLOAT2(100, 100));
SetMinimized(true);
SetVisible(false);
}
void CameraWindow::SetEntity(Entity entity)
+1 -1
View File
@@ -22,7 +22,7 @@ void ColliderWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 60;
File diff suppressed because it is too large Load Diff
+49
View File
@@ -74,4 +74,53 @@ public:
SpriteWindow spriteWnd;
FontWindow fontWnd;
VoxelGridWindow voxelGridWnd;
enum class Filter : uint64_t
{
Transform = 1 << 0,
Material = 1 << 1,
Mesh = 1 << 2,
Object = 1 << 3,
EnvironmentProbe = 1 << 4,
Decal = 1 << 5,
Sound = 1 << 6,
Weather = 1 << 7,
Light = 1 << 8,
Animation = 1 << 9,
Force = 1 << 10,
Emitter = 1 << 11,
Hairparticle = 1 << 12,
IK = 1 << 13,
Camera = 1 << 14,
Armature = 1 << 15,
Collider = 1 << 16,
Script = 1 << 17,
Expression = 1 << 18,
Terrain = 1 << 19,
Spring = 1 << 20,
Humanoid = 1 << 21,
Video = 1 << 22,
Sprite = 1 << 23,
Font = 1 << 24,
VoxelGrid = 1 << 25,
RigidBody = 1 << 26,
SoftBody = 1 << 27,
All = ~0ull,
} filter = Filter::All;
wi::gui::ComboBox filterCombo;
wi::gui::TextInputField filterInput;
wi::gui::CheckBox filterCaseCheckBox;
wi::gui::TreeList entityTree;
wi::unordered_set<wi::ecs::Entity> entitytree_temp_items;
wi::unordered_set<wi::ecs::Entity> entitytree_added_items;
wi::unordered_set<wi::ecs::Entity> entitytree_opened_items;
void PushToEntityTree(wi::ecs::Entity entity, int level);
void RefreshEntityTree();
bool CheckEntityFilter(wi::ecs::Entity entity);
};
template<>
struct enable_bitmask_operators<ComponentsWindow::Filter> {
static const bool enable = true;
};
+2 -23
View File
@@ -9,9 +9,7 @@ void ContentBrowserWindow::Create(EditorComponent* _editor)
editor = _editor;
control_size = 30;
wi::gui::Window::WindowControls controls = wi::gui::Window::WindowControls::ALL;
controls &= ~wi::gui::Window::WindowControls::RESIZE_BOTTOMLEFT;
wi::gui::Window::Create("Content Browser", controls);
wi::gui::Window::Create("Content Browser");
RemoveWidget(&scrollbar_horizontal);
@@ -49,25 +47,6 @@ void ContentBrowserWindow::Update(const wi::Canvas& canvas, float dt)
sprites[i].params.corners_rounding[1].radius = radius;
sprites[i].params.corners_rounding[2].radius = radius;
sprites[i].params.corners_rounding[3].radius = radius;
resizeDragger_UpperLeft.sprites[i].params.enableCornerRounding();
resizeDragger_UpperLeft.sprites[i].params.corners_rounding[0].radius = radius;
resizeDragger_UpperRight.sprites[i].params.enableCornerRounding();
resizeDragger_UpperRight.sprites[i].params.corners_rounding[1].radius = radius;
resizeDragger_BottomLeft.sprites[i].params.enableCornerRounding();
resizeDragger_BottomLeft.sprites[i].params.corners_rounding[2].radius = radius;
resizeDragger_BottomRight.sprites[i].params.enableCornerRounding();
resizeDragger_BottomRight.sprites[i].params.corners_rounding[3].radius = radius;
if (IsCollapsed())
{
resizeDragger_UpperLeft.sprites[i].params.corners_rounding[2].radius = radius;
resizeDragger_UpperRight.sprites[i].params.corners_rounding[3].radius = radius;
}
else
{
resizeDragger_UpperLeft.sprites[i].params.corners_rounding[2].radius = 0;
resizeDragger_UpperRight.sprites[i].params.corners_rounding[3].radius = 0;
}
openFolderButton.sprites[i].params.enableCornerRounding();
openFolderButton.sprites[i].params.corners_rounding[0].radius = radius;
@@ -353,7 +332,7 @@ void ContentBrowserWindow::SetSelection(SELECTION selection)
}
// Refresh theme:
editor->optionsWnd.generalWnd.themeCombo.SetSelected(editor->optionsWnd.generalWnd.themeCombo.GetSelected());
editor->generalWnd.themeCombo.SetSelected(editor->generalWnd.themeCombo.GetSelected());
});
}
+1 -1
View File
@@ -22,7 +22,7 @@ void DecalWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 200;
+951 -402
View File
File diff suppressed because it is too large Load Diff
+34 -22
View File
@@ -1,22 +1,16 @@
#pragma once
#include "Translator.h"
#include "wiScene_BindLua.h"
#include "OptionsWindow.h"
#include "ComponentsWindow.h"
#include "ProfilerWindow.h"
#include "ContentBrowserWindow.h"
#include "GraphicsWindow.h"
#include "CameraWindow.h"
#include "MaterialPickerWindow.h"
#include "PaintToolWindow.h"
#include "GeneralWindow.h"
#include "IconDefinitions.h"
class EditorLoadingScreen : public wi::LoadingScreen
{
private:
wi::Sprite sprite;
wi::SpriteFont font;
public:
void Load() override;
void Update(float dt) override;
};
class Editor;
class EditorComponent : public wi::RenderPath2D
{
@@ -25,6 +19,8 @@ public:
wi::gui::Button newSceneButton;
wi::gui::ComboBox newEntityCombo;
wi::gui::Button translateButton;
wi::gui::Button rotateButton;
wi::gui::Button scaleButton;
@@ -58,10 +54,22 @@ public:
wi::gui::Window aboutWindow;
wi::gui::Label aboutLabel;
OptionsWindow optionsWnd;
ComponentsWindow componentsWnd;
ProfilerWindow profilerWnd;
ContentBrowserWindow contentBrowserWnd;
wi::gui::Window topmenuWnd;
wi::gui::Button generalButton;
wi::gui::Button graphicsButton;
wi::gui::Button cameraButton;
wi::gui::Button materialsButton;
wi::gui::Button paintToolButton;
GeneralWindow generalWnd;
GraphicsWindow graphicsWnd;
CameraWindow cameraWnd;
MaterialPickerWindow materialPickerWnd;
PaintToolWindow paintToolWnd;
wi::primitive::Ray pickRay;
wi::physics::PickDragOperation physicsDragOp;
@@ -80,6 +88,12 @@ public:
void Render() const override;
void Compose(wi::graphics::CommandList cmd) const override;
wi::graphics::Viewport viewport3D;
void ResizeViewport3D();
bool camControlStart = true;
XMFLOAT4 originalMouse = XMFLOAT4(0, 0, 0, 0);
XMFLOAT4 currentMouse = XMFLOAT4(0, 0, 0, 0);
enum EDITORSTENCILREF
{
@@ -119,7 +133,7 @@ public:
bool bone_picking = false;
void CheckBonePickingEnabled();
void UpdateTopMenuAnimation();
void UpdateDynamicWidgets();
wi::Archive clipboard;
@@ -200,13 +214,15 @@ public:
wi::vector<uint8_t> filedata;
};
wi::vector<FontData> font_datas;
wi::jobsystem::context loadmodel_workload;
wi::SpriteFont loadmodel_font;
};
class Editor : public wi::Application
{
public:
EditorComponent renderComponent;
EditorLoadingScreen loader;
wi::config::File config;
void Initialize() override;
@@ -223,18 +239,16 @@ enum class EditorLocalization
// Top menu:
Save,
Open,
ContentBrowser,
Backlog,
Profiler,
Cinema,
__REMOVED_Cinema,
FullScreen,
Windowed,
BugReport,
About,
Exit,
// Other:
UntitledScene,
ContentBrowser,
Count
};
@@ -242,7 +256,6 @@ static const char* EditorLocalizationStrings[] = {
// Top menu:
"Save",
"Open",
"Content",
"Backlog",
"Profiler",
"Cinema",
@@ -251,8 +264,7 @@ static const char* EditorLocalizationStrings[] = {
"Bug report",
"About",
"Exit",
// Other:
"Untitled scene"
"Untitled scene",
"Content",
};
static_assert(arraysize(EditorLocalizationStrings) == size_t(EditorLocalization::Count));
-2
View File
@@ -103,7 +103,6 @@
<ClCompile Include="$(MSBuildThisFileDirectory)ModelImporter_OBJ.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)NameWindow.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)ObjectWindow.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)OptionsWindow.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)PaintToolWindow.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)GraphicsWindow.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)ProfilerWindow.cpp" />
@@ -173,7 +172,6 @@
<ClInclude Include="$(MSBuildThisFileDirectory)ModelImporter.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)NameWindow.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)ObjectWindow.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)OptionsWindow.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)PaintToolWindow.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)GraphicsWindow.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)ProfilerWindow.h" />
-2
View File
@@ -74,7 +74,6 @@
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)TerrainWindow.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)MaterialPickerWindow.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)OptionsWindow.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)ComponentsWindow.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)ScriptWindow.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)RigidBodyWindow.cpp" />
@@ -132,7 +131,6 @@
<ClInclude Include="$(MSBuildThisFileDirectory)IconsFontAwesome6.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)IconDefinitions.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)MaterialPickerWindow.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)OptionsWindow.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)ComponentsWindow.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)ScriptWindow.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)RigidBodyWindow.h" />
+1 -1
View File
@@ -21,7 +21,7 @@ void EmitterWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 130;
+1 -1
View File
@@ -23,7 +23,7 @@ void EnvProbeWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 5, y = 0, step = 35;
+1 -1
View File
@@ -22,7 +22,7 @@ void ExpressionWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 60;
+1 -1
View File
@@ -22,7 +22,7 @@ void FontWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 60;
+1 -1
View File
@@ -21,7 +21,7 @@ void ForceFieldWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 60;
+102 -45
View File
@@ -11,9 +11,10 @@ void GeneralWindow::Create(EditorComponent* _editor)
{
editor = _editor;
wi::gui::Window::Create("General", wi::gui::Window::WindowControls::COLLAPSE);
wi::gui::Window::Create("General", wi::gui::Window::WindowControls::CLOSE | wi::gui::Window::WindowControls::RESIZE_RIGHT);
SetText("General Options " ICON_GENERALOPTIONS);
SetSize(XMFLOAT2(580, 700));
SetSize(XMFLOAT2(300, 700));
physicsDebugCheckBox.Create("Physics visualizer: ");
physicsDebugCheckBox.SetTooltip("Visualize the physics world");
@@ -370,7 +371,7 @@ void GeneralWindow::Create(EditorComponent* _editor)
theme_color_idle = wi::Color(46, 52, 64, 255);
theme_color_focus = wi::Color(59, 66, 82, 255);
dark_point = wi::Color(46, 52, 64, 255);
theme.shadow_color = wi::Color(46, 52, 64, 200);
theme.shadow_color = wi::Color(106, 112, 124, 200);
theme.font.color = wi::Color(236, 239, 244, 255);
theme.font.shadow_color = wi::Color::Shadow();
break;
@@ -432,39 +433,33 @@ void GeneralWindow::Create(EditorComponent* _editor)
}
// customize individual elements:
editor->loadmodel_font.params.color = theme.font.color;
XMFLOAT4 highlight = theme_color_focus;
highlight.x *= 2;
highlight.y *= 2;
highlight.z *= 2;
editor->newEntityCombo.SetAngularHighlightColor(highlight);
editor->componentsWnd.newComponentCombo.SetAngularHighlightColor(highlight);
editor->componentsWnd.materialWnd.textureSlotButton.SetColor(wi::Color::White(), wi::gui::IDLE);
editor->componentsWnd.spriteWnd.textureButton.SetColor(wi::Color::White(), wi::gui::IDLE);
editor->optionsWnd.paintToolWnd.brushTextureButton.SetColor(wi::Color::White(), wi::gui::IDLE);
editor->optionsWnd.paintToolWnd.revealTextureButton.SetColor(wi::Color::White(), wi::gui::IDLE);
editor->paintToolWnd.brushTextureButton.SetColor(wi::Color::White(), wi::gui::IDLE);
editor->paintToolWnd.revealTextureButton.SetColor(wi::Color::White(), wi::gui::IDLE);
editor->aboutLabel.sprites[wi::gui::FOCUS] = editor->aboutLabel.sprites[wi::gui::IDLE];
for (int i = 0; i < arraysize(wi::gui::Widget::sprites); ++i)
{
editor->optionsWnd.sprites[i].params.enableCornerRounding();
editor->optionsWnd.sprites[i].params.corners_rounding[1].radius = 10;
editor->optionsWnd.resizeDragger_UpperRight.sprites[i].params.enableCornerRounding();
editor->optionsWnd.resizeDragger_UpperRight.sprites[i].params.corners_rounding[1].radius = 10;
}
for (int i = 0; i < arraysize(wi::gui::Widget::sprites); ++i)
{
editor->componentsWnd.sprites[i].params.enableCornerRounding();
editor->componentsWnd.sprites[i].params.corners_rounding[0].radius = 10;
editor->componentsWnd.resizeDragger_UpperLeft.sprites[i].params.enableCornerRounding();
editor->componentsWnd.resizeDragger_UpperLeft.sprites[i].params.corners_rounding[0].radius = 10;
}
int scene_id = 0;
for (auto& editorscene : editor->scenes)
{
for (int i = 0; i < arraysize(editorscene->tabSelectButton.sprites); ++i)
if (scene_id > 0)
{
editorscene->tabSelectButton.sprites[i].params.enableCornerRounding();
editorscene->tabSelectButton.sprites[i].params.corners_rounding[0].radius = 10;
editorscene->tabSelectButton.sprites[i].params.corners_rounding[2].radius = 10;
for (int i = 0; i < arraysize(editorscene->tabSelectButton.sprites); ++i)
{
editorscene->tabSelectButton.sprites[i].params.enableCornerRounding();
editorscene->tabSelectButton.sprites[i].params.corners_rounding[0].radius = 10;
}
}
for (int i = 0; i < arraysize(editorscene->tabCloseButton.sprites); ++i)
{
editorscene->tabCloseButton.sprites[i].params.enableCornerRounding();
editorscene->tabCloseButton.sprites[i].params.corners_rounding[1].radius = 10;
editorscene->tabCloseButton.sprites[i].params.corners_rounding[3].radius = 10;
}
if (editor->current_scene == scene_id)
@@ -481,10 +476,76 @@ void GeneralWindow::Create(EditorComponent* _editor)
for (int i = 0; i < arraysize(editor->newSceneButton.sprites); ++i)
{
editor->newSceneButton.sprites[i].params.enableCornerRounding();
editor->newSceneButton.sprites[i].params.corners_rounding[0].radius = 10;
editor->newSceneButton.sprites[i].params.corners_rounding[1].radius = 10;
editor->newSceneButton.sprites[i].params.corners_rounding[2].radius = 10;
editor->newSceneButton.sprites[i].params.corners_rounding[3].radius = 10;
editor->newSceneButton.sprites[i].params.corners_rounding[0].radius = 20;
editor->newSceneButton.sprites[i].params.corners_rounding[1].radius = 20;
editor->newSceneButton.sprites[i].params.corners_rounding[2].radius = 20;
editor->newSceneButton.sprites[i].params.corners_rounding[3].radius = 20;
editor->newEntityCombo.sprites[i].params.enableCornerRounding();
editor->newEntityCombo.sprites[i].params.corners_rounding[0].radius = 20;
editor->newEntityCombo.sprites[i].params.corners_rounding[1].radius = 20;
editor->newEntityCombo.sprites[i].params.corners_rounding[2].radius = 20;
editor->newEntityCombo.sprites[i].params.corners_rounding[3].radius = 20;
editor->generalButton.sprites[i].params.enableCornerRounding();
editor->generalButton.sprites[i].params.corners_rounding[0].radius = 20;
editor->generalButton.sprites[i].params.corners_rounding[1].radius = 20;
editor->generalButton.sprites[i].params.corners_rounding[2].radius = 20;
editor->generalButton.sprites[i].params.corners_rounding[3].radius = 20;
editor->graphicsButton.sprites[i].params.enableCornerRounding();
editor->graphicsButton.sprites[i].params.corners_rounding[0].radius = 20;
editor->graphicsButton.sprites[i].params.corners_rounding[1].radius = 20;
editor->graphicsButton.sprites[i].params.corners_rounding[2].radius = 20;
editor->graphicsButton.sprites[i].params.corners_rounding[3].radius = 20;
editor->cameraButton.sprites[i].params.enableCornerRounding();
editor->cameraButton.sprites[i].params.corners_rounding[0].radius = 20;
editor->cameraButton.sprites[i].params.corners_rounding[1].radius = 20;
editor->cameraButton.sprites[i].params.corners_rounding[2].radius = 20;
editor->cameraButton.sprites[i].params.corners_rounding[3].radius = 20;
editor->materialsButton.sprites[i].params.enableCornerRounding();
editor->materialsButton.sprites[i].params.corners_rounding[0].radius = 20;
editor->materialsButton.sprites[i].params.corners_rounding[1].radius = 20;
editor->materialsButton.sprites[i].params.corners_rounding[2].radius = 20;
editor->materialsButton.sprites[i].params.corners_rounding[3].radius = 20;
editor->paintToolButton.sprites[i].params.enableCornerRounding();
editor->paintToolButton.sprites[i].params.corners_rounding[0].radius = 20;
editor->paintToolButton.sprites[i].params.corners_rounding[1].radius = 20;
editor->paintToolButton.sprites[i].params.corners_rounding[2].radius = 20;
editor->paintToolButton.sprites[i].params.corners_rounding[3].radius = 20;
editor->componentsWnd.newComponentCombo.sprites[i].params.enableCornerRounding();
editor->componentsWnd.newComponentCombo.sprites[i].params.corners_rounding[0].radius = 20;
editor->componentsWnd.newComponentCombo.sprites[i].params.corners_rounding[1].radius = 20;
editor->componentsWnd.newComponentCombo.sprites[i].params.corners_rounding[2].radius = 20;
editor->componentsWnd.newComponentCombo.sprites[i].params.corners_rounding[3].radius = 20;
editor->dummyButton.sprites[i].params.enableCornerRounding();
editor->dummyButton.sprites[i].params.corners_rounding[0].radius = 10;
editor->dummyButton.sprites[i].params.corners_rounding[1].radius = 10;
editor->dummyButton.sprites[i].params.corners_rounding[2].radius = 10;
editor->dummyButton.sprites[i].params.corners_rounding[3].radius = 10;
editor->physicsButton.sprites[i].params.enableCornerRounding();
editor->physicsButton.sprites[i].params.corners_rounding[0].radius = 10;
editor->physicsButton.sprites[i].params.corners_rounding[1].radius = 10;
editor->physicsButton.sprites[i].params.corners_rounding[2].radius = 10;
editor->physicsButton.sprites[i].params.corners_rounding[3].radius = 10;
editor->navtestButton.sprites[i].params.enableCornerRounding();
editor->navtestButton.sprites[i].params.corners_rounding[0].radius = 10;
editor->navtestButton.sprites[i].params.corners_rounding[1].radius = 10;
editor->navtestButton.sprites[i].params.corners_rounding[2].radius = 10;
editor->navtestButton.sprites[i].params.corners_rounding[3].radius = 10;
editor->cinemaButton.sprites[i].params.enableCornerRounding();
editor->cinemaButton.sprites[i].params.corners_rounding[0].radius = 10;
editor->cinemaButton.sprites[i].params.corners_rounding[1].radius = 10;
editor->cinemaButton.sprites[i].params.corners_rounding[2].radius = 10;
editor->cinemaButton.sprites[i].params.corners_rounding[3].radius = 10;
}
for (int i = 0; i < arraysize(wi::gui::Widget::sprites); ++i)
{
@@ -511,41 +572,35 @@ void GeneralWindow::Create(EditorComponent* _editor)
editor->aboutWindow.sprites[i].params.corners_rounding[1].radius = 10;
editor->aboutWindow.sprites[i].params.corners_rounding[2].radius = 10;
editor->aboutWindow.sprites[i].params.corners_rounding[3].radius = 10;
editor->aboutWindow.resizeDragger_UpperLeft.sprites[i].params.enableCornerRounding();
editor->aboutWindow.resizeDragger_UpperLeft.sprites[i].params.corners_rounding[0].radius = 10;
editor->aboutWindow.resizeDragger_UpperRight.sprites[i].params.enableCornerRounding();
editor->aboutWindow.resizeDragger_UpperRight.sprites[i].params.corners_rounding[1].radius = 10;
editor->aboutWindow.resizeDragger_BottomLeft.sprites[i].params.enableCornerRounding();
editor->aboutWindow.resizeDragger_BottomLeft.sprites[i].params.corners_rounding[2].radius = 10;
editor->aboutWindow.resizeDragger_BottomRight.sprites[i].params.enableCornerRounding();
editor->aboutWindow.resizeDragger_BottomRight.sprites[i].params.corners_rounding[3].radius = 10;
}
for (int i = 0; i < arraysize(wi::gui::Widget::sprites); ++i)
{
editor->saveButton.sprites[i].params.enableCornerRounding();
editor->saveButton.sprites[i].params.corners_rounding[2].radius = 10;
editor->saveButton.sprites[i].params.corners_rounding[0].radius = 10;
editor->playButton.sprites[i].params.enableCornerRounding();
editor->playButton.sprites[i].params.corners_rounding[2].radius = 40;
editor->playButton.sprites[i].params.corners_rounding[0].radius = 10;
editor->stopButton.sprites[i].params.enableCornerRounding();
editor->stopButton.sprites[i].params.corners_rounding[3].radius = 40;
editor->stopButton.sprites[i].params.corners_rounding[1].radius = 10;
editor->translateButton.sprites[i].params.enableCornerRounding();
editor->translateButton.sprites[i].params.corners_rounding[2].radius = 40;
editor->translateButton.sprites[i].params.corners_rounding[0].radius = 10;
editor->translateButton.sprites[i].params.corners_rounding[1].radius = 10;
editor->scaleButton.sprites[i].params.enableCornerRounding();
editor->scaleButton.sprites[i].params.corners_rounding[3].radius = 40;
editor->scaleButton.sprites[i].params.corners_rounding[2].radius = 10;
editor->scaleButton.sprites[i].params.corners_rounding[3].radius = 10;
editor->dummyButton.sprites[i].params.enableCornerRounding();
editor->dummyButton.sprites[i].params.corners_rounding[3].radius = 40;
editor->dummyButton.sprites[i].params.corners_rounding[3].radius = 10;
editor->navtestButton.sprites[i].params.enableCornerRounding();
editor->navtestButton.sprites[i].params.corners_rounding[2].radius = 40;
editor->navtestButton.sprites[i].params.corners_rounding[2].radius = 10;
editor->physicsButton.sprites[i].params.enableCornerRounding();
editor->physicsButton.sprites[i].params.corners_rounding[2].radius = 40;
editor->physicsButton.sprites[i].params.corners_rounding[3].radius = 40;
editor->physicsButton.sprites[i].params.corners_rounding[2].radius = 10;
editor->physicsButton.sprites[i].params.corners_rounding[3].radius = 10;
}
editor->componentsWnd.weatherWnd.default_sky_horizon = dark_point;
editor->componentsWnd.weatherWnd.default_sky_zenith = theme_color_idle;
@@ -676,6 +731,8 @@ void GeneralWindow::Create(EditorComponent* _editor)
});
AddWidget(&ktxConvButton);
SetVisible(false);
}
void GeneralWindow::RefreshLanguageSelectionAfterWholeGUIWasInitialized()
+6 -6
View File
@@ -7,13 +7,14 @@ using namespace wi::graphics;
void GraphicsWindow::Create(EditorComponent* _editor)
{
editor = _editor;
wi::gui::Window::Create("Graphics", wi::gui::Window::WindowControls::COLLAPSE);
wi::gui::Window::Create("Graphics", wi::gui::Window::WindowControls::CLOSE | wi::gui::Window::WindowControls::RESIZE_RIGHT);
SetText("Graphics Options " ICON_GRAPHICSOPTIONS);
wi::renderer::SetToDrawDebugEnvProbes(true);
wi::renderer::SetToDrawGridHelper(true);
wi::renderer::SetToDrawDebugCameras(true);
SetSize(XMFLOAT2(580, 1660));
SetSize(XMFLOAT2(300, 1660));
float step = 21;
float itemheight = 18;
@@ -1417,8 +1418,7 @@ void GraphicsWindow::Create(EditorComponent* _editor)
fsr2Combo.SetSelected(fsr2_preset);
AddWidget(&fsr2Combo);
Translate(XMFLOAT3(100, 50, 0));
SetMinimized(true);
SetVisible(false);
}
void GraphicsWindow::UpdateSwapChainFormats(wi::graphics::SwapChain* swapChain)
@@ -1632,7 +1632,7 @@ void GraphicsWindow::ResizeLayout()
if (!widget.IsVisible())
return;
const float margin_left = 155;
const float margin_right = 45;
const float margin_right = 50;
widget.SetPos(XMFLOAT2(margin_left, y));
widget.SetSize(XMFLOAT2(width - margin_left - margin_right, widget.GetScale().y));
y += widget.GetSize().y;
@@ -1641,7 +1641,7 @@ void GraphicsWindow::ResizeLayout()
auto add_right = [&](wi::gui::Widget& widget) {
if (!widget.IsVisible())
return;
const float margin_right = 45;
const float margin_right = 50;
widget.SetPos(XMFLOAT2(width - margin_right - widget.GetSize().x, y));
y += widget.GetSize().y;
y += padding;
+1 -1
View File
@@ -21,7 +21,7 @@ void HairParticleWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 120;
+2 -2
View File
@@ -21,7 +21,7 @@ void HierarchyWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 80;
@@ -53,7 +53,7 @@ void HierarchyWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
parentCombo.SetTooltip("Choose a parent entity (also works if selected entity has no transform)");
+2 -2
View File
@@ -22,7 +22,7 @@ void HumanoidWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 60;
@@ -228,7 +228,7 @@ void HumanoidWindow::Create(EditorComponent* _editor)
// record NEW selection state...
editor->RecordSelection(archive);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
AddWidget(&boneList);
+1 -1
View File
@@ -21,7 +21,7 @@ void IKWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 120;
+8
View File
@@ -3,6 +3,7 @@
// These map the Font Awesome icon definitions to editor:
// These definitions will help to change icons that are scattered throughout the editor code
// Search available icons: https://fontawesome.com/search?q=paper&o=r&m=free
#define ICON_LAYER ICON_FA_LAYER_GROUP
#define ICON_TRANSFORM ICON_FA_LOCATION_DOT
#define ICON_MESH ICON_FA_CUBE
@@ -73,6 +74,7 @@
#define ICON_STOP ICON_FA_STOP
#define ICON_PEN ICON_FA_PEN
#define ICON_FILTER ICON_FA_FILTER
#define ICON_SEARCH ICON_FA_MAGNIFYING_GLASS
#define ICON_SAVE_EMBED ICON_FA_FILE_ZIPPER
#define ICON_SAVE_NO_EMBED ICON_FA_FILE
#define ICON_SAVE_HEADER ICON_FA_FILE_CODE
@@ -83,3 +85,9 @@
#define ICON_SOFT ICON_FA_LEAF
#define ICON_HACKING ICON_FA_COMPUTER
#define ICON_NORD ICON_FA_MOUNTAIN
#define ICON_GENERALOPTIONS ICON_FA_GEAR
#define ICON_GRAPHICSOPTIONS ICON_FA_DISPLAY
#define ICON_CAMERAOPTIONS ICON_CAMERA
#define ICON_MATERIALBROWSER ICON_MATERIAL
#define ICON_PAINTTOOL ICON_FA_PAINTBRUSH
+1 -1
View File
@@ -21,7 +21,7 @@ void LayerWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 30;
+2 -2
View File
@@ -22,7 +22,7 @@ void LightWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 130;
@@ -463,7 +463,7 @@ void LightWindow::RefreshCascades()
addCascadeButton.SetEnabled(true);
// refresh theme:
editor->optionsWnd.generalWnd.themeCombo.SetSelected(editor->optionsWnd.generalWnd.themeCombo.GetSelected());
editor->generalWnd.themeCombo.SetSelected(editor->generalWnd.themeCombo.GetSelected());
}
+3 -2
View File
@@ -8,13 +8,14 @@ using namespace wi::scene;
void MaterialPickerWindow::Create(EditorComponent* _editor)
{
editor = _editor;
wi::gui::Window::Create("Materials", wi::gui::Window::WindowControls::COLLAPSE);
wi::gui::Window::Create("Materials", wi::gui::Window::WindowControls::CLOSE | wi::gui::Window::WindowControls::RESIZE_RIGHT);
SetText("Materials " ICON_MATERIALBROWSER);
SetSize(XMFLOAT2(300, 400));
zoomSlider.Create(10, 100, 100, 100 - 10, "Zoom: ");
AddWidget(&zoomSlider);
SetCollapsed(true);
SetVisible(false);
}
void MaterialPickerWindow::RecreateButtons()
+2 -2
View File
@@ -22,7 +22,7 @@ void MaterialWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float hei = 18;
@@ -505,7 +505,7 @@ void MaterialWindow::Create(EditorComponent* _editor)
{
*name = args.sValue;
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
}
});
AddWidget(&materialNameField);
+1 -1
View File
@@ -25,7 +25,7 @@ void MeshWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 95;
+2 -2
View File
@@ -21,7 +21,7 @@ void NameWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 60;
@@ -42,7 +42,7 @@ void NameWindow::Create(EditorComponent* _editor)
}
name->name = args.sValue;
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
AddWidget(&nameInput);
+1 -1
View File
@@ -270,7 +270,7 @@ void ObjectWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 140;
File diff suppressed because it is too large Load Diff
-75
View File
@@ -1,75 +0,0 @@
#pragma once
#include "GraphicsWindow.h"
#include "CameraWindow.h"
#include "MaterialPickerWindow.h"
#include "PaintToolWindow.h"
#include "GeneralWindow.h"
class EditorComponent;
class OptionsWindow : public wi::gui::Window
{
public:
void Create(EditorComponent* editor);
void Update(float dt);
void ResizeLayout() override;
EditorComponent* editor = nullptr;
GeneralWindow generalWnd;
GraphicsWindow graphicsWnd;
CameraWindow cameraWnd;
MaterialPickerWindow materialPickerWnd;
PaintToolWindow paintToolWnd;
enum class Filter : uint64_t
{
Transform = 1 << 0,
Material = 1 << 1,
Mesh = 1 << 2,
Object = 1 << 3,
EnvironmentProbe = 1 << 4,
Decal = 1 << 5,
Sound = 1 << 6,
Weather = 1 << 7,
Light = 1 << 8,
Animation = 1 << 9,
Force = 1 << 10,
Emitter = 1 << 11,
Hairparticle = 1 << 12,
IK = 1 << 13,
Camera = 1 << 14,
Armature = 1 << 15,
Collider = 1 << 16,
Script = 1 << 17,
Expression = 1 << 18,
Terrain = 1 << 19,
Spring = 1 << 20,
Humanoid = 1 << 21,
Video = 1 << 22,
Sprite = 1 << 23,
Font = 1 << 24,
VoxelGrid = 1 << 25,
RigidBody = 1 << 26,
SoftBody = 1 << 27,
All = ~0ull,
} filter = Filter::All;
wi::gui::ComboBox newCombo;
wi::gui::ComboBox filterCombo;
wi::gui::TextInputField filterInput;
wi::gui::CheckBox filterCaseCheckBox;
wi::gui::TreeList entityTree;
wi::unordered_set<wi::ecs::Entity> entitytree_temp_items;
wi::unordered_set<wi::ecs::Entity> entitytree_added_items;
wi::unordered_set<wi::ecs::Entity> entitytree_opened_items;
void PushToEntityTree(wi::ecs::Entity entity, int level);
void RefreshEntityTree();
bool CheckEntityFilter(wi::ecs::Entity entity);
};
template<>
struct enable_bitmask_operators<OptionsWindow::Filter> {
static const bool enable = true;
};
+17 -16
View File
@@ -11,8 +11,9 @@ void PaintToolWindow::Create(EditorComponent* _editor)
{
editor = _editor;
wi::gui::Window::Create("Paint Tool", wi::gui::Window::WindowControls::COLLAPSE);
SetSize(XMFLOAT2(360, 800));
wi::gui::Window::Create("Paint Tool", wi::gui::Window::WindowControls::CLOSE | wi::gui::Window::WindowControls::RESIZE_RIGHT);
SetText("Paint Tool " ICON_PAINTTOOL);
SetSize(XMFLOAT2(300, 800));
float x = 105;
float y = 0;
@@ -388,9 +389,7 @@ void PaintToolWindow::Create(EditorComponent* _editor)
});
AddWidget(&revealTextureButton);
Translate(XMFLOAT3((float)editor->GetLogicalWidth() - 550, 50, 0));
SetMinimized(true);
SetVisible(false);
}
void PaintToolWindow::Update(float dt)
@@ -469,9 +468,8 @@ void PaintToolWindow::Update(float dt)
}
}
auto pointer = wi::input::GetPointer();
posNew = XMFLOAT2(pointer.x, pointer.y);
float pressureNew = pressureCheckBox.GetCheck() ? pointer.w : 1.0f;
posNew = XMFLOAT2(editor->currentMouse.x, editor->currentMouse.y);
float pressureNew = pressureCheckBox.GetCheck() ? editor->currentMouse.w : 1.0f;
const MODE mode = GetMode();
const float radius = radiusSlider.GetValue();
@@ -549,7 +547,7 @@ void PaintToolWindow::Update(float dt)
{
case MODE_TEXTURE:
{
wi::primitive::Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor, camera);
wi::primitive::Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor->renderPath, camera);
brushIntersect = wi::scene::Pick(pickRay, ~0u, ~0u, scene);
ObjectComponent* object = scene.objects.GetComponent(brushIntersect.entity);
@@ -669,7 +667,7 @@ void PaintToolWindow::Update(float dt)
case MODE_TERRAIN_MATERIAL:
{
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor, camera);
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor->renderPath, camera);
brushIntersect = wi::scene::Pick(pickRay, wi::enums::FILTER_TERRAIN, ~0u, scene);
if (brushIntersect.entity == INVALID_ENTITY)
break;
@@ -768,7 +766,7 @@ void PaintToolWindow::Update(float dt)
case MODE_VERTEXCOLOR:
case MODE_WIND:
{
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor, camera);
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor->renderPath, camera);
brushIntersect = wi::scene::Pick(pickRay, wi::enums::FILTER_OBJECT_ALL, ~0u, scene);
if (brushIntersect.entity == INVALID_ENTITY)
break;
@@ -939,7 +937,7 @@ void PaintToolWindow::Update(float dt)
case MODE_SCULPTING_ADD:
case MODE_SCULPTING_SUBTRACT:
{
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor, camera);
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor->renderPath, camera);
brushIntersect = wi::scene::Pick(pickRay, terrain_only ? wi::enums::FILTER_TERRAIN : wi::enums::FILTER_OBJECT_ALL, ~0u, scene);
if (brushIntersect.entity == INVALID_ENTITY)
break;
@@ -979,7 +977,7 @@ void PaintToolWindow::Update(float dt)
case PaintToolWindow::AxisLock::Disabled:
if (sculpting_normal.x < FLT_EPSILON && sculpting_normal.y < FLT_EPSILON && sculpting_normal.z < FLT_EPSILON)
{
sculpting_normal = editor->hovered.normal;
sculpting_normal = brushIntersect.normal;
}
sculptDir = XMVector3TransformNormal(XMVector3Normalize(XMLoadFloat3(&sculpting_normal)), XMMatrixInverse(nullptr, W));
break;
@@ -1123,7 +1121,7 @@ void PaintToolWindow::Update(float dt)
wi::renderer::RenderableLine sculpt_dir_line;
sculpt_dir_line.color_start = XMFLOAT4(0, 1, 0, 1);
sculpt_dir_line.color_end = XMFLOAT4(0, 1, 0, 1);
sculpt_dir_line.start = editor->hovered.position;
sculpt_dir_line.start = brushIntersect.position;
XMStoreFloat3(
&sculpt_dir_line.end,
XMLoadFloat3(&sculpt_dir_line.start) +
@@ -1146,7 +1144,7 @@ void PaintToolWindow::Update(float dt)
case MODE_SOFTBODY_PINNING:
case MODE_SOFTBODY_PHYSICS:
{
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor, camera);
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor->renderPath, camera);
brushIntersect = wi::scene::Pick(pickRay, wi::enums::FILTER_OBJECT_ALL, ~0u, scene);
if (brushIntersect.entity == INVALID_ENTITY)
break;
@@ -1254,7 +1252,7 @@ void PaintToolWindow::Update(float dt)
case MODE_HAIRPARTICLE_REMOVE_TRIANGLE:
case MODE_HAIRPARTICLE_LENGTH:
{
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor, camera);
Ray pickRay = wi::renderer::GetPickRay((long)pos.x, (long)pos.y, *editor->renderPath, camera);
brushIntersect = wi::scene::Pick(pickRay, wi::enums::FILTER_OBJECT_ALL, ~0u, scene);
if (brushIntersect.entity == INVALID_ENTITY)
break;
@@ -1508,6 +1506,8 @@ void PaintToolWindow::DrawBrush(const wi::Canvas& canvas, CommandList cmd) const
PaintToolWindow::MODE PaintToolWindow::GetMode() const
{
if (!IsVisible())
return MODE_DISABLED;
return (MODE)modeComboBox.GetSelectedUserdata();
}
@@ -2040,6 +2040,7 @@ void PaintToolWindow::RecreateTerrainMaterialButtons()
button.Create("");
AddWidget(&button);
button.SetVisible(false);
button.SetEnabled(true);
button.SetText("");
button.SetTooltip("");
-19
View File
@@ -49,25 +49,6 @@ void ProfilerWindow::Update(const wi::Canvas& canvas, float dt)
sprites[i].params.corners_rounding[1].radius = 10;
sprites[i].params.corners_rounding[2].radius = 10;
sprites[i].params.corners_rounding[3].radius = 10;
resizeDragger_UpperLeft.sprites[i].params.enableCornerRounding();
resizeDragger_UpperLeft.sprites[i].params.corners_rounding[0].radius = 10;
resizeDragger_UpperRight.sprites[i].params.enableCornerRounding();
resizeDragger_UpperRight.sprites[i].params.corners_rounding[1].radius = 10;
resizeDragger_BottomLeft.sprites[i].params.enableCornerRounding();
resizeDragger_BottomLeft.sprites[i].params.corners_rounding[2].radius = 10;
resizeDragger_BottomRight.sprites[i].params.enableCornerRounding();
resizeDragger_BottomRight.sprites[i].params.corners_rounding[3].radius = 10;
if (IsCollapsed())
{
resizeDragger_UpperLeft.sprites[i].params.corners_rounding[2].radius = 10;
resizeDragger_UpperRight.sprites[i].params.corners_rounding[3].radius = 10;
}
else
{
resizeDragger_UpperLeft.sprites[i].params.corners_rounding[2].radius = 0;
resizeDragger_UpperRight.sprites[i].params.corners_rounding[3].radius = 0;
}
}
}
void ProfilerWindow::ResizeLayout()
+1 -1
View File
@@ -22,7 +22,7 @@ void RigidBodyWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 140;
+1 -1
View File
@@ -18,7 +18,7 @@ void ScriptWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float hei = 20;
+1 -1
View File
@@ -21,7 +21,7 @@ void SoftBodyWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 95;
+1 -1
View File
@@ -48,7 +48,7 @@ void SoundWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 60;
+1 -1
View File
@@ -21,7 +21,7 @@ void SpringWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 120;
+1 -1
View File
@@ -23,7 +23,7 @@ void SpriteWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
textureButton.Create("Base Texture");
+21 -7
View File
@@ -67,6 +67,7 @@ PerlinModifierWindow::PerlinModifierWindow() : ModifierWindow("Perlin Noise")
AddWidget(&octavesSlider);
SetSize(XMFLOAT2(200, 140));
SetCollapsed(true);
}
void PerlinModifierWindow::ResizeLayout()
{
@@ -140,6 +141,7 @@ VoronoiModifierWindow::VoronoiModifierWindow() : ModifierWindow("Voronoi Noise")
AddWidget(&perturbationSlider);
SetSize(XMFLOAT2(200, 200));
SetCollapsed(true);
}
void VoronoiModifierWindow::ResizeLayout()
{
@@ -238,6 +240,7 @@ HeightmapModifierWindow::HeightmapModifierWindow() : ModifierWindow("Heightmap")
AddWidget(&loadButton);
SetSize(XMFLOAT2(200, 180));
SetCollapsed(true);
}
void HeightmapModifierWindow::ResizeLayout()
{
@@ -545,7 +548,7 @@ void PropsWindow::AddWindow(wi::terrain::Prop& prop)
windows.emplace_back().reset(wnd);
editor->optionsWnd.generalWnd.themeCombo.SetSelected(editor->optionsWnd.generalWnd.themeCombo.GetSelected()); // theme refresh
editor->generalWnd.themeCombo.SetSelected(editor->generalWnd.themeCombo.GetSelected()); // theme refresh
}
void PropsWindow::Update(const wi::Canvas& canvas, float dt)
@@ -604,6 +607,17 @@ void PropsWindow::ResizeLayout()
y += padding;
};
auto add_fullwidth = [&](wi::gui::Widget& widget) {
if (!widget.IsVisible())
return;
const float margin_left = padding;
const float margin_right = padding;
widget.SetPos(XMFLOAT2(margin_left, y));
widget.SetSize(XMFLOAT2(width - margin_left - margin_right, widget.GetScale().y));
y += widget.GetSize().y;
y += padding;
};
auto add_window = [&](wi::gui::Window& widget) {
const float margin_left = padding;
const float margin_right = padding;
@@ -614,7 +628,7 @@ void PropsWindow::ResizeLayout()
widget.SetEnabled(true);
};
add(addButton);
add_fullwidth(addButton);
for(auto& window : windows)
{
@@ -646,7 +660,7 @@ void TerrainWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 140;
@@ -937,7 +951,7 @@ void TerrainWindow::Create(EditorComponent* _editor)
generate_callback();
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
AddWidget(&presetCombo);
@@ -1102,7 +1116,7 @@ void TerrainWindow::Create(EditorComponent* _editor)
{
terrain->materialEntities[i] = INVALID_ENTITY;
}
editor->optionsWnd.paintToolWnd.RecreateTerrainMaterialButtons();
editor->paintToolWnd.RecreateTerrainMaterialButtons();
});
AddWidget(&materialCombos[i]);
@@ -1410,7 +1424,7 @@ void TerrainWindow::AddModifier(ModifierWindow* modifier_window)
modifiers_to_remove.push_back(modifier_window);
});
editor->optionsWnd.generalWnd.themeCombo.SetSelected(editor->optionsWnd.generalWnd.themeCombo.GetSelected()); // theme refresh
editor->generalWnd.themeCombo.SetSelected(editor->generalWnd.themeCombo.GetSelected()); // theme refresh
}
void TerrainWindow::SetupAssets()
{
@@ -1722,7 +1736,7 @@ void TerrainWindow::SetupAssets()
terrain = &terrain_preset;
presetCombo.SetSelected(0);
editor->optionsWnd.paintToolWnd.RecreateTerrainMaterialButtons();
editor->paintToolWnd.RecreateTerrainMaterialButtons();
}
void TerrainWindow::Update(const wi::Canvas& canvas, float dt)
+1 -1
View File
@@ -21,7 +21,7 @@ void TransformWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 80;
+16 -17
View File
@@ -104,7 +104,7 @@ namespace Translator_Internal
}
using namespace Translator_Internal;
void Translator::Update(const CameraComponent& camera, const wi::Canvas& canvas)
void Translator::Update(const CameraComponent& camera, const XMFLOAT4& currentMouse, const wi::Canvas& canvas)
{
if (selected.empty())
{
@@ -116,7 +116,6 @@ void Translator::Update(const CameraComponent& camera, const wi::Canvas& canvas)
dragStarted = false;
dragEnded = false;
XMFLOAT4 pointer = wi::input::GetPointer();
XMVECTOR pos = transform.GetPositionV();
// Non recursive selection will be computed to not apply recursive operations two times
@@ -144,7 +143,7 @@ void Translator::Update(const CameraComponent& camera, const wi::Canvas& canvas)
if (!has_selected_transform)
return;
const Ray ray = wi::renderer::GetPickRay((long)pointer.x, (long)pointer.y, canvas, camera);
const Ray ray = wi::renderer::GetPickRay((long)currentMouse.x, (long)currentMouse.y, canvas, camera);
const XMVECTOR rayOrigin = XMLoadFloat3(&ray.origin);
const XMVECTOR rayDir = XMLoadFloat3(&ray.direction);
@@ -286,7 +285,7 @@ void Translator::Update(const CameraComponent& camera, const wi::Canvas& canvas)
}
}
if (dragging || (state != TRANSLATOR_IDLE && wi::input::Press(wi::input::MOUSE_BUTTON_LEFT) && interactable))
if (dragging || (state != TRANSLATOR_IDLE && wi::input::Press(wi::input::MOUSE_BUTTON_LEFT)))
{
// Dragging operation:
if (isRotator)
@@ -491,7 +490,7 @@ void Translator::Update(const CameraComponent& camera, const wi::Canvas& canvas)
dragging = false;
}
}
void Translator::Draw(const CameraComponent& camera, CommandList cmd) const
void Translator::Draw(const CameraComponent& camera, const XMFLOAT4& currentMouse, CommandList cmd) const
{
if (!IsEnabled() || selected.empty() || !has_selected_transform)
{
@@ -1025,47 +1024,47 @@ void Translator::Draw(const CameraComponent& camera, CommandList cmd) const
device->Draw(vertexCount, 0, cmd);
}
XMFLOAT4 pointer = wi::input::GetPointer();
wi::font::Params params;
params.posX = pointer.x - 20;
params.posY = pointer.y + 20;
params.posX = currentMouse.x - 20;
params.posY = currentMouse.y + 20;
params.v_align = wi::font::WIFALIGN_TOP;
params.h_align = wi::font::WIFALIGN_RIGHT;
params.scaling = 0.8f;
params.shadowColor = wi::Color::Black();
std::string str;
char text[256] = {};
if (isTranslator)
{
str += "Offset = " + std::to_string(transform.translation_local.x - transform_start.translation_local.x) + ", " + std::to_string(transform.translation_local.y - transform_start.translation_local.y) + ", " + std::to_string(transform.translation_local.z - transform_start.translation_local.z);
snprintf(text, arraysize(text), "Offset = %.2f, %.2f, %.2f", transform.translation_local.x - transform_start.translation_local.x, transform.translation_local.y - transform_start.translation_local.y, transform.translation_local.z - transform_start.translation_local.z);
}
if (isRotator)
{
switch (state)
{
case Translator::TRANSLATOR_X:
str += "Axis = X";
snprintf(text, arraysize(text), "Axis = X\nAngle = %.2f degrees", wi::math::RadiansToDegrees(angle));
break;
case Translator::TRANSLATOR_Y:
str += "Axis = Y";
snprintf(text, arraysize(text), "Axis = Y\nAngle = %.2f degrees", wi::math::RadiansToDegrees(angle));
break;
case Translator::TRANSLATOR_Z:
str += "Axis = Z";
snprintf(text, arraysize(text), "Axis = Z\nAngle = %.2f degrees", wi::math::RadiansToDegrees(angle));
break;
case Translator::TRANSLATOR_XYZ:
str += "Axis = Screen";
snprintf(text, arraysize(text), "Axis = Screen\nAngle = %.2f degrees", wi::math::RadiansToDegrees(angle));
break;
default:
break;
}
str += "\nAngle = " + std::to_string(int(angle / XM_PI * 180)) + " degrees";
}
if (isScalator)
{
str += "Scaling = " + std::to_string(transform.scale_local.x / transform_start.scale_local.x) + ", " + std::to_string(transform.scale_local.y / transform_start.scale_local.y) + ", " + std::to_string(transform.scale_local.z / transform_start.scale_local.z);
snprintf(text, arraysize(text), "Scaling = %.2f, %.2f, %.2f", transform.scale_local.x / transform_start.scale_local.x, transform.scale_local.y / transform_start.scale_local.y, transform.scale_local.z / transform_start.scale_local.z);
}
params.shadowColor.setA(uint8_t(opacity * 255.0f));
params.color.setA(uint8_t(opacity * 255.0f));
wi::font::Draw(str, params, cmd);
wi::font::Draw(text, params, cmd);
}
device->EventEnd(cmd);
+4 -3
View File
@@ -13,8 +13,8 @@ private:
bool has_selected_transform = false;
public:
void Update(const wi::scene::CameraComponent& camera, const wi::Canvas& canvas);
void Draw(const wi::scene::CameraComponent& camera, wi::graphics::CommandList cmd) const;
void Update(const wi::scene::CameraComponent& camera, const XMFLOAT4& currentMouse, const wi::Canvas& canvas);
void Draw(const wi::scene::CameraComponent& camera, const XMFLOAT4& currentMouse, wi::graphics::CommandList cmd) const;
// Attach selection to translator temporarily
void PreTranslate();
@@ -49,7 +49,6 @@ public:
float dist = 1;
bool interactable = true;
bool isTranslator = true;
bool isScalator = false;
bool isRotator = false;
@@ -74,6 +73,8 @@ public:
// Check if the drag ended in this exact frame
bool IsDragEnded() const { return dragEnded; };
bool IsInteracting() const { return state != TRANSLATOR_IDLE; }
wi::scene::TransformComponent transform_start;
wi::vector<XMFLOAT4X4> matrices_start;
wi::vector<XMFLOAT4X4> matrices_current;
+1 -1
View File
@@ -44,7 +44,7 @@ void VideoWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 60;
+1 -1
View File
@@ -21,7 +21,7 @@ void VoxelGridWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 80;
+1 -1
View File
@@ -22,7 +22,7 @@ void WeatherWindow::Create(EditorComponent* _editor)
editor->RecordEntity(archive, entity);
editor->optionsWnd.RefreshEntityTree();
editor->componentsWnd.RefreshEntityTree();
});
float x = 150;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1
View File
@@ -179,6 +179,7 @@ BOOL CreateEditorWindow(int nCmdShow)
editor.SetWindow(hWnd);
ShowWindow(hWnd, nCmdShow);
//SendMessage(hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
UpdateWindow(hWnd);
DragAcceptFiles(hWnd, TRUE);
+14 -16
View File
@@ -4,6 +4,7 @@
[![Github Build Status](https://github.com/turanszkij/WickedEngine/workflows/Build/badge.svg)](https://github.com/turanszkij/WickedEngine/actions)
[![Discord chat](https://img.shields.io/discord/602811659224088577?logo=discord)](https://discord.gg/CFjRYmE)
[![Forum](https://img.shields.io/badge/forum--blue)](https://wickedengine.net/forum/)
<a href="https://twitter.com/intent/follow?screen_name=turanszkij"><img src="https://img.shields.io/twitter/follow/turanszkij.svg?style=social" alt="follow on Twitter"></a>
<br/>
[![Steam](https://img.shields.io/badge/-Steam-383838.svg?style=for-the-badge&logo=steam)](https://store.steampowered.com/app/1967460/Wicked_Engine/)
@@ -13,15 +14,15 @@
<br/>
<img align="right" src="https://github.com/turanszkij/wickedengine-gifs/raw/main/videoprojectors.gif" width="320px"/>
Wicked Engine is an open-source 3D engine with modern graphics. Use this as a C++ framework for your graphics projects, a standalone 3D editor, LUA scripting or just for learning.<br/>
This project is hosted on <a href="https://github.com/turanszkij/WickedEngine/">GitHub</a>.
- [Documentation](Content/Documentation/WickedEngine-Documentation.md)<br/>
- [Scripting API Documentation](Content/Documentation/ScriptingAPI-Documentation.md)<br/>
- [Website](https://wickedengine.net/)<br/>
- [Forum](https://wickedengine.net/forum/)<br/>
- [Features](features.txt)<br/>
- [Devblog](https://wickedengine.net/)<br/>
- [Videos](https://www.youtube.com/playlist?list=PLLN-1FTGyLU_HJoC5zx6hJkB3D2XLiaxS)<br/>
- [C++ Documentation](Content/Documentation/WickedEngine-Documentation.md)<br/>
- [Lua Documentation](Content/Documentation/ScriptingAPI-Documentation.md)<br/>
You can get the full source code by using Git version control and cloning https://github.com/turanszkij/WickedEngine.git, or downloading it as zip. You can also download prebuilt and packaged version of the Editor here (requires Github sign in): [![Github Build Status](https://github.com/turanszkij/WickedEngine/workflows/Build/badge.svg)](https://github.com/turanszkij/WickedEngine/actions)
You can get the full source code by using Git version control and cloning https://github.com/turanszkij/WickedEngine.git, or downloading it as zip. You can also download nightly packaged builds of the Editor here (requires Github sign in): [![Github Build Status](https://github.com/turanszkij/WickedEngine/workflows/Build/badge.svg)](https://github.com/turanszkij/WickedEngine/actions)
<br/>
<br/>
@@ -203,7 +204,7 @@ The native model format is the <b>WISCENE</b> format. Any application using Wick
<img align="right" src="https://github.com/turanszkij/wickedengine-gifs/raw/main/character_lookat.gif" width="320px"/>
In addition, the Editor supports the importing of some common model formats (the list will potentially grow):
In addition, the Editor supports importing some common model formats:
- <b>OBJ</b>
- <b>GLTF 2.0</b>
- <b>VRM</b>
@@ -214,24 +215,20 @@ The preferred workflow is to import models into the Editor, and save them as <b>
<img align="right" src="https://github.com/turanszkij/wickedengine-gifs/raw/main/snowstorm.gif" width="320px"/>
### Graphics API:
The default renderer is `DirectX 12` on Windows and `Vulkan` on Linux. The `DirectX 11` renderer is no longer available starting from version 0.57.0, but it can be found on the <a href="https://github.com/turanszkij/WickedEngine/tree/dx11-backup">dx11-backup branch</a>.
The default renderer is `DirectX 12` on Windows and `Vulkan` on Linux.
You can specify command line arguments (without any prefix) to switch between render devices or other settings. Currently the list of options:
<table>
<tr>
<th>Argument</th>
<th>Description</th>
</tr>
<tr>
<td>dx12</td>
<td>Use DirectX 12 rendering device</td>
</tr>
<tr>
<td>vulkan</td>
<td>Use Vulkan rendering device</td>
<td>Use the Vulkan rendering device on Windows</td>
</tr>
<tr>
<td>debugdevice</td>
<td>Use debug layer for graphics API validation. Performance will be degraded, but graphics warnings and errors will be written to "Output" window</td>
<td>Use debug layer for graphics API validation. Performance will be degraded, but graphics warnings and errors will be written to the "Output" window</td>
</tr>
<tr>
<td>gpuvalidation</td>
@@ -271,9 +268,10 @@ If you are having trouble getting the applications to run, make sure that you sa
<img align="right" src="https://github.com/turanszkij/wickedengine-gifs/raw/main/weather.gif" width="320px"/>
- If you experience crashes, follow these steps to find out the problem:
- If you experience crashes, you can try these to find out the problem:
- make sure your environment is up to date, with latest graphics drivers and operating system updates.
- see if there is a wiBackLog.txt in your user temp folder (for example: C:\Users\username\AppData\Local\Temp), and request help on Discord or Github issue
- build the engine in Debug mode and try to run it, see where it crashes, provide call stack on Discord or Github issue
- see if there is a wiBackLog.txt in your user temp folder (for example: C:\Users\username\AppData\Local\Temp)
- request help on the [Forum](https://wickedengine.net/forum/), [Discord](https://discord.gg/CFjRYmE) or [Github issue](https://github.com/turanszkij/WickedEngine/issues)
- build the engine in Debug mode and try to run it, see where it crashes
- run the engine with the `debugdevice` command argument and post the text from your console output window when the crash happens
- for very advanced users, using `gpuvalidation` with `debugdevice` will print additional graphics debug information
@@ -8,6 +8,8 @@ static const uint IMAGE_FLAG_OUTPUT_COLOR_SPACE_LINEAR = 1u << 2u;
static const uint IMAGE_FLAG_FULLSCREEN = 1u << 3u;
static const uint IMAGE_FLAG_MIRROR = 1u << 4u;
static const uint IMAGE_FLAG_CORNER_ROUNDING = 1u << 5u;
static const uint IMAGE_FLAG_ANGULAR_DOUBLESIDED = 1u << 6u;
static const uint IMAGE_FLAG_ANGULAR_INVERSE = 1u << 7u;
struct ImageConstants
{
@@ -33,6 +35,10 @@ struct ImageConstants
float2 b1;
float2 b2;
float2 b3;
float2 angular_softness_direction;
float angular_softness_scale;
float angular_softness_offset;
};
CONSTANTBUFFER(image, ImageConstants, CBSLOT_IMAGE);
@@ -125,11 +125,7 @@ static const uint TONEMAP_FLAG_ACES = 1 << 1;
struct PushConstantsTonemap
{
float2 resolution_rcp;
float exposure;
uint flags;
float brightness;
float contrast;
float saturation;
uint2 exposure_brightness_contrast_saturation;
int texture_input;
int buffer_input_luminance;
@@ -139,6 +135,7 @@ struct PushConstantsTonemap
int texture_bloom;
int texture_output;
uint display_colorspace;
uint flags;
};
struct PostprocessTileStatistics
+24 -1
View File
@@ -56,12 +56,35 @@ float4 main(VertextoPixel input) : SV_TARGET
color.rgb = RemoveSRGBCurve_Fast(color.rgb);
color.rgb *= image.hdr_scaling;
}
[branch]
if (image.border_soften > 0)
{
float edge = max(abs(input.edge.x), abs(input.edge.y));
color.a *= smoothstep(0, image.border_soften, 1 - edge);
}
[branch]
if (image.angular_softness_scale > 0)
{
float2 direction = normalize(uvsets.xy - 0.5);
float dp = dot(direction, image.angular_softness_direction);
if (image.flags & IMAGE_FLAG_ANGULAR_DOUBLESIDED)
{
dp = abs(dp);
}
else
{
dp = saturate(dp);
}
float angular = saturate(mad(dp, image.angular_softness_scale, image.angular_softness_offset));
if (image.flags & IMAGE_FLAG_ANGULAR_INVERSE)
{
angular = 1 - angular;
}
angular = smoothstep(0, 1, angular);
color.a *= angular;
}
return color;
}
+11 -45
View File
@@ -59,53 +59,19 @@ float4x4 saturationMatrix(float saturation)
return float4x4(red, 0, green, 0, blue, 0, 0, 0, 0, 1);
}
#ifndef __PSSL__
#undef WICKED_ENGINE_DEFAULT_ROOTSIGNATURE // don't use auto root signature!
[RootSignature(
"RootConstants(num32BitConstants=16, b999),"
"DescriptorTable( "
"SRV(t0, space = 2, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"SRV(t0, space = 3, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"SRV(t0, space = 4, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"SRV(t0, space = 5, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"SRV(t0, space = 6, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"SRV(t0, space = 7, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"SRV(t0, space = 8, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"SRV(t0, space = 9, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"SRV(t0, space = 10, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"SRV(t0, space = 11, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"SRV(t0, space = 12, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"SRV(t0, space = 13, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"SRV(t0, space = 14, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"SRV(t0, space = 15, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"SRV(t0, space = 16, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"SRV(t0, space = 17, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"SRV(t0, space = 18, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"SRV(t0, space = 19, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"SRV(t0, space = 20, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"UAV(u0, space = 21, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"UAV(u0, space = 22, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"UAV(u0, space = 23, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"UAV(u0, space = 24, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"UAV(u0, space = 25, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"UAV(u0, space = 26, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"UAV(u0, space = 27, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"UAV(u0, space = 28, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"UAV(u0, space = 29, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"UAV(u0, space = 30, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"UAV(u0, space = 31, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"UAV(u0, space = 32, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE),"
"UAV(u0, space = 33, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)"
"), "
"StaticSampler(s100, addressU = TEXTURE_ADDRESS_CLAMP, addressV = TEXTURE_ADDRESS_CLAMP, addressW = TEXTURE_ADDRESS_CLAMP, filter = FILTER_MIN_MAG_MIP_LINEAR)"
)]
#endif // __PSSL__
[numthreads(POSTPROCESS_BLOCKSIZE, POSTPROCESS_BLOCKSIZE, 1)]
void main(uint3 DTid : SV_DispatchThreadID)
{
if(!GetCamera().is_pixel_inside_scissor(DTid.xy))
return;
float2 uv = (DTid.xy + 0.5f) * tonemap_push.resolution_rcp;
float exposure = tonemap_push.exposure;
float4 exposure_brightness_contrast_saturation = unpack_half4(tonemap_push.exposure_brightness_contrast_saturation);
float exposure = exposure_brightness_contrast_saturation.x;
float brightness = exposure_brightness_contrast_saturation.y;
float contrast = exposure_brightness_contrast_saturation.z;
float saturation = exposure_brightness_contrast_saturation.w;
[branch]
if (tonemap_push.texture_input_distortion >= 0)
@@ -164,8 +130,8 @@ void main(uint3 DTid : SV_DispatchThreadID)
result.rgb += (dither((float2)DTid.xy) - 0.5f) / 64.0f;
}
result.rgb = (result.rgb - 0.5f) * tonemap_push.contrast + 0.5f + tonemap_push.brightness;
result.rgb = (float3)(mul(saturationMatrix(tonemap_push.saturation), result));
result.rgb = (result.rgb - 0.5f) * contrast + 0.5f + brightness;
result.rgb = (float3)(mul(saturationMatrix(saturation), result));
[branch]
if (tonemap_push.texture_output >= 0)
+27 -4
View File
@@ -256,6 +256,8 @@ namespace wi
{
auto range = wi::profiler::BeginRangeCPU("Update");
infoDisplay.rect = {};
wi::lua::SetDeltaTime(double(dt));
wi::lua::Update();
@@ -317,6 +319,11 @@ namespace wi
// Draw the information display
if (infoDisplay.active)
{
if (infoDisplay.rect.right > 0)
{
graphicsDevice->BindScissorRects(1, &infoDisplay.rect, cmd);
}
infodisplay_str.clear();
if (infoDisplay.watermark)
{
@@ -445,8 +452,8 @@ namespace wi
}
wi::font::Params params = wi::font::Params(
4,
4,
4 + canvas.PhysicalToLogical((uint32_t)infoDisplay.rect.left),
4 + canvas.PhysicalToLogical((uint32_t)infoDisplay.rect.top),
infoDisplay.size,
wi::font::WIFALIGN_LEFT,
wi::font::WIFALIGN_TOP,
@@ -506,10 +513,26 @@ namespace wi
params.cursor = wi::font::Draw(std::to_string(wi::renderer::GetShaderErrorCount()) + " shader compilation errors! Check the backlog for more information!\n", params, cmd);
}
if (infoDisplay.colorgrading_helper)
{
wi::image::Draw(wi::texturehelper::getColorGradeDefault(), wi::image::Params(0, 0, 256.0f / canvas.GetDPIScaling(), 16.0f / canvas.GetDPIScaling()), cmd);
wi::image::Draw(
wi::texturehelper::getColorGradeDefault(),
wi::image::Params(
canvas.PhysicalToLogical((uint32_t)infoDisplay.rect.left),
canvas.PhysicalToLogical((uint32_t)infoDisplay.rect.top),
canvas.PhysicalToLogical(256),
canvas.PhysicalToLogical(16)
),
cmd
);
}
if (infoDisplay.rect.right > 0)
{
Rect rect;
rect.right = canvas.width;
rect.bottom = canvas.height;
graphicsDevice->BindScissorRects(1, &rect, cmd);
}
}
+2
View File
@@ -116,6 +116,8 @@ namespace wi
int size = 16;
// display default color grading helper texture in top left corner of the screen
bool colorgrading_helper = false;
// rect to specify where to render the information
wi::graphics::Rect rect;
};
// display all-time engine information text
InfoDisplayer infoDisplay;
+9
View File
@@ -46,6 +46,7 @@ namespace wi::backlog
bool locked = false;
bool blockLuaExec = false;
LogLevel logLevel = LogLevel::Default;
LogLevel unseen = LogLevel::None;
std::string getTextWithoutLock()
{
@@ -321,6 +322,7 @@ namespace wi::backlog
}
params.cursor = wi::font::Draw(x.text, params, cmd);
}
unseen = LogLevel::None;
}
std::string getText()
@@ -385,6 +387,8 @@ namespace wi::backlog
break;
}
unseen = std::max(unseen, level);
// lock released on block end
}
@@ -463,4 +467,9 @@ namespace wi::backlog
{
logLevel = newLevel;
}
LogLevel GetUnseenLogLevelMax()
{
return unseen;
}
}
+2
View File
@@ -53,6 +53,8 @@ namespace wi::backlog
void SetLogLevel(LogLevel newLevel);
LogLevel GetUnseenLogLevelMax();
// These are no longer used, but kept here to not break user code:
inline void input(const char input) {}
+773 -317
View File
File diff suppressed because it is too large Load Diff
+64 -14
View File
@@ -264,6 +264,9 @@ namespace wi::gui
mutable wi::Sprite tooltipSprite;
mutable wi::SpriteFont tooltipFont;
mutable wi::SpriteFont scripttipFont;
float angular_highlight_width = 0;
float angular_highlight_timer = 0;
XMFLOAT4 angular_highlight_color = XMFLOAT4(1, 1, 1, 1);
public:
Widget();
@@ -295,7 +298,7 @@ namespace wi::gui
virtual void ResizeLayout() {};
virtual void Update(const wi::Canvas& canvas, float dt);
virtual void Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const {}
virtual void Render(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const;
virtual void RenderTooltip(const wi::Canvas& canvas, wi::graphics::CommandList cmd) const;
// last param default: set color for all states
@@ -338,6 +341,11 @@ namespace wi::gui
void SetLocalizationEnabled(bool value) { localization_enabled = value ? LocalizationEnabled::All : LocalizationEnabled::None; }
virtual void ExportLocalization(wi::Localization& localization) const;
virtual void ImportLocalization(const wi::Localization& localization);
void SetAngularHighlightWidth(float value) { angular_highlight_width = value; };
float GetAngularHighlightWidth() const { return angular_highlight_width; };
void SetAngularHighlightColor(const XMFLOAT4& value) { angular_highlight_color = value; };
XMFLOAT4 GetAngularHighlightColor() const { return angular_highlight_color; };
};
// Clickable, draggable box
@@ -396,7 +404,7 @@ namespace wi::gui
// 1: full extra offset
void SetOverScroll(float amount) { overscroll = amount; }
// Check whether the scrollbar is required (when the items don't fit and scrolling could be used)
bool IsScrollbarRequired() const { return scrollbar_granularity < 0.999f; }
bool IsScrollbarRequired() const { return scrollbar_granularity < 1; }
void SetSafeArea(float value) { safe_area = value; }
enum SCROLLBAR_STATE
@@ -423,6 +431,7 @@ namespace wi::gui
class Label : public Widget
{
protected:
bool wrap_enabled = true;
public:
void Create(const std::string& name);
@@ -434,6 +443,8 @@ namespace wi::gui
float scrollbar_width = 18;
ScrollBar scrollbar;
void SetWrapEnabled(bool value) { wrap_enabled = value; }
};
// Text input box
@@ -547,6 +558,8 @@ namespace wi::gui
int selected = -1;
int maxVisibleItemCount = 8;
int firstItemVisible = 0;
bool drop_arrow = true;
float fixed_drop_width = 0; // 0 = not fixed, takes width from base scale
// While the widget is active (rolled down) these are the inner states that control behaviour
enum COMBOSTATE
@@ -573,6 +586,7 @@ namespace wi::gui
std::wstring invalid_selection_text;
float GetDropOffset(const wi::Canvas& canvas) const;
float GetDropX(const wi::Canvas& canvas) const;
float GetItemOffset(const wi::Canvas& canvas, int index) const;
public:
void Create(const std::string& name);
@@ -608,6 +622,11 @@ namespace wi::gui
void ExportLocalization(wi::Localization& localization) const override;
void ImportLocalization(const wi::Localization& localization) override;
void SetDropArrowEnabled(bool value) { drop_arrow = value; }
bool IsDropArrowEnabled() const { return drop_arrow; }
void SetFixedDropWidth(float value) { fixed_drop_width = value; }
float GetFixedDropWidth() const { return fixed_drop_width; }
};
// Widget container
@@ -622,19 +641,41 @@ namespace wi::gui
std::function<void(EventArgs args)> onCollapse;
std::function<void()> onResize;
float resizehitboxwidth = 6;
enum RESIZE_STATE
{
RESIZE_STATE_NONE,
RESIZE_STATE_LEFT,
RESIZE_STATE_TOP,
RESIZE_STATE_RIGHT,
RESIZE_STATE_BOTTOM,
RESIZE_STATE_TOPLEFT,
RESIZE_STATE_TOPRIGHT,
RESIZE_STATE_BOTTOMRIGHT,
RESIZE_STATE_BOTTOMLEFT,
} resize_state = RESIZE_STATE_NONE;
XMFLOAT2 resize_begin = XMFLOAT2(0, 0);
float resize_blink_timer = 0;
public:
enum class WindowControls
{
NONE = 0,
RESIZE_TOPLEFT = 1 << 0,
RESIZE_TOPRIGHT = 1 << 1,
RESIZE_BOTTOMLEFT = 1 << 2,
RESIZE_BOTTOMRIGHT = 1 << 3,
MOVE = 1 << 4,
CLOSE = 1 << 5,
COLLAPSE = 1 << 6,
RESIZE_LEFT = 1 << 0,
RESIZE_TOP = 1 << 1,
RESIZE_RIGHT = 1 << 2,
RESIZE_BOTTOM = 1 << 3,
RESIZE_TOPLEFT = 1 << 4,
RESIZE_TOPRIGHT = 1 << 5,
RESIZE_BOTTOMLEFT = 1 << 6,
RESIZE_BOTTOMRIGHT = 1 << 7,
MOVE = 1 << 8,
CLOSE = 1 << 9,
COLLAPSE = 1 << 10,
RESIZE = RESIZE_TOPLEFT | RESIZE_TOPRIGHT | RESIZE_BOTTOMLEFT | RESIZE_BOTTOMRIGHT,
RESIZE = RESIZE_LEFT | RESIZE_TOP | RESIZE_RIGHT | RESIZE_BOTTOM | RESIZE_TOPLEFT | RESIZE_TOPRIGHT | RESIZE_BOTTOMLEFT | RESIZE_BOTTOMRIGHT,
CLOSE_AND_COLLAPSE = CLOSE | COLLAPSE,
ALL = RESIZE | MOVE | CLOSE | COLLAPSE,
};
@@ -675,14 +716,11 @@ namespace wi::gui
Button closeButton;
Button collapseButton;
Button resizeDragger_UpperLeft;
Button resizeDragger_UpperRight;
Button resizeDragger_BottomLeft;
Button resizeDragger_BottomRight;
Button moveDragger;
Label label;
ScrollBar scrollbar_vertical;
ScrollBar scrollbar_horizontal;
WindowControls controls;
void ExportLocalization(wi::Localization& localization) const override;
void ImportLocalization(const wi::Localization& localization) override;
@@ -742,6 +780,7 @@ namespace wi::gui
protected:
std::function<void(EventArgs args)> onSelect;
std::function<void(EventArgs args)> onDelete;
std::function<void(EventArgs args)> onDoubleClick;
int item_highlight = -1;
int opener_highlight = -1;
@@ -753,6 +792,16 @@ namespace wi::gui
float GetItemOffset(int index) const;
bool DoesItemHaveChildren(int index) const;
float resizehitboxwidth = 6;
enum RESIZE_STATE
{
RESIZE_STATE_NONE,
RESIZE_STATE_BOTTOM,
} resize_state = RESIZE_STATE_NONE;
XMFLOAT2 resize_begin = XMFLOAT2(0, 0);
float resize_blink_timer = 0;
public:
void Create(const std::string& name);
@@ -775,6 +824,7 @@ namespace wi::gui
void OnSelect(std::function<void(EventArgs args)> func);
void OnDelete(std::function<void(EventArgs args)> func);
void OnDoubleClick(std::function<void(EventArgs args)> func);
ScrollBar scrollbar;
};
+8
View File
@@ -769,6 +769,14 @@ namespace wi::graphics
int32_t top = 0;
int32_t right = 0;
int32_t bottom = 0;
constexpr void from_viewport(const Viewport& vp)
{
left = int32_t(vp.top_left_x);
right = int32_t(vp.top_left_x + vp.width);
top = int32_t(vp.top_left_y);
bottom = int32_t(vp.top_left_y + vp.height);
}
};
struct Box
+1 -4
View File
@@ -1173,10 +1173,7 @@ namespace vulkan_internal
// the color space change will not be applied
res = vkDeviceWaitIdle(device);
assert(res == VK_SUCCESS);
{
std::scoped_lock lock(allocationhandler->destroylocker);
allocationhandler->destroyer_swapchains.emplace_back(internal_state->swapChain, allocationhandler->framecount);
}
vkDestroySwapchainKHR(device, internal_state->swapChain, nullptr);
internal_state->swapChain = nullptr;
}
}
+20
View File
@@ -114,6 +114,18 @@ namespace wi::image
image.packed_color.x = uint(packed_color.v);
image.packed_color.y = uint(packed_color.v >> 32ull);
if (params.angular_softness_outer_angle > 0)
{
const float innerConeAngleCos = std::cos(params.angular_softness_inner_angle);
const float outerConeAngleCos = std::cos(params.angular_softness_outer_angle);
// https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_lights_punctual#inner-and-outer-cone-angles
const float lightAngleScale = 1.0f / std::max(0.001f, innerConeAngleCos - outerConeAngleCos);
const float lightAngleOffset = -outerConeAngleCos * lightAngleScale;
image.angular_softness_direction = params.angular_softness_direction;
image.angular_softness_scale = lightAngleScale;
image.angular_softness_offset = lightAngleOffset;
}
image.flags = 0;
if (params.isExtractNormalMapEnabled())
{
@@ -132,6 +144,14 @@ namespace wi::image
{
image.flags |= IMAGE_FLAG_FULLSCREEN;
}
if (params.isAngularSoftnessDoubleSided())
{
image.flags |= IMAGE_FLAG_ANGULAR_DOUBLESIDED;
}
if (params.isAngularSoftnessInverse())
{
image.flags |= IMAGE_FLAG_ANGULAR_INVERSE;
}
image.border_soften = params.border_soften;
image.mask_alpha_range = XMConvertFloatToHalf(params.mask_alpha_range_start) | (XMConvertFloatToHalf(params.mask_alpha_range_end) << 16u);
+20
View File
@@ -4,6 +4,7 @@
#include "wiEnums.h"
#include "wiColor.h"
#include "wiCanvas.h"
#include "wiPrimitive.h"
namespace wi::image
{
@@ -57,6 +58,8 @@ namespace wi::image
OUTPUT_COLOR_SPACE_LINEAR = 1 << 7,
CORNER_ROUNDING = 1 << 8,
DEPTH_TEST = 1 << 9,
ANGULAR_DOUBLESIDED = 1 << 10,
ANGULAR_INVERSE = 1 << 11,
};
uint32_t _flags = EMPTY;
@@ -76,6 +79,9 @@ namespace wi::image
float hdr_scaling = 1.0f; // a scaling value for use by linear output mapping
float mask_alpha_range_start = 0; // constrain mask alpha to not go below this level
float mask_alpha_range_end = 1; // constrain mask alpha to not go above this level
XMFLOAT2 angular_softness_direction = XMFLOAT2(0, 1);
float angular_softness_inner_angle = 0;
float angular_softness_outer_angle = 0;
// you can deform the image by its corners (0: top left, 1: top right, 2: bottom left, 3: bottom right)
XMFLOAT2 corners[4] = {
@@ -117,6 +123,8 @@ namespace wi::image
constexpr bool isLinearOutputMappingEnabled() const { return _flags & OUTPUT_COLOR_SPACE_LINEAR; }
constexpr bool isCornerRoundingEnabled() const { return _flags & CORNER_ROUNDING; }
constexpr bool isDepthTestEnabled() const { return _flags & DEPTH_TEST; }
constexpr bool isAngularSoftnessDoubleSided() const { return _flags & ANGULAR_DOUBLESIDED; }
constexpr bool isAngularSoftnessInverse() const { return _flags & ANGULAR_INVERSE; }
// enables draw rectangle for base texture (cutout texture outside draw rectangle)
constexpr void enableDrawRect(const XMFLOAT4& rect) { _flags |= DRAWRECT; drawRect = rect; }
@@ -137,6 +145,8 @@ namespace wi::image
constexpr void enableLinearOutputMapping(float scaling = 1.0f) { _flags |= OUTPUT_COLOR_SPACE_LINEAR; hdr_scaling = scaling; }
constexpr void enableCornerRounding() { _flags |= CORNER_ROUNDING; }
constexpr void enableDepthTest() { _flags |= DEPTH_TEST; }
constexpr void enableAngularSoftnessDoubleSided() { _flags |= ANGULAR_DOUBLESIDED; }
constexpr void enableAngularSoftnessInverse() { _flags |= ANGULAR_INVERSE; }
// disable draw rectangle for base texture (whole texture will be drawn, no cutout)
constexpr void disableDrawRect() { _flags &= ~DRAWRECT; }
@@ -150,6 +160,8 @@ namespace wi::image
constexpr void disableLinearOutputMapping() { _flags &= ~OUTPUT_COLOR_SPACE_LINEAR; }
constexpr void disableCornerRounding() { _flags &= ~CORNER_ROUNDING; }
constexpr void disableDepthTest() { _flags &= ~DEPTH_TEST; }
constexpr void disableAngularSoftnessDoubleSided() { _flags &= ~ANGULAR_DOUBLESIDED; }
constexpr void disableAngularSoftnessInverse() { _flags &= ~ANGULAR_INVERSE; }
Params() = default;
@@ -185,6 +197,14 @@ namespace wi::image
enableBackground();
}
}
Params(
const wi::primitive::Hitbox2D& hitbox, const XMFLOAT4& color = XMFLOAT4(1, 1, 1, 1)
) :
pos(XMFLOAT3(hitbox.pos.x, hitbox.pos.y, 0)),
siz(hitbox.siz),
color(color)
{}
};
+64
View File
@@ -50,6 +50,11 @@ namespace wi::input
MouseState mouse;
Pen pen;
bool pen_override = false;
bool double_click = false;
wi::Timer doubleclick_timer;
XMFLOAT2 doubleclick_prevpos = XMFLOAT2(0, 0);
CURSOR cursor_current = CURSOR_DEFAULT;
CURSOR cursor_next = CURSOR_DEFAULT;
const KeyboardState& GetKeyboardState() { return keyboard; }
const MouseState& GetMouseState() { return mouse; }
@@ -429,6 +434,55 @@ namespace wi::input
}
}
double_click = false;
if (Press(MOUSE_BUTTON_LEFT))
{
XMFLOAT2 pos = mouse.position;
double elapsed = doubleclick_timer.record_elapsed_seconds();
if (elapsed < 0.5 && wi::math::Distance(doubleclick_prevpos, pos) < 5)
{
double_click = true;
}
doubleclick_prevpos = pos;
}
// Cursor update:
if(cursor_next != cursor_current || cursor_next != CURSOR_DEFAULT)
{
#ifdef PLATFORM_WINDOWS_DESKTOP
static HCURSOR cursor_table[] = {
::LoadCursor(nullptr, IDC_ARROW),
::LoadCursor(nullptr, IDC_IBEAM),
::LoadCursor(nullptr, IDC_SIZEALL),
::LoadCursor(nullptr, IDC_SIZENS),
::LoadCursor(nullptr, IDC_SIZEWE),
::LoadCursor(nullptr, IDC_SIZENESW),
::LoadCursor(nullptr, IDC_SIZENWSE),
::LoadCursor(nullptr, IDC_HAND),
::LoadCursor(nullptr, IDC_NO)
};
::SetCursor(cursor_table[cursor_next]);
#endif // PLATFORM_WINDOWS_DESKTOP
#ifdef SDL2
static SDL_Cursor* cursor_table[] = {
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW),
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM),
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL),
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS),
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE),
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW),
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE),
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND),
SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO),
};
SDL_SetCursor(cursor_table[cursor_next] ? cursor_table[cursor_next] : cursor_table[CURSOR_DEFAULT]);
#endif // SDL2
cursor_current = cursor_next;
}
cursor_next = CURSOR_DEFAULT;
wi::profiler::EndRange(range);
}
@@ -749,6 +803,11 @@ namespace wi::input
#endif // _WIN32
}
bool IsDoubleClicked()
{
return double_click;
}
XMFLOAT4 GetAnalog(GAMEPAD_ANALOG analog, int playerindex)
{
if (playerindex < (int)controllers.size())
@@ -805,4 +864,9 @@ namespace wi::input
return touches;
}
void SetCursor(CURSOR cursor)
{
cursor_next = cursor;
}
}
+17
View File
@@ -181,6 +181,9 @@ namespace wi::input
// send various feedback to the controller
void SetControllerFeedback(const ControllerFeedback& data, int playerindex = 0);
// Check if left mouse button was double clicked in the current frame:
bool IsDoubleClicked();
struct Pen
{
XMFLOAT2 position = {};
@@ -203,5 +206,19 @@ namespace wi::input
};
const wi::vector<Touch>& GetTouches();
enum CURSOR
{
CURSOR_DEFAULT,
CURSOR_TEXTINPUT,
CURSOR_RESIZEALL,
CURSOR_RESIZE_NS,
CURSOR_RESIZE_EW,
CURSOR_RESIZE_NESW,
CURSOR_RESIZE_NWSE,
CURSOR_HAND,
CURSOR_NOTALLOWED,
};
void SetCursor(CURSOR cursor);
};
+85 -49
View File
@@ -62,12 +62,12 @@ namespace wi::jobsystem
{
uint32_t numCores = 0;
uint32_t numThreads = 0;
std::unique_ptr<JobQueue[]> jobQueuePerThread;
std::unique_ptr<JobQueue[]> jobQueuePerThread[int(Priority::Count)];
std::atomic_bool alive{ true };
std::condition_variable wakeCondition;
std::mutex wakeMutex;
std::atomic<uint32_t> nextQueue{ 0 };
wi::vector<std::thread> threads;
wi::vector<std::thread> threads[int(Priority::Count)];
void ShutDown()
{
alive.store(false); // indicate that new jobs cannot be started from this point
@@ -78,14 +78,20 @@ namespace wi::jobsystem
wakeCondition.notify_all(); // wakes up sleeping worker threads
}
});
for (auto& thread : threads)
for (auto& thread : threads[int(Priority::High)])
{
thread.join();
}
for (auto& thread : threads[int(Priority::Low)])
{
thread.join();
}
wake_loop = false;
waker.join();
jobQueuePerThread.reset();
threads.clear();
jobQueuePerThread[int(Priority::High)].reset();
jobQueuePerThread[int(Priority::Low)].reset();
threads[int(Priority::High)].clear();
threads[int(Priority::Low)].clear();
numCores = 0;
numThreads = 0;
}
@@ -97,12 +103,12 @@ namespace wi::jobsystem
// Start working on a job queue
// After the job queue is finished, it can switch to an other queue and steal jobs from there
inline void work(uint32_t startingQueue)
inline void work(uint32_t startingQueue, Priority priority)
{
Job job;
for (uint32_t i = 0; i < internal_state.numThreads; ++i)
{
JobQueue& job_queue = internal_state.jobQueuePerThread[startingQueue % internal_state.numThreads];
JobQueue& job_queue = internal_state.jobQueuePerThread[int(priority)][startingQueue % internal_state.numThreads];
while (job_queue.pop_front(job))
{
JobArgs args;
@@ -146,65 +152,95 @@ namespace wi::jobsystem
// Calculate the actual number of worker threads we want (-1 main thread):
internal_state.numThreads = std::min(maxThreadCount, std::max(1u, internal_state.numCores - 1));
internal_state.jobQueuePerThread.reset(new JobQueue[internal_state.numThreads]);
internal_state.threads.reserve(internal_state.numThreads);
internal_state.jobQueuePerThread[int(Priority::High)].reset(new JobQueue[internal_state.numThreads]);
internal_state.jobQueuePerThread[int(Priority::Low)].reset(new JobQueue[internal_state.numThreads]);
internal_state.threads[int(Priority::High)].reserve(internal_state.numThreads);
internal_state.threads[int(Priority::Low)].reserve(internal_state.numThreads);
for (uint32_t threadID = 0; threadID < internal_state.numThreads; ++threadID)
{
internal_state.threads.emplace_back([threadID] {
for (int prio = 0; prio < int(Priority::Count); ++prio)
{
const Priority priority = (Priority)prio;
internal_state.threads[prio].emplace_back([threadID, priority] {
while (internal_state.alive.load())
{
work(threadID);
while (internal_state.alive.load())
{
work(threadID, priority);
// finished with jobs, put to sleep
std::unique_lock<std::mutex> lock(internal_state.wakeMutex);
internal_state.wakeCondition.wait(lock);
}
// finished with jobs, put to sleep
std::unique_lock<std::mutex> lock(internal_state.wakeMutex);
internal_state.wakeCondition.wait(lock);
}
});
std::thread& worker = internal_state.threads.back();
});
std::thread& worker = internal_state.threads[prio].back();
#ifdef _WIN32
// Do Windows-specific thread setup:
HANDLE handle = (HANDLE)worker.native_handle();
// Do Windows-specific thread setup:
HANDLE handle = (HANDLE)worker.native_handle();
// Put each thread on to dedicated core:
DWORD_PTR affinityMask = 1ull << threadID;
DWORD_PTR affinity_result = SetThreadAffinityMask(handle, affinityMask);
assert(affinity_result > 0);
// Put each thread on to dedicated core:
DWORD_PTR affinityMask = 1ull << threadID;
DWORD_PTR affinity_result = SetThreadAffinityMask(handle, affinityMask);
assert(affinity_result > 0);
//// Increase thread priority:
//BOOL priority_result = SetThreadPriority(handle, THREAD_PRIORITY_HIGHEST);
//assert(priority_result != 0);
if (priority == Priority::High)
{
BOOL priority_result = SetThreadPriority(handle, THREAD_PRIORITY_NORMAL);
assert(priority_result != 0);
std::wstring wthreadname = L"wi::jobsystem_" + std::to_wstring(threadID);
HRESULT hr = SetThreadDescription(handle, wthreadname.c_str());
assert(SUCCEEDED(hr));
}
else
{
BOOL priority_result = SetThreadPriority(handle, THREAD_PRIORITY_LOWEST);
assert(priority_result != 0);
std::wstring wthreadname = L"wi::jobsystem_lowprio_" + std::to_wstring(threadID);
HRESULT hr = SetThreadDescription(handle, wthreadname.c_str());
assert(SUCCEEDED(hr));
}
// Name the thread:
std::wstring wthreadname = L"wi::jobsystem_" + std::to_wstring(threadID);
HRESULT hr = SetThreadDescription(handle, wthreadname.c_str());
assert(SUCCEEDED(hr));
#elif defined(PLATFORM_LINUX)
#define handle_error_en(en, msg) \
do { errno = en; perror(msg); } while (0)
int ret;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
size_t cpusetsize = sizeof(cpuset);
int ret;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
size_t cpusetsize = sizeof(cpuset);
CPU_SET(threadID, &cpuset);
ret = pthread_setaffinity_np(worker.native_handle(), cpusetsize, &cpuset);
if (ret != 0)
handle_error_en(ret, std::string(" pthread_setaffinity_np[" + std::to_string(threadID) + ']').c_str());
CPU_SET(threadID, &cpuset);
ret = pthread_setaffinity_np(worker.native_handle(), cpusetsize, &cpuset);
if (ret != 0)
handle_error_en(ret, std::string(" pthread_setaffinity_np[" + std::to_string(threadID) + ']').c_str());
if (priority == Priority::High)
{
std::string thread_name = "wi::job::" + std::to_string(threadID);
ret = pthread_setname_np(worker.native_handle(), thread_name.c_str());
if (ret != 0)
handle_error_en(ret, std::string(" pthread_setname_np[" + std::to_string(threadID) + ']').c_str());
}
else
{
// TODO: set lower priority
std::string thread_name = "wi::job_low::" + std::to_string(threadID);
ret = pthread_setname_np(worker.native_handle(), thread_name.c_str());
if (ret != 0)
handle_error_en(ret, std::string(" pthread_setname_np[" + std::to_string(threadID) + ']').c_str());
}
// Name the thread
std::string thread_name = "wi::job::" + std::to_string(threadID);
ret = pthread_setname_np(worker.native_handle(), thread_name.c_str());
if (ret != 0)
handle_error_en(ret, std::string(" pthread_setname_np[" + std::to_string(threadID) + ']').c_str());
#undef handle_error_en
#elif defined(PLATFORM_PS5)
wi::jobsystem::ps5::SetupWorker(worker, threadID);
wi::jobsystem::ps5::SetupWorker(worker, threadID);
#endif // _WIN32
}
}
wi::backlog::post("wi::jobsystem Initialized with [" + std::to_string(internal_state.numCores) + " cores] [" + std::to_string(internal_state.numThreads) + " threads] (" + std::to_string((int)std::round(timer.elapsed())) + " ms)");
@@ -233,7 +269,7 @@ namespace wi::jobsystem
job.groupJobEnd = 1;
job.sharedmemory_size = 0;
internal_state.jobQueuePerThread[internal_state.nextQueue.fetch_add(1) % internal_state.numThreads].push_back(job);
internal_state.jobQueuePerThread[int(ctx.priority)][internal_state.nextQueue.fetch_add(1) % internal_state.numThreads].push_back(job);
internal_state.wakeCondition.notify_one();
}
@@ -261,7 +297,7 @@ namespace wi::jobsystem
job.groupJobOffset = groupID * groupSize;
job.groupJobEnd = std::min(job.groupJobOffset + groupSize, jobCount);
internal_state.jobQueuePerThread[internal_state.nextQueue.fetch_add(1) % internal_state.numThreads].push_back(job);
internal_state.jobQueuePerThread[int(ctx.priority)][internal_state.nextQueue.fetch_add(1) % internal_state.numThreads].push_back(job);
}
internal_state.wakeCondition.notify_all();
@@ -287,7 +323,7 @@ namespace wi::jobsystem
internal_state.wakeCondition.notify_all();
// work() will pick up any jobs that are on stand by and execute them on this thread:
work(internal_state.nextQueue.fetch_add(1) % internal_state.numThreads);
work(internal_state.nextQueue.fetch_add(1) % internal_state.numThreads, ctx.priority);
while (IsBusy(ctx))
{
+8
View File
@@ -20,10 +20,18 @@ namespace wi::jobsystem
uint32_t GetThreadCount();
enum class Priority
{
High, // Default
Low, // Use this when you need the results after a few frames, not blocking high priority tasks
Count
};
// Defines a state of execution, can be waited on
struct context
{
std::atomic<uint32_t> counter{ 0 };
Priority priority = Priority::High;
};
// Add a task to execute asynchronously. Any idle thread will execute this.
+3 -12
View File
@@ -1635,11 +1635,6 @@ namespace wi
{
GraphicsDevice* device = wi::graphics::GetDevice();
// Set scissor on Compose, because some post processes don't handle scissoring (eg. Bloom) and those should be cut off:
// Note that on expensive render operations we also used scissor to avoid wasted processing
Rect scissor = GetScissorNativeResolution();
device->BindScissorRects(1, &scissor, cmd);
wi::image::Params fx;
fx.blendFlag = BLENDMODE_OPAQUE;
fx.quality = wi::image::QUALITY_LINEAR;
@@ -1660,13 +1655,6 @@ namespace wi
wi::image::Draw(&debugUAV, fx, cmd);
}
// Restore full resolution scissor:
scissor.left = 0;
scissor.top = 0;
scissor.right = GetPhysicalWidth();
scissor.bottom = GetPhysicalHeight();
device->BindScissorRects(1, &scissor, cmd);
RenderPath2D::Compose(cmd);
}
@@ -2346,6 +2334,9 @@ namespace wi
{
ao = value;
if (!rtParticleDistortion.IsValid())
return; // ResizeBuffers hasn't been called yet
rtAO = {};
ssaoResources = {};
msaoResources = {};
+8 -8
View File
@@ -6392,7 +6392,7 @@ void DrawDebugWorld(
device->CreateBuffer(&bd, indices, &wirecamIB);
}
device->BindPipelineState(&PSO_debug[DEBUGRENDERING_CUBE], cmd);
device->BindPipelineState(&PSO_debug[DEBUGRENDERING_CUBE_DEPTH], cmd);
const GPUBuffer* vbs[] = {
&wirecamVB,
@@ -6528,7 +6528,7 @@ void DrawDebugWorld(
{
device->EventBegin("DebugPartitionTree", cmd);
device->BindPipelineState(&PSO_debug[DEBUGRENDERING_CUBE], cmd);
device->BindPipelineState(&PSO_debug[DEBUGRENDERING_CUBE_DEPTH], cmd);
const GPUBuffer* vbs[] = {
&wirecubeVB,
@@ -7221,7 +7221,7 @@ void DrawDebugWorld(
// Local proxy boxes:
device->BindPipelineState(&PSO_debug[DEBUGRENDERING_CUBE], cmd);
device->BindPipelineState(&PSO_debug[DEBUGRENDERING_CUBE_DEPTH], cmd);
const GPUBuffer* vbs[] = {
&wirecubeVB,
@@ -7375,7 +7375,7 @@ void DrawDebugWorld(
if (mesh == nullptr)
{
// No mesh, just draw a box:
device->BindPipelineState(&PSO_debug[DEBUGRENDERING_CUBE], cmd);
device->BindPipelineState(&PSO_debug[DEBUGRENDERING_CUBE_DEPTH], cmd);
const GPUBuffer* vbs[] = {
&wirecubeVB,
};
@@ -15807,10 +15807,13 @@ void Postprocess_Tonemap(
assert(texture_colorgradinglut == nullptr || texture_colorgradinglut->desc.type == TextureDesc::Type::TEXTURE_3D); // This must be a 3D lut
XMHALF4 exposure_brightness_contrast_saturation = XMHALF4(exposure, brightness, contrast, saturation);
PushConstantsTonemap tonemap_push = {};
tonemap_push.resolution_rcp.x = 1.0f / desc.width;
tonemap_push.resolution_rcp.y = 1.0f / desc.height;
tonemap_push.exposure = exposure;
tonemap_push.exposure_brightness_contrast_saturation.x = uint(exposure_brightness_contrast_saturation.v);
tonemap_push.exposure_brightness_contrast_saturation.y = uint(exposure_brightness_contrast_saturation.v >> 32ull);
tonemap_push.flags = 0;
if (dither)
{
@@ -15820,9 +15823,6 @@ void Postprocess_Tonemap(
{
tonemap_push.flags |= TONEMAP_FLAG_ACES;
}
tonemap_push.brightness = brightness;
tonemap_push.contrast = contrast;
tonemap_push.saturation = saturation;
tonemap_push.texture_input = device->GetDescriptorIndex(&input, SubresourceType::SRV);
tonemap_push.buffer_input_luminance = device->GetDescriptorIndex((buffer_luminance == nullptr) ? &luminance_dummy : buffer_luminance, SubresourceType::SRV);
tonemap_push.texture_input_distortion = device->GetDescriptorIndex(texture_distortion, SubresourceType::SRV);
+1 -1
View File
@@ -4844,7 +4844,7 @@ namespace wi::scene
{
SoundComponent& sound = sounds[i];
if (!sound.soundinstance.IsValid())
if (!sound.soundinstance.IsValid() && sound.soundResource.IsValid())
{
sound.soundinstance.SetLooped(sound.IsLooped());
wi::audio::CreateSoundInstance(&sound.soundResource.GetSound(), &sound.soundinstance);
+1
View File
@@ -2078,6 +2078,7 @@ namespace wi::scene
// With this we will ensure that serialized entities are unique and persistent across the scene:
EntitySerializer seri;
seri.ctx.priority = wi::jobsystem::Priority::Low; // serialization tasks will be low priority to not block rendering if scene loading is asynchronous
if(archive.GetVersion() >= 84)
{
+2 -2
View File
@@ -9,7 +9,7 @@ namespace wi::version
// minor features, major updates, breaking compatibility changes
const int minor = 71;
// minor bug fixes, alterations, refactors, updates
const int revision = 455;
const int revision = 456;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);
@@ -50,7 +50,7 @@ All contributors: https://github.com/turanszkij/WickedEngine/graphs/contributors
Patreon supporters
---------------------------
Nemerle, James Webb, Quifeng Jin, TheGameCreators, Joseph Goldin, Yuri, Sergey K, Yukawa Kanta, Dragon Josh, John, LurkingNinja, Bernardo Del Castillo, Invictus, Scott Hunt, Yazan Altaki, Tuan NV, Robert MacGregor, cybernescence, Alexander Dahlin, blueapples, Delhills, NI NI, Sherief, ktopoet, Justin Macklin, Cédric Fabre, TogetherTeam, Bartosz Boczula, Arne Koenig, Ivan Trajchev, nathants, Fahd Ahmed, Gabriel Jadderson, SAS_Controller, Dominik Madarász, Segfault, Mike amanfo, Dennis Brakhane, rookie, Peter Moore, therealjtgill, Nicolas Embleton, Desuuc, radino1977, Anthony Curtis, manni heck, Matthias Hölzl, Phyffer, Lucas Pinheiro, Tapkaara, gpman, Anthony Python, Gnowos, Klaus, slaughternaut, Paul Brain, Connor Greaves, Alexandr, Lee Bamber, MCAlarm MC2, Titoutan, Willow, Aldo, lokimx, K. Osterman, Nomad, ykl, Alex Krokos, Timmy, Avaflow
Nemerle, James Webb, Quifeng Jin, TheGameCreators, Joseph Goldin, Yuri, Sergey K, Yukawa Kanta, Dragon Josh, John, LurkingNinja, Bernardo Del Castillo, Invictus, Scott Hunt, Yazan Altaki, Tuan NV, Robert MacGregor, cybernescence, Alexander Dahlin, blueapples, Delhills, NI NI, Sherief, ktopoet, Justin Macklin, Cédric Fabre, TogetherTeam, Bartosz Boczula, Arne Koenig, Ivan Trajchev, nathants, Fahd Ahmed, Gabriel Jadderson, SAS_Controller, Dominik Madarász, Segfault, Mike amanfo, Dennis Brakhane, rookie, Peter Moore, therealjtgill, Nicolas Embleton, Desuuc, radino1977, Anthony Curtis, manni heck, Matthias Hölzl, Phyffer, Lucas Pinheiro, Tapkaara, gpman, Anthony Python, Gnowos, Klaus, slaughternaut, Paul Brain, Connor Greaves, Alexandr, Lee Bamber, MCAlarm MC2, Titoutan, Willow, Aldo, lokimx, K. Osterman, Nomad, ykl, Alex Krokos, Timmy, Avaflow, mat, Hexegonel Samael Michael, Joe Spataro, soru
)";
return credits;