mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Texture processor cleanup, new asset properties config UI
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
_isSrgb = false
|
_isSrgb = false
|
||||||
},
|
},
|
||||||
Processor = "TextureProcessor",
|
Processor = "TextureProcessor",
|
||||||
ProcessorConfig = (GlitchyEditor.Assets.Importers.TextureProcessorConfig){
|
ProcessorConfig = (GlitchyEditor.Assets.Processors.TextureProcessorConfig){
|
||||||
_generateMipMaps = .No,
|
_generateMipMaps = .No,
|
||||||
_samplerStateDescription = {
|
_samplerStateDescription = {
|
||||||
MinFilter = .Linear,
|
MinFilter = .Linear,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
_isSrgb = false
|
_isSrgb = false
|
||||||
},
|
},
|
||||||
Processor = "TextureProcessor",
|
Processor = "TextureProcessor",
|
||||||
ProcessorConfig = (GlitchyEditor.Assets.Importers.TextureProcessorConfig){
|
ProcessorConfig = (GlitchyEditor.Assets.Processors.TextureProcessorConfig){
|
||||||
_generateMipMaps = .No,
|
_generateMipMaps = .No,
|
||||||
_samplerStateDescription = {
|
_samplerStateDescription = {
|
||||||
MinFilter = .Point,
|
MinFilter = .Point,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
_isSrgb = false
|
_isSrgb = false
|
||||||
},
|
},
|
||||||
Processor = "TextureProcessor",
|
Processor = "TextureProcessor",
|
||||||
ProcessorConfig = (GlitchyEditor.Assets.Importers.TextureProcessorConfig){
|
ProcessorConfig = (GlitchyEditor.Assets.Processors.TextureProcessorConfig){
|
||||||
_generateMipMaps = .No,
|
_generateMipMaps = .No,
|
||||||
_samplerStateDescription = {
|
_samplerStateDescription = {
|
||||||
MinFilter = .Linear,
|
MinFilter = .Linear,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using GlitchyEngine;
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using GlitchyEngine.Content;
|
using GlitchyEngine.Content;
|
||||||
|
using GlitchyEditor.Assets.Processors;
|
||||||
|
|
||||||
namespace GlitchyEditor.Assets;
|
namespace GlitchyEditor.Assets;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using GlitchyEngine.Renderer;
|
||||||
|
using GlitchyEditor.Assets.Processors;
|
||||||
|
using GlitchyEngine;
|
||||||
|
using GlitchyEditor.Assets.Importers;
|
||||||
|
namespace GlitchyEditor.Assets.Exporters;
|
||||||
|
|
||||||
|
|
||||||
|
class TextureExporter : IAssetExporter
|
||||||
|
{
|
||||||
|
public AssetExporterConfig CreateDefaultConfig()
|
||||||
|
{
|
||||||
|
return new AssetExporterConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<void> Export(Stream stream, ProcessedResource processedResource, AssetExporterConfig config)
|
||||||
|
{
|
||||||
|
Log.EngineLogger.AssertDebug(processedResource is ProcessedTexture);
|
||||||
|
|
||||||
|
ProcessedTexture processedTexture = (.)processedResource;
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
File Format:
|
||||||
|
TextureType (1 byte)
|
||||||
|
Pixel Format (4 bytes)
|
||||||
|
Width of larges mip-slice (4 bytes)
|
||||||
|
Height of larges mip-slice (4 bytes)
|
||||||
|
Depth of larges mip-slice (4 bytes)
|
||||||
|
Array size (4 bytes)
|
||||||
|
Mip map levels (4 bytes)
|
||||||
|
Is Cubemap (1 byte)
|
||||||
|
Data Byte count (8 bytes)
|
||||||
|
Pixeldata
|
||||||
|
{
|
||||||
|
Array[0]: Mip[0] Mip[1] ... Mip[M]
|
||||||
|
Array[1]: Mip[0] Mip[1] ... Mip[M]
|
||||||
|
...
|
||||||
|
Array[N]: Mip[0] Mip[1] ... Mip[M]
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
Try!(stream.Write(processedTexture.Dimension));
|
||||||
|
Try!(stream.Write(processedTexture.PixelFormat));
|
||||||
|
Try!(stream.Write((uint32)processedTexture.Width));
|
||||||
|
Try!(stream.Write((uint32)processedTexture.Height));
|
||||||
|
Try!(stream.Write((uint32)processedTexture.Depth));
|
||||||
|
Try!(stream.Write((uint32)processedTexture.ArraySize));
|
||||||
|
Try!(stream.Write((uint32)processedTexture.MipMapCount));
|
||||||
|
Try!(stream.Write(processedTexture.IsCubeMap));
|
||||||
|
|
||||||
|
Try!(WriteSamplerStateDescription(stream, processedTexture.SamplerStateDescription));
|
||||||
|
|
||||||
|
for (int arraySlice < processedTexture.ArraySize)
|
||||||
|
{
|
||||||
|
int validateWidth = processedTexture.Width;
|
||||||
|
int validateHeight = processedTexture.Height;
|
||||||
|
int validateDepth = processedTexture.Depth;
|
||||||
|
|
||||||
|
for (int mipSlice < processedTexture.MipMapCount)
|
||||||
|
{
|
||||||
|
ProcessedTexture.TextureSurface slice = processedTexture.Surfaces[arraySlice, mipSlice];
|
||||||
|
|
||||||
|
Log.EngineLogger.AssertDebug(validateWidth == slice.Width);
|
||||||
|
Log.EngineLogger.AssertDebug(validateHeight == slice.Height);
|
||||||
|
Log.EngineLogger.AssertDebug(validateDepth == slice.Depth);
|
||||||
|
validateWidth /= 2;
|
||||||
|
validateHeight /= 2;
|
||||||
|
validateDepth /= 2;
|
||||||
|
|
||||||
|
if (validateWidth < 1)
|
||||||
|
validateWidth = 1;
|
||||||
|
|
||||||
|
if (validateHeight < 1)
|
||||||
|
validateHeight = 1;
|
||||||
|
|
||||||
|
if (validateDepth < 1)
|
||||||
|
validateDepth = 1;
|
||||||
|
|
||||||
|
Try!(stream.Write((uint32)slice.LinePitch));
|
||||||
|
Try!(stream.Write((uint32)slice.SlicePitch));
|
||||||
|
Try!(stream.Write((uint64)slice.PixelData.Count));
|
||||||
|
Try!(stream.TryWrite(slice.PixelData));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result<void> WriteSamplerStateDescription(Stream stream, SamplerStateDescription sampler)
|
||||||
|
{
|
||||||
|
Try!(stream.Write(sampler.MinFilter));
|
||||||
|
Try!(stream.Write(sampler.MagFilter));
|
||||||
|
Try!(stream.Write(sampler.MipFilter));
|
||||||
|
Try!(stream.Write(sampler.FilterMode));
|
||||||
|
Try!(stream.Write(sampler.ComparisonFunction));
|
||||||
|
Try!(stream.Write(sampler.AddressModeU));
|
||||||
|
Try!(stream.Write(sampler.AddressModeV));
|
||||||
|
Try!(stream.Write(sampler.AddressModeW));
|
||||||
|
Try!(stream.Write(sampler.MipLODBias));
|
||||||
|
Try!(stream.Write(sampler.MipMinLOD));
|
||||||
|
Try!(stream.Write(sampler.MipMaxLOD));
|
||||||
|
Try!(stream.Write(sampler.MaxAnisotropy));
|
||||||
|
Try!(stream.Write(sampler.BorderColor));
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using Bon;
|
using Bon;
|
||||||
using GlitchyEngine.Content;
|
using GlitchyEngine.Content;
|
||||||
|
using ImGui;
|
||||||
|
|
||||||
namespace GlitchyEditor.Assets.Importers;
|
namespace GlitchyEditor.Assets.Importers;
|
||||||
|
|
||||||
@@ -21,18 +22,26 @@ abstract class Config
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract void ShowEditor();
|
||||||
}
|
}
|
||||||
|
|
||||||
[BonTarget, BonPolyRegister]
|
[BonTarget, BonPolyRegister]
|
||||||
class AssetImporterConfig : Config
|
class AssetImporterConfig : Config
|
||||||
{
|
{
|
||||||
|
public override void ShowEditor()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[BonTarget, BonPolyRegister]
|
[BonTarget, BonPolyRegister]
|
||||||
class AssetProcessorConfig : Config
|
class AssetProcessorConfig : Config
|
||||||
{
|
{
|
||||||
|
public override void ShowEditor()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[BonTarget, BonPolyRegister]
|
[BonTarget, BonPolyRegister]
|
||||||
@@ -46,4 +55,16 @@ class AssetExporterConfig : Config
|
|||||||
get => _compression;
|
get => _compression;
|
||||||
set => SetIfChanged(ref _compression, value);
|
set => SetIfChanged(ref _compression, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void ShowEditor()
|
||||||
|
{
|
||||||
|
ImGui.PropertyTableStartNewProperty("Compression");
|
||||||
|
ImGui.AttachTooltip("Specifies the compression method used to compress the processed asset.");
|
||||||
|
|
||||||
|
AssetCompression compression = _compression;
|
||||||
|
if (ImGui.EnumCombo<AssetCompression>("##Compression", ref compression))
|
||||||
|
{
|
||||||
|
Compression = compression;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using GlitchyEngine.Content;
|
||||||
|
|
||||||
|
namespace GlitchyEditor.Assets.Importers;
|
||||||
|
|
||||||
|
class ImportedResource
|
||||||
|
{
|
||||||
|
private AssetIdentifier _assetIdentifier ~ delete _;
|
||||||
|
|
||||||
|
public AssetIdentifier AssetIdentifier => _assetIdentifier;
|
||||||
|
|
||||||
|
public this(AssetIdentifier ownAssetIdentifier)
|
||||||
|
{
|
||||||
|
_assetIdentifier = ownAssetIdentifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using GlitchyEngine.Content;
|
using GlitchyEngine.Content;
|
||||||
|
using GlitchyEditor.Assets.Processors;
|
||||||
|
|
||||||
namespace GlitchyEditor.Assets.Importers;
|
namespace GlitchyEditor.Assets.Importers;
|
||||||
|
|
||||||
|
|||||||
@@ -6,22 +6,14 @@ using GlitchyEngine.Content;
|
|||||||
using GlitchyEngine;
|
using GlitchyEngine;
|
||||||
using GlitchyEngine.Renderer;
|
using GlitchyEngine.Renderer;
|
||||||
using GlitchyEngine.Math;
|
using GlitchyEngine.Math;
|
||||||
|
using System.Threading;
|
||||||
|
using GlitchyEditor.Assets.Processors;
|
||||||
|
using ImGui;
|
||||||
|
|
||||||
using static GlitchyEditor.Assets.Importers.LoadedTextureInfo;
|
using static GlitchyEditor.Assets.Importers.LoadedTextureInfo;
|
||||||
|
|
||||||
namespace GlitchyEditor.Assets.Importers;
|
namespace GlitchyEditor.Assets.Importers;
|
||||||
|
|
||||||
class ImportedResource
|
|
||||||
{
|
|
||||||
private AssetIdentifier _assetIdentifier ~ delete _;
|
|
||||||
|
|
||||||
public AssetIdentifier AssetIdentifier => _assetIdentifier;
|
|
||||||
|
|
||||||
public this(AssetIdentifier ownAssetIdentifier)
|
|
||||||
{
|
|
||||||
_assetIdentifier = ownAssetIdentifier;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ImportedTexture : ImportedResource
|
class ImportedTexture : ImportedResource
|
||||||
{
|
{
|
||||||
//public TextureDimension TextureType;
|
//public TextureDimension TextureType;
|
||||||
@@ -48,6 +40,18 @@ class TextureImporterConfig : AssetImporterConfig
|
|||||||
get => _isSrgb;
|
get => _isSrgb;
|
||||||
set => SetIfChanged(ref _isSrgb, value);
|
set => SetIfChanged(ref _isSrgb, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void ShowEditor()
|
||||||
|
{
|
||||||
|
ImGui.PropertyTableStartNewProperty("Is sRGB");
|
||||||
|
ImGui.AttachTooltip("If checked, the texture will be forced to be imported as sRGB. Refer to the documentation for an detailed explanation what you should do here.");
|
||||||
|
|
||||||
|
bool isSrgb = _isSrgb;
|
||||||
|
if (ImGui.Checkbox("##isSrgb", &isSrgb))
|
||||||
|
{
|
||||||
|
IsSrgb = isSrgb;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -64,6 +68,8 @@ class TextureImporter : IAssetImporter
|
|||||||
|
|
||||||
public Result<ImportedResource> Import(StringView fullFileName, AssetIdentifier assetIdentifier, AssetImporterConfig config)
|
public Result<ImportedResource> Import(StringView fullFileName, AssetIdentifier assetIdentifier, AssetImporterConfig config)
|
||||||
{
|
{
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(config is TextureImporterConfig);
|
Log.EngineLogger.AssertDebug(config is TextureImporterConfig);
|
||||||
|
|
||||||
ImportedTexture importedData = new ImportedTexture(new AssetIdentifier(assetIdentifier.FullIdentifier));
|
ImportedTexture importedData = new ImportedTexture(new AssetIdentifier(assetIdentifier.FullIdentifier));
|
||||||
@@ -221,443 +227,3 @@ class TextureImporter : IAssetImporter
|
|||||||
return .Ok;
|
return .Ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[BonTarget]
|
|
||||||
enum GenerateMipMaps
|
|
||||||
{
|
|
||||||
No,
|
|
||||||
Box,
|
|
||||||
Kaiser
|
|
||||||
}
|
|
||||||
|
|
||||||
[BonTarget, BonPolyRegister]
|
|
||||||
class TextureProcessorConfig : AssetProcessorConfig
|
|
||||||
{
|
|
||||||
[BonInclude]
|
|
||||||
private GenerateMipMaps _generateMipMaps;
|
|
||||||
|
|
||||||
[BonInclude]
|
|
||||||
private SamplerStateDescription _samplerStateDescription = .();
|
|
||||||
|
|
||||||
public GenerateMipMaps GenerateMipMaps
|
|
||||||
{
|
|
||||||
get => _generateMipMaps;
|
|
||||||
set => SetIfChanged(ref _generateMipMaps, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SamplerStateDescription SamplerStateDescription
|
|
||||||
{
|
|
||||||
get => _samplerStateDescription;
|
|
||||||
set => SetIfChanged(ref _samplerStateDescription, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class ProcessedResource
|
|
||||||
{
|
|
||||||
private AssetIdentifier _assetIdentifier ~ delete _;
|
|
||||||
|
|
||||||
public AssetIdentifier AssetIdentifier => _assetIdentifier;
|
|
||||||
|
|
||||||
public abstract AssetType AssetType {get;}
|
|
||||||
|
|
||||||
public this(AssetIdentifier ownAssetIdentifier)
|
|
||||||
{
|
|
||||||
_assetIdentifier = ownAssetIdentifier;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ProcessedTexture : ProcessedResource
|
|
||||||
{
|
|
||||||
public Format PixelFormat = .Unknown;
|
|
||||||
public int MipMapCount = -1;
|
|
||||||
public int ArraySize = -1;
|
|
||||||
public TextureDimension Dimension = .Unknown;
|
|
||||||
public bool IsCubeMap;
|
|
||||||
|
|
||||||
public int Width = -1;
|
|
||||||
public int Height = -1;
|
|
||||||
public int Depth = -1;
|
|
||||||
|
|
||||||
public SamplerStateDescription SamplerStateDescription;
|
|
||||||
|
|
||||||
public override AssetType AssetType => .Texture;
|
|
||||||
|
|
||||||
public class TextureSurface
|
|
||||||
{
|
|
||||||
public uint8[] PixelData;
|
|
||||||
public int Width;
|
|
||||||
public int Height;
|
|
||||||
public int Depth;
|
|
||||||
public int MipLevel;
|
|
||||||
public int ArraySlice;
|
|
||||||
public int LinePitch;
|
|
||||||
public int SlicePitch;
|
|
||||||
|
|
||||||
[AllowAppend]
|
|
||||||
public this(int width, int height, int depth, Span<uint8> data, int mipLevel, int arraySlice, int linePitch, int slicePitch)
|
|
||||||
{
|
|
||||||
uint8[] pixelData = append uint8[data.Length];
|
|
||||||
data.CopyTo(pixelData);
|
|
||||||
|
|
||||||
PixelData = pixelData;
|
|
||||||
Width = width;
|
|
||||||
Height = height;
|
|
||||||
Depth = depth;
|
|
||||||
MipLevel = mipLevel;
|
|
||||||
ArraySlice = arraySlice;
|
|
||||||
LinePitch = linePitch;
|
|
||||||
SlicePitch = slicePitch;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint64 LoadRaw(int x, int y, int z, Format format, ComponentInfo component)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.AssertDebug(x >= 0 && y >= 0 && z >= 0 && x < Width && y < Height && z < Depth);
|
|
||||||
|
|
||||||
int64 pixelOffset = x + (Width * y) + (Width * Height) * z;
|
|
||||||
|
|
||||||
int64 bitOffset = pixelOffset * format.BitsPerPixel();
|
|
||||||
|
|
||||||
bitOffset += component.BitSize;
|
|
||||||
|
|
||||||
int64 byteOffset = bitOffset / 8;
|
|
||||||
int shift = bitOffset % 8;
|
|
||||||
|
|
||||||
int bytesToRead = (component.BitSize + shift) / 8;
|
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(bytesToRead <= 8);
|
|
||||||
|
|
||||||
uint64 data = 0;
|
|
||||||
|
|
||||||
data = PixelData.Ptr[byteOffset];
|
|
||||||
data >>= shift;
|
|
||||||
uint64 mask = (1 << component.BitSize) - 1;
|
|
||||||
data &= mask;
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public TextureSurface[,] Surfaces;
|
|
||||||
|
|
||||||
public this(AssetIdentifier ownAssetIdentifier) : base(ownAssetIdentifier)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public ~this()
|
|
||||||
{
|
|
||||||
for (int i < Surfaces?.GetLength(0) ?? 0)
|
|
||||||
{
|
|
||||||
for (int j < Surfaces.GetLength(1))
|
|
||||||
{
|
|
||||||
delete Surfaces[i, j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete Surfaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetSurfaceCount(int arraySize, int mipMapCount)
|
|
||||||
{
|
|
||||||
ArraySize = arraySize;
|
|
||||||
|
|
||||||
if (IsCubeMap)
|
|
||||||
ArraySize *= 6;
|
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(Surfaces == null || arraySize > Surfaces.GetLength(0));
|
|
||||||
Log.EngineLogger.AssertDebug(Surfaces == null ||mipMapCount > Surfaces.GetLength(1));
|
|
||||||
|
|
||||||
MipMapCount = mipMapCount;
|
|
||||||
|
|
||||||
TextureSurface[,] oldSurfaces = Surfaces;
|
|
||||||
Surfaces = new TextureSurface[ArraySize, MipMapCount];
|
|
||||||
|
|
||||||
if (oldSurfaces != null)
|
|
||||||
{
|
|
||||||
for (int i < oldSurfaces.GetLength(0))
|
|
||||||
{
|
|
||||||
for (int j < oldSurfaces.GetLength(1))
|
|
||||||
{
|
|
||||||
Surfaces[i, j] = oldSurfaces[i, j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TextureProcessor : IAssetProcessor
|
|
||||||
{
|
|
||||||
public AssetProcessorConfig CreateDefaultConfig()
|
|
||||||
{
|
|
||||||
return new TextureProcessorConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Result<ProcessedResource> Process(ImportedResource importedObject, AssetProcessorConfig config)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.AssertDebug(config is TextureProcessorConfig);
|
|
||||||
Log.EngineLogger.AssertDebug(importedObject is ImportedTexture);
|
|
||||||
|
|
||||||
return Try!(ProcessTexture(importedObject as ImportedTexture, config as TextureProcessorConfig));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Result<ProcessedTexture> ProcessTexture(ImportedTexture importedTexture, TextureProcessorConfig config)
|
|
||||||
{
|
|
||||||
ProcessedTexture processedTexture = new ProcessedTexture(new AssetIdentifier(importedTexture.AssetIdentifier.FullIdentifier));
|
|
||||||
|
|
||||||
processedTexture.Dimension = importedTexture.TextureInfo.Dimension;
|
|
||||||
processedTexture.PixelFormat = (.)importedTexture.TextureInfo.PixelFormat;
|
|
||||||
processedTexture.IsCubeMap = importedTexture.TextureInfo.IsCubeMap;
|
|
||||||
processedTexture.Width = importedTexture.TextureInfo.Width;
|
|
||||||
processedTexture.Height = importedTexture.TextureInfo.Height;
|
|
||||||
processedTexture.Depth = importedTexture.TextureInfo.Depth;
|
|
||||||
|
|
||||||
processedTexture.SamplerStateDescription = config.SamplerStateDescription;
|
|
||||||
|
|
||||||
processedTexture.SetSurfaceCount(importedTexture.TextureInfo.ArraySize, importedTexture.TextureInfo.MipMapCount);
|
|
||||||
|
|
||||||
for (LoadedSurface loadedSurface in importedTexture.Surfaces)
|
|
||||||
{
|
|
||||||
ProcessedTexture.TextureSurface surface = new .(loadedSurface.Width, loadedSurface.Height, loadedSurface.Depth,
|
|
||||||
loadedSurface.Data, loadedSurface.MipLevel, loadedSurface.ArrayIndex, loadedSurface.Pitch, loadedSurface.SlicePitch);
|
|
||||||
|
|
||||||
processedTexture.Surfaces[loadedSurface.ArrayIndex * (processedTexture.IsCubeMap ? 6 : 1) + loadedSurface.CubeFace, loadedSurface.MipLevel] = surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(config.GenerateMipMaps case .No))
|
|
||||||
{
|
|
||||||
// TODO: Unpack BC-Formats to RGBA
|
|
||||||
|
|
||||||
GenerateMipMaps(processedTexture, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Pack to BC-Format or what ever was selected.
|
|
||||||
|
|
||||||
return processedTexture;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int CalculateMipMapCount(int width, int height, int depth)
|
|
||||||
{
|
|
||||||
var width, height, depth;
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
|
|
||||||
if (width == 1 && height == 1 && depth == 1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (width > 1)
|
|
||||||
width >>= 1;
|
|
||||||
if (height > 1)
|
|
||||||
height >>= 1;
|
|
||||||
if (depth > 1)
|
|
||||||
depth >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CanGenerateMipMaps(Format format)
|
|
||||||
{
|
|
||||||
// TODO!
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Result<void> GenerateMipMaps(ProcessedTexture processedTexture, TextureProcessorConfig config)
|
|
||||||
{
|
|
||||||
if (!CanGenerateMipMaps(processedTexture.PixelFormat))
|
|
||||||
{
|
|
||||||
return .Err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mipMapCount = CalculateMipMapCount(processedTexture.Width, processedTexture.Height, processedTexture.Depth);
|
|
||||||
|
|
||||||
if (processedTexture.MipMapCount != mipMapCount)
|
|
||||||
{
|
|
||||||
processedTexture.SetSurfaceCount(processedTexture.ArraySize, mipMapCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int arraySlice < processedTexture.ArraySize)
|
|
||||||
{
|
|
||||||
ProcessedTexture.TextureSurface largerSurface = processedTexture.Surfaces[arraySlice, 0];
|
|
||||||
|
|
||||||
for (int mipMap = 1; mipMap < processedTexture.MipMapCount; mipMap++)
|
|
||||||
{
|
|
||||||
ref ProcessedTexture.TextureSurface surface = ref processedTexture.Surfaces[arraySlice, mipMap];
|
|
||||||
|
|
||||||
surface = GenerateMipLevel(processedTexture.PixelFormat, largerSurface, surface);
|
|
||||||
|
|
||||||
largerSurface = surface;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return .Ok;
|
|
||||||
|
|
||||||
// TODO: Generate Mip Maps
|
|
||||||
/*int mipMapCount = CalculateMipMapCount(processedTexture.Width, processedTexture.Height, processedTexture.Depth);
|
|
||||||
|
|
||||||
processedTexture.SetMipMapCount(mipMapCount);
|
|
||||||
|
|
||||||
for (int slice < processedTexture.ArraySize)
|
|
||||||
{
|
|
||||||
for (int mipMap < mipMapCount)
|
|
||||||
{
|
|
||||||
if (processedTexture.Surfaces[slice, mipMap] == null)
|
|
||||||
{
|
|
||||||
processedTexture.Surfaces[slice, mipMap] = GenerateMipLevel(processedTexture.Surfaces[slice, mipMap - 1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
private ProcessedTexture.TextureSurface GenerateMipLevel(Format pixelFormat, ProcessedTexture.TextureSurface largerLevel, ProcessedTexture.TextureSurface smallerLevel)
|
|
||||||
{
|
|
||||||
var smallerLevel;
|
|
||||||
|
|
||||||
int width = Math.Max(largerLevel.Width / 2, 1);
|
|
||||||
int height = Math.Max(largerLevel.Height / 2, 1);
|
|
||||||
int depth = Math.Max(largerLevel.Depth / 2, 1);
|
|
||||||
|
|
||||||
if (smallerLevel == null)
|
|
||||||
{
|
|
||||||
smallerLevel = new ProcessedTexture.TextureSurface(width, height, depth,
|
|
||||||
new uint8[width * height * depth * pixelFormat.BitsPerPixel()], largerLevel.MipLevel + 1, largerLevel.ArraySlice,
|
|
||||||
-1, -1); // TODO!
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Kaiser mip maps?
|
|
||||||
|
|
||||||
FormatInfo formatInfo = default; //pixelFormat.GetFormatInfo();
|
|
||||||
|
|
||||||
// Simple box filter
|
|
||||||
for (int x < width)
|
|
||||||
for (int y < height)
|
|
||||||
for (int z < depth)
|
|
||||||
{
|
|
||||||
for (int channel < formatInfo.ComponentCount)
|
|
||||||
{
|
|
||||||
ComponentInfo info = formatInfo.Components[channel];
|
|
||||||
|
|
||||||
switch (info.DataType)
|
|
||||||
{
|
|
||||||
case .UNorm, .UInt:
|
|
||||||
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return smallerLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Box<DataType>() where DataType : const ComponentDataType
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TextureExporter : IAssetExporter
|
|
||||||
{
|
|
||||||
public AssetExporterConfig CreateDefaultConfig()
|
|
||||||
{
|
|
||||||
return new AssetExporterConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Result<void> Export(Stream stream, ProcessedResource processedResource, AssetExporterConfig config)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.AssertDebug(processedResource is ProcessedTexture);
|
|
||||||
|
|
||||||
ProcessedTexture processedTexture = (.)processedResource;
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
File Format:
|
|
||||||
TextureType (1 byte)
|
|
||||||
Pixel Format (4 bytes)
|
|
||||||
Width of larges mip-slice (4 bytes)
|
|
||||||
Height of larges mip-slice (4 bytes)
|
|
||||||
Depth of larges mip-slice (4 bytes)
|
|
||||||
Array size (4 bytes)
|
|
||||||
Mip map levels (4 bytes)
|
|
||||||
Is Cubemap (1 byte)
|
|
||||||
Data Byte count (8 bytes)
|
|
||||||
Pixeldata
|
|
||||||
{
|
|
||||||
Array[0]: Mip[0] Mip[1] ... Mip[M]
|
|
||||||
Array[1]: Mip[0] Mip[1] ... Mip[M]
|
|
||||||
...
|
|
||||||
Array[N]: Mip[0] Mip[1] ... Mip[M]
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
Try!(stream.Write(processedTexture.Dimension));
|
|
||||||
Try!(stream.Write(processedTexture.PixelFormat));
|
|
||||||
Try!(stream.Write((uint32)processedTexture.Width));
|
|
||||||
Try!(stream.Write((uint32)processedTexture.Height));
|
|
||||||
Try!(stream.Write((uint32)processedTexture.Depth));
|
|
||||||
Try!(stream.Write((uint32)processedTexture.ArraySize));
|
|
||||||
Try!(stream.Write((uint32)processedTexture.MipMapCount));
|
|
||||||
Try!(stream.Write(processedTexture.IsCubeMap));
|
|
||||||
|
|
||||||
Try!(WriteSamplerStateDescription(stream, processedTexture.SamplerStateDescription));
|
|
||||||
|
|
||||||
for (int arraySlice < processedTexture.ArraySize)
|
|
||||||
{
|
|
||||||
int validateWidth = processedTexture.Width;
|
|
||||||
int validateHeight = processedTexture.Height;
|
|
||||||
int validateDepth = processedTexture.Depth;
|
|
||||||
|
|
||||||
for (int mipSlice < processedTexture.MipMapCount)
|
|
||||||
{
|
|
||||||
ProcessedTexture.TextureSurface slice = processedTexture.Surfaces[arraySlice, mipSlice];
|
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(validateWidth == slice.Width);
|
|
||||||
Log.EngineLogger.AssertDebug(validateHeight == slice.Height);
|
|
||||||
Log.EngineLogger.AssertDebug(validateDepth == slice.Depth);
|
|
||||||
validateWidth /= 2;
|
|
||||||
validateHeight /= 2;
|
|
||||||
validateDepth /= 2;
|
|
||||||
|
|
||||||
if (validateWidth < 1)
|
|
||||||
validateWidth = 1;
|
|
||||||
|
|
||||||
if (validateHeight < 1)
|
|
||||||
validateHeight = 1;
|
|
||||||
|
|
||||||
if (validateDepth < 1)
|
|
||||||
validateDepth = 1;
|
|
||||||
|
|
||||||
Try!(stream.Write((uint32)slice.LinePitch));
|
|
||||||
Try!(stream.Write((uint32)slice.SlicePitch));
|
|
||||||
Try!(stream.Write((uint64)slice.PixelData.Count));
|
|
||||||
Try!(stream.TryWrite(slice.PixelData));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return .Ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Result<void> WriteSamplerStateDescription(Stream stream, SamplerStateDescription sampler)
|
|
||||||
{
|
|
||||||
Try!(stream.Write(sampler.MinFilter));
|
|
||||||
Try!(stream.Write(sampler.MagFilter));
|
|
||||||
Try!(stream.Write(sampler.MipFilter));
|
|
||||||
Try!(stream.Write(sampler.FilterMode));
|
|
||||||
Try!(stream.Write(sampler.ComparisonFunction));
|
|
||||||
Try!(stream.Write(sampler.AddressModeU));
|
|
||||||
Try!(stream.Write(sampler.AddressModeV));
|
|
||||||
Try!(stream.Write(sampler.AddressModeW));
|
|
||||||
Try!(stream.Write(sampler.MipLODBias));
|
|
||||||
Try!(stream.Write(sampler.MipMinLOD));
|
|
||||||
Try!(stream.Write(sampler.MipMaxLOD));
|
|
||||||
Try!(stream.Write(sampler.MaxAnisotropy));
|
|
||||||
Try!(stream.Write(sampler.BorderColor));
|
|
||||||
|
|
||||||
return .Ok;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using GlitchyEngine.Content;
|
||||||
|
|
||||||
|
namespace GlitchyEditor.Assets.Processors;
|
||||||
|
|
||||||
|
abstract class ProcessedResource
|
||||||
|
{
|
||||||
|
private AssetIdentifier _assetIdentifier ~ delete _;
|
||||||
|
|
||||||
|
public AssetIdentifier AssetIdentifier => _assetIdentifier;
|
||||||
|
|
||||||
|
public abstract AssetType AssetType {get;}
|
||||||
|
|
||||||
|
public this(AssetIdentifier ownAssetIdentifier)
|
||||||
|
{
|
||||||
|
_assetIdentifier = ownAssetIdentifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,451 @@
|
|||||||
|
using System;
|
||||||
|
using Bon;
|
||||||
|
using GlitchyEditor.Assets.Importers;
|
||||||
|
using GlitchyEngine.Renderer;
|
||||||
|
using GlitchyEngine.Content;
|
||||||
|
using GlitchyEngine;
|
||||||
|
using ImGui;
|
||||||
|
|
||||||
|
namespace GlitchyEditor.Assets.Processors;
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
enum GenerateMipMaps
|
||||||
|
{
|
||||||
|
No,
|
||||||
|
Box,
|
||||||
|
Kaiser
|
||||||
|
}
|
||||||
|
|
||||||
|
[BonTarget, BonPolyRegister]
|
||||||
|
class TextureProcessorConfig : AssetProcessorConfig
|
||||||
|
{
|
||||||
|
[BonInclude]
|
||||||
|
private GenerateMipMaps _generateMipMaps;
|
||||||
|
|
||||||
|
[BonInclude]
|
||||||
|
private SamplerStateDescription _samplerStateDescription = .();
|
||||||
|
|
||||||
|
public GenerateMipMaps GenerateMipMaps
|
||||||
|
{
|
||||||
|
get => _generateMipMaps;
|
||||||
|
set => SetIfChanged(ref _generateMipMaps, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SamplerStateDescription SamplerStateDescription
|
||||||
|
{
|
||||||
|
get => _samplerStateDescription;
|
||||||
|
set => SetIfChanged(ref _samplerStateDescription, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ShowEditor()
|
||||||
|
{
|
||||||
|
ImGui.PropertyTableStartNewProperty("Generate Mip Maps", "Specifies the algorithm used to generate mip maps for this texture.");
|
||||||
|
|
||||||
|
ImGui.BeginDisabled();
|
||||||
|
|
||||||
|
GenerateMipMaps generateMipMaps = _generateMipMaps;
|
||||||
|
if (ImGui.EnumCombo("##generateMipMaps", ref generateMipMaps))
|
||||||
|
{
|
||||||
|
GenerateMipMaps = generateMipMaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Show some mip map generation settings (e.g. count)
|
||||||
|
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
|
ImGui.PropertyTableStartNewRow();
|
||||||
|
if (ImGui.TreeNodeEx("Sampling", ImGui.TreeNodeFlags.SpanAllColumns | ImGui.TreeNodeFlags.Framed))
|
||||||
|
{
|
||||||
|
ref SamplerStateDescription sampler = ref _samplerStateDescription;
|
||||||
|
|
||||||
|
bool IsAnisotropic()
|
||||||
|
{
|
||||||
|
return sampler.MinFilter == .Anisotropic ||
|
||||||
|
sampler.MagFilter == .Anisotropic ||
|
||||||
|
sampler.MipFilter == .Anisotropic;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsAnisotropic())
|
||||||
|
{
|
||||||
|
ImGui.PropertyTableStartNewProperty("Filter", "Sampling method used for minification, magnification and mip-level sampling. Note: If one filter is set to Anisotropic, all are set to Anisotropic.");
|
||||||
|
|
||||||
|
FilterFunction filter = .Anisotropic;
|
||||||
|
if (ImGui.EnumCombo("##minFilter", ref filter))
|
||||||
|
{
|
||||||
|
_changed = true;
|
||||||
|
|
||||||
|
if (sampler.MinFilter == .Anisotropic)
|
||||||
|
sampler.MinFilter = filter;
|
||||||
|
|
||||||
|
if (sampler.MagFilter == .Anisotropic)
|
||||||
|
sampler.MagFilter = filter;
|
||||||
|
|
||||||
|
if (sampler.MipFilter == .Anisotropic)
|
||||||
|
sampler.MipFilter = filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.PropertyTableStartNewProperty("Max Anisotropy", "Clamps the anisotropic sampling rate to the specified value.");
|
||||||
|
int32 maxAnisotropy = sampler.MaxAnisotropy;
|
||||||
|
if (ImGui.SliderInt("##maxAnisotropy", &maxAnisotropy, 1, 16))
|
||||||
|
{
|
||||||
|
sampler.MaxAnisotropy = (uint8)maxAnisotropy;
|
||||||
|
_changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.PropertyTableStartNewProperty("Min Filter", "Sampling method used for minification. Note: If one filter is set to Anisotropic, all are set to Anisotropic.");
|
||||||
|
if (ImGui.EnumCombo("##minFilter", ref sampler.MinFilter))
|
||||||
|
_changed = true;
|
||||||
|
|
||||||
|
ImGui.PropertyTableStartNewProperty("Mag Filter", "Sampling method used for magnification. Note: If one filter is set to Anisotropic, all are set to Anisotropic.");
|
||||||
|
if (ImGui.EnumCombo("##magFilter", ref sampler.MagFilter))
|
||||||
|
_changed = true;
|
||||||
|
|
||||||
|
ImGui.PropertyTableStartNewProperty("Mip Filter", "Method used for mip-level sampling. Note: If one filter is set to Anisotropic, all are set to Anisotropic.");
|
||||||
|
if (ImGui.EnumCombo("##mipFilter", ref sampler.MipFilter))
|
||||||
|
_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.PropertyTableStartNewProperty("Mip LOD Bias", "Offset from the calculated mipmap level.");
|
||||||
|
if (ImGui.DragFloat("##mipLodBias", &sampler.MipLODBias))
|
||||||
|
_changed = true;
|
||||||
|
|
||||||
|
ImGui.PropertyTableStartNewProperty("Mip Min LOD", "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.");
|
||||||
|
if (ImGui.DragFloat("##mipMinLod", &sampler.MipMinLOD, v_min: 0.0f, v_max: 64))
|
||||||
|
_changed = true;
|
||||||
|
|
||||||
|
ImGui.PropertyTableStartNewProperty("Mip Max LOD", "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.");
|
||||||
|
if (ImGui.DragFloat("##mipMaxLod", &sampler.MipMaxLOD, v_min: 0.0f, v_max: 64))
|
||||||
|
_changed = true;
|
||||||
|
|
||||||
|
// Make sure max lod is always at least min lod.
|
||||||
|
sampler.MipMaxLOD = Math.Max(sampler.MipMaxLOD, sampler.MipMinLOD);
|
||||||
|
|
||||||
|
ImGui.PropertyTableStartNewProperty("Filter mode", "Filtering method to use when sampling a texture.");
|
||||||
|
if (ImGui.EnumCombo("##filterMode", ref sampler.FilterMode))
|
||||||
|
_changed = true;
|
||||||
|
|
||||||
|
if (sampler.FilterMode == .Comparison)
|
||||||
|
{
|
||||||
|
ImGui.PropertyTableStartNewProperty("Comparison function", "The function that is used to compare the sampled data against the existing sampled data.");
|
||||||
|
if (ImGui.EnumCombo("##ComparisonFunction", ref sampler.ComparisonFunction))
|
||||||
|
_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.PropertyTableStartNewProperty("Address Mode U", "Method to use for resolving a u texture coordinate that is outside the 0 to 1 range.");
|
||||||
|
if (ImGui.EnumCombo("##AddressModeU", ref sampler.AddressModeU))
|
||||||
|
_changed = true;
|
||||||
|
|
||||||
|
ImGui.PropertyTableStartNewProperty("Address ModeV", "Method to use for resolving a v texture coordinate that is outside the 0 to 1 range.");
|
||||||
|
if (ImGui.EnumCombo("##AddressModeV", ref sampler.AddressModeV))
|
||||||
|
_changed = true;
|
||||||
|
|
||||||
|
ImGui.PropertyTableStartNewProperty("Address ModeW", "Method to use for resolving a w texture coordinate that is outside the 0 to 1 range.");
|
||||||
|
if (ImGui.EnumCombo("##AddressModeW", ref sampler.AddressModeW))
|
||||||
|
_changed = true;
|
||||||
|
|
||||||
|
if (sampler.AddressModeU == .Border || sampler.AddressModeV == .Border || sampler.AddressModeW == .Border)
|
||||||
|
{
|
||||||
|
ImGui.PropertyTableStartNewProperty("Border Color", "Border color to use if any of the address modes is set to Border");
|
||||||
|
if (ImGui.ColorEdit4("##BorderColor", ref sampler.BorderColor))
|
||||||
|
_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TreePop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ProcessedTexture : ProcessedResource
|
||||||
|
{
|
||||||
|
public Format PixelFormat = .Unknown;
|
||||||
|
public int MipMapCount = -1;
|
||||||
|
public int ArraySize = -1;
|
||||||
|
public TextureDimension Dimension = .Unknown;
|
||||||
|
public bool IsCubeMap;
|
||||||
|
|
||||||
|
public int Width = -1;
|
||||||
|
public int Height = -1;
|
||||||
|
public int Depth = -1;
|
||||||
|
|
||||||
|
public SamplerStateDescription SamplerStateDescription;
|
||||||
|
|
||||||
|
public override AssetType AssetType => .Texture;
|
||||||
|
|
||||||
|
public class TextureSurface
|
||||||
|
{
|
||||||
|
public uint8[] PixelData;
|
||||||
|
public int Width;
|
||||||
|
public int Height;
|
||||||
|
public int Depth;
|
||||||
|
public int MipLevel;
|
||||||
|
public int ArraySlice;
|
||||||
|
public int LinePitch;
|
||||||
|
public int SlicePitch;
|
||||||
|
|
||||||
|
[AllowAppend]
|
||||||
|
public this(int width, int height, int depth, Span<uint8> data, int mipLevel, int arraySlice, int linePitch, int slicePitch)
|
||||||
|
{
|
||||||
|
uint8[] pixelData = append uint8[data.Length];
|
||||||
|
data.CopyTo(pixelData);
|
||||||
|
|
||||||
|
PixelData = pixelData;
|
||||||
|
Width = width;
|
||||||
|
Height = height;
|
||||||
|
Depth = depth;
|
||||||
|
MipLevel = mipLevel;
|
||||||
|
ArraySlice = arraySlice;
|
||||||
|
LinePitch = linePitch;
|
||||||
|
SlicePitch = slicePitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint64 LoadRaw(int x, int y, int z, Format format, ComponentInfo component)
|
||||||
|
{
|
||||||
|
Log.EngineLogger.AssertDebug(x >= 0 && y >= 0 && z >= 0 && x < Width && y < Height && z < Depth);
|
||||||
|
|
||||||
|
int64 pixelOffset = x + (Width * y) + (Width * Height) * z;
|
||||||
|
|
||||||
|
int64 bitOffset = pixelOffset * format.BitsPerPixel();
|
||||||
|
|
||||||
|
bitOffset += component.BitSize;
|
||||||
|
|
||||||
|
int64 byteOffset = bitOffset / 8;
|
||||||
|
int shift = bitOffset % 8;
|
||||||
|
|
||||||
|
int bytesToRead = (component.BitSize + shift) / 8;
|
||||||
|
|
||||||
|
Log.EngineLogger.AssertDebug(bytesToRead <= 8);
|
||||||
|
|
||||||
|
uint64 data = 0;
|
||||||
|
|
||||||
|
data = PixelData.Ptr[byteOffset];
|
||||||
|
data >>= shift;
|
||||||
|
uint64 mask = (1 << component.BitSize) - 1;
|
||||||
|
data &= mask;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextureSurface[,] Surfaces;
|
||||||
|
|
||||||
|
public this(AssetIdentifier ownAssetIdentifier) : base(ownAssetIdentifier)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ~this()
|
||||||
|
{
|
||||||
|
for (int i < Surfaces?.GetLength(0) ?? 0)
|
||||||
|
{
|
||||||
|
for (int j < Surfaces.GetLength(1))
|
||||||
|
{
|
||||||
|
delete Surfaces[i, j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete Surfaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetSurfaceCount(int arraySize, int mipMapCount)
|
||||||
|
{
|
||||||
|
ArraySize = arraySize;
|
||||||
|
|
||||||
|
if (IsCubeMap)
|
||||||
|
ArraySize *= 6;
|
||||||
|
|
||||||
|
Log.EngineLogger.AssertDebug(Surfaces == null || arraySize > Surfaces.GetLength(0));
|
||||||
|
Log.EngineLogger.AssertDebug(Surfaces == null ||mipMapCount > Surfaces.GetLength(1));
|
||||||
|
|
||||||
|
MipMapCount = mipMapCount;
|
||||||
|
|
||||||
|
TextureSurface[,] oldSurfaces = Surfaces;
|
||||||
|
Surfaces = new TextureSurface[ArraySize, MipMapCount];
|
||||||
|
|
||||||
|
if (oldSurfaces != null)
|
||||||
|
{
|
||||||
|
for (int i < oldSurfaces.GetLength(0))
|
||||||
|
{
|
||||||
|
for (int j < oldSurfaces.GetLength(1))
|
||||||
|
{
|
||||||
|
Surfaces[i, j] = oldSurfaces[i, j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TextureProcessor : IAssetProcessor
|
||||||
|
{
|
||||||
|
public AssetProcessorConfig CreateDefaultConfig()
|
||||||
|
{
|
||||||
|
return new TextureProcessorConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<ProcessedResource> Process(ImportedResource importedObject, AssetProcessorConfig config)
|
||||||
|
{
|
||||||
|
Log.EngineLogger.AssertDebug(config is TextureProcessorConfig);
|
||||||
|
Log.EngineLogger.AssertDebug(importedObject is ImportedTexture);
|
||||||
|
|
||||||
|
return Try!(ProcessTexture(importedObject as ImportedTexture, config as TextureProcessorConfig));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result<ProcessedTexture> ProcessTexture(ImportedTexture importedTexture, TextureProcessorConfig config)
|
||||||
|
{
|
||||||
|
ProcessedTexture processedTexture = new ProcessedTexture(new AssetIdentifier(importedTexture.AssetIdentifier.FullIdentifier));
|
||||||
|
|
||||||
|
processedTexture.Dimension = importedTexture.TextureInfo.Dimension;
|
||||||
|
processedTexture.PixelFormat = (.)importedTexture.TextureInfo.PixelFormat;
|
||||||
|
processedTexture.IsCubeMap = importedTexture.TextureInfo.IsCubeMap;
|
||||||
|
processedTexture.Width = importedTexture.TextureInfo.Width;
|
||||||
|
processedTexture.Height = importedTexture.TextureInfo.Height;
|
||||||
|
processedTexture.Depth = importedTexture.TextureInfo.Depth;
|
||||||
|
|
||||||
|
processedTexture.SamplerStateDescription = config.SamplerStateDescription;
|
||||||
|
|
||||||
|
processedTexture.SetSurfaceCount(importedTexture.TextureInfo.ArraySize, importedTexture.TextureInfo.MipMapCount);
|
||||||
|
|
||||||
|
for (LoadedSurface loadedSurface in importedTexture.Surfaces)
|
||||||
|
{
|
||||||
|
ProcessedTexture.TextureSurface surface = new .(loadedSurface.Width, loadedSurface.Height, loadedSurface.Depth,
|
||||||
|
loadedSurface.Data, loadedSurface.MipLevel, loadedSurface.ArrayIndex, loadedSurface.Pitch, loadedSurface.SlicePitch);
|
||||||
|
|
||||||
|
processedTexture.Surfaces[loadedSurface.ArrayIndex * (processedTexture.IsCubeMap ? 6 : 1) + loadedSurface.CubeFace, loadedSurface.MipLevel] = surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(config.GenerateMipMaps case .No))
|
||||||
|
{
|
||||||
|
// TODO: Unpack BC-Formats to RGBA
|
||||||
|
|
||||||
|
GenerateMipMaps(processedTexture, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Pack to BC-Format or what ever was selected.
|
||||||
|
|
||||||
|
return processedTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int CalculateMipMapCount(int width, int height, int depth)
|
||||||
|
{
|
||||||
|
var width, height, depth;
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (width == 1 && height == 1 && depth == 1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (width > 1)
|
||||||
|
width >>= 1;
|
||||||
|
if (height > 1)
|
||||||
|
height >>= 1;
|
||||||
|
if (depth > 1)
|
||||||
|
depth >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanGenerateMipMaps(Format format)
|
||||||
|
{
|
||||||
|
// TODO!
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result<void> GenerateMipMaps(ProcessedTexture processedTexture, TextureProcessorConfig config)
|
||||||
|
{
|
||||||
|
if (!CanGenerateMipMaps(processedTexture.PixelFormat))
|
||||||
|
{
|
||||||
|
return .Err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mipMapCount = CalculateMipMapCount(processedTexture.Width, processedTexture.Height, processedTexture.Depth);
|
||||||
|
|
||||||
|
if (processedTexture.MipMapCount != mipMapCount)
|
||||||
|
{
|
||||||
|
processedTexture.SetSurfaceCount(processedTexture.ArraySize, mipMapCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int arraySlice < processedTexture.ArraySize)
|
||||||
|
{
|
||||||
|
ProcessedTexture.TextureSurface largerSurface = processedTexture.Surfaces[arraySlice, 0];
|
||||||
|
|
||||||
|
for (int mipMap = 1; mipMap < processedTexture.MipMapCount; mipMap++)
|
||||||
|
{
|
||||||
|
ref ProcessedTexture.TextureSurface surface = ref processedTexture.Surfaces[arraySlice, mipMap];
|
||||||
|
|
||||||
|
surface = GenerateMipLevel(processedTexture.PixelFormat, largerSurface, surface);
|
||||||
|
|
||||||
|
largerSurface = surface;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
|
|
||||||
|
// TODO: Generate Mip Maps
|
||||||
|
/*int mipMapCount = CalculateMipMapCount(processedTexture.Width, processedTexture.Height, processedTexture.Depth);
|
||||||
|
|
||||||
|
processedTexture.SetMipMapCount(mipMapCount);
|
||||||
|
|
||||||
|
for (int slice < processedTexture.ArraySize)
|
||||||
|
{
|
||||||
|
for (int mipMap < mipMapCount)
|
||||||
|
{
|
||||||
|
if (processedTexture.Surfaces[slice, mipMap] == null)
|
||||||
|
{
|
||||||
|
processedTexture.Surfaces[slice, mipMap] = GenerateMipLevel(processedTexture.Surfaces[slice, mipMap - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
private ProcessedTexture.TextureSurface GenerateMipLevel(Format pixelFormat, ProcessedTexture.TextureSurface largerLevel, ProcessedTexture.TextureSurface smallerLevel)
|
||||||
|
{
|
||||||
|
var smallerLevel;
|
||||||
|
|
||||||
|
int width = Math.Max(largerLevel.Width / 2, 1);
|
||||||
|
int height = Math.Max(largerLevel.Height / 2, 1);
|
||||||
|
int depth = Math.Max(largerLevel.Depth / 2, 1);
|
||||||
|
|
||||||
|
if (smallerLevel == null)
|
||||||
|
{
|
||||||
|
smallerLevel = new ProcessedTexture.TextureSurface(width, height, depth,
|
||||||
|
new uint8[width * height * depth * pixelFormat.BitsPerPixel()], largerLevel.MipLevel + 1, largerLevel.ArraySlice,
|
||||||
|
-1, -1); // TODO!
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Kaiser mip maps?
|
||||||
|
|
||||||
|
FormatInfo formatInfo = default; //pixelFormat.GetFormatInfo();
|
||||||
|
|
||||||
|
// Simple box filter
|
||||||
|
for (int x < width)
|
||||||
|
for (int y < height)
|
||||||
|
for (int z < depth)
|
||||||
|
{
|
||||||
|
for (int channel < formatInfo.ComponentCount)
|
||||||
|
{
|
||||||
|
ComponentInfo info = formatInfo.Components[channel];
|
||||||
|
|
||||||
|
switch (info.DataType)
|
||||||
|
{
|
||||||
|
case .UNorm, .UInt:
|
||||||
|
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return smallerLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Box<DataType>() where DataType : const ComponentDataType
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -178,7 +178,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nodeOpen && ImGui.BeginTableEx("properties", TableId, 2, .SizingStretchSame | .BordersInner | .Resizable))
|
if (nodeOpen && ImGui.BeginPropertyTable("properties", TableId))
|
||||||
{
|
{
|
||||||
if (entity.TryGetComponent<TComponent>(let actualComponent))
|
if (entity.TryGetComponent<TComponent>(let actualComponent))
|
||||||
showComponentEditor(entity, actualComponent);
|
showComponentEditor(entity, actualComponent);
|
||||||
@@ -187,33 +187,6 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts a new row in the table and enters the first column.
|
|
||||||
private static void StartNewRow()
|
|
||||||
{
|
|
||||||
ImGui.TableNextRow();
|
|
||||||
ImGui.TableSetColumnIndex(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Starts a new property by creating a new table row, writing the name in the first column and entering the second column.
|
|
||||||
private static void StartNewProperty(StringView propertyName)
|
|
||||||
{
|
|
||||||
StartNewRow();
|
|
||||||
|
|
||||||
bool isFirstTableRow = ImGui.TableGetRowIndex() == 0;
|
|
||||||
|
|
||||||
if (isFirstTableRow)
|
|
||||||
ImGui.PushItemWidth(-1);
|
|
||||||
|
|
||||||
ImGui.TextUnformatted(propertyName);
|
|
||||||
|
|
||||||
ImGui.AttachTooltip(propertyName);
|
|
||||||
|
|
||||||
ImGui.TableSetColumnIndex(1);
|
|
||||||
|
|
||||||
if (isFirstTableRow)
|
|
||||||
ImGui.PushItemWidth(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ShowNameComponentEditor(Entity entity)
|
private static void ShowNameComponentEditor(Entity entity)
|
||||||
{
|
{
|
||||||
if (!entity.HasComponent<NameComponent>())
|
if (!entity.HasComponent<NameComponent>())
|
||||||
@@ -239,7 +212,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
ImGui.PushItemWidth(-1);
|
ImGui.PushItemWidth(-1);
|
||||||
|
|
||||||
StartNewProperty("Name");
|
ImGui.PropertyTableStartNewProperty("Name");
|
||||||
|
|
||||||
ImGui.PushItemWidth(-1);
|
ImGui.PushItemWidth(-1);
|
||||||
|
|
||||||
@@ -264,7 +237,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
float3 position = transform.Position;
|
float3 position = transform.Position;
|
||||||
|
|
||||||
StartNewProperty("Position");
|
ImGui.PropertyTableStartNewProperty("Position");
|
||||||
if (ImGui.Float3Editor("##Position", ref position, resetValues: .Zero, dragSpeed: 0.1f))
|
if (ImGui.Float3Editor("##Position", ref position, resetValues: .Zero, dragSpeed: 0.1f))
|
||||||
{
|
{
|
||||||
transform.Position = position;
|
transform.Position = position;
|
||||||
@@ -287,7 +260,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
rotationEuler.XY = 0;
|
rotationEuler.XY = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
StartNewProperty("Rotation");
|
ImGui.PropertyTableStartNewProperty("Rotation");
|
||||||
if (ImGui.Float3Editor("##Rotation", ref rotationEuler, resetValues: .Zero, dragSpeed: 0.1f, componentEnabled: componentEditable, format: .("%.3f°",)))
|
if (ImGui.Float3Editor("##Rotation", ref rotationEuler, resetValues: .Zero, dragSpeed: 0.1f, componentEnabled: componentEditable, format: .("%.3f°",)))
|
||||||
{
|
{
|
||||||
transform.EditorRotationEuler = MathHelper.ToRadians(rotationEuler);
|
transform.EditorRotationEuler = MathHelper.ToRadians(rotationEuler);
|
||||||
@@ -301,7 +274,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
float3 scale = transform.Scale;
|
float3 scale = transform.Scale;
|
||||||
|
|
||||||
StartNewProperty("Scale");
|
ImGui.PropertyTableStartNewProperty("Scale");
|
||||||
if (ImGui.Float3Editor("##Scale", ref scale, resetValues: .One, dragSpeed: 0.1f))
|
if (ImGui.Float3Editor("##Scale", ref scale, resetValues: .One, dragSpeed: 0.1f))
|
||||||
transform.Scale = scale;
|
transform.Scale = scale;
|
||||||
}
|
}
|
||||||
@@ -310,14 +283,14 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
private static void ShowCameraComponentEditor(Entity entity, CameraComponent* cameraComponent)
|
private static void ShowCameraComponentEditor(Entity entity, CameraComponent* cameraComponent)
|
||||||
{
|
{
|
||||||
StartNewProperty("Is Primary");
|
ImGui.PropertyTableStartNewProperty("Is Primary");
|
||||||
ImGui.Checkbox("##Is_Primary", &cameraComponent.Primary);
|
ImGui.Checkbox("##Is_Primary", &cameraComponent.Primary);
|
||||||
|
|
||||||
var camera = ref cameraComponent.Camera;
|
var camera = ref cameraComponent.Camera;
|
||||||
|
|
||||||
String typeName = strings[camera.ProjectionType.Underlying];
|
String typeName = strings[camera.ProjectionType.Underlying];
|
||||||
|
|
||||||
StartNewProperty("Projection");
|
ImGui.PropertyTableStartNewProperty("Projection");
|
||||||
if (ImGui.BeginCombo("##Projection", typeName.CStr()))
|
if (ImGui.BeginCombo("##Projection", typeName.CStr()))
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
@@ -338,59 +311,59 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if (camera.ProjectionType == .Perspective)
|
if (camera.ProjectionType == .Perspective)
|
||||||
{
|
{
|
||||||
StartNewProperty("Fov Y");
|
ImGui.PropertyTableStartNewProperty("Fov Y");
|
||||||
float fovY = MathHelper.ToDegrees(camera.PerspectiveFovY);
|
float fovY = MathHelper.ToDegrees(camera.PerspectiveFovY);
|
||||||
if (ImGui.DragFloat("##Fov Y", &fovY, 0.1f, format: "%.3f°"))
|
if (ImGui.DragFloat("##Fov Y", &fovY, 0.1f, format: "%.3f°"))
|
||||||
camera.PerspectiveFovY = MathHelper.ToRadians(fovY);
|
camera.PerspectiveFovY = MathHelper.ToRadians(fovY);
|
||||||
|
|
||||||
StartNewProperty("Near");
|
ImGui.PropertyTableStartNewProperty("Near");
|
||||||
float near = camera.PerspectiveNearPlane;
|
float near = camera.PerspectiveNearPlane;
|
||||||
if (ImGui.DragFloat("##Near", &near, 0.1f))
|
if (ImGui.DragFloat("##Near", &near, 0.1f))
|
||||||
camera.PerspectiveNearPlane = near;
|
camera.PerspectiveNearPlane = near;
|
||||||
|
|
||||||
StartNewProperty("Far");
|
ImGui.PropertyTableStartNewProperty("Far");
|
||||||
float far = camera.PerspectiveFarPlane;
|
float far = camera.PerspectiveFarPlane;
|
||||||
if (ImGui.DragFloat("##Far", &far, 0.1f))
|
if (ImGui.DragFloat("##Far", &far, 0.1f))
|
||||||
camera.PerspectiveFarPlane = far;
|
camera.PerspectiveFarPlane = far;
|
||||||
}
|
}
|
||||||
else if (camera.ProjectionType == .InfinitePerspective)
|
else if (camera.ProjectionType == .InfinitePerspective)
|
||||||
{
|
{
|
||||||
StartNewProperty("Vertical FOV");
|
ImGui.PropertyTableStartNewProperty("Vertical FOV");
|
||||||
float fovY = MathHelper.ToDegrees(camera.PerspectiveFovY);
|
float fovY = MathHelper.ToDegrees(camera.PerspectiveFovY);
|
||||||
if (ImGui.DragFloat("##Vertical FOV", &fovY, 0.1f, format: "%.3f°"))
|
if (ImGui.DragFloat("##Vertical FOV", &fovY, 0.1f, format: "%.3f°"))
|
||||||
camera.PerspectiveFovY = MathHelper.ToRadians(fovY);
|
camera.PerspectiveFovY = MathHelper.ToRadians(fovY);
|
||||||
|
|
||||||
StartNewProperty("Near");
|
ImGui.PropertyTableStartNewProperty("Near");
|
||||||
float near = camera.PerspectiveNearPlane;
|
float near = camera.PerspectiveNearPlane;
|
||||||
if (ImGui.DragFloat("##Near", &near, 0.1f))
|
if (ImGui.DragFloat("##Near", &near, 0.1f))
|
||||||
camera.PerspectiveNearPlane = near;
|
camera.PerspectiveNearPlane = near;
|
||||||
}
|
}
|
||||||
else if (camera.ProjectionType == .Orthographic)
|
else if (camera.ProjectionType == .Orthographic)
|
||||||
{
|
{
|
||||||
StartNewProperty("Size");
|
ImGui.PropertyTableStartNewProperty("Size");
|
||||||
float size = camera.OrthographicHeight;
|
float size = camera.OrthographicHeight;
|
||||||
if (ImGui.DragFloat("##Size", &size, 0.1f))
|
if (ImGui.DragFloat("##Size", &size, 0.1f))
|
||||||
camera.OrthographicHeight = size;
|
camera.OrthographicHeight = size;
|
||||||
|
|
||||||
StartNewProperty("Near");
|
ImGui.PropertyTableStartNewProperty("Near");
|
||||||
float near = camera.OrthographicNearPlane;
|
float near = camera.OrthographicNearPlane;
|
||||||
if (ImGui.DragFloat("##Near", &near, 0.1f))
|
if (ImGui.DragFloat("##Near", &near, 0.1f))
|
||||||
camera.OrthographicNearPlane = near;
|
camera.OrthographicNearPlane = near;
|
||||||
|
|
||||||
StartNewProperty("Far");
|
ImGui.PropertyTableStartNewProperty("Far");
|
||||||
float far = camera.OrthographicFarPlane;
|
float far = camera.OrthographicFarPlane;
|
||||||
if (ImGui.DragFloat("##Far", &far, 0.1f))
|
if (ImGui.DragFloat("##Far", &far, 0.1f))
|
||||||
camera.OrthographicFarPlane = far;
|
camera.OrthographicFarPlane = far;
|
||||||
}
|
}
|
||||||
|
|
||||||
StartNewProperty("Fixed Aspect Ratio");
|
ImGui.PropertyTableStartNewProperty("Fixed Aspect Ratio");
|
||||||
bool fixedAspectRatio = camera.FixedAspectRatio;
|
bool fixedAspectRatio = camera.FixedAspectRatio;
|
||||||
if (ImGui.Checkbox("##Fixed Aspect Ratio", &fixedAspectRatio))
|
if (ImGui.Checkbox("##Fixed Aspect Ratio", &fixedAspectRatio))
|
||||||
camera.FixedAspectRatio = fixedAspectRatio;
|
camera.FixedAspectRatio = fixedAspectRatio;
|
||||||
|
|
||||||
if (fixedAspectRatio)
|
if (fixedAspectRatio)
|
||||||
{
|
{
|
||||||
StartNewProperty("Aspect Ratio");
|
ImGui.PropertyTableStartNewProperty("Aspect Ratio");
|
||||||
float aspect = camera.AspectRatio;
|
float aspect = camera.AspectRatio;
|
||||||
if (ImGui.DragFloat("##Aspect Ratio", &aspect, 0.1f))
|
if (ImGui.DragFloat("##Aspect Ratio", &aspect, 0.1f))
|
||||||
camera.AspectRatio = aspect;
|
camera.AspectRatio = aspect;
|
||||||
@@ -400,11 +373,11 @@ namespace GlitchyEditor.EditWindows
|
|||||||
private static void ShowSpriteRendererComponentEditor(Entity entity, SpriteRendererComponent* spriteRendererComponent)
|
private static void ShowSpriteRendererComponentEditor(Entity entity, SpriteRendererComponent* spriteRendererComponent)
|
||||||
{
|
{
|
||||||
ColorRGBA spriteColor = ColorRGBA.LinearToSRGB(spriteRendererComponent.Color);
|
ColorRGBA spriteColor = ColorRGBA.LinearToSRGB(spriteRendererComponent.Color);
|
||||||
StartNewProperty("Color");
|
ImGui.PropertyTableStartNewProperty("Color");
|
||||||
if (ImGui.ColorEdit4("##Color", ref spriteColor))
|
if (ImGui.ColorEdit4("##Color", ref spriteColor))
|
||||||
spriteRendererComponent.Color = ColorRGBA.SRgbToLinear(spriteColor);
|
spriteRendererComponent.Color = ColorRGBA.SRgbToLinear(spriteColor);
|
||||||
|
|
||||||
StartNewProperty("Texture");
|
ImGui.PropertyTableStartNewProperty("Texture");
|
||||||
ImGui.Button("...");
|
ImGui.Button("...");
|
||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
if (ImGui.BeginDragDropTarget())
|
||||||
@@ -423,18 +396,18 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ImGui.EndDragDropTarget();
|
ImGui.EndDragDropTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
StartNewProperty("UV Transform");
|
ImGui.PropertyTableStartNewProperty("UV Transform");
|
||||||
ImGui.Float4Editor("##UV Transform", ref spriteRendererComponent.UvTransform, resetValues: float4(0, 0, 1, 1));
|
ImGui.Float4Editor("##UV Transform", ref spriteRendererComponent.UvTransform, resetValues: float4(0, 0, 1, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ShowCircleRendererComponentEditor(Entity entity, CircleRendererComponent* circleRendererComponent)
|
private static void ShowCircleRendererComponentEditor(Entity entity, CircleRendererComponent* circleRendererComponent)
|
||||||
{
|
{
|
||||||
ColorRGBA spriteColor = ColorRGBA.LinearToSRGB(circleRendererComponent.Color);
|
ColorRGBA spriteColor = ColorRGBA.LinearToSRGB(circleRendererComponent.Color);
|
||||||
StartNewProperty("Color");
|
ImGui.PropertyTableStartNewProperty("Color");
|
||||||
if (ImGui.ColorEdit4("##Color", ref spriteColor))
|
if (ImGui.ColorEdit4("##Color", ref spriteColor))
|
||||||
circleRendererComponent.Color = ColorRGBA.SRgbToLinear(spriteColor);
|
circleRendererComponent.Color = ColorRGBA.SRgbToLinear(spriteColor);
|
||||||
|
|
||||||
StartNewProperty("Texture");
|
ImGui.PropertyTableStartNewProperty("Texture");
|
||||||
ImGui.Button("...");
|
ImGui.Button("...");
|
||||||
|
|
||||||
if (ImGui.BeginDragDropTarget())
|
if (ImGui.BeginDragDropTarget())
|
||||||
@@ -453,10 +426,10 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ImGui.EndDragDropTarget();
|
ImGui.EndDragDropTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
StartNewProperty("UV Transform");
|
ImGui.PropertyTableStartNewProperty("UV Transform");
|
||||||
ImGui.Float4Editor("##UV Transform", ref circleRendererComponent.UvTransform, resetValues: float4(0, 0, 1, 1));
|
ImGui.Float4Editor("##UV Transform", ref circleRendererComponent.UvTransform, resetValues: float4(0, 0, 1, 1));
|
||||||
|
|
||||||
StartNewProperty("Inner Radius");
|
ImGui.PropertyTableStartNewProperty("Inner Radius");
|
||||||
ImGui.DragFloat("##Inner Radius", &circleRendererComponent.InnerRadius, 0.1f, 0.0f, 1.0f);
|
ImGui.DragFloat("##Inner Radius", &circleRendererComponent.InnerRadius, 0.1f, 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,7 +452,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
private static void ShowTextRendererComponentEditor(Entity entity, TextRendererComponent* textRendererComponent)
|
private static void ShowTextRendererComponentEditor(Entity entity, TextRendererComponent* textRendererComponent)
|
||||||
{
|
{
|
||||||
StartNewProperty("Rich text");
|
ImGui.PropertyTableStartNewProperty("Rich text");
|
||||||
|
|
||||||
ImGui.AttachTooltip("If checked, the text will be interpreted as rich text.");
|
ImGui.AttachTooltip("If checked, the text will be interpreted as rich text.");
|
||||||
|
|
||||||
@@ -491,7 +464,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
textRendererComponent.NeedsRebuild = true;
|
textRendererComponent.NeedsRebuild = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
StartNewProperty("Text");
|
ImGui.PropertyTableStartNewProperty("Text");
|
||||||
|
|
||||||
String text = textRendererComponent.[Friend]_text;
|
String text = textRendererComponent.[Friend]_text;
|
||||||
|
|
||||||
@@ -516,21 +489,21 @@ namespace GlitchyEditor.EditWindows
|
|||||||
textRendererComponent.NeedsRebuild = true;
|
textRendererComponent.NeedsRebuild = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
StartNewProperty("Font Size");
|
ImGui.PropertyTableStartNewProperty("Font Size");
|
||||||
|
|
||||||
if (ImGui.DragFloat("##fontSize", &textRendererComponent.FontSize))
|
if (ImGui.DragFloat("##fontSize", &textRendererComponent.FontSize))
|
||||||
{
|
{
|
||||||
textRendererComponent.NeedsRebuild = true;
|
textRendererComponent.NeedsRebuild = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
StartNewProperty("Color");
|
ImGui.PropertyTableStartNewProperty("Color");
|
||||||
|
|
||||||
if (ImGui.ColorEdit4("##color", ref textRendererComponent.Color))
|
if (ImGui.ColorEdit4("##color", ref textRendererComponent.Color))
|
||||||
{
|
{
|
||||||
textRendererComponent.NeedsRebuild = true;
|
textRendererComponent.NeedsRebuild = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
StartNewProperty("Horizontal Alignment");
|
ImGui.PropertyTableStartNewProperty("Horizontal Alignment");
|
||||||
|
|
||||||
if (ImGui.EnumCombo("##horAlign", ref textRendererComponent.HorizontalAlignment))
|
if (ImGui.EnumCombo("##horAlign", ref textRendererComponent.HorizontalAlignment))
|
||||||
{
|
{
|
||||||
@@ -540,7 +513,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
private static void ShowMeshRendererComponentEditor(Entity entity, MeshRendererComponent* meshRendererComponent)
|
private static void ShowMeshRendererComponentEditor(Entity entity, MeshRendererComponent* meshRendererComponent)
|
||||||
{
|
{
|
||||||
StartNewProperty("Material");
|
ImGui.PropertyTableStartNewProperty("Material");
|
||||||
|
|
||||||
Material material = meshRendererComponent.Material;
|
Material material = meshRendererComponent.Material;
|
||||||
|
|
||||||
@@ -574,7 +547,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
const String[?] bodyTypeStrings = .("Static", "Dynamic", "Kinematic");
|
const String[?] bodyTypeStrings = .("Static", "Dynamic", "Kinematic");
|
||||||
String bodyTypeName = bodyTypeStrings[rigidBodyComponent.BodyType.Underlying];
|
String bodyTypeName = bodyTypeStrings[rigidBodyComponent.BodyType.Underlying];
|
||||||
|
|
||||||
StartNewProperty("Type");
|
ImGui.PropertyTableStartNewProperty("Type");
|
||||||
if (ImGui.BeginCombo("##Type", bodyTypeName.CStr()))
|
if (ImGui.BeginCombo("##Type", bodyTypeName.CStr()))
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
@@ -594,14 +567,14 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isFixedRotation = rigidBodyComponent.FixedRotation;
|
bool isFixedRotation = rigidBodyComponent.FixedRotation;
|
||||||
StartNewProperty("Fixed Rotation");
|
ImGui.PropertyTableStartNewProperty("Fixed Rotation");
|
||||||
if (ImGui.Checkbox("##Fixed Rotation", &isFixedRotation))
|
if (ImGui.Checkbox("##Fixed Rotation", &isFixedRotation))
|
||||||
{
|
{
|
||||||
rigidBodyComponent.FixedRotation = isFixedRotation;
|
rigidBodyComponent.FixedRotation = isFixedRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
float gravityScale = rigidBodyComponent.GravityScale;
|
float gravityScale = rigidBodyComponent.GravityScale;
|
||||||
StartNewProperty("Gravity Scale");
|
ImGui.PropertyTableStartNewProperty("Gravity Scale");
|
||||||
if (ImGui.DragFloat("##Gravity Scale", &gravityScale))
|
if (ImGui.DragFloat("##Gravity Scale", &gravityScale))
|
||||||
{
|
{
|
||||||
rigidBodyComponent.GravityScale = gravityScale;
|
rigidBodyComponent.GravityScale = gravityScale;
|
||||||
@@ -611,32 +584,32 @@ namespace GlitchyEditor.EditWindows
|
|||||||
private static void ShowBoxCollider2DComponentEditor(Entity entity, BoxCollider2DComponent* boxCollider)
|
private static void ShowBoxCollider2DComponentEditor(Entity entity, BoxCollider2DComponent* boxCollider)
|
||||||
{
|
{
|
||||||
float2 offset = boxCollider.Offset;
|
float2 offset = boxCollider.Offset;
|
||||||
StartNewProperty("Offset");
|
ImGui.PropertyTableStartNewProperty("Offset");
|
||||||
if (ImGui.Float2Editor("##Offset", ref offset, .Zero, 0.1f))
|
if (ImGui.Float2Editor("##Offset", ref offset, .Zero, 0.1f))
|
||||||
boxCollider.Offset = offset;
|
boxCollider.Offset = offset;
|
||||||
|
|
||||||
float2 size = boxCollider.Size;
|
float2 size = boxCollider.Size;
|
||||||
StartNewProperty("Size");
|
ImGui.PropertyTableStartNewProperty("Size");
|
||||||
if (ImGui.Float2Editor("##Size", ref size, .Zero, 0.1f, float2(0.01f, 0.01f), float.PositiveInfinity.XX))
|
if (ImGui.Float2Editor("##Size", ref size, .Zero, 0.1f, float2(0.01f, 0.01f), float.PositiveInfinity.XX))
|
||||||
boxCollider.Size = size;
|
boxCollider.Size = size;
|
||||||
|
|
||||||
float density = boxCollider.Density;
|
float density = boxCollider.Density;
|
||||||
StartNewProperty("Density");
|
ImGui.PropertyTableStartNewProperty("Density");
|
||||||
if (ImGui.DragFloat("##Density", &density, 0.0f, 0.1f))
|
if (ImGui.DragFloat("##Density", &density, 0.0f, 0.1f))
|
||||||
boxCollider.Density = density;
|
boxCollider.Density = density;
|
||||||
|
|
||||||
float friction = boxCollider.Friction;
|
float friction = boxCollider.Friction;
|
||||||
StartNewProperty("Friction");
|
ImGui.PropertyTableStartNewProperty("Friction");
|
||||||
if (ImGui.DragFloat("##Friction", &friction, 0.0f, 0.1f))
|
if (ImGui.DragFloat("##Friction", &friction, 0.0f, 0.1f))
|
||||||
boxCollider.Friction = friction;
|
boxCollider.Friction = friction;
|
||||||
|
|
||||||
float restitution = boxCollider.Restitution;
|
float restitution = boxCollider.Restitution;
|
||||||
StartNewProperty("Restitution");
|
ImGui.PropertyTableStartNewProperty("Restitution");
|
||||||
if (ImGui.DragFloat("##Restitution", &restitution, 0.0f, 0.1f))
|
if (ImGui.DragFloat("##Restitution", &restitution, 0.0f, 0.1f))
|
||||||
boxCollider.Restitution = restitution;
|
boxCollider.Restitution = restitution;
|
||||||
|
|
||||||
float restitutionThreshold = boxCollider.RestitutionThreshold;
|
float restitutionThreshold = boxCollider.RestitutionThreshold;
|
||||||
StartNewProperty("Restitution Threshold");
|
ImGui.PropertyTableStartNewProperty("Restitution Threshold");
|
||||||
if (ImGui.DragFloat("##RestitutionThreshold", &restitutionThreshold, 0.0f, 0.1f))
|
if (ImGui.DragFloat("##RestitutionThreshold", &restitutionThreshold, 0.0f, 0.1f))
|
||||||
boxCollider.RestitutionThreshold = restitutionThreshold;
|
boxCollider.RestitutionThreshold = restitutionThreshold;
|
||||||
}
|
}
|
||||||
@@ -644,32 +617,32 @@ namespace GlitchyEditor.EditWindows
|
|||||||
private static void ShowCircleCollider2DComponentEditor(Entity entity, CircleCollider2DComponent* circleCollider)
|
private static void ShowCircleCollider2DComponentEditor(Entity entity, CircleCollider2DComponent* circleCollider)
|
||||||
{
|
{
|
||||||
float2 offset = circleCollider.Offset;
|
float2 offset = circleCollider.Offset;
|
||||||
StartNewProperty("Offset");
|
ImGui.PropertyTableStartNewProperty("Offset");
|
||||||
if (ImGui.Float2Editor("##Offset", ref offset, .Zero, 0.1f))
|
if (ImGui.Float2Editor("##Offset", ref offset, .Zero, 0.1f))
|
||||||
circleCollider.Offset = offset;
|
circleCollider.Offset = offset;
|
||||||
|
|
||||||
float radius = circleCollider.Radius;
|
float radius = circleCollider.Radius;
|
||||||
StartNewProperty("Radius");
|
ImGui.PropertyTableStartNewProperty("Radius");
|
||||||
if (ImGui.DragFloat("##Radius", &radius, 0.0f, 0.1f))
|
if (ImGui.DragFloat("##Radius", &radius, 0.0f, 0.1f))
|
||||||
circleCollider.Radius = radius;
|
circleCollider.Radius = radius;
|
||||||
|
|
||||||
float density = circleCollider.Density;
|
float density = circleCollider.Density;
|
||||||
StartNewProperty("Density");
|
ImGui.PropertyTableStartNewProperty("Density");
|
||||||
if (ImGui.DragFloat("##Density", &density, 0.0f, 0.1f))
|
if (ImGui.DragFloat("##Density", &density, 0.0f, 0.1f))
|
||||||
circleCollider.Density = density;
|
circleCollider.Density = density;
|
||||||
|
|
||||||
float friction = circleCollider.Friction;
|
float friction = circleCollider.Friction;
|
||||||
StartNewProperty("Friction");
|
ImGui.PropertyTableStartNewProperty("Friction");
|
||||||
if (ImGui.DragFloat("##Friction", &friction, 0.0f, 0.1f))
|
if (ImGui.DragFloat("##Friction", &friction, 0.0f, 0.1f))
|
||||||
circleCollider.Friction = friction;
|
circleCollider.Friction = friction;
|
||||||
|
|
||||||
float restitution = circleCollider.Restitution;
|
float restitution = circleCollider.Restitution;
|
||||||
StartNewProperty("Restitution");
|
ImGui.PropertyTableStartNewProperty("Restitution");
|
||||||
if (ImGui.DragFloat("##Restitution", &restitution, 0.0f, 0.1f))
|
if (ImGui.DragFloat("##Restitution", &restitution, 0.0f, 0.1f))
|
||||||
circleCollider.Restitution = restitution;
|
circleCollider.Restitution = restitution;
|
||||||
|
|
||||||
float restitutionThreshold = circleCollider.RestitutionThreshold;
|
float restitutionThreshold = circleCollider.RestitutionThreshold;
|
||||||
StartNewProperty("Restitution Threshold");
|
ImGui.PropertyTableStartNewProperty("Restitution Threshold");
|
||||||
if (ImGui.DragFloat("##RestitutionThreshold", &restitutionThreshold, 0.0f, 0.1f))
|
if (ImGui.DragFloat("##RestitutionThreshold", &restitutionThreshold, 0.0f, 0.1f))
|
||||||
circleCollider.RestitutionThreshold = restitutionThreshold;
|
circleCollider.RestitutionThreshold = restitutionThreshold;
|
||||||
}
|
}
|
||||||
@@ -689,11 +662,11 @@ namespace GlitchyEditor.EditWindows
|
|||||||
private static void ShowPolygonCollider2DComponentEditor(Entity entity, PolygonCollider2DComponent* polygonCollider)
|
private static void ShowPolygonCollider2DComponentEditor(Entity entity, PolygonCollider2DComponent* polygonCollider)
|
||||||
{
|
{
|
||||||
float2 offset = polygonCollider.Offset;
|
float2 offset = polygonCollider.Offset;
|
||||||
StartNewProperty("Offset");
|
ImGui.PropertyTableStartNewProperty("Offset");
|
||||||
if (ImGui.Float2Editor("Offset", ref offset, .Zero, 0.1f))
|
if (ImGui.Float2Editor("Offset", ref offset, .Zero, 0.1f))
|
||||||
polygonCollider.Offset = offset;
|
polygonCollider.Offset = offset;
|
||||||
|
|
||||||
StartNewRow();
|
ImGui.PropertyTableStartNewRow();
|
||||||
|
|
||||||
bool isOpen = ImGui.TreeNodeEx("Vertices", .AllowOverlap | .SpanAllColumns);
|
bool isOpen = ImGui.TreeNodeEx("Vertices", .AllowOverlap | .SpanAllColumns);
|
||||||
|
|
||||||
@@ -727,12 +700,12 @@ namespace GlitchyEditor.EditWindows
|
|||||||
// If isOpen is true, show list of vertices
|
// If isOpen is true, show list of vertices
|
||||||
if (isOpen)
|
if (isOpen)
|
||||||
{
|
{
|
||||||
StartNewProperty("Show Vertex gizmos");
|
ImGui.PropertyTableStartNewProperty("Show Vertex gizmos");
|
||||||
ImGui.Checkbox("##Show Vertex gizmos", &_editVerticesPolygonCollider2D);
|
ImGui.Checkbox("##Show Vertex gizmos", &_editVerticesPolygonCollider2D);
|
||||||
|
|
||||||
for (int i < polygonCollider.VertexCount)
|
for (int i < polygonCollider.VertexCount)
|
||||||
{
|
{
|
||||||
StartNewProperty(scope $"{i}");
|
ImGui.PropertyTableStartNewProperty(scope $"{i}");
|
||||||
ImGui.Float2Editor(scope $"##{i}", ref polygonCollider.Vertices[i]);
|
ImGui.Float2Editor(scope $"##{i}", ref polygonCollider.Vertices[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -740,22 +713,22 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
|
|
||||||
float density = polygonCollider.Density;
|
float density = polygonCollider.Density;
|
||||||
StartNewProperty("Density");
|
ImGui.PropertyTableStartNewProperty("Density");
|
||||||
if (ImGui.DragFloat("##Density", &density, 0.0f, 0.1f))
|
if (ImGui.DragFloat("##Density", &density, 0.0f, 0.1f))
|
||||||
polygonCollider.Density = density;
|
polygonCollider.Density = density;
|
||||||
|
|
||||||
float friction = polygonCollider.Friction;
|
float friction = polygonCollider.Friction;
|
||||||
StartNewProperty("Friction");
|
ImGui.PropertyTableStartNewProperty("Friction");
|
||||||
if (ImGui.DragFloat("##Friction", &friction, 0.0f, 0.1f))
|
if (ImGui.DragFloat("##Friction", &friction, 0.0f, 0.1f))
|
||||||
polygonCollider.Friction = friction;
|
polygonCollider.Friction = friction;
|
||||||
|
|
||||||
float restitution = polygonCollider.Restitution;
|
float restitution = polygonCollider.Restitution;
|
||||||
StartNewProperty("Restitution");
|
ImGui.PropertyTableStartNewProperty("Restitution");
|
||||||
if (ImGui.DragFloat("##Restitution", &restitution, 0.0f, 0.1f))
|
if (ImGui.DragFloat("##Restitution", &restitution, 0.0f, 0.1f))
|
||||||
polygonCollider.Restitution = restitution;
|
polygonCollider.Restitution = restitution;
|
||||||
|
|
||||||
float restitutionThreshold = polygonCollider.RestitutionThreshold;
|
float restitutionThreshold = polygonCollider.RestitutionThreshold;
|
||||||
StartNewProperty("Restitution Threshold");
|
ImGui.PropertyTableStartNewProperty("Restitution Threshold");
|
||||||
if (ImGui.DragFloat("##RestitutionThreshold", &restitutionThreshold, 0.0f, 0.1f))
|
if (ImGui.DragFloat("##RestitutionThreshold", &restitutionThreshold, 0.0f, 0.1f))
|
||||||
polygonCollider.RestitutionThreshold = restitutionThreshold;
|
polygonCollider.RestitutionThreshold = restitutionThreshold;
|
||||||
}
|
}
|
||||||
@@ -768,7 +741,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
char8* scriptLabel = scriptComponent.ScriptClassName.ToScopeCStr!() ?? "Select Script...";
|
char8* scriptLabel = scriptComponent.ScriptClassName.ToScopeCStr!() ?? "Select Script...";
|
||||||
|
|
||||||
StartNewProperty("Script");
|
ImGui.PropertyTableStartNewProperty("Script");
|
||||||
if (ImGui.Button(scriptLabel))
|
if (ImGui.Button(scriptLabel))
|
||||||
ImGui.OpenPopup("SelectScript");
|
ImGui.OpenPopup("SelectScript");
|
||||||
|
|
||||||
@@ -803,7 +776,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
String typeName = strings[light.LightType.Underlying];
|
String typeName = strings[light.LightType.Underlying];
|
||||||
|
|
||||||
StartNewProperty("Type");
|
ImGui.PropertyTableStartNewProperty("Type");
|
||||||
if (ImGui.BeginCombo("##Type", typeName.CStr()))
|
if (ImGui.BeginCombo("##Type", typeName.CStr()))
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
@@ -823,19 +796,19 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
|
|
||||||
ColorRGB color = ColorRGB.LinearToSRGB(light.Color);
|
ColorRGB color = ColorRGB.LinearToSRGB(light.Color);
|
||||||
StartNewProperty("Color");
|
ImGui.PropertyTableStartNewProperty("Color");
|
||||||
if (ImGui.ColorEdit3("##Color", ref color))
|
if (ImGui.ColorEdit3("##Color", ref color))
|
||||||
light.Color = ColorRGB.SRgbToLinear(color);
|
light.Color = ColorRGB.SRgbToLinear(color);
|
||||||
|
|
||||||
float illuminance = light.Illuminance;
|
float illuminance = light.Illuminance;
|
||||||
StartNewProperty("Illuminance");
|
ImGui.PropertyTableStartNewProperty("Illuminance");
|
||||||
if (ImGui.DragFloat("##Illuminance", &illuminance, 0.1f, 0.0f, float.MaxValue))
|
if (ImGui.DragFloat("##Illuminance", &illuminance, 0.1f, 0.0f, float.MaxValue))
|
||||||
light.Illuminance = illuminance;
|
light.Illuminance = illuminance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ShowMeshComponentEditor(Entity entity, MeshComponent* meshComponent)
|
private static void ShowMeshComponentEditor(Entity entity, MeshComponent* meshComponent)
|
||||||
{
|
{
|
||||||
StartNewProperty("Mesh");
|
ImGui.PropertyTableStartNewProperty("Mesh");
|
||||||
|
|
||||||
GeometryBinding mesh = meshComponent.Mesh;
|
GeometryBinding mesh = meshComponent.Mesh;
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,34 @@ class PropertiesWindow : EditorWindow
|
|||||||
{
|
{
|
||||||
AssetFile assetFile = GetCurrentAssetFile();
|
AssetFile assetFile = GetCurrentAssetFile();
|
||||||
|
|
||||||
if (_currentPropertiesEditor?.Asset != assetFile)
|
if (assetFile == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ImGui.BeginPropertyTable("asset_properties", ImGui.GetID("asset_properties")))
|
||||||
|
{
|
||||||
|
assetFile.AssetConfig?.ImporterConfig?.ShowEditor();
|
||||||
|
assetFile.AssetConfig?.ProcessorConfig?.ShowEditor();
|
||||||
|
assetFile.AssetConfig?.ExporterConfig?.ShowEditor();
|
||||||
|
|
||||||
|
ImGui.EndTable();
|
||||||
|
|
||||||
|
ImGui.Separator();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasChanges = (assetFile.AssetConfig?.ImporterConfig?.Changed ?? false) || (assetFile.AssetConfig?.ProcessorConfig?.Changed ?? false) || (assetFile.AssetConfig?.ExporterConfig?.Changed ?? false);
|
||||||
|
|
||||||
|
if (!hasChanges)
|
||||||
|
ImGui.BeginDisabled();
|
||||||
|
|
||||||
|
if (ImGui.Button("Apply"))
|
||||||
|
{
|
||||||
|
assetFile.SaveAssetConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasChanges)
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
|
/*if (_currentPropertiesEditor?.Asset != assetFile)
|
||||||
{
|
{
|
||||||
delete _currentPropertiesEditor;
|
delete _currentPropertiesEditor;
|
||||||
_currentPropertiesEditor = _editor.ContentManager.GetNewPropertiesEditor(assetFile);
|
_currentPropertiesEditor = _editor.ContentManager.GetNewPropertiesEditor(assetFile);
|
||||||
@@ -81,7 +108,7 @@ class PropertiesWindow : EditorWindow
|
|||||||
// We need the actual asset for preview and sometimes for editing
|
// We need the actual asset for preview and sometimes for editing
|
||||||
if (asset?.Identifier != assetFile.AssetFile.Identifier)
|
if (asset?.Identifier != assetFile.AssetFile.Identifier)
|
||||||
{
|
{
|
||||||
_currentAssetHandle = _editor.ContentManager.LoadAsset(assetFile.AssetFile.Identifier);
|
//_currentAssetHandle = _editor.ContentManager.LoadAsset(assetFile.AssetFile.Identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: allow changing AssetLoader
|
// TODO: allow changing AssetLoader
|
||||||
@@ -96,7 +123,7 @@ class PropertiesWindow : EditorWindow
|
|||||||
ShowPropertiesEditor(assetFile);
|
ShowPropertiesEditor(assetFile);
|
||||||
|
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
*/
|
||||||
// TODO: preview asset
|
// TODO: preview asset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ using GlitchyEngine;
|
|||||||
using GlitchyEngine.Content;
|
using GlitchyEngine.Content;
|
||||||
using GlitchyEditor.Assets;
|
using GlitchyEditor.Assets;
|
||||||
using GlitchyEditor.Assets.Importers;
|
using GlitchyEditor.Assets.Importers;
|
||||||
|
using GlitchyEditor.Assets.Processors;
|
||||||
|
using GlitchyEditor.Assets.Exporters;
|
||||||
|
|
||||||
namespace GlitchyEditor
|
namespace GlitchyEditor
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -156,6 +156,10 @@ class EditorContentManager : IContentManager
|
|||||||
|
|
||||||
for (let (placeholder, loadedAsset) in _newFinishedEntries)
|
for (let (placeholder, loadedAsset) in _newFinishedEntries)
|
||||||
{
|
{
|
||||||
|
Log.EngineLogger.Trace($"Dequeue: {Internal.UnsafeCastToPtr(placeholder)} {placeholder.AssetHandle} {placeholder.RefCount}");
|
||||||
|
|
||||||
|
placeholder.LoadingTask.Wait();
|
||||||
|
|
||||||
delete placeholder.LoadingTask;
|
delete placeholder.LoadingTask;
|
||||||
placeholder.LoadingTask = null;
|
placeholder.LoadingTask = null;
|
||||||
|
|
||||||
@@ -537,6 +541,11 @@ class EditorContentManager : IContentManager
|
|||||||
AssetHandle = assetHandle;
|
AssetHandle = assetHandle;
|
||||||
PlaceholderType = placeholderType;
|
PlaceholderType = placeholderType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ~this()
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Trace($"Deleted: {Internal.UnsafeCastToPtr(this)}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private append Monitor _finishedEntriesLock = .();
|
private append Monitor _finishedEntriesLock = .();
|
||||||
@@ -624,14 +633,17 @@ class EditorContentManager : IContentManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadedAsset.Identifier = assetNode.Identifier;
|
using (_finishedEntriesLock.Enter())
|
||||||
loadedAsset.[Friend]_contentManager = this;
|
{
|
||||||
loadedAsset.[Friend]_handle = handle;
|
loadedAsset.Identifier = assetNode.Identifier;
|
||||||
|
loadedAsset.[Friend]_contentManager = this;
|
||||||
|
loadedAsset.[Friend]_handle = handle;
|
||||||
|
|
||||||
_handleToAsset.Add(handle, loadedAsset);
|
_handleToAsset.Add(handle, loadedAsset);
|
||||||
_identiferToHandle.Add(loadedAsset.Identifier, handle);
|
_identiferToHandle.Add(loadedAsset.Identifier, handle);
|
||||||
|
|
||||||
file.[Friend]_loadedAsset = loadedAsset;
|
SetReference!(file.[Friend]_loadedAsset, loadedAsset);
|
||||||
|
}
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
@@ -1050,6 +1062,7 @@ class EditorContentManager : IContentManager
|
|||||||
|
|
||||||
if (loader.Load(dataStream) case .Ok(let loadedAsset))
|
if (loader.Load(dataStream) case .Ok(let loadedAsset))
|
||||||
{
|
{
|
||||||
|
Log.EngineLogger.Trace($"Loaded asset");
|
||||||
return loadedAsset;
|
return loadedAsset;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1064,6 +1077,7 @@ class EditorContentManager : IContentManager
|
|||||||
Log.EngineLogger.Error($"Failed to load asset \"{assetNode->Identifier}\" ({cachedAsset.Handle}): Could not open stream to cached file.");
|
Log.EngineLogger.Error($"Failed to load asset \"{assetNode->Identifier}\" ({cachedAsset.Handle}): Could not open stream to cached file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.EngineLogger.Trace($"Made error placeholder");
|
||||||
NewPlaceholderAsset placeholder = new NewPlaceholderAsset(asset.Handle, .Error);
|
NewPlaceholderAsset placeholder = new NewPlaceholderAsset(asset.Handle, .Error);
|
||||||
|
|
||||||
return placeholder;
|
return placeholder;
|
||||||
@@ -1074,11 +1088,15 @@ class EditorContentManager : IContentManager
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
NewPlaceholderAsset placeholder = new NewPlaceholderAsset(asset.Handle, .Loading);
|
NewPlaceholderAsset placeholder = new NewPlaceholderAsset(asset.Handle, .Loading);
|
||||||
|
Log.EngineLogger.Trace($"Created: {Internal.UnsafeCastToPtr(placeholder)} {placeholder.AssetHandle} {placeholder.RefCount}");
|
||||||
|
|
||||||
placeholder.LoadingTask = new Task(new () => {
|
placeholder.LoadingTask = new Task(new () => {
|
||||||
|
Log.EngineLogger.Trace($"Load: {Internal.UnsafeCastToPtr(placeholder)} {placeholder.AssetHandle} {placeholder.RefCount}");
|
||||||
Asset loadedAsset = InternalLoad(asset);
|
Asset loadedAsset = InternalLoad(asset);
|
||||||
|
|
||||||
using (_finishedEntriesLock.Enter())
|
using (_finishedEntriesLock.Enter())
|
||||||
{
|
{
|
||||||
|
Log.EngineLogger.Trace($"Enqueue: {Internal.UnsafeCastToPtr(placeholder)} {placeholder.AssetHandle} {placeholder.RefCount}");
|
||||||
_newFinishedEntries.Add((placeholder, loadedAsset));
|
_newFinishedEntries.Add((placeholder, loadedAsset));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -35,4 +35,43 @@ extension ImGui
|
|||||||
{
|
{
|
||||||
return SetDragDropPayload(type.GetName(), data, sz, cond);
|
return SetDragDropPayload(type.GetName(), data, sz, cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Starts a new row in the table and enters the first column.
|
||||||
|
public static bool BeginPropertyTable(char8* name, uint32 tableId)
|
||||||
|
{
|
||||||
|
return ImGui.BeginTableEx(name, tableId, 2, .SizingStretchSame | .BordersInner | .Resizable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Starts a new row in the table and enters the first column.
|
||||||
|
public static void PropertyTableStartNewRow()
|
||||||
|
{
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Starts a new property by creating a new table row, writing the name in the first column and entering the second column.
|
||||||
|
public static void PropertyTableStartNewProperty(StringView propertyName)
|
||||||
|
{
|
||||||
|
PropertyTableStartNewRow();
|
||||||
|
|
||||||
|
bool isFirstTableRow = ImGui.TableGetRowIndex() == 0;
|
||||||
|
|
||||||
|
if (isFirstTableRow)
|
||||||
|
ImGui.PushItemWidth(-1);
|
||||||
|
|
||||||
|
ImGui.TextUnformatted(propertyName);
|
||||||
|
|
||||||
|
ImGui.AttachTooltip(propertyName);
|
||||||
|
|
||||||
|
ImGui.TableSetColumnIndex(1);
|
||||||
|
|
||||||
|
if (isFirstTableRow)
|
||||||
|
ImGui.PushItemWidth(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void PropertyTableStartNewProperty(StringView propertyName, StringView tooltip)
|
||||||
|
{
|
||||||
|
PropertyTableStartNewProperty(propertyName);
|
||||||
|
AttachTooltip(tooltip);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user