mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Made TextureAtlas platform independent
This commit is contained in:
@@ -1,11 +1,6 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using GlitchyEngine.Renderer;
|
using GlitchyEngine.Renderer;
|
||||||
using System.Collections;
|
|
||||||
using GlitchyEngine.Renderer;
|
|
||||||
using GlitchyEngine.Math;
|
|
||||||
using GlitchyEngine;
|
|
||||||
using DirectX.D3D11;
|
|
||||||
using System;
|
|
||||||
namespace Sandbox.VoxelFun
|
namespace Sandbox.VoxelFun
|
||||||
{
|
{
|
||||||
class BlockTextures
|
class BlockTextures
|
||||||
@@ -51,113 +46,4 @@ namespace Sandbox.VoxelFun
|
|||||||
_atlas.SamplerState = new SamplerState(context, desc)..ReleaseRefNoDelete();
|
_atlas.SamplerState = new SamplerState(context, desc)..ReleaseRefNoDelete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TextureAtlas : Texture
|
|
||||||
{
|
|
||||||
// TODO: native code
|
|
||||||
private ID3D11Texture2D* nativeTexture ~ _?.Release();
|
|
||||||
|
|
||||||
public override extern uint32 Width {get;}
|
|
||||||
public override extern uint32 Height {get;}
|
|
||||||
public override uint32 Depth => 1;
|
|
||||||
public override extern uint32 ArraySize {get;}
|
|
||||||
public override extern uint32 MipLevels {get;}
|
|
||||||
|
|
||||||
public this(GraphicsContext context, List<BlockTexture> textures) : base(context)
|
|
||||||
{
|
|
||||||
// Todo: rewrite this garbage algorithm
|
|
||||||
|
|
||||||
List<(Color* data, uint32 width, uint32 height, BlockTexture blockTex)> textureDatas = new .(textures.Count);
|
|
||||||
defer
|
|
||||||
{
|
|
||||||
for(let item in textureDatas)
|
|
||||||
{
|
|
||||||
LodePng.LodePng.Free(item.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete textureDatas;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 maxWidth = 0;
|
|
||||||
uint32 maxHeight = 0;
|
|
||||||
|
|
||||||
for(let texture in textures)
|
|
||||||
{
|
|
||||||
(Color* data, uint32 width, uint32 height, BlockTexture blockTex) tex;
|
|
||||||
tex.blockTex = texture;
|
|
||||||
|
|
||||||
let error = LodePng.LodePng.Decode32File(out tex.data, out tex.width, out tex.height, texture.FileName);
|
|
||||||
|
|
||||||
if(error != 0)
|
|
||||||
Log.ClientLogger.Error($"Failed to load texture \"{texture.FileName}\". ({error}) \"{StringView(LodePng.LodePng.ErrorText(error))}\"");
|
|
||||||
|
|
||||||
if(tex.width > maxWidth)
|
|
||||||
maxWidth = tex.width;
|
|
||||||
|
|
||||||
if(tex.height > maxHeight)
|
|
||||||
maxHeight = tex.height;
|
|
||||||
|
|
||||||
textureDatas.Add(tex);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 texturesX = (.)System.Math.Ceiling(System.Math.Sqrt(textureDatas.Count));
|
|
||||||
uint32 texturesY = (.)System.Math.Ceiling((float)textureDatas.Count / (float)texturesX);
|
|
||||||
|
|
||||||
uint32 textureWidth = texturesX * maxWidth;
|
|
||||||
uint32 textureHeight = texturesY * maxHeight;
|
|
||||||
|
|
||||||
Color[] atlasColors = new DirectX.Color[textureWidth * textureHeight];
|
|
||||||
defer delete atlasColors;
|
|
||||||
|
|
||||||
uint32 currentX = 0;
|
|
||||||
uint32 currentY = 0;
|
|
||||||
|
|
||||||
for(let texture in textureDatas)
|
|
||||||
{
|
|
||||||
texture.blockTex.[Friend]_atlasStart = .((float)currentX / (float)textureWidth, (float)currentY / (float)textureHeight);
|
|
||||||
texture.blockTex.[Friend]_atlasSize = .((float)texture.width / (float)textureWidth, (float)texture.height / (float)textureHeight);
|
|
||||||
|
|
||||||
for(uint32 penY = currentY, uint32 y = 0; y < texture.height; penY++, y++)
|
|
||||||
for(uint32 penX = currentX, uint32 x = 0; x < texture.width; penX++, x++)
|
|
||||||
{
|
|
||||||
atlasColors[penX + penY * textureWidth] = texture.data[x + y * texture.width];
|
|
||||||
}
|
|
||||||
|
|
||||||
currentX += maxWidth;
|
|
||||||
if(currentX >= textureWidth)
|
|
||||||
{
|
|
||||||
currentX = 0;
|
|
||||||
currentY += maxHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Texture2DDescription desc;
|
|
||||||
desc.Width = textureWidth;
|
|
||||||
desc.Height = textureHeight;
|
|
||||||
desc.ArraySize = 1;
|
|
||||||
desc.MipLevels = 1;
|
|
||||||
desc.SampleDesc = .(1, 0);
|
|
||||||
desc.Usage = .Immutable;
|
|
||||||
desc.MiscFlags = .None;
|
|
||||||
desc.BindFlags = .ShaderResource;
|
|
||||||
desc.CpuAccessFlags = .None;
|
|
||||||
desc.Format = .R8G8B8A8_UNorm;
|
|
||||||
|
|
||||||
//SubresourceData data = .(atlasColors.CArray(), textureWidth, textureWidth * textureHeight);
|
|
||||||
SubresourceData data = .(atlasColors.CArray(), textureWidth * sizeof(Color), 0);
|
|
||||||
|
|
||||||
// TODO: this is bad platform dependant code...
|
|
||||||
var result = _context.[Friend]nativeDevice.CreateTexture2D(ref desc, &data, &nativeTexture);
|
|
||||||
|
|
||||||
//LodePng.LodePng.Encode32File("testout.png", textureD)
|
|
||||||
|
|
||||||
if(result.Failed)
|
|
||||||
Log.ClientLogger.Error($"Failed to create atlas texture. Error ({result.Underlying}): {result}");
|
|
||||||
|
|
||||||
result = _context.[Friend]nativeDevice.CreateShaderResourceView(nativeTexture, null, &nativeView);
|
|
||||||
|
|
||||||
if(result.Failed)
|
|
||||||
Log.ClientLogger.Error($"Failed to create atlas texture. Error ({result.Underlying}): {result}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using GlitchyEngine;
|
||||||
|
using GlitchyEngine.Math;
|
||||||
|
using GlitchyEngine.Renderer;
|
||||||
|
|
||||||
|
namespace Sandbox.VoxelFun
|
||||||
|
{
|
||||||
|
class TextureAtlas : Texture2D
|
||||||
|
{
|
||||||
|
public this(GraphicsContext context, List<BlockTexture> textures) : base(context)
|
||||||
|
{
|
||||||
|
// Todo: rewrite this garbage algorithm
|
||||||
|
|
||||||
|
List<(Color* data, uint32 width, uint32 height, BlockTexture blockTex)> textureDatas = new .(textures.Count);
|
||||||
|
defer
|
||||||
|
{
|
||||||
|
for(let item in textureDatas)
|
||||||
|
{
|
||||||
|
LodePng.LodePng.Free(item.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete textureDatas;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 maxWidth = 0;
|
||||||
|
uint32 maxHeight = 0;
|
||||||
|
|
||||||
|
for(let texture in textures)
|
||||||
|
{
|
||||||
|
(Color* data, uint32 width, uint32 height, BlockTexture blockTex) tex;
|
||||||
|
tex.blockTex = texture;
|
||||||
|
|
||||||
|
let error = LodePng.LodePng.Decode32File(out tex.data, out tex.width, out tex.height, texture.FileName);
|
||||||
|
|
||||||
|
if(error != 0)
|
||||||
|
Log.ClientLogger.Error($"Failed to load texture \"{texture.FileName}\". ({error}) \"{StringView(LodePng.LodePng.ErrorText(error))}\"");
|
||||||
|
|
||||||
|
if(tex.width > maxWidth)
|
||||||
|
maxWidth = tex.width;
|
||||||
|
|
||||||
|
if(tex.height > maxHeight)
|
||||||
|
maxHeight = tex.height;
|
||||||
|
|
||||||
|
textureDatas.Add(tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 texturesX = (.)System.Math.Ceiling(System.Math.Sqrt(textureDatas.Count));
|
||||||
|
uint32 texturesY = (.)System.Math.Ceiling((float)textureDatas.Count / (float)texturesX);
|
||||||
|
|
||||||
|
uint32 textureWidth = texturesX * maxWidth;
|
||||||
|
uint32 textureHeight = texturesY * maxHeight;
|
||||||
|
|
||||||
|
Color[] atlasColors = new DirectX.Color[textureWidth * textureHeight];
|
||||||
|
defer delete atlasColors;
|
||||||
|
|
||||||
|
uint32 currentX = 0;
|
||||||
|
uint32 currentY = 0;
|
||||||
|
|
||||||
|
for(let texture in textureDatas)
|
||||||
|
{
|
||||||
|
texture.blockTex.[Friend]_atlasStart = .((float)currentX / (float)textureWidth, (float)currentY / (float)textureHeight);
|
||||||
|
texture.blockTex.[Friend]_atlasSize = .((float)texture.width / (float)textureWidth, (float)texture.height / (float)textureHeight);
|
||||||
|
|
||||||
|
for(uint32 penY = currentY, uint32 y = 0; y < texture.height; penY++, y++)
|
||||||
|
for(uint32 penX = currentX, uint32 x = 0; x < texture.width; penX++, x++)
|
||||||
|
{
|
||||||
|
atlasColors[penX + penY * textureWidth] = texture.data[x + y * texture.width];
|
||||||
|
}
|
||||||
|
|
||||||
|
currentX += maxWidth;
|
||||||
|
if(currentX >= textureWidth)
|
||||||
|
{
|
||||||
|
currentX = 0;
|
||||||
|
currentY += maxHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture2DDesc desc;
|
||||||
|
desc.Width = textureWidth;
|
||||||
|
desc.Height = textureHeight;
|
||||||
|
desc.ArraySize = 1;
|
||||||
|
desc.MipLevels = 1;
|
||||||
|
desc.Format = .R8G8B8A8_UNorm;
|
||||||
|
|
||||||
|
CreateTexturePlatform(desc, atlasColors.CArray(), textureWidth * sizeof(Color));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user