Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d8c1b111a | ||
|
|
3298053d9d | ||
|
|
adccb74f44 | ||
|
|
97113b5df6 | ||
|
|
c374d86ec7 | ||
|
|
803fd7f8ba | ||
|
|
11a57f5285 | ||
|
|
0d015b485e | ||
|
|
17e4a6a589 | ||
|
|
c1a87ed946 | ||
|
|
20dae92be7 | ||
|
|
df67f32399 | ||
|
|
14a802d057 | ||
|
|
12d6df3edf | ||
|
|
2838449186 | ||
|
|
75513bea3d | ||
|
|
16c3d7c44d | ||
|
|
7ae069baf6 | ||
|
|
00dc3faa19 | ||
|
|
f39acdadb3 | ||
|
|
1254d01545 | ||
|
|
0bc517842f | ||
|
|
3e63281508 | ||
|
|
ef486b7082 | ||
|
|
81a61d5a90 | ||
|
|
37197cbdf1 | ||
|
|
b53ed2d8f2 | ||
|
|
457b43352a | ||
|
|
cc7fb7311f | ||
|
|
5f27b8001a | ||
|
|
0cbb8a4966 | ||
|
|
79adc70f01 | ||
|
|
78ba016b03 | ||
|
|
3e55a1614a | ||
|
|
f0de874572 | ||
|
|
6e02a04a4f | ||
|
|
cd1562f372 | ||
|
|
e8505f6bdb | ||
|
|
66d66d3308 | ||
|
|
88b393157a | ||
|
|
28155ec92c | ||
|
|
1641bafd06 | ||
|
|
76bff3a6c1 | ||
|
|
a507eeb1cd | ||
|
|
77c45db122 | ||
|
|
e12fcaacff | ||
|
|
b31d43820a | ||
|
|
334c2c0366 | ||
|
|
bb520b43ec | ||
|
|
46693666aa | ||
|
|
9e1f648aa0 | ||
|
|
5f5da2ed35 | ||
|
|
fa2277cd99 | ||
|
|
54936d5744 | ||
|
|
04d69717a3 | ||
|
|
3becc1e25b | ||
|
|
e8e6207bc1 | ||
|
|
f4c5bf9c2d | ||
|
|
f4607a6210 | ||
|
|
6a59deb9e2 | ||
|
|
ac1817fe33 | ||
|
|
5855b13873 | ||
|
|
ef5e4ba64f | ||
|
|
4fd9a924a0 | ||
|
|
e60d74fccd | ||
|
|
5e5134a607 | ||
|
|
fd6826785a | ||
|
|
43bcf01299 | ||
|
|
0ee2f5fa9e |
@@ -5,3 +5,7 @@ build/
|
||||
recovery/
|
||||
vendor/directx
|
||||
imgui.ini
|
||||
GlitchyEditor/resources/scripts/ScriptCore.dll
|
||||
GlitchyEditor/resources/scripts/ScriptCore.pdb
|
||||
GlitchyEditor/settings.bon
|
||||
GlitchyEditor/MonoDebugger.log
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
FileVersion = 1
|
||||
Projects = {Sandbox = {Path = "Sandbox"}, GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, LodePng = {Path = "vendor/lodepng-beef/lodepng-beef"}, FreeType = {Path = "GlitchyEngine/vendor/freetype"}, cgltf-beef = {Path = "GlitchyEngine/vendor/gltf/cgltf-beef"}, GlitchyEditor = {Path = "GlitchyEditor"}, msdfgen-beef = {Path = "GlitchyEngine/vendor/msdfgen/msdfgen-beef"}, ImGui = {Path = "GlitchyEngine/vendor/imgui/ImGui"}, ImGuiImplDX11 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplDX11"}, ImGuiImplWin32 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplWin32"}, ImGuizmo = {Path = "GlitchyEngine/vendor/imgui/ImGuizmo"}, GlitchyEngineHelper = {Path = "GlitchyEngineHelper"}, bon = {Path = "GlitchyEngine/vendor/bon"}, box2d-beef = {Path = "GlitchyEngine/vendor/box2D"}, "Beef.Linq" = {Path = "GlitchyEngine/vendor/Beef.Linq/src"}}
|
||||
Projects = {Sandbox = {Path = "Sandbox"}, GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, LodePng = {Path = "vendor/lodepng-beef/lodepng-beef"}, FreeType = {Path = "GlitchyEngine/vendor/freetype"}, cgltf-beef = {Path = "GlitchyEngine/vendor/gltf/cgltf-beef"}, GlitchyEditor = {Path = "GlitchyEditor"}, msdfgen-beef = {Path = "GlitchyEngine/vendor/msdfgen/msdfgen-beef"}, ImGui = {Path = "GlitchyEngine/vendor/imgui/ImGui"}, ImGuiImplDX11 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplDX11"}, ImGuiImplWin32 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplWin32"}, ImGuizmo = {Path = "GlitchyEngine/vendor/imgui/ImGuizmo"}, GlitchyEngineHelper = {Path = "GlitchyEngineHelper"}, bon = {Path = "GlitchyEngine/vendor/bon"}, box2d-beef = {Path = "GlitchyEngine/vendor/box2D"}, "Beef.Linq" = {Path = "GlitchyEngine/vendor/Beef.Linq/src"}, ScriptCore = {Path = "ScriptCore"}}
|
||||
Unlocked = ["corlib"]
|
||||
WorkspaceFolders = {GlitchyEngine = ["GlitchyEngine", "GlitchLog", "GlitchyEngineHelper"], "GlitchyEngine/Dependencies" = ["cgltf-beef", "DirectX", "FreeType", "ImGui", "ImGuiImplDX11", "ImGuiImplWin32", "ImGuizmo", "LodePng", "msdfgen-beef", "bon", "box2d-beef", "Beef.Linq"]}
|
||||
WorkspaceFolders = {GlitchyEngine = ["GlitchyEngine", "GlitchLog", "GlitchyEngineHelper", "ScriptCore"], "GlitchyEngine/Dependencies" = ["cgltf-beef", "DirectX", "FreeType", "ImGui", "ImGuiImplDX11", "ImGuiImplWin32", "ImGuizmo", "LodePng", "msdfgen-beef", "bon", "box2d-beef", "Beef.Linq"]}
|
||||
|
||||
[Workspace]
|
||||
StartupProject = "GlitchyEditor"
|
||||
|
||||
@@ -5,3 +5,6 @@ Dependencies = {corlib = "*", GlitchLog = "*", GlitchyEngine = "*"}
|
||||
Name = "GlitchyEditor"
|
||||
TargetType = "BeefGUIApplication"
|
||||
StartupObject = "GlitchyEngine.Program"
|
||||
|
||||
[Configs.Debug.Win64]
|
||||
DebugCommandArguments = "\"D:\\Development\\Projects\\Beef\\GlitchyEngine\\GlitchyEditor\\SandboxProject\""
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
project_user.bon
|
||||
@@ -30,10 +30,10 @@
|
||||
}
|
||||
},
|
||||
MeshComponent = {
|
||||
Mesh = "Models/sphere.glb"
|
||||
Mesh = "Assets/Models/sphere.glb"
|
||||
},
|
||||
MeshRendererComponent = {
|
||||
Material = "Textures/TestMaterial.mat"
|
||||
Material = "Assets/Textures/TestMaterial.mat"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -49,12 +49,12 @@
|
||||
},
|
||||
Rotation = {
|
||||
X = 0.614328027,
|
||||
Y = 0.239776045,
|
||||
Y = 0.23977606,
|
||||
Z = 0.0315669999,
|
||||
W = 0.751073837
|
||||
W = 0.751073778
|
||||
},
|
||||
Scale = {
|
||||
X = 0.999998868,
|
||||
X = 0.999998808,
|
||||
Y = 1,
|
||||
Z = 1.00000095
|
||||
},
|
||||
@@ -70,7 +70,7 @@
|
||||
Color = {
|
||||
R = 1,
|
||||
G = 0.991771996,
|
||||
B = 0.74086225
|
||||
B = 0.74086231
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -103,10 +103,10 @@
|
||||
}
|
||||
},
|
||||
MeshComponent = {
|
||||
Mesh = "Models/plane.glb"
|
||||
Mesh = "Assets/Models/plane.glb"
|
||||
},
|
||||
MeshRendererComponent = {
|
||||
Material = "Textures/TestMaterial.mat"
|
||||
Material = "Assets/Textures/TestMaterial.mat"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -146,7 +146,7 @@
|
||||
OrthographicHeight = 10,
|
||||
OrthographicNearPlane = 0,
|
||||
OrthographicFarPlane = 10,
|
||||
AspectRatio = 2.19888878,
|
||||
AspectRatio = 1.87453413,
|
||||
FixedAspectRatio = false
|
||||
}
|
||||
},
|
||||
@@ -164,7 +164,7 @@
|
||||
Rotation = {
|
||||
X = 0.18301262,
|
||||
Y = -0.683013558,
|
||||
Z = 0.683012128,
|
||||
Z = 0.683012187,
|
||||
W = 0.183013007
|
||||
},
|
||||
Scale = {
|
||||
@@ -173,13 +173,13 @@
|
||||
Z = 1
|
||||
},
|
||||
EditorEulerRotation = {
|
||||
X = 1.57079446,
|
||||
Y = -2.61799312,
|
||||
X = 1.57079458,
|
||||
Y = -2.61799288,
|
||||
Z = 0
|
||||
}
|
||||
},
|
||||
MeshComponent = {
|
||||
Mesh = "Models/plane.glb"
|
||||
Mesh = ""
|
||||
},
|
||||
MeshRendererComponent = {
|
||||
Material = ""
|
||||
@@ -192,32 +192,32 @@
|
||||
},
|
||||
TransformComponent = {
|
||||
Position = {
|
||||
X = 2.37353587,
|
||||
X = 2.37353563,
|
||||
Y = 0.629615188,
|
||||
Z = -1.34831977
|
||||
},
|
||||
Rotation = {
|
||||
X = 0.270598024,
|
||||
Y = -0.65328145,
|
||||
Y = -0.65328151,
|
||||
Z = 0.65328151,
|
||||
W = 0.270598054
|
||||
},
|
||||
Scale = {
|
||||
X = 0.999999881,
|
||||
Y = 0.999999821,
|
||||
X = 0.999999821,
|
||||
Y = 0.999999762,
|
||||
Z = 0.999999702
|
||||
},
|
||||
EditorEulerRotation = {
|
||||
X = 1.57079637,
|
||||
Y = -2.3561945,
|
||||
Z = 8.94069743e-08
|
||||
X = 1.57079649,
|
||||
Y = -2.35619426,
|
||||
Z = 8.94069601e-08
|
||||
}
|
||||
},
|
||||
MeshComponent = {
|
||||
Mesh = "Models/plane.glb"
|
||||
Mesh = "Assets/Models/plane.glb"
|
||||
},
|
||||
MeshRendererComponent = {
|
||||
Material = "Textures/RocketMaterial.mat"
|
||||
Material = "Assets/Textures/RocketMaterial.mat"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -13,7 +13,7 @@
|
||||
B = 0.32878688,
|
||||
A = 1
|
||||
},
|
||||
Sprite = "Textures/TestMat/rustediron2_albedo.png",
|
||||
Sprite = "Assets/Textures/TestMat/rustediron2_albedo.png",
|
||||
UvTransform = {
|
||||
X = 0,
|
||||
Y = 0,
|
||||
@@ -23,7 +23,7 @@
|
||||
},
|
||||
TransformComponent = {
|
||||
Position = {
|
||||
X = 0,
|
||||
X = -0.72789681,
|
||||
Y = 2,
|
||||
Z = 0
|
||||
},
|
||||
@@ -71,8 +71,8 @@
|
||||
SpriteRendererComponent = {
|
||||
Color = {
|
||||
R = 1,
|
||||
G = 0.941886365,
|
||||
B = 0.401484847,
|
||||
G = 0.941887021,
|
||||
B = 0.401484489,
|
||||
A = 1
|
||||
},
|
||||
Sprite = "",
|
||||
@@ -162,14 +162,20 @@
|
||||
OrthographicHeight = 10,
|
||||
OrthographicNearPlane = 0,
|
||||
OrthographicFarPlane = 10,
|
||||
AspectRatio = 3.22169805,
|
||||
AspectRatio = 2.05582929,
|
||||
FixedAspectRatio = false
|
||||
}
|
||||
},
|
||||
ScriptComponent = {
|
||||
ScriptClass = "Sandbox.Camera",
|
||||
Fields = [
|
||||
DistanceFromPlayer = (Float)-7,
|
||||
DontFollowRadius = (Float)3
|
||||
] }
|
||||
},
|
||||
{
|
||||
Id = 15710354273720487680,
|
||||
NameComponent = {
|
||||
Name = "Circle"
|
||||
Name = "Player"
|
||||
},
|
||||
CircleRendererComponent = {
|
||||
Color = {
|
||||
@@ -189,8 +195,8 @@
|
||||
},
|
||||
TransformComponent = {
|
||||
Position = {
|
||||
X = -0.12120308,
|
||||
Y = 0.660160363,
|
||||
X = -0.121203206,
|
||||
Y = 0.660161078,
|
||||
Z = 0
|
||||
},
|
||||
Rotation = {
|
||||
@@ -224,7 +230,17 @@
|
||||
Friction = 0.5,
|
||||
Restitution = 0,
|
||||
RestitutionThreshold = 0.5
|
||||
}
|
||||
},
|
||||
ScriptComponent = {
|
||||
ScriptClass = "Sandbox.MyTestEntity",
|
||||
Fields = [
|
||||
_rigidBody = (Component)15710354273720487680,
|
||||
TheEntity = (Entity)0,
|
||||
JumpForce = (Float)200,
|
||||
MoveForce = (Float)148,
|
||||
MyNumber = (Int)22,
|
||||
Camera = (Entity)1491484622542812645
|
||||
] }
|
||||
},
|
||||
{
|
||||
Id = 935640822766280888,
|
||||
@@ -249,9 +265,9 @@
|
||||
Z = 1
|
||||
},
|
||||
EditorEulerRotation = {
|
||||
X = 1.0908947,
|
||||
X = 1.09089541,
|
||||
Y = -0.340793997,
|
||||
Z = 0.160857916
|
||||
Z = 0.160857871
|
||||
}
|
||||
},
|
||||
LightComponent = {
|
||||
@@ -260,7 +276,7 @@
|
||||
Color = {
|
||||
R = 0.985467017,
|
||||
G = 1,
|
||||
B = 0.569978654
|
||||
B = 0.569977939
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -273,7 +289,7 @@
|
||||
Position = {
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Z = -1.47202551
|
||||
Z = 2.56930423
|
||||
},
|
||||
Rotation = {
|
||||
X = 0,
|
||||
@@ -293,10 +309,196 @@
|
||||
}
|
||||
},
|
||||
MeshComponent = {
|
||||
Mesh = "Models/sphere.glb"
|
||||
Mesh = "Assets/Models/sphere.glb"
|
||||
},
|
||||
MeshRendererComponent = {
|
||||
Material = "Textures/TestMaterial.mat"
|
||||
Material = "Assets/Textures/TestMaterial.mat"
|
||||
}
|
||||
},
|
||||
{
|
||||
Id = 2241063100006479259,
|
||||
NameComponent = {
|
||||
Name = "Floor 2"
|
||||
},
|
||||
SpriteRendererComponent = {
|
||||
Color = {
|
||||
R = 0.425658971,
|
||||
G = 0.855207443,
|
||||
B = 0.0558161177,
|
||||
A = 1
|
||||
},
|
||||
Sprite = "",
|
||||
UvTransform = {
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Z = 1,
|
||||
W = 1
|
||||
}
|
||||
},
|
||||
TransformComponent = {
|
||||
Position = {
|
||||
X = 6.74610233,
|
||||
Y = -2.03225946,
|
||||
Z = 0
|
||||
},
|
||||
Rotation = {
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Z = -0.331792623,
|
||||
W = 0.94335258
|
||||
},
|
||||
Scale = {
|
||||
X = 5.29557419,
|
||||
Y = 1,
|
||||
Z = 1
|
||||
},
|
||||
EditorEulerRotation = {
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Z = -0.676406503
|
||||
}
|
||||
},
|
||||
Rigidbody2D = {
|
||||
BodyType = .Static,
|
||||
FixedRotation = false
|
||||
},
|
||||
BoxCollider2D = {
|
||||
Offset = {
|
||||
X = 0,
|
||||
Y = 0
|
||||
},
|
||||
Size = {
|
||||
X = 0.5,
|
||||
Y = 0.5
|
||||
},
|
||||
Density = 1,
|
||||
Friction = 0.5,
|
||||
Restitution = 0,
|
||||
RestitutionThreshold = 0.5
|
||||
}
|
||||
},
|
||||
{
|
||||
Id = 5126705881069187728,
|
||||
NameComponent = {
|
||||
Name = "Floor 3"
|
||||
},
|
||||
SpriteRendererComponent = {
|
||||
Color = {
|
||||
R = 0.666117013,
|
||||
G = 0.0600316115,
|
||||
B = 1,
|
||||
A = 1
|
||||
},
|
||||
Sprite = "",
|
||||
UvTransform = {
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Z = 1,
|
||||
W = 1
|
||||
}
|
||||
},
|
||||
TransformComponent = {
|
||||
Position = {
|
||||
X = 15.2321281,
|
||||
Y = -1.98709273,
|
||||
Z = 0
|
||||
},
|
||||
Rotation = {
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Z = 0.134986058,
|
||||
W = 0.990847468
|
||||
},
|
||||
Scale = {
|
||||
X = 13.9764528,
|
||||
Y = 1,
|
||||
Z = 1
|
||||
},
|
||||
EditorEulerRotation = {
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Z = 0.270798802
|
||||
}
|
||||
},
|
||||
Rigidbody2D = {
|
||||
BodyType = .Static,
|
||||
FixedRotation = false
|
||||
},
|
||||
BoxCollider2D = {
|
||||
Offset = {
|
||||
X = 0,
|
||||
Y = 0
|
||||
},
|
||||
Size = {
|
||||
X = 0.5,
|
||||
Y = 0.5
|
||||
},
|
||||
Density = 1,
|
||||
Friction = 0.5,
|
||||
Restitution = 0.800000012,
|
||||
RestitutionThreshold = 0.5
|
||||
}
|
||||
},
|
||||
{
|
||||
Id = 6861260438693901700,
|
||||
NameComponent = {
|
||||
Name = "Floor 4"
|
||||
},
|
||||
SpriteRendererComponent = {
|
||||
Color = {
|
||||
R = 0.176544309,
|
||||
G = 0.666713238,
|
||||
B = 0.687030852,
|
||||
A = 1
|
||||
},
|
||||
Sprite = "",
|
||||
UvTransform = {
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Z = 1,
|
||||
W = 1
|
||||
}
|
||||
},
|
||||
TransformComponent = {
|
||||
Position = {
|
||||
X = -6.27842855,
|
||||
Y = 2.62550163,
|
||||
Z = 0
|
||||
},
|
||||
Rotation = {
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Z = 0.187087879,
|
||||
W = 0.982343197
|
||||
},
|
||||
Scale = {
|
||||
X = 0.999999464,
|
||||
Y = 6.49634314,
|
||||
Z = 1
|
||||
},
|
||||
EditorEulerRotation = {
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Z = 0.376393616
|
||||
}
|
||||
},
|
||||
Rigidbody2D = {
|
||||
BodyType = .Static,
|
||||
FixedRotation = false
|
||||
},
|
||||
BoxCollider2D = {
|
||||
Offset = {
|
||||
X = 0,
|
||||
Y = 0
|
||||
},
|
||||
Size = {
|
||||
X = 0.5,
|
||||
Y = 0.5
|
||||
},
|
||||
Density = 1,
|
||||
Friction = 0.5,
|
||||
Restitution = 0.899999857,
|
||||
RestitutionThreshold = 0.5
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,398 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.tlog
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
|
||||
*.vbp
|
||||
|
||||
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
||||
*.dsw
|
||||
*.dsp
|
||||
|
||||
# Visual Studio 6 technical files
|
||||
*.ncb
|
||||
*.aps
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# Visual Studio History (VSHistory) files
|
||||
.vshistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
# VS Code files for those working on multiple tools
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Windows Installer files from build outputs
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# JetBrains Rider
|
||||
*.sln.iml
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using GlitchyEngine;
|
||||
using GlitchyEngine.Math;
|
||||
|
||||
using static GlitchyEngine.Math.Math;
|
||||
|
||||
namespace Sandbox;
|
||||
public class Camera : Entity
|
||||
{
|
||||
public float DistanceFromPlayer = 5.0f;
|
||||
|
||||
public float DontFollowRadius = 3.0f;
|
||||
|
||||
void OnUpdate(float deltaTime)
|
||||
{
|
||||
Entity player = FindEntityWithName("Player");
|
||||
|
||||
if (player != null)
|
||||
{
|
||||
float2 playerPosition = player.Transform.Translation.XY;
|
||||
|
||||
float2 cameraPosition = Transform.Translation.XY;
|
||||
|
||||
float2 distanceVector = playerPosition - cameraPosition;
|
||||
|
||||
float distance = length(distanceVector);
|
||||
|
||||
float2 neededMovement = float2.Zero;
|
||||
|
||||
if (distance > DontFollowRadius)
|
||||
{
|
||||
neededMovement = distanceVector - (distanceVector / distance) * DontFollowRadius;
|
||||
}
|
||||
|
||||
Transform.Translation = new float3(cameraPosition + neededMovement, DistanceFromPlayer);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("Player not found!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
using System;
|
||||
using System.Runtime.Remoting.Metadata.W3cXsd2001;
|
||||
using GlitchyEngine;
|
||||
using GlitchyEngine.Editor;
|
||||
using GlitchyEngine.Math;
|
||||
|
||||
using static GlitchyEngine.Math.Math;
|
||||
|
||||
namespace Sandbox
|
||||
{
|
||||
|
||||
public enum MyEnum
|
||||
{
|
||||
Yes = 1,
|
||||
No,
|
||||
Maybe = 1337
|
||||
}
|
||||
|
||||
public struct MyStruct
|
||||
{
|
||||
public float TheFloat;
|
||||
public float2 TheVector;
|
||||
public MyEnum TheEnum;
|
||||
}
|
||||
|
||||
class MyTestEntity : Entity
|
||||
{
|
||||
[ShowInEditor]
|
||||
RigidBody2D _rigidBody;
|
||||
|
||||
//public bool Bo;
|
||||
|
||||
//public byte By;
|
||||
//public ushort Us;
|
||||
//public uint Ui;
|
||||
//public ulong Ul;
|
||||
|
||||
//public sbyte Sb;
|
||||
//public short Sh;
|
||||
//public int In;
|
||||
//public long Lo;
|
||||
|
||||
//public float Fl;
|
||||
//public double Do;
|
||||
//public float2 V2;
|
||||
//public float3 V3;
|
||||
//public float4 V4;
|
||||
|
||||
public Entity TheEntity;
|
||||
|
||||
public float JumpForce = 2000;
|
||||
[ShowInEditor] float MoveForce = 1000;
|
||||
[ShowInEditor] private int MyNumber = 1337;
|
||||
//[ShowInEditor] public double MyDouble = 1000.0f;
|
||||
|
||||
public MyStruct AStruct;
|
||||
|
||||
public MyEnum AEnum = MyEnum.Maybe;
|
||||
|
||||
public Camera Camera;
|
||||
|
||||
/// <summary>
|
||||
/// Called after the script component was created. (The entity might not be fully created yet)
|
||||
/// </summary>
|
||||
void OnCreate()
|
||||
{
|
||||
Log.Info($"Create! {UUID}");
|
||||
|
||||
Log.Info($"Jump Force: {JumpForce}");
|
||||
|
||||
//_rigidBody ??= GetComponent<RigidBody2D>() ?? AddComponent<RigidBody2D>();
|
||||
|
||||
if (_rigidBody == null)
|
||||
{
|
||||
Log.Error("_rigidBody was not set in editor.");
|
||||
}
|
||||
|
||||
if (Camera == null)
|
||||
{
|
||||
Log.Warning("Camera wasn't set in editor. Searching...");
|
||||
Camera = FindEntityWithName("Camera").As<Camera>();
|
||||
|
||||
if (Camera == null)
|
||||
{
|
||||
Log.Error("Camera not found.");
|
||||
}
|
||||
}
|
||||
Log.Warning("Achtung.");
|
||||
|
||||
try
|
||||
{
|
||||
SubVoid();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
void SubVoid()
|
||||
{
|
||||
throw new Exception("Ouha!", new IndexOutOfRangeException("Bist du jecke2?!", new AccessViolationException("Haleluja")));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called every frame.
|
||||
/// </summary>
|
||||
/// <param name="deltaTime"></param>
|
||||
void OnUpdate(float deltaTime)
|
||||
{
|
||||
float2 force = float2.Zero;
|
||||
|
||||
if (Input.IsKeyPressed(Key.A))
|
||||
{
|
||||
force.X -= MoveForce * deltaTime;
|
||||
}
|
||||
|
||||
if (Input.IsKeyPressed(Key.D))
|
||||
{
|
||||
force.X += MoveForce * deltaTime;
|
||||
}
|
||||
|
||||
if (Input.IsKeyPressed(Key.Q))
|
||||
Camera.DistanceFromPlayer -= deltaTime;
|
||||
|
||||
if (Input.IsKeyPressed(Key.E))
|
||||
Camera.DistanceFromPlayer += deltaTime;
|
||||
|
||||
if (Input.IsKeyPressing(Key.Space))
|
||||
{
|
||||
force.Y += JumpForce;
|
||||
}
|
||||
|
||||
if (Input.IsKeyPressing(Key.N))
|
||||
SubVoid();
|
||||
|
||||
_rigidBody.ApplyForceToCenter(force);
|
||||
|
||||
if (Input.IsMouseButtonReleasing(MouseButton.MiddleButton))
|
||||
{
|
||||
Log.Info($"Ouha! {MyNumber}");
|
||||
Physics2D.Gravity *= new float2(1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called before the component is being destroyed.
|
||||
/// </summary>
|
||||
void OnDestroy()
|
||||
{
|
||||
Log.Trace("Destroy");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||
// die einer Assembly zugeordnet sind.
|
||||
[assembly: AssemblyTitle("SandboxProject")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SandboxProject")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2023")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
|
||||
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
|
||||
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
|
||||
[assembly: Guid("7a70819c-5317-402a-8553-95c5a001e370")]
|
||||
|
||||
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||
//
|
||||
// Hauptversion
|
||||
// Nebenversion
|
||||
// Buildnummer
|
||||
// Revision
|
||||
//
|
||||
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
|
||||
// indem Sie "*" wie unten gezeigt eingeben:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{7A70819C-5317-402A-8553-95C5A001E370}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>SandboxProject</RootNamespace>
|
||||
<AssemblyName>SandboxProject</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>portable</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<LangVersion>default</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<LangVersion>default</LangVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Camera.cs" />
|
||||
<Compile Include="MyTestEntity.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\ScriptCore\ScriptCore.csproj">
|
||||
<Project>{6222c226-fc78-498c-80ba-5cf10ac9123c}</Project>
|
||||
<Name>ScriptCore</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1,37 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.4.33205.214
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SandboxProject", "SandboxProject.csproj", "{7A70819C-5317-402A-8553-95C5A001E370}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ScriptCore", "..\..\..\..\ScriptCore\ScriptCore.csproj", "{6222C226-FC78-498C-80BA-5CF10AC9123C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScriptCoreGenerator", "..\..\..\..\ScriptCoreGenerator\ScriptCoreGenerator.csproj", "{5D662996-1E1E-4170-A08A-B26CDB63A0DE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7A70819C-5317-402A-8553-95C5A001E370}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7A70819C-5317-402A-8553-95C5A001E370}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7A70819C-5317-402A-8553-95C5A001E370}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7A70819C-5317-402A-8553-95C5A001E370}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6222C226-FC78-498C-80BA-5CF10AC9123C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6222C226-FC78-498C-80BA-5CF10AC9123C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6222C226-FC78-498C-80BA-5CF10AC9123C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6222C226-FC78-498C-80BA-5CF10AC9123C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5D662996-1E1E-4170-A08A-B26CDB63A0DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5D662996-1E1E-4170-A08A-B26CDB63A0DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5D662996-1E1E-4170-A08A-B26CDB63A0DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5D662996-1E1E-4170-A08A-B26CDB63A0DE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {B5D43D8D-D80B-41AA-BE40-1DC507D87148}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
Before Width: | Height: | Size: 119 B After Width: | Height: | Size: 119 B |
@@ -0,0 +1,31 @@
|
||||
{
|
||||
Effect = "Resources/Shaders/myEffect.hlsl",
|
||||
Textures = [
|
||||
"AlbedoTexture": "Assets/Textures/rocket.png",
|
||||
"NormalTexture": "Assets/Textures/TestMat/rustediron2_normal.png",
|
||||
"MetallicTexture": "Assets/Textures/TestMat/rustediron2_metallic.png",
|
||||
"RoughnessTexture": "Assets/Textures/TestMat/rustediron2_roughness.png"
|
||||
],
|
||||
Variables = [
|
||||
"AlbedoColor": .ColorRGBA{
|
||||
Value = {
|
||||
R = 1,
|
||||
G = 1,
|
||||
B = 1,
|
||||
A = 1
|
||||
}
|
||||
},
|
||||
"NormalScaling": .Float2{
|
||||
Value = {
|
||||
X = 1,
|
||||
Y = 1
|
||||
}
|
||||
},
|
||||
"MetallicFactor": .Float{
|
||||
Value = 0
|
||||
},
|
||||
"RoughnessFactor": .Float{
|
||||
Value = 1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 119 B After Width: | Height: | Size: 119 B |
|
Before Width: | Height: | Size: 10 MiB After Width: | Height: | Size: 10 MiB |
|
Before Width: | Height: | Size: 3.3 MiB After Width: | Height: | Size: 3.3 MiB |
@@ -0,0 +1,23 @@
|
||||
{
|
||||
AssetLoader = "EditorTextureAssetLoader",
|
||||
Config = (GlitchyEditor.Assets.EditorTextureAssetLoaderConfig){
|
||||
_samplerStateDescription = {
|
||||
MinFilter = .Anisotropic,
|
||||
MagFilter = .Anisotropic,
|
||||
MipFilter = .Anisotropic,
|
||||
ComparisonFunction = .Never,
|
||||
AddressModeU = .Wrap,
|
||||
AddressModeV = .Wrap,
|
||||
AddressModeW = .Clamp,
|
||||
MipMinLOD = -Infinity,
|
||||
MipMaxLOD = Infinity,
|
||||
MaxAnisotropy = 1,
|
||||
BorderColor = {
|
||||
R = 1,
|
||||
G = 1,
|
||||
B = 1,
|
||||
A = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 7.4 MiB After Width: | Height: | Size: 7.4 MiB |
|
Before Width: | Height: | Size: 3.0 MiB After Width: | Height: | Size: 3.0 MiB |
@@ -0,0 +1,39 @@
|
||||
{
|
||||
Effect = "Resources/Shaders/myEffect.hlsl",
|
||||
Textures = [
|
||||
"AlbedoTexture": "Assets/Textures/TestMat/rustediron2_albedo.png",
|
||||
"NormalTexture": "Assets/Textures/TestMat/rustediron2_normal.png",
|
||||
"MetallicTexture": "Assets/Textures/TestMat/rustediron2_metallic.png",
|
||||
"RoughnessTexture": "Assets/Textures/TestMat/rustediron2_roughness.png",
|
||||
"EmissiveTexture": "Assets/Textures/rocket.png"
|
||||
],
|
||||
Variables = [
|
||||
"AlbedoColor": .ColorRGBA{
|
||||
Value = {
|
||||
R = 1,
|
||||
G = 1,
|
||||
B = 1,
|
||||
A = 1
|
||||
}
|
||||
},
|
||||
"NormalScaling": .Float2{
|
||||
Value = {
|
||||
X = 1,
|
||||
Y = 1
|
||||
}
|
||||
},
|
||||
"MetallicFactor": .Float{
|
||||
Value = 1
|
||||
},
|
||||
"RoughnessFactor": .Float{
|
||||
Value = 1
|
||||
},
|
||||
"EmissiveColor": .ColorRGB{
|
||||
Value = {
|
||||
R = 1,
|
||||
G = 0,
|
||||
B = 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 119 B After Width: | Height: | Size: 119 B |
|
Before Width: | Height: | Size: 258 B After Width: | Height: | Size: 258 B |
@@ -1,20 +1,17 @@
|
||||
{
|
||||
AssetLoader = "EditorTextureAssetLoader",
|
||||
Config = (GlitchyEditor.Assets.EditorTextureAssetLoaderConfig){
|
||||
_generateMipMaps = false,
|
||||
_isSrgb = false,
|
||||
_isSrgb = true,
|
||||
_samplerStateDescription = {
|
||||
MinFilter = .Linear,
|
||||
MagFilter = .Linear,
|
||||
MipFilter = .Linear,
|
||||
FilterMode = .Default,
|
||||
ComparisonFunction = .Never,
|
||||
AddressModeU = .Wrap,
|
||||
AddressModeV = .Wrap,
|
||||
AddressModeU = .Clamp,
|
||||
AddressModeV = .Clamp,
|
||||
AddressModeW = .Clamp,
|
||||
MipLODBias = 0,
|
||||
MipMinLOD = -3.40282347e+38,
|
||||
MipMaxLOD = 3.40282347e+38,
|
||||
MipMinLOD = -Infinity,
|
||||
MipMaxLOD = Infinity,
|
||||
MaxAnisotropy = 1,
|
||||
BorderColor = {
|
||||
R = 1,
|
||||
@@ -0,0 +1 @@
|
||||
{_projectName="SandboxProject"}
|
||||
@@ -1,31 +0,0 @@
|
||||
{
|
||||
Effect = "Shaders/myEffect.hlsl",
|
||||
Textures = [
|
||||
"AlbedoTexture": "Textures/rocket.png",
|
||||
"NormalTexture": "Textures/TestMat/rustediron2_normal.png",
|
||||
"MetallicTexture": "Textures/TestMat/rustediron2_metallic.png",
|
||||
"RoughnessTexture": "Textures/TestMat/rustediron2_roughness.png"
|
||||
],
|
||||
Variables = [
|
||||
"AlbedoColor": .ColorRGBA{
|
||||
Value = {
|
||||
R = 1,
|
||||
G = 1,
|
||||
B = 1,
|
||||
A = 1
|
||||
}
|
||||
},
|
||||
"NormalScaling": .Float2{
|
||||
Value = {
|
||||
X = 1,
|
||||
Y = 1
|
||||
}
|
||||
},
|
||||
"MetallicFactor": .Float{
|
||||
Value = 0
|
||||
},
|
||||
"RoughnessFactor": .Float{
|
||||
Value = 1
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
{
|
||||
Effect = "Shaders\\myEffect.hlsl",
|
||||
Textures = [
|
||||
"AlbedoTexture": "Textures\\TestMat\\rustediron2_albedo.png",
|
||||
"NormalTexture": "Textures\\TestMat\\rustediron2_normal.png",
|
||||
"MetallicTexture": "Textures\\TestMat\\rustediron2_metallic.png",
|
||||
"RoughnessTexture": "Textures\\TestMat\\rustediron2_roughness.png"
|
||||
],
|
||||
Variables = [
|
||||
"AlbedoColor": .ColorRGBA{
|
||||
Value = {
|
||||
R = 1,
|
||||
G = 1,
|
||||
B = 1,
|
||||
A = 1
|
||||
}
|
||||
},
|
||||
"NormalScaling": .Float2{
|
||||
Value = {
|
||||
X = 1,
|
||||
Y = 1
|
||||
}
|
||||
},
|
||||
"MetallicFactor": .Float{
|
||||
Value = 1
|
||||
},
|
||||
"RoughnessFactor": .Float{
|
||||
Value = 1
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
4.5/
|
||||
@@ -0,0 +1 @@
|
||||
Install mono and copy the folder `lib/mono/4.5` here!
|
||||
@@ -0,0 +1 @@
|
||||
project_user.bon
|
||||
@@ -0,0 +1,398 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.tlog
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
|
||||
*.vbp
|
||||
|
||||
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
||||
*.dsw
|
||||
*.dsp
|
||||
|
||||
# Visual Studio 6 technical files
|
||||
*.ncb
|
||||
*.aps
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# Visual Studio History (VSHistory) files
|
||||
.vshistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
# VS Code files for those working on multiple tools
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Windows Installer files from build outputs
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# JetBrains Rider
|
||||
*.sln.iml
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||
// die einer Assembly zugeordnet sind.
|
||||
[assembly: AssemblyTitle("[ProjectName]")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("[ProjectName]")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2023")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
|
||||
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
|
||||
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
|
||||
[assembly: Guid("7a70819c-5317-402a-8553-95c5a001e370")]
|
||||
|
||||
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||
//
|
||||
// Hauptversion
|
||||
// Nebenversion
|
||||
// Buildnummer
|
||||
// Revision
|
||||
//
|
||||
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
|
||||
// indem Sie "*" wie unten gezeigt eingeben:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{7A70819C-5317-402A-8553-95C5A001E370}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>[ProjectName]</RootNamespace>
|
||||
<AssemblyName>[ProjectName]</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>portable</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<LangVersion>default</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<LangVersion>default</LangVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="ScriptCore, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>[CoreLibPath]</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.4.33205.214
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "[ProjectName]", "[ProjectName].csproj", "{7A70819C-5317-402A-8553-95C5A001E370}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7A70819C-5317-402A-8553-95C5A001E370}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7A70819C-5317-402A-8553-95C5A001E370}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7A70819C-5317-402A-8553-95C5A001E370}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7A70819C-5317-402A-8553-95C5A001E370}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {B5D43D8D-D80B-41AA-BE40-1DC507D87148}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,59 @@
|
||||
#pragma EngineBuffer[ Name = "SceneConstants"; Binding = "Scene" ]
|
||||
cbuffer SceneConstants : register(b0)
|
||||
{
|
||||
float4x4 ViewProjection;
|
||||
}
|
||||
|
||||
#pragma EngineBuffer[ Name = "ObjectConstants"; Binding = "Object" ]
|
||||
cbuffer ObjectConstants : register(b1)
|
||||
{
|
||||
float4x4 Transform;
|
||||
/**
|
||||
* \brief Inverted and transposed transform matrix.
|
||||
* \remarks This matrix is used in order to correctly transform normal vectors.
|
||||
*/
|
||||
float4x3 Transform_InvT;
|
||||
#ifdef OutputEntityId
|
||||
uint EntityId;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Pixel Shader output for lit surfaces.
|
||||
*/
|
||||
struct PS_OUT_Lit
|
||||
{
|
||||
/** RGB: Albedo A: Transparency */
|
||||
float4 Albedo : SV_TARGET0;
|
||||
/** RG: TextureNormal.XY | BA: GeoNrm.XY */
|
||||
float4 Normal : SV_TARGET1;
|
||||
/** R: GeoNrm.Z | GBA: GeoTan.XYZ */
|
||||
float4 Tangent : SV_TARGET2;
|
||||
/** RGB: world position XYZ | A: 1.0 */
|
||||
float4 Position : SV_TARGET3;
|
||||
/** RGB: emissive light and color | A: unused */
|
||||
float4 Emissive : SV_TARGET4;
|
||||
/** R: Metallicity | G: Roughness | B: Ambient | A: Unused */
|
||||
float4 Material : SV_TARGET5;
|
||||
#ifdef OutputEntityId
|
||||
/** Needed for editor picking. Simply pass through the EntityId. */
|
||||
uint EntityId : SV_TARGET6;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Pixel Shader output for unlit surfaces.
|
||||
*/
|
||||
struct PS_OUT_Unlit
|
||||
{
|
||||
/** RGB: Color A: Transparency */
|
||||
float4 Color : SV_TARGET0;
|
||||
/** RGB: emissive light and color | A: unused */
|
||||
float4 Emissive : SV_TARGET1;
|
||||
/** RGB: world position XYZ | A: 1.0 */
|
||||
float4 Position : SV_TARGET2;
|
||||
|
||||
#ifdef OutputEntityId
|
||||
uint EntityId : SV_TARGET5;
|
||||
#endif
|
||||
};
|
||||
@@ -0,0 +1,111 @@
|
||||
Texture2DArray Texture : register(t0);
|
||||
SamplerState Sampler : register(s0);
|
||||
|
||||
Texture2DArray<int4> IntTexture : register(t1);
|
||||
SamplerState IntSampler : register(s1);
|
||||
|
||||
Texture2DArray<uint4> UIntTexture : register(t2);
|
||||
SamplerState UIntSampler : register(s2);
|
||||
|
||||
#define SWIZZLE_NONE 0
|
||||
#define SWIZZLE_R 1
|
||||
#define SWIZZLE_G 2
|
||||
#define SWIZZLE_B 3
|
||||
#define SWIZZLE_A 4
|
||||
|
||||
cbuffer Constants
|
||||
{
|
||||
float ColorOffset = 0.5;
|
||||
float AlphaOffset = 0.0;
|
||||
float ColorScale = 0.5;
|
||||
float AlphaScale = 1.0;
|
||||
|
||||
float MipLevel = 0.0;
|
||||
float ArraySlice = 0.0;
|
||||
|
||||
// 0: Float | 1: Int | 2: Uint
|
||||
int Mode = 0;
|
||||
|
||||
int4 Swizzle = int4(SWIZZLE_R, SWIZZLE_G, SWIZZLE_B, SWIZZLE_A);
|
||||
|
||||
float2 Texels;
|
||||
|
||||
float4x4 WorldViewProjection;
|
||||
}
|
||||
|
||||
struct VS_Input
|
||||
{
|
||||
float2 Position : POSITION;
|
||||
float2 Texcoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PS_Input
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float2 Texcoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
PS_Input VS(VS_Input input)
|
||||
{
|
||||
PS_Input output;
|
||||
|
||||
output.Position = mul(WorldViewProjection, float4(input.Position, 0.0f, 1.0f));
|
||||
output.Texcoord = input.Texcoord;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void SwizzleColor(int swizzleMode, float4 colorToSwizzle, inout float output)
|
||||
{
|
||||
switch (swizzleMode)
|
||||
{
|
||||
case SWIZZLE_R:
|
||||
output = colorToSwizzle.r;
|
||||
break;
|
||||
case SWIZZLE_G:
|
||||
output = colorToSwizzle.g;
|
||||
break;
|
||||
case SWIZZLE_B:
|
||||
output = colorToSwizzle.b;
|
||||
break;
|
||||
case SWIZZLE_A:
|
||||
output = colorToSwizzle.a;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float4 PS(PS_Input input) : SV_Target0
|
||||
{
|
||||
float4 outputColor;
|
||||
|
||||
if (Mode == 0)
|
||||
{
|
||||
//float4 color = Texture.SampleLevel(Sampler, float3(input.Texcoord, ArraySlice), MipLevel);
|
||||
// Quasi next neighbor
|
||||
float4 color = Texture.Load(int4(input.Texcoord * Texels, ArraySlice, MipLevel));
|
||||
outputColor = float4(ColorOffset.xxx, AlphaOffset) + color * float4(ColorScale.xxx, AlphaScale);
|
||||
}
|
||||
else if (Mode == 1)
|
||||
{
|
||||
int4 color = IntTexture.Load(int4(input.Texcoord * Texels, ArraySlice, MipLevel));
|
||||
outputColor = float4(ColorOffset.xxx, AlphaOffset) + color * float4(ColorScale.xxx, AlphaScale);
|
||||
}
|
||||
else if (Mode == 2)
|
||||
{
|
||||
uint4 color = UIntTexture.Load(int4(input.Texcoord * Texels, ArraySlice, MipLevel));
|
||||
outputColor = float4(ColorOffset.xxx, AlphaOffset) + color * float4(ColorScale.xxx, AlphaScale);
|
||||
}
|
||||
|
||||
float4 swizzledOutput = float4(0, 0, 0, 1);
|
||||
|
||||
SwizzleColor(Swizzle.r, outputColor, swizzledOutput.r);
|
||||
SwizzleColor(Swizzle.g, outputColor, swizzledOutput.g);
|
||||
SwizzleColor(Swizzle.b, outputColor, swizzledOutput.b);
|
||||
SwizzleColor(Swizzle.a, outputColor, swizzledOutput.a);
|
||||
|
||||
return swizzledOutput;
|
||||
}
|
||||
|
||||
#pragma Effect[VS=VS; PS=PS]
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
AssetLoader = "EffectAssetLoader",
|
||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}/* No reflection data for GlitchyEditor.Assets.EffectAssetLoaderConfig. Add [BonTarget] or force it */
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
AssetLoader = "EffectAssetLoader",
|
||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}/* No reflection data for GlitchyEditor.Assets.EffectAssetLoaderConfig. Add [BonTarget] or force it */
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "ShaderHelpers.hlsl"
|
||||
|
||||
#include "GlitchyEngine.hlsl"
|
||||
|
||||
Texture2D AlbedoTexture : register(t0);
|
||||
SamplerState AlbedoSampler : register(s0);
|
||||
|
||||
@@ -14,28 +16,11 @@ SamplerState MetallicSampler : register(s2);
|
||||
Texture2D<float> RoughnessTexture : register(t3);
|
||||
SamplerState RoughnessSampler : register(s3);
|
||||
|
||||
// Texture2D<float> AmbientTexture : register(t4);
|
||||
// SamplerState AmbientSampler : register(s4);
|
||||
Texture2D<float3> EmissiveTexture : register(t4);
|
||||
SamplerState EmissiveSampler : register(s4);
|
||||
|
||||
#pragma EngineBuffer[ Name = "SceneConstants"; Binding = "Scene" ]
|
||||
cbuffer SceneConstants : register(b0)
|
||||
{
|
||||
float4x4 ViewProjection;
|
||||
}
|
||||
|
||||
#pragma EngineBuffer[ Name = "ObjectConstants"; Binding = "Object" ]
|
||||
cbuffer ObjectConstants : register(b1)
|
||||
{
|
||||
float4x4 Transform;
|
||||
/**
|
||||
* \brief Inverted and transposed transform matrix.
|
||||
* \remarks This matrix is used in order to correctly transform normal vectors.
|
||||
*/
|
||||
float4x3 Transform_InvT;
|
||||
#ifdef OutputEntityId
|
||||
uint EntityId;
|
||||
#endif
|
||||
}
|
||||
// Texture2D<float> AmbientTexture : register(t5);
|
||||
// SamplerState AmbientSampler : register(s5);
|
||||
|
||||
cbuffer MaterialConstants : register(b2)
|
||||
{
|
||||
@@ -44,9 +29,12 @@ cbuffer MaterialConstants : register(b2)
|
||||
#pragma EditorVariable[ Name = "NormalScaling"; Preview = "Normal Scaling" ]
|
||||
float2 NormalScaling = float2(1.0, 1.0);
|
||||
#pragma EditorVariable[ Name = "MetallicFactor"; Preview = "Metallic Factor"; Min = 0.0f; Max = 1.0f ]
|
||||
float MetallicFactor = 1.0;
|
||||
float MetallicFactor = 0.0;
|
||||
#pragma EditorVariable[ Name = "RoughnessFactor"; Preview = "Rougness Factor"; Min = 0.0f; Max = 1.0f ]
|
||||
float RoughnessFactor = 1.0;
|
||||
float RoughnessFactor = 0.6;
|
||||
#pragma EditorVariable[ Name = "EmissiveColor"; Preview = "Emissive Factor"; Type="ColorHDR" ]
|
||||
float3 EmissiveColor = float3(0.0, 0.0, 0.0);
|
||||
// # pra gma Editor Variable[ Name = "AmbientFactor"; Preview = "Ambient Factor" ]
|
||||
// float AmbientFactor = 1.0;
|
||||
}
|
||||
|
||||
@@ -59,7 +47,7 @@ struct VS_IN
|
||||
float2 TexCoord : TEXCOORD;
|
||||
};
|
||||
|
||||
struct PS_IN
|
||||
typedef struct PS_IN
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float3 WorldPosition : WORLDPOSITION;
|
||||
@@ -70,11 +58,11 @@ struct PS_IN
|
||||
#ifdef OutputEntityId
|
||||
nointerpolation uint EntityId : ENTITYID;
|
||||
#endif
|
||||
};
|
||||
} VS_OUT;
|
||||
|
||||
PS_IN VS(VS_IN input)
|
||||
VS_OUT VS(VS_IN input)
|
||||
{
|
||||
PS_IN output;
|
||||
VS_OUT output;
|
||||
|
||||
float4 worldPosition = mul(Transform, float4(input.Position, 1));
|
||||
|
||||
@@ -92,22 +80,22 @@ PS_IN VS(VS_IN input)
|
||||
return output;
|
||||
}
|
||||
|
||||
struct PS_OUT
|
||||
{
|
||||
float4 Albedo : SV_TARGET0;
|
||||
// RG: TextureNormal.XY BA: GeoNrm.XY
|
||||
float4 Normal : SV_TARGET1;
|
||||
// R: GeoNrm.Z GBA: GeoTan.XYZ
|
||||
float4 Tangent : SV_TARGET2;
|
||||
float4 Position : SV_TARGET3;
|
||||
// R: Metallicity G: Roughness B: Ambient
|
||||
float4 Material : SV_TARGET4;
|
||||
#ifdef OutputEntityId
|
||||
uint EntityId : SV_TARGET5;
|
||||
#endif
|
||||
};
|
||||
//struct PS_OUT
|
||||
//{
|
||||
// float4 Albedo : SV_TARGET0;
|
||||
// // RG: TextureNormal.XY BA: GeoNrm.XY
|
||||
// float4 Normal : SV_TARGET1;
|
||||
// // R: GeoNrm.Z GBA: GeoTan.XYZ
|
||||
// float4 Tangent : SV_TARGET2;
|
||||
// float4 Position : SV_TARGET3;
|
||||
// // R: Metallicity G: Roughness B: Ambient
|
||||
// float4 Material : SV_TARGET4;
|
||||
//#ifdef OutputEntityId
|
||||
// uint EntityId : SV_TARGET5;
|
||||
//#endif
|
||||
//};
|
||||
|
||||
PS_OUT PS(PS_IN input)
|
||||
PS_OUT_Lit PS(PS_IN input)
|
||||
{
|
||||
// Build tangent space
|
||||
float3 normal = normalize(input.Normal);
|
||||
@@ -124,6 +112,9 @@ PS_OUT PS(PS_IN input)
|
||||
float texMetallic = MetallicTexture.Sample(MetallicSampler, input.TexCoord);
|
||||
float texRoughness = RoughnessTexture.Sample(RoughnessSampler, input.TexCoord);
|
||||
|
||||
|
||||
float3 texEmissive = EmissiveTexture.Sample(EmissiveSampler, input.TexCoord);
|
||||
|
||||
//float3 objectNormal = mul(tangentTransform, texNormal);
|
||||
//float3 worldNormal = mul(objectNormal, (float3x3)Transform);
|
||||
|
||||
@@ -131,6 +122,7 @@ PS_OUT PS(PS_IN input)
|
||||
float3 finalNormal = ScaleNormal(texNormal, NormalScaling);
|
||||
float finalMetallic = texMetallic * MetallicFactor;
|
||||
float finalRoughness = texRoughness * RoughnessFactor;
|
||||
float3 finalEmissive = texEmissive * EmissiveColor;
|
||||
|
||||
/////////////TODO: REMOVEME
|
||||
|
||||
@@ -141,12 +133,13 @@ PS_OUT PS(PS_IN input)
|
||||
|
||||
/////////////TODO: END_REMOVEME
|
||||
|
||||
PS_OUT output;
|
||||
PS_OUT_Lit output;
|
||||
output.Albedo = finalAlbedo;
|
||||
//output.Normal = float4(objectNormal, 1.0);
|
||||
output.Normal = float4(finalNormal.xy, normal.xy);
|
||||
output.Tangent = float4(normal.z, tangent.xyz);
|
||||
output.Position = float4(input.WorldPosition, 1.0);
|
||||
output.Emissive = float4(finalEmissive, 0.0);
|
||||
output.Material = float4(finalMetallic, finalRoughness, 1.0, 0);
|
||||
|
||||
#ifdef OutputEntityId
|
||||
@@ -15,7 +15,8 @@ Texture2D GBuffer_Albedo : register(t0);
|
||||
Texture2D GBuffer_Normal : register(t1);
|
||||
Texture2D GBuffer_Tangent : register(t2);
|
||||
Texture2D GBuffer_Position : register(t3);
|
||||
Texture2D GBuffer_Material : register(t4);
|
||||
Texture2D GBuffer_Emissive : register(t4);
|
||||
Texture2D GBuffer_Material : register(t5);
|
||||
|
||||
cbuffer Constants
|
||||
{
|
||||
@@ -58,7 +59,8 @@ float4 PS(PS_IN input) : SV_TARGET
|
||||
float4 rawAlbedo = GBuffer_Albedo.Sample(Sampler, input.TexCoord);
|
||||
float4 rawNormal = GBuffer_Normal.Sample(Sampler, input.TexCoord);
|
||||
float4 rawTangent = GBuffer_Tangent.Sample(Sampler, input.TexCoord);
|
||||
float4 rawPosition = GBuffer_Position.Sample(Sampler, input.TexCoord);
|
||||
float4 rawPosition = GBuffer_Position.Sample(Sampler, input.TexCoord);
|
||||
float4 rawEmissive = GBuffer_Emissive.Sample(Sampler, input.TexCoord);
|
||||
float4 rawMaterial = GBuffer_Material.Sample(Sampler, input.TexCoord);
|
||||
|
||||
// Extract data from GBuffer
|
||||
@@ -108,7 +110,7 @@ float4 PS(PS_IN input) : SV_TARGET
|
||||
|
||||
float3 luminanceColor = LightColor * Illuminance;
|
||||
|
||||
float3 final = (kd * diffuse + specular) * luminanceColor * n_dot_l;
|
||||
float3 final = (kd * diffuse + specular) * luminanceColor * n_dot_l + rawEmissive;
|
||||
|
||||
#if OUTPUT == Inspect_NormalDistribution
|
||||
final = max(final - 10000000, nrmDist.xxx);
|
||||
@@ -9,8 +9,8 @@
|
||||
AddressModeU = .Clamp,
|
||||
AddressModeV = .Clamp,
|
||||
AddressModeW = .Clamp,
|
||||
MipMinLOD = -340282346638528859811704183484516925440,
|
||||
MipMaxLOD = 340282346638528859811704183484516925440,
|
||||
MipMinLOD = -3.40282347e+38,
|
||||
MipMaxLOD = 3.40282347e+38,
|
||||
MaxAnisotropy = 1,
|
||||
BorderColor = {
|
||||
R = 1,
|
||||
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETStandard,Version=v2.0/",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETStandard,Version=v2.0": {},
|
||||
".NETStandard,Version=v2.0/": {
|
||||
"ScriptCore/1.0.0": {
|
||||
"dependencies": {
|
||||
"Half": "1.0.0",
|
||||
"NETStandard.Library": "2.0.3"
|
||||
},
|
||||
"runtime": {
|
||||
"ScriptCore.dll": {}
|
||||
}
|
||||
},
|
||||
"Half/1.0.0": {
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/System.Half.dll": {
|
||||
"assemblyVersion": "1.0.0.0",
|
||||
"fileVersion": "1.0.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.NETCore.Platforms/1.1.0": {},
|
||||
"NETStandard.Library/2.0.3": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"ScriptCore/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Half/1.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-EPLLPQA1UjF9QM3ymNhWLhgcnBNc8e1po4qWRWTD3Hd9xiohYlkCob0QjDIbJs6Nvfd4eAbsjxIwRyh7httyXA==",
|
||||
"path": "half/1.0.0",
|
||||
"hashPath": "half.1.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.NETCore.Platforms/1.1.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==",
|
||||
"path": "microsoft.netcore.platforms/1.1.0",
|
||||
"hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512"
|
||||
},
|
||||
"NETStandard.Library/2.0.3": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
|
||||
"path": "netstandard.library/2.0.3",
|
||||
"hashPath": "netstandard.library.2.0.3.nupkg.sha512"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ public class AssetNode
|
||||
{
|
||||
public String Name ~ delete _;
|
||||
public String Path ~ delete _;
|
||||
public String Identifier ~ delete _;
|
||||
|
||||
public bool IsDirectory;
|
||||
|
||||
@@ -38,14 +39,43 @@ public static class AssetIdentifier
|
||||
{
|
||||
public const char8 DirectorySeparatorChar = '/';
|
||||
|
||||
// TODO: Asset identifiers and paths have little to do with each other and already caused a bit of pain, we should consider not using String for both.
|
||||
/// Removes or unifies potential platform specific or file-path related stuff in the given asset identifier
|
||||
public static void Fixup(String assetIdentifier)
|
||||
{
|
||||
const String DotSeperator = $".{DirectorySeparatorChar}";
|
||||
const String SeperatorDot = $"{DirectorySeparatorChar}.";
|
||||
int dotIndex = 0;
|
||||
|
||||
assetIdentifier.Replace('\\', DirectorySeparatorChar);
|
||||
assetIdentifier.Replace(DotSeperator, "");
|
||||
assetIdentifier.Replace(SeperatorDot, "");
|
||||
|
||||
// Replace /./ stuff
|
||||
while ((dotIndex = assetIdentifier.IndexOf('.', dotIndex)) != -1)
|
||||
{
|
||||
char8 lastChar = '\0';
|
||||
char8 nextChar = '\0';
|
||||
|
||||
int nextIndex = dotIndex + 1;
|
||||
if (nextIndex < assetIdentifier.Length)
|
||||
nextChar = assetIdentifier[nextIndex];
|
||||
|
||||
int lastIndex = dotIndex - 1;
|
||||
if (lastIndex < assetIdentifier.Length)
|
||||
lastChar = assetIdentifier[nextIndex];
|
||||
|
||||
// We either need to have a slash on both sides, or we have to be at the start or end of the string
|
||||
if ((lastChar == '\0' || lastChar == DirectorySeparatorChar) &&
|
||||
(lastChar == '\0' || lastChar == DirectorySeparatorChar))
|
||||
{
|
||||
if (lastChar != '\0')
|
||||
assetIdentifier.Remove(lastIndex, 2);
|
||||
else
|
||||
assetIdentifier.Remove(dotIndex, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skip the dot
|
||||
dotIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (assetIdentifier.StartsWith(DirectorySeparatorChar))
|
||||
assetIdentifier.Remove(0, 1);
|
||||
@@ -61,32 +91,124 @@ class AssetHierarchy
|
||||
|
||||
bool _fileSystemDirty = false;
|
||||
|
||||
internal TreeNode<AssetNode> _assetHierarchy = null ~ DeleteTreeAndChildren!(_);
|
||||
internal TreeNode<AssetNode> _assetRootNode = null ~ DeleteTreeAndChildren!(_);
|
||||
internal TreeNode<AssetNode> _resourcesDirectoryNode = null;
|
||||
internal TreeNode<AssetNode> _assetsDirectoryNode = null;
|
||||
private append Dictionary<StringView, TreeNode<AssetNode>> _pathToAssetNode = .();
|
||||
private append Dictionary<StringView, TreeNode<AssetNode>> _identifierToAssetNode = .();
|
||||
|
||||
private append String _contentDirectory = .();
|
||||
private append String _resourcesDirectory = .();
|
||||
private append String _assetsDirectory = .();
|
||||
|
||||
private EditorContentManager _contentManager;
|
||||
|
||||
public StringView ContentDirectory
|
||||
public TreeNode<AssetNode> RootNode => _assetRootNode;
|
||||
|
||||
public StringView ResourcesDirectory
|
||||
{
|
||||
get => _contentDirectory;
|
||||
get => _resourcesDirectory;
|
||||
private set
|
||||
{
|
||||
_contentDirectory.Clear();
|
||||
_contentDirectory.Append(value);
|
||||
Path.Fixup(_contentDirectory);
|
||||
_resourcesDirectory.Set(value);
|
||||
Path.Fixup(_resourcesDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
public StringView AssetsDirectory
|
||||
{
|
||||
get => _assetsDirectory;
|
||||
private set
|
||||
{
|
||||
_assetsDirectory.Set(value);
|
||||
Path.Fixup(_assetsDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
public this(EditorContentManager contentManager)
|
||||
{
|
||||
_contentManager = contentManager;
|
||||
|
||||
// Create a root node that will contain all Asset directory nodes.
|
||||
_assetRootNode = new TreeNode<AssetNode>(new AssetNode());
|
||||
_assetRootNode->Path = new String();
|
||||
_assetRootNode->Name = new String();
|
||||
_assetRootNode->IsDirectory = true;
|
||||
|
||||
Log.EngineLogger.Trace($"Created root node");
|
||||
}
|
||||
|
||||
public void SetContentDirectory(StringView contentDirectory)
|
||||
public void SetResourcesDirectory(StringView fileName)
|
||||
{
|
||||
ContentDirectory = contentDirectory;
|
||||
ResourcesDirectory = fileName;
|
||||
|
||||
_resourcesDirectoryNode?.ForEach(scope (node) => {
|
||||
_pathToAssetNode.Remove(node->Path);
|
||||
_identifierToAssetNode.Remove(node->Identifier);
|
||||
});
|
||||
_assetRootNode.RemoveChild(_resourcesDirectoryNode);
|
||||
DeleteTreeAndChildren!(_resourcesDirectoryNode);
|
||||
_resourcesDirectoryNode = null;
|
||||
|
||||
if (!Directory.Exists(ResourcesDirectory))
|
||||
{
|
||||
Log.EngineLogger.Error($"Resources directory \"{ResourcesDirectory}\" doesn't exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
AssetNode assetNode = new AssetNode();
|
||||
assetNode.Path = new String(ResourcesDirectory);
|
||||
assetNode.Name = new String();
|
||||
assetNode.Identifier = new String("###resources");
|
||||
assetNode.IsDirectory = true;
|
||||
Path.GetFileName(assetNode.Path, assetNode.Name);
|
||||
|
||||
_resourcesDirectoryNode = _assetRootNode.AddChild(assetNode);
|
||||
_pathToAssetNode.Add(assetNode.Path, _resourcesDirectoryNode);
|
||||
_identifierToAssetNode.Add(assetNode.Identifier, _resourcesDirectoryNode);
|
||||
|
||||
Log.EngineLogger.Trace($"Created directory node for: \"{ResourcesDirectory}\"");
|
||||
|
||||
_fileSystemDirty = true;
|
||||
|
||||
// TODO: Watch resources folder?
|
||||
//SetupResourcesFileSystemWatcher();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public void SetAssetsDirectory(StringView fileName)
|
||||
{
|
||||
AssetsDirectory = fileName;
|
||||
|
||||
_assetsDirectoryNode?.ForEach(scope (node) => {
|
||||
_pathToAssetNode.Remove(node->Path);
|
||||
_identifierToAssetNode.Remove(node->Identifier);
|
||||
});
|
||||
_assetRootNode.RemoveChild(_assetsDirectoryNode);
|
||||
DeleteTreeAndChildren!(_assetsDirectoryNode);
|
||||
_assetsDirectoryNode = null;
|
||||
|
||||
if (!Directory.Exists(AssetsDirectory))
|
||||
{
|
||||
// TODO: This is not an error, if no project is loaded
|
||||
Log.EngineLogger.Warning($"Assets directory \"{AssetsDirectory}\" doesn't exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
AssetNode assetNode = new AssetNode();
|
||||
assetNode.Path = new String(AssetsDirectory);
|
||||
assetNode.Name = new String();
|
||||
assetNode.Identifier = new String("###assets");
|
||||
assetNode.IsDirectory = true;
|
||||
Path.GetFileName(assetNode.Path, assetNode.Name);
|
||||
|
||||
_assetsDirectoryNode = _assetRootNode.AddChild(assetNode);
|
||||
_pathToAssetNode.Add(assetNode.Path, _assetsDirectoryNode);
|
||||
_identifierToAssetNode.Add(assetNode.Identifier, _assetsDirectoryNode);
|
||||
|
||||
Log.EngineLogger.Trace($"Created directory node for: \"{AssetsDirectory}\"");
|
||||
|
||||
|
||||
_fileSystemDirty = true;
|
||||
|
||||
@@ -99,7 +221,7 @@ class AssetHierarchy
|
||||
private void SetupFileSystemWatcher()
|
||||
{
|
||||
delete fsw;
|
||||
fsw = new FileSystemWatcher(_contentDirectory);
|
||||
fsw = new FileSystemWatcher(_assetsDirectory);
|
||||
fsw.IncludeSubdirectories = true;
|
||||
|
||||
fsw.OnChanged.Add(new (filename) => {
|
||||
@@ -126,15 +248,7 @@ class AssetHierarchy
|
||||
fsw.OnRenamed.Add(new (oldName, newName) => {
|
||||
Log.EngineLogger.Trace($"File renamed (From \"{oldName}\" to \"{newName}\")");
|
||||
|
||||
//_fileSystemDirty = true;
|
||||
FileRenamed(oldName, newName);
|
||||
/*String contentFilePath = scope String();
|
||||
|
||||
Path.InternalCombine(contentFilePath, ContentDirectory, oldName);
|
||||
|
||||
//_fileSystemDirty = true;
|
||||
TreeNode<AssetNode> fileNode = GetNodeFromPath(contentFilePath);
|
||||
fileNode->*/
|
||||
});
|
||||
|
||||
fsw.StartRaisingEvents();
|
||||
@@ -153,6 +267,19 @@ class AssetHierarchy
|
||||
return .Err;
|
||||
}
|
||||
|
||||
/// Gets the tree node for the given filePath or .Err, if the file/directory doesn't exist.
|
||||
/// @param filePath the path for which to return the tree node.
|
||||
/// @remarks Do not hold a reference to the TreeNode because it can become invalid when the file hierarchy changes.
|
||||
public Result<TreeNode<AssetNode>> GetNodeFromIdentifier(StringView identifier)
|
||||
{
|
||||
if (_identifierToAssetNode.TryGetValue(identifier, let treeNode))
|
||||
{
|
||||
return treeNode;
|
||||
}
|
||||
|
||||
return .Err;
|
||||
}
|
||||
|
||||
public bool FileExists(StringView filePath)
|
||||
{
|
||||
return _pathToAssetNode.ContainsKey(filePath);
|
||||
@@ -167,33 +294,36 @@ class AssetHierarchy
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines and set the Identfier for the given asset node.
|
||||
private void DetermineIdentifier(TreeNode<AssetNode> assetNode)
|
||||
{
|
||||
if (assetNode->Identifier == null)
|
||||
assetNode->Identifier = new String();
|
||||
|
||||
assetNode->Identifier.Clear();
|
||||
|
||||
// Get the Identifier which is simply the path relative to the asste root (either Resources- or Assets-Folder)
|
||||
if (assetNode.IsInSubtree(_resourcesDirectoryNode))
|
||||
{
|
||||
Path.GetRelativePath(assetNode->Path, _resourcesDirectoryNode->Path, assetNode->Identifier);
|
||||
assetNode->Identifier.Insert(0, "Resources/");
|
||||
}
|
||||
else if (assetNode.IsInSubtree(_assetsDirectoryNode))
|
||||
{
|
||||
Path.GetRelativePath(assetNode->Path, _assetsDirectoryNode->Path, assetNode->Identifier);
|
||||
assetNode->Identifier.Insert(0, "Assets/");
|
||||
}
|
||||
AssetIdentifier.Fixup(assetNode->Identifier);
|
||||
}
|
||||
|
||||
/// Rebuilds the asset file hierarchy.
|
||||
private void UpdateFiles()
|
||||
{
|
||||
Log.EngineLogger.Trace($"Updating asset hierarchy");
|
||||
|
||||
if (_assetHierarchy == null)
|
||||
{
|
||||
// TODO: move to init?
|
||||
|
||||
_assetHierarchy = new TreeNode<AssetNode>(new AssetNode());
|
||||
_assetHierarchy->Path = new String(ContentDirectory);
|
||||
_assetHierarchy->Name = new String("Content");
|
||||
_assetHierarchy->IsDirectory = true;
|
||||
|
||||
Log.EngineLogger.Trace($"Created directory node for: \"{_assetHierarchy->Path}\"");
|
||||
|
||||
_pathToAssetNode.Add(ContentDirectory, _assetHierarchy);
|
||||
}
|
||||
|
||||
void HandleFile(AssetNode node)
|
||||
{
|
||||
String identifier = scope .(node.Path.Length);
|
||||
Path.GetRelativePath(node.Path, _contentDirectory, identifier);
|
||||
AssetIdentifier.Fixup(identifier);
|
||||
|
||||
node.AssetFile = new AssetFile(_contentManager, identifier, node.Path, node.IsDirectory);
|
||||
node.AssetFile = new AssetFile(_contentManager, node.Identifier, node.Path, node.IsDirectory);
|
||||
}
|
||||
|
||||
/// Determines the files that belong to the given directory and adds them to the tree.
|
||||
@@ -212,6 +342,7 @@ class AssetHierarchy
|
||||
entry.GetFilePath(filepathBuffer..Clear());
|
||||
|
||||
Path.GetExtension(filepathBuffer, .. extensionBuffer..Clear());
|
||||
filepathBuffer.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||
|
||||
// Ignore meta files.
|
||||
if (extensionBuffer.Equals(AssetFile.ConfigFileExtension, .OrdinalIgnoreCase))
|
||||
@@ -225,13 +356,15 @@ class AssetHierarchy
|
||||
assetNode.Name = new String();
|
||||
Path.GetFileName(filepathBuffer, assetNode.Name);
|
||||
|
||||
filepathBuffer.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||
|
||||
assetNode.Path = new String(filepathBuffer);
|
||||
assetNode.IsDirectory = false;
|
||||
|
||||
treeNode = directory.AddChild(assetNode);
|
||||
|
||||
DetermineIdentifier(treeNode);
|
||||
|
||||
_pathToAssetNode.Add(assetNode.Path, treeNode);
|
||||
_identifierToAssetNode.Add(assetNode.Identifier, treeNode);
|
||||
|
||||
//GrabSubAssets(node);
|
||||
HandleFile(treeNode.Value);
|
||||
@@ -243,17 +376,6 @@ class AssetHierarchy
|
||||
|
||||
void RemoveOrphanedEntries(TreeNode<AssetNode> node)
|
||||
{
|
||||
/// Removes the node and its children from _pathToAssetNode
|
||||
void RemoveSubtree(TreeNode<AssetNode> tree)
|
||||
{
|
||||
_pathToAssetNode.Remove(tree->Path);
|
||||
|
||||
for (var child in tree.Children)
|
||||
{
|
||||
RemoveSubtree(child);
|
||||
}
|
||||
}
|
||||
|
||||
for (TreeNode<AssetNode> child in node.Children)
|
||||
{
|
||||
if (!Directory.Exists(child->Path) && !File.Exists(child->Path))
|
||||
@@ -262,7 +384,10 @@ class AssetHierarchy
|
||||
|
||||
@child.Remove();
|
||||
|
||||
RemoveSubtree(child);
|
||||
child.ForEach(scope (node) => {
|
||||
_pathToAssetNode.Remove(node->Path);
|
||||
_identifierToAssetNode.Remove(node->Identifier);
|
||||
});
|
||||
|
||||
DeleteTreeAndChildren!(child);
|
||||
}
|
||||
@@ -284,11 +409,30 @@ class AssetHierarchy
|
||||
AssetNode assetNode = new AssetNode();
|
||||
assetNode.Path = new String(path);
|
||||
assetNode.Name = new String();
|
||||
//assetNode.Identifier = new String();
|
||||
assetNode.IsDirectory = true;
|
||||
Path.GetFileName(assetNode.Path, assetNode.Name);
|
||||
|
||||
/*// Get the Identifier which is simply the path relative to the asste root (either Resources- or Assets-Folder)
|
||||
if (parentNode == _resourcesDirectoryNode || parentNode.IsChildOf(_resourcesDirectoryNode))
|
||||
{
|
||||
Path.GetRelativePath(assetNode.Path, _resourcesDirectoryNode->Path, assetNode.Identifier);
|
||||
assetNode.Identifier.Insert(0, "Resources/");
|
||||
}
|
||||
else
|
||||
{
|
||||
Path.GetRelativePath(assetNode.Path, _assetsDirectoryNode->Path, assetNode.Identifier);
|
||||
assetNode.Identifier.Insert(0, "Assets/");
|
||||
}
|
||||
AssetIdentifier.Fixup(assetNode.Identifier);*/
|
||||
|
||||
treeNode = parentNode.AddChild(assetNode);
|
||||
|
||||
DetermineIdentifier(treeNode);
|
||||
|
||||
_pathToAssetNode.Add(assetNode.Path, treeNode);
|
||||
// No Identifiers for Directories, because we can't use directories as Assets anyways...
|
||||
//_identifierToAssetNode.Add(assetNode.Identifier, treeNode);
|
||||
|
||||
Log.EngineLogger.Trace($"Created directory node for: \"{assetNode.Path}\"");
|
||||
}
|
||||
@@ -305,13 +449,46 @@ class AssetHierarchy
|
||||
AddDirectoryToTree(directoryNameBuffer, treeNode);
|
||||
}
|
||||
|
||||
AddFilesOfDirectory(treeNode);
|
||||
|
||||
RemoveOrphanedEntries(treeNode);
|
||||
AddFilesOfDirectory(treeNode);
|
||||
}
|
||||
|
||||
String filter = scope $"{ContentDirectory}/*";
|
||||
if (!AssetsDirectory.IsWhiteSpace)
|
||||
{
|
||||
String filter = scope $"{AssetsDirectory}/*";
|
||||
|
||||
String directoryNameBuffer = scope String(256);
|
||||
|
||||
for (var directory in Directory.Enumerate(filter, .Directories))
|
||||
{
|
||||
directory.GetFilePath(directoryNameBuffer..Clear());
|
||||
|
||||
AddDirectoryToTree(directoryNameBuffer, _assetsDirectoryNode);
|
||||
}
|
||||
|
||||
RemoveOrphanedEntries(_assetsDirectoryNode);
|
||||
AddFilesOfDirectory(_assetsDirectoryNode);
|
||||
}
|
||||
|
||||
if (!ResourcesDirectory.IsWhiteSpace)
|
||||
{
|
||||
String filter = scope $"{ResourcesDirectory}/*";
|
||||
|
||||
String directoryNameBuffer = scope String(256);
|
||||
|
||||
for (var directory in Directory.Enumerate(filter, .Directories))
|
||||
{
|
||||
directory.GetFilePath(directoryNameBuffer..Clear());
|
||||
|
||||
AddDirectoryToTree(directoryNameBuffer, _resourcesDirectoryNode);
|
||||
}
|
||||
|
||||
RemoveOrphanedEntries(_resourcesDirectoryNode);
|
||||
AddFilesOfDirectory(_resourcesDirectoryNode);
|
||||
}
|
||||
|
||||
//*String filter = scope $"{AssetsDirectory}/*";
|
||||
/*
|
||||
String directoryNameBuffer = scope String(256);
|
||||
|
||||
for (var directory in Directory.Enumerate(filter, .Directories))
|
||||
@@ -321,7 +498,7 @@ class AssetHierarchy
|
||||
AddDirectoryToTree(directoryNameBuffer, _assetHierarchy);
|
||||
}
|
||||
|
||||
RemoveOrphanedEntries(_assetHierarchy);
|
||||
RemoveOrphanedEntries(_assetHierarchy);*/
|
||||
|
||||
_fileSystemDirty = false;
|
||||
}
|
||||
@@ -336,7 +513,7 @@ class AssetHierarchy
|
||||
fileName.RemoveFromEnd(AssetFile.ConfigFileExtension.Length);
|
||||
|
||||
String fileNameWithContentRoot = scope .();
|
||||
Path.InternalCombine(fileNameWithContentRoot, _contentDirectory, fileName);
|
||||
Path.InternalCombine(fileNameWithContentRoot, _assetsDirectory, fileName);
|
||||
|
||||
var nodeResult = GetNodeFromPath(fileNameWithContentRoot);
|
||||
|
||||
@@ -366,10 +543,10 @@ class AssetHierarchy
|
||||
|
||||
|
||||
String oldFileNameWithContentRoot = scope .();
|
||||
Path.InternalCombine(oldFileNameWithContentRoot, _contentDirectory, oldFilePath);
|
||||
Path.InternalCombine(oldFileNameWithContentRoot, _assetsDirectory, oldFilePath);
|
||||
|
||||
String newFileNameWithContentRoot = scope .();
|
||||
Path.InternalCombine(newFileNameWithContentRoot, _contentDirectory, newFilePath);
|
||||
Path.InternalCombine(newFileNameWithContentRoot, _assetsDirectory, newFilePath);
|
||||
|
||||
// Rename config file
|
||||
{
|
||||
@@ -397,10 +574,14 @@ class AssetHierarchy
|
||||
}
|
||||
|
||||
_pathToAssetNode.Remove(oldFileNameWithContentRoot);
|
||||
_identifierToAssetNode.Remove(node->Identifier);
|
||||
|
||||
node->Path.Set(newFileNameWithContentRoot);
|
||||
_pathToAssetNode.Add(node->Path, node);
|
||||
|
||||
DetermineIdentifier(node);
|
||||
_identifierToAssetNode.Add(node->Identifier, node);
|
||||
|
||||
node->Name.Clear();
|
||||
Path.GetFileName(newFileNameWithContentRoot, node->Name);
|
||||
|
||||
|
||||
@@ -0,0 +1,748 @@
|
||||
using System.IO;
|
||||
using System;
|
||||
using GlitchyEngine;
|
||||
using System.Collections;
|
||||
|
||||
namespace GlitchyEditor.Assets.Importers;
|
||||
|
||||
// Based on https://github.com/Diron-P/DDSReader/blob/main/dds_loader.h
|
||||
|
||||
public struct LoadedSurface
|
||||
{
|
||||
public Span<uint8> Data;
|
||||
public uint32 Pitch;
|
||||
public uint32 SlicePitch;
|
||||
|
||||
public int ArrayIndex;
|
||||
public int CubeFace;
|
||||
public int MipLevel;
|
||||
}
|
||||
|
||||
public struct LoadedTextureInfo
|
||||
{
|
||||
public enum Dimension
|
||||
{
|
||||
Unknown,
|
||||
Texture1D,
|
||||
Texture2D,
|
||||
Texture3D
|
||||
}
|
||||
|
||||
public uint8[] PixelData = null;
|
||||
public DirectX.DXGI.Format PixelFormat = .Unknown;
|
||||
public int MipMapCount = 0;
|
||||
public int ArraySize = 0;
|
||||
public Dimension Dimension = .Unknown;
|
||||
public bool IsCubeMap;
|
||||
|
||||
public int Width;
|
||||
public int Height;
|
||||
public int Depth;
|
||||
}
|
||||
|
||||
static class DdsImporter
|
||||
{
|
||||
private const uint32 MagicWord = 0x20534444; // 'DDS
|
||||
|
||||
public enum LoadError
|
||||
{
|
||||
Unknown,
|
||||
WrongMagicWord,
|
||||
StreamReadFailed,
|
||||
InvalidArraySize,
|
||||
WrongDimensions,
|
||||
IncompleteCubemap
|
||||
}
|
||||
|
||||
private enum HeaderFlags : uint32
|
||||
{
|
||||
/// Required in every .dds file.
|
||||
DDSD_CAPS = 0x1,
|
||||
/// Required in every .dds file.
|
||||
DDSD_HEIGHT = 0x2,
|
||||
/// Required in every .dds file.
|
||||
DDSD_WIDTH = 0x4,
|
||||
/// Required in every .dds file.
|
||||
DDSD_PITCH = 0x8,
|
||||
/// Required in every .dds file.
|
||||
DDSD_PIXELFORMAT = 0x1000,
|
||||
/// Required in a mipmapped texture.
|
||||
DDSD_MIPMAPCOUNT = 0x20000,
|
||||
/// Required when pitch is provided for a compressed texture.
|
||||
DDSD_LINEARSIZE = 0x80000,
|
||||
/// Required in a depth texture.
|
||||
DDSD_DEPTH = 0x800000
|
||||
}
|
||||
|
||||
private enum Caps1 : uint32
|
||||
{
|
||||
/// Should be set, when the file contains multiple surfaces (e.g. Cubemaps or Mipmaps).
|
||||
Complex = 0x8,
|
||||
/// Should be set, if the file contains mipmaps.
|
||||
MipMap = 0x400000,
|
||||
/// Should always be set.
|
||||
Texture = 0x1000
|
||||
}
|
||||
|
||||
[AllowDuplicates]
|
||||
private enum Caps2 : uint32
|
||||
{
|
||||
Cubemap = 0x200,
|
||||
Cubemap_PositiveX = 0x400,
|
||||
Cubemap_NegativeX = 0x800,
|
||||
Cubemap_X = Cubemap_PositiveX | Cubemap_NegativeX,
|
||||
Cubemap_PositiveY = 0x1000,
|
||||
Cubemap_NegativeY = 0x2000,
|
||||
Cubemap_Y = Cubemap_PositiveY | Cubemap_NegativeY,
|
||||
Cubemap_PositiveZ = 0x4000,
|
||||
Cubemap_NegativeZ = 0x8000,
|
||||
Cubemap_Z = Cubemap_PositiveZ | Cubemap_NegativeZ,
|
||||
/// This is the flag that should be set for Cubemaps in DX10+
|
||||
Cubemap_AllFaces = Cubemap | Cubemap_X | Cubemap_Y | Cubemap_Z,
|
||||
|
||||
Volume = 0x200000,
|
||||
}
|
||||
|
||||
[CRepr]
|
||||
private struct DdsHeader
|
||||
{
|
||||
/// Size of this structure. This member must be set to 124.
|
||||
private uint32 Size;
|
||||
/// Flags to indicate which members contain valid data.
|
||||
public HeaderFlags Flags;
|
||||
/// Surface height (in pixels).
|
||||
public uint32 Height;
|
||||
/// Surface width (in pixels).
|
||||
public uint32 Width;
|
||||
public uint32 PitchOrLinearSize;
|
||||
/// Depth of a volume texture (in pixels), otherwise unused.
|
||||
public uint32 Depth;
|
||||
/// Number of mipmap levels, otherwise unused.
|
||||
public uint32 MipMapCount;
|
||||
/// Unused.
|
||||
private uint32[11] Reserved1;
|
||||
/// The pixel format.
|
||||
public DdsPixelFormat PixelFormat;
|
||||
public Caps1 Caps;
|
||||
public Caps2 Caps2;
|
||||
/// Unused.
|
||||
private uint32 dwCaps3;
|
||||
/// Unused.
|
||||
private uint32 dwCaps4;
|
||||
/// Unused.
|
||||
private uint32 dwReserved2;
|
||||
}
|
||||
|
||||
private enum SurfaceType : uint32
|
||||
{
|
||||
/// Texture contains alpha data; dwRGBAlphaBitMask contains valid data.
|
||||
AlphaPixels = 0x1,
|
||||
/// Used in some older DDS files for alpha channel only uncompressed data (dwRGBBitCount contains the alpha channel bitcount; dwABitMask contains valid data)
|
||||
Alpha = 0x2,
|
||||
|
||||
/// Texture contains compressed RGB data; dwFourCC contains valid data.
|
||||
FourCC = 0x4,
|
||||
/// Texture contains uncompressed RGB data; dwRGBBitCount and the RGB masks (dwRBitMask, dwGBitMask, dwBBitMask) contain valid data.
|
||||
RGB = 0x40,
|
||||
|
||||
RGBA = RGB | AlphaPixels,
|
||||
|
||||
/// Used in some older DDS files for YUV uncompressed data (dwRGBBitCount contains the YUV bit count;
|
||||
/// dwRBitMask contains the Y mask, dwGBitMask contains the U mask, dwBBitMask contains the V mask)
|
||||
YUV = 0x200,
|
||||
|
||||
/// Used in some older DDS files for single channel color uncompressed data (dwRGBBitCount contains the luminance channel bit count;
|
||||
/// dwRBitMask contains the channel mask). Can be combined with DDPF_ALPHAPIXELS for a two channel DDS file.
|
||||
Luminance = 0x20000
|
||||
}
|
||||
|
||||
private static uint32 MakeFourCC(char8 c0, char8 c1, char8 c2, char8 c3)
|
||||
{
|
||||
return ((uint32)c3 << 24 | (uint32) c2 << 16 | (uint32) c1 << 8 | (uint32) c0);
|
||||
}
|
||||
|
||||
/*private enum FourCC : uint32
|
||||
{
|
||||
DXT1 = MakeFourCC('D', 'X', 'T', '1'),
|
||||
DXT2 = MakeFourCC('D', 'X', 'T', '2'),
|
||||
DXT3 = MakeFourCC('D', 'X', 'T', '3'),
|
||||
DXT4 = MakeFourCC('D', 'X', 'T', '4'),
|
||||
DXT5 = MakeFourCC('D', 'X', 'T', '5'),
|
||||
/// indicates the prescense of the DDS_HEADER_DXT10 extended header
|
||||
DX10 = MakeFourCC('D', 'X', '1', '0'),
|
||||
}*/
|
||||
|
||||
[CRepr]
|
||||
private struct DdsPixelFormat
|
||||
{
|
||||
/// Structure size; set to 32 (bytes).
|
||||
private uint32 Size;
|
||||
/// Values which indicate what type of data is in the surface.
|
||||
public SurfaceType SurfaceType;
|
||||
public uint32 FourCC;
|
||||
/// Number of bits in an RGB (possibly including alpha) format. Valid when dwFlags includes DDPF_RGB, DDPF_LUMINANCE, or DDPF_YUV.
|
||||
public uint32 RGBBitCount;
|
||||
/// Red (or luminance or Y) mask for reading color data. For instance, given the A8R8G8B8 format, the red mask would be 0x00ff0000.
|
||||
public uint32 RBitMask;
|
||||
/// Green (or U) mask for reading color data. For instance, given the A8R8G8B8 format, the green mask would be 0x0000ff00.
|
||||
public uint32 GBitMask;
|
||||
/// Blue (or V) mask for reading color data. For instance, given the A8R8G8B8 format, the blue mask would be 0x000000ff.
|
||||
public uint32 BBitMask;
|
||||
/// Alpha mask for reading alpha data. dwFlags must include DDPF_ALPHAPIXELS or DDPF_ALPHA. For instance, given the A8R8G8B8 format, the alpha mask would be 0xff000000.
|
||||
public uint32 ABitMask;
|
||||
}
|
||||
|
||||
public enum ResourceDimensions : uint32
|
||||
{
|
||||
Texture1D = 2,
|
||||
Texture2D = 3,
|
||||
Texture3D = 4
|
||||
}
|
||||
|
||||
public enum MiscFlags : uint32
|
||||
{
|
||||
TextureCube = 0x4,
|
||||
}
|
||||
|
||||
public enum AlphaMode : uint32
|
||||
{
|
||||
Unknown = 0x0,
|
||||
Straight = 0x1,
|
||||
Premultiplied = 0x2,
|
||||
Opaque = 0x3,
|
||||
/// Any alpha channel content is being used as a 4th channel and is not intended to represent transparency (straight or premultiplied).
|
||||
Custom = 0x4
|
||||
}
|
||||
|
||||
/// DDS header extension to handle resource arrays, DXGI pixel formats that don't map to the legacy Microsoft DirectDraw pixel format structures, and additional metadata.
|
||||
[CRepr]
|
||||
private struct DdsDxt10Header
|
||||
{
|
||||
public DirectX.DXGI.Format PixelFormat;
|
||||
public ResourceDimensions ResourceDimension;
|
||||
public MiscFlags MiscFlags;
|
||||
/// Number of elements in the array. For a 2D cubemap this is the number of cubes, so the file contains ArraySize * 6 2D textures.
|
||||
/// For a 3D Texture this must be 1.
|
||||
public uint32 ArraySize;
|
||||
|
||||
public AlphaMode AlphaMode;
|
||||
}
|
||||
|
||||
private static Result<void, LoadError> DecodeHeader(Stream data, out DdsHeader header, out DdsDxt10Header? extendedHeader)
|
||||
{
|
||||
header = ?;
|
||||
extendedHeader = null;
|
||||
|
||||
// Check the magic word
|
||||
Result<uint32> magicWord = data.Read<uint32>();
|
||||
|
||||
if (magicWord case .Err)
|
||||
return .Err(.StreamReadFailed);
|
||||
|
||||
if (magicWord != MagicWord)
|
||||
return .Err(.WrongMagicWord);
|
||||
|
||||
// Load the header
|
||||
Result<DdsHeader> headerResult = data.Read<DdsHeader>();
|
||||
|
||||
if (headerResult case .Err)
|
||||
return .Err(.StreamReadFailed);
|
||||
|
||||
header = headerResult;
|
||||
|
||||
// If available, load the extended header
|
||||
if (header.PixelFormat.SurfaceType.HasFlag(.FourCC) && header.PixelFormat.FourCC == MakeFourCC('D', 'X', '1', '0'))
|
||||
{
|
||||
Result<DdsDxt10Header> extendedHeaderResult = data.Read<DdsDxt10Header>();
|
||||
|
||||
if (headerResult case .Err)
|
||||
return .Err(.StreamReadFailed);
|
||||
|
||||
extendedHeader = extendedHeaderResult;
|
||||
}
|
||||
|
||||
return .Ok;
|
||||
}
|
||||
|
||||
private static bool IsBitMask(DdsPixelFormat ddspf, uint32 rBitMask, uint32 gBitMask, uint32 bBitMask, uint32 aBitMask)
|
||||
{
|
||||
return ddspf.RBitMask == rBitMask && ddspf.GBitMask == gBitMask && ddspf.BBitMask == bBitMask && ddspf.ABitMask == aBitMask;
|
||||
}
|
||||
|
||||
private static DirectX.DXGI.Format GetFormat(in DdsHeader header, in DdsDxt10Header? extendedheader, bool isSrgb)
|
||||
{
|
||||
if (extendedheader != null)
|
||||
return extendedheader.Value.PixelFormat;
|
||||
|
||||
DdsPixelFormat pixelFormat = header.PixelFormat;
|
||||
|
||||
// Currently supports only basic dxgi formats.
|
||||
//if (pixelFormat.SurfaceType.HasFlag(.RGBA))
|
||||
if (pixelFormat.SurfaceType.HasFlag(.RGB))
|
||||
{
|
||||
switch (pixelFormat.RGBBitCount)
|
||||
{
|
||||
case 32:
|
||||
if (IsBitMask(pixelFormat, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000))
|
||||
return isSrgb ? .R8G8B8A8_UNorm_SRGB : .R8G8B8A8_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000))
|
||||
return isSrgb ? .B8G8R8A8_UNorm_SRGB : .B8G8R8A8_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0x00FF0000, 0x0000FF00, 0x000000FF, 0))
|
||||
return isSrgb ? .B8G8R8X8_UNorm_SRGB : .B8G8R8X8_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0x000003FF, 0x000FFc00, 0x3FF00000, 0))
|
||||
return .R10G10B10A2_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0x3FF00000, 0x000FFc00, 0x000003FF, 0))
|
||||
return .R10G10B10A2_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0x0000FFFF, 0xFFFF0000, 0, 0))
|
||||
return .R16G16_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0xFFFFFFFF, 0, 0, 0))
|
||||
return .R32_Float;
|
||||
|
||||
case 24:
|
||||
// NO 24 bit formats
|
||||
return .Unknown;
|
||||
|
||||
case 16:
|
||||
if (IsBitMask(pixelFormat, 0x7C00, 0x03E0, 0x001F, 0x8000))
|
||||
return .B5G5R5A1_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0xF800, 0x07E0, 0x001F, 0))
|
||||
return .B5G6R5_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0x0F00, 0x00F0, 0x000F, 0xF000))
|
||||
return .B4G4R4A4_UNORM;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0x00FF, 0, 0, 0xFF00))
|
||||
return .R8G8_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0xFFFF, 0, 0, 0))
|
||||
return .R16_UNorm;
|
||||
|
||||
case 8:
|
||||
if (IsBitMask(pixelFormat, 0xFF, 0, 0, 0))
|
||||
return .R8_UNorm;
|
||||
|
||||
default:
|
||||
return .Unknown;
|
||||
}
|
||||
}
|
||||
else if (pixelFormat.SurfaceType.HasFlag(.Luminance))
|
||||
{
|
||||
switch (pixelFormat.RGBBitCount)
|
||||
{
|
||||
case 16:
|
||||
if (IsBitMask(pixelFormat, 0xFFFF, 0, 0, 0))
|
||||
return .R16_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0x00FF, 0, 0, 0xFF00))
|
||||
return .R8G8_UNorm;
|
||||
|
||||
case 8:
|
||||
if (IsBitMask(pixelFormat, 0xFF, 0, 0, 0))
|
||||
return .R8_UNorm;
|
||||
|
||||
if (IsBitMask(pixelFormat, 0x00FF, 0, 0, 0xFF00))
|
||||
return .R8G8_UNorm; // Some DDS writers assume the bitcount should be 8 instead of 16
|
||||
|
||||
default:
|
||||
return .Unknown;
|
||||
}
|
||||
}
|
||||
else if (pixelFormat.SurfaceType.HasFlag(.Luminance))
|
||||
{
|
||||
if (pixelFormat.RGBBitCount == 8)
|
||||
{
|
||||
return .A8_UNorm;
|
||||
}
|
||||
}
|
||||
else if (pixelFormat.SurfaceType.HasFlag(.FourCC))
|
||||
{
|
||||
switch (pixelFormat.FourCC)
|
||||
{
|
||||
case MakeFourCC('D', 'X', 'T', '1'):
|
||||
return isSrgb ? .BC1_UNorm_SRGB : .BC1_UNorm;
|
||||
case MakeFourCC('D', 'X', 'T', '3'):
|
||||
return isSrgb ? .BC2_UNorm_SRGB : .BC2_UNorm;
|
||||
case MakeFourCC('D', 'X', 'T', '5'):
|
||||
return isSrgb ? .BC3_UNorm_SRGB : .BC3_UNorm;
|
||||
|
||||
// Legacy compression formats.
|
||||
case MakeFourCC('D', 'X', 'T', '2'):
|
||||
return isSrgb ? .BC2_UNorm_SRGB : .BC2_UNorm;
|
||||
case MakeFourCC('D', 'X', 'T', '4'):
|
||||
return isSrgb ? .BC3_UNorm_SRGB : .BC3_UNorm;
|
||||
|
||||
case MakeFourCC('B', 'C', '4', 'U'), MakeFourCC('A', 'T', 'I', '1'):
|
||||
return .BC4_UNorm;
|
||||
case MakeFourCC('B', 'C', '4', 'S'):
|
||||
return .BC4_SNorm;
|
||||
case MakeFourCC('B', 'C', '5', 'U'), MakeFourCC('A', 'T', 'I', '2'):
|
||||
return .BC5_UNorm;
|
||||
case MakeFourCC('B', 'C', '5', 'S'):
|
||||
return .BC5_SNorm;
|
||||
|
||||
case MakeFourCC('R', 'G', 'B', 'G'):
|
||||
return .R8G8_B8G8_UNorm;
|
||||
case MakeFourCC('G', 'R', 'G', 'B'):
|
||||
return .G8R8_G8B8_UNorm;
|
||||
|
||||
case MakeFourCC('Y', 'U', 'Y', '2'):
|
||||
return .YUY2;
|
||||
|
||||
case 36:
|
||||
return .R16G16B16A16_UNorm;
|
||||
case 111:
|
||||
return .R16_Float;
|
||||
case 112:
|
||||
return .R16G16_Float;
|
||||
case 113:
|
||||
return .R16G16B16A16_Float;
|
||||
case 114:
|
||||
return .R32_Float;
|
||||
case 115:
|
||||
return .R32G32_Float;
|
||||
case 116:
|
||||
return .R32G32B32A32_Float;
|
||||
default:
|
||||
return .Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
return .Unknown;
|
||||
}
|
||||
|
||||
public static void GetPitch(uint32 width, uint32 height, DirectX.DXGI.Format format, out uint32 rowBytes, out uint32 numRows, out uint64 numBytes)
|
||||
{
|
||||
rowBytes = 0;
|
||||
numRows = 0;
|
||||
numBytes = 0;
|
||||
|
||||
bool bc = false;
|
||||
bool packed = false;
|
||||
bool planar = false;
|
||||
uint32 bpe = 0;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case .BC1_Typeless, .BC1_UNorm, .BC1_UNorm_SRGB,
|
||||
.BC4_Typeless, .BC4_UNorm, .BC4_SNorm:
|
||||
bc = true;
|
||||
bpe = 8;
|
||||
break;
|
||||
|
||||
case .BC2_Typeless, .BC2_UNorm, .BC2_UNorm_SRGB,
|
||||
.BC3_Typeless, .BC3_UNorm, .BC3_UNorm_SRGB,
|
||||
.BC5_Typeless, .BC5_UNorm, .BC5_SNorm,
|
||||
.BC6H_Typeless, .BC6H_UF16, .BC6H_SF16,
|
||||
.BC7_Typeless, .BC7_UNorm, .BC7_UNorm_SRGB:
|
||||
bc = true;
|
||||
bpe = 16;
|
||||
break;
|
||||
|
||||
case .R8G8_B8G8_UNorm, .G8R8_G8B8_UNorm, .YUY2:
|
||||
packed = true;
|
||||
bpe = 4;
|
||||
break;
|
||||
|
||||
case .Y210, .Y216:
|
||||
packed = true;
|
||||
bpe = 8;
|
||||
break;
|
||||
|
||||
case .NV12, .P208, .OPAQUE_420:
|
||||
planar = true;
|
||||
bpe = 2;
|
||||
break;
|
||||
|
||||
case .P010, .P016:
|
||||
planar = true;
|
||||
bpe = 4;
|
||||
break;
|
||||
|
||||
/*
|
||||
case .D16_UNORM_S8_UINT:
|
||||
case .R16_UNORM_X8_TYPELESS:
|
||||
case .X16_TYPELESS_G8_UINT:
|
||||
planar = true;
|
||||
bpe = 4;
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (bc)
|
||||
{
|
||||
uint32 numBlocksWide = 0;
|
||||
if (width > 0)
|
||||
{
|
||||
numBlocksWide = Math.Max(1, (width + 3u) / 4u);
|
||||
}
|
||||
uint32 numBlocksHigh = 0;
|
||||
if (height > 0)
|
||||
{
|
||||
numBlocksHigh = Math.Max(1, (height + 3u) / 4u);
|
||||
}
|
||||
rowBytes = numBlocksWide * bpe;
|
||||
numRows = numBlocksHigh;
|
||||
numBytes = rowBytes * numBlocksHigh;
|
||||
}
|
||||
else if (packed)
|
||||
{
|
||||
rowBytes = (((uint32)width + 1u) >> 1) * bpe;
|
||||
numRows = height;
|
||||
numBytes = rowBytes * height;
|
||||
}
|
||||
else if (format == .NV11)
|
||||
{
|
||||
rowBytes = ((width + 3u) >> 2) * 4u;
|
||||
numRows = height * 2u; // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data
|
||||
numBytes = rowBytes * numRows;
|
||||
}
|
||||
else if (planar)
|
||||
{
|
||||
rowBytes = ((width + 1u) >> 1) * bpe;
|
||||
numBytes = (rowBytes * height) + ((rowBytes * height + 1u) >> 1);
|
||||
numRows = height + ((height + 1u) >> 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 bpp = format.BitsPerPixel();// BitsPerPixel(format);
|
||||
if (bpp == 0)
|
||||
return;
|
||||
|
||||
rowBytes = (width * bpp + 7u) / 8u; // round up to nearest byte
|
||||
numRows = height;
|
||||
numBytes = rowBytes * height;
|
||||
}
|
||||
|
||||
//#if defined(_M_IX86) || defined(_M_ARM) || defined(_M_HYBRID_X86_ARM64)
|
||||
/*static_assert(sizeof(size_t) == 4, "Not a 32-bit platform!");
|
||||
if (numBytes > UINT32_MAX || rowBytes > UINT32_MAX || numRows > UINT32_MAX)
|
||||
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);*/
|
||||
/*#else
|
||||
static_assert(sizeof(size_t) == 8, "Not a 64-bit platform!");
|
||||
#endif*/
|
||||
|
||||
/*if (outNumBytes)
|
||||
{
|
||||
*outNumBytes = static_cast<size_t>(numBytes);
|
||||
}
|
||||
if (outRowBytes)
|
||||
{
|
||||
*outRowBytes = static_cast<size_t>(rowBytes);
|
||||
}
|
||||
if (outNumRows)
|
||||
{
|
||||
*outNumRows = static_cast<size_t>(numRows);
|
||||
}*/
|
||||
}
|
||||
|
||||
public static Result<void, LoadError> LoadDds(Stream data, bool isSrgb, List<LoadedSurface> surfaces, out LoadedTextureInfo textureInfo)
|
||||
{
|
||||
// TODO: Care about alpha mode
|
||||
|
||||
textureInfo = .();
|
||||
|
||||
var headerResult = DecodeHeader(data, let header, let extendedHeader);
|
||||
|
||||
if (headerResult case .Err)
|
||||
return headerResult;
|
||||
|
||||
int surfaceCount = 1;
|
||||
|
||||
if (header.Flags.HasFlag(.DDSD_MIPMAPCOUNT) || header.MipMapCount != 0)
|
||||
{
|
||||
if (header.MipMapCount == 0)
|
||||
Log.EngineLogger.Warning("Mipmap count is zero, even though the flags say it shouldn't.");
|
||||
|
||||
if (!header.Flags.HasFlag(.DDSD_MIPMAPCOUNT))
|
||||
Log.EngineLogger.Warning("Mipmap count is not zero, even though the mipmap count flag isn't set.");
|
||||
|
||||
textureInfo.MipMapCount = header.MipMapCount;
|
||||
surfaceCount *= textureInfo.MipMapCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
textureInfo.MipMapCount = 1;
|
||||
}
|
||||
|
||||
if (extendedHeader != null)
|
||||
{
|
||||
textureInfo.ArraySize = extendedHeader.Value.ArraySize;
|
||||
surfaceCount *= textureInfo.ArraySize;
|
||||
|
||||
if (textureInfo.ArraySize == 0)
|
||||
return .Err(.InvalidArraySize);
|
||||
}
|
||||
else
|
||||
{
|
||||
textureInfo.ArraySize = 1;
|
||||
}
|
||||
|
||||
if (header.Caps2.HasFlag(.Cubemap))
|
||||
{
|
||||
if (!header.Caps2.HasFlag(.Cubemap_AllFaces))
|
||||
Log.EngineLogger.Warning("Texture might only contains partial cubemap, this is not allowed. (Defined Cubemap-Flag, but not all cubemap faces)");
|
||||
|
||||
surfaceCount *= 6;
|
||||
textureInfo.IsCubeMap = true;
|
||||
}
|
||||
|
||||
textureInfo.PixelFormat = GetFormat(header, extendedHeader, isSrgb);
|
||||
|
||||
textureInfo.Width = header.Width;
|
||||
textureInfo.Height = header.Height;
|
||||
textureInfo.Depth = header.Depth;
|
||||
|
||||
switch (extendedHeader?.ResourceDimension)
|
||||
{
|
||||
case .Texture1D:
|
||||
textureInfo.Dimension = .Texture1D;
|
||||
|
||||
if (header.Flags.HasFlag(.DDSD_HEIGHT) && header.Height != 1)
|
||||
return .Err(.WrongDimensions);
|
||||
|
||||
textureInfo.Height = 1;
|
||||
textureInfo.Depth = 1;
|
||||
|
||||
case .Texture2D:
|
||||
textureInfo.Dimension = .Texture2D;
|
||||
|
||||
textureInfo.Depth = 1;
|
||||
|
||||
case .Texture3D:
|
||||
textureInfo.Dimension = .Texture3D;
|
||||
case null:
|
||||
if (header.Flags.HasFlag(.DDSD_DEPTH))
|
||||
textureInfo.Dimension = .Texture3D;
|
||||
else
|
||||
{
|
||||
textureInfo.Dimension = .Texture2D;
|
||||
textureInfo.Depth = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we have enough space in the list (avoid allocations later)
|
||||
surfaces.Reserve(surfaceCount);
|
||||
|
||||
uint32 scanLineSize = 0;
|
||||
uint32 slicePitch = 0;
|
||||
uint64 numBytes = 0;
|
||||
uint32 blockSize = 0; // Block size in bytes.
|
||||
|
||||
switch (textureInfo.PixelFormat)
|
||||
{
|
||||
case .BC1_UNorm, .BC1_UNorm_SRGB, .BC1_Typeless,
|
||||
.BC4_UNorm, .BC4_SNorm, .BC4_Typeless:
|
||||
blockSize = 8;
|
||||
case .BC2_UNorm, .BC2_UNorm_SRGB, .BC2_Typeless,
|
||||
.BC3_UNorm, .BC3_UNorm_SRGB, .BC3_Typeless,
|
||||
.BC5_UNorm, .BC5_SNorm, .BC5_Typeless,
|
||||
.BC7_UNorm, .BC7_UNorm_SRGB, .BC7_Typeless:
|
||||
blockSize = 16;
|
||||
default:
|
||||
}
|
||||
|
||||
uint32 width = 0;
|
||||
uint32 height = 0;
|
||||
uint32 depth = 0;
|
||||
|
||||
uint32 index = 0;
|
||||
|
||||
uint offset = 0;
|
||||
|
||||
for (uint32 arrayIndex = 0; arrayIndex < textureInfo.ArraySize; arrayIndex++)
|
||||
{
|
||||
for (uint32 cubeFace = 0; cubeFace < (textureInfo.IsCubeMap ? 6 : 1); cubeFace++)
|
||||
{
|
||||
width = header.Width;
|
||||
height = header.Height;
|
||||
depth = header.Depth;
|
||||
|
||||
for (uint32 mipLevel = 0; mipLevel < textureInfo.MipMapCount; ++mipLevel)
|
||||
{
|
||||
/*// This will recalculate te pitch of the main image as well.
|
||||
if (header.Flags.HasFlag(.DDSD_LINEARSIZE))
|
||||
{
|
||||
// compressed textures
|
||||
scanLineSize = Math.Max(1, ((width + 3u) / 4u)) * blockSize;
|
||||
uint32 numScanLines = Math.Max(1, ((height + 3u) / 4u));
|
||||
numBytes = scanLineSize * numScanLines;
|
||||
}
|
||||
else if (header.Flags.HasFlag(.DDSD_PITCH))
|
||||
{
|
||||
// uncompressed data
|
||||
scanLineSize = (width * header.PixelFormat.RGBBitCount + 7u) / 8u;
|
||||
numBytes = scanLineSize * height;
|
||||
}
|
||||
else
|
||||
{
|
||||
scanLineSize = header.PitchOrLinearSize;
|
||||
numBytes = scanLineSize * height;
|
||||
}*/
|
||||
|
||||
GetPitch(width, height, textureInfo.PixelFormat, out scanLineSize, let numRows, out numBytes);
|
||||
|
||||
|
||||
LoadedSurface surface = .();
|
||||
// We don't know how large data-array is, so we don't have one yet.
|
||||
// Only save the offset, we will adjust the pointer later.
|
||||
surface.Data = Span<uint8>((uint8*)(void*)offset, (int)numBytes);
|
||||
surface.Pitch = scanLineSize;
|
||||
//surface.SlicePitch = slicePitch;
|
||||
surface.SlicePitch = scanLineSize * numRows;
|
||||
|
||||
surface.ArrayIndex = arrayIndex;
|
||||
surface.CubeFace = cubeFace;
|
||||
surface.MipLevel = mipLevel;
|
||||
|
||||
surfaces.Add(surface);
|
||||
|
||||
++index;
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
depth >>= 1;
|
||||
|
||||
if (width == 0)
|
||||
{
|
||||
width = 1;
|
||||
}
|
||||
|
||||
if (height == 0)
|
||||
{
|
||||
height = 1;
|
||||
}
|
||||
|
||||
offset += numBytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
textureInfo.PixelData = new uint8[offset];
|
||||
|
||||
Result<int> pixelDataResult = data.TryRead(textureInfo.PixelData);
|
||||
|
||||
if (pixelDataResult case .Err)
|
||||
{
|
||||
delete textureInfo.PixelData;
|
||||
return .Err(.StreamReadFailed);
|
||||
}
|
||||
|
||||
for (ref LoadedSurface surface in ref surfaces)
|
||||
{
|
||||
// Data pointer so far only has the offset inside the array.
|
||||
// Move the pointer, so that it is inside the array.
|
||||
surface.Data.Ptr += (uint)(void*)textureInfo.PixelData.Ptr;
|
||||
}
|
||||
|
||||
return .Ok;
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
||||
|
||||
if (ImGui.BeginDragDropTarget())
|
||||
{
|
||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
||||
|
||||
if (payload != null)
|
||||
{
|
||||
@@ -78,7 +78,7 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
||||
|
||||
if (ImGui.BeginDragDropTarget())
|
||||
{
|
||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
||||
|
||||
if (payload != null)
|
||||
{
|
||||
@@ -99,7 +99,8 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
||||
{
|
||||
for (let (name, arguments) in effect.[Friend]_variableDescriptions)
|
||||
{
|
||||
let variable = effect.Variables[name];
|
||||
if (!effect.Variables.TryGetVariable(name, let variable))
|
||||
continue;
|
||||
|
||||
bool hasPreviewName = TryGetValue(arguments, "Preview", var previewName);
|
||||
|
||||
@@ -107,35 +108,69 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
||||
|
||||
bool hasPreviewType = TryGetValue(arguments, "Type", var previewType);
|
||||
|
||||
if (hasPreviewType && previewType.Get<String>() == "Color")
|
||||
if (hasPreviewType && (previewType.Get<String>() == "Color" || previewType.Get<String>() == "ColorHDR"))
|
||||
{
|
||||
Log.EngineLogger.AssertDebug(variable.Type == .Float && variable.Rows == 1);
|
||||
|
||||
if (variable.Columns == 3)
|
||||
if (previewType.Get<String>().Equals("Color", .InvariantCultureIgnoreCase))
|
||||
{
|
||||
material.GetVariable<Vector3>(variable.Name, var value);
|
||||
Log.EngineLogger.AssertDebug(variable.Type == .Float && variable.Rows == 1);
|
||||
|
||||
value = (Vector3)ColorRGB.LinearToSRGB((ColorRGB)value);
|
||||
|
||||
if (ImGui.ColorEdit3(displayName.Ptr, *(float[3]*)&value))
|
||||
if (variable.Columns == 3)
|
||||
{
|
||||
value = (Vector3)ColorRGB.SRgbToLinear((ColorRGB)value);
|
||||
material.SetVariable(variable.Name, value);
|
||||
material.GetVariable<float3>(variable.Name, var value);
|
||||
|
||||
value = (float3)ColorRGB.LinearToSRGB((ColorRGB)value);
|
||||
|
||||
if (ImGui.ColorEdit3(displayName.Ptr, ref *(float[3]*)&value))
|
||||
{
|
||||
value = (float3)ColorRGB.SRgbToLinear((ColorRGB)value);
|
||||
material.SetVariable(variable.Name, value);
|
||||
}
|
||||
}
|
||||
else if (variable.Columns == 4)
|
||||
{
|
||||
material.GetVariable<float4>(variable.Name, var value);
|
||||
|
||||
value = (float4)ColorRGBA.LinearToSRGB((ColorRGBA)value);
|
||||
|
||||
if (ImGui.ColorEdit4(displayName.Ptr, ref *(float[4]*)&value))
|
||||
{
|
||||
value = (float4)ColorRGBA.SRgbToLinear((ColorRGBA)value);
|
||||
material.SetVariable(variable.Name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (variable.Columns == 4)
|
||||
else if (previewType.Get<String>().Equals("ColorHDR", .InvariantCultureIgnoreCase))
|
||||
{
|
||||
material.GetVariable<Vector4>(variable.Name, var value);
|
||||
Log.EngineLogger.AssertDebug(variable.Type == .Float && variable.Rows == 1);
|
||||
|
||||
value = (Vector4)ColorRGBA.LinearToSRGB((ColorRGBA)value);
|
||||
|
||||
if (ImGui.ColorEdit4(displayName.Ptr, *(float[4]*)&value))
|
||||
if (variable.Columns == 3)
|
||||
{
|
||||
value = (Vector4)ColorRGBA.SRgbToLinear((ColorRGBA)value);
|
||||
material.SetVariable(variable.Name, value);
|
||||
material.GetVariable<float3>(variable.Name, var value);
|
||||
|
||||
value = (float3)ColorRGB.LinearToSRGB((ColorRGB)value);
|
||||
|
||||
if (ImGui.ColorEdit3(displayName.Ptr, ref *(float[3]*)&value, .HDR | .Float))
|
||||
{
|
||||
value = (float3)ColorRGB.SRgbToLinear((ColorRGB)value);
|
||||
material.SetVariable(variable.Name, value);
|
||||
}
|
||||
}
|
||||
else if (variable.Columns == 4)
|
||||
{
|
||||
material.GetVariable<float4>(variable.Name, var value);
|
||||
|
||||
value = (float4)ColorRGBA.LinearToSRGB((ColorRGBA)value);
|
||||
|
||||
if (ImGui.ColorEdit4(displayName.Ptr, ref *(float[4]*)&value, .HDR | .Float))
|
||||
{
|
||||
value = (float4)ColorRGBA.SRgbToLinear((ColorRGBA)value);
|
||||
material.SetVariable(variable.Name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//ImGui.ColorEdit3("", null, .HDR | .Float)
|
||||
|
||||
else if (variable.Type == .Float && variable.Rows == 1)
|
||||
{
|
||||
bool hasMin = TryGetValue(arguments, "Min", var min);
|
||||
@@ -154,28 +189,28 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
||||
if (ImGui.EditVector<1>(displayName, ref *(float[1]*)&value, .(), 0.1f, 100.0f, minV, maxV))
|
||||
material.SetVariable(variable.Name, value);
|
||||
case 2:
|
||||
material.GetVariable<Vector2>(variable.Name, var value);
|
||||
material.GetVariable<float2>(variable.Name, var value);
|
||||
|
||||
Vector2 minV = hasMin ? min.Get<Vector2>() : .(float.MinValue);
|
||||
Vector2 maxV = hasMax ? max.Get<Vector2>() : .(float.MaxValue);
|
||||
float2 minV = hasMin ? min.Get<float2>() : (float2)float.MinValue;
|
||||
float2 maxV = hasMax ? max.Get<float2>() : (float2)float.MaxValue;
|
||||
|
||||
if (ImGui.EditVector2(displayName, ref value, .Zero, 0.1f, 100.0f, minV, maxV))
|
||||
if (ImGui.Editfloat2(displayName, ref value, .Zero, 0.1f, 100.0f, minV, maxV))
|
||||
material.SetVariable(variable.Name, value);
|
||||
case 3:
|
||||
material.GetVariable<Vector3>(variable.Name, var value);
|
||||
material.GetVariable<float3>(variable.Name, var value);
|
||||
|
||||
Vector3 minV = hasMin ? min.Get<Vector3>() : .(float.MinValue);
|
||||
Vector3 maxV = hasMax ? max.Get<Vector3>() : .(float.MaxValue);
|
||||
float3 minV = hasMin ? min.Get<float3>() : (float3)float.MinValue;
|
||||
float3 maxV = hasMax ? max.Get<float3>() : (float3)float.MaxValue;
|
||||
|
||||
if (ImGui.EditVector3(displayName, ref value, .Zero, 0.1f, 100.0f, minV, maxV))
|
||||
if (ImGui.Editfloat3(displayName, ref value, .Zero, 0.1f, 100.0f, minV, maxV))
|
||||
material.SetVariable(variable.Name, value);
|
||||
case 4:
|
||||
material.GetVariable<Vector4>(variable.Name, var value);
|
||||
material.GetVariable<float4>(variable.Name, var value);
|
||||
|
||||
Vector4 minV = hasMin ? min.Get<Vector4>() : .(float.MinValue);
|
||||
Vector4 maxV = hasMax ? max.Get<Vector4>() : .(float.MaxValue);
|
||||
float4 minV = hasMin ? min.Get<float4>() : (float4)float.MinValue;
|
||||
float4 maxV = hasMax ? max.Get<float4>() : (float4)float.MaxValue;
|
||||
|
||||
if (ImGui.EditVector4(displayName, ref value, .Zero, 0.1f, 100.0f, minV, maxV))
|
||||
if (ImGui.Editfloat4(displayName, ref value, .Zero, 0.1f, 100.0f, minV, maxV))
|
||||
material.SetVariable(variable.Name, value);
|
||||
}
|
||||
}
|
||||
@@ -198,14 +233,22 @@ class MaterialAssetLoaderConfig : AssetLoaderConfig
|
||||
[BonTarget]
|
||||
public enum VariableValue
|
||||
{
|
||||
case bool(bool Value);
|
||||
case bool2(bool2 Value);
|
||||
case bool3(bool3 Value);
|
||||
case bool4(bool4 Value);
|
||||
case int(int Value);
|
||||
case int2(int2 Value);
|
||||
case int3(int3 Value);
|
||||
case int4(int4 Value);
|
||||
case uint(uint Value);
|
||||
case uint2(uint2 Value);
|
||||
case uint3(uint3 Value);
|
||||
case uint4(uint4 Value);
|
||||
case Float(float Value);
|
||||
case Float2(Vector2 Value);
|
||||
case Float3(Vector3 Value);
|
||||
case Float4(Vector4 Value);
|
||||
case Int(int Value);
|
||||
case Int2(Int2 Value);
|
||||
case Int3(Int3 Value);
|
||||
case Int4(Int4 Value);
|
||||
case Float2(float2 Value);
|
||||
case Float3(float3 Value);
|
||||
case Float4(float4 Value);
|
||||
case ColorRGB(ColorRGB Value);
|
||||
case ColorRGBA(ColorRGBA Value);
|
||||
case None;
|
||||
@@ -347,6 +390,7 @@ class MaterialAssetLoader : IAssetLoader, IAssetSaver //, IReloadingAssetLoader
|
||||
|
||||
for (let (slotName, textureIdentifier) in materialFile.Textures)
|
||||
{
|
||||
|
||||
AssetHandle<Texture> texture = contentManager.LoadAsset(textureIdentifier);
|
||||
|
||||
if (texture.IsInvalid)
|
||||
@@ -402,7 +446,7 @@ class MaterialAssetLoader : IAssetLoader, IAssetSaver //, IReloadingAssetLoader
|
||||
|
||||
for (let (slotName, texture) in material.[Friend]_textures)
|
||||
{
|
||||
Texture textureAsset = texture.Get();
|
||||
Texture textureAsset = texture.Handle.Get();
|
||||
|
||||
materialFile.Textures.Add(new String(slotName), new String(textureAsset?.Identifier ?? ""));
|
||||
}
|
||||
@@ -450,13 +494,13 @@ class MaterialAssetLoader : IAssetLoader, IAssetSaver //, IReloadingAssetLoader
|
||||
material.GetVariable<float>(variable.Name, let value);
|
||||
variableValue = .Float(value);
|
||||
case 2:
|
||||
material.GetVariable<Vector2>(variable.Name, let value);
|
||||
material.GetVariable<float2>(variable.Name, let value);
|
||||
variableValue = .Float2(value);
|
||||
case 3:
|
||||
material.GetVariable<Vector3>(variable.Name, let value);
|
||||
material.GetVariable<float3>(variable.Name, let value);
|
||||
variableValue = .Float3(value);
|
||||
case 4:
|
||||
material.GetVariable<Vector4>(variable.Name, let value);
|
||||
material.GetVariable<float4>(variable.Name, let value);
|
||||
variableValue = .Float4(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ using GlitchyEngine.Renderer;
|
||||
using GlitchyEngine.Math;
|
||||
using DirectXTK;
|
||||
using ImGui;
|
||||
using GlitchyEditor.Assets.Importers;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace GlitchyEditor.Assets;
|
||||
|
||||
@@ -164,6 +166,9 @@ class EditorTextureAssetLoaderConfig : AssetLoaderConfig
|
||||
}
|
||||
}
|
||||
|
||||
using internal GlitchyEngine.Renderer;
|
||||
using internal GlitchyEngine.Platform.DX11;
|
||||
|
||||
class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
||||
{
|
||||
private static readonly List<StringView> _fileExtensions = new .(){".png", ".dds"} ~ delete _; // ".jpg", ".bmp"
|
||||
@@ -230,23 +235,80 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
||||
return .Unknown;
|
||||
}
|
||||
|
||||
/** \brief Loads the texture from the specified path.
|
||||
* @param path The path of the texture to load.
|
||||
* @param texture The reference to the pointer that will hold the texture.
|
||||
* @returns true if the texture was loaded successfully; false otherwise.
|
||||
*/
|
||||
protected static bool LoadDdsResourcePlatform(Stream stream)
|
||||
{
|
||||
Debug.Profiler.ProfileResourceFunction!();
|
||||
|
||||
uint8[] ddsData = new:ScopedAlloc! uint8[stream.Length];
|
||||
|
||||
var result = stream.TryRead(ddsData);
|
||||
|
||||
if (result case .Err(let err))
|
||||
{
|
||||
Log.EngineLogger.Error($"Failed to read texture data from stream. Error: {err}");
|
||||
}
|
||||
|
||||
DirectX.D3D11.ID3D11Texture2D* texture = null;
|
||||
DirectX.D3D11.ID3D11ShaderResourceView* view = null;
|
||||
|
||||
DirectX.Common.HResult loadResult = DDSTextureLoader.CreateDDSTextureFromMemory(GlitchyEngine.Platform.DX11.NativeDevice,
|
||||
ddsData.Ptr, (uint)ddsData.Count, (.)&texture, &view);
|
||||
|
||||
view.Release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Texture LoadTexture(Stream data, EditorTextureAssetLoaderConfig config)
|
||||
{
|
||||
Debug.Profiler.ProfileResourceFunction!();
|
||||
|
||||
Texture texture = null;
|
||||
List<LoadedSurface> surfaces = scope .();
|
||||
LoadedTextureInfo textureInfo;
|
||||
|
||||
// Make sure we clean up the pixel data
|
||||
defer { delete textureInfo.PixelData; }
|
||||
|
||||
|
||||
switch(GetTextureType(data))
|
||||
{
|
||||
case .DDS:
|
||||
texture = LoadDds(data, config);
|
||||
|
||||
var v = data.Position;
|
||||
|
||||
//LoadDdsResourcePlatform(data);
|
||||
|
||||
data.Position = v;
|
||||
|
||||
Result<void> result = LoadDds(data, config, surfaces, out textureInfo);
|
||||
|
||||
if (result case .Err)
|
||||
return null;
|
||||
|
||||
case .PNG:
|
||||
texture = LoadPng(data, config);
|
||||
Result<void> result = LoadPng(data, config, surfaces, out textureInfo);
|
||||
|
||||
if (result case .Err)
|
||||
return null;
|
||||
|
||||
case .Unknown:
|
||||
Log.EngineLogger.Error("Unknown texture format.");
|
||||
texture = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Make the format SRGB or non-SRGB
|
||||
if (config.IsSRGB)
|
||||
textureInfo.PixelFormat = textureInfo.PixelFormat.GetSRGB();
|
||||
else
|
||||
textureInfo.PixelFormat = textureInfo.PixelFormat.GetNonSRGB();
|
||||
|
||||
Texture texture = CreateTexture(surfaces, textureInfo);
|
||||
|
||||
if (texture != null)
|
||||
{
|
||||
SetSampler(texture, config);
|
||||
@@ -256,10 +318,88 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
||||
return texture;
|
||||
}
|
||||
|
||||
private static Texture2D LoadPng(Stream data, EditorTextureAssetLoaderConfig config)
|
||||
private static Texture CreateTexture(List<LoadedSurface> surfaces, LoadedTextureInfo textureInfo)
|
||||
{
|
||||
TextureSliceData[] slices = scope TextureSliceData[surfaces.Count];
|
||||
|
||||
for (int i < slices.Count)
|
||||
{
|
||||
slices[i] = .(surfaces[i].Data.Ptr, surfaces[i].Pitch, surfaces[i].SlicePitch);
|
||||
}
|
||||
|
||||
//slices[0].SlicePitch = (.)(surfaces[0].Pitch * textureInfo.Height);
|
||||
|
||||
switch (textureInfo.Dimension)
|
||||
{
|
||||
//case .Texture1D:
|
||||
case .Texture2D:
|
||||
if (textureInfo.IsCubeMap)
|
||||
{
|
||||
Texture2DDesc staging = .();
|
||||
|
||||
staging.Width = (.)textureInfo.Width;
|
||||
staging.Height = (.)textureInfo.Height;
|
||||
|
||||
staging.MipLevels = (.)textureInfo.MipMapCount;
|
||||
staging.ArraySize = (.)textureInfo.ArraySize;
|
||||
|
||||
staging.Format = textureInfo.PixelFormat;
|
||||
|
||||
// TODO: allow enabling read/write
|
||||
staging.CpuAccess = .None;
|
||||
staging.Usage = .Default;
|
||||
|
||||
TextureCube cubeTexture = new TextureCube(staging);
|
||||
|
||||
//cubeTexture.SetData();
|
||||
|
||||
for (let surface in surfaces)
|
||||
{
|
||||
cubeTexture.SetData(surface.Data.Ptr, surface.Pitch / staging.Width, (TextureCubeFace)surface.CubeFace, (.)surface.ArrayIndex, (.)surface.MipLevel);
|
||||
}
|
||||
|
||||
return cubeTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
Texture2DDesc staging = .();
|
||||
|
||||
staging.Width = (.)textureInfo.Width;
|
||||
staging.Height = (.)textureInfo.Height;
|
||||
|
||||
staging.MipLevels = (.)textureInfo.MipMapCount;
|
||||
staging.ArraySize = (.)textureInfo.ArraySize;
|
||||
|
||||
staging.Format = textureInfo.PixelFormat;
|
||||
|
||||
// TODO: allow enabling read/write
|
||||
staging.CpuAccess = .None;
|
||||
staging.Usage = .Immutable;
|
||||
|
||||
Texture2D stagingTexture = new Texture2D(staging);
|
||||
|
||||
stagingTexture.SetData(slices);
|
||||
|
||||
/*for (let surface in surfaces)
|
||||
{
|
||||
stagingTexture.[Friend]PlatformSetData(surface.Data.Ptr, surface.Pitch / staging.Width, 0, 0, staging.Width, staging.Height, (.)surface.ArrayIndex, (.)surface.MipLevel, .Write);
|
||||
}*/
|
||||
|
||||
return stagingTexture;
|
||||
}
|
||||
default:
|
||||
Runtime.NotImplemented();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Result<void> LoadPng(Stream data, EditorTextureAssetLoaderConfig config, List<LoadedSurface> surfaces, out LoadedTextureInfo textureInfo)
|
||||
{
|
||||
Debug.Profiler.ProfileResourceFunction!();
|
||||
|
||||
textureInfo = .();
|
||||
|
||||
uint8[] pngData = new:ScopedAlloc! uint8[data.Length];
|
||||
|
||||
var result = data.TryRead(pngData);
|
||||
@@ -267,7 +407,7 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
||||
if (result case .Err(let err))
|
||||
{
|
||||
Log.EngineLogger.Error($"Failed to read data from stream. Texture: Error: {err}");
|
||||
return null;
|
||||
return .Err;
|
||||
}
|
||||
|
||||
uint8* rawData = null;
|
||||
@@ -285,25 +425,55 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
||||
if (errorCode != 0)
|
||||
{
|
||||
Log.EngineLogger.Error($"Failed to decode PNG file {errorCode}.");
|
||||
return null;
|
||||
return .Err;
|
||||
}
|
||||
}
|
||||
|
||||
Texture2DDesc desc = .(width, height, config.IsSRGB ? .R8G8B8A8_UNorm_SRGB : .R8G8B8A8_UNorm, 1, 1, .Immutable);
|
||||
Texture2D texture = new Texture2D(desc);
|
||||
texture.SetData<Color>((.)rawData);
|
||||
uint8[] pixelData = new uint8[4 * width * height];
|
||||
Internal.MemCpy(pixelData.Ptr, rawData, pixelData.Count);
|
||||
|
||||
LoadedSurface surface = .();
|
||||
surface.Data = Span<uint8>(pixelData);
|
||||
surface.Pitch = 4 * width;
|
||||
surface.SlicePitch = 0;
|
||||
surface.ArrayIndex = 0;
|
||||
surface.MipLevel = 0;
|
||||
|
||||
surfaces.Add(surface);
|
||||
|
||||
//Texture2DDesc desc = .(width, height, config.IsSRGB ? .R8G8B8A8_UNorm_SRGB : .R8G8B8A8_UNorm, 1, 1, .Immutable);
|
||||
//Texture2D texture = new Texture2D(desc);
|
||||
//texture.SetData<Color>((.)rawData);
|
||||
|
||||
// TODO: Generate mip maps
|
||||
|
||||
return texture;
|
||||
textureInfo.PixelData = pixelData;
|
||||
textureInfo.Width = width;
|
||||
textureInfo.Height = height;
|
||||
textureInfo.Depth = 1;
|
||||
|
||||
textureInfo.ArraySize = 1;
|
||||
textureInfo.MipMapCount = 1;
|
||||
|
||||
textureInfo.Dimension = .Texture2D;
|
||||
|
||||
textureInfo.IsCubeMap = false;
|
||||
|
||||
textureInfo.PixelFormat = config.IsSRGB ? .R8G8B8A8_UNorm_SRGB : .R8G8B8A8_UNorm;
|
||||
|
||||
return .Ok;
|
||||
|
||||
//return texture;
|
||||
}
|
||||
|
||||
private static Texture LoadDds(Stream data, EditorTextureAssetLoaderConfig config)
|
||||
private static Result<void> LoadDds(Stream data, EditorTextureAssetLoaderConfig config, List<LoadedSurface> surfaces, out LoadedTextureInfo textureInfo)
|
||||
{
|
||||
// TODO: Move the loading of Dds files here.
|
||||
Texture2D texture = new [Friend]Texture2D(data);
|
||||
var result = DdsImporter.LoadDds(data, config.IsSRGB, surfaces, out textureInfo);
|
||||
|
||||
return texture;
|
||||
if (result case .Err)
|
||||
return .Err;
|
||||
|
||||
return .Ok;
|
||||
}
|
||||
|
||||
private static void SetSampler(Texture texture, EditorTextureAssetLoaderConfig config)
|
||||
@@ -315,12 +485,38 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
||||
}
|
||||
|
||||
private static Texture2D _placeholder2D;
|
||||
private static TextureCube _placeholderCube;
|
||||
|
||||
private static Texture2D _error2D;
|
||||
private static TextureCube _errorCube;
|
||||
|
||||
public Asset GetPlaceholderAsset(Type assetType)
|
||||
{
|
||||
switch (assetType)
|
||||
{
|
||||
case typeof(TextureCube):
|
||||
if (_placeholderCube == null)
|
||||
{
|
||||
// TODO: immutable
|
||||
Texture2DDesc desc = .(1, 1, .R8G8B8A8_UNorm, 1, 1, .Default, .None);
|
||||
|
||||
_placeholderCube = new TextureCube(desc);
|
||||
_placeholderCube.SamplerState = SamplerStateManager.PointWrap;
|
||||
Color color = Color.Cyan;
|
||||
_placeholderCube.SetData<Color>(&color, .PositiveX);
|
||||
_placeholderCube.SetData<Color>(&color, .NegativeX);
|
||||
_placeholderCube.SetData<Color>(&color, .PositiveY);
|
||||
_placeholderCube.SetData<Color>(&color, .NegativeY);
|
||||
_placeholderCube.SetData<Color>(&color, .PositiveZ);
|
||||
_placeholderCube.SetData<Color>(&color, .NegativeZ);
|
||||
|
||||
Content.ManageAsset(_placeholderCube);
|
||||
_placeholderCube.ReleaseRef();
|
||||
|
||||
_placeholderCube.[Friend]Complete = false;
|
||||
}
|
||||
|
||||
return _placeholderCube;
|
||||
case typeof(Texture2D):
|
||||
fallthrough;
|
||||
default:
|
||||
@@ -347,6 +543,31 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
||||
{
|
||||
switch (assetType)
|
||||
{
|
||||
case typeof(TextureCube):
|
||||
if (_placeholderCube == null)
|
||||
{
|
||||
// TODO: immutable
|
||||
Texture2DDesc desc = .(2, 2, .R8G8B8A8_UNorm, 1, 1, .Default, .None);
|
||||
|
||||
_errorCube = new TextureCube(desc);
|
||||
_errorCube.SamplerState = SamplerStateManager.PointWrap;
|
||||
|
||||
Color[4] color = .(Color.HotPink, Color.Black, Color.Black, Color.HotPink);
|
||||
|
||||
_errorCube.SetData<Color>(&color, .PositiveX);
|
||||
_errorCube.SetData<Color>(&color, .NegativeX);
|
||||
_errorCube.SetData<Color>(&color, .PositiveY);
|
||||
_errorCube.SetData<Color>(&color, .NegativeY);
|
||||
_errorCube.SetData<Color>(&color, .PositiveZ);
|
||||
_errorCube.SetData<Color>(&color, .NegativeZ);
|
||||
|
||||
Content.ManageAsset(_errorCube);
|
||||
_errorCube.ReleaseRef();
|
||||
|
||||
_errorCube.[Friend]Complete = false;
|
||||
}
|
||||
|
||||
return _placeholderCube;
|
||||
case typeof(Texture2D):
|
||||
fallthrough;
|
||||
default:
|
||||
@@ -356,7 +577,9 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
||||
|
||||
_error2D = new Texture2D(desc);
|
||||
_error2D.SamplerState = SamplerStateManager.PointWrap;
|
||||
|
||||
Color[4] color = .(Color.HotPink, Color.Black, Color.Black, Color.HotPink);
|
||||
|
||||
_error2D.SetData<Color>(&color);
|
||||
|
||||
Content.ManageAsset(_error2D);
|
||||
|
||||
@@ -0,0 +1,608 @@
|
||||
using ImGui;
|
||||
using System;
|
||||
using GlitchyEngine.Content;
|
||||
using GlitchyEngine.Renderer;
|
||||
using GlitchyEngine.Math;
|
||||
using GlitchyEngine;
|
||||
namespace GlitchyEditor.EditWindows;
|
||||
|
||||
class AssetViewer : EditorWindow
|
||||
{
|
||||
public const String s_WindowTitle = "Asset Viewer";
|
||||
|
||||
public EditorContentManager _manager;
|
||||
|
||||
private AssetHandle _selectedAsset;
|
||||
|
||||
append TexturererViewerer _textureViewer = .();
|
||||
|
||||
public this(EditorContentManager contentManager)
|
||||
{
|
||||
_manager = contentManager;
|
||||
}
|
||||
|
||||
protected override void InternalShow()
|
||||
{
|
||||
if(!ImGui.Begin(s_WindowTitle, &_open, .None))
|
||||
{
|
||||
ImGui.End();
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui.PushStyleVar(.CellPadding, .(0, 0));
|
||||
|
||||
bool alt_pressed = ImGui.GetIO().KeyAlt;
|
||||
|
||||
if (ImGui.BeginTable("AssetViewerTable", 2, .BordersInnerV | .Resizable | .Reorderable | .NoPadOuterX))
|
||||
{
|
||||
if (alt_pressed)
|
||||
{
|
||||
// Header anzeigen, damit sie neu angeordnet werden können
|
||||
ImGui.TableSetupColumn("Assets");
|
||||
ImGui.TableSetupColumn("Viewer");
|
||||
ImGui.TableHeadersRow();
|
||||
}
|
||||
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableSetColumnIndex(0);
|
||||
|
||||
if (ImGui.BeginChild("Assets"))
|
||||
DrawAssetList();
|
||||
|
||||
ImGui.EndChild();
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
|
||||
if (ImGui.BeginChild("Files"))
|
||||
DrawAssetViewer();
|
||||
|
||||
ImGui.EndChild();
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
ImGui.PopStyleVar(1);
|
||||
|
||||
ImGui.End();
|
||||
}
|
||||
|
||||
void DrawAssetList()
|
||||
{
|
||||
for (let (handle, asset) in _manager.[Friend]_handleToAsset)
|
||||
{
|
||||
// TODO: gucken, was der Typ ist
|
||||
|
||||
String name = scope String();
|
||||
|
||||
if (asset.Identifier.IsWhiteSpace)
|
||||
name.Append("Unnamed");
|
||||
else
|
||||
name.Append(asset.Identifier);
|
||||
|
||||
name.Append(" (");
|
||||
asset.GetType().GetName(name);
|
||||
name.Append(") [");
|
||||
name.AppendF($"{handle.ID}]");
|
||||
|
||||
name.TrimStart();
|
||||
|
||||
ImGui.TreeNodeFlags flags = .Leaf;
|
||||
|
||||
if(handle == _selectedAsset)
|
||||
flags |= .Selected;
|
||||
|
||||
if (ImGui.TreeNodeEx(name, flags, name))
|
||||
{
|
||||
if (ImGui.IsItemClicked(.Left))
|
||||
_selectedAsset = handle;
|
||||
|
||||
ImGui.TreePop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawAssetViewer()
|
||||
{
|
||||
if (_selectedAsset.IsInvalid)
|
||||
{
|
||||
ImGui.Text("Select an asset to view it.");
|
||||
return;
|
||||
}
|
||||
|
||||
Asset asset = _selectedAsset.Get<Asset>();
|
||||
|
||||
/*if (!asset.Complete)
|
||||
{
|
||||
ImGui.Text("Loading asset...");
|
||||
return;
|
||||
}*/
|
||||
|
||||
/*switch (asset.GetType())
|
||||
{
|
||||
case typeof(RenderTargetGroup):
|
||||
DrawRenderTargetGroupViewer((RenderTargetGroup)asset);
|
||||
case typeof(Texture):
|
||||
_textureViewer.ViewTexture((Texture)asset);
|
||||
|
||||
}*/
|
||||
|
||||
if (var texture = asset as Texture)
|
||||
_textureViewer.ViewTexture(texture);
|
||||
if (var texture = asset as RenderTargetGroup)
|
||||
_textureViewer.ViewTexture(texture);
|
||||
}
|
||||
}
|
||||
|
||||
class TexturererViewerer
|
||||
{
|
||||
enum BackgroundMode : int32
|
||||
{
|
||||
White,
|
||||
Black,
|
||||
Pink,
|
||||
Checkerboard,
|
||||
CustomColor
|
||||
}
|
||||
|
||||
enum SampleMode : int32
|
||||
{
|
||||
Point,
|
||||
Linear
|
||||
}
|
||||
|
||||
enum ColorChannelSwizzle : int32
|
||||
{
|
||||
None,
|
||||
R,
|
||||
G,
|
||||
B,
|
||||
A
|
||||
}
|
||||
|
||||
AssetHandle<Effect> _effect;
|
||||
AssetHandle<Effect> _renderTargetEffect;
|
||||
|
||||
float _zoom = 1.0f;
|
||||
|
||||
BackgroundMode _backgroundMode = .Checkerboard;
|
||||
ColorRGBA _backgroundColor;
|
||||
|
||||
SampleMode _sampleMode = .Linear;
|
||||
|
||||
RenderTarget2D _target ~ _?.ReleaseRef();
|
||||
// TODO: we don't need depth!
|
||||
DepthStencilTarget _depth ~ _?.ReleaseRef();
|
||||
|
||||
public this()
|
||||
{
|
||||
_effect = Content.LoadAsset("Resources/Shaders/textureViewerShader.hlsl");
|
||||
_renderTargetEffect = Content.LoadAsset("Resources/Shaders/RenderTargetGroupViewer.hlsl");
|
||||
}
|
||||
|
||||
float2 _position;
|
||||
|
||||
bool _moving;
|
||||
|
||||
float _colorOffset = 0;
|
||||
float _colorScale = 1;
|
||||
float _alphaOffset = 0;
|
||||
float _alphaScale = 1;
|
||||
|
||||
int32 _mipLevel = 0;
|
||||
int32 _arraySlice = 0;
|
||||
int32 _groupIndex = 0;
|
||||
|
||||
ColorChannelSwizzle _swizzleR = .R;
|
||||
ColorChannelSwizzle _swizzleG = .G;
|
||||
ColorChannelSwizzle _swizzleB = .B;
|
||||
ColorChannelSwizzle _swizzleA = .A;
|
||||
|
||||
public void ShowSettings(float width, float height, int maxMips, int arraySize, RenderTargetGroup rtGroup)
|
||||
{
|
||||
char8*[] items = scope .("White", "Black", "Pink", "Checkerboard", "Custom Color");
|
||||
|
||||
if (ImGui.CollapsingHeader("View"))
|
||||
{
|
||||
ImGui.SliderFloat("Zoom", &_zoom, 0.01f, 100.0f);
|
||||
|
||||
float maxDimension = max(width, height);
|
||||
|
||||
ImGui.SliderFloat2("Position", ref *(float[2]*)&_position, 2 * -maxDimension * _zoom, 2 * maxDimension * _zoom);
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
ImGui.Combo("Background", (.)&_backgroundMode, items.Ptr, (.)items.Count);
|
||||
|
||||
if (_backgroundMode == .CustomColor)
|
||||
{
|
||||
ImGui.ColorPicker4("Color", ref _backgroundColor);
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui.CollapsingHeader("Sampling"))
|
||||
{
|
||||
items = scope .("Point", "Linear");
|
||||
|
||||
ImGui.Combo("Sampler", (.)&_sampleMode, items.Ptr, (.)items.Count);
|
||||
|
||||
ImGui.SliderInt("Mip Level", &_mipLevel, 0, (int32)maxMips);
|
||||
ImGui.SliderInt("Array Slice", &_arraySlice, 0, (int32)arraySize);
|
||||
|
||||
ImGui.BeginDisabled(rtGroup == null);
|
||||
|
||||
ImGui.SliderInt("Group Target", &_groupIndex, (rtGroup?.HasDepth == true) ? -1 : 0, (int32)(rtGroup?.ColorTargetCount ?? 1) - 1);
|
||||
|
||||
ImGui.TextUnformatted(scope $"Target name: {(rtGroup?.GetTargetDescription(_groupIndex).DebugName ?? "???")}");
|
||||
|
||||
ImGui.EndDisabled();
|
||||
}
|
||||
|
||||
if (ImGui.CollapsingHeader("Color and Transparency"))
|
||||
{
|
||||
ImGui.TextUnformatted("Channel Swizzle:");
|
||||
|
||||
if (ImGui.BeginTable("ColorAndAlpha", 4))
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableSetColumnIndex(0);
|
||||
|
||||
ImGui.PushID("Color");
|
||||
|
||||
ImGui.TextUnformatted("Color:");
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.DragFloat("Offset", &_colorOffset, 0.1f);
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.DragFloat("Scale", &_colorScale, 0.1f);
|
||||
ImGui.TableNextColumn();
|
||||
|
||||
if (ImGui.Button("Reset"))
|
||||
{
|
||||
_colorOffset = 0.0f;
|
||||
_colorScale = 1.0f;
|
||||
}
|
||||
ImGui.SameLine();
|
||||
ImGui.BeginDisabled();
|
||||
if (ImGui.Button("Auto"))
|
||||
{
|
||||
Runtime.NotImplemented();
|
||||
}
|
||||
ImGui.EndDisabled();
|
||||
|
||||
ImGui.PopID();
|
||||
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableSetColumnIndex(0);
|
||||
|
||||
ImGui.PushID("Alpha");
|
||||
|
||||
ImGui.TextUnformatted("Alpha:");
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.DragFloat("Offset", &_alphaOffset, 0.1f);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.DragFloat("Scale", &_alphaScale, 0.1f);
|
||||
ImGui.TableNextColumn();
|
||||
|
||||
if (ImGui.Button("Reset"))
|
||||
{
|
||||
_alphaOffset = 0.0f;
|
||||
_alphaScale = 1.0f;
|
||||
}
|
||||
|
||||
ImGui.PopID();
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
ImGui.TextUnformatted("Channel Swizzle:");
|
||||
|
||||
if (ImGui.BeginTable("SwizzleTable", 9))
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableSetColumnIndex(0);
|
||||
|
||||
SwizzleCombo("R", ref _swizzleR);
|
||||
ImGui.TableNextColumn();
|
||||
SwizzleCombo("G", ref _swizzleG);
|
||||
ImGui.TableNextColumn();
|
||||
SwizzleCombo("B", ref _swizzleB);
|
||||
ImGui.TableNextColumn();
|
||||
SwizzleCombo("A", ref _swizzleA);
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
|
||||
if (ImGui.Button("Reset swizzle"))
|
||||
{
|
||||
_swizzleR = .R;
|
||||
_swizzleG = .G;
|
||||
_swizzleB = .B;
|
||||
_swizzleA = .A;
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SwizzleCombo(StringView text, ref ColorChannelSwizzle swizzle)
|
||||
{
|
||||
ImGui.TextUnformatted(text);
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
|
||||
if (ImGui.BeginCombo(scope $"##swizzle{text}", scope $"{swizzle}"))
|
||||
{
|
||||
if (ImGui.Selectable("R", swizzle == .R))
|
||||
swizzle = .R;
|
||||
|
||||
if (ImGui.Selectable("G", swizzle == .G))
|
||||
swizzle = .G;
|
||||
|
||||
if (ImGui.Selectable("B", swizzle == .B))
|
||||
swizzle = .B;
|
||||
|
||||
if (ImGui.Selectable("A", swizzle == .A))
|
||||
swizzle = .A;
|
||||
|
||||
if (ImGui.Selectable("None", swizzle == .None))
|
||||
swizzle = .None;
|
||||
|
||||
ImGui.EndCombo();
|
||||
}
|
||||
}
|
||||
|
||||
public void ViewTexture(RenderTargetGroup texture)
|
||||
{
|
||||
ShowSettings(texture.Width, texture.Height, texture.MipLevels - 1, texture.ArraySize - 1, texture);
|
||||
|
||||
if (ImGui.BeginChild("imageChild"))
|
||||
{
|
||||
UpdateInput();
|
||||
|
||||
var viewportSize = ImGui.GetContentRegionAvail();
|
||||
|
||||
viewportSize.x = Math.Max(viewportSize.x, 1);
|
||||
viewportSize.y = Math.Max(viewportSize.y, 1);
|
||||
|
||||
if(_target == null || viewportSize.x != _target.Width || viewportSize.y != _target.Height)
|
||||
{
|
||||
_target?.ReleaseRef();
|
||||
_target = new RenderTarget2D(.(.R8G8B8A8_UNorm_SRGB, (.)viewportSize.x, (.)viewportSize.y));
|
||||
_target.SamplerState = SamplerStateManager.PointClamp;
|
||||
_depth?.ReleaseRef();
|
||||
_depth = new DepthStencilTarget((.)viewportSize.x, (.)viewportSize.y, .D16_UNorm);
|
||||
}
|
||||
|
||||
RenderBackground();
|
||||
|
||||
RenderTexture(texture);
|
||||
|
||||
ImGui.Image(_target, viewportSize);
|
||||
|
||||
ImGui.EndChild();
|
||||
}
|
||||
}
|
||||
|
||||
public void ViewTexture(Texture texture)
|
||||
{
|
||||
ShowSettings(texture.Width, texture.Height, texture.MipLevels - 1, texture.ArraySize - 1, null);
|
||||
|
||||
if (ImGui.BeginChild("imageChild"))
|
||||
{
|
||||
UpdateInput();
|
||||
|
||||
var viewportSize = ImGui.GetContentRegionAvail();
|
||||
|
||||
viewportSize.x = Math.Max(viewportSize.x, 1);
|
||||
viewportSize.y = Math.Max(viewportSize.y, 1);
|
||||
|
||||
if(_target == null || viewportSize.x != _target.Width || viewportSize.y != _target.Height)
|
||||
{
|
||||
_target?.ReleaseRef();
|
||||
_target = new RenderTarget2D(.(.R8G8B8A8_UNorm_SRGB, (.)viewportSize.x, (.)viewportSize.y));
|
||||
_target.SamplerState = SamplerStateManager.PointClamp;
|
||||
_depth?.ReleaseRef();
|
||||
_depth = new DepthStencilTarget((.)viewportSize.x, (.)viewportSize.y, .D16_UNorm);
|
||||
}
|
||||
|
||||
RenderBackground();
|
||||
|
||||
RenderTexture(texture);
|
||||
|
||||
ImGui.Image(_target, viewportSize);
|
||||
|
||||
ImGui.EndChild();
|
||||
}
|
||||
}
|
||||
|
||||
float lastWheel;
|
||||
|
||||
private void UpdateInput()
|
||||
{
|
||||
var windowPos = ImGui.GetWindowPos();
|
||||
var mousePos = ImGui.GetIO().MousePos;
|
||||
float2 mouseInWindow = .(mousePos.x - windowPos.x, mousePos.y - windowPos.y);
|
||||
|
||||
bool windowHovered = ImGui.IsWindowHovered();
|
||||
|
||||
if(windowHovered && Input.IsMouseButtonPressing(.MiddleButton))
|
||||
{
|
||||
_moving = true;
|
||||
}
|
||||
else if(Input.IsMouseButtonReleased(.MiddleButton))
|
||||
{
|
||||
_moving = false;
|
||||
}
|
||||
|
||||
if(windowHovered || _moving)
|
||||
{
|
||||
float mouseWheel = ImGui.GetIO().MouseWheel;
|
||||
|
||||
float delta = mouseWheel - lastWheel;
|
||||
|
||||
if(delta != 0)
|
||||
{
|
||||
_position -= mouseInWindow;
|
||||
_position /= _zoom;
|
||||
|
||||
_zoom *= Math.Pow(1.1f, delta);
|
||||
|
||||
_position *= _zoom;
|
||||
_position += mouseInWindow;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(_moving)
|
||||
{
|
||||
int2 movement = Input.GetMouseMovement();
|
||||
|
||||
_position.X += movement.X;
|
||||
_position.Y += movement.Y;
|
||||
}
|
||||
}
|
||||
|
||||
OrthographicCamera _camera = new OrthographicCamera() ~ delete _;
|
||||
|
||||
private void RenderBackground()
|
||||
{
|
||||
Viewport vp = .(0, 0, _target.Width, _target.Height);
|
||||
RenderCommand.SetViewport(vp);
|
||||
|
||||
// TODO: don't clear pink!
|
||||
RenderCommand.Clear(_target, .Pink);
|
||||
RenderCommand.Clear(_depth, .Depth, 1.0f, 0);
|
||||
|
||||
//_target.Bind();
|
||||
RenderCommand.SetRenderTarget(_target);
|
||||
RenderCommand.SetDepthStencilTarget(_depth);
|
||||
RenderCommand.BindRenderTargets();
|
||||
|
||||
float2 targetSize = float2(_target.Width, _target.Height);
|
||||
|
||||
_camera.Left = 0;
|
||||
_camera.Top = 0;
|
||||
_camera.Right = targetSize.X;
|
||||
_camera.Bottom = -targetSize.Y;
|
||||
_camera.NearPlane = -5;
|
||||
_camera.FarPlane = 5;
|
||||
_camera.Update();
|
||||
|
||||
Renderer2D.BeginScene(_camera);
|
||||
|
||||
switch(_backgroundMode)
|
||||
{
|
||||
case .Black:
|
||||
Renderer2D.DrawQuadPivotCorner(float3(0, 0, 1), targetSize, 0, .Black);
|
||||
case .White:
|
||||
Renderer2D.DrawQuadPivotCorner(float3(0, 0, 1), targetSize, 0, .White);
|
||||
case .Pink:
|
||||
Renderer2D.DrawQuadPivotCorner(float3(0, 0, 1), targetSize, 0, .HotPink);
|
||||
case .CustomColor:
|
||||
Renderer2D.DrawQuadPivotCorner(float3(0, 0, 1), targetSize, 0, _backgroundColor);
|
||||
case .Checkerboard:
|
||||
float quadSize = 50.0f;
|
||||
|
||||
float2 numQuads = (targetSize / 500f) * 10f;
|
||||
|
||||
for(float x = 0; x < numQuads.X; x++)
|
||||
{
|
||||
for(float y = 0; y < numQuads.Y; y++)
|
||||
{
|
||||
Renderer2D.DrawQuadPivotCorner(float3(x * quadSize, -y * quadSize, 1), quadSize.XX, 0, ((x + y) % 2 == 0) ? .White : .Gray);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Renderer2D.EndScene();
|
||||
}
|
||||
|
||||
private void RenderTexture(TextureViewBinding viewedTexture, float2 textureSize, Format format)
|
||||
{
|
||||
float2 mippedTextureSize = float2((int)textureSize.X >> _mipLevel, (int)textureSize.X >> _mipLevel);
|
||||
|
||||
// Sicherstellen, dass die Auflösung nicht 0 wird
|
||||
mippedTextureSize = max(mippedTextureSize, 1);
|
||||
|
||||
//float2 textureSize = float2(viewedTexture.Width, viewedTexture.Height);
|
||||
float2 zoomedTextureSize = textureSize * _zoom;
|
||||
|
||||
// TODO: Sampler state for rt group
|
||||
//var sampler = viewedTexture.SamplerState;
|
||||
|
||||
/*switch(_sampleMode)
|
||||
{
|
||||
case .Point:
|
||||
viewedTexture.SamplerState = SamplerStateManager.PointClamp;
|
||||
case .Linear:
|
||||
viewedTexture.SamplerState = SamplerStateManager.LinearClamp;
|
||||
}*/
|
||||
|
||||
//Renderer2D.BeginScene(_camera, .SortByTexture, _effect);
|
||||
|
||||
// float3(_position * .(1, -1), 0)
|
||||
RenderCommand.Clear(_depth, .Depth, 1.0f, 0);
|
||||
|
||||
Matrix matrix = .Translation(float3(_position * .(1, -1), 0)) * .Scaling(float3(zoomedTextureSize, 1));
|
||||
|
||||
// TODO: ViewProjection kommt nicht korrekt an?
|
||||
_renderTargetEffect.Variables["WorldViewProjection"].SetData(_camera.ViewProjection * matrix);
|
||||
_renderTargetEffect.Variables["ColorOffset"].SetData(_colorOffset);
|
||||
_renderTargetEffect.Variables["ColorScale"].SetData(_colorScale);
|
||||
_renderTargetEffect.Variables["AlphaOffset"].SetData(_alphaOffset);
|
||||
_renderTargetEffect.Variables["AlphaScale"].SetData(_alphaScale);
|
||||
|
||||
_renderTargetEffect.Variables["Texels"].SetData(mippedTextureSize);
|
||||
|
||||
_renderTargetEffect.Variables["MipLevel"].SetData((float)_mipLevel);
|
||||
|
||||
_renderTargetEffect.Variables["Swizzle"].SetData(int4((int32)_swizzleR, (int32)_swizzleG, (int32)_swizzleB, (int32)_swizzleA));
|
||||
|
||||
if (format.IsInt())
|
||||
{
|
||||
// Int Texture
|
||||
_renderTargetEffect.Variables["Mode"].SetData(1);
|
||||
_renderTargetEffect.SetTexture("IntTexture", viewedTexture);
|
||||
_renderTargetEffect.SetTexture("UIntTexture", null);
|
||||
_renderTargetEffect.SetTexture("Texture", null);
|
||||
}
|
||||
else if (format.IsUInt())
|
||||
{
|
||||
// UInt Texture
|
||||
_renderTargetEffect.Variables["Mode"].SetData(2);
|
||||
_renderTargetEffect.SetTexture("IntTexture", null);
|
||||
_renderTargetEffect.SetTexture("UIntTexture", viewedTexture);
|
||||
_renderTargetEffect.SetTexture("Texture", null);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Float Texture
|
||||
_renderTargetEffect.Variables["Mode"].SetData(0);
|
||||
_renderTargetEffect.SetTexture("IntTexture", null);
|
||||
_renderTargetEffect.SetTexture("UIntTexture", null);
|
||||
_renderTargetEffect.SetTexture("Texture", viewedTexture);
|
||||
}
|
||||
|
||||
_renderTargetEffect.Variables["Swizzle"].SetData(int4((int32)_swizzleR, (int32)_swizzleG, (int32)_swizzleB, (int32)_swizzleA));
|
||||
|
||||
_renderTargetEffect.ApplyChanges();
|
||||
_renderTargetEffect.Bind();
|
||||
|
||||
Quad.Draw();
|
||||
}
|
||||
|
||||
private void RenderTexture(RenderTargetGroup viewedTexture)
|
||||
{
|
||||
var desc = _groupIndex >= 0 ? viewedTexture.[Friend]_colorTargetDescriptions[_groupIndex] : viewedTexture.[Friend]_depthTargetDescription;
|
||||
|
||||
RenderTexture(viewedTexture.GetViewBinding(_groupIndex), float2(viewedTexture.Width, viewedTexture.Height), desc.Format.GetShaderViewFormat());
|
||||
}
|
||||
|
||||
private void RenderTexture(Texture viewedTexture)
|
||||
{
|
||||
RenderTexture(viewedTexture.GetViewBinding(), float2(viewedTexture.Width, viewedTexture.Height), viewedTexture.Format);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,9 @@ using System.Collections;
|
||||
using GlitchyEngine.Renderer;
|
||||
using GlitchyEngine;
|
||||
using GlitchyEngine.Content;
|
||||
using GlitchyEngine.Scripting;
|
||||
using GlitchyEngine.Core;
|
||||
using Mono;
|
||||
|
||||
namespace GlitchyEditor.EditWindows
|
||||
{
|
||||
@@ -68,6 +71,7 @@ namespace GlitchyEditor.EditWindows
|
||||
ShowComponentEditor<Rigidbody2DComponent>("Rigidbody 2D", entity, => ShowRigidBody2DComponentEditor, => ShowComponentContextMenu<Rigidbody2DComponent>);
|
||||
ShowComponentEditor<BoxCollider2DComponent>("Box collider 2D", entity, => ShowBoxCollider2DComponentEditor, => ShowComponentContextMenu<BoxCollider2DComponent>);
|
||||
ShowComponentEditor<CircleCollider2DComponent>("Circle collider 2D", entity, => ShowCircleCollider2DComponentEditor, => ShowComponentContextMenu<CircleCollider2DComponent>);
|
||||
ShowComponentEditor<ScriptComponent>("Script Component", entity, => ShowScriptComponentEditor, => ShowComponentContextMenu<ScriptComponent>);
|
||||
|
||||
ShowAddComponentButton(entity);
|
||||
}
|
||||
@@ -108,7 +112,8 @@ namespace GlitchyEditor.EditWindows
|
||||
|
||||
if (nodeOpen)
|
||||
{
|
||||
showComponentEditor(entity, component);
|
||||
if (entity.TryGetComponent<TComponent>(let actualComponent))
|
||||
showComponentEditor(entity, actualComponent);
|
||||
|
||||
ImGui.TreePop();
|
||||
}
|
||||
@@ -158,16 +163,32 @@ namespace GlitchyEditor.EditWindows
|
||||
|
||||
textWidth += ImGui.GetStyle().FramePadding.x * 3.0f;
|
||||
|
||||
Vector3 position = transform.Position;
|
||||
if (ImGui.EditVector3("Position", ref position, .Zero, 0.1f, textWidth))
|
||||
float3 position = transform.Position;
|
||||
if (ImGui.Editfloat3("Position", ref position, .Zero, 0.1f, textWidth))
|
||||
{
|
||||
transform.Position = position;
|
||||
|
||||
Vector3 rotationEuler = MathHelper.ToDegrees(transform.EditorRotationEuler);
|
||||
if (ImGui.EditVector3("Rotation", ref rotationEuler, .Zero, 0.1f, textWidth))
|
||||
// if necessary reposition Rigidbody2D
|
||||
if (entity.TryGetComponent<Rigidbody2DComponent>(let rigidbody2D))
|
||||
{
|
||||
rigidbody2D.SetPosition(position.XY);
|
||||
}
|
||||
}
|
||||
|
||||
float3 rotationEuler = MathHelper.ToDegrees(transform.EditorRotationEuler);
|
||||
if (ImGui.Editfloat3("Rotation", ref rotationEuler, .Zero, 0.1f, textWidth))
|
||||
{
|
||||
transform.EditorRotationEuler = MathHelper.ToRadians(rotationEuler);
|
||||
|
||||
Vector3 scale = transform.Scale;
|
||||
if (ImGui.EditVector3("Scale", ref scale, .One, 0.1f, textWidth))
|
||||
// if necessary reposition Rigidbody2D
|
||||
if (entity.TryGetComponent<Rigidbody2DComponent>(let rigidbody2D))
|
||||
{
|
||||
rigidbody2D.SetAngle(rotationEuler.Z);
|
||||
}
|
||||
}
|
||||
|
||||
float3 scale = transform.Scale;
|
||||
if (ImGui.Editfloat3("Scale", ref scale, .One, 0.1f, textWidth))
|
||||
transform.Scale = scale;
|
||||
}
|
||||
|
||||
@@ -260,7 +281,7 @@ namespace GlitchyEditor.EditWindows
|
||||
|
||||
if (ImGui.BeginDragDropTarget())
|
||||
{
|
||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
||||
|
||||
if (payload != null)
|
||||
{
|
||||
@@ -288,7 +309,7 @@ namespace GlitchyEditor.EditWindows
|
||||
|
||||
if (ImGui.BeginDragDropTarget())
|
||||
{
|
||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
||||
|
||||
if (payload != null)
|
||||
{
|
||||
@@ -320,7 +341,7 @@ namespace GlitchyEditor.EditWindows
|
||||
|
||||
if (ImGui.BeginDragDropTarget())
|
||||
{
|
||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
||||
|
||||
if (payload != null)
|
||||
{
|
||||
@@ -373,12 +394,12 @@ namespace GlitchyEditor.EditWindows
|
||||
textWidth += ImGui.GetStyle().FramePadding.x * 3.0f;
|
||||
|
||||
|
||||
Vector2 offset = boxCollider.Offset;
|
||||
if (ImGui.EditVector2("Offset", ref offset, .Zero, 0.1f, textWidth))
|
||||
float2 offset = boxCollider.Offset;
|
||||
if (ImGui.Editfloat2("Offset", ref offset, .Zero, 0.1f, textWidth))
|
||||
boxCollider.Offset = offset;
|
||||
|
||||
Vector2 size = boxCollider.Size;
|
||||
if (ImGui.EditVector2("Size", ref size, .Zero, 0.1f, textWidth))
|
||||
float2 size = boxCollider.Size;
|
||||
if (ImGui.Editfloat2("Size", ref size, .Zero, 0.1f, textWidth))
|
||||
boxCollider.Size = size;
|
||||
|
||||
float density = boxCollider.Density;
|
||||
@@ -404,8 +425,8 @@ namespace GlitchyEditor.EditWindows
|
||||
textWidth += ImGui.GetStyle().FramePadding.x * 3.0f;
|
||||
|
||||
|
||||
Vector2 offset = circleCollider.Offset;
|
||||
if (ImGui.EditVector2("Offset", ref offset, .Zero, 0.1f, textWidth))
|
||||
float2 offset = circleCollider.Offset;
|
||||
if (ImGui.Editfloat2("Offset", ref offset, .Zero, 0.1f, textWidth))
|
||||
circleCollider.Offset = offset;
|
||||
|
||||
float radius = circleCollider.Radius;
|
||||
@@ -429,6 +450,561 @@ namespace GlitchyEditor.EditWindows
|
||||
circleCollider.RestitutionThreshold = restitutionThreshold;
|
||||
}
|
||||
|
||||
private static void ShowScriptComponentEditor(Entity entity, ScriptComponent* scriptComponent)
|
||||
{
|
||||
static char8[64] buffer = .();
|
||||
|
||||
StringView search = StringView();
|
||||
|
||||
char8* scriptLabel = scriptComponent.Instance?.ScriptClass.FullName.ToScopeCStr!() ?? "Select Script...";
|
||||
|
||||
if (ImGui.Button(scriptLabel))
|
||||
ImGui.OpenPopup("SelectScript");
|
||||
|
||||
if (ImGui.BeginPopup("SelectScript"))
|
||||
{
|
||||
ImGui.InputText("##ScriptSearch", &buffer, buffer.Count);
|
||||
|
||||
search = StringView(&buffer);
|
||||
|
||||
for (let (className, scriptClass) in ScriptEngine.EntityClasses)
|
||||
{
|
||||
if (!search.IsWhiteSpace && !className.Contains(search, true))
|
||||
continue;
|
||||
|
||||
if (ImGui.Selectable(className.ToScopeCStr!(),
|
||||
className == scriptComponent.ScriptClassName))
|
||||
{
|
||||
//scriptComponent.Instance = new ScriptInstance(scriptClass);
|
||||
// decrement refCount to 1 (scriptComponent.Instance increments its)
|
||||
//scriptComponent.Instance.ReleaseRef();
|
||||
//ScriptEngine.InitializeInstance(entity, scriptComponent);
|
||||
|
||||
scriptComponent.ScriptClassName = scriptClass.FullName;
|
||||
|
||||
ScriptEngine.CreateScriptFieldMap(entity);
|
||||
}
|
||||
}
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
ScriptClass scriptClass = ScriptEngine.GetScriptClass(scriptComponent.ScriptClassName);
|
||||
|
||||
/*T GetFieldValue<T>()
|
||||
{
|
||||
return scriptComponent.Instance.GetFieldValue<T>(monoField);
|
||||
}
|
||||
|
||||
void SetFieldValue<T>(in T value)
|
||||
{
|
||||
scriptComponent.Instance.SetFieldValue<T>(monoField, value);
|
||||
}*/
|
||||
|
||||
T GetFieldValue<T>(ScriptInstance scriptInstance, in ScriptField scriptField)
|
||||
{
|
||||
return scriptInstance.GetFieldValue<T>(scriptField);
|
||||
}
|
||||
|
||||
void GetFieldValue<T>(ScriptInstance scriptInstance, in ScriptField scriptField, out T value)
|
||||
{
|
||||
value = scriptInstance.GetFieldValue<T>(scriptField);
|
||||
}
|
||||
|
||||
void SetFieldValue<T>(ScriptInstance scriptInstance, in ScriptField scriptField, in T value)
|
||||
{
|
||||
scriptInstance.SetFieldValue<T>(scriptField, value);
|
||||
}
|
||||
|
||||
T GetData<T>(void* instance, ScriptField scriptField)
|
||||
{
|
||||
T data = default;
|
||||
Mono.mono_field_get_value((.)instance, scriptField.[Friend]_monoField, &data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void GetData<T>(void* instance, ScriptField scriptField, T* data)
|
||||
{
|
||||
Mono.mono_field_get_value((.)instance, scriptField.[Friend]_monoField, data);
|
||||
}
|
||||
|
||||
void SetData<T>(void* instance, ScriptField scriptField, in T value)
|
||||
{
|
||||
Mono.mono_field_set_value((.)instance, scriptField.[Friend]_monoField, &value);
|
||||
}
|
||||
|
||||
void SetData<T>(void* instance, ScriptField scriptField, T* data)
|
||||
{
|
||||
Mono.mono_field_set_value((.)instance, scriptField.[Friend]_monoField, data);
|
||||
}
|
||||
|
||||
if (scriptComponent.Instance?.IsInitialized == true)
|
||||
{
|
||||
SharpClass sharpClass = scriptComponent.Instance.ScriptClass;
|
||||
ScriptInstance scriptInstance = scriptComponent.Instance;
|
||||
|
||||
/*void DoFunnyStuff(void* instance, SharpType sharpType)
|
||||
{
|
||||
for (let (fieldName, scriptField) in sharpType.Fields)
|
||||
{
|
||||
var monoField = scriptField.[Friend]_monoField;
|
||||
|
||||
switch (scriptField.FieldType)
|
||||
{
|
||||
case .Float:
|
||||
var value = GetData<float>(instance, scriptField);
|
||||
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .Float, &value))
|
||||
SetData(instance, scriptField, value);
|
||||
|
||||
case .Struct:
|
||||
{
|
||||
var v = Mono.mono_field_get_value_object(ScriptEngine.[Friend]s_AppDomain, scriptField.[Friend]_monoField, (.)instance);
|
||||
|
||||
void* dataPtr = Mono.mono_object_unbox(v);
|
||||
|
||||
Span<uint8> data = .((.)dataPtr, scriptField.SizeInBytes);
|
||||
|
||||
if (ImGui.CollapsingHeader(fieldName.Ptr))
|
||||
{
|
||||
DoFunnyStuff(dataPtr, scriptField.SharpType);
|
||||
}
|
||||
|
||||
SetData<MonoObject>(instance, scriptField, v);
|
||||
|
||||
//Mono.mono_field_set_value_object(ScriptEngine.[Friend]s_AppDomain, scriptField.[Friend]_monoField, (.)instance);
|
||||
//uint8* data = ;
|
||||
|
||||
/*uint8[] data = scope .[scriptField.SizeInBytes];
|
||||
|
||||
GetData(instance, scriptField, data.Ptr);
|
||||
|
||||
if (ImGui.CollapsingHeader(fieldName.Ptr))
|
||||
{
|
||||
DoFunnyStuff(data.Ptr, scriptField.SharpType);
|
||||
}
|
||||
|
||||
MonoObject* boxed = Mono.mono_value_box(ScriptEngine.[Friend]s_AppDomain, ((SharpClass)scriptField.SharpType).[Friend]_monoClass, data.Ptr);
|
||||
|
||||
SetData<MonoObject>(instance, scriptField, boxed);*/
|
||||
|
||||
//Mono.mono_field_get_value(instance, scriptField.[Friend]_monoField, data.Ptr);
|
||||
|
||||
}
|
||||
default:
|
||||
//Log.EngineLogger.Error($"Unhandled field type {scriptField.FieldType}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DoFunnyStuff(scriptInstance.[Friend]_instance, sharpClass);*/
|
||||
|
||||
for (let (fieldName, scriptField) in sharpClass.Fields)
|
||||
{
|
||||
var monoField = scriptField.[Friend]_monoField;
|
||||
|
||||
switch (scriptField.FieldType)
|
||||
{
|
||||
case .Bool:
|
||||
var value = GetFieldValue<bool>(scriptInstance, scriptField);
|
||||
if (ImGui.Checkbox(fieldName.ToScopeCStr!(), &value))
|
||||
SetFieldValue(scriptInstance, scriptField, value);
|
||||
|
||||
case .SByte:
|
||||
var value = GetFieldValue<int8>(scriptInstance, scriptField);
|
||||
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .S8, &value))
|
||||
SetFieldValue(scriptInstance, scriptField, value);
|
||||
case .Short:
|
||||
var value = GetFieldValue<int16>(scriptInstance, scriptField);
|
||||
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .S16, &value))
|
||||
SetFieldValue(scriptInstance, scriptField, value);
|
||||
case .Int:
|
||||
var value = GetFieldValue<int32>(scriptInstance, scriptField);
|
||||
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .S32, &value))
|
||||
SetFieldValue(scriptInstance, scriptField, value);
|
||||
case .Long:
|
||||
var value = GetFieldValue<int64>(scriptInstance, scriptField);
|
||||
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .S64, &value))
|
||||
SetFieldValue(scriptInstance, scriptField, value);
|
||||
|
||||
case .Byte:
|
||||
var value = GetFieldValue<uint8>(scriptInstance, scriptField);
|
||||
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .U8, &value))
|
||||
SetFieldValue(scriptInstance, scriptField, value);
|
||||
case .UShort:
|
||||
var value = GetFieldValue<uint16>(scriptInstance, scriptField);
|
||||
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .U16, &value))
|
||||
SetFieldValue(scriptInstance, scriptField, value);
|
||||
case .UInt:
|
||||
var value = GetFieldValue<uint32>(scriptInstance, scriptField);
|
||||
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .U32, &value))
|
||||
SetFieldValue(scriptInstance, scriptField, value);
|
||||
case .ULong:
|
||||
var value = GetFieldValue<uint64>(scriptInstance, scriptField);
|
||||
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .U64, &value))
|
||||
SetFieldValue(scriptInstance, scriptField, value);
|
||||
|
||||
case .Float:
|
||||
var value = GetFieldValue<float>(scriptInstance, scriptField);
|
||||
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .Float, &value))
|
||||
SetFieldValue(scriptInstance, scriptField, value);
|
||||
|
||||
case .float2:
|
||||
GetFieldValue<float2>(scriptInstance, scriptField, var value);
|
||||
if (ImGui.Editfloat2(fieldName, ref value))
|
||||
SetFieldValue(scriptInstance, scriptField, value);
|
||||
case .float3:
|
||||
GetFieldValue<float3>(scriptInstance, scriptField, var value);
|
||||
if (ImGui.Editfloat3(fieldName, ref value))
|
||||
SetFieldValue(scriptInstance, scriptField, value);
|
||||
case .float4:
|
||||
GetFieldValue<float4>(scriptInstance, scriptField, var value);
|
||||
if (ImGui.Editfloat4(fieldName, ref value))
|
||||
SetFieldValue(scriptInstance, scriptField, value);
|
||||
|
||||
case .Double:
|
||||
var value = GetFieldValue<double>(scriptInstance, scriptField);
|
||||
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .Double, &value))
|
||||
SetFieldValue(scriptInstance, scriptField, value);
|
||||
|
||||
case .Entity:
|
||||
// TODO!
|
||||
|
||||
case .Enum:
|
||||
// TODO!
|
||||
case .Struct:
|
||||
// TODO!
|
||||
/*{
|
||||
uint8[] data = scope .[scriptField.SizeInBytes];
|
||||
|
||||
Mono.mono_field_get_value(scriptInstance.[Friend]_instance, scriptField.[Friend]_monoField, data.Ptr);
|
||||
|
||||
//scriptField.
|
||||
|
||||
//scriptInstance.GetFieldValue();
|
||||
|
||||
//scriptInstance.ScriptClass.Fields[]
|
||||
/*
|
||||
var value = GetFieldValue<double>(scriptInstance, scriptField);
|
||||
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .Double, &value))
|
||||
SetFieldValue(scriptInstance, scriptField, value);
|
||||
*/
|
||||
}*/
|
||||
default:
|
||||
Log.EngineLogger.Error($"Unhandled field type {scriptField.FieldType}");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (scriptClass != null)
|
||||
{
|
||||
let scriptFields = ScriptEngine.GetScriptFieldMap(entity);
|
||||
|
||||
for (var (fieldName, field) in ref scriptFields)
|
||||
{
|
||||
switch (field.Type)
|
||||
{
|
||||
case .Bool:
|
||||
var value = field.GetData<bool>();
|
||||
if (ImGui.Checkbox(fieldName.CStr(), &value))
|
||||
field.SetData(value);
|
||||
|
||||
case .SByte:
|
||||
var value = field.GetData<int8>();
|
||||
if (ImGui.DragScalar(fieldName.CStr(), .S8, &value))
|
||||
field.SetData(value);
|
||||
case .Short:
|
||||
var value = field.GetData<int16>();
|
||||
if (ImGui.DragScalar(fieldName.CStr(), .S16, &value))
|
||||
field.SetData(value);
|
||||
case .Int:
|
||||
var value = field.GetData<int32>();
|
||||
if (ImGui.DragScalar(fieldName.CStr(), .S32, &value))
|
||||
field.SetData(value);
|
||||
case .Int2:
|
||||
var value = field.GetData<int2>();
|
||||
if (ImGui.DragScalarN(fieldName.CStr(), .S32, &value, 2))
|
||||
field.SetData(value);
|
||||
case .Int3:
|
||||
var value = field.GetData<int3>();
|
||||
if (ImGui.DragScalarN(fieldName.CStr(), .S32, &value, 3))
|
||||
field.SetData(value);
|
||||
case .Int4:
|
||||
var value = field.GetData<int4>();
|
||||
if (ImGui.DragScalarN(fieldName.CStr(), .S32, &value, 4))
|
||||
field.SetData(value);
|
||||
case .Long:
|
||||
var value = field.GetData<int64>();
|
||||
if (ImGui.DragScalar(fieldName.CStr(), .S64, &value))
|
||||
field.SetData(value);
|
||||
|
||||
case .Byte:
|
||||
var value = field.GetData<uint8>();
|
||||
if (ImGui.DragScalar(fieldName.CStr(), .U8, &value))
|
||||
field.SetData(value);
|
||||
case .UShort:
|
||||
var value = field.GetData<uint16>();
|
||||
if (ImGui.DragScalar(fieldName.CStr(), .U16, &value))
|
||||
field.SetData(value);
|
||||
case .UInt:
|
||||
var value = field.GetData<uint32>();
|
||||
if (ImGui.DragScalar(fieldName.CStr(), .U32, &value))
|
||||
field.SetData(value);
|
||||
case .ULong:
|
||||
var value = field.GetData<uint64>();
|
||||
if (ImGui.DragScalar(fieldName.CStr(), .U64, &value))
|
||||
field.SetData(value);
|
||||
|
||||
case .Float:
|
||||
var value = field.GetData<float>();
|
||||
if (ImGui.DragScalar(fieldName.CStr(), .Float, &value))
|
||||
field.SetData(value);
|
||||
case .float2:
|
||||
var value = field.GetData<float2>();
|
||||
if (ImGui.Editfloat2(fieldName, ref value))
|
||||
field.SetData(value);
|
||||
case .float3:
|
||||
var value = field.GetData<float3>();
|
||||
if (ImGui.Editfloat3(fieldName, ref value))
|
||||
field.SetData(value);
|
||||
case .float4:
|
||||
var value = field.GetData<float4>();
|
||||
if (ImGui.Editfloat4(fieldName, ref value))
|
||||
field.SetData(value);
|
||||
|
||||
case .Double:
|
||||
var value = field.GetData<double>();
|
||||
if (ImGui.DragScalar(fieldName.CStr(), .Double, &value))
|
||||
field.SetData(value);
|
||||
case .Double2:
|
||||
var value = field.GetData<double2>();
|
||||
if (ImGui.DragScalarN(fieldName.CStr(), .Double, &value, 2))
|
||||
field.SetData(value);
|
||||
case .Double3:
|
||||
var value = field.GetData<double3>();
|
||||
if (ImGui.DragScalarN(fieldName.CStr(), .Double, &value, 3))
|
||||
field.SetData(value);
|
||||
case .Double4:
|
||||
var value = field.GetData<double4>();
|
||||
if (ImGui.DragScalarN(fieldName.CStr(), .Double, &value, 4))
|
||||
field.SetData(value);
|
||||
|
||||
case .Enum:
|
||||
ShowEnumSelector(field, fieldName, scriptClass);
|
||||
//case .String:
|
||||
// TODO!
|
||||
|
||||
case .Entity:
|
||||
ShowEntityReceiver(field, fieldName, scriptClass);
|
||||
case .Component:
|
||||
ShowComponentReceiver(field, fieldName, scriptClass);
|
||||
|
||||
case .Struct:
|
||||
// TODO!
|
||||
|
||||
case .Class:
|
||||
// We don't support editing classes
|
||||
|
||||
default:
|
||||
Log.EngineLogger.Error($"Unhandled field type {field.Type}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ShowEnumSelector(ScriptFieldInstance* field, StringView fieldName, ScriptClass scriptClass)
|
||||
{
|
||||
ScriptField scriptField = scriptClass.Fields[fieldName];
|
||||
SharpEnum enumType = scriptField.SharpType as SharpEnum;
|
||||
|
||||
Log.EngineLogger.Assert(enumType != null, "Enum must have a SharpEnum!");
|
||||
|
||||
// Simply get Enum as a uint64
|
||||
var fieldValue = field.GetData<uint64>();
|
||||
|
||||
StringView valueName = "<Invalid Value>";
|
||||
|
||||
if (enumType.Values.TryGetValue(fieldValue, let enumValue))
|
||||
valueName = enumValue.Name;
|
||||
|
||||
if (ImGui.BeginCombo(fieldName.Ptr, valueName.Ptr))
|
||||
{
|
||||
for (let (entryValue, enumEntry) in enumType.Values)
|
||||
{
|
||||
if (ImGui.Selectable(enumEntry.Name.Ptr, fieldValue == entryValue))
|
||||
field.SetData(entryValue);
|
||||
}
|
||||
|
||||
ImGui.EndCombo();
|
||||
}
|
||||
}
|
||||
|
||||
private static Entity? ShowEntitySelector()
|
||||
{
|
||||
static char8[128] entitySearch = .();
|
||||
|
||||
Entity? result = null;
|
||||
|
||||
if (ImGui.BeginPopup("ENTITY_SELECTOR"))
|
||||
{
|
||||
ImGui.TextUnformatted("Search:");
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.InputText("##entitySearcher", &entitySearch, (uint64)entitySearch.Count))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void ShowEntityReceiver(ScriptFieldInstance* field, StringView fieldName, ScriptClass scriptClass)
|
||||
{
|
||||
var entityId = field.GetData<UUID>();
|
||||
|
||||
Result<Entity> fieldEntity = Editor.Instance.CurrentScene.GetEntityByID(entityId);
|
||||
|
||||
String entityName = scope .(32);
|
||||
|
||||
if (entityId == UUID(0))
|
||||
entityName.Set("None");
|
||||
else if (fieldEntity case .Ok(Entity e))
|
||||
entityName.Set(e.Name);
|
||||
else
|
||||
entityName..Clear().AppendF($"Missing entity ({entityId})");
|
||||
|
||||
ImGui.Text($"{fieldName}: ");
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.Button(entityName))
|
||||
{
|
||||
if (fieldEntity case .Ok)
|
||||
Editor.Instance.EntityHierarchyWindow.HighlightEntity(fieldEntity);
|
||||
}
|
||||
|
||||
if (ImGui.BeginDragDropTarget())
|
||||
{
|
||||
ImGui.Payload* peekPayload = ImGui.AcceptDragDropPayload(.Entity, .AcceptPeekOnly);
|
||||
|
||||
bool allowDrop = false;
|
||||
|
||||
if (peekPayload != null)
|
||||
{
|
||||
Entity draggedEntity = *(Entity*)peekPayload.Data;
|
||||
|
||||
ScriptClass draggedScriptClass = ScriptEngine.[Friend]s_EntityRoot;
|
||||
|
||||
if (draggedEntity.TryGetComponent<ScriptComponent>(let draggedScript))
|
||||
{
|
||||
var draggedClassName = draggedScript.ScriptClassName;
|
||||
draggedScriptClass = ScriptEngine.GetScriptClass(draggedClassName);
|
||||
|
||||
}
|
||||
|
||||
// TODO: I don't like the fact, that we are using mono directly
|
||||
|
||||
ScriptField scriptField = scriptClass.Fields[fieldName];
|
||||
var fieldMonoClass = Mono.mono_type_get_class(scriptField.GetMonoType());
|
||||
|
||||
allowDrop = draggedScriptClass.[Friend]IsSubclass(fieldMonoClass);
|
||||
}
|
||||
|
||||
if (allowDrop)
|
||||
{
|
||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.Entity);
|
||||
|
||||
if (payload != null)
|
||||
{
|
||||
Log.EngineLogger.AssertDebug(payload.DataSize == sizeof(Entity));
|
||||
|
||||
Entity droppedEntity = *(Entity*)payload.Data;
|
||||
|
||||
if (droppedEntity.IsValid)
|
||||
field.SetData<UUID>(droppedEntity.UUID);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndDragDropTarget();
|
||||
}
|
||||
}
|
||||
|
||||
//private static Entity?
|
||||
|
||||
private static void ShowComponentReceiver(ScriptFieldInstance* field, StringView fieldName, ScriptClass scriptClass)
|
||||
{
|
||||
var entityId = field.GetData<UUID>();
|
||||
|
||||
Result<Entity> fieldEntity = Editor.Instance.CurrentScene.GetEntityByID(entityId);
|
||||
|
||||
String entityName = scope .(32);
|
||||
|
||||
if (entityId == UUID(0))
|
||||
entityName.Set("None");
|
||||
else if (fieldEntity case .Ok(Entity e))
|
||||
entityName.Set(e.Name);
|
||||
else
|
||||
entityName..Clear().AppendF($"Missing reference ({entityId})");
|
||||
|
||||
ImGui.Text($"{fieldName}: ");
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.Button(entityName))
|
||||
{
|
||||
if (fieldEntity case .Ok)
|
||||
Editor.Instance.EntityHierarchyWindow.HighlightEntity(fieldEntity);
|
||||
}
|
||||
|
||||
if (ImGui.BeginDragDropTarget())
|
||||
{
|
||||
ImGui.Payload* peekPayload = ImGui.AcceptDragDropPayload(.Entity, .AcceptPeekOnly);
|
||||
|
||||
bool allowDrop = false;
|
||||
|
||||
if (peekPayload != null)
|
||||
{
|
||||
Entity draggedEntity = *(Entity*)peekPayload.Data;
|
||||
|
||||
// TODO: I don't like the fact, that we are using mono directly
|
||||
|
||||
ScriptField scriptField = scriptClass.Fields[fieldName];
|
||||
|
||||
// For some reason we have to retrieve the MonoType like this. Using scriptField.GetMonoType() directly returns the wrong type...
|
||||
MonoReflectionType* reflectionType = Mono.mono_type_get_object(ScriptEngine.[Friend]s_AppDomain, scriptField.GetMonoType());
|
||||
MonoType* actualMonoType = Mono.mono_reflection_type_get_type(reflectionType);
|
||||
|
||||
// TODO: We shouldn't abuse the script glue like that.
|
||||
// ScriptGlue should only be called by C#, not by Beef.
|
||||
if (ScriptGlue.[Friend]s_HasComponentMethods.TryGetValue(actualMonoType, let has_component))
|
||||
{
|
||||
allowDrop = has_component(draggedEntity);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.EngineLogger.Warning($"No HasComponent-Function found for field {scriptField.Name}");
|
||||
allowDrop = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (allowDrop)
|
||||
{
|
||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.Entity);
|
||||
|
||||
if (payload != null)
|
||||
{
|
||||
Log.EngineLogger.AssertDebug(payload.DataSize == sizeof(Entity));
|
||||
|
||||
Entity droppedEntity = *(Entity*)payload.Data;
|
||||
|
||||
if (droppedEntity.IsValid)
|
||||
field.SetData<UUID>(droppedEntity.UUID);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndDragDropTarget();
|
||||
}
|
||||
}
|
||||
|
||||
private static void LabelColumn(StringView label)
|
||||
{
|
||||
ImGui.TextUnformatted(label);
|
||||
@@ -493,7 +1069,7 @@ namespace GlitchyEditor.EditWindows
|
||||
|
||||
if (ImGui.BeginDragDropTarget())
|
||||
{
|
||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
||||
|
||||
if (payload != null)
|
||||
{
|
||||
@@ -584,6 +1160,7 @@ namespace GlitchyEditor.EditWindows
|
||||
ShowComponentButton<CircleCollider2DComponent>("Circle collider 2D");
|
||||
ShowComponentButton<MeshComponent>("Mesh");
|
||||
ShowComponentButton<MeshRendererComponent>("Mesh Renderer");
|
||||
ShowComponentButton<ScriptComponent>("C# Script");
|
||||
|
||||
ImGui.EndCombo();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using ImGui;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using GlitchyEngine.Collections;
|
||||
using System.Collections;
|
||||
using GlitchyEngine.Renderer;
|
||||
@@ -12,8 +13,35 @@ namespace GlitchyEditor.EditWindows
|
||||
{
|
||||
using internal GlitchyEditor.EditorContentManager;
|
||||
|
||||
class AssetCreator
|
||||
{
|
||||
private String _name ~ delete _;
|
||||
private String _defaultFileName ~ delete _;
|
||||
private CreateAssetFunc _doCreateAsset ~ delete _;
|
||||
|
||||
public delegate void CreateAssetFunc(StringView outputPath);
|
||||
|
||||
public StringView Name => _name;
|
||||
public StringView DefaultFileName => _defaultFileName;
|
||||
|
||||
public CreateAssetFunc CreateAsset => _doCreateAsset;
|
||||
|
||||
public this(StringView name, StringView defaultFileName, CreateAssetFunc createAsset)
|
||||
{
|
||||
_name = new String(name);
|
||||
_defaultFileName = new String(defaultFileName);
|
||||
_doCreateAsset = createAsset;
|
||||
}
|
||||
}
|
||||
|
||||
class ContentBrowserWindow : EditorWindow
|
||||
{
|
||||
private append List<AssetCreator> _assetCreators = .() ~ ClearAndDeleteItems!(_);
|
||||
|
||||
private typealias AssetCreatorTree = TreeNode<(StringView Name, AssetCreator Creator)>;
|
||||
|
||||
private AssetCreatorTree _creatorTree = new AssetCreatorTree(("Create new Asset", null)) ~ delete _;
|
||||
|
||||
public const String s_WindowTitle = "Content Browser";
|
||||
|
||||
private append String _currentDirectory = .();
|
||||
@@ -32,6 +60,28 @@ namespace GlitchyEditor.EditWindows
|
||||
_manager = contentManager;
|
||||
}
|
||||
|
||||
public void RegisterAssetCreator(AssetCreator assetCreator)
|
||||
{
|
||||
_assetCreators.Add(assetCreator);
|
||||
|
||||
AssetCreatorTree tree = _creatorTree;
|
||||
|
||||
for (StringView entryName in assetCreator.Name.Split('/'))
|
||||
{
|
||||
AssetCreatorTree nextNode = tree.Children.Where(scope (node) => node->Name == entryName).FirstOrDefault();
|
||||
|
||||
// Create new node if we didn't find it
|
||||
nextNode ??= tree.AddChild((entryName, null));
|
||||
|
||||
tree = nextNode;
|
||||
}
|
||||
|
||||
if (tree->Creator == null)
|
||||
{
|
||||
tree->Creator = assetCreator;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void InternalShow()
|
||||
{
|
||||
_manager.Update();
|
||||
@@ -39,7 +89,7 @@ namespace GlitchyEditor.EditWindows
|
||||
// Make sure we are in an existing directory.
|
||||
if (!_manager.AssetHierarchy.FileExists(_currentDirectory))
|
||||
{
|
||||
_currentDirectory.Set(_manager.ContentDirectory);
|
||||
_currentDirectory.Set(_manager.AssetDirectory);
|
||||
}
|
||||
|
||||
if(!ImGui.Begin(s_WindowTitle, &_open, .None))
|
||||
@@ -48,34 +98,70 @@ namespace GlitchyEditor.EditWindows
|
||||
return;
|
||||
}
|
||||
|
||||
// Context menu when clicking on the background.
|
||||
if (ImGui.BeginPopupContextWindow())
|
||||
ImGui.PushStyleVar(.CellPadding, .(0, 0));
|
||||
|
||||
bool alt_pressed = ImGui.GetIO().KeyAlt;
|
||||
|
||||
if (ImGui.BeginTable("table", 2, .BordersInnerV | .Resizable | .Reorderable | .NoPadOuterX))
|
||||
{
|
||||
ShowCurrentFolderContextMenu();
|
||||
ImGui.EndPopup();
|
||||
if (alt_pressed)
|
||||
{
|
||||
// Header anzeigen, damit sie neu angeordnet werden können
|
||||
ImGui.TableSetupColumn("Folder Hierarchy");
|
||||
ImGui.TableSetupColumn("Files");
|
||||
ImGui.TableHeadersRow();
|
||||
}
|
||||
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableSetColumnIndex(0);
|
||||
|
||||
if (ImGui.BeginChild("Sidebar"))
|
||||
{
|
||||
DrawDirectorySideBar();
|
||||
|
||||
ImGui.EndChild();
|
||||
}
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
|
||||
DrawSearchBar();
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
if (ImGui.BeginChild("Files"))
|
||||
{
|
||||
DrawCurrentDirectory();
|
||||
|
||||
// Context menu when clicking on the background.
|
||||
if (ImGui.BeginPopupContextWindow())
|
||||
{
|
||||
ShowCurrentFolderContextMenu();
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
ImGui.EndChild();
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
ImGui.Columns(2);
|
||||
|
||||
ImGui.BeginChild("Sidebar");
|
||||
|
||||
DrawDirectorySideBar();
|
||||
|
||||
ImGui.EndChild();
|
||||
|
||||
ImGui.NextColumn();
|
||||
|
||||
ImGui.BeginChild("Files");
|
||||
|
||||
DrawCurrentDirectory();
|
||||
|
||||
ImGui.EndChild();
|
||||
|
||||
ImGui.Columns(1);
|
||||
ImGui.PopStyleVar(1);
|
||||
|
||||
ImGui.End();
|
||||
}
|
||||
|
||||
char8[256] _filesFilter = .();
|
||||
bool _searchEverywhere;
|
||||
|
||||
private void DrawSearchBar()
|
||||
{
|
||||
ImGui.TextUnformatted("Search:");
|
||||
ImGui.SameLine();
|
||||
ImGui.InputText("##search", &_filesFilter, _filesFilter.Count);
|
||||
ImGui.SameLine();
|
||||
ImGui.Checkbox("Search everywhere", &_searchEverywhere);
|
||||
}
|
||||
|
||||
/// Renders the context menu that is shown when the user right clicks on the background of the file browser.
|
||||
private void ShowCurrentFolderContextMenu()
|
||||
{
|
||||
@@ -84,12 +170,69 @@ namespace GlitchyEditor.EditWindows
|
||||
if (Path.OpenFolder(_currentDirectory) case .Err)
|
||||
Log.EngineLogger.Error("Failed to open directory in file browser.");
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
ShowCreateContextMenu(_creatorTree);
|
||||
}
|
||||
|
||||
/// Shows the menu for the given asset creator tree.
|
||||
private void ShowCreateContextMenu(AssetCreatorTree subtree)
|
||||
{
|
||||
if (subtree.Children.Count == 0)
|
||||
{
|
||||
if (ImGui.MenuItem(subtree->Name.ToScopeCStr!()))
|
||||
{
|
||||
CreateAsset(subtree->Creator);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ImGui.BeginMenu(subtree->Name.ToScopeCStr!()))
|
||||
{
|
||||
for (let node in subtree.Children)
|
||||
{
|
||||
ShowCreateContextMenu(node);
|
||||
}
|
||||
|
||||
ImGui.EndMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new asset with the given creator
|
||||
private void CreateAsset(AssetCreator creator)
|
||||
{
|
||||
if (!Directory.Exists(_currentDirectory))
|
||||
{
|
||||
Log.EngineLogger.Error($"Directory {_currentDirectory} doesn't exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
String currentFile = scope String();
|
||||
Path.Combine(currentFile, _currentDirectory, creator.DefaultFileName);
|
||||
|
||||
String fileExtension = scope String();
|
||||
Path.GetExtension(currentFile, fileExtension);
|
||||
|
||||
StringView fileWithoutExtension = currentFile[0...^(fileExtension.Length + 1)];
|
||||
|
||||
int i = 0;
|
||||
while (File.Exists(currentFile))
|
||||
{
|
||||
i++;
|
||||
currentFile.Set(fileWithoutExtension);
|
||||
currentFile.AppendF($"({i})");
|
||||
currentFile.Append(fileExtension);
|
||||
}
|
||||
|
||||
creator.CreateAsset(currentFile);
|
||||
}
|
||||
|
||||
/// Renders a sidebar that shows a tree of all directories in the asset folder.
|
||||
private void DrawDirectorySideBar()
|
||||
{
|
||||
for(var child in _manager.AssetHierarchy.[Friend]_assetHierarchy.Children)
|
||||
for(var child in _manager.AssetHierarchy.RootNode.Children)
|
||||
{
|
||||
ImGuiPrintEntityTree(child);
|
||||
}
|
||||
@@ -106,17 +249,22 @@ namespace GlitchyEditor.EditWindows
|
||||
|
||||
ImGui.TreeNodeFlags flags = .OpenOnArrow | .SpanAvailWidth;
|
||||
|
||||
if(tree.Children.Count == 0)
|
||||
if(tree.Children.Where(scope (node) => node->IsDirectory).Count() == 0)
|
||||
flags |= .Leaf;
|
||||
|
||||
if (tree->Path == _currentDirectory)
|
||||
{
|
||||
flags |= .Selected;
|
||||
}
|
||||
|
||||
// TODO: this kinda works, but the user should be able to close the directory
|
||||
/*if (_manager.AssetHierarchy.GetNodeFromPath(_currentDirectory) case .Ok(let currentTreeNode))
|
||||
{
|
||||
if (currentTreeNode.IsInSubtree(tree))
|
||||
ImGui.SetNextItemOpen(true);
|
||||
}*/
|
||||
|
||||
bool isOpen = ImGui.TreeNodeEx(name, flags, $"{name}");
|
||||
|
||||
if (ImGui.IsItemClicked(.Left))
|
||||
if (!ImGui.IsItemToggledOpen() && ImGui.IsItemClicked(.Left))
|
||||
{
|
||||
_currentDirectory.Set(tree->Path);
|
||||
}
|
||||
@@ -132,50 +280,74 @@ namespace GlitchyEditor.EditWindows
|
||||
}
|
||||
}
|
||||
|
||||
private static Vector2 DirectoryItemSize = .(110, 110);
|
||||
private static float2 DirectoryItemSize = .(110, 110);
|
||||
|
||||
const Vector2 padding = .(24, 24);
|
||||
const float2 padding = .(24, 24);
|
||||
|
||||
/// Renders the contents of _currentDirectory.
|
||||
private void DrawCurrentDirectory()
|
||||
{
|
||||
if (_currentDirectory.IsEmpty)
|
||||
return;
|
||||
List<TreeNode<AssetNode>> files = null;
|
||||
|
||||
ImGui.Style* style = ImGui.GetStyle();
|
||||
|
||||
float window_visible_x2 = ImGui.GetWindowPos().x + ImGui.GetWindowContentRegionMax().x;
|
||||
|
||||
// Get the node of the current directory.
|
||||
var currentDirectoryNode = _manager.AssetHierarchy.GetNodeFromPath(_currentDirectory);
|
||||
StringView searchFilter = StringView(&_filesFilter);
|
||||
|
||||
if (currentDirectoryNode case .Err)
|
||||
if (_searchEverywhere && searchFilter.Length > 0)
|
||||
{
|
||||
Log.EngineLogger.Error($"No node exists for {_currentDirectory}.");
|
||||
ImGui.TextUnformatted("Failed to display contents of directory.");
|
||||
return;
|
||||
files = scope:: List<TreeNode<AssetNode>>();
|
||||
_manager.AssetHierarchy.[Friend]_assetRootNode.ForEach(scope (node) =>
|
||||
{
|
||||
if (node->Name.Contains(searchFilter, true))
|
||||
{
|
||||
files.Add(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_currentDirectory.IsEmpty)
|
||||
return;
|
||||
|
||||
// Get the node of the current directory.
|
||||
var currentDirectoryNode = _manager.AssetHierarchy.GetNodeFromPath(_currentDirectory);
|
||||
|
||||
if (currentDirectoryNode case .Err)
|
||||
{
|
||||
Log.EngineLogger.Error($"No node exists for {_currentDirectory}.");
|
||||
ImGui.TextUnformatted("Failed to display contents of directory.");
|
||||
return;
|
||||
}
|
||||
|
||||
files = currentDirectoryNode->Children;
|
||||
|
||||
// show back button (".."-File)
|
||||
if (currentDirectoryNode->Parent != null)
|
||||
{
|
||||
ImGui.PushID("Back");
|
||||
|
||||
DrawBackButton(currentDirectoryNode->Parent);
|
||||
|
||||
// X-Coordinate of the right side of the current entry.
|
||||
float currentButtonRight = ImGui.GetItemRectMax().x;
|
||||
// Expected right-Coordinate if next entry was on the same line.
|
||||
float expectedButtonRight = currentButtonRight + style.ItemSpacing.x + DirectoryItemSize.X;
|
||||
|
||||
// If the next button won't fit on the same line we start a new line.
|
||||
if (expectedButtonRight < window_visible_x2)
|
||||
ImGui.SameLine();
|
||||
|
||||
ImGui.PopID();
|
||||
}
|
||||
}
|
||||
|
||||
if (currentDirectoryNode->Parent != null)
|
||||
for (var entry in files)
|
||||
{
|
||||
ImGui.PushID("Back");
|
||||
if (!entry->Name.Contains(searchFilter, true))
|
||||
continue;
|
||||
|
||||
DrawBackButton(currentDirectoryNode->Parent);
|
||||
|
||||
// X-Coordinate of the right side of the current entry.
|
||||
float currentButtonRight = ImGui.GetItemRectMax().x;
|
||||
// Expected right-Coordinate if next entry was on the same line.
|
||||
float expectedButtonRight = currentButtonRight + style.ItemSpacing.x + DirectoryItemSize.X;
|
||||
|
||||
// If the next button won't fit on the same line we start a new line.
|
||||
if (expectedButtonRight < window_visible_x2)
|
||||
ImGui.SameLine();
|
||||
|
||||
ImGui.PopID();
|
||||
}
|
||||
|
||||
for (var entry in currentDirectoryNode->Children)
|
||||
{
|
||||
ImGui.PushID(entry->Name);
|
||||
|
||||
DrawDirectoryItem(entry);
|
||||
@@ -186,17 +358,30 @@ namespace GlitchyEditor.EditWindows
|
||||
float expectedButtonRight = currentButtonRight + style.ItemSpacing.x + DirectoryItemSize.X;
|
||||
|
||||
// If we aren't the last entry and the next button won't fit on the same line we start a new line.
|
||||
if (entry != currentDirectoryNode->Children.Back && expectedButtonRight < window_visible_x2)
|
||||
if (entry != files.Back && expectedButtonRight < window_visible_x2)
|
||||
ImGui.SameLine();
|
||||
|
||||
ImGui.PopID();
|
||||
}
|
||||
}
|
||||
|
||||
float _zoom = 1.0f;
|
||||
static readonly float2 IconBaseSize = .(100, 100);
|
||||
|
||||
float2 IconSize => IconBaseSize * _zoom;
|
||||
|
||||
/// Renders the button for the given directory item.
|
||||
private void DrawBackButton(TreeNode<AssetNode> entry)
|
||||
{
|
||||
ImGui.BeginChild("item", (.)DirectoryItemSize);
|
||||
ImGui.PushStyleVar(.WindowPadding, .(0, 0));
|
||||
ImGui.PushStyleVar(.FramePadding, .(0, 0));
|
||||
ImGui.PushStyleVar(.ItemSpacing, .(0, 0));
|
||||
|
||||
defer {ImGui.PopStyleVar(3); }
|
||||
|
||||
float2 DirectoryItemSize = IconSize + (float2)ImGui.GetStyle().WindowPadding * 2 + float2(0, ImGui.GetFontSize());
|
||||
|
||||
ImGui.BeginChild("item", (.)DirectoryItemSize, false, .NoScrollbar);
|
||||
|
||||
if (entry->Path == _selectedFile)
|
||||
{
|
||||
@@ -210,7 +395,7 @@ namespace GlitchyEditor.EditWindows
|
||||
|
||||
SubTexture2D image = s_FolderTexture;
|
||||
|
||||
ImGui.ImageButton(image, (.)(DirectoryItemSize - padding));
|
||||
ImGui.ImageButton("BackFolder", image, (.)IconSize);
|
||||
|
||||
ImGui.PopStyleColor();
|
||||
|
||||
@@ -235,7 +420,15 @@ namespace GlitchyEditor.EditWindows
|
||||
/// Renders the button for the given directory item.
|
||||
private void DrawDirectoryItem(TreeNode<AssetNode> entry)
|
||||
{
|
||||
ImGui.BeginChild("item", (.)DirectoryItemSize);
|
||||
ImGui.PushStyleVar(.WindowPadding, .(0, 0));
|
||||
ImGui.PushStyleVar(.FramePadding, .(0, 0));
|
||||
ImGui.PushStyleVar(.ItemSpacing, .(0, 0));
|
||||
|
||||
defer {ImGui.PopStyleVar(3); }
|
||||
|
||||
float2 DirectoryItemSize = IconSize + (float2)ImGui.GetStyle().WindowPadding * 2 + float2(0, ImGui.GetFontSize());
|
||||
|
||||
ImGui.BeginChild("item", (.)DirectoryItemSize, false, .NoScrollbar);
|
||||
|
||||
if (entry->Path == _selectedFile)
|
||||
{
|
||||
@@ -250,21 +443,13 @@ namespace GlitchyEditor.EditWindows
|
||||
// TODO: preview images
|
||||
SubTexture2D image = entry->IsDirectory ? s_FolderTexture : s_FileTexture;
|
||||
|
||||
ImGui.ImageButton(image, (.)(DirectoryItemSize - padding));
|
||||
ImGui.ImageButton("FileImage", image, (.)IconSize);
|
||||
|
||||
ImGui.PopStyleColor();
|
||||
|
||||
if (ImGui.BeginDragDropSource())
|
||||
{
|
||||
String fullpath = scope String(entry->Path);
|
||||
|
||||
// TODO: this is dirty
|
||||
if (fullpath.StartsWith(_manager.ContentDirectory, .OrdinalIgnoreCase))
|
||||
fullpath.Remove(0, _manager.ContentDirectory.Length);
|
||||
|
||||
Path.Fixup(fullpath);
|
||||
|
||||
ImGui.SetDragDropPayload("CONTENT_BROWSER_ITEM", fullpath.CStr(), (.)fullpath.Length, .Once);
|
||||
ImGui.SetDragDropPayload(.ContentBrowserItem, entry->Identifier, (uint64)entry->Identifier.Length, .Once);
|
||||
|
||||
ImGui.EndDragDropSource();
|
||||
}
|
||||
@@ -290,6 +475,7 @@ namespace GlitchyEditor.EditWindows
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
// TODO: Sub assets are probably borked now... I don't know if they ever worked, didn't test them
|
||||
if (entry->SubAssets?.Count > 0)
|
||||
{
|
||||
// Button for revealing sub assets (e.g. Meshes in 3D-Model)
|
||||
@@ -310,7 +496,7 @@ namespace GlitchyEditor.EditWindows
|
||||
String fullpath = scope String(entry->Path);
|
||||
fullpath.AppendF($"#{subAsset.Name}");
|
||||
|
||||
ImGui.SetDragDropPayload("CONTENT_BROWSER_ITEM", fullpath.CStr(), (.)fullpath.Length, .Once);
|
||||
ImGui.SetDragDropPayload(.ContentBrowserItem, fullpath.CStr(), (.)fullpath.Length, .Once);
|
||||
|
||||
ImGui.EndDragDropSource();
|
||||
}
|
||||
@@ -322,6 +508,8 @@ namespace GlitchyEditor.EditWindows
|
||||
DeleteItemPopup(entry);
|
||||
|
||||
ImGui.EndChild();
|
||||
|
||||
ImGui.AttachTooltip(entry->Name);
|
||||
}
|
||||
|
||||
private void DeleteItemPopup(TreeNode<AssetNode> fileOrFolder)
|
||||
|
||||
@@ -32,9 +32,9 @@ namespace GlitchyEditor.EditWindows
|
||||
public uint32 SelectedEntityId {get; private set; }
|
||||
public bool SelectionChanged { get; private set; }
|
||||
|
||||
public Vector2 ViewportSize => (Vector2)_oldViewportSize;
|
||||
public float2 ViewportSize => (float2)_oldViewportSize;
|
||||
// Occurs when the viewport is resized.
|
||||
public Event<EventHandler<Vector2>> ViewportSizeChanged ~ _.Dispose();
|
||||
public Event<EventHandler<float2>> ViewportSizeChanged ~ _.Dispose();
|
||||
// Occurs when an entity was clicked.
|
||||
public Event<EventHandler<uint32>> EntityClicked ~ _.Dispose();
|
||||
|
||||
@@ -126,7 +126,7 @@ namespace GlitchyEditor.EditWindows
|
||||
|
||||
if(_oldViewportSize != viewportSize)
|
||||
{
|
||||
ViewportSizeChanged.Invoke(this, (Vector2)viewportSize);
|
||||
ViewportSizeChanged.Invoke(this, (float2)viewportSize);
|
||||
_viewPortChanged = true;
|
||||
_oldViewportSize = viewportSize;
|
||||
}
|
||||
@@ -137,7 +137,7 @@ namespace GlitchyEditor.EditWindows
|
||||
{
|
||||
if (ImGui.BeginDragDropTarget())
|
||||
{
|
||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem);
|
||||
|
||||
if (payload != null)
|
||||
{
|
||||
@@ -154,14 +154,14 @@ namespace GlitchyEditor.EditWindows
|
||||
{
|
||||
_wrappedCursor = false;
|
||||
|
||||
let mousePos = (Vector2)ImGui.GetMousePos();
|
||||
let winPos = (Vector2)ImGui.GetWindowPos();
|
||||
let regionMin = winPos + (Vector2)ImGui.GetWindowContentRegionMin();
|
||||
let regionMax = winPos + (Vector2)ImGui.GetWindowContentRegionMax();
|
||||
let mousePos = (float2)ImGui.GetMousePos();
|
||||
let winPos = (float2)ImGui.GetWindowPos();
|
||||
let regionMin = winPos + (float2)ImGui.GetWindowContentRegionMin();
|
||||
let regionMax = winPos + (float2)ImGui.GetWindowContentRegionMax();
|
||||
|
||||
ImGui.DrawRect((.)regionMin, (.)regionMax, .(0, 255, 0));
|
||||
|
||||
Vector2 newMousePos = mousePos;
|
||||
float2 newMousePos = mousePos;
|
||||
|
||||
if (mousePos.X < regionMin.X + 1)
|
||||
{
|
||||
@@ -181,9 +181,9 @@ namespace GlitchyEditor.EditWindows
|
||||
newMousePos.Y = regionMin.Y + 10;
|
||||
}
|
||||
|
||||
if (newMousePos != mousePos)
|
||||
if (any(newMousePos != mousePos))
|
||||
{
|
||||
Input.SetMousePosition((Int2)newMousePos);
|
||||
Input.SetMousePosition((int2)newMousePos);
|
||||
// After wrapping the cursor the the other side, the camera controller must not compare the positions,
|
||||
// because the delta doesn't represent the correct movement of the cursor.
|
||||
// TODO: can be solved by using direct mouse movement instead of comparing positions
|
||||
@@ -195,7 +195,7 @@ namespace GlitchyEditor.EditWindows
|
||||
/// If the user clicks, the entity beneath the cursor will be selected.
|
||||
private void MousePicking(ImGui.Vec2 viewportSize, bool gizmoUsed)
|
||||
{
|
||||
Vector2 relativeMouse = (Vector2)ImGui.GetMousePos() - (Vector2)ImGui.GetItemRectMin();
|
||||
float2 relativeMouse = (float2)ImGui.GetMousePos() - (float2)ImGui.GetItemRectMin();
|
||||
|
||||
int rtWidth = _editor.EditorSceneRenderer.CompositeTarget.Width;
|
||||
int rtHeight = _editor.EditorSceneRenderer.CompositeTarget.Height;
|
||||
@@ -316,9 +316,9 @@ namespace GlitchyEditor.EditWindows
|
||||
parentView = parentTransformCmp.WorldTransform.Invert();
|
||||
}
|
||||
|
||||
Vector3 snap = .(_snap);
|
||||
float3 snap = (float3)_snap;
|
||||
if (_gizmoType.HasFlag(.ROTATE))
|
||||
snap = .(_angleSnap);
|
||||
snap = (float3)_angleSnap;
|
||||
|
||||
if (ImGuizmo.Manipulate((.)&view, (.)&projection, _gizmoType, _gizmoMode, (.)&worldTransform, null, _doSnap ? (.)&snap : null))
|
||||
{
|
||||
|
||||