mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4874cfe511 | ||
|
|
63b9270710 | ||
|
|
2bac6a8d05 | ||
|
|
e51fc77c3f | ||
|
|
8c53f21690 | ||
|
|
ad1b37dc64 | ||
|
|
8e46945362 | ||
|
|
6a250d4927 |
@@ -5,6 +5,3 @@ build/
|
|||||||
recovery/
|
recovery/
|
||||||
vendor/directx
|
vendor/directx
|
||||||
imgui.ini
|
imgui.ini
|
||||||
GlitchyEditor/resources/scripts/ScriptCore.dll
|
|
||||||
GlitchyEditor/resources/scripts/ScriptCore.pdb
|
|
||||||
GlitchyEditor/settings.bon
|
|
||||||
|
|||||||
+1
-10
@@ -24,13 +24,4 @@
|
|||||||
url = https://github.com/EinScott/bon.git
|
url = https://github.com/EinScott/bon.git
|
||||||
[submodule "GlitchyEngineHelper/vendor/DirectXTK"]
|
[submodule "GlitchyEngineHelper/vendor/DirectXTK"]
|
||||||
path = GlitchyEngineHelper/vendor/DirectXTK
|
path = GlitchyEngineHelper/vendor/DirectXTK
|
||||||
url = https://github.com/microsoft/DirectXTK.git
|
url = https://github.com/microsoft/DirectXTK.git
|
||||||
[submodule "GlitchyEngine/vendor/box2D"]
|
|
||||||
path = GlitchyEngine/vendor/box2D
|
|
||||||
url = https://github.com/jazzbre/box2d-beef.git
|
|
||||||
[submodule "GlitchyEngine/vendor/Beef.Linq"]
|
|
||||||
path = GlitchyEngine/vendor/Beef.Linq
|
|
||||||
url = https://github.com/aharabada/Beef.Linq.git
|
|
||||||
[submodule "GlitchyEngine/vendor/NetHostBeef"]
|
|
||||||
path = GlitchyEngine/vendor/NetHostBeef
|
|
||||||
url = https://github.com/aharabada/NetHostBeef.git
|
|
||||||
+2
-6
@@ -1,10 +1,6 @@
|
|||||||
FileVersion = 1
|
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"}, ScriptCore = {Path = "ScriptCore"}, NetHostBeef = {Path = "GlitchyEngine/vendor/NetHostBeef/NetHostBeef"}}
|
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"}}
|
||||||
Unlocked = ["corlib"]
|
WorkspaceFolders = {GlitchyEngine = ["GlitchyEngine", "GlitchLog", "GlitchyEngineHelper"], "GlitchyEngine/Dependencies" = ["cgltf-beef", "DirectX", "FreeType", "ImGui", "ImGuiImplDX11", "ImGuiImplWin32", "ImGuizmo", "LodePng", "msdfgen-beef", "bon"]}
|
||||||
WorkspaceFolders = {GlitchyEngine = ["GlitchyEngine", "GlitchLog", "GlitchyEngineHelper", "ScriptCore"], "GlitchyEngine/Dependencies" = ["cgltf-beef", "DirectX", "FreeType", "ImGui", "ImGuiImplDX11", "ImGuiImplWin32", "ImGuizmo", "LodePng", "msdfgen-beef", "bon", "box2d-beef", "Beef.Linq", "NetHostBeef"]}
|
|
||||||
|
|
||||||
[Workspace]
|
[Workspace]
|
||||||
StartupProject = "GlitchyEditor"
|
StartupProject = "GlitchyEditor"
|
||||||
|
|
||||||
[Configs.Debug.Win64]
|
|
||||||
AllocStackTraceDepth = 12
|
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
///
|
|
||||||
/// Loading and usage of an asset.
|
|
||||||
///
|
|
||||||
// Shows the usage of the Content Manager.
|
|
||||||
// An asset is loaded with Content.LoadAsset(AssetName)
|
|
||||||
// Loading an asset returns an AssetHandle.
|
|
||||||
// Usually you want to hold on to the AssetHandle.
|
|
||||||
// If you need the actual asset you can use Content.GetAsset<AssetType>(AssetHandle) to retrieve the actual asset.
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Only hold on to AssetHandle.
|
|
||||||
* Do NOT hold actual Assets! The Asset might get invalidated
|
|
||||||
* (e.g. reloading after the source-file changed).
|
|
||||||
*/
|
|
||||||
AssetHandle _lineEffect;
|
|
||||||
|
|
||||||
void Start()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Loading an asset returns a handle to that asset.
|
|
||||||
*/
|
|
||||||
_lineEffect = Content.LoadAsset("Shaders\\LineEffect.hlsl");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
// Use case 1:
|
|
||||||
{
|
|
||||||
// Retrieve the actual asset. Note that this Asset is only guaranteed to persist
|
|
||||||
// for the current frame.
|
|
||||||
Effect fx = Content.GetAsset<Effect>(_lineEffect);
|
|
||||||
|
|
||||||
// Note: Assets are ref counted, however since they are not inteded to be held GetAsset
|
|
||||||
// does NOT increment the reference counter so you usually should NOT decrement it.
|
|
||||||
// The exception is when you manually hold on to an asset (see Example below)
|
|
||||||
|
|
||||||
// Use asset
|
|
||||||
fx.Variables["ViewProjection"].SetData(viewProjection * transform);
|
|
||||||
fx.Variables["Color"].SetData(color);
|
|
||||||
fx.ApplyChanges();
|
|
||||||
fx.Bind();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use case 2:
|
|
||||||
{
|
|
||||||
// Retrieve the actual asset.
|
|
||||||
Effect fx = _lineEffect.Get<Effect>();
|
|
||||||
|
|
||||||
// ...
|
|
||||||
// Same as case 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Holding on to an actual asset.
|
|
||||||
///
|
|
||||||
// Shows the usage of the Content Manager when you hold a reference to the actual Asset instead of the handle.
|
|
||||||
// This should usually not be done. Eventhough it is technically fine, it has the implication, that if the
|
|
||||||
// content manager decides to reload the asset the changes will not be reflected in the held reference
|
|
||||||
// (which they would if you used GetAsset before every usage.)
|
|
||||||
// Also the content manager can't unload the asset because the reference counter wouldn't be zero.
|
|
||||||
// Though there currently is no way for the content manager to unload an asset unless it is specifically told to do so.
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Field to hold the asset.
|
|
||||||
*/
|
|
||||||
Effect _lineEffect;
|
|
||||||
|
|
||||||
void Start()
|
|
||||||
{
|
|
||||||
// Load the Asset.
|
|
||||||
AssetHandle handle = Content.LoadAsset("Shaders\\LineEffect.hlsl");
|
|
||||||
// Get the actual asset.
|
|
||||||
_lineEffect = Content.GetAsset<Effect>(handle); // Alternative: _lineEffect = handle.Get<Effect>();
|
|
||||||
// Increment the reference counter so that the asset doesn't get unloaded.
|
|
||||||
_lineEffect.AddRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Destroy()
|
|
||||||
{
|
|
||||||
// Make sure to release the asset once you don't need it anymore. Otherwise it will leak.
|
|
||||||
_lineEffect.Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
_lineEffect.Variables["ViewProjection"].SetData(viewProjection * transform);
|
|
||||||
_lineEffect.Variables["Color"].SetData(color);
|
|
||||||
_lineEffect.ApplyChanges();
|
|
||||||
_lineEffect.Bind();
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
///
|
|
||||||
/// This shows the usage of a smart/typed Asset Handle.
|
|
||||||
///
|
|
||||||
// In the basic usage-patterns the user has two options:
|
|
||||||
// Either he/she holds a handle and has to query for the actual asset every time
|
|
||||||
// or he/she hold the actual asset and loses reloading capabilities.
|
|
||||||
// The idea of the auto asset is to provide a way that can provide both.
|
|
||||||
|
|
||||||
AssetHandle<Effect> _lineEffect;
|
|
||||||
|
|
||||||
void Start()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Loading an asset returns a handle to that asset.
|
|
||||||
* The asset handle is implicitly converted to a smart AssetHandle.
|
|
||||||
*/
|
|
||||||
_lineEffect = Content.LoadAsset("Shaders\\LineEffect.hlsl");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
// Use case 1 (Convenience)
|
|
||||||
{
|
|
||||||
_lineEffect.Variables["ViewProjection"].SetData(viewProjection * transform);
|
|
||||||
_lineEffect.Variables["Color"].SetData(color);
|
|
||||||
_lineEffect.ApplyChanges();
|
|
||||||
_lineEffect.Bind();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use case 2 (Technically more efficient)
|
|
||||||
{
|
|
||||||
Effect fx = _lineEffect.Get();
|
|
||||||
fx.Variables["ViewProjection"].SetData(viewProjection * transform);
|
|
||||||
fx.Variables["Color"].SetData(color);
|
|
||||||
fx.ApplyChanges();
|
|
||||||
fx.Bind();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Auto Assets use comp time to expose all the fields, Methods and properties of the actual asset.
|
|
||||||
// They will automatically check if the asset for the handle changed and update accordingly.
|
|
||||||
// This means it is more convenient to use than both basic patterns and has all benefits of both.
|
|
||||||
//
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Design Code Examples
|
|
||||||
|
|
||||||
This directory (and its subdirectories) contains non functional code snippets showing the intended usage of certain systems of the engine.
|
|
||||||
@@ -5,6 +5,3 @@ Dependencies = {corlib = "*", GlitchLog = "*", GlitchyEngine = "*"}
|
|||||||
Name = "GlitchyEditor"
|
Name = "GlitchyEditor"
|
||||||
TargetType = "BeefGUIApplication"
|
TargetType = "BeefGUIApplication"
|
||||||
StartupObject = "GlitchyEngine.Program"
|
StartupObject = "GlitchyEngine.Program"
|
||||||
|
|
||||||
[Configs.Debug.Win64]
|
|
||||||
DebugCommandArguments = "\"content\\Scenes\\physics2D.scene\""
|
|
||||||
|
|||||||
@@ -1,398 +0,0 @@
|
|||||||
## 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
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
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 OnCreate()
|
|
||||||
{
|
|
||||||
Log.Info("Camera Create");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnUpdate(float deltaTime)
|
|
||||||
{
|
|
||||||
Log.Info($"Camera Update {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!");
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
using System;
|
|
||||||
using GlitchyEngine;
|
|
||||||
using GlitchyEngine.Editor;
|
|
||||||
using GlitchyEngine.Math;
|
|
||||||
|
|
||||||
using static GlitchyEngine.Math.Math;
|
|
||||||
|
|
||||||
namespace Sandbox
|
|
||||||
{
|
|
||||||
|
|
||||||
public enum MyEnum
|
|
||||||
{
|
|
||||||
Yes,
|
|
||||||
No,
|
|
||||||
Maybe
|
|
||||||
}
|
|
||||||
|
|
||||||
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 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>();
|
|
||||||
|
|
||||||
//Camera = FindEntityWithName("Camera").As<Camera>();
|
|
||||||
|
|
||||||
//if (Camera == null)
|
|
||||||
//{
|
|
||||||
// Log.Error("Camera not found.");
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called every frame.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="deltaTime"></param>
|
|
||||||
void OnUpdate(float deltaTime)
|
|
||||||
{
|
|
||||||
Log.Info($"On update: {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;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//_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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"profiles": {
|
|
||||||
"Start Editor": {
|
|
||||||
"commandName": "Executable",
|
|
||||||
"executablePath": "D:\\Development\\Projects\\Beef\\GlitchyEngine\\build\\Debug_Win64\\GlitchyEditor\\GlitchyEditor.exe",
|
|
||||||
"commandLineArgs": "\"content\\Scenes\\physics2D.scene\"",
|
|
||||||
"workingDirectory": "D:\\Development\\Projects\\Beef\\GlitchyEngine\\GlitchyEditor",
|
|
||||||
"nativeDebugging": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
<?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>Sandbox</RootNamespace>
|
|
||||||
<AssemblyName>Sandbox</AssemblyName>
|
|
||||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
|
||||||
<FileAlignment>512</FileAlignment>
|
|
||||||
<Deterministic>true</Deterministic>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<DebugType>full</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>
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
|
||||||
<LangVersion>latest</LangVersion>
|
|
||||||
<OutputPath>bin</OutputPath>
|
|
||||||
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
|
||||||
|
|
||||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
|
||||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
|
||||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\..\..\ScriptCore\ScriptCore.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
|
|
||||||
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}") = "Sandbox", "Sandbox.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
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using GlitchyEngine;
|
|
||||||
|
|
||||||
namespace Sandbox;
|
|
||||||
|
|
||||||
public static class TestClass
|
|
||||||
{
|
|
||||||
[UnmanagedCallersOnly]
|
|
||||||
public static void TestFunction()
|
|
||||||
{
|
|
||||||
Console.WriteLine("Hello from the second Assembly!");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void InternalTest()
|
|
||||||
{
|
|
||||||
Console.WriteLine("Ja, ich existiere in der Tat");
|
|
||||||
|
|
||||||
Log.Info("Yeah!");
|
|
||||||
//Console.WriteLine("Und nun bin ich anders");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int Test(IntPtr arg, int sizeofArg)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"YUPPYPLASDPASDOIUZASD");
|
|
||||||
return 7;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "ModelAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.ModelAssetLoaderConfig){}
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "ModelAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.ModelAssetLoaderConfig){}
|
|
||||||
}
|
|
||||||
@@ -1,224 +0,0 @@
|
|||||||
{
|
|
||||||
Name = "Scene name here pls!!!",
|
|
||||||
Entities = [
|
|
||||||
{
|
|
||||||
Id = 5169765174113462770,
|
|
||||||
NameComponent = {
|
|
||||||
Name = "Sphere"
|
|
||||||
},
|
|
||||||
TransformComponent = {
|
|
||||||
Position = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0.5,
|
|
||||||
Z = 0
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0,
|
|
||||||
W = 1
|
|
||||||
},
|
|
||||||
Scale = {
|
|
||||||
X = 1,
|
|
||||||
Y = 1,
|
|
||||||
Z = 1
|
|
||||||
},
|
|
||||||
EditorEulerRotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MeshComponent = {
|
|
||||||
Mesh = "Models/sphere.glb"
|
|
||||||
},
|
|
||||||
MeshRendererComponent = {
|
|
||||||
Material = "Textures/TestMaterial.mat"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Id = 17158420331978163131,
|
|
||||||
NameComponent = {
|
|
||||||
Name = "Light"
|
|
||||||
},
|
|
||||||
TransformComponent = {
|
|
||||||
Position = {
|
|
||||||
X = -1,
|
|
||||||
Y = 4,
|
|
||||||
Z = -4
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0.614328027,
|
|
||||||
Y = 0.239776045,
|
|
||||||
Z = 0.0315669999,
|
|
||||||
W = 0.751073837
|
|
||||||
},
|
|
||||||
Scale = {
|
|
||||||
X = 0.999998868,
|
|
||||||
Y = 1,
|
|
||||||
Z = 1.00000095
|
|
||||||
},
|
|
||||||
EditorEulerRotation = {
|
|
||||||
X = 1.30899811,
|
|
||||||
Y = 0.349065989,
|
|
||||||
Z = 0.349065989
|
|
||||||
}
|
|
||||||
},
|
|
||||||
LightComponent = {
|
|
||||||
LightType = .Directional,
|
|
||||||
Illuminance = 10,
|
|
||||||
Color = {
|
|
||||||
R = 1,
|
|
||||||
G = 0.991771996,
|
|
||||||
B = 0.74086225
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Id = 5556050645816939548,
|
|
||||||
NameComponent = {
|
|
||||||
Name = "Plane"
|
|
||||||
},
|
|
||||||
TransformComponent = {
|
|
||||||
Position = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0,
|
|
||||||
W = 1
|
|
||||||
},
|
|
||||||
Scale = {
|
|
||||||
X = 10,
|
|
||||||
Y = 1,
|
|
||||||
Z = 10
|
|
||||||
},
|
|
||||||
EditorEulerRotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MeshComponent = {
|
|
||||||
Mesh = "Models/plane.glb"
|
|
||||||
},
|
|
||||||
MeshRendererComponent = {
|
|
||||||
Material = "Textures/TestMaterial.mat"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Id = 3947673900993587516,
|
|
||||||
NameComponent = {
|
|
||||||
Name = "Camera"
|
|
||||||
},
|
|
||||||
TransformComponent = {
|
|
||||||
Position = {
|
|
||||||
X = 0,
|
|
||||||
Y = 2,
|
|
||||||
Z = -5
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0.216440007,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0,
|
|
||||||
W = 0.976296008
|
|
||||||
},
|
|
||||||
Scale = {
|
|
||||||
X = 1,
|
|
||||||
Y = 1,
|
|
||||||
Z = 1
|
|
||||||
},
|
|
||||||
EditorEulerRotation = {
|
|
||||||
X = 0.436332017,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
CameraComponent = {
|
|
||||||
Primary = true,
|
|
||||||
ProjectionType = .InfinitePerspective,
|
|
||||||
PerspectiveFovY = 1.30899692,
|
|
||||||
PerspectiveNearPlane = 0.100000001,
|
|
||||||
PerspectiveFarPlane = 10000,
|
|
||||||
OrthographicHeight = 10,
|
|
||||||
OrthographicNearPlane = 0,
|
|
||||||
OrthographicFarPlane = 10,
|
|
||||||
AspectRatio = 2.19888878,
|
|
||||||
FixedAspectRatio = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Id = 420718992779301759,
|
|
||||||
NameComponent = {
|
|
||||||
Name = "Entity"
|
|
||||||
},
|
|
||||||
TransformComponent = {
|
|
||||||
Position = {
|
|
||||||
X = 3,
|
|
||||||
Y = 0.501076996,
|
|
||||||
Z = -0.669378757
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0.18301262,
|
|
||||||
Y = -0.683013558,
|
|
||||||
Z = 0.683012128,
|
|
||||||
W = 0.183013007
|
|
||||||
},
|
|
||||||
Scale = {
|
|
||||||
X = 1,
|
|
||||||
Y = 1,
|
|
||||||
Z = 1
|
|
||||||
},
|
|
||||||
EditorEulerRotation = {
|
|
||||||
X = 1.57079446,
|
|
||||||
Y = -2.61799312,
|
|
||||||
Z = 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MeshComponent = {
|
|
||||||
Mesh = "Models/plane.glb"
|
|
||||||
},
|
|
||||||
MeshRendererComponent = {
|
|
||||||
Material = ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Id = 8080288871271083510,
|
|
||||||
NameComponent = {
|
|
||||||
Name = "Rocket"
|
|
||||||
},
|
|
||||||
TransformComponent = {
|
|
||||||
Position = {
|
|
||||||
X = 2.37353587,
|
|
||||||
Y = 0.629615188,
|
|
||||||
Z = -1.34831977
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0.270598024,
|
|
||||||
Y = -0.65328145,
|
|
||||||
Z = 0.65328151,
|
|
||||||
W = 0.270598054
|
|
||||||
},
|
|
||||||
Scale = {
|
|
||||||
X = 0.999999881,
|
|
||||||
Y = 0.999999821,
|
|
||||||
Z = 0.999999702
|
|
||||||
},
|
|
||||||
EditorEulerRotation = {
|
|
||||||
X = 1.57079637,
|
|
||||||
Y = -2.3561945,
|
|
||||||
Z = 8.94069743e-08
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MeshComponent = {
|
|
||||||
Mesh = "Models/plane.glb"
|
|
||||||
},
|
|
||||||
MeshRendererComponent = {
|
|
||||||
Material = "Textures/RocketMaterial.mat"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,212 +0,0 @@
|
|||||||
{
|
|
||||||
Name = "Scene name here pls!!!",
|
|
||||||
Entities = [
|
|
||||||
{
|
|
||||||
Id = 6000868443984780499,
|
|
||||||
NameComponent = {
|
|
||||||
Name = "Child"
|
|
||||||
},
|
|
||||||
SpriterRendererComponent = {
|
|
||||||
Color = {
|
|
||||||
R = 1,
|
|
||||||
G = 0.388184,
|
|
||||||
B = 0.090109,
|
|
||||||
A = 1
|
|
||||||
},
|
|
||||||
UvTransform = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 1,
|
|
||||||
W = 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
TransformComponent = {
|
|
||||||
ParentId = 820806682740348099,
|
|
||||||
Position = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0.75,
|
|
||||||
Z = 0
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0,
|
|
||||||
W = 1
|
|
||||||
},
|
|
||||||
Scale = {
|
|
||||||
X = 0.5,
|
|
||||||
Y = 0.5,
|
|
||||||
Z = 1
|
|
||||||
},
|
|
||||||
EditorEulerRotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Id = 820806682740348099,
|
|
||||||
NameComponent = {
|
|
||||||
Name = "Quad"
|
|
||||||
},
|
|
||||||
SpriterRendererComponent = {
|
|
||||||
Color = {
|
|
||||||
R = 0,
|
|
||||||
G = 0.551178,
|
|
||||||
B = 0.328787,
|
|
||||||
A = 1
|
|
||||||
},
|
|
||||||
UvTransform = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 1,
|
|
||||||
W = 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
TransformComponent = {
|
|
||||||
Position = {
|
|
||||||
X = 0,
|
|
||||||
Y = 2,
|
|
||||||
Z = 0
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0,
|
|
||||||
W = 1
|
|
||||||
},
|
|
||||||
Scale = {
|
|
||||||
X = 1,
|
|
||||||
Y = 1,
|
|
||||||
Z = 1
|
|
||||||
},
|
|
||||||
EditorEulerRotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Rigidbody2D = {
|
|
||||||
BodyType = .Dynamic,
|
|
||||||
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 = 15398726361722237419,
|
|
||||||
NameComponent = {
|
|
||||||
Name = "Floor"
|
|
||||||
},
|
|
||||||
SpriterRendererComponent = {
|
|
||||||
Color = {
|
|
||||||
R = 1,
|
|
||||||
G = 0.941886,
|
|
||||||
B = 0.401485,
|
|
||||||
A = 1
|
|
||||||
},
|
|
||||||
UvTransform = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 1,
|
|
||||||
W = 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
TransformComponent = {
|
|
||||||
Position = {
|
|
||||||
X = 0,
|
|
||||||
Y = -0.5,
|
|
||||||
Z = 0
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0,
|
|
||||||
W = 1
|
|
||||||
},
|
|
||||||
Scale = {
|
|
||||||
X = 10,
|
|
||||||
Y = 1,
|
|
||||||
Z = 1
|
|
||||||
},
|
|
||||||
EditorEulerRotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
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 = 1491484622542812645,
|
|
||||||
NameComponent = {
|
|
||||||
Name = "Camera"
|
|
||||||
},
|
|
||||||
TransformComponent = {
|
|
||||||
Position = {
|
|
||||||
X = 0,
|
|
||||||
Y = 1,
|
|
||||||
Z = -5
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0,
|
|
||||||
W = 1
|
|
||||||
},
|
|
||||||
Scale = {
|
|
||||||
X = 1,
|
|
||||||
Y = 1,
|
|
||||||
Z = 1
|
|
||||||
},
|
|
||||||
EditorEulerRotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
CameraComponent = {
|
|
||||||
Primary = true,
|
|
||||||
ProjectionType = .InfinitePerspective,
|
|
||||||
PerspectiveFovY = 1.308997,
|
|
||||||
PerspectiveNearPlane = 0.1,
|
|
||||||
PerspectiveFarPlane = 10000,
|
|
||||||
OrthographicHeight = 10,
|
|
||||||
OrthographicNearPlane = 0,
|
|
||||||
OrthographicFarPlane = 10,
|
|
||||||
AspectRatio = 2.116827,
|
|
||||||
FixedAspectRatio = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,530 +0,0 @@
|
|||||||
{
|
|
||||||
Name = "Scene name here pls!!!",
|
|
||||||
Entities = [
|
|
||||||
{
|
|
||||||
Id = 820806682740348099,
|
|
||||||
NameComponent = {
|
|
||||||
Name = "Quad"
|
|
||||||
},
|
|
||||||
SpriteRendererComponent = {
|
|
||||||
Color = {
|
|
||||||
R = 0,
|
|
||||||
G = 0.55117774,
|
|
||||||
B = 0.32878688,
|
|
||||||
A = 1
|
|
||||||
},
|
|
||||||
Sprite = "Textures/TestMat/rustediron2_albedo.png",
|
|
||||||
UvTransform = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 1,
|
|
||||||
W = 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
TransformComponent = {
|
|
||||||
Position = {
|
|
||||||
X = -0.72789681,
|
|
||||||
Y = 2,
|
|
||||||
Z = 0
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0,
|
|
||||||
W = 1
|
|
||||||
},
|
|
||||||
Scale = {
|
|
||||||
X = 1,
|
|
||||||
Y = 1,
|
|
||||||
Z = 1
|
|
||||||
},
|
|
||||||
EditorEulerRotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Rigidbody2D = {
|
|
||||||
BodyType = .Dynamic,
|
|
||||||
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 = 15398726361722237419,
|
|
||||||
NameComponent = {
|
|
||||||
Name = "Floor"
|
|
||||||
},
|
|
||||||
SpriteRendererComponent = {
|
|
||||||
Color = {
|
|
||||||
R = 1,
|
|
||||||
G = 0.941886961,
|
|
||||||
B = 0.401484549,
|
|
||||||
A = 1
|
|
||||||
},
|
|
||||||
Sprite = "",
|
|
||||||
UvTransform = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 1,
|
|
||||||
W = 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
TransformComponent = {
|
|
||||||
Position = {
|
|
||||||
X = 0,
|
|
||||||
Y = -0.5,
|
|
||||||
Z = 0
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0,
|
|
||||||
W = 1
|
|
||||||
},
|
|
||||||
Scale = {
|
|
||||||
X = 10,
|
|
||||||
Y = 1,
|
|
||||||
Z = 1
|
|
||||||
},
|
|
||||||
EditorEulerRotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
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 = 1491484622542812645,
|
|
||||||
NameComponent = {
|
|
||||||
Name = "Camera"
|
|
||||||
},
|
|
||||||
TransformComponent = {
|
|
||||||
Position = {
|
|
||||||
X = 0,
|
|
||||||
Y = 1,
|
|
||||||
Z = -5
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0,
|
|
||||||
W = 1
|
|
||||||
},
|
|
||||||
Scale = {
|
|
||||||
X = 1,
|
|
||||||
Y = 1,
|
|
||||||
Z = 1
|
|
||||||
},
|
|
||||||
EditorEulerRotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
CameraComponent = {
|
|
||||||
Primary = true,
|
|
||||||
ProjectionType = .InfinitePerspective,
|
|
||||||
PerspectiveFovY = 1.30899692,
|
|
||||||
PerspectiveNearPlane = 0.100000001,
|
|
||||||
PerspectiveFarPlane = 10000,
|
|
||||||
OrthographicHeight = 10,
|
|
||||||
OrthographicNearPlane = 0,
|
|
||||||
OrthographicFarPlane = 10,
|
|
||||||
AspectRatio = 0.884925187,
|
|
||||||
FixedAspectRatio = false
|
|
||||||
},
|
|
||||||
ScriptComponent = {
|
|
||||||
ScriptClass = "Sandbox.Camera",
|
|
||||||
Fields = [
|
|
||||||
DistanceFromPlayer = (Float)-7,
|
|
||||||
DontFollowRadius = (Float)3
|
|
||||||
] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Id = 15710354273720487680,
|
|
||||||
NameComponent = {
|
|
||||||
Name = "Player"
|
|
||||||
},
|
|
||||||
CircleRendererComponent = {
|
|
||||||
Color = {
|
|
||||||
R = 1,
|
|
||||||
G = 0,
|
|
||||||
B = 0,
|
|
||||||
A = 1
|
|
||||||
},
|
|
||||||
InnerRadius = 0.300000012,
|
|
||||||
Sprite = "",
|
|
||||||
UvTransform = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 1,
|
|
||||||
W = 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
TransformComponent = {
|
|
||||||
Position = {
|
|
||||||
X = -0.121203184,
|
|
||||||
Y = 0.660160959,
|
|
||||||
Z = 0
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0,
|
|
||||||
W = 1
|
|
||||||
},
|
|
||||||
Scale = {
|
|
||||||
X = 1,
|
|
||||||
Y = 1,
|
|
||||||
Z = 1
|
|
||||||
},
|
|
||||||
EditorEulerRotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Rigidbody2D = {
|
|
||||||
BodyType = .Dynamic,
|
|
||||||
FixedRotation = false
|
|
||||||
},
|
|
||||||
CircleCollider2D = {
|
|
||||||
Offset = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0
|
|
||||||
},
|
|
||||||
Radius = 0.5,
|
|
||||||
Density = 1,
|
|
||||||
Friction = 0.5,
|
|
||||||
Restitution = 0,
|
|
||||||
RestitutionThreshold = 0.5
|
|
||||||
},
|
|
||||||
ScriptComponent = {
|
|
||||||
ScriptClass = "Sandbox.MyTestEntity",
|
|
||||||
Fields = [
|
|
||||||
Bo = (Bool)false,
|
|
||||||
By = (Byte)0,
|
|
||||||
Us = (UShort)57,
|
|
||||||
Ui = (UInt)54,
|
|
||||||
Ul = (ULong)53,
|
|
||||||
Sb = (SByte)-128,
|
|
||||||
Sh = (Short)95,
|
|
||||||
In = (Int)-149,
|
|
||||||
Lo = (Long)82,
|
|
||||||
Fl = (Float)-98.122963,
|
|
||||||
Do = (Double)118,
|
|
||||||
V2 = (float2){
|
|
||||||
X = 11,
|
|
||||||
Y = 12
|
|
||||||
},
|
|
||||||
V3 = (float3){
|
|
||||||
X = 13,
|
|
||||||
Y = 14,
|
|
||||||
Z = 15
|
|
||||||
},
|
|
||||||
V4 = (float4){
|
|
||||||
X = 14,
|
|
||||||
Y = 17,
|
|
||||||
Z = 18,
|
|
||||||
W = 19
|
|
||||||
},
|
|
||||||
TheEntity = (Entity)0,
|
|
||||||
JumpForce = (Float)200,
|
|
||||||
MoveForce = (Float)148,
|
|
||||||
MyNumber = (Int)22,
|
|
||||||
MyDouble = (Double)23
|
|
||||||
] }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Id = 935640822766280888,
|
|
||||||
NameComponent = {
|
|
||||||
Name = "Light"
|
|
||||||
},
|
|
||||||
TransformComponent = {
|
|
||||||
Position = {
|
|
||||||
X = 3.88327599,
|
|
||||||
Y = 0,
|
|
||||||
Z = -0.808795214
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0.497987002,
|
|
||||||
Y = -0.103420995,
|
|
||||||
Z = 0.155380026,
|
|
||||||
W = 0.846859217
|
|
||||||
},
|
|
||||||
Scale = {
|
|
||||||
X = 0.999997795,
|
|
||||||
Y = 1,
|
|
||||||
Z = 1
|
|
||||||
},
|
|
||||||
EditorEulerRotation = {
|
|
||||||
X = 1.09089541,
|
|
||||||
Y = -0.340793997,
|
|
||||||
Z = 0.160857871
|
|
||||||
}
|
|
||||||
},
|
|
||||||
LightComponent = {
|
|
||||||
LightType = .Directional,
|
|
||||||
Illuminance = 12.8999996,
|
|
||||||
Color = {
|
|
||||||
R = 0.985467017,
|
|
||||||
G = 1,
|
|
||||||
B = 0.569978058
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Id = 721949523193525565,
|
|
||||||
NameComponent = {
|
|
||||||
Name = "Sphere"
|
|
||||||
},
|
|
||||||
TransformComponent = {
|
|
||||||
Position = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 2.56930423
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0,
|
|
||||||
W = 1
|
|
||||||
},
|
|
||||||
Scale = {
|
|
||||||
X = 1,
|
|
||||||
Y = 1,
|
|
||||||
Z = 1
|
|
||||||
},
|
|
||||||
EditorEulerRotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MeshComponent = {
|
|
||||||
Mesh = "Models/sphere.glb"
|
|
||||||
},
|
|
||||||
MeshRendererComponent = {
|
|
||||||
Material = "Textures/TestMaterial.mat"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Id = 2241063100006479259,
|
|
||||||
NameComponent = {
|
|
||||||
Name = "Floor 2"
|
|
||||||
},
|
|
||||||
SpriteRendererComponent = {
|
|
||||||
Color = {
|
|
||||||
R = 0.425658971,
|
|
||||||
G = 0.855207562,
|
|
||||||
B = 0.0558161102,
|
|
||||||
A = 1
|
|
||||||
},
|
|
||||||
Sprite = "",
|
|
||||||
UvTransform = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 1,
|
|
||||||
W = 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
TransformComponent = {
|
|
||||||
Position = {
|
|
||||||
X = 6.74610233,
|
|
||||||
Y = -2.03225899,
|
|
||||||
Z = 0
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = -0.331792623,
|
|
||||||
W = 0.943352342
|
|
||||||
},
|
|
||||||
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.666116953,
|
|
||||||
G = 0.0600316115,
|
|
||||||
B = 1,
|
|
||||||
A = 1
|
|
||||||
},
|
|
||||||
Sprite = "",
|
|
||||||
UvTransform = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 1,
|
|
||||||
W = 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
TransformComponent = {
|
|
||||||
Position = {
|
|
||||||
X = 15.2321301,
|
|
||||||
Y = -1.98709249,
|
|
||||||
Z = 0
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0.134986058,
|
|
||||||
W = 0.990847468
|
|
||||||
},
|
|
||||||
Scale = {
|
|
||||||
X = 13.9764566,
|
|
||||||
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.176544324,
|
|
||||||
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.62550211,
|
|
||||||
Z = 0
|
|
||||||
},
|
|
||||||
Rotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0.187087834,
|
|
||||||
W = 0.982343197
|
|
||||||
},
|
|
||||||
Scale = {
|
|
||||||
X = 0.999999523,
|
|
||||||
Y = 6.49634314,
|
|
||||||
Z = 1
|
|
||||||
},
|
|
||||||
EditorEulerRotation = {
|
|
||||||
X = 0,
|
|
||||||
Y = 0,
|
|
||||||
Z = 0.376393586
|
|
||||||
}
|
|
||||||
},
|
|
||||||
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.899999976,
|
|
||||||
RestitutionThreshold = 0.5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
//=================================================================================================
|
|
||||||
//
|
|
||||||
// Baking Lab
|
|
||||||
// by MJP and David Neubelt
|
|
||||||
// http://mynameismjp.wordpress.com/
|
|
||||||
//
|
|
||||||
// All code licensed under the MIT license
|
|
||||||
//
|
|
||||||
//=================================================================================================
|
|
||||||
|
|
||||||
// The code in this file was originally written by Stephen Hill (@self_shadow), who deserves all
|
|
||||||
// credit for coming up with this fit and implementing it. Buy him a beer next time you see him. :)
|
|
||||||
|
|
||||||
// Source: https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl
|
|
||||||
|
|
||||||
// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
|
|
||||||
static const float3x3 ACESInputMat =
|
|
||||||
{
|
|
||||||
{0.59719, 0.35458, 0.04823},
|
|
||||||
{0.07600, 0.90834, 0.01566},
|
|
||||||
{0.02840, 0.13383, 0.83777}
|
|
||||||
};
|
|
||||||
|
|
||||||
// ODT_SAT => XYZ => D60_2_D65 => sRGB
|
|
||||||
static const float3x3 ACESOutputMat =
|
|
||||||
{
|
|
||||||
{ 1.60475, -0.53108, -0.07367},
|
|
||||||
{-0.10208, 1.10813, -0.00605},
|
|
||||||
{-0.00327, -0.07276, 1.07602}
|
|
||||||
};
|
|
||||||
|
|
||||||
float3 RRTAndODTFit(float3 v)
|
|
||||||
{
|
|
||||||
float3 a = v * (v + 0.0245786f) - 0.000090537f;
|
|
||||||
float3 b = v * (0.983729f * v + 0.4329510f) + 0.238081f;
|
|
||||||
return a / b;
|
|
||||||
}
|
|
||||||
|
|
||||||
float3 ACESFitted(float3 color)
|
|
||||||
{
|
|
||||||
color = mul(ACESInputMat, color);
|
|
||||||
|
|
||||||
// Apply RRT and ODT
|
|
||||||
color = RRTAndODTFit(color);
|
|
||||||
|
|
||||||
color = mul(ACESOutputMat, color);
|
|
||||||
|
|
||||||
// Clamp to [0, 1]
|
|
||||||
color = saturate(color);
|
|
||||||
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EffectAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
cbuffer Constants : register(b0)
|
|
||||||
{
|
|
||||||
uint ClearValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 VS(float2 input : POSITION) : SV_Position
|
|
||||||
{
|
|
||||||
return float4(input, 0.0f, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint PS(float4 input : SV_Position) : SV_Target0
|
|
||||||
{
|
|
||||||
return ClearValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma Effect[VS = VS; PS = PS]
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EffectAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
Texture2D Texture : register(t0);
|
|
||||||
SamplerState TextureSampler : register(s0);
|
|
||||||
|
|
||||||
struct VS_IN
|
|
||||||
{
|
|
||||||
float2 Position : POSITION;
|
|
||||||
float2 TexCoord : TEXCOORD0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PS_IN
|
|
||||||
{
|
|
||||||
float4 Position : SV_POSITION;
|
|
||||||
float2 TexCoord : TEXCOORD;
|
|
||||||
};
|
|
||||||
|
|
||||||
PS_IN VS(VS_IN input)
|
|
||||||
{
|
|
||||||
PS_IN output;
|
|
||||||
|
|
||||||
output.Position = float4(input.Position, 0, 1);
|
|
||||||
output.TexCoord = input.TexCoord;
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS(PS_IN input) : SV_TARGET
|
|
||||||
{
|
|
||||||
float4 color = Texture.Sample(TextureSampler, input.TexCoord);
|
|
||||||
|
|
||||||
return float4(pow(color.rgb, 1.0f / 2.2f), color.a);
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma Effect[VS = VS; PS = PS]
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EffectAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
#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
|
|
||||||
};
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EffectAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}/* No reflection data for GlitchyEditor.Assets.EffectAssetLoaderConfig. Add [BonTarget] or force it */
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
#define PI 3.14159265358979323846f
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the diffuse lighting of a lambertian surface
|
|
||||||
* @param diffuseColor (rho/ pi) * C_diffuse
|
|
||||||
* @param illuminanceColor The product of the "brightness" and the light color.
|
|
||||||
* @param n_dot_l The dot product of the surface normal and the light direction.
|
|
||||||
*/
|
|
||||||
float3 CalculateDiffuseReflection(float3 diffuseColor, float3 illuminanceColor, float3 n_dot_l)
|
|
||||||
{
|
|
||||||
float3 directColor = illuminanceColor * saturate(n_dot_l);
|
|
||||||
|
|
||||||
return (directColor * diffuseColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the blinn-phong-specular reflection
|
|
||||||
* @param n The normalized surface normal
|
|
||||||
* @param h The normalized half way vector (nrm(l + v))
|
|
||||||
* @param alpha The reflections alpha-value
|
|
||||||
* @param illuminanceColor The product of the "brightness" and the light color.
|
|
||||||
* @param n_dot_l The dot product of the surface normal and the light direction.
|
|
||||||
*/
|
|
||||||
float3 CalculateSpecularReflection(float3 n, float3 h, float alpha, float3 illuminanceColor, float n_dot_l)
|
|
||||||
{
|
|
||||||
float highlight = pow(saturate(dot(n, h)), alpha) * float(n_dot_l > 0.0);
|
|
||||||
return (illuminanceColor * highlight); // Todo: * SpecularColor
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EffectAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* This File contains Function for PBR.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __PBR_HLSL__
|
|
||||||
#define __PBR_HLSL__
|
|
||||||
|
|
||||||
#include "ShaderHelpers.hlsl"
|
|
||||||
|
|
||||||
// #define PBR_IBL
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Normal Distribution Function. (Trowbridge-Reits GGX)
|
|
||||||
* Calculates the relative surface area of microfacets exactly aligned to the halfway vector.
|
|
||||||
* @param normal The surface normal.
|
|
||||||
* @param halfway The halfway vector between the surface normal and the view direction.
|
|
||||||
* @param roughness Roughness value.
|
|
||||||
* @returns The relative surface area of microfacets exactly aligned to the halfway vector.
|
|
||||||
*/
|
|
||||||
float NormalDistributionGGX(float3 normal, float3 halfway, float roughness)
|
|
||||||
{
|
|
||||||
// Square roughness because it looks better
|
|
||||||
float a = roughness * roughness;
|
|
||||||
float aa = a * a;
|
|
||||||
|
|
||||||
float n_dot_h = max(dot(normal, halfway), 0.0f);
|
|
||||||
|
|
||||||
float denom = (n_dot_h * n_dot_h) * (aa - 1.0f) + 1.0f;
|
|
||||||
denom = PI * denom * denom;
|
|
||||||
|
|
||||||
return aa / denom;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Geometry Function calculating the overshadowing of microfacets based on roughness. (Schlick-Beckmann GGX).
|
|
||||||
* @param dot-product of normal vector and vector from surface to camera.
|
|
||||||
* @param k Roughness value.
|
|
||||||
*/
|
|
||||||
float GeometrySchlickGGX(float n_dot_v, float k)
|
|
||||||
{
|
|
||||||
return n_dot_v / (n_dot_v * (1 - k) + k);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Geometry Function calculating the overshadowing of microfacets based on roughness. (Smith)
|
|
||||||
* @param normal The surface normal.
|
|
||||||
* @param viewDir Vector from surface to viewer.
|
|
||||||
* @param lightDir Vector from surface to light source.
|
|
||||||
* @param roughness Roughness value.
|
|
||||||
*/
|
|
||||||
float GeometrySmith(float3 normal, float3 viewDir, float3 lightDir, float roughness)
|
|
||||||
{
|
|
||||||
#ifdef PBR_IBL
|
|
||||||
// IBL
|
|
||||||
float k = roughness * roughness / 2;
|
|
||||||
#else
|
|
||||||
// Direct lighting
|
|
||||||
float k = (roughness + 1.0f);
|
|
||||||
k = (k * k) / 8;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const float n_dot_v = max(dot(normal, viewDir), 0.0f);
|
|
||||||
float n_dot_l = max(dot(normal, lightDir), 0.0f);
|
|
||||||
|
|
||||||
return GeometrySchlickGGX(n_dot_v, k) * GeometrySchlickGGX(n_dot_l, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the fresnel value.
|
|
||||||
* @param n_dot_v Dot product of the normal and view direction
|
|
||||||
* @param F0 base reflectivity.
|
|
||||||
*/
|
|
||||||
float3 FresnelSchlick(float n_dot_v, float3 F0)
|
|
||||||
{
|
|
||||||
return F0 + (1.0 - F0) * pow(clamp(1.0 - n_dot_v, 0.0, 1.0), 5.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __PBR_HLSL__
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EffectAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}
|
|
||||||
}
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
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]
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EffectAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}/* No reflection data for GlitchyEditor.Assets.EffectAssetLoaderConfig. Add [BonTarget] or force it */
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
#ifndef __SHADER_HELPERS_HLSL__
|
|
||||||
#define __SHADER_HELPERS_HLSL__
|
|
||||||
|
|
||||||
#define PI 3.14159265358979323846f
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Calculates the weighted sum of two normal vectors.
|
|
||||||
* nrm1: The first normal vector
|
|
||||||
* nrm2: The second normal vector
|
|
||||||
* a: The weight factor for nrm1
|
|
||||||
* b: The weight factor for nrm2
|
|
||||||
*/
|
|
||||||
float3 BlendNormals(float3 nrm1, float3 nrm2, float a, float b)
|
|
||||||
{
|
|
||||||
return normalize(float3(a * nrm1.x / nrm1.z + b * nrm2.x / nrm2.z,
|
|
||||||
a * nrm1.y / nrm1.z + b * nrm2.y / nrm2.z,
|
|
||||||
1.0f));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Scales a normal vector by a factor where 0 results in the vector (0, 0, 1)
|
|
||||||
* nrm: The normal vector
|
|
||||||
* a: The scaling factor
|
|
||||||
*/
|
|
||||||
float3 ScaleNormal(float3 nrm1, float a)
|
|
||||||
{
|
|
||||||
return normalize(float3(a * nrm1.x / nrm1.z,
|
|
||||||
a * nrm1.y / nrm1.z,
|
|
||||||
1.0f));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Scales a normal vector by a factor where 0 results in the vector (0, 0, 1)
|
|
||||||
* nrm: The normal vector
|
|
||||||
* a: The scaling factor
|
|
||||||
*/
|
|
||||||
float3 ScaleNormal(float3 nrm1, float2 a)
|
|
||||||
{
|
|
||||||
return normalize(float3(a.x * nrm1.x / nrm1.z,
|
|
||||||
a.y * nrm1.y / nrm1.z,
|
|
||||||
1.0f));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reconstructs the z-component of a normalized normal vector from a two-component value
|
|
||||||
* cnrm: The x- and y-components of a normalized normal vector
|
|
||||||
*/
|
|
||||||
float3 DecompressNormal(float2 cnrm)
|
|
||||||
{
|
|
||||||
return float3(cnrm, sqrt(1.0 - cnrm.x * cnrm.x - cnrm.y * cnrm.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reconstructs the tangent space from a normal and a tangent
|
|
||||||
* normal: The surface normal
|
|
||||||
* tangent: The surface tangent
|
|
||||||
* sigma: Defines the handedness of the tangent space matrix. 1.0 if it is right handend. -1.0 if it is left handed
|
|
||||||
*/
|
|
||||||
float3x3 ConstructTangentSpace(float3 normal, float3 tangent, float3 sigma)
|
|
||||||
{
|
|
||||||
float3 n = normalize(normal);
|
|
||||||
float3 t = normalize(tangent - n * dot(tangent, n));
|
|
||||||
float3 b = cross(n, t) * sigma;
|
|
||||||
|
|
||||||
return float3x3(t, b, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the luminance of an rgb-value.
|
|
||||||
* @param rgb The rgb color.
|
|
||||||
* @return The luminance of the given rgb color.
|
|
||||||
*/
|
|
||||||
float ColorToLuminance(float3 rgb)
|
|
||||||
{
|
|
||||||
return rgb.r * 0.212639 + rgb.g * 0.715169 + rgb.b * 0.072192;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extrancts the handedness of the bitangent that is encoded in the z-component of the tangent.
|
|
||||||
* @param tangentz The z-component of the tangent with the handedness encoded.
|
|
||||||
* @return The handedness of the bitangent (bitangent = handedness * tangent x normal)
|
|
||||||
*/
|
|
||||||
float GetBitangentHandedness(float tangentz)
|
|
||||||
{
|
|
||||||
// handedness is in least significant bit of tangent.z
|
|
||||||
uint z = asuint(tangentz);
|
|
||||||
return (z & 1) > 0 ? 1.0 : -1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __SHADER_HELPERS_HLSL__
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EffectAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
#include "ACES.hlsl"
|
|
||||||
|
|
||||||
Texture2D CameraTarget : register(t0);
|
|
||||||
SamplerState CameraTargetSampler : register(s0);
|
|
||||||
|
|
||||||
struct VS_IN
|
|
||||||
{
|
|
||||||
float2 Position : POSITION;
|
|
||||||
float2 TexCoord : TEXCOORD0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PS_IN
|
|
||||||
{
|
|
||||||
float4 Position : SV_POSITION;
|
|
||||||
float2 TexCoord : TEXCOORD;
|
|
||||||
};
|
|
||||||
|
|
||||||
PS_IN VS(VS_IN input)
|
|
||||||
{
|
|
||||||
PS_IN output;
|
|
||||||
|
|
||||||
output.Position = float4(input.Position, 0, 1);
|
|
||||||
output.TexCoord = input.TexCoord;
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS(PS_IN input) : SV_TARGET
|
|
||||||
{
|
|
||||||
float4 rawColor = CameraTarget.Sample(CameraTargetSampler, input.TexCoord);
|
|
||||||
|
|
||||||
// float3 color = rawColor.rgb / (rawColor.rgb + 1.0f);
|
|
||||||
|
|
||||||
float3 color = ACESFitted(rawColor.rgb);
|
|
||||||
|
|
||||||
return float4(color, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma Effect[VS = VS; PS = PS]
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EffectAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
#define EDITOR
|
|
||||||
|
|
||||||
Texture2D Texture : register(t0);
|
Texture2D Texture : register(t0);
|
||||||
SamplerState Sampler : register(s0);
|
SamplerState Sampler : register(s0);
|
||||||
|
|
||||||
@@ -16,9 +14,6 @@ struct VS_Input
|
|||||||
float4 Color : COLOR;
|
float4 Color : COLOR;
|
||||||
float4 UVTransform : TEXCOORD1;
|
float4 UVTransform : TEXCOORD1;
|
||||||
float InnerRadius : TEXCOORD2;
|
float InnerRadius : TEXCOORD2;
|
||||||
#ifdef EDITOR
|
|
||||||
uint EntityId : ENTITYID;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PS_Input
|
struct PS_Input
|
||||||
@@ -27,9 +22,6 @@ struct PS_Input
|
|||||||
float2 RawPos : TEXCOORD0;
|
float2 RawPos : TEXCOORD0;
|
||||||
float2 Texcoord : TEXCOORD1;
|
float2 Texcoord : TEXCOORD1;
|
||||||
float4 Color : COLOR;
|
float4 Color : COLOR;
|
||||||
#ifdef EDITOR
|
|
||||||
nointerpolation uint EntityId : ENTITYID;
|
|
||||||
#endif
|
|
||||||
float InnerRadius : TEXCOORD2;
|
float InnerRadius : TEXCOORD2;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -43,25 +35,11 @@ PS_Input VS(VS_Input input)
|
|||||||
output.Color = input.Color;
|
output.Color = input.Color;
|
||||||
output.InnerRadius = input.InnerRadius;
|
output.InnerRadius = input.InnerRadius;
|
||||||
|
|
||||||
#ifdef EDITOR
|
|
||||||
output.EntityId = input.EntityId;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PS_Output
|
float4 PS(PS_Input input) : SV_Target0
|
||||||
{
|
{
|
||||||
float4 Color : SV_Target0;
|
|
||||||
#ifdef EDITOR
|
|
||||||
uint EntityId : SV_TARGET1;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
PS_Output PS(PS_Input input)
|
|
||||||
{
|
|
||||||
PS_Output output;
|
|
||||||
|
|
||||||
float2 uv = input.RawPos * 2;
|
float2 uv = input.RawPos * 2;
|
||||||
|
|
||||||
float distance = 1.0f - length(uv);
|
float distance = 1.0f - length(uv);
|
||||||
@@ -75,14 +53,10 @@ PS_Output PS(PS_Input input)
|
|||||||
// Discard invisible pixels
|
// Discard invisible pixels
|
||||||
clip(amount - 0.5f);
|
clip(amount - 0.5f);
|
||||||
|
|
||||||
output.Color = Texture.Sample(Sampler, input.Texcoord) * input.Color;
|
float4 color = Texture.Sample(Sampler, input.Texcoord) * input.Color;
|
||||||
output.Color.a *= amount;
|
color.a *= amount;
|
||||||
|
|
||||||
#ifdef EDITOR
|
return color;
|
||||||
output.EntityId = input.EntityId;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma Effect[VS=VS; PS=PS]
|
#effect[VS=VS, PS=PS]
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EffectAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}
|
|
||||||
}
|
|
||||||
@@ -28,4 +28,4 @@ float4 PS(PS_Input input) : SV_Target0
|
|||||||
return Color;
|
return Color;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma Effect[VS=VS; PS=PS]
|
#effect[VS=VS, PS=PS]
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EffectAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
#define EDITOR
|
|
||||||
|
|
||||||
cbuffer Constants : register(b0)
|
|
||||||
{
|
|
||||||
float4x4 ViewProjection;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VS_Input
|
|
||||||
{
|
|
||||||
float4 Position : POSITION;
|
|
||||||
float4 Color : COLOR;
|
|
||||||
#ifdef EDITOR
|
|
||||||
uint EntityId : ENTITYID;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct PS_Input
|
|
||||||
{
|
|
||||||
float4 Position : SV_Position;
|
|
||||||
float4 Color : COLOR;
|
|
||||||
#ifdef EDITOR
|
|
||||||
nointerpolation uint EntityId : ENTITYID;
|
|
||||||
#endif
|
|
||||||
} VS_Output;
|
|
||||||
|
|
||||||
VS_Output VS(VS_Input input)
|
|
||||||
{
|
|
||||||
VS_Output output;
|
|
||||||
|
|
||||||
output.Position = mul(ViewProjection, input.Position);
|
|
||||||
output.Color = input.Color;
|
|
||||||
|
|
||||||
#ifdef EDITOR
|
|
||||||
output.EntityId = input.EntityId;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PS_Output
|
|
||||||
{
|
|
||||||
float4 Color : SV_TARGET0;
|
|
||||||
#ifdef EDITOR
|
|
||||||
uint EntityId : SV_TARGET1;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
PS_Output PS(PS_Input input)
|
|
||||||
{
|
|
||||||
PS_Output output;
|
|
||||||
|
|
||||||
output.Color = input.Color;
|
|
||||||
|
|
||||||
#ifdef EDITOR
|
|
||||||
output.EntityId = input.EntityId;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma Effect[VS=VS; PS=PS]
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EffectAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}/* No reflection data for GlitchyEditor.Assets.EffectAssetLoaderConfig. Add [BonTarget] or force it */
|
|
||||||
}
|
|
||||||
@@ -90,4 +90,4 @@ float4 PS(PS_Input input) : SV_Target0
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma Effect[VS=VS; PS=PS]
|
#effect[VS=VS, PS=PS]
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EffectAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}
|
|
||||||
}
|
|
||||||
@@ -1,152 +0,0 @@
|
|||||||
#define OutputEntityId
|
|
||||||
|
|
||||||
#include "ShaderHelpers.hlsl"
|
|
||||||
|
|
||||||
#include "GlitchyEngine.hlsl"
|
|
||||||
|
|
||||||
Texture2D AlbedoTexture : register(t0);
|
|
||||||
SamplerState AlbedoSampler : register(s0);
|
|
||||||
|
|
||||||
Texture2D<float3> NormalTexture : register(t1);
|
|
||||||
SamplerState NormalSampler : register(s1);
|
|
||||||
|
|
||||||
Texture2D<float> MetallicTexture : register(t2);
|
|
||||||
SamplerState MetallicSampler : register(s2);
|
|
||||||
|
|
||||||
Texture2D<float> RoughnessTexture : register(t3);
|
|
||||||
SamplerState RoughnessSampler : register(s3);
|
|
||||||
|
|
||||||
Texture2D<float3> EmissiveTexture : register(t4);
|
|
||||||
SamplerState EmissiveSampler : register(s4);
|
|
||||||
|
|
||||||
// Texture2D<float> AmbientTexture : register(t5);
|
|
||||||
// SamplerState AmbientSampler : register(s5);
|
|
||||||
|
|
||||||
cbuffer MaterialConstants : register(b2)
|
|
||||||
{
|
|
||||||
#pragma EditorVariable[ Name = "AlbedoColor"; Preview = "Albedo Color"; Type="Color" ]
|
|
||||||
float4 AlbedoColor = float4(1.0, 1.0, 1.0, 1.0);
|
|
||||||
#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 = 0.0;
|
|
||||||
#pragma EditorVariable[ Name = "RoughnessFactor"; Preview = "Rougness Factor"; Min = 0.0f; Max = 1.0f ]
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct VS_IN
|
|
||||||
{
|
|
||||||
float3 Position : POSITION;
|
|
||||||
float3 Normal : NORMAL;
|
|
||||||
// Todo: Tangent.w... handedness
|
|
||||||
float3 Tangent : TANGENT;
|
|
||||||
float2 TexCoord : TEXCOORD;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct PS_IN
|
|
||||||
{
|
|
||||||
float4 Position : SV_POSITION;
|
|
||||||
float3 WorldPosition : WORLDPOSITION;
|
|
||||||
float3 Normal : NORMAL;
|
|
||||||
float3 Tangent : TANGENT;
|
|
||||||
float2 TexCoord : TEXCOORD;
|
|
||||||
//nointerpolation float Handedness : HANDEDNESS;
|
|
||||||
#ifdef OutputEntityId
|
|
||||||
nointerpolation uint EntityId : ENTITYID;
|
|
||||||
#endif
|
|
||||||
} VS_OUT;
|
|
||||||
|
|
||||||
VS_OUT VS(VS_IN input)
|
|
||||||
{
|
|
||||||
VS_OUT output;
|
|
||||||
|
|
||||||
float4 worldPosition = mul(Transform, float4(input.Position, 1));
|
|
||||||
|
|
||||||
output.Position = mul(ViewProjection, worldPosition);
|
|
||||||
output.WorldPosition = worldPosition.xyz / worldPosition.w;
|
|
||||||
|
|
||||||
output.Normal = mul(Transform_InvT, input.Normal);
|
|
||||||
output.Tangent = mul((float3x3)Transform, input.Tangent);
|
|
||||||
// TODO: output.Handedness = input.Tangent.w
|
|
||||||
|
|
||||||
output.TexCoord = input.TexCoord;
|
|
||||||
|
|
||||||
output.EntityId = EntityId;
|
|
||||||
|
|
||||||
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
|
|
||||||
//};
|
|
||||||
|
|
||||||
PS_OUT_Lit PS(PS_IN input)
|
|
||||||
{
|
|
||||||
// Build tangent space
|
|
||||||
float3 normal = normalize(input.Normal);
|
|
||||||
float3 tangent = normalize(input.Tangent - dot(input.Tangent, normal) * input.Normal);
|
|
||||||
// TODO: float3 bitangent = input.Handedness * cross(normal, tangent);
|
|
||||||
float3 bitangent = -cross(normal, tangent);
|
|
||||||
|
|
||||||
//float3x3 tangentTransform = float3x3(tangent, bitangent, normal);
|
|
||||||
//tangentTransform = transpose(tangentTransform);
|
|
||||||
|
|
||||||
float4 texAlbedo = AlbedoTexture.Sample(AlbedoSampler, input.TexCoord);
|
|
||||||
float3 texNormal = NormalTexture.Sample(NormalSampler, input.TexCoord);
|
|
||||||
texNormal.xy = texNormal.xy * 2.0 - 1.0;
|
|
||||||
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);
|
|
||||||
|
|
||||||
float4 finalAlbedo = texAlbedo * AlbedoColor;
|
|
||||||
float3 finalNormal = ScaleNormal(texNormal, NormalScaling);
|
|
||||||
float finalMetallic = texMetallic * MetallicFactor;
|
|
||||||
float finalRoughness = texRoughness * RoughnessFactor;
|
|
||||||
float3 finalEmissive = texEmissive * EmissiveColor;
|
|
||||||
|
|
||||||
/////////////TODO: REMOVEME
|
|
||||||
|
|
||||||
//worldNormal = max(worldNormal - 10000000, normal);
|
|
||||||
//texAlbedo = max(texAlbedo - 10000000, 1.0);
|
|
||||||
//texMetallic = max(texMetallic - 10000000, 0.0);
|
|
||||||
//texRoughness = max(texRoughness - 10000000, 0.1);
|
|
||||||
|
|
||||||
/////////////TODO: END_REMOVEME
|
|
||||||
|
|
||||||
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
|
|
||||||
output.EntityId = input.EntityId;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma Effect[VS = VS; PS = PS]
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EffectAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}
|
|
||||||
}
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
#include "ShaderHelpers.hlsl"
|
|
||||||
#include "PBR.hlsl"
|
|
||||||
|
|
||||||
#define Render 0
|
|
||||||
#define Inspect_NormalDistribution 1
|
|
||||||
#define Inspect_GeometryFunction 2
|
|
||||||
#define Inspect_Fresnel 3
|
|
||||||
#define Inspect_Normal 4
|
|
||||||
|
|
||||||
#define OUTPUT Render
|
|
||||||
|
|
||||||
SamplerState Sampler : register(s0);
|
|
||||||
|
|
||||||
Texture2D GBuffer_Albedo : register(t0);
|
|
||||||
Texture2D GBuffer_Normal : register(t1);
|
|
||||||
Texture2D GBuffer_Tangent : register(t2);
|
|
||||||
Texture2D GBuffer_Position : register(t3);
|
|
||||||
Texture2D GBuffer_Emissive : register(t4);
|
|
||||||
Texture2D GBuffer_Material : register(t5);
|
|
||||||
|
|
||||||
cbuffer Constants
|
|
||||||
{
|
|
||||||
float3 CameraPos;
|
|
||||||
float2 Scaling;
|
|
||||||
}
|
|
||||||
|
|
||||||
cbuffer LightConstants
|
|
||||||
{
|
|
||||||
float3 LightColor;
|
|
||||||
float Illuminance;
|
|
||||||
float3 LightDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct VS_IN
|
|
||||||
{
|
|
||||||
float2 Position : POSITION;
|
|
||||||
float2 TexCoord : TEXCOORD0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PS_IN
|
|
||||||
{
|
|
||||||
float4 Position : SV_POSITION;
|
|
||||||
float2 TexCoord : TEXCOORD;
|
|
||||||
};
|
|
||||||
|
|
||||||
PS_IN VS(VS_IN input)
|
|
||||||
{
|
|
||||||
PS_IN output;
|
|
||||||
|
|
||||||
output.Position = float4(input.Position, 0, 1);
|
|
||||||
output.TexCoord = input.TexCoord * Scaling;
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS(PS_IN input) : SV_TARGET
|
|
||||||
{
|
|
||||||
// Load Data from GBuffer
|
|
||||||
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 rawEmissive = GBuffer_Emissive.Sample(Sampler, input.TexCoord);
|
|
||||||
float4 rawMaterial = GBuffer_Material.Sample(Sampler, input.TexCoord);
|
|
||||||
|
|
||||||
// Extract data from GBuffer
|
|
||||||
float3 albedo = rawAlbedo.rgb;
|
|
||||||
//float3 surfaceNormal = normalize(rawNormal.xyz);
|
|
||||||
float3 worldPosition = rawPosition.xyz;
|
|
||||||
|
|
||||||
float metallic = rawMaterial.r;
|
|
||||||
float roughness = rawMaterial.g;
|
|
||||||
|
|
||||||
float3 textureNormal = DecompressNormal(rawNormal.rg);
|
|
||||||
float3 rawGeoNrm = float3(rawNormal.ba, rawTangent.r);
|
|
||||||
float3 rawGeoTan = rawTangent.gba;
|
|
||||||
|
|
||||||
// Reconstruct normal space
|
|
||||||
float3 normal = normalize(rawGeoNrm);
|
|
||||||
float3 tangent = normalize(rawGeoTan - dot(rawGeoTan, normal) * normal);
|
|
||||||
float3 bitangent = -cross(normal, tangent);
|
|
||||||
|
|
||||||
float3x3 tangentTransform = float3x3(tangent, bitangent, normal);
|
|
||||||
|
|
||||||
float3 surfaceNormal = mul(textureNormal, tangentTransform);
|
|
||||||
|
|
||||||
float3 lightDir = normalize(LightDir);
|
|
||||||
float3 viewDir = normalize(CameraPos - worldPosition.xyz);
|
|
||||||
float3 halfway = normalize(lightDir + viewDir);
|
|
||||||
|
|
||||||
float n_dot_v = max(dot(surfaceNormal, viewDir), 0.0f);
|
|
||||||
float n_dot_h = max(dot(surfaceNormal, halfway), 0.0f);
|
|
||||||
float n_dot_l = max(dot(surfaceNormal, lightDir), 0.0f);
|
|
||||||
|
|
||||||
float nrmDist = NormalDistributionGGX(surfaceNormal, halfway, roughness);
|
|
||||||
float geo = GeometrySmith(surfaceNormal, viewDir, lightDir, roughness);
|
|
||||||
|
|
||||||
float3 F0 = 0.04f;
|
|
||||||
F0 = lerp(F0, albedo, metallic);
|
|
||||||
float3 fresnel = FresnelSchlick(n_dot_h, F0);
|
|
||||||
|
|
||||||
float3 ks = fresnel;
|
|
||||||
float3 kd = 1.0f - ks;
|
|
||||||
|
|
||||||
// Metals have no diffuse light
|
|
||||||
kd *= 1.0f - metallic;
|
|
||||||
|
|
||||||
float3 diffuse = albedo / PI;
|
|
||||||
float3 specular = (nrmDist * fresnel * geo) / max(4 * n_dot_v * n_dot_l, 0.0001f);
|
|
||||||
|
|
||||||
float3 luminanceColor = LightColor * Illuminance;
|
|
||||||
|
|
||||||
float3 final = (kd * diffuse + specular) * luminanceColor * n_dot_l + rawEmissive;
|
|
||||||
|
|
||||||
#if OUTPUT == Inspect_NormalDistribution
|
|
||||||
final = max(final - 10000000, nrmDist.xxx);
|
|
||||||
#elif OUTPUT == Inspect_GeometryFunction
|
|
||||||
final = max(final - 10000000, geo.xxx);
|
|
||||||
#elif OUTPUT == Inspect_Fresnel
|
|
||||||
final = max(final - 10000000, fresnel);
|
|
||||||
#elif OUTPUT == Inspect_Normal
|
|
||||||
final = max(final - 10000000, surfaceNormal / 2 + 0.5f);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return float4(final, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma Effect[VS = VS; PS = PS]
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EffectAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
#define EDITOR
|
|
||||||
|
|
||||||
Texture2D Texture : register(t0);
|
Texture2D Texture : register(t0);
|
||||||
SamplerState Sampler : register(s0);
|
SamplerState Sampler : register(s0);
|
||||||
|
|
||||||
@@ -15,9 +13,6 @@ struct VS_Input
|
|||||||
float4x4 Transform : TRANSFORM;
|
float4x4 Transform : TRANSFORM;
|
||||||
float4 Color : COLOR;
|
float4 Color : COLOR;
|
||||||
float4 UVTransform : TEXCOORD1;
|
float4 UVTransform : TEXCOORD1;
|
||||||
#ifdef EDITOR
|
|
||||||
uint EntityId : ENTITYID;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PS_Input
|
struct PS_Input
|
||||||
@@ -25,9 +20,6 @@ struct PS_Input
|
|||||||
float4 Position : SV_Position;
|
float4 Position : SV_Position;
|
||||||
float2 Texcoord : TEXCOORD;
|
float2 Texcoord : TEXCOORD;
|
||||||
float4 Color : COLOR;
|
float4 Color : COLOR;
|
||||||
#ifdef EDITOR
|
|
||||||
nointerpolation uint EntityId : ENTITYID;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
PS_Input VS(VS_Input input)
|
PS_Input VS(VS_Input input)
|
||||||
@@ -38,37 +30,12 @@ PS_Input VS(VS_Input input)
|
|||||||
output.Texcoord = input.UVTransform.xy + input.UVTransform.zw * input.Texcoord;
|
output.Texcoord = input.UVTransform.xy + input.UVTransform.zw * input.Texcoord;
|
||||||
output.Color = input.Color;
|
output.Color = input.Color;
|
||||||
|
|
||||||
// Premultiply Alpha
|
|
||||||
output.Color.rgb *= output.Color.a;
|
|
||||||
|
|
||||||
#ifdef EDITOR
|
|
||||||
output.EntityId = input.EntityId;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PS_Output
|
float4 PS(PS_Input input) : SV_Target0
|
||||||
{
|
{
|
||||||
float4 Color : SV_Target0;
|
return Texture.Sample(Sampler, input.Texcoord) * input.Color;
|
||||||
#ifdef EDITOR
|
|
||||||
uint EntityId : SV_TARGET1;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
PS_Output PS(PS_Input input)
|
|
||||||
{
|
|
||||||
PS_Output output;
|
|
||||||
|
|
||||||
output.Color = Texture.Sample(Sampler, input.Texcoord) * input.Color;
|
|
||||||
|
|
||||||
clip(output.Color.a - 0.001f);
|
|
||||||
|
|
||||||
#ifdef EDITOR
|
|
||||||
output.EntityId = input.EntityId;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma Effect[VS = VS; PS = PS]
|
#effect[VS=VS, PS=PS]
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EffectAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
Texture2D Texture : register(t0);
|
|
||||||
SamplerState Sampler : register(s0);
|
|
||||||
|
|
||||||
cbuffer Constants
|
|
||||||
{
|
|
||||||
float4x4 ViewProjection;
|
|
||||||
|
|
||||||
float ColorOffset = 0.5f;
|
|
||||||
float AlphaOffset = 0.0f;
|
|
||||||
float ColorScale = 0.5f;
|
|
||||||
float AlphaScale = 1.0f;
|
|
||||||
|
|
||||||
float2 TextureSizeInPixels;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct VS_Input
|
|
||||||
{
|
|
||||||
float2 Position : POSITION;
|
|
||||||
float2 Texcoord : TEXCOORD0;
|
|
||||||
float4x4 Transform : TRANSFORM;
|
|
||||||
float4 Color : COLOR;
|
|
||||||
float4 UVTransform : TEXCOORD1;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PS_Input
|
|
||||||
{
|
|
||||||
float4 Position : SV_Position;
|
|
||||||
float2 Texcoord : TEXCOORD0;
|
|
||||||
float4 Color : COLOR;
|
|
||||||
};
|
|
||||||
|
|
||||||
PS_Input VS(VS_Input input)
|
|
||||||
{
|
|
||||||
PS_Input output;
|
|
||||||
|
|
||||||
output.Position = mul(ViewProjection, mul(input.Transform, float4(input.Position, 0.0f, 1.0f)));
|
|
||||||
output.Texcoord = input.UVTransform.xy + input.UVTransform.zw * input.Texcoord;
|
|
||||||
output.Color = input.Color;
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS(PS_Input input) : SV_Target0
|
|
||||||
{
|
|
||||||
float4 color = Texture.Sample(Sampler, input.Texcoord);
|
|
||||||
|
|
||||||
float4 final = float4(ColorOffset.xxx, AlphaOffset) + color * float4(ColorScale.xxx, AlphaScale);
|
|
||||||
|
|
||||||
return final;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma Effect[VS=VS; PS=PS]
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EffectAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 119 B |
@@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EditorTextureAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EditorTextureAssetLoaderConfig){
|
|
||||||
_samplerStateDescription = {
|
|
||||||
MinFilter = .Linear,
|
|
||||||
MagFilter = .Linear,
|
|
||||||
MipFilter = .Linear,
|
|
||||||
ComparisonFunction = .Never,
|
|
||||||
AddressModeU = .Clamp,
|
|
||||||
AddressModeV = .Clamp,
|
|
||||||
AddressModeW = .Clamp,
|
|
||||||
MipMinLOD = -340282346638528859811704183484516925440,
|
|
||||||
MipMaxLOD = 340282346638528859811704183484516925440,
|
|
||||||
MaxAnisotropy = 1,
|
|
||||||
BorderColor = {
|
|
||||||
R = 1,
|
|
||||||
G = 1,
|
|
||||||
B = 1,
|
|
||||||
A = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EditorTextureAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EditorTextureAssetLoaderConfig){
|
|
||||||
_samplerStateDescription = {
|
|
||||||
MinFilter = .Linear,
|
|
||||||
MagFilter = .Linear,
|
|
||||||
MipFilter = .Linear,
|
|
||||||
ComparisonFunction = .Never,
|
|
||||||
AddressModeU = .Clamp,
|
|
||||||
AddressModeV = .Clamp,
|
|
||||||
AddressModeW = .Clamp,
|
|
||||||
MipMinLOD = -340282346638528859811704183484516925440,
|
|
||||||
MipMaxLOD = 340282346638528859811704183484516925440,
|
|
||||||
MaxAnisotropy = 1,
|
|
||||||
BorderColor = {
|
|
||||||
R = 1,
|
|
||||||
G = 1,
|
|
||||||
B = 1,
|
|
||||||
A = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -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,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "MaterialAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.ModelAssetLoaderConfig){}/* No reflection data for GlitchyEditor.Assets.ModelAssetLoaderConfig. Add [BonTarget] or force it */
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 119 B |
@@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EditorTextureAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EditorTextureAssetLoaderConfig){
|
|
||||||
_samplerStateDescription = {
|
|
||||||
MinFilter = .Linear,
|
|
||||||
MagFilter = .Linear,
|
|
||||||
MipFilter = .Linear,
|
|
||||||
ComparisonFunction = .Never,
|
|
||||||
AddressModeU = .Clamp,
|
|
||||||
AddressModeV = .Clamp,
|
|
||||||
AddressModeW = .Clamp,
|
|
||||||
MipMinLOD = -340282346638528859811704183484516925440,
|
|
||||||
MipMaxLOD = 340282346638528859811704183484516925440,
|
|
||||||
MaxAnisotropy = 1,
|
|
||||||
BorderColor = {
|
|
||||||
R = 1,
|
|
||||||
G = 1,
|
|
||||||
B = 1,
|
|
||||||
A = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EditorTextureAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EditorTextureAssetLoaderConfig){
|
|
||||||
_generateMipMaps = true,
|
|
||||||
_isSrgb = true,
|
|
||||||
_samplerStateDescription = {
|
|
||||||
MinFilter = .Anisotropic,
|
|
||||||
MagFilter = .Anisotropic,
|
|
||||||
MipFilter = .Anisotropic,
|
|
||||||
FilterMode = .Default,
|
|
||||||
ComparisonFunction = .Never,
|
|
||||||
AddressModeU = .Wrap,
|
|
||||||
AddressModeV = .Wrap,
|
|
||||||
AddressModeW = .Wrap,
|
|
||||||
MipLODBias = 0,
|
|
||||||
MipMinLOD = 0,
|
|
||||||
MipMaxLOD = 3,
|
|
||||||
MaxAnisotropy = 16,
|
|
||||||
BorderColor = {
|
|
||||||
R = 1,
|
|
||||||
G = 1,
|
|
||||||
B = 1,
|
|
||||||
A = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.3 MiB |
@@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 7.4 MiB |
@@ -1,27 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EditorTextureAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EditorTextureAssetLoaderConfig){
|
|
||||||
_generateMipMaps = false,
|
|
||||||
_isSrgb = false,
|
|
||||||
_samplerStateDescription = {
|
|
||||||
MinFilter = .Linear,
|
|
||||||
MagFilter = .Linear,
|
|
||||||
MipFilter = .Linear,
|
|
||||||
FilterMode = .Default,
|
|
||||||
ComparisonFunction = .Never,
|
|
||||||
AddressModeU = .Wrap,
|
|
||||||
AddressModeV = .Wrap,
|
|
||||||
AddressModeW = .Clamp,
|
|
||||||
MipLODBias = 2.5999999,
|
|
||||||
MipMinLOD = -Infinity,
|
|
||||||
MipMaxLOD = Infinity,
|
|
||||||
MaxAnisotropy = 1,
|
|
||||||
BorderColor = {
|
|
||||||
R = 1,
|
|
||||||
G = 1,
|
|
||||||
B = 1,
|
|
||||||
A = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.0 MiB |
@@ -1,27 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EditorTextureAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EditorTextureAssetLoaderConfig){
|
|
||||||
_generateMipMaps = false,
|
|
||||||
_isSrgb = true,
|
|
||||||
_samplerStateDescription = {
|
|
||||||
MinFilter = .Linear,
|
|
||||||
MagFilter = .Linear,
|
|
||||||
MipFilter = .Linear,
|
|
||||||
FilterMode = .Default,
|
|
||||||
ComparisonFunction = .Never,
|
|
||||||
AddressModeU = .Wrap,
|
|
||||||
AddressModeV = .Wrap,
|
|
||||||
AddressModeW = .Clamp,
|
|
||||||
MipLODBias = 0,
|
|
||||||
MipMinLOD = -3.40282347e+38,
|
|
||||||
MipMaxLOD = 3.40282347e+38,
|
|
||||||
MaxAnisotropy = 1,
|
|
||||||
BorderColor = {
|
|
||||||
R = 1,
|
|
||||||
G = 1,
|
|
||||||
B = 1,
|
|
||||||
A = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +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",
|
|
||||||
"EmissiveTexture": "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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "MaterialAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.ModelAssetLoaderConfig){}
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 119 B |
@@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EditorTextureAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EditorTextureAssetLoaderConfig){
|
|
||||||
_samplerStateDescription = {
|
|
||||||
MinFilter = .Linear,
|
|
||||||
MagFilter = .Linear,
|
|
||||||
MipFilter = .Linear,
|
|
||||||
ComparisonFunction = .Never,
|
|
||||||
AddressModeU = .Clamp,
|
|
||||||
AddressModeV = .Clamp,
|
|
||||||
AddressModeW = .Clamp,
|
|
||||||
MipMinLOD = -340282346638528859811704183484516925440,
|
|
||||||
MipMaxLOD = 340282346638528859811704183484516925440,
|
|
||||||
MaxAnisotropy = 1,
|
|
||||||
BorderColor = {
|
|
||||||
R = 1,
|
|
||||||
G = 1,
|
|
||||||
B = 1,
|
|
||||||
A = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EditorTextureAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EditorTextureAssetLoaderConfig){
|
|
||||||
_isSrgb = true,
|
|
||||||
_samplerStateDescription = {
|
|
||||||
MinFilter = .Linear,
|
|
||||||
MagFilter = .Linear,
|
|
||||||
MipFilter = .Linear,
|
|
||||||
ComparisonFunction = .Never,
|
|
||||||
AddressModeU = .Clamp,
|
|
||||||
AddressModeV = .Clamp,
|
|
||||||
AddressModeW = .Clamp,
|
|
||||||
MipMinLOD = -3.40282347e+38,
|
|
||||||
MipMaxLOD = 3.40282347e+38,
|
|
||||||
MaxAnisotropy = 1,
|
|
||||||
BorderColor = {
|
|
||||||
R = 1,
|
|
||||||
G = 1,
|
|
||||||
B = 1,
|
|
||||||
A = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EditorTextureAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EditorTextureAssetLoaderConfig){
|
|
||||||
_isSrgb = true,
|
|
||||||
_samplerStateDescription = {
|
|
||||||
MinFilter = .Linear,
|
|
||||||
ComparisonFunction = .Never,
|
|
||||||
AddressModeU = .Clamp,
|
|
||||||
AddressModeV = .Clamp,
|
|
||||||
AddressModeW = .Clamp,
|
|
||||||
MipMinLOD = -340282346638528859811704183484516925440,
|
|
||||||
MipMaxLOD = 340282346638528859811704183484516925440,
|
|
||||||
MaxAnisotropy = 1,
|
|
||||||
BorderColor = {
|
|
||||||
R = 1,
|
|
||||||
G = 1,
|
|
||||||
B = 1,
|
|
||||||
A = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
AssetLoader = "EditorTextureAssetLoader",
|
|
||||||
Config = (GlitchyEditor.Assets.EditorTextureAssetLoaderConfig){
|
|
||||||
_isSrgb = true,
|
|
||||||
_samplerStateDescription = {
|
|
||||||
MinFilter = .Linear,
|
|
||||||
MagFilter = .Linear,
|
|
||||||
MipFilter = .Linear,
|
|
||||||
ComparisonFunction = .Never,
|
|
||||||
AddressModeU = .Clamp,
|
|
||||||
AddressModeV = .Clamp,
|
|
||||||
AddressModeW = .Clamp,
|
|
||||||
MipMinLOD = -Infinity,
|
|
||||||
MipMaxLOD = Infinity,
|
|
||||||
MaxAnisotropy = 1,
|
|
||||||
BorderColor = {
|
|
||||||
R = 1,
|
|
||||||
G = 1,
|
|
||||||
B = 1,
|
|
||||||
A = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
4.5/
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Install mono and copy the folder `lib/mono/4.5` here!
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"runtimeTarget": {
|
|
||||||
"name": ".NETCoreApp,Version=v7.0",
|
|
||||||
"signature": ""
|
|
||||||
},
|
|
||||||
"compilationOptions": {},
|
|
||||||
"targets": {
|
|
||||||
".NETCoreApp,Version=v7.0": {
|
|
||||||
"ScriptCore/1.0.0": {
|
|
||||||
"runtime": {
|
|
||||||
"ScriptCore.dll": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"libraries": {
|
|
||||||
"ScriptCore/1.0.0": {
|
|
||||||
"type": "project",
|
|
||||||
"serviceable": false,
|
|
||||||
"sha512": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"runtimeOptions": {
|
|
||||||
"additionalProbingPaths": [
|
|
||||||
"C:\\Users\\Simon\\.dotnet\\store\\|arch|\\|tfm|",
|
|
||||||
"C:\\Users\\Simon\\.nuget\\packages",
|
|
||||||
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"runtimeOptions": {
|
|
||||||
"tfm": "net7.0",
|
|
||||||
"rollForward": "LatestMinor",
|
|
||||||
"framework": {
|
|
||||||
"name": "Microsoft.NETCore.App",
|
|
||||||
"version": "7.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
using System;
|
|
||||||
using GlitchyEngine;
|
|
||||||
using System.IO;
|
|
||||||
using Bon;
|
|
||||||
using GlitchyEngine.Content;
|
|
||||||
|
|
||||||
namespace GlitchyEditor;
|
|
||||||
|
|
||||||
[BonTarget]
|
|
||||||
class AssetConfig
|
|
||||||
{
|
|
||||||
[BonIgnore]
|
|
||||||
public bool IgnoreFile = false;
|
|
||||||
|
|
||||||
[BonInclude]
|
|
||||||
public String AssetLoader ~ delete _;
|
|
||||||
|
|
||||||
[BonInclude]
|
|
||||||
public AssetLoaderConfig Config ~ delete _;
|
|
||||||
}
|
|
||||||
|
|
||||||
class AssetFile
|
|
||||||
{
|
|
||||||
private EditorContentManager _contentManager;
|
|
||||||
|
|
||||||
private String _path;
|
|
||||||
private String _identifier;
|
|
||||||
private String _assetConfigPath;
|
|
||||||
|
|
||||||
private AssetConfig _assetConfig ~ delete _;
|
|
||||||
|
|
||||||
private bool _isDirectory;
|
|
||||||
|
|
||||||
private Asset _loadedAsset;
|
|
||||||
|
|
||||||
public bool IsDirectory => _isDirectory;
|
|
||||||
|
|
||||||
public StringView FilePath => _path;
|
|
||||||
public StringView Identifier => _identifier;
|
|
||||||
|
|
||||||
public const String ConfigFileExtension = ".ass";
|
|
||||||
|
|
||||||
public AssetConfig AssetConfig => _assetConfig;
|
|
||||||
|
|
||||||
public Asset LoadedAsset => _loadedAsset;
|
|
||||||
|
|
||||||
[AllowAppend]
|
|
||||||
public this(EditorContentManager contentManager, StringView identifier, StringView path, bool isDirectory)
|
|
||||||
{
|
|
||||||
String identifierBuffer = append String(identifier);
|
|
||||||
String pathBuffer = append String(path);
|
|
||||||
String configPathBuffer = append String(path.Length + ConfigFileExtension.Length);
|
|
||||||
|
|
||||||
_identifier = identifierBuffer;
|
|
||||||
_path = pathBuffer;
|
|
||||||
|
|
||||||
configPathBuffer..Append(path).Append(ConfigFileExtension);
|
|
||||||
_assetConfigPath = configPathBuffer;
|
|
||||||
|
|
||||||
_contentManager = contentManager;
|
|
||||||
|
|
||||||
_isDirectory = isDirectory;
|
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(File.Exists(_path), "File doesn't exist.");
|
|
||||||
|
|
||||||
FindAssetConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loads the asset config (.ass) file or creates it.
|
|
||||||
private void FindAssetConfig()
|
|
||||||
{
|
|
||||||
if (File.Exists(_assetConfigPath))
|
|
||||||
{
|
|
||||||
LoadAssetConfig();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CreateDefaultAssetLoader();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CreateDefaultAssetLoader()
|
|
||||||
{
|
|
||||||
String fileExtension = Path.GetExtension(_path, .. scope .());
|
|
||||||
|
|
||||||
_assetConfig = new AssetConfig();
|
|
||||||
var assetLoader = _contentManager.GetDefaultAssetLoader(fileExtension);
|
|
||||||
|
|
||||||
// We don't have a loader -> we don't need a config
|
|
||||||
if (assetLoader == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_assetConfig.AssetLoader = new String();
|
|
||||||
assetLoader.GetType().GetName(_assetConfig.AssetLoader);
|
|
||||||
|
|
||||||
_assetConfig.Config = assetLoader?.GetDefaultConfig();
|
|
||||||
_assetConfig.Config?.[Friend]_changed = true;
|
|
||||||
|
|
||||||
SaveAssetConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LoadAssetConfig()
|
|
||||||
{
|
|
||||||
if (Bon.DeserializeFromFile(ref _assetConfig, _assetConfigPath) case .Err)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Error($"Failed to load asset config {_assetConfigPath}");
|
|
||||||
|
|
||||||
// TODO: Handle failure of asset config loading
|
|
||||||
Runtime.NotImplemented();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveAssetConfig()
|
|
||||||
{
|
|
||||||
gBonEnv.serializeFlags |= .Verbose;
|
|
||||||
|
|
||||||
Bon.SerializeIntoFile(_assetConfig, _assetConfigPath);
|
|
||||||
|
|
||||||
_assetConfig.Config.[Friend]_changed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,426 +0,0 @@
|
|||||||
using GlitchyEngine;
|
|
||||||
using GlitchyEngine.Collections;
|
|
||||||
using GlitchyEngine.Renderer;
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace GlitchyEditor.Assets;
|
|
||||||
|
|
||||||
public class AssetNode
|
|
||||||
{
|
|
||||||
public String Name ~ delete _;
|
|
||||||
public String Path ~ delete _;
|
|
||||||
|
|
||||||
public bool IsDirectory;
|
|
||||||
|
|
||||||
public AssetFile AssetFile ~ delete _;
|
|
||||||
|
|
||||||
public List<SubAsset> SubAssets ~ {
|
|
||||||
SubAssets?.ClearAndDeleteItems();
|
|
||||||
delete SubAssets;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Texture2D PreviewImage ~ _?.ReleaseRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SubAsset
|
|
||||||
{
|
|
||||||
public AssetNode Asset;
|
|
||||||
public String Name ~ delete _;
|
|
||||||
//public String AssetInternalPath ~ delete _;
|
|
||||||
|
|
||||||
public Texture2D PreviewImage ~ _?.ReleaseRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class AssetIdentifier
|
|
||||||
{
|
|
||||||
public const char8 DirectorySeparatorChar = '/';
|
|
||||||
|
|
||||||
public static void Fixup(String assetIdentifier)
|
|
||||||
{
|
|
||||||
const String DotSeperator = $".{DirectorySeparatorChar}";
|
|
||||||
const String SeperatorDot = $"{DirectorySeparatorChar}.";
|
|
||||||
|
|
||||||
assetIdentifier.Replace('\\', DirectorySeparatorChar);
|
|
||||||
assetIdentifier.Replace(DotSeperator, "");
|
|
||||||
assetIdentifier.Replace(SeperatorDot, "");
|
|
||||||
|
|
||||||
if (assetIdentifier.StartsWith(DirectorySeparatorChar))
|
|
||||||
assetIdentifier.Remove(0, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class AssetHierarchy
|
|
||||||
{
|
|
||||||
FileSystemWatcher fsw ~ {
|
|
||||||
_.StopRaisingEvents();
|
|
||||||
delete _;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool _fileSystemDirty = false;
|
|
||||||
|
|
||||||
internal TreeNode<AssetNode> _assetHierarchy = null ~ DeleteTreeAndChildren!(_);
|
|
||||||
private append Dictionary<StringView, TreeNode<AssetNode>> _pathToAssetNode = .();
|
|
||||||
|
|
||||||
private append String _contentDirectory = .();
|
|
||||||
|
|
||||||
private EditorContentManager _contentManager;
|
|
||||||
|
|
||||||
public StringView ContentDirectory
|
|
||||||
{
|
|
||||||
get => _contentDirectory;
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
_contentDirectory.Clear();
|
|
||||||
_contentDirectory.Append(value);
|
|
||||||
Path.Fixup(_contentDirectory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(EditorContentManager contentManager)
|
|
||||||
{
|
|
||||||
_contentManager = contentManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetContentDirectory(StringView contentDirectory)
|
|
||||||
{
|
|
||||||
ContentDirectory = contentDirectory;
|
|
||||||
|
|
||||||
_fileSystemDirty = true;
|
|
||||||
|
|
||||||
SetupFileSystemWatcher();
|
|
||||||
|
|
||||||
Update();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Initializes the FSW for the current ContentDirectory and registers the events.
|
|
||||||
private void SetupFileSystemWatcher()
|
|
||||||
{
|
|
||||||
delete fsw;
|
|
||||||
fsw = new FileSystemWatcher(_contentDirectory);
|
|
||||||
fsw.IncludeSubdirectories = true;
|
|
||||||
|
|
||||||
fsw.OnChanged.Add(new (filename) => {
|
|
||||||
// Note: Gets fired for a directory if a file inside it is created/removed
|
|
||||||
|
|
||||||
Log.EngineLogger.Trace($"File content changed (\"{filename}\")");
|
|
||||||
//_fileSystemDirty = true;
|
|
||||||
|
|
||||||
FileContentChanged(filename);
|
|
||||||
});
|
|
||||||
|
|
||||||
fsw.OnCreated.Add(new (filename) => {
|
|
||||||
Log.EngineLogger.Trace($"File created (\"{filename}\")");
|
|
||||||
|
|
||||||
_fileSystemDirty = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
fsw.OnDeleted.Add(new (filename) => {
|
|
||||||
Log.EngineLogger.Trace($"File deleted (\"{filename}\")");
|
|
||||||
|
|
||||||
_fileSystemDirty = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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>> GetNodeFromPath(StringView filePath)
|
|
||||||
{
|
|
||||||
if (_pathToAssetNode.TryGetValue(filePath, let treeNode))
|
|
||||||
{
|
|
||||||
return treeNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
return .Err;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool FileExists(StringView filePath)
|
|
||||||
{
|
|
||||||
return _pathToAssetNode.ContainsKey(filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Update()
|
|
||||||
{
|
|
||||||
// TODO: do we really need to do this in the update loop?
|
|
||||||
if (_fileSystemDirty)
|
|
||||||
{
|
|
||||||
UpdateFiles();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Determines the files that belong to the given directory and adds them to the tree.
|
|
||||||
void AddFilesOfDirectory(TreeNode<AssetNode> directory)
|
|
||||||
{
|
|
||||||
// Filter that accepts all files.
|
|
||||||
String filter = scope $"{directory->Path}/*";
|
|
||||||
|
|
||||||
// Buffer used to hold the path of the files iterated below.
|
|
||||||
String filepathBuffer = scope String(256);
|
|
||||||
// Buffer used to hold the file extension of the files iterated below.
|
|
||||||
String extensionBuffer = scope String(16);
|
|
||||||
|
|
||||||
for (var entry in Directory.Enumerate(filter, .Files))
|
|
||||||
{
|
|
||||||
entry.GetFilePath(filepathBuffer..Clear());
|
|
||||||
|
|
||||||
Path.GetExtension(filepathBuffer, .. extensionBuffer..Clear());
|
|
||||||
|
|
||||||
// Ignore meta files.
|
|
||||||
if (extensionBuffer.Equals(AssetFile.ConfigFileExtension, .OrdinalIgnoreCase))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
TreeNode<AssetNode> treeNode = directory.Children.Where(scope (node) => node.Value.Path == filepathBuffer).FirstOrDefault();
|
|
||||||
|
|
||||||
if (treeNode == null)
|
|
||||||
{
|
|
||||||
AssetNode assetNode = new AssetNode();
|
|
||||||
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);
|
|
||||||
_pathToAssetNode.Add(assetNode.Path, treeNode);
|
|
||||||
|
|
||||||
//GrabSubAssets(node);
|
|
||||||
HandleFile(treeNode.Value);
|
|
||||||
|
|
||||||
Log.EngineLogger.Trace($"Created file node for: \"{assetNode.Path}\"");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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))
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Trace($"Removed orphaned node for: \"{child->Path}\"");
|
|
||||||
|
|
||||||
@child.Remove();
|
|
||||||
|
|
||||||
RemoveSubtree(child);
|
|
||||||
|
|
||||||
DeleteTreeAndChildren!(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds the given directory to the specified tree.
|
|
||||||
/// Recursively adds all Files and Subdirectories.
|
|
||||||
void AddDirectoryToTree(String path, TreeNode<AssetNode> parentNode)
|
|
||||||
{
|
|
||||||
path.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
|
||||||
|
|
||||||
// Try to find the node for the specified path in the given parent
|
|
||||||
TreeNode<AssetNode> treeNode = parentNode.Children.Where(scope (node) => node.Value.Path == path).FirstOrDefault();
|
|
||||||
|
|
||||||
// Create new Node for the Directory, if no TreeNode exists.
|
|
||||||
if (treeNode == null)
|
|
||||||
{
|
|
||||||
AssetNode assetNode = new AssetNode();
|
|
||||||
assetNode.Path = new String(path);
|
|
||||||
assetNode.Name = new String();
|
|
||||||
assetNode.IsDirectory = true;
|
|
||||||
Path.GetFileName(assetNode.Path, assetNode.Name);
|
|
||||||
|
|
||||||
treeNode = parentNode.AddChild(assetNode);
|
|
||||||
_pathToAssetNode.Add(assetNode.Path, treeNode);
|
|
||||||
|
|
||||||
Log.EngineLogger.Trace($"Created directory node for: \"{assetNode.Path}\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
String directoryNameBuffer = scope String(256);
|
|
||||||
|
|
||||||
// Filter that finds all entries of a directory.
|
|
||||||
String filter = scope $"{path}/*";
|
|
||||||
|
|
||||||
for (var directory in Directory.Enumerate(filter, .Directories))
|
|
||||||
{
|
|
||||||
directory.GetFilePath(directoryNameBuffer..Clear());
|
|
||||||
|
|
||||||
AddDirectoryToTree(directoryNameBuffer, treeNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
AddFilesOfDirectory(treeNode);
|
|
||||||
|
|
||||||
RemoveOrphanedEntries(treeNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
String filter = scope $"{ContentDirectory}/*";
|
|
||||||
|
|
||||||
String directoryNameBuffer = scope String(256);
|
|
||||||
|
|
||||||
for (var directory in Directory.Enumerate(filter, .Directories))
|
|
||||||
{
|
|
||||||
directory.GetFilePath(directoryNameBuffer..Clear());
|
|
||||||
|
|
||||||
AddDirectoryToTree(directoryNameBuffer, _assetHierarchy);
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveOrphanedEntries(_assetHierarchy);
|
|
||||||
|
|
||||||
_fileSystemDirty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FileContentChanged(StringView fileName)
|
|
||||||
{
|
|
||||||
var fileName;
|
|
||||||
|
|
||||||
// Config files aren't really tracked but changing them effectively changes the corresponding file
|
|
||||||
// so we fire the event for them.
|
|
||||||
if (fileName.EndsWith(AssetFile.ConfigFileExtension))
|
|
||||||
fileName.RemoveFromEnd(AssetFile.ConfigFileExtension.Length);
|
|
||||||
|
|
||||||
String fileNameWithContentRoot = scope .();
|
|
||||||
Path.InternalCombine(fileNameWithContentRoot, _contentDirectory, fileName);
|
|
||||||
|
|
||||||
var nodeResult = GetNodeFromPath(fileNameWithContentRoot);
|
|
||||||
|
|
||||||
TreeNode<AssetNode> node = null;
|
|
||||||
|
|
||||||
if (!(nodeResult case .Ok(out node)))
|
|
||||||
{
|
|
||||||
// This happens, when we create new files.
|
|
||||||
Log.EngineLogger.Trace($"Could not find node for file \"{fileNameWithContentRoot}\"");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't fire event for directories.
|
|
||||||
if (node->IsDirectory)
|
|
||||||
return;
|
|
||||||
|
|
||||||
OnFileContentChanged(node.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FileRenamed(StringView oldFilePath, StringView newFilePath)
|
|
||||||
{
|
|
||||||
var oldFilePath;
|
|
||||||
|
|
||||||
// Ignore Config files.
|
|
||||||
if (oldFilePath.EndsWith(AssetFile.ConfigFileExtension))
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
String oldFileNameWithContentRoot = scope .();
|
|
||||||
Path.InternalCombine(oldFileNameWithContentRoot, _contentDirectory, oldFilePath);
|
|
||||||
|
|
||||||
String newFileNameWithContentRoot = scope .();
|
|
||||||
Path.InternalCombine(newFileNameWithContentRoot, _contentDirectory, newFilePath);
|
|
||||||
|
|
||||||
// Rename config file
|
|
||||||
{
|
|
||||||
String oldConfigFileName = scope $"{oldFileNameWithContentRoot}{AssetFile.ConfigFileExtension}";
|
|
||||||
String newConfigFileName = scope $"{newFileNameWithContentRoot}{AssetFile.ConfigFileExtension}";
|
|
||||||
|
|
||||||
if (File.Exists(oldConfigFileName) && !File.Exists(newConfigFileName))
|
|
||||||
{
|
|
||||||
if (File.Move(oldConfigFileName, newConfigFileName) case .Err(let value))
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Error($"Failed to move file {oldConfigFileName} to {newConfigFileName}. Code: {value}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var nodeResult = GetNodeFromPath(oldFileNameWithContentRoot);
|
|
||||||
|
|
||||||
TreeNode<AssetNode> node = null;
|
|
||||||
|
|
||||||
if (!(nodeResult case .Ok(out node)))
|
|
||||||
{
|
|
||||||
// This happens, when we create new files.
|
|
||||||
Log.EngineLogger.Trace($"Could not find node for file \"{oldFileNameWithContentRoot}\"");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_pathToAssetNode.Remove(oldFileNameWithContentRoot);
|
|
||||||
|
|
||||||
node->Path.Set(newFileNameWithContentRoot);
|
|
||||||
_pathToAssetNode.Add(node->Path, node);
|
|
||||||
|
|
||||||
node->Name.Clear();
|
|
||||||
Path.GetFileName(newFileNameWithContentRoot, node->Name);
|
|
||||||
|
|
||||||
String oldIdentifier = scope .(node->AssetFile.[Friend]_identifier);
|
|
||||||
|
|
||||||
node->AssetFile.[Friend]_path.Set(node->Path);
|
|
||||||
|
|
||||||
node->AssetFile.[Friend]_identifier.Set(newFilePath);
|
|
||||||
AssetIdentifier.Fixup(node->AssetFile.[Friend]_identifier);
|
|
||||||
|
|
||||||
node->AssetFile.[Friend]_assetConfigPath..Set(node->Path).Append(AssetFile.ConfigFileExtension);
|
|
||||||
|
|
||||||
OnFileRenamed(node.Value, oldIdentifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
public delegate void FileContentChangedFunc(AssetNode node);
|
|
||||||
|
|
||||||
public Event<FileContentChangedFunc> OnFileContentChanged ~ _.Dispose();
|
|
||||||
|
|
||||||
public delegate void FileRenamedFunc(AssetNode node, StringView oldName);
|
|
||||||
|
|
||||||
public Event<FileRenamedFunc> OnFileRenamed ~ _.Dispose();
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
namespace GlitchyEditor.Assets;
|
|
||||||
|
|
||||||
abstract class AssetPropertiesEditor
|
|
||||||
{
|
|
||||||
private AssetFile _asset;
|
|
||||||
|
|
||||||
public AssetFile Asset => _asset;
|
|
||||||
|
|
||||||
public this(AssetFile asset)
|
|
||||||
{
|
|
||||||
_asset = asset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void ShowEditor();
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
using Bon;
|
|
||||||
using GlitchyEngine.Content;
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.IO;
|
|
||||||
using GlitchyEngine;
|
|
||||||
using GlitchyEngine.Renderer;
|
|
||||||
|
|
||||||
namespace GlitchyEditor.Assets;
|
|
||||||
|
|
||||||
class EffectAssetPropertiesEditor : AssetPropertiesEditor
|
|
||||||
{
|
|
||||||
public this(AssetFile asset) : base(asset)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ShowEditor()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AssetPropertiesEditor Factory(AssetFile assetFile)
|
|
||||||
{
|
|
||||||
return new Self(assetFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[BonTarget, BonPolyRegister]
|
|
||||||
class EffectAssetLoaderConfig : AssetLoaderConfig
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class EffectAssetLoader : IAssetLoader //, IReloadingAssetLoader
|
|
||||||
{
|
|
||||||
private static readonly List<StringView> _fileExtensions = new .(){".hlsl"} ~ delete _;
|
|
||||||
|
|
||||||
public static List<StringView> FileExtensions => _fileExtensions;
|
|
||||||
|
|
||||||
public AssetLoaderConfig GetDefaultConfig()
|
|
||||||
{
|
|
||||||
return new EffectAssetLoaderConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset LoadAsset(Stream file, AssetLoaderConfig config, StringView assetIdentifier, StringView? subAsset, IContentManager contentManager)
|
|
||||||
{
|
|
||||||
Effect effect = new Effect(file, assetIdentifier, contentManager);
|
|
||||||
|
|
||||||
return effect;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset GetPlaceholderAsset(Type assetType)
|
|
||||||
{
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset GetErrorAsset(Type assetType)
|
|
||||||
{
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
using GlitchyEngine.Content;
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace GlitchyEditor.Assets;
|
|
||||||
|
|
||||||
interface IAssetSaver
|
|
||||||
{
|
|
||||||
Result<void> EditorSaveAsset(Stream file, Asset asset, AssetLoaderConfig config, StringView assetIdentifier, StringView? subAsset, IContentManager contentManager);
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace GlitchyEditor.Assets;
|
|
||||||
|
|
||||||
interface IReloadingAssetLoader
|
|
||||||
{
|
|
||||||
public void ReloadAsset(AssetFile assetFile, Stream data);
|
|
||||||
}
|
|
||||||
@@ -1,748 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,535 +0,0 @@
|
|||||||
using Bon;
|
|
||||||
using GlitchyEngine.Content;
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.IO;
|
|
||||||
using GlitchyEngine;
|
|
||||||
using GlitchyEngine.Renderer;
|
|
||||||
using ImGui;
|
|
||||||
using GlitchyEngine.Math;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using Bon.Integrated;
|
|
||||||
|
|
||||||
namespace GlitchyEditor.Assets;
|
|
||||||
|
|
||||||
class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
|
||||||
{
|
|
||||||
public static bool TryGetValue(Dictionary<String, Variant> parameters, String name, out Variant value)
|
|
||||||
{
|
|
||||||
if (parameters.TryGetValue(name, let param))
|
|
||||||
{
|
|
||||||
value = param;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = ?;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mixin DropAssetTarget<T>() where T : Asset
|
|
||||||
{
|
|
||||||
AssetHandle handle = .Invalid;
|
|
||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
|
||||||
{
|
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
|
||||||
|
|
||||||
if (payload != null)
|
|
||||||
{
|
|
||||||
StringView fullpath = .((char8*)payload.Data, (int)payload.DataSize);
|
|
||||||
|
|
||||||
handle = Content.LoadAsset(fullpath);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndDragDropTarget();
|
|
||||||
}
|
|
||||||
|
|
||||||
handle
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(AssetFile asset) : base(asset)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ShowEditor()
|
|
||||||
{
|
|
||||||
Material material = Asset.LoadedAsset as Material;
|
|
||||||
|
|
||||||
if (material == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Effect effect = material?.Effect;
|
|
||||||
|
|
||||||
if (effect == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ShowTextures(material, effect);
|
|
||||||
|
|
||||||
ShowVariables(material, effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShowTextures(Material material, Effect effect)
|
|
||||||
{
|
|
||||||
for (let texture in effect.Textures)
|
|
||||||
{
|
|
||||||
ImGui.Button(texture.key);
|
|
||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
|
||||||
{
|
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
|
||||||
|
|
||||||
if (payload != null)
|
|
||||||
{
|
|
||||||
StringView path = .((char8*)payload.Data, (int)payload.DataSize);
|
|
||||||
|
|
||||||
AssetHandle<Texture2D> newTexture = Content.LoadAsset(path);
|
|
||||||
|
|
||||||
//newTexture.Get().SamplerState = SamplerStateManager.AnisotropicWrap;
|
|
||||||
material.SetTexture(texture.key, newTexture.Cast<Texture>());
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndDragDropTarget();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShowVariables(Material material, Effect effect)
|
|
||||||
{
|
|
||||||
for (let (name, arguments) in effect.[Friend]_variableDescriptions)
|
|
||||||
{
|
|
||||||
if (!effect.Variables.TryGetVariable(name, let variable))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
bool hasPreviewName = TryGetValue(arguments, "Preview", var previewName);
|
|
||||||
|
|
||||||
StringView displayName = hasPreviewName ? previewName.Get<String>() : name;
|
|
||||||
|
|
||||||
bool hasPreviewType = TryGetValue(arguments, "Type", var previewType);
|
|
||||||
|
|
||||||
if (hasPreviewType && (previewType.Get<String>() == "Color" || previewType.Get<String>() == "ColorHDR"))
|
|
||||||
{
|
|
||||||
if (previewType.Get<String>().Equals("Color", .InvariantCultureIgnoreCase))
|
|
||||||
{
|
|
||||||
Log.EngineLogger.AssertDebug(variable.Type == .Float && variable.Rows == 1);
|
|
||||||
|
|
||||||
if (variable.Columns == 3)
|
|
||||||
{
|
|
||||||
material.GetVariable<float3>(variable.Name, var value);
|
|
||||||
|
|
||||||
value = (float3)ColorRGB.LinearToSRGB((ColorRGB)value);
|
|
||||||
|
|
||||||
if (ImGui.ColorEdit3(displayName.Ptr, *(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, *(float[4]*)&value))
|
|
||||||
{
|
|
||||||
value = (float4)ColorRGBA.SRgbToLinear((ColorRGBA)value);
|
|
||||||
material.SetVariable(variable.Name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (previewType.Get<String>().Equals("ColorHDR", .InvariantCultureIgnoreCase))
|
|
||||||
{
|
|
||||||
Log.EngineLogger.AssertDebug(variable.Type == .Float && variable.Rows == 1);
|
|
||||||
|
|
||||||
if (variable.Columns == 3)
|
|
||||||
{
|
|
||||||
material.GetVariable<float3>(variable.Name, var value);
|
|
||||||
|
|
||||||
value = (float3)ColorRGB.LinearToSRGB((ColorRGB)value);
|
|
||||||
|
|
||||||
if (ImGui.ColorEdit3(displayName.Ptr, *(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, *(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);
|
|
||||||
bool hasMax = TryGetValue(arguments, "Max", var max);
|
|
||||||
|
|
||||||
for (int r < variable.Rows)
|
|
||||||
{
|
|
||||||
switch (variable.Columns)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
material.GetVariable<float>(variable.Name, var value);
|
|
||||||
|
|
||||||
float[1] minV = hasMin ? min.Get<float[1]>() : .(float.MinValue);
|
|
||||||
float[1] maxV = hasMax ? max.Get<float[1]>() : .(float.MaxValue);
|
|
||||||
|
|
||||||
if (ImGui.EditVector<1>(displayName, ref *(float[1]*)&value, .(), 0.1f, 100.0f, minV, maxV))
|
|
||||||
material.SetVariable(variable.Name, value);
|
|
||||||
case 2:
|
|
||||||
material.GetVariable<float2>(variable.Name, var value);
|
|
||||||
|
|
||||||
float2 minV = hasMin ? min.Get<float2>() : (float2)float.MinValue;
|
|
||||||
float2 maxV = hasMax ? max.Get<float2>() : (float2)float.MaxValue;
|
|
||||||
|
|
||||||
if (ImGui.Editfloat2(displayName, ref value, .Zero, 0.1f, 100.0f, minV, maxV))
|
|
||||||
material.SetVariable(variable.Name, value);
|
|
||||||
case 3:
|
|
||||||
material.GetVariable<float3>(variable.Name, var value);
|
|
||||||
|
|
||||||
float3 minV = hasMin ? min.Get<float3>() : (float3)float.MinValue;
|
|
||||||
float3 maxV = hasMax ? max.Get<float3>() : (float3)float.MaxValue;
|
|
||||||
|
|
||||||
if (ImGui.Editfloat3(displayName, ref value, .Zero, 0.1f, 100.0f, minV, maxV))
|
|
||||||
material.SetVariable(variable.Name, value);
|
|
||||||
case 4:
|
|
||||||
material.GetVariable<float4>(variable.Name, var value);
|
|
||||||
|
|
||||||
float4 minV = hasMin ? min.Get<float4>() : (float4)float.MinValue;
|
|
||||||
float4 maxV = hasMax ? max.Get<float4>() : (float4)float.MaxValue;
|
|
||||||
|
|
||||||
if (ImGui.Editfloat4(displayName, ref value, .Zero, 0.1f, 100.0f, minV, maxV))
|
|
||||||
material.SetVariable(variable.Name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AssetPropertiesEditor Factory(AssetFile assetFile)
|
|
||||||
{
|
|
||||||
return new Self(assetFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[BonTarget, BonPolyRegister]
|
|
||||||
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(float2 Value);
|
|
||||||
case Float3(float3 Value);
|
|
||||||
case Float4(float4 Value);
|
|
||||||
case ColorRGB(ColorRGB Value);
|
|
||||||
case ColorRGBA(ColorRGBA Value);
|
|
||||||
case None;
|
|
||||||
|
|
||||||
/*static this()
|
|
||||||
{
|
|
||||||
gBonEnv.typeHandlers.Add(typeof(Self),
|
|
||||||
((.)new => VariableValueSerialize, (.)new => VariableValueDeserialize));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void VariableValueSerialize(BonWriter writer, ValueView value, BonEnvironment env)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Assert(value.type == typeof(Self));
|
|
||||||
|
|
||||||
let variableValue = value.Get<Self>();
|
|
||||||
|
|
||||||
writer.Type(variableValue)
|
|
||||||
using (writer.ObjectBlock())
|
|
||||||
{
|
|
||||||
Serialize.Value(writer, nameof(MaterialFile.Effect), materialFile.Effect, env);
|
|
||||||
Serialize.Value(writer, nameof(MaterialFile.Textures), materialFile.Textures, env);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Result<void> VariableValueDeserialize(BonReader reader, ValueView val, BonEnvironment env)
|
|
||||||
{
|
|
||||||
return .Ok;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
[BonTarget]
|
|
||||||
class MaterialFile
|
|
||||||
{
|
|
||||||
public String Effect ~ delete _;
|
|
||||||
|
|
||||||
public Dictionary<String, String> Textures ~ DeleteDictionaryAndKeysAndValues!(_);
|
|
||||||
public Dictionary<String, VariableValue> Variables ~
|
|
||||||
{
|
|
||||||
if (_ != null)
|
|
||||||
{
|
|
||||||
for (var entry in _)
|
|
||||||
{
|
|
||||||
delete entry.key;
|
|
||||||
//delete entry.value;
|
|
||||||
/*if (entry.value.HasValue)
|
|
||||||
entry.value->Dispose();*/
|
|
||||||
}
|
|
||||||
|
|
||||||
delete _;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*static this()
|
|
||||||
{
|
|
||||||
gBonEnv.typeHandlers.Add(typeof(Self),
|
|
||||||
((.)new => MaterialSerialize, (.)new => MaterialDeserialize));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void MaterialSerialize(BonWriter writer, ValueView value, BonEnvironment env)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Assert(value.type == typeof(Self));
|
|
||||||
|
|
||||||
let materialFile = value.Get<Self>();
|
|
||||||
|
|
||||||
using (writer.ObjectBlock())
|
|
||||||
{
|
|
||||||
Serialize.Value(writer, nameof(MaterialFile.Effect), materialFile.Effect, env);
|
|
||||||
Serialize.Value(writer, nameof(MaterialFile.Textures), materialFile.Textures, env);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void SerializeVariablesDictionary(BonWriter writer, MaterialFile materialFile, BonEnvironment env)
|
|
||||||
{
|
|
||||||
using (writer.ArrayBlock())
|
|
||||||
{
|
|
||||||
for (let (name, value) in materialFile.Variables)
|
|
||||||
{
|
|
||||||
let keyVal = ValueView(typeof(String), name);
|
|
||||||
Serialize.Value(writer, keyVal, env);
|
|
||||||
writer.Pair();
|
|
||||||
|
|
||||||
ValueView valueVal;// = ValueView(, entriesPtr + (currentIndex * entryStride) + entryValueOffset);
|
|
||||||
switch(value.GetType())
|
|
||||||
{
|
|
||||||
case typeof(ColorRGBA):
|
|
||||||
writer.Identifier("ColorRGBA");
|
|
||||||
default:
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Serialize.Value(writer, valueVal, env);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Result<void> MaterialDeserialize(BonReader reader, ValueView val, BonEnvironment env)
|
|
||||||
{
|
|
||||||
return .Ok;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
class MaterialAssetLoader : IAssetLoader, IAssetSaver //, IReloadingAssetLoader
|
|
||||||
{
|
|
||||||
private static readonly List<StringView> _fileExtensions = new .(){".mat"} ~ delete _;
|
|
||||||
|
|
||||||
public static List<StringView> FileExtensions => _fileExtensions;
|
|
||||||
|
|
||||||
public AssetLoaderConfig GetDefaultConfig()
|
|
||||||
{
|
|
||||||
return new ModelAssetLoaderConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset LoadAsset(Stream file, AssetLoaderConfig config, StringView assetIdentifier, StringView? subAsset, IContentManager contentManager)
|
|
||||||
{
|
|
||||||
StreamReader reader = scope .(file);
|
|
||||||
|
|
||||||
String text = scope .();
|
|
||||||
|
|
||||||
reader.ReadToEnd(text);
|
|
||||||
|
|
||||||
MaterialFile materialFile = scope .();
|
|
||||||
|
|
||||||
var result = Bon.Deserialize<MaterialFile>(ref materialFile, text);
|
|
||||||
|
|
||||||
if (result case .Err)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Error("Failed to load material.");
|
|
||||||
Debug.SafeBreak();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Effect fx = Content.GetAsset<Effect>(contentManager.LoadAsset(materialFile.Effect, true), contentManager);
|
|
||||||
|
|
||||||
Material material = new Material(fx);
|
|
||||||
|
|
||||||
for (let (slotName, textureIdentifier) in materialFile.Textures)
|
|
||||||
{
|
|
||||||
|
|
||||||
AssetHandle<Texture> texture = contentManager.LoadAsset(textureIdentifier);
|
|
||||||
|
|
||||||
if (texture.IsInvalid)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Error($"Failed to load texture \"{textureIdentifier}\".");
|
|
||||||
}
|
|
||||||
|
|
||||||
material.SetTexture(slotName, texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let (slotName, variableValue) in materialFile.Variables)
|
|
||||||
{
|
|
||||||
switch (variableValue)
|
|
||||||
{
|
|
||||||
case .ColorRGBA(let value):
|
|
||||||
material.SetVariable(slotName, value);
|
|
||||||
case .ColorRGB(let value):
|
|
||||||
material.SetVariable(slotName, value);
|
|
||||||
case .Float(let value):
|
|
||||||
material.SetVariable(slotName, value);
|
|
||||||
case .Float2(let value):
|
|
||||||
material.SetVariable(slotName, value);
|
|
||||||
case .Float3(let value):
|
|
||||||
material.SetVariable(slotName, value);
|
|
||||||
case .Float4(let value):
|
|
||||||
material.SetVariable(slotName, value);
|
|
||||||
case .None:
|
|
||||||
default:
|
|
||||||
Log.EngineLogger.Error($"Unknown variable type of variable {slotName}: {variableValue}");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return material;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Result<void> EditorSaveAsset(Stream file, Asset asset, AssetLoaderConfig config, StringView assetIdentifier, StringView? subAsset, IContentManager contentManager)
|
|
||||||
{
|
|
||||||
Material material = asset as Material;
|
|
||||||
|
|
||||||
if (material == null)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Error("Asset must be a Material!");
|
|
||||||
return .Err;
|
|
||||||
}
|
|
||||||
|
|
||||||
MaterialFile materialFile = scope .();
|
|
||||||
|
|
||||||
materialFile.Effect = new String(material.Effect.Identifier);
|
|
||||||
materialFile.Textures = new .();
|
|
||||||
materialFile.Variables = new .();
|
|
||||||
|
|
||||||
for (let (slotName, texture) in material.[Friend]_textures)
|
|
||||||
{
|
|
||||||
Texture textureAsset = texture.Handle.Get();
|
|
||||||
|
|
||||||
materialFile.Textures.Add(new String(slotName), new String(textureAsset?.Identifier ?? ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
Effect effect = material.Effect;
|
|
||||||
|
|
||||||
if (effect == null)
|
|
||||||
return .Ok;
|
|
||||||
|
|
||||||
for (let (name, arguments) in effect.[Friend]_variableDescriptions)
|
|
||||||
{
|
|
||||||
VariableValue variableValue = .None;
|
|
||||||
|
|
||||||
let variable = effect.Variables[name];
|
|
||||||
|
|
||||||
bool hasPreviewType = MaterialAssetPropertiesEditor.TryGetValue(arguments, "Type", var previewType);
|
|
||||||
|
|
||||||
if (hasPreviewType && previewType.Get<String>() == "Color")
|
|
||||||
{
|
|
||||||
Log.EngineLogger.AssertDebug(variable.Type == .Float && variable.Rows == 1);
|
|
||||||
|
|
||||||
if (variable.Columns == 3)
|
|
||||||
{
|
|
||||||
material.GetVariable<ColorRGB>(variable.Name, var value);
|
|
||||||
|
|
||||||
value = ColorRGB.LinearToSRGB((ColorRGB)value);
|
|
||||||
|
|
||||||
//variantValue = new box value;
|
|
||||||
variableValue = .ColorRGB(value);
|
|
||||||
}
|
|
||||||
else if (variable.Columns == 4)
|
|
||||||
{
|
|
||||||
material.GetVariable<ColorRGBA>(variable.Name, var value);
|
|
||||||
|
|
||||||
value = ColorRGBA.LinearToSRGB((ColorRGBA)value);
|
|
||||||
|
|
||||||
variableValue = .ColorRGBA(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (variable.Type == .Float && variable.Rows == 1)
|
|
||||||
{
|
|
||||||
switch (variable.Columns)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
material.GetVariable<float>(variable.Name, let value);
|
|
||||||
variableValue = .Float(value);
|
|
||||||
case 2:
|
|
||||||
material.GetVariable<float2>(variable.Name, let value);
|
|
||||||
variableValue = .Float2(value);
|
|
||||||
case 3:
|
|
||||||
material.GetVariable<float3>(variable.Name, let value);
|
|
||||||
variableValue = .Float3(value);
|
|
||||||
case 4:
|
|
||||||
material.GetVariable<float4>(variable.Name, let value);
|
|
||||||
variableValue = .Float4(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
materialFile.Variables.Add(new String(name), variableValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
String text = scope .();
|
|
||||||
|
|
||||||
gBonEnv.serializeFlags |= .IncludeDefault | .Verbose;
|
|
||||||
|
|
||||||
Bon.Serialize<MaterialFile>(materialFile, text);
|
|
||||||
|
|
||||||
StreamWriter writer = scope .(file, .UTF8, 1024);
|
|
||||||
writer.Write(text);
|
|
||||||
|
|
||||||
return .Ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
Material _placeholder;
|
|
||||||
Material _error;
|
|
||||||
|
|
||||||
public Asset GetPlaceholderAsset(Type assetType)
|
|
||||||
{
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset GetErrorAsset(Type assetType)
|
|
||||||
{
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
using Bon;
|
|
||||||
using GlitchyEngine.Content;
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.IO;
|
|
||||||
using GlitchyEngine;
|
|
||||||
|
|
||||||
namespace GlitchyEditor.Assets;
|
|
||||||
|
|
||||||
class ModelAssetPropertiesEditor : AssetPropertiesEditor
|
|
||||||
{
|
|
||||||
public this(AssetFile asset) : base(asset)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ShowEditor()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AssetPropertiesEditor Factory(AssetFile assetFile)
|
|
||||||
{
|
|
||||||
return new ModelAssetPropertiesEditor(assetFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[BonTarget, BonPolyRegister]
|
|
||||||
class ModelAssetLoaderConfig : AssetLoaderConfig
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class ModelAssetLoader : IAssetLoader //, IReloadingAssetLoader
|
|
||||||
{
|
|
||||||
private static readonly List<StringView> _fileExtensions = new .(){".gltf", ".glb"} ~ delete _;
|
|
||||||
|
|
||||||
public static List<StringView> FileExtensions => _fileExtensions;
|
|
||||||
|
|
||||||
public AssetLoaderConfig GetDefaultConfig()
|
|
||||||
{
|
|
||||||
return new ModelAssetLoaderConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset LoadAsset(Stream file, AssetLoaderConfig config, StringView assetIdentifier, StringView? subAsset, IContentManager contentManager)
|
|
||||||
{
|
|
||||||
//Log.EngineLogger.Assert(subAsset != null);
|
|
||||||
|
|
||||||
return ModelLoader.LoadMesh(file, subAsset ?? assetIdentifier, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset GetPlaceholderAsset(Type assetType)
|
|
||||||
{
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset GetErrorAsset(Type assetType)
|
|
||||||
{
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
using System;
|
|
||||||
namespace Bon.Integrated;
|
|
||||||
|
|
||||||
extension Serialize
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -1,594 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using Bon;
|
|
||||||
using System.IO;
|
|
||||||
using GlitchyEngine;
|
|
||||||
using GlitchyEngine.Content;
|
|
||||||
using GlitchyEngine.Renderer;
|
|
||||||
using GlitchyEngine.Math;
|
|
||||||
using DirectXTK;
|
|
||||||
using ImGui;
|
|
||||||
using GlitchyEditor.Assets.Importers;
|
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace GlitchyEditor.Assets;
|
|
||||||
|
|
||||||
class TextureAssetPropertiesEditor : AssetPropertiesEditor
|
|
||||||
{
|
|
||||||
EditorTextureAssetLoaderConfig _textureConfig;
|
|
||||||
|
|
||||||
public this(AssetFile asset) : base(asset)
|
|
||||||
{
|
|
||||||
_textureConfig = asset.AssetConfig.Config as EditorTextureAssetLoaderConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char8*[3] _filterFuncNames = char8*[]("Point", "Linear", "Anisotropic");
|
|
||||||
|
|
||||||
public override void ShowEditor()
|
|
||||||
{
|
|
||||||
if (_textureConfig == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool generateMips = _textureConfig.GenerateMipMaps;
|
|
||||||
if (ImGui.Checkbox("Generate Mip Maps", &generateMips))
|
|
||||||
_textureConfig.GenerateMipMaps = generateMips;
|
|
||||||
|
|
||||||
bool isSrgb = _textureConfig.IsSRGB;
|
|
||||||
if (ImGui.Checkbox("Is sRGB", &isSrgb))
|
|
||||||
_textureConfig.IsSRGB = isSrgb;
|
|
||||||
|
|
||||||
SamplerStateDescription samplerStateDescription = _textureConfig.SamplerStateDescription;
|
|
||||||
|
|
||||||
void ShowFilterCombo(String label, ref FilterFunction filterFunction)
|
|
||||||
{
|
|
||||||
int32 selectedFilter = filterFunction.Underlying;
|
|
||||||
if (ImGui.Combo(label, &selectedFilter, &_filterFuncNames, 3))
|
|
||||||
filterFunction = (.)selectedFilter;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.Separator();
|
|
||||||
ImGui.TextUnformatted("Texture Filtering:");
|
|
||||||
ImGui.Separator();
|
|
||||||
|
|
||||||
ImGui.EnumCombo("Min Filter", ref samplerStateDescription.MinFilter);
|
|
||||||
ImGui.AttachTooltip("""
|
|
||||||
Sampling method used for minification.
|
|
||||||
If set to "Anisotropic" all Filters are set to "Anisotropic" internally.
|
|
||||||
""");
|
|
||||||
ImGui.EnumCombo("Mag Filter", ref samplerStateDescription.MagFilter);
|
|
||||||
ImGui.AttachTooltip("""
|
|
||||||
Sampling method used for magnification.
|
|
||||||
If set to "Anisotropic" all Filters are set to "Anisotropic" internally.
|
|
||||||
""");
|
|
||||||
ImGui.EnumCombo("Mip Map Filter", ref samplerStateDescription.MipFilter);
|
|
||||||
ImGui.AttachTooltip("""
|
|
||||||
Method used for mip-level sampling.
|
|
||||||
If set to "Anisotropic" all Filters are set to "Anisotropic" internally.
|
|
||||||
""");
|
|
||||||
|
|
||||||
if (samplerStateDescription.MagFilter == .Anisotropic ||
|
|
||||||
samplerStateDescription.MinFilter == .Anisotropic ||
|
|
||||||
samplerStateDescription.MipFilter == .Anisotropic)
|
|
||||||
{
|
|
||||||
ImGui.SliderScalar("Anisotropy Level", ref samplerStateDescription.MaxAnisotropy, 1, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.NewLine();
|
|
||||||
|
|
||||||
ImGui.EnumCombo("Filter Mode", ref samplerStateDescription.FilterMode);
|
|
||||||
ImGui.AttachTooltip("Filtering method to use when sampling a texture.");
|
|
||||||
|
|
||||||
if (samplerStateDescription.FilterMode == .Comparison)
|
|
||||||
{
|
|
||||||
ImGui.EnumCombo("Comparison Function", ref samplerStateDescription.ComparisonFunction);
|
|
||||||
ImGui.AttachTooltip("""
|
|
||||||
The function that is used to compare the sampled data against the existing sampled data.
|
|
||||||
Only applies if Filter Mode is set to FilterMode.Comparison.
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.Separator();
|
|
||||||
ImGui.TextUnformatted("Wrapping");
|
|
||||||
ImGui.Separator();
|
|
||||||
|
|
||||||
ImGui.EnumCombo("Wrap Mode U", ref samplerStateDescription.AddressModeU);
|
|
||||||
ImGui.AttachTooltip("Method to use for resolving a u texture coordinate that is outside the 0 to 1 range.");
|
|
||||||
|
|
||||||
ImGui.EnumCombo("Wrap Mode V", ref samplerStateDescription.AddressModeV);
|
|
||||||
ImGui.AttachTooltip("Method to use for resolving a v texture coordinate that is outside the 0 to 1 range.");
|
|
||||||
|
|
||||||
ImGui.EnumCombo("Wrap Mode W", ref samplerStateDescription.AddressModeW);
|
|
||||||
ImGui.AttachTooltip("Method to use for resolving a w texture coordinate that is outside the 0 to 1 range.");
|
|
||||||
|
|
||||||
if (samplerStateDescription.AddressModeU == .Border ||
|
|
||||||
samplerStateDescription.AddressModeV == .Border ||
|
|
||||||
samplerStateDescription.AddressModeW == .Border)
|
|
||||||
{
|
|
||||||
ImGui.ColorEdit4("Border Color", ref samplerStateDescription.BorderColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.Separator();
|
|
||||||
ImGui.TextUnformatted("Mip Maps");
|
|
||||||
ImGui.Separator();
|
|
||||||
|
|
||||||
ImGui.DragFloat("Mip LOD Bias", &samplerStateDescription.MipLODBias, 0.1f);
|
|
||||||
ImGui.AttachTooltip("""
|
|
||||||
Offset from the calculated mipmap level.
|
|
||||||
For example, if the GPU calculates that a texture should be sampled at mipmap level 3 and "Mip LOD Bias" is 2, then the texture will be sampled at mipmap level 5.
|
|
||||||
""");
|
|
||||||
|
|
||||||
ImGui.DragFloat("Min Mip LOD", &samplerStateDescription.MipMinLOD);
|
|
||||||
ImGui.AttachTooltip("Lower end of the mipmap range to clamp access to, where 0 is the largest and most detailed mipmap level and any level higher than that is less detailed.");
|
|
||||||
|
|
||||||
ImGui.DragFloat("Max LOD Bias", &samplerStateDescription.MipMaxLOD);
|
|
||||||
ImGui.AttachTooltip("""
|
|
||||||
Upper end of the mipmap range to clamp access to, where 0 is the largest and most detailed mipmap level and any level higher than that is less detailed.
|
|
||||||
This value must be greater than or equal to "Min Mip LOD". To have no upper limit on LOD set this to a large value.
|
|
||||||
""");
|
|
||||||
|
|
||||||
_textureConfig.SamplerStateDescription = samplerStateDescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AssetPropertiesEditor Factory(AssetFile assetFile)
|
|
||||||
{
|
|
||||||
return new TextureAssetPropertiesEditor(assetFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[BonTarget, BonPolyRegister]
|
|
||||||
class EditorTextureAssetLoaderConfig : AssetLoaderConfig
|
|
||||||
{
|
|
||||||
[BonInclude]
|
|
||||||
private bool _generateMipMaps;
|
|
||||||
|
|
||||||
[BonInclude]
|
|
||||||
private bool _isSrgb;
|
|
||||||
|
|
||||||
[BonInclude]
|
|
||||||
private SamplerStateDescription _samplerStateDescription = .();
|
|
||||||
|
|
||||||
public bool GenerateMipMaps
|
|
||||||
{
|
|
||||||
get => _generateMipMaps;
|
|
||||||
set => SetIfChanged(ref _generateMipMaps, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsSRGB
|
|
||||||
{
|
|
||||||
get => _isSrgb;
|
|
||||||
set => SetIfChanged(ref _isSrgb, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SamplerStateDescription SamplerStateDescription
|
|
||||||
{
|
|
||||||
get => _samplerStateDescription;
|
|
||||||
set => SetIfChanged(ref _samplerStateDescription, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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"
|
|
||||||
|
|
||||||
public static List<StringView> FileExtensions => _fileExtensions;
|
|
||||||
|
|
||||||
public AssetLoaderConfig GetDefaultConfig()
|
|
||||||
{
|
|
||||||
return new EditorTextureAssetLoaderConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset LoadAsset(Stream data, AssetLoaderConfig config, StringView assetIdentifier, StringView? subAsset, IContentManager contentManager)
|
|
||||||
{
|
|
||||||
var config;
|
|
||||||
|
|
||||||
if (config == null)
|
|
||||||
{
|
|
||||||
config = GetDefaultConfig();
|
|
||||||
defer:: delete config;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(config is EditorTextureAssetLoaderConfig, "config has wrong type.");
|
|
||||||
|
|
||||||
return LoadTexture(data, (EditorTextureAssetLoaderConfig)config);
|
|
||||||
}
|
|
||||||
|
|
||||||
const String PngMagicWord = "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A";
|
|
||||||
const String DdsMagicWord = "DDS ";
|
|
||||||
|
|
||||||
enum TextureType
|
|
||||||
{
|
|
||||||
Unknown,
|
|
||||||
DDS,
|
|
||||||
PNG
|
|
||||||
}
|
|
||||||
|
|
||||||
private static TextureType GetTextureType(Stream data)
|
|
||||||
{
|
|
||||||
int64 position = data.Position;
|
|
||||||
|
|
||||||
var readResult = data.Read<char8[8]>();
|
|
||||||
|
|
||||||
data.Position = position;
|
|
||||||
|
|
||||||
char8[8] magicWord;
|
|
||||||
if (readResult case .Ok(out magicWord))
|
|
||||||
{
|
|
||||||
StringView strView = .(&magicWord, magicWord.Count);
|
|
||||||
|
|
||||||
if (strView.StartsWith(PngMagicWord))
|
|
||||||
{
|
|
||||||
return .PNG;
|
|
||||||
}
|
|
||||||
else if (strView.StartsWith(DdsMagicWord))
|
|
||||||
{
|
|
||||||
return .DDS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Runtime.FatalError("Unknown image format.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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!();
|
|
||||||
|
|
||||||
List<LoadedSurface> surfaces = scope .();
|
|
||||||
LoadedTextureInfo textureInfo;
|
|
||||||
|
|
||||||
// Make sure we clean up the pixel data
|
|
||||||
defer { delete textureInfo.PixelData; }
|
|
||||||
|
|
||||||
|
|
||||||
switch(GetTextureType(data))
|
|
||||||
{
|
|
||||||
case .DDS:
|
|
||||||
|
|
||||||
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:
|
|
||||||
Result<void> result = LoadPng(data, config, surfaces, out textureInfo);
|
|
||||||
|
|
||||||
if (result case .Err)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
case .Unknown:
|
|
||||||
Log.EngineLogger.Error("Unknown texture format.");
|
|
||||||
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);
|
|
||||||
texture.[Friend]Complete = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (result case .Err(let err))
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Error($"Failed to read data from stream. Texture: Error: {err}");
|
|
||||||
return .Err;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8* rawData = null;
|
|
||||||
defer
|
|
||||||
{
|
|
||||||
if (rawData != null)
|
|
||||||
LodePng.LodePng.Free(rawData);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 width = 0, height = 0;
|
|
||||||
|
|
||||||
{
|
|
||||||
Debug.Profiler.ProfileResourceScope!("LodePng.LodePng.Decode32");
|
|
||||||
uint32 errorCode = LodePng.LodePng.Decode32(&rawData, &width, &height, pngData.Ptr, (.)pngData.Count);
|
|
||||||
if (errorCode != 0)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Error($"Failed to decode PNG file {errorCode}.");
|
|
||||||
return .Err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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 Result<void> LoadDds(Stream data, EditorTextureAssetLoaderConfig config, List<LoadedSurface> surfaces, out LoadedTextureInfo textureInfo)
|
|
||||||
{
|
|
||||||
var result = DdsImporter.LoadDds(data, config.IsSRGB, surfaces, out textureInfo);
|
|
||||||
|
|
||||||
if (result case .Err)
|
|
||||||
return .Err;
|
|
||||||
|
|
||||||
return .Ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void SetSampler(Texture texture, EditorTextureAssetLoaderConfig config)
|
|
||||||
{
|
|
||||||
using (SamplerState samplerState = SamplerStateManager.GetSampler(config.SamplerStateDescription))
|
|
||||||
{
|
|
||||||
texture.SamplerState = samplerState;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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:
|
|
||||||
if (_placeholder2D == null)
|
|
||||||
{
|
|
||||||
Texture2DDesc desc = .(1, 1, .R8G8B8A8_UNorm, 1, 1, .Immutable, .None);
|
|
||||||
|
|
||||||
_placeholder2D = new Texture2D(desc);
|
|
||||||
_placeholder2D.SamplerState = SamplerStateManager.PointWrap;
|
|
||||||
Color color = Color.Cyan;
|
|
||||||
_placeholder2D.SetData<Color>(&color);
|
|
||||||
|
|
||||||
Content.ManageAsset(_placeholder2D);
|
|
||||||
_placeholder2D.ReleaseRef();
|
|
||||||
|
|
||||||
_placeholder2D.[Friend]Complete = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _placeholder2D;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset GetErrorAsset(Type assetType)
|
|
||||||
{
|
|
||||||
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:
|
|
||||||
if (_error2D == null)
|
|
||||||
{
|
|
||||||
Texture2DDesc desc = .(2, 2, .R8G8B8A8_UNorm, 1, 1, .Immutable, .None);
|
|
||||||
|
|
||||||
_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);
|
|
||||||
_error2D.ReleaseRef();
|
|
||||||
|
|
||||||
_placeholder2D.[Friend]Complete = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _error2D;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,612 +0,0 @@
|
|||||||
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("Shaders\\textureViewerShader.hlsl");
|
|
||||||
_renderTargetEffect = Content.LoadAsset("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", *(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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,10 +3,6 @@ using GlitchyEngine.World;
|
|||||||
using System;
|
using System;
|
||||||
using GlitchyEngine.Math;
|
using GlitchyEngine.Math;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using GlitchyEngine.Renderer;
|
|
||||||
using GlitchyEngine;
|
|
||||||
using GlitchyEngine.Content;
|
|
||||||
using GlitchyEngine.Scripting;
|
|
||||||
|
|
||||||
namespace GlitchyEditor.EditWindows
|
namespace GlitchyEditor.EditWindows
|
||||||
{
|
{
|
||||||
@@ -61,15 +57,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
ShowComponentEditor<TransformComponent>("Transform", entity, => ShowTransformComponentEditor);
|
ShowComponentEditor<TransformComponent>("Transform", entity, => ShowTransformComponentEditor);
|
||||||
ShowComponentEditor<CameraComponent>("Camera", entity, => ShowCameraComponentEditor, => ShowComponentContextMenu<CameraComponent>);
|
ShowComponentEditor<CameraComponent>("Camera", entity, => ShowCameraComponentEditor, => ShowComponentContextMenu<CameraComponent>);
|
||||||
ShowComponentEditor<SpriteRendererComponent>("Sprite Renderer", entity, => ShowSpriteRendererComponentEditor, => ShowComponentContextMenu<SpriteRendererComponent>);
|
ShowComponentEditor<SpriterRendererComponent>("Sprite Renderer", entity, => ShowSpriteRendererComponentEditor, => ShowComponentContextMenu<SpriterRendererComponent>);
|
||||||
ShowComponentEditor<CircleRendererComponent>("Circle Renderer", entity, => ShowCircleRendererComponentEditor, => ShowComponentContextMenu<CircleRendererComponent>);
|
|
||||||
ShowComponentEditor<MeshRendererComponent>("Mesh Renderer", entity, => ShowMeshRendererComponentEditor, => ShowComponentContextMenu<MeshRendererComponent>);
|
|
||||||
ShowComponentEditor<LightComponent>("Light", entity, => ShowLightComponentEditor, => ShowComponentContextMenu<LightComponent>);
|
|
||||||
ShowComponentEditor<MeshComponent>("Mesh", entity, => ShowMeshComponentEditor, => ShowComponentContextMenu<MeshComponent>);
|
|
||||||
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);
|
ShowAddComponentButton(entity);
|
||||||
}
|
}
|
||||||
@@ -120,18 +108,18 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
private static void ShowNameComponentEditor(Entity entity)
|
private static void ShowNameComponentEditor(Entity entity)
|
||||||
{
|
{
|
||||||
if (!entity.HasComponent<NameComponent>())
|
if (!entity.HasComponent<DebugNameComponent>())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char8[256] nameBuffer = default;
|
char8[256] nameBuffer = default;
|
||||||
|
|
||||||
NameComponent* component = entity.GetComponent<NameComponent>();
|
DebugNameComponent* component = entity.GetComponent<DebugNameComponent>();
|
||||||
|
|
||||||
StringView name = null;
|
String name = null;
|
||||||
|
|
||||||
if(component != null)
|
if(component != null)
|
||||||
{
|
{
|
||||||
name = component.Name;
|
name = component.DebugName;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -145,10 +133,11 @@ namespace GlitchyEditor.EditWindows
|
|||||||
{
|
{
|
||||||
if(component == null)
|
if(component == null)
|
||||||
{
|
{
|
||||||
component = entity.AddComponent<NameComponent>();
|
component = entity.AddComponent<DebugNameComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
component.Name = StringView(&nameBuffer);
|
component.DebugName.Clear();
|
||||||
|
component.DebugName.Append(&nameBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,32 +149,16 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
textWidth += ImGui.GetStyle().FramePadding.x * 3.0f;
|
textWidth += ImGui.GetStyle().FramePadding.x * 3.0f;
|
||||||
|
|
||||||
float3 position = transform.Position;
|
Vector3 position = transform.Position;
|
||||||
if (ImGui.Editfloat3("Position", ref position, .Zero, 0.1f, textWidth))
|
if (ImGui.EditVector3("Position", ref position, .Zero, 0.1f, textWidth))
|
||||||
{
|
|
||||||
transform.Position = position;
|
transform.Position = position;
|
||||||
|
|
||||||
// if necessary reposition Rigidbody2D
|
Vector3 rotationEuler = MathHelper.ToDegrees(transform.EditorRotationEuler);
|
||||||
if (entity.TryGetComponent<Rigidbody2DComponent>(let rigidbody2D))
|
if (ImGui.EditVector3("Rotation", ref rotationEuler, .Zero, 0.1f, textWidth))
|
||||||
{
|
|
||||||
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);
|
transform.EditorRotationEuler = MathHelper.ToRadians(rotationEuler);
|
||||||
|
|
||||||
// if necessary reposition Rigidbody2D
|
|
||||||
if (entity.TryGetComponent<Rigidbody2DComponent>(let rigidbody2D))
|
|
||||||
{
|
|
||||||
rigidbody2D.SetAngle(rotationEuler.Z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float3 scale = transform.Scale;
|
Vector3 scale = transform.Scale;
|
||||||
if (ImGui.Editfloat3("Scale", ref scale, .One, 0.1f, textWidth))
|
if (ImGui.EditVector3("Scale", ref scale, .One, 0.1f, textWidth))
|
||||||
transform.Scale = scale;
|
transform.Scale = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,552 +241,9 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ShowSpriteRendererComponentEditor(Entity entity, SpriteRendererComponent* spriteRendererComponent)
|
private static void ShowSpriteRendererComponentEditor(Entity entity, SpriterRendererComponent* spriteRendererComponent)
|
||||||
{
|
{
|
||||||
ColorRGBA spriteColor = ColorRGBA.LinearToSRGB(spriteRendererComponent.Color);
|
ImGui.ColorEdit4("Color", ref spriteRendererComponent.Color);
|
||||||
if (ImGui.ColorEdit4("Color", ref spriteColor))
|
|
||||||
spriteRendererComponent.Color = ColorRGBA.SRgbToLinear(spriteColor);
|
|
||||||
|
|
||||||
ImGui.Button("Texture");
|
|
||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
|
||||||
{
|
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
|
||||||
|
|
||||||
if (payload != null)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Warning("");
|
|
||||||
|
|
||||||
StringView path = .((char8*)payload.Data, (int)payload.DataSize);
|
|
||||||
|
|
||||||
spriteRendererComponent.Sprite = Content.LoadAsset(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndDragDropTarget();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ImGui.EditVector<4>("UV Transform", ref *(float[4]*)&spriteRendererComponent.UvTransform);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ShowCircleRendererComponentEditor(Entity entity, CircleRendererComponent* circleRendererComponent)
|
|
||||||
{
|
|
||||||
ColorRGBA spriteColor = ColorRGBA.LinearToSRGB(circleRendererComponent.Color);
|
|
||||||
if (ImGui.ColorEdit4("Color", ref spriteColor))
|
|
||||||
circleRendererComponent.Color = ColorRGBA.SRgbToLinear(spriteColor);
|
|
||||||
|
|
||||||
ImGui.Button("Texture");
|
|
||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
|
||||||
{
|
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
|
||||||
|
|
||||||
if (payload != null)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Warning("");
|
|
||||||
|
|
||||||
StringView path = .((char8*)payload.Data, (int)payload.DataSize);
|
|
||||||
|
|
||||||
circleRendererComponent.Sprite = Content.LoadAsset(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndDragDropTarget();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ImGui.EditVector<4>("UV Transform", ref *(float[4]*)&circleRendererComponent.UvTransform);
|
|
||||||
|
|
||||||
ImGui.DragFloat("Inner Radius", &circleRendererComponent.InnerRadius, 0.1f, 0.0f, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ShowMeshRendererComponentEditor(Entity entity, MeshRendererComponent* meshRendererComponent)
|
|
||||||
{
|
|
||||||
ImGui.TextUnformatted("Material:");
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
Material material = meshRendererComponent.Material;
|
|
||||||
|
|
||||||
StringView identifier = material?.Identifier ?? "None";
|
|
||||||
ImGui.Button(identifier.ToScopeCStr!());
|
|
||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
|
||||||
{
|
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
|
||||||
|
|
||||||
if (payload != null)
|
|
||||||
{
|
|
||||||
StringView fullpath = .((char8*)payload.Data, (int)payload.DataSize);
|
|
||||||
|
|
||||||
meshRendererComponent.Material = Content.LoadAsset(fullpath);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndDragDropTarget();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Effect effect = material?.Effect;
|
|
||||||
|
|
||||||
if (effect == null)
|
|
||||||
return;*/
|
|
||||||
|
|
||||||
// Show a preview of the material here!
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ShowRigidBody2DComponentEditor(Entity entity, Rigidbody2DComponent* rigidBodyComponent)
|
|
||||||
{
|
|
||||||
const String[?] bodyTypeStrings = .("Static", "Dynamic", "Kinematic");
|
|
||||||
String bodyTypeName = bodyTypeStrings[rigidBodyComponent.BodyType.Underlying];
|
|
||||||
|
|
||||||
if (ImGui.BeginCombo("Type", bodyTypeName.CStr()))
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
bool isSelected = (bodyTypeName == bodyTypeStrings[i]);
|
|
||||||
|
|
||||||
if (ImGui.Selectable(bodyTypeStrings[i], isSelected))
|
|
||||||
{
|
|
||||||
rigidBodyComponent.BodyType = (.)i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isSelected)
|
|
||||||
ImGui.SetItemDefaultFocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndCombo();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ImGui.Checkbox("Fixed Rotation", &rigidBodyComponent.FixedRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ShowBoxCollider2DComponentEditor(Entity entity, BoxCollider2DComponent* boxCollider)
|
|
||||||
{
|
|
||||||
float textWidth = ImGui.CalcTextSize("Offset".CStr()).x;
|
|
||||||
textWidth += ImGui.GetStyle().FramePadding.x * 3.0f;
|
|
||||||
|
|
||||||
|
|
||||||
float2 offset = boxCollider.Offset;
|
|
||||||
if (ImGui.Editfloat2("Offset", ref offset, .Zero, 0.1f, textWidth))
|
|
||||||
boxCollider.Offset = offset;
|
|
||||||
|
|
||||||
float2 size = boxCollider.Size;
|
|
||||||
if (ImGui.Editfloat2("Size", ref size, .Zero, 0.1f, textWidth))
|
|
||||||
boxCollider.Size = size;
|
|
||||||
|
|
||||||
float density = boxCollider.Density;
|
|
||||||
if (ImGui.DragFloat("Density", &density, 0.0f, 0.1f, textWidth))
|
|
||||||
boxCollider.Density = density;
|
|
||||||
|
|
||||||
float friction = boxCollider.Friction;
|
|
||||||
if (ImGui.DragFloat("Friction", &friction, 0.0f, 0.1f, textWidth))
|
|
||||||
boxCollider.Friction = friction;
|
|
||||||
|
|
||||||
float restitution = boxCollider.Restitution;
|
|
||||||
if (ImGui.DragFloat("Restitution", &restitution, 0.0f, 0.1f, textWidth))
|
|
||||||
boxCollider.Restitution = restitution;
|
|
||||||
|
|
||||||
float restitutionThreshold = boxCollider.RestitutionThreshold;
|
|
||||||
if (ImGui.DragFloat("RestitutionThreshold", &restitutionThreshold, 0.0f, 0.1f, textWidth))
|
|
||||||
boxCollider.RestitutionThreshold = restitutionThreshold;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ShowCircleCollider2DComponentEditor(Entity entity, CircleCollider2DComponent* circleCollider)
|
|
||||||
{
|
|
||||||
float textWidth = ImGui.CalcTextSize("Offset".CStr()).x;
|
|
||||||
textWidth += ImGui.GetStyle().FramePadding.x * 3.0f;
|
|
||||||
|
|
||||||
|
|
||||||
float2 offset = circleCollider.Offset;
|
|
||||||
if (ImGui.Editfloat2("Offset", ref offset, .Zero, 0.1f, textWidth))
|
|
||||||
circleCollider.Offset = offset;
|
|
||||||
|
|
||||||
float radius = circleCollider.Radius;
|
|
||||||
if (ImGui.DragFloat("Radius", &radius, 0.0f, 0.1f, textWidth))
|
|
||||||
circleCollider.Radius = radius;
|
|
||||||
|
|
||||||
float density = circleCollider.Density;
|
|
||||||
if (ImGui.DragFloat("Density", &density, 0.0f, 0.1f, textWidth))
|
|
||||||
circleCollider.Density = density;
|
|
||||||
|
|
||||||
float friction = circleCollider.Friction;
|
|
||||||
if (ImGui.DragFloat("Friction", &friction, 0.0f, 0.1f, textWidth))
|
|
||||||
circleCollider.Friction = friction;
|
|
||||||
|
|
||||||
float restitution = circleCollider.Restitution;
|
|
||||||
if (ImGui.DragFloat("Restitution", &restitution, 0.0f, 0.1f, textWidth))
|
|
||||||
circleCollider.Restitution = restitution;
|
|
||||||
|
|
||||||
float restitutionThreshold = circleCollider.RestitutionThreshold;
|
|
||||||
if (ImGui.DragFloat("RestitutionThreshold", &restitutionThreshold, 0.0f, 0.1f, textWidth))
|
|
||||||
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...";
|
|
||||||
char8* scriptLabel = scriptComponent.Instance?.ScriptClass.FullName.CStr() ?? "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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scriptComponent.Instance?.IsInitialized == true)
|
|
||||||
{
|
|
||||||
SharpClass sharpClass = scriptComponent.Instance.ScriptClass;
|
|
||||||
ScriptInstance scriptInstance = scriptComponent.Instance;
|
|
||||||
|
|
||||||
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!
|
|
||||||
default:
|
|
||||||
Log.EngineLogger.Error($"Unhandled field type {scriptField.FieldType}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (scriptClass != null)
|
|
||||||
{
|
|
||||||
let scriptFields = ScriptEngine.GetScriptFieldMap(entity);
|
|
||||||
|
|
||||||
for (var (name, field) in ref scriptFields)
|
|
||||||
{
|
|
||||||
switch (field.Type)
|
|
||||||
{
|
|
||||||
case .Bool:
|
|
||||||
var value = field.GetData<bool>();
|
|
||||||
if (ImGui.Checkbox(name.CStr(), &value))
|
|
||||||
field.SetData(value);
|
|
||||||
|
|
||||||
case .SByte:
|
|
||||||
var value = field.GetData<int8>();
|
|
||||||
if (ImGui.DragScalar(name.CStr(), .S8, &value))
|
|
||||||
field.SetData(value);
|
|
||||||
case .Short:
|
|
||||||
var value = field.GetData<int16>();
|
|
||||||
if (ImGui.DragScalar(name.CStr(), .S16, &value))
|
|
||||||
field.SetData(value);
|
|
||||||
case .Int:
|
|
||||||
var value = field.GetData<int32>();
|
|
||||||
if (ImGui.DragScalar(name.CStr(), .S32, &value))
|
|
||||||
field.SetData(value);
|
|
||||||
case .Int2:
|
|
||||||
var value = field.GetData<int2>();
|
|
||||||
if (ImGui.DragScalarN(name.CStr(), .S32, &value, 2))
|
|
||||||
field.SetData(value);
|
|
||||||
case .Int3:
|
|
||||||
var value = field.GetData<int3>();
|
|
||||||
if (ImGui.DragScalarN(name.CStr(), .S32, &value, 3))
|
|
||||||
field.SetData(value);
|
|
||||||
case .Int4:
|
|
||||||
var value = field.GetData<int4>();
|
|
||||||
if (ImGui.DragScalarN(name.CStr(), .S32, &value, 4))
|
|
||||||
field.SetData(value);
|
|
||||||
case .Long:
|
|
||||||
var value = field.GetData<int64>();
|
|
||||||
if (ImGui.DragScalar(name.CStr(), .S64, &value))
|
|
||||||
field.SetData(value);
|
|
||||||
|
|
||||||
case .Byte:
|
|
||||||
var value = field.GetData<uint8>();
|
|
||||||
if (ImGui.DragScalar(name.CStr(), .U8, &value))
|
|
||||||
field.SetData(value);
|
|
||||||
case .UShort:
|
|
||||||
var value = field.GetData<uint16>();
|
|
||||||
if (ImGui.DragScalar(name.CStr(), .U16, &value))
|
|
||||||
field.SetData(value);
|
|
||||||
case .UInt:
|
|
||||||
var value = field.GetData<uint32>();
|
|
||||||
if (ImGui.DragScalar(name.CStr(), .U32, &value))
|
|
||||||
field.SetData(value);
|
|
||||||
case .ULong:
|
|
||||||
var value = field.GetData<uint64>();
|
|
||||||
if (ImGui.DragScalar(name.CStr(), .U64, &value))
|
|
||||||
field.SetData(value);
|
|
||||||
|
|
||||||
case .Float:
|
|
||||||
var value = field.GetData<float>();
|
|
||||||
if (ImGui.DragScalar(name.CStr(), .Float, &value))
|
|
||||||
field.SetData(value);
|
|
||||||
case .float2:
|
|
||||||
var value = field.GetData<float2>();
|
|
||||||
if (ImGui.Editfloat2(name, ref value))
|
|
||||||
field.SetData(value);
|
|
||||||
case .float3:
|
|
||||||
var value = field.GetData<float3>();
|
|
||||||
if (ImGui.Editfloat3(name, ref value))
|
|
||||||
field.SetData(value);
|
|
||||||
case .float4:
|
|
||||||
var value = field.GetData<float4>();
|
|
||||||
if (ImGui.Editfloat4(name, ref value))
|
|
||||||
field.SetData(value);
|
|
||||||
|
|
||||||
case .Double:
|
|
||||||
var value = field.GetData<double>();
|
|
||||||
if (ImGui.DragScalar(name.CStr(), .Double, &value))
|
|
||||||
field.SetData(value);
|
|
||||||
case .Double2:
|
|
||||||
var value = field.GetData<double2>();
|
|
||||||
if (ImGui.DragScalarN(name.CStr(), .Double, &value, 2))
|
|
||||||
field.SetData(value);
|
|
||||||
case .Double3:
|
|
||||||
var value = field.GetData<double3>();
|
|
||||||
if (ImGui.DragScalarN(name.CStr(), .Double, &value, 3))
|
|
||||||
field.SetData(value);
|
|
||||||
case .Double4:
|
|
||||||
var value = field.GetData<double4>();
|
|
||||||
if (ImGui.DragScalarN(name.CStr(), .Double, &value, 4))
|
|
||||||
field.SetData(value);
|
|
||||||
|
|
||||||
case .Enum:
|
|
||||||
// TODO!
|
|
||||||
|
|
||||||
//case .String:
|
|
||||||
// TODO!
|
|
||||||
|
|
||||||
case .Entity:
|
|
||||||
// TODO!
|
|
||||||
|
|
||||||
case .Struct:
|
|
||||||
// TODO!
|
|
||||||
|
|
||||||
default:
|
|
||||||
Log.EngineLogger.Error($"Unhandled field type {field.Type}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void LabelColumn(StringView label)
|
|
||||||
{
|
|
||||||
ImGui.TextUnformatted(label);
|
|
||||||
ImGui.NextColumn();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ShowLightComponentEditor(Entity entity, LightComponent* lightComponent)
|
|
||||||
{
|
|
||||||
ImGui.Columns(2);
|
|
||||||
defer ImGui.Columns(1);
|
|
||||||
|
|
||||||
const String[?] strings = String[]("Directional", "Point", "Spot");
|
|
||||||
|
|
||||||
var light = ref lightComponent.SceneLight;
|
|
||||||
|
|
||||||
String typeName = strings[light.LightType.Underlying];
|
|
||||||
|
|
||||||
LabelColumn("Type");
|
|
||||||
|
|
||||||
if (ImGui.BeginCombo("##Type", typeName.CStr()))
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
bool isSelected = (typeName == strings[i]);
|
|
||||||
|
|
||||||
if (ImGui.Selectable(strings[i], isSelected))
|
|
||||||
{
|
|
||||||
light.LightType = (.)i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isSelected)
|
|
||||||
ImGui.SetItemDefaultFocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndCombo();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.NextColumn();
|
|
||||||
LabelColumn("Color");
|
|
||||||
|
|
||||||
ColorRGB color = ColorRGB.LinearToSRGB(light.Color);
|
|
||||||
if (ImGui.ColorEdit3("##Color", ref color))
|
|
||||||
light.Color = ColorRGB.SRgbToLinear(color);
|
|
||||||
|
|
||||||
ImGui.NextColumn();
|
|
||||||
LabelColumn("Illuminance");
|
|
||||||
|
|
||||||
float illuminance = light.Illuminance;
|
|
||||||
if (ImGui.DragFloat("##Illuminance", &illuminance, 0.1f, 0.0f, float.MaxValue))
|
|
||||||
light.Illuminance = illuminance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ShowMeshComponentEditor(Entity entity, MeshComponent* meshComponent)
|
|
||||||
{
|
|
||||||
ImGui.TextUnformatted("Mesh:");
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
GeometryBinding mesh = meshComponent.Mesh;
|
|
||||||
|
|
||||||
StringView identifier = mesh?.Identifier ?? "None";
|
|
||||||
ImGui.Button(identifier.ToScopeCStr!());
|
|
||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
|
||||||
{
|
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
|
||||||
|
|
||||||
if (payload != null)
|
|
||||||
{
|
|
||||||
StringView fullpath = .((char8*)payload.Data, (int)payload.DataSize);
|
|
||||||
|
|
||||||
/*int idx = fullpath.IndexOf('#');
|
|
||||||
|
|
||||||
if (idx == -1)
|
|
||||||
{
|
|
||||||
// Doesn't make sense here, we NEED a sub asset
|
|
||||||
Runtime.NotImplemented();
|
|
||||||
}
|
|
||||||
|
|
||||||
StringView filePath = fullpath.Substring(0, idx);
|
|
||||||
StringView meshName = fullpath.Substring(idx + 1);*/
|
|
||||||
|
|
||||||
meshComponent.Mesh = Content.LoadAsset(fullpath);
|
|
||||||
|
|
||||||
// TODO: support multiple primitives (treat every primitive as a single mesh? or: mesh can have multiple primitives)
|
|
||||||
/*using (GeometryBinding binding = ModelLoader.LoadMesh(filePath, meshName, 0))
|
|
||||||
{
|
|
||||||
meshComponent.Mesh = binding;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//ModelLoader.LoadModel(scope .(path), )
|
|
||||||
|
|
||||||
/*using (Texture2D newTexture = new Texture2D(path, true))
|
|
||||||
{
|
|
||||||
newTexture.SamplerState = SamplerStateManager.AnisotropicWrap;
|
|
||||||
material.SetTexture(texture.key, newTexture);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndDragDropTarget();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ShowAddComponentButton(Entity entity)
|
private static void ShowAddComponentButton(Entity entity)
|
||||||
@@ -829,10 +259,6 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
void ShowComponentButton<TComponent>(String name) where TComponent : struct, new
|
void ShowComponentButton<TComponent>(String name) where TComponent : struct, new
|
||||||
{
|
{
|
||||||
// If the entity already has this component, don't show the option to add it
|
|
||||||
if (entity.HasComponent<TComponent>())
|
|
||||||
return;
|
|
||||||
|
|
||||||
float textWidth = ImGui.CalcTextSize(name.CStr()).x;
|
float textWidth = ImGui.CalcTextSize(name.CStr()).x;
|
||||||
buttonWidth = Math.Max(buttonWidth, textWidth + ImGui.GetStyle().FramePadding.x * 2);
|
buttonWidth = Math.Max(buttonWidth, textWidth + ImGui.GetStyle().FramePadding.x * 2);
|
||||||
|
|
||||||
@@ -861,15 +287,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
ShowComponentButton<CameraComponent>("Camera");
|
ShowComponentButton<CameraComponent>("Camera");
|
||||||
ShowComponentButton<SpriteRendererComponent>("Sprite Renderer");
|
ShowComponentButton<SpriterRendererComponent>("Sprite Renderer");
|
||||||
ShowComponentButton<CircleRendererComponent>("Circle Renderer");
|
|
||||||
ShowComponentButton<LightComponent>("Light");
|
|
||||||
ShowComponentButton<Rigidbody2DComponent>("Rigidbody 2D");
|
|
||||||
ShowComponentButton<BoxCollider2DComponent>("Box collider 2D");
|
|
||||||
ShowComponentButton<CircleCollider2DComponent>("Circle collider 2D");
|
|
||||||
ShowComponentButton<MeshComponent>("Mesh");
|
|
||||||
ShowComponentButton<MeshRendererComponent>("Mesh Renderer");
|
|
||||||
ShowComponentButton<ScriptComponent>("C# Script");
|
|
||||||
|
|
||||||
ImGui.EndCombo();
|
ImGui.EndCombo();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,462 +0,0 @@
|
|||||||
using ImGui;
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using GlitchyEngine.Collections;
|
|
||||||
using System.Collections;
|
|
||||||
using GlitchyEngine.Renderer;
|
|
||||||
using GlitchyEngine.Math;
|
|
||||||
using GlitchyEngine;
|
|
||||||
using GlitchyEditor.Assets;
|
|
||||||
|
|
||||||
namespace GlitchyEditor.EditWindows
|
|
||||||
{
|
|
||||||
using internal GlitchyEditor.EditorContentManager;
|
|
||||||
|
|
||||||
class ContentBrowserWindow : EditorWindow
|
|
||||||
{
|
|
||||||
public const String s_WindowTitle = "Content Browser";
|
|
||||||
|
|
||||||
private append String _currentDirectory = .();
|
|
||||||
|
|
||||||
private append String _selectedFile = .();
|
|
||||||
|
|
||||||
public static SubTexture2D s_FolderTexture;
|
|
||||||
public static SubTexture2D s_FileTexture;
|
|
||||||
|
|
||||||
public EditorContentManager _manager;
|
|
||||||
|
|
||||||
public StringView SelectedFile => _selectedFile;
|
|
||||||
|
|
||||||
public this(EditorContentManager contentManager)
|
|
||||||
{
|
|
||||||
_manager = contentManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void InternalShow()
|
|
||||||
{
|
|
||||||
_manager.Update();
|
|
||||||
|
|
||||||
// Make sure we are in an existing directory.
|
|
||||||
if (!_manager.AssetHierarchy.FileExists(_currentDirectory))
|
|
||||||
{
|
|
||||||
_currentDirectory.Set(_manager.ContentDirectory);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!ImGui.Begin(s_WindowTitle, &_open, .None))
|
|
||||||
{
|
|
||||||
ImGui.End();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.PushStyleVar(.CellPadding, .(0, 0));
|
|
||||||
|
|
||||||
bool alt_pressed = ImGui.GetIO().KeyAlt;
|
|
||||||
|
|
||||||
if (ImGui.BeginTable("table", 2, .BordersInnerV | .Resizable | .Reorderable | .NoPadOuterX))
|
|
||||||
{
|
|
||||||
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.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()
|
|
||||||
{
|
|
||||||
if (ImGui.MenuItem("Open in file browser..."))
|
|
||||||
{
|
|
||||||
if (Path.OpenFolder(_currentDirectory) case .Err)
|
|
||||||
Log.EngineLogger.Error("Failed to open directory in file browser.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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)
|
|
||||||
{
|
|
||||||
ImGuiPrintEntityTree(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Renders an ImGui tree of all directories in the given tree.
|
|
||||||
/// @param tree The file hierarchy of which to render all directories.
|
|
||||||
private void ImGuiPrintEntityTree(TreeNode<AssetNode> tree)
|
|
||||||
{
|
|
||||||
if (!tree->IsDirectory)
|
|
||||||
return;
|
|
||||||
|
|
||||||
String name = tree->Name;
|
|
||||||
|
|
||||||
ImGui.TreeNodeFlags flags = .OpenOnArrow | .SpanAvailWidth;
|
|
||||||
|
|
||||||
if(tree.Children.Count == 0)
|
|
||||||
flags |= .Leaf;
|
|
||||||
|
|
||||||
if (tree->Path == _currentDirectory)
|
|
||||||
{
|
|
||||||
flags |= .Selected;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isOpen = ImGui.TreeNodeEx(name, flags, $"{name}");
|
|
||||||
|
|
||||||
if (ImGui.IsItemClicked(.Left))
|
|
||||||
{
|
|
||||||
_currentDirectory.Set(tree->Path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isOpen)
|
|
||||||
{
|
|
||||||
for(var child in tree.Children)
|
|
||||||
{
|
|
||||||
ImGuiPrintEntityTree(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.TreePop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static float2 DirectoryItemSize = .(110, 110);
|
|
||||||
|
|
||||||
const float2 padding = .(24, 24);
|
|
||||||
|
|
||||||
/// Renders the contents of _currentDirectory.
|
|
||||||
private void DrawCurrentDirectory()
|
|
||||||
{
|
|
||||||
List<TreeNode<AssetNode>> files = null;
|
|
||||||
|
|
||||||
ImGui.Style* style = ImGui.GetStyle();
|
|
||||||
|
|
||||||
float window_visible_x2 = ImGui.GetWindowPos().x + ImGui.GetWindowContentRegionMax().x;
|
|
||||||
|
|
||||||
StringView searchFilter = StringView(&_filesFilter);
|
|
||||||
|
|
||||||
if (_searchEverywhere && searchFilter.Length > 0)
|
|
||||||
{
|
|
||||||
files = scope:: List<TreeNode<AssetNode>>();
|
|
||||||
_manager.AssetHierarchy.[Friend]_assetHierarchy.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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var entry in files)
|
|
||||||
{
|
|
||||||
if (!entry->Name.Contains(searchFilter, true))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ImGui.PushID(entry->Name);
|
|
||||||
|
|
||||||
DrawDirectoryItem(entry);
|
|
||||||
|
|
||||||
// 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 we aren't the last entry and the next button won't fit on the same line we start a new line.
|
|
||||||
if (entry != files.Back && expectedButtonRight < window_visible_x2)
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
ImGui.PopID();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Renders the button for the given directory item.
|
|
||||||
private void DrawBackButton(TreeNode<AssetNode> entry)
|
|
||||||
{
|
|
||||||
ImGui.BeginChild("item", (.)DirectoryItemSize);
|
|
||||||
|
|
||||||
if (entry->Path == _selectedFile)
|
|
||||||
{
|
|
||||||
var color = ImGui.GetStyleColorVec4(.ButtonHovered);
|
|
||||||
ImGui.PushStyleColor(.Button, *color);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ImGui.PushStyleColor(.Button, ImGui.Vec4(0, 0, 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
SubTexture2D image = s_FolderTexture;
|
|
||||||
|
|
||||||
ImGui.ImageButton(image, (.)(DirectoryItemSize - padding));
|
|
||||||
|
|
||||||
ImGui.PopStyleColor();
|
|
||||||
|
|
||||||
if (ImGui.IsItemHovered() && ImGui.IsMouseClicked(.Left))
|
|
||||||
{
|
|
||||||
if (_selectedFile != entry->Path)
|
|
||||||
{
|
|
||||||
_selectedFile.Set(entry->Path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.IsItemHovered() && ImGui.IsMouseDoubleClicked(.Left))
|
|
||||||
{
|
|
||||||
EntryDoubleClicked(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.TextUnformatted("..");
|
|
||||||
|
|
||||||
ImGui.EndChild();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Renders the button for the given directory item.
|
|
||||||
private void DrawDirectoryItem(TreeNode<AssetNode> entry)
|
|
||||||
{
|
|
||||||
ImGui.BeginChild("item", (.)DirectoryItemSize);
|
|
||||||
|
|
||||||
if (entry->Path == _selectedFile)
|
|
||||||
{
|
|
||||||
var color = ImGui.GetStyleColorVec4(.ButtonHovered);
|
|
||||||
ImGui.PushStyleColor(.Button, *color);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ImGui.PushStyleColor(.Button, ImGui.Vec4(0, 0, 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: preview images
|
|
||||||
SubTexture2D image = entry->IsDirectory ? s_FolderTexture : s_FileTexture;
|
|
||||||
|
|
||||||
ImGui.ImageButton(image, (.)(DirectoryItemSize - padding));
|
|
||||||
|
|
||||||
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.EndDragDropSource();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.IsItemHovered() && ImGui.IsMouseClicked(.Left))
|
|
||||||
{
|
|
||||||
if (_selectedFile != entry->Path)
|
|
||||||
{
|
|
||||||
_selectedFile.Set(entry->Path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.IsItemHovered() && ImGui.IsMouseDoubleClicked(.Left))
|
|
||||||
{
|
|
||||||
EntryDoubleClicked(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.TextUnformatted(entry->Name);
|
|
||||||
|
|
||||||
if (ImGui.BeginPopupContextWindow())
|
|
||||||
{
|
|
||||||
ShowItemContextMenu(entry);
|
|
||||||
ImGui.EndPopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry->SubAssets?.Count > 0)
|
|
||||||
{
|
|
||||||
// Button for revealing sub assets (e.g. Meshes in 3D-Model)
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
if (ImGui.Button(">"))
|
|
||||||
ImGui.OpenPopup("SubAssets");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.BeginPopup("SubAssets", .Popup))
|
|
||||||
{
|
|
||||||
for (var subAsset in entry->SubAssets)
|
|
||||||
{
|
|
||||||
ImGui.Button(subAsset.Name);
|
|
||||||
|
|
||||||
if (ImGui.BeginDragDropSource())
|
|
||||||
{
|
|
||||||
String fullpath = scope String(entry->Path);
|
|
||||||
fullpath.AppendF($"#{subAsset.Name}");
|
|
||||||
|
|
||||||
ImGui.SetDragDropPayload("CONTENT_BROWSER_ITEM", fullpath.CStr(), (.)fullpath.Length, .Once);
|
|
||||||
|
|
||||||
ImGui.EndDragDropSource();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndPopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
DeleteItemPopup(entry);
|
|
||||||
|
|
||||||
ImGui.EndChild();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DeleteItemPopup(TreeNode<AssetNode> fileOrFolder)
|
|
||||||
{
|
|
||||||
// Always center this window when appearing
|
|
||||||
ImGui.Vec2 center = ImGui.GetMainViewport().GetCenter();
|
|
||||||
ImGui.SetNextWindowPos(center, .Appearing, ImGui.Vec2(0.5f, 0.5f));
|
|
||||||
|
|
||||||
// TODO: fix delete popup
|
|
||||||
|
|
||||||
if (ImGui.BeginPopupModal("Delete?", null, .AlwaysAutoResize))
|
|
||||||
{
|
|
||||||
ImGui.Text($"""
|
|
||||||
Delete "{fileOrFolder->Name}"?
|
|
||||||
|
|
||||||
|
|
||||||
""");
|
|
||||||
|
|
||||||
ImGui.Separator();
|
|
||||||
|
|
||||||
if (ImGui.Button("Yes", ImGui.Vec2(120, 0)))
|
|
||||||
{
|
|
||||||
ImGui.CloseCurrentPopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.SetItemDefaultFocus();
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
if (ImGui.Button("Cancel", ImGui.Vec2(120, 0)))
|
|
||||||
{
|
|
||||||
ImGui.CloseCurrentPopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndPopup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Shows the context menu for the given file/folder.
|
|
||||||
private void ShowItemContextMenu(TreeNode<AssetNode> fileOrFolder)
|
|
||||||
{
|
|
||||||
bool isFile = !fileOrFolder->IsDirectory;
|
|
||||||
|
|
||||||
if (ImGui.MenuItem("Show in file browser..."))
|
|
||||||
{
|
|
||||||
if (Path.OpenFolderAndSelectItem(fileOrFolder->Path) case .Err)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Error("Failed to show path in file browser.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isFile && ImGui.MenuItem("Open file with..."))
|
|
||||||
{
|
|
||||||
if (Path.OpenWithDialog(fileOrFolder->Path) case .Err)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Error("Failed to show \"Open with...\" dialog.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.MenuItem("Delete"))
|
|
||||||
{
|
|
||||||
ImGui.OpenPopup("Delete?");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EntryDoubleClicked(TreeNode<AssetNode> entry)
|
|
||||||
{
|
|
||||||
if (entry->IsDirectory)
|
|
||||||
{
|
|
||||||
_currentDirectory.Set(entry->Path);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (Path.OpenFolder(entry->Path) case .Err)
|
|
||||||
Log.EngineLogger.Error("Failed to open directory in file browser.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,334 +0,0 @@
|
|||||||
using System;
|
|
||||||
using ImGui;
|
|
||||||
using GlitchyEngine.Renderer;
|
|
||||||
using GlitchyEngine.Math;
|
|
||||||
using GlitchyEngine;
|
|
||||||
using GlitchyEngine.World;
|
|
||||||
using ImGuizmo;
|
|
||||||
using GlitchyEngine.Events;
|
|
||||||
|
|
||||||
namespace GlitchyEditor.EditWindows
|
|
||||||
{
|
|
||||||
class EditorViewportWindow : EditorWindow
|
|
||||||
{
|
|
||||||
public const String s_WindowTitle = "Scene";
|
|
||||||
|
|
||||||
private ImGui.Vec2 _oldViewportSize = .(100, 100);
|
|
||||||
private bool _viewPortChanged;
|
|
||||||
|
|
||||||
/// True if the cursor wrapped from one side of the viewport to the other last frame.
|
|
||||||
private bool _wrappedCursor;
|
|
||||||
|
|
||||||
private RenderTargetGroup _renderTarget ~ _?.ReleaseRef();
|
|
||||||
|
|
||||||
private ImGuizmo.OPERATION _gizmoType = .TRANSLATE;
|
|
||||||
private ImGuizmo.MODE _gizmoMode = .LOCAL;
|
|
||||||
private float _snap = 0.5f;
|
|
||||||
private float _angleSnap = 45.0f;
|
|
||||||
private bool _doSnap = false;
|
|
||||||
|
|
||||||
private bool _visible;
|
|
||||||
|
|
||||||
public uint32 SelectedEntityId {get; private set; }
|
|
||||||
public bool SelectionChanged { get; private set; }
|
|
||||||
|
|
||||||
public float2 ViewportSize => (float2)_oldViewportSize;
|
|
||||||
// Occurs when the viewport is resized.
|
|
||||||
public Event<EventHandler<float2>> ViewportSizeChanged ~ _.Dispose();
|
|
||||||
// Occurs when an entity was clicked.
|
|
||||||
public Event<EventHandler<uint32>> EntityClicked ~ _.Dispose();
|
|
||||||
|
|
||||||
/// The render target that is shown in the viewport window.
|
|
||||||
public RenderTargetGroup RenderTarget
|
|
||||||
{
|
|
||||||
get => _renderTarget;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if(_renderTarget == value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SetReference!(_renderTarget, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets or sets whether the editor functionality (gizmo, picking etc.) is enabled.
|
|
||||||
public bool EditorMode { get; set; } = true
|
|
||||||
|
|
||||||
public bool Visible => _visible;
|
|
||||||
|
|
||||||
public this(Editor editor)
|
|
||||||
{
|
|
||||||
_editor = editor;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void InternalShow()
|
|
||||||
{
|
|
||||||
ImGui.PushStyleVar(.WindowPadding, ImGui.Vec2(1, 1));
|
|
||||||
defer ImGui.PopStyleVar();
|
|
||||||
|
|
||||||
if(!ImGui.Begin(s_WindowTitle, &_open, .NoScrollbar | .MenuBar))
|
|
||||||
{
|
|
||||||
ImGui.End();
|
|
||||||
|
|
||||||
_visible = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_visible = true;
|
|
||||||
|
|
||||||
let viewportSize = ImGui.GetContentRegionAvail();
|
|
||||||
|
|
||||||
if(ImGui.IsWindowHovered() && Input.IsMouseButtonPressing(.RightButton))
|
|
||||||
{
|
|
||||||
let currentWindow = ImGui.GetCurrentWindow();
|
|
||||||
ImGui.FocusWindow(currentWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
_hasFocus = ImGui.IsWindowFocused();
|
|
||||||
|
|
||||||
ShowMenuBar();
|
|
||||||
|
|
||||||
if (_editor.CurrentCamera.[Friend]BindMouse && _hasFocus)
|
|
||||||
WrapMouseInViewport();
|
|
||||||
|
|
||||||
// If we wrapped this frame we weren't hovering because the cursor has to be be out of bounds to wrap
|
|
||||||
_editor.CurrentCamera.AllowMove = _hasFocus && (ImGui.IsWindowHovered() || _wrappedCursor);
|
|
||||||
|
|
||||||
if (_hasFocus && !_editor.CurrentCamera.InUse)
|
|
||||||
{
|
|
||||||
if (Input.IsKeyPressing(.Q))
|
|
||||||
_gizmoType = .TRANSLATE;
|
|
||||||
if (Input.IsKeyPressing(.W))
|
|
||||||
_gizmoType = .ROTATE;
|
|
||||||
if (Input.IsKeyPressing(.E))
|
|
||||||
_gizmoType = .SCALE;
|
|
||||||
|
|
||||||
if (Input.IsKeyPressing(.G))
|
|
||||||
_gizmoMode = .WORLD;
|
|
||||||
if (Input.IsKeyPressing(.L))
|
|
||||||
_gizmoMode = .LOCAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_renderTarget != null)
|
|
||||||
{
|
|
||||||
ImGui.Image(_renderTarget.GetViewBinding(0), viewportSize);
|
|
||||||
//ImGui.Image(_editor.CurrentCamera.RenderTarget.GetViewBinding(0), viewportSize);
|
|
||||||
//ImGui.Image(_editor.CurrentScene.[Friend]_compositeTarget.GetViewBinding(0), viewportSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
HandleDropTarget();
|
|
||||||
|
|
||||||
bool gizmoUsed = DrawImGuizmo(viewportSize);
|
|
||||||
|
|
||||||
MousePicking(viewportSize, gizmoUsed);
|
|
||||||
|
|
||||||
ImGui.End();
|
|
||||||
|
|
||||||
if(_oldViewportSize != viewportSize)
|
|
||||||
{
|
|
||||||
ViewportSizeChanged.Invoke(this, (float2)viewportSize);
|
|
||||||
_viewPortChanged = true;
|
|
||||||
_oldViewportSize = viewportSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provides the ImGui Drop target and handles dropped payload.
|
|
||||||
private void HandleDropTarget()
|
|
||||||
{
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
|
||||||
{
|
|
||||||
ImGui.Payload* payload = ImGui.AcceptDragDropPayload("CONTENT_BROWSER_ITEM");
|
|
||||||
|
|
||||||
if (payload != null)
|
|
||||||
{
|
|
||||||
StringView path = .((char8*)payload.Data, (int)payload.DataSize);
|
|
||||||
_editor.RequestOpenScene(this, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndDragDropTarget();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wraps the mouse, so that it always stays in the viewport.
|
|
||||||
private void WrapMouseInViewport()
|
|
||||||
{
|
|
||||||
_wrappedCursor = false;
|
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
float2 newMousePos = mousePos;
|
|
||||||
|
|
||||||
if (mousePos.X < regionMin.X + 1)
|
|
||||||
{
|
|
||||||
newMousePos.X = regionMax.X - 2;
|
|
||||||
}
|
|
||||||
else if (mousePos.X > regionMax.X - 1)
|
|
||||||
{
|
|
||||||
newMousePos.X = regionMin.X + 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mousePos.Y < regionMin.Y + 1)
|
|
||||||
{
|
|
||||||
newMousePos.Y = regionMax.Y - 100;
|
|
||||||
}
|
|
||||||
else if (mousePos.Y > regionMax.Y - 1)
|
|
||||||
{
|
|
||||||
newMousePos.Y = regionMin.Y + 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (any(newMousePos != mousePos))
|
|
||||||
{
|
|
||||||
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
|
|
||||||
_editor.CurrentCamera.[Friend]MouseCooldown = 2;
|
|
||||||
_wrappedCursor = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If the user clicks, the entity beneath the cursor will be selected.
|
|
||||||
private void MousePicking(ImGui.Vec2 viewportSize, bool gizmoUsed)
|
|
||||||
{
|
|
||||||
float2 relativeMouse = (float2)ImGui.GetMousePos() - (float2)ImGui.GetItemRectMin();
|
|
||||||
|
|
||||||
int rtWidth = _editor.EditorSceneRenderer.CompositeTarget.Width;
|
|
||||||
int rtHeight = _editor.EditorSceneRenderer.CompositeTarget.Height;
|
|
||||||
|
|
||||||
if (Input.IsMouseButtonPressing(.LeftButton) &&
|
|
||||||
ImGui.IsWindowHovered() && !gizmoUsed && !_editor.CurrentCamera.InUse &&
|
|
||||||
relativeMouse.X >= 0 && relativeMouse.Y >= 0 &&
|
|
||||||
relativeMouse.X < viewportSize.x && relativeMouse.Y < viewportSize.y &&
|
|
||||||
relativeMouse.X < rtWidth && relativeMouse.Y < rtHeight)
|
|
||||||
{
|
|
||||||
uint32 id = uint32.MaxValue;
|
|
||||||
|
|
||||||
_editor.EditorSceneRenderer.CompositeTarget.GetData<uint32>(&id, 1, (.)relativeMouse.X, (.)relativeMouse.Y, 1, 1);
|
|
||||||
|
|
||||||
SelectionChanged = true;
|
|
||||||
SelectedEntityId = id;
|
|
||||||
|
|
||||||
EntityClicked(this, id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SelectionChanged = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShowMenuBar()
|
|
||||||
{
|
|
||||||
if(ImGui.BeginMenuBar())
|
|
||||||
{
|
|
||||||
if (ImGui.RadioButton("Position", _gizmoType.HasFlag(.TRANSLATE)))
|
|
||||||
{
|
|
||||||
if (Input.IsKeyPressed(Key.Control))
|
|
||||||
_gizmoType ^= .TRANSLATE;
|
|
||||||
else
|
|
||||||
_gizmoType = .TRANSLATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.RadioButton("Rotation", _gizmoType.HasFlag(.ROTATE)))
|
|
||||||
{
|
|
||||||
if (Input.IsKeyPressed(Key.Control))
|
|
||||||
_gizmoType ^= .ROTATE;
|
|
||||||
else
|
|
||||||
_gizmoType = .ROTATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.RadioButton("Scale", _gizmoType.HasFlag(.SCALE)))
|
|
||||||
{
|
|
||||||
if (Input.IsKeyPressed(Key.Control))
|
|
||||||
_gizmoType ^= .SCALE;
|
|
||||||
else
|
|
||||||
_gizmoType = .SCALE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.RadioButton("All", _gizmoType == .TRANSLATE | .ROTATE | .SCALE))
|
|
||||||
_gizmoType = .TRANSLATE | .ROTATE | .SCALE;
|
|
||||||
|
|
||||||
// If we scale, the mode must be local otherwise we could skew the matrix.
|
|
||||||
if (_gizmoType.HasFlag(.SCALE))
|
|
||||||
_gizmoMode = .LOCAL;
|
|
||||||
|
|
||||||
if (ImGui.MenuItem(_gizmoMode == .WORLD ? "Global" : "Local", null, true, !_gizmoType.HasFlag(.SCALE)))
|
|
||||||
{
|
|
||||||
if (_gizmoMode == .WORLD)
|
|
||||||
_gizmoMode = .LOCAL;
|
|
||||||
else
|
|
||||||
_gizmoMode = .WORLD;
|
|
||||||
}
|
|
||||||
|
|
||||||
_doSnap = Input.IsKeyPressed(.Shift);
|
|
||||||
|
|
||||||
ImGui.PushItemWidth(100);
|
|
||||||
|
|
||||||
if (_gizmoType.HasFlag(.ROTATE))
|
|
||||||
{
|
|
||||||
ImGui.DragFloat("Angle Snap", &_angleSnap, 1.0f, 0.0f, 180.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_gizmoType.HasFlag(.TRANSLATE) || _gizmoType.HasFlag(.SCALE))
|
|
||||||
{
|
|
||||||
ImGui.DragFloat("Snap", &_snap, 0.1f, 0.0f, float.MaxValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.PopItemWidth();
|
|
||||||
|
|
||||||
ImGui.EndMenuBar();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool DrawImGuizmo(ImGui.Vec2 viewportSize)
|
|
||||||
{
|
|
||||||
// TODO: Needed if we have a orthographic editor-camera (or support gizmos in the Play-Window, where we can also have ortho projections)
|
|
||||||
ImGuizmo.SetOrthographic(false);
|
|
||||||
ImGuizmo.SetDrawlist();
|
|
||||||
|
|
||||||
var topLeft = ImGui.GetWindowPos();
|
|
||||||
var cntMin = ImGui.GetWindowContentRegionMin();
|
|
||||||
|
|
||||||
topLeft.x += cntMin.x;
|
|
||||||
topLeft.y += cntMin.y;
|
|
||||||
ImGuizmo.SetRect(topLeft.x, topLeft.y, viewportSize.x, viewportSize.y);
|
|
||||||
|
|
||||||
var view = _editor.CurrentCamera.View;
|
|
||||||
var projection = _editor.CurrentCamera.Projection;
|
|
||||||
|
|
||||||
if(_editor.EntityHierarchyWindow.SelectedEntities.Count == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var entity = _editor.EntityHierarchyWindow.SelectedEntities.Back;
|
|
||||||
|
|
||||||
var transformCmp = entity.GetComponent<TransformComponent>();
|
|
||||||
|
|
||||||
var worldTransform = transformCmp.WorldTransform;
|
|
||||||
|
|
||||||
Matrix parentView = .Identity;
|
|
||||||
if (transformCmp.Parent != .InvalidEntity)
|
|
||||||
{
|
|
||||||
var parentTransformCmp = Entity(transformCmp.Parent, entity.Scene).GetComponent<TransformComponent>();
|
|
||||||
parentView = parentTransformCmp.WorldTransform.Invert();
|
|
||||||
}
|
|
||||||
|
|
||||||
float3 snap = (float3)_snap;
|
|
||||||
if (_gizmoType.HasFlag(.ROTATE))
|
|
||||||
snap = (float3)_angleSnap;
|
|
||||||
|
|
||||||
if (ImGuizmo.Manipulate((.)&view, (.)&projection, _gizmoType, _gizmoMode, (.)&worldTransform, null, _doSnap ? (.)&snap : null))
|
|
||||||
{
|
|
||||||
// TODO: Fix when parent is scaled
|
|
||||||
// Seems to work fine for parent rotation and translation but scaled parent ruins everything
|
|
||||||
// (probably because scaling a rotated matrix results in a skewed matrix, but unity can do it and so should we)
|
|
||||||
transformCmp.LocalTransform = parentView * worldTransform;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ImGuizmo.IsUsing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user