This commit is contained in:
Simon Lübeß
2022-02-13 02:14:56 +01:00
parent 5b1f694bc9
commit a2db0774f8
7 changed files with 541 additions and 527 deletions
+15 -3
View File
@@ -39,7 +39,15 @@ namespace GlitchyEngine.Content
#if DEBUG #if DEBUG
var nameComponent = world.AssignComponent<DebugNameComponent>(entity); var nameComponent = world.AssignComponent<DebugNameComponent>(entity);
if (node.Name != null)
{
nameComponent.SetName(StringView(node.Name)); nameComponent.SetName(StringView(node.Name));
}
else
{
nameComponent.SetName("Unnamed Node");
}
#endif #endif
if(parentEntity.HasValue) if(parentEntity.HasValue)
@@ -120,16 +128,16 @@ namespace GlitchyEngine.Content
meshParent.Entity = entity; meshParent.Entity = entity;
var mesh = world.AssignComponent<MeshComponent>(meshEntity); var mesh = world.AssignComponent<MeshComponent>(meshEntity);
mesh.Mesh = ModelLoader.PrimitiveToGeoBinding(node.Mesh.Primitives[0], validationEffect); mesh.Mesh = PrimitiveToGeoBinding(primitive, validationEffect);
if(skeleton == null) if(skeleton == null)
{ {
var meshRenderer = world.AssignComponent<MeshRendererComponent>(entity); var meshRenderer = world.AssignComponent<MeshRendererComponent>(meshEntity);
meshRenderer.Material = material; meshRenderer.Material = material;
} }
else else
{ {
var meshRenderer = world.AssignComponent<SkinnedMeshRendererComponent>(entity); var meshRenderer = world.AssignComponent<SkinnedMeshRendererComponent>(meshEntity);
meshRenderer.Material = material; meshRenderer.Material = material;
meshRenderer.Skeleton = skeleton; meshRenderer.Skeleton = skeleton;
} }
@@ -179,6 +187,7 @@ namespace GlitchyEngine.Content
uint8* bufferData = (uint8*)indices.BufferView.Buffer.Data; uint8* bufferData = (uint8*)indices.BufferView.Buffer.Data;
bufferData += indices.BufferView.Offset; bufferData += indices.BufferView.Offset;
// TODO: this is a mess
ib.SetData<uint8>(bufferData, (.)indices.BufferView.Size); ib.SetData<uint8>(bufferData, (.)indices.BufferView.Size);
binding.SetIndexBuffer(ib); binding.SetIndexBuffer(ib);
@@ -388,6 +397,7 @@ namespace GlitchyEngine.Content
joint.InverseBindPose = GetEntry<Matrix>(skin.InverseBindMatrices, i); joint.InverseBindPose = GetEntry<Matrix>(skin.InverseBindMatrices, i);
if (skin.Joints[i].Name != null)
joint.Name = new String(skin.Joints[i].Name); joint.Name = new String(skin.Joints[i].Name);
int parentId = skin.Joints.IndexOf(skin.Joints[i].Parent); int parentId = skin.Joints.IndexOf(skin.Joints[i].Parent);
@@ -528,6 +538,8 @@ namespace GlitchyEngine.Content
CGLTF.AccessorReadFloat(accessor, (uint)index, (float*)&result, 4); CGLTF.AccessorReadFloat(accessor, (uint)index, (float*)&result, 4);
case typeof(Matrix): case typeof(Matrix):
CGLTF.AccessorReadFloat(accessor, (uint)index, (float*)&result, 16); CGLTF.AccessorReadFloat(accessor, (uint)index, (float*)&result, 16);
case typeof(uint16):
CGLTF.AccessorReadUint(accessor, (uint)index, (uint32*)&result, 2);
case default: case default:
uint8* data = (uint8*)accessor.BufferView.Buffer.Data; uint8* data = (uint8*)accessor.BufferView.Buffer.Data;
@@ -70,7 +70,7 @@ namespace GlitchyEngine.Renderer
{ {
byteData = new uint8[nativeDescription.ByteWidth]*; byteData = new uint8[nativeDescription.ByteWidth]*;
defer:: delete byteData; defer:: delete byteData;
Internal.MemCpy(byteData + dstByteOffset, data, byteLength); Internal.MemCpy(byteData + dstByteOffset, data, Math.Min(nativeDescription.ByteWidth, byteLength));
} }
SubresourceData srData = .(byteData, byteLength, 0); SubresourceData srData = .(byteData, byteLength, 0);
+1 -1
View File
@@ -5,4 +5,4 @@ Dependencies = {GlitchyEngine = "*", corlib = "*", msdfgen-beef = "*", LodePng =
Name = "Sandbox" Name = "Sandbox"
TargetType = "BeefGUIApplication" TargetType = "BeefGUIApplication"
StartupObject = "GlitchyEngine.Program" StartupObject = "GlitchyEngine.Program"
ProcessorMacros = ["GAMMA_TEST", "NOT_SANDBOX_2D"] ProcessorMacros = ["NOT_GAMMA_TEST", "SANDBOX_2D"]
Binary file not shown.
+521
View File
@@ -0,0 +1,521 @@
using GlitchyEngine.Renderer;
using GlitchyEngine.Events;
using GlitchyEngine.ImGui;
using GlitchyEngine.Math;
using GlitchyEngine;
using System;
using GlitchyEngine.World;
using GlitchyEngine.Renderer.Animation;
using GlitchyEngine.Content;
using System.Collections;
namespace Sandbox
{
class ExampleLayer : Layer
{
[Ordered]
struct VertexColorTexture : IVertexData
{
public Vector3 Position;
public Color Color;
public Vector2 TexCoord;
public this() => this = default;
public this(Vector3 pos, Color color)
{
Position = pos;
Color = color;
TexCoord = .();
}
public this(Vector3 pos, Color color, Vector2 texCoord)
{
Position = pos;
Color = color;
TexCoord = texCoord;
}
public static readonly VertexElement[] VertexElements ~ delete _;
public static VertexElement[] IVertexData.VertexElements => VertexElements;
static this()
{
VertexElements = new VertexElement[](
VertexElement(.R32G32B32_Float, "POSITION"),
VertexElement(.R8G8B8A8_UNorm, "COLOR"),
VertexElement(.R32G32_Float, "TEXCOORD"),
);
}
}
GeometryBinding _geometryBinding ~ _?.ReleaseRef();
GeometryBinding _quadGeometryBinding ~ _?.ReleaseRef();
RasterizerState _rasterizerState ~ _?.ReleaseRef();
RasterizerState _rasterizerStateClockWise ~ _?.ReleaseRef();
GraphicsContext _context ~ _?.ReleaseRef();
DepthStencilTarget _depthTarget ~ _?.ReleaseRef();
Material _checkerMaterial ~ _?.ReleaseRef();
Material _logoMaterial ~ _?.ReleaseRef();
Texture2D _texture ~ _?.ReleaseRef();
Texture2D _ge_logo ~ _?.ReleaseRef();
BlendState _alphaBlendState ~ _?.ReleaseRef();
BlendState _opaqueBlendState ~ _?.ReleaseRef();
EcsWorld _world = new EcsWorld() ~ delete _;
PerspectiveCameraController _cameraController ~ delete _;
private Vector3 CircleCoord(float angle)
{
return .(Math.Cos(angle), Math.Sin(angle), 0);
}
[AllowAppend]
public this() : base("Example")
{
Application.Get().Window.IsVSync = false;
_context = Application.Get().Window.Context..AddRef();
var effectLibrary = Application.Get().EffectLibrary;
effectLibrary.LoadNoRefInc("content\\Shaders\\basicShader.hlsl");
effectLibrary.LoadNoRefInc("content\\Shaders\\testShader.hlsl");
var textureEffect = effectLibrary.Load("content\\Shaders\\textureShader.hlsl");
_depthTarget = new DepthStencilTarget(_context.SwapChain.Width, _context.SwapChain.Height);
// Create Input Layout
VertexLayout vertexLayout = new VertexLayout(VertexColorTexture.VertexElements, false, textureEffect.VertexShader);
textureEffect.ReleaseRef();
// Create hexagon
{
_geometryBinding = new GeometryBinding();
_geometryBinding.SetPrimitiveTopology(.TriangleList);
_geometryBinding.SetVertexLayout(vertexLayout);
float pO3 = Math.PI_f / 3.0f;
VertexColorTexture[?] vertices = .(
VertexColorTexture(.Zero, Color(255,255,255)),
VertexColorTexture(CircleCoord(0), Color(255, 0, 0)),
VertexColorTexture(CircleCoord(pO3), Color(255,255, 0)),
VertexColorTexture(CircleCoord(pO3*2), Color( 0,255, 0)),
VertexColorTexture(CircleCoord(Math.PI_f), Color( 0,255,255)),
VertexColorTexture(CircleCoord(-pO3*2), Color( 0, 0,255)),
VertexColorTexture(CircleCoord(-pO3), Color(255, 0,255)),
);
let vb = new VertexBuffer(typeof(VertexColorTexture), (.)vertices.Count, .Immutable);
vb.SetData(vertices);
_geometryBinding.SetVertexBufferSlot(vb, 0);
vb.ReleaseRef();
uint16[?] indices = .(
0, 1, 2,
0, 2, 3,
0, 3, 4,
0, 4, 5,
0, 5, 6,
0, 6, 1);
let ib = new IndexBuffer((.)indices.Count, .Immutable);
ib.SetData(indices);
_geometryBinding.SetIndexBuffer(ib);
ib.ReleaseRef();
}
// Create Quad
{
_quadGeometryBinding = new GeometryBinding();
_quadGeometryBinding.SetPrimitiveTopology(.TriangleList);
_quadGeometryBinding.SetVertexLayout(vertexLayout);
VertexColorTexture[?] vertices = .(
VertexColorTexture(Vector3(-0.75f, 0.75f, 0), Color.White, .(0, 0)),
VertexColorTexture(Vector3(-0.75f, -0.75f, 0), Color.White, .(0, 1)),
VertexColorTexture(Vector3(0.75f, -0.75f, 0), Color.White, .(1, 1)),
VertexColorTexture(Vector3(0.75f, 0.75f, 0), Color.White, .(1, 0)),
);
let qvb = new VertexBuffer(typeof(VertexColorTexture), (.)vertices.Count, .Immutable);
qvb.SetData(vertices);
_quadGeometryBinding.SetVertexBufferSlot(qvb, 0);
qvb.ReleaseRef();
uint16[?] indices = .(
0, 1, 2,
2, 3, 0);
let qib = new IndexBuffer((.)indices.Count, .Immutable);
qib.SetData(indices);
_quadGeometryBinding.SetIndexBuffer(qib);
qib.ReleaseRef();
}
vertexLayout.ReleaseRef();
// Create rasterizer state
RasterizerStateDescription rsDesc = .(.Solid, .Back, true);
_rasterizerState = new RasterizerState(rsDesc);
rsDesc.FrontCounterClockwise = false;
_rasterizerStateClockWise = new RasterizerState(rsDesc);
_texture = new Texture2D("content/Textures/Checkerboard.dds");
_ge_logo = new Texture2D("content/Textures/GE_Logo.dds");
let sampler = SamplerStateManager.GetSampler(
SamplerStateDescription()
{
MagFilter = .Point
});
_texture.SamplerState = sampler;
_ge_logo.SamplerState = sampler;
sampler.ReleaseRef();
_logoMaterial = new Material(textureEffect);
_logoMaterial.SetTexture("ColorTexture", _ge_logo);
_checkerMaterial = new Material(textureEffect);
_checkerMaterial.SetTexture("ColorTexture", _texture);
BlendStateDescription blendDesc = .();
blendDesc.RenderTarget[0] = .(true, .SourceAlpha, .InvertedSourceAlpha, .Add, .SourceAlpha, .InvertedSourceAlpha, .Add, .All);
_alphaBlendState = new BlendState(blendDesc);
_opaqueBlendState = new BlendState(.Default);
InitEcs();
_cameraController = new .(_context.SwapChain.AspectRatio);
_cameraController.CameraPosition = .(0, 0, -5);
_cameraController.TranslationSpeed = 10;
TestLoadModel();
}
List<AnimationClip> Clips = new List<AnimationClip>() ~ DeleteContainerAndReleaseItems!(_);
Material animationMat;
void TestLoadModel()
{
var testEffect = Application.Get().EffectLibrary.Get("testShader");
var materialTestMaterial = new Material(testEffect);
animationMat = materialTestMaterial;
Matrix[] matrices = scope Matrix[255];
Matrix3x3[] matrices2 = scope Matrix3x3[255];
for(int i < 255)
{
matrices[i] = .Identity;
matrices2[i] = .Identity;
}
materialTestMaterial.SetVariable("SkinningMatrices", matrices);
materialTestMaterial.SetVariable("InvTransSkinningMatrices", matrices2);
materialTestMaterial.SetVariable("BaseColor", Color.White);
materialTestMaterial.SetVariable("LightDir", Vector3(1, 1, -0.5f).Normalized());
ModelLoader.LoadModel("content\\Models\\RiggedFigure\\RiggedFigure.glb", testEffect, materialTestMaterial, _world, Clips);
materialTestMaterial.ReleaseRef();
testEffect.ReleaseRef();
for(var (entity, transform, mesh, meshRenderer) in _world.Enumerate<TransformComponent, MeshComponent, SkinnedMeshRendererComponent>())
{
var animation = _world.AssignComponent<AnimationComponent>(entity);
animation.AnimationClip = Clips[0];
animation.TimeScale = 1.0f;
animation.IsPlaying = true;
animation.[Friend]_pose = new SkeletonPose(meshRenderer.Skeleton);
}
}
Entity evenCrazierParent;
Entity crazyParent;
Material testMaterial1 ~ _?.ReleaseRef();
Material testMaterial2 ~ _?.ReleaseRef();
void InitEcs()
{
_world.Register<DebugNameComponent>();
_world.Register<TransformComponent>();
_world.Register<ParentComponent>();
_world.Register<MeshComponent>();
_world.Register<MeshRendererComponent>();
_world.Register<SkinnedMeshRendererComponent>();
_world.Register<CameraComponent>();
_world.Register<AnimationComponent>();
var basicEffect = Application.Get().EffectLibrary.Get("basicShader");
testMaterial1 = new Material(basicEffect);
testMaterial1.SetVariable("BaseColor", _squareColor0);
testMaterial2 = new Material(basicEffect);
testMaterial2.SetVariable("BaseColor", _squareColor1);
basicEffect.ReleaseRef();
/*
Entity[20][20] entities;
int i = 0;
for(int x < 20)
for(int y < 20)
{
Entity entity = _world.NewEntity();
entities[x][y] = entity;
var transform = _world.AssignComponent<TransformComponent>(entity);
*transform = TransformComponent();
transform.LocalTransform = Matrix.Translation(x * 0.2f, y * 0.2f, 0) * Matrix.Scaling(0.1f);
var mesh = _world.AssignComponent<MeshComponent>(entity);
mesh.Mesh = _quadGeometryBinding;
i++;
var meshRenderer = _world.AssignComponent<MeshRendererComponent>(entity);
if(i % 2 == 0)
meshRenderer.Material = testMaterial1;
else
meshRenderer.Material = testMaterial2;
}
crazyParent = _world.NewEntity();
evenCrazierParent = _world.NewEntity();
var crazyTransform = _world.AssignComponent<TransformComponent>(evenCrazierParent);
crazyTransform.Position = .Zero;
crazyTransform.Scale = .One;
crazyTransform.Rotation = .Identity;
var pp = _world.AssignComponent<ParentComponent>(crazyParent);
pp.Entity = evenCrazierParent;
crazyTransform = _world.AssignComponent<TransformComponent>(crazyParent);
crazyTransform.Position = .Zero;
crazyTransform.Scale = .(2.0f, 2.0f, 2.0f);
crazyTransform.Rotation = .Identity;
for(int x < 20)
for(int y < 20)
{
var parent = _world.AssignComponent<ParentComponent>(entities[x][y]);
parent.Entity = crazyParent;
}
*/
}
float f = 0.0f;
bool playAnimation = false;
public override void Update(GameTime gameTime)
{
f += (float)gameTime.FrameTime.TotalSeconds;
_cameraController.Update(gameTime);
RenderCommand.Clear(null, .(0.2f, 0.2f, 0.2f));
RenderCommand.Clear(_depthTarget, .Depth, 1.0f, 0);
// Draw test geometry
RenderCommand.SetRenderTarget(null);
RenderCommand.SetDepthStencilTarget(_depthTarget);
RenderCommand.BindRenderTargets();
RenderCommand.SetViewport(_context.SwapChain.BackbufferViewport);
Renderer.BeginScene(_cameraController.Camera);
RenderCommand.SetBlendState(_opaqueBlendState);
var basicEffect = Application.Get().EffectLibrary.Get("basicShader");
RenderCommand.SetRasterizerState(_rasterizerState);
TransformSystem.Update(_world);
for(var (entity, transform, mesh, meshRenderer) in _world.Enumerate<TransformComponent, MeshComponent, MeshRendererComponent>())
{
Renderer.Submit(mesh.Mesh, meshRenderer.Material, transform.WorldTransform);
}
for(var (entity, transform, mesh, meshRenderer, animation) in _world.Enumerate<TransformComponent, MeshComponent, SkinnedMeshRendererComponent, AnimationComponent>())
{
var material = meshRenderer.Material;
var timeIndex = ref animation.TimeIndex;
var currentClip = animation.AnimationClip;
var pose = animation.Pose;
// Only advance time index if animation is playing
if(animation.IsPlaying)
{
timeIndex += (float)gameTime.FrameTime.TotalSeconds * animation.TimeScale;
if(currentClip.IsLooping && currentClip.Duration != 0)
{
timeIndex %= currentClip.Duration;
// modulo can result in negative numbers
if(timeIndex < 0)
timeIndex += currentClip.Duration;
}
}
var skeleton = currentClip.Skeleton;
// Update joints
for(int i < skeleton.Joints.Count)
{
ref JointPose localPose = ref pose.LocalPose[i];
localPose = currentClip.JointAnimations[i].GetCurrentPose(timeIndex);
Matrix jointToParent =
Matrix.Translation(localPose.Translation) *
Matrix.RotationQuaternion(localPose.Rotation) *
Matrix.Scaling(localPose.Scale);
uint8 parentIndex = skeleton.Joints[i].ParentID;
ref Matrix globalPose = ref pose.GlobalPose[i];
if(parentIndex == uint8.MaxValue)
{
globalPose = jointToParent;
}
else
{
globalPose = pose.GlobalPose[parentIndex] * jointToParent;
}
pose.SkinningMatricies[i] = globalPose * skeleton.Joints[i].InverseBindPose;
pose.InvTransSkinningMatricies[i] = ((Matrix3x3)pose.SkinningMatricies[i]).Inverse().Transpose();
}
int i = 0;
for(var globalPose in pose.GlobalPose)
{
Joint currentJoint = meshRenderer.Skeleton.Joints[i];
Matrix bindPose = currentJoint.InverseBindPose.Invert();
// Draw skeleton
Matrix mat = pose.SkinningMatricies[i] * bindPose;
uint8 parentId = currentJoint.ParentID;
if(parentId != uint8.MaxValue)
{
Vector3 start = mat.Translation;
Joint parent = meshRenderer.Skeleton.Joints[parentId];
Matrix parentBindPose = parent.InverseBindPose.Invert();
Matrix parentMatrix = pose.SkinningMatricies[parentId] * parentBindPose;
Vector3 end = parentMatrix.Translation;
Renderer.DrawLine(start, end, .Black, transform.WorldTransform);
}
DebugRenderer.DrawCoordinateCross(transform.WorldTransform * mat, 0.5f);
i++;
}
material.SetVariable("SkinningMatrices", pose.SkinningMatricies);
material.SetVariable("InvTransSkinningMatrices", pose.InvTransSkinningMatricies);
// non engine
material.SetVariable("BaseColor", Color.White);
material.SetVariable("LightDir", Vector3(1, 1, -0.5f).Normalized());
Renderer.Submit(mesh.Mesh, material, transform.WorldTransform);
}
basicEffect.Variables["BaseColor"].SetData(_squareColor1);
_checkerMaterial.SetVariable("BaseColor", Color.White);
Renderer.Submit(_quadGeometryBinding, _checkerMaterial, Matrix.RotationY(f) * Matrix.RotationX(MathHelper.PiOverTwo) * .Scaling(1.5f));
RenderCommand.SetBlendState(_alphaBlendState);
_logoMaterial.SetVariable("BaseColor", Color.Pink);
Renderer.Submit(_quadGeometryBinding, _logoMaterial, .Translation(0, 0, -1) * .Scaling(2f));
DebugRenderer.Render(_world);
Renderer.EndScene();
basicEffect.ReleaseRef();
}
ColorRGBA _squareColor0 = ColorRGBA.CornflowerBlue;
ColorRGBA _squareColor1;
public override void OnEvent(Event event)
{
_cameraController.OnEvent(event);
EventDispatcher dispatcher = EventDispatcher(event);
dispatcher.Dispatch<ImGuiRenderEvent>(scope (e) => OnImGuiRender(e));
dispatcher.Dispatch<WindowResizeEvent>(scope (e) => OnWindowResize(e));
}
private bool OnImGuiRender(ImGuiRenderEvent e)
{
/*
ImGui.Begin("Test");
var v = ImGui.ColorEdit3("Square Color", ref _squareColor0);
if(v)
{
testMaterial1.SetVariable("BaseColor", _squareColor0);
testMaterial2.SetVariable("BaseColor", ColorRGBA.White - _squareColor0);
}
ImGui.End();
*/
return false;
}
private bool OnWindowResize(WindowResizeEvent e)
{
_depthTarget.ReleaseRef();
_depthTarget = new DepthStencilTarget(_context.SwapChain.Width, _context.SwapChain.Height);
return false;
}
}
}
+1 -9
View File
@@ -16,8 +16,6 @@ namespace Sandbox
{ {
class ExampleLayer2D : Layer class ExampleLayer2D : Layer
{ {
RasterizerState _rasterizerState ~ _?.ReleaseRef();
GraphicsContext _context ~ _?.ReleaseRef(); GraphicsContext _context ~ _?.ReleaseRef();
DepthStencilTarget _depthTarget ~ _?.ReleaseRef(); DepthStencilTarget _depthTarget ~ _?.ReleaseRef();
@@ -43,10 +41,6 @@ namespace Sandbox
_context = Application.Get().Window.Context..AddRef(); _context = Application.Get().Window.Context..AddRef();
// Create rasterizer state
GlitchyEngine.Renderer.RasterizerStateDescription rsDesc = .(.Solid, .Back, false, 0);
_rasterizerState = new RasterizerState(rsDesc);
_depthTarget = new DepthStencilTarget(_context.SwapChain.Width, _context.SwapChain.Height); _depthTarget = new DepthStencilTarget(_context.SwapChain.Width, _context.SwapChain.Height);
_checkerTexture = new Texture2D("content/Textures/Checkerboard.dds"); _checkerTexture = new Texture2D("content/Textures/Checkerboard.dds");
@@ -79,7 +73,7 @@ namespace Sandbox
_textureViewer = new TextureViewer(); _textureViewer = new TextureViewer();
cameraController = new OrthographicCameraController(16 / 9f); cameraController = new OrthographicCameraController(_context.SwapChain.AspectRatio);
DepthStencilStateDescription dssDesc = .() DepthStencilStateDescription dssDesc = .()
{ {
@@ -106,8 +100,6 @@ namespace Sandbox
RenderCommand.SetDepthStencilTarget(_depthTarget); RenderCommand.SetDepthStencilTarget(_depthTarget);
RenderCommand.BindRenderTargets(); RenderCommand.BindRenderTargets();
RenderCommand.SetRasterizerState(_rasterizerState);
RenderCommand.SetViewport(_context.SwapChain.BackbufferViewport); RenderCommand.SetViewport(_context.SwapChain.BackbufferViewport);
Renderer2D.BeginScene(cameraController.Camera, .BackToFront); Renderer2D.BeginScene(cameraController.Camera, .BackToFront);
-511
View File
@@ -14,517 +14,6 @@ using GlitchyEngine.Renderer.Animation;
namespace Sandbox namespace Sandbox
{ {
class ExampleLayer : Layer
{
[Ordered]
struct VertexColorTexture : IVertexData
{
public Vector3 Position;
public Color Color;
public Vector2 TexCoord;
public this() => this = default;
public this(Vector3 pos, Color color)
{
Position = pos;
Color = color;
TexCoord = .();
}
public this(Vector3 pos, Color color, Vector2 texCoord)
{
Position = pos;
Color = color;
TexCoord = texCoord;
}
public static readonly VertexElement[] VertexElements ~ delete _;
public static VertexElement[] IVertexData.VertexElements => VertexElements;
static this()
{
VertexElements = new VertexElement[](
VertexElement(.R32G32B32_Float, "POSITION"),
VertexElement(.R8G8B8A8_UNorm, "COLOR"),
VertexElement(.R32G32_Float, "TEXCOORD"),
);
}
}
GeometryBinding _geometryBinding ~ _?.ReleaseRef();
GeometryBinding _quadGeometryBinding ~ _?.ReleaseRef();
RasterizerState _rasterizerState ~ _?.ReleaseRef();
RasterizerState _rasterizerStateClockWise ~ _?.ReleaseRef();
GraphicsContext _context ~ _?.ReleaseRef();
DepthStencilTarget _depthTarget ~ _?.ReleaseRef();
Material _checkerMaterial ~ _?.ReleaseRef();
Material _logoMaterial ~ _?.ReleaseRef();
Texture2D _texture ~ _?.ReleaseRef();
Texture2D _ge_logo ~ _?.ReleaseRef();
BlendState _alphaBlendState ~ _?.ReleaseRef();
BlendState _opaqueBlendState ~ _?.ReleaseRef();
EcsWorld _world = new EcsWorld() ~ delete _;
// OrthographicCameraController _cameraController ~ delete _;
PerspectiveCameraController _cameraController ~ delete _;
private Vector3 CircleCoord(float angle)
{
return .(Math.Cos(angle), Math.Sin(angle), 0);
}
[AllowAppend]
public this() : base("Example")
{
Application.Get().Window.IsVSync = false;
_context = Application.Get().Window.Context..AddRef();
var effectLibrary = Application.Get().EffectLibrary;
effectLibrary.LoadNoRefInc("content\\Shaders\\basicShader.hlsl");
effectLibrary.LoadNoRefInc("content\\Shaders\\testShader.hlsl");
var textureEffect = effectLibrary.Load("content\\Shaders\\textureShader.hlsl");
_depthTarget = new DepthStencilTarget(_context.SwapChain.Width, _context.SwapChain.Height);
// Create Input Layout
VertexLayout vertexLayout = new VertexLayout(VertexColorTexture.VertexElements, false, textureEffect.VertexShader);
textureEffect.ReleaseRef();
// Create hexagon
{
_geometryBinding = new GeometryBinding();
_geometryBinding.SetPrimitiveTopology(.TriangleList);
_geometryBinding.SetVertexLayout(vertexLayout);
float pO3 = Math.PI_f / 3.0f;
VertexColorTexture[?] vertices = .(
VertexColorTexture(.Zero, Color(255,255,255)),
VertexColorTexture(CircleCoord(0), Color(255, 0, 0)),
VertexColorTexture(CircleCoord(pO3), Color(255,255, 0)),
VertexColorTexture(CircleCoord(pO3*2), Color( 0,255, 0)),
VertexColorTexture(CircleCoord(Math.PI_f), Color( 0,255,255)),
VertexColorTexture(CircleCoord(-pO3*2), Color( 0, 0,255)),
VertexColorTexture(CircleCoord(-pO3), Color(255, 0,255)),
);
let vb = new VertexBuffer(typeof(VertexColorTexture), (.)vertices.Count, .Immutable);
vb.SetData(vertices);
_geometryBinding.SetVertexBufferSlot(vb, 0);
vb.ReleaseRef();
uint16[?] indices = .(
0, 1, 2,
0, 2, 3,
0, 3, 4,
0, 4, 5,
0, 5, 6,
0, 6, 1);
let ib = new IndexBuffer((.)indices.Count, .Immutable);
ib.SetData(indices);
_geometryBinding.SetIndexBuffer(ib);
ib.ReleaseRef();
}
// Create Quad
{
_quadGeometryBinding = new GeometryBinding();
_quadGeometryBinding.SetPrimitiveTopology(.TriangleList);
_quadGeometryBinding.SetVertexLayout(vertexLayout);
VertexColorTexture[?] vertices = .(
VertexColorTexture(Vector3(-0.75f, 0.75f, 0), Color.White, .(0, 0)),
VertexColorTexture(Vector3(-0.75f, -0.75f, 0), Color.White, .(0, 1)),
VertexColorTexture(Vector3(0.75f, -0.75f, 0), Color.White, .(1, 1)),
VertexColorTexture(Vector3(0.75f, 0.75f, 0), Color.White, .(1, 0)),
);
let qvb = new VertexBuffer(typeof(VertexColorTexture), (.)vertices.Count, .Immutable);
qvb.SetData(vertices);
_quadGeometryBinding.SetVertexBufferSlot(qvb, 0);
qvb.ReleaseRef();
uint16[?] indices = .(
0, 1, 2,
2, 3, 0);
let qib = new IndexBuffer((.)indices.Count, .Immutable);
qib.SetData(indices);
_quadGeometryBinding.SetIndexBuffer(qib);
qib.ReleaseRef();
}
vertexLayout.ReleaseRef();
// Create rasterizer state
RasterizerStateDescription rsDesc = .(.Solid, .Back, true);
_rasterizerState = new RasterizerState(rsDesc);
rsDesc.FrontCounterClockwise = false;
_rasterizerStateClockWise = new RasterizerState(rsDesc);
_texture = new Texture2D("content/Textures/Checkerboard.dds");
_ge_logo = new Texture2D("content/Textures/GE_Logo.dds");
let sampler = SamplerStateManager.GetSampler(
SamplerStateDescription()
{
MagFilter = .Point
});
_texture.SamplerState = sampler;
_ge_logo.SamplerState = sampler;
sampler.ReleaseRef();
_logoMaterial = new Material(textureEffect);
_logoMaterial.SetTexture("ColorTexture", _ge_logo);
_checkerMaterial = new Material(textureEffect);
_checkerMaterial.SetTexture("ColorTexture", _texture);
BlendStateDescription blendDesc = .();
blendDesc.RenderTarget[0] = .(true, .SourceAlpha, .InvertedSourceAlpha, .Add, .SourceAlpha, .InvertedSourceAlpha, .Add, .All);
_alphaBlendState = new BlendState(blendDesc);
_opaqueBlendState = new BlendState(.Default);
InitEcs();
//_cameraController = new OrthographicCameraController(Application.Get().Window.Context.SwapChain.BackbufferViewport.Width /
// Application.Get().Window.Context.SwapChain.BackbufferViewport.Height);
_cameraController = new .(Application.Get().Window.Context.SwapChain.BackbufferViewport.Width /
Application.Get().Window.Context.SwapChain.BackbufferViewport.Height);
_cameraController.CameraPosition = .(0, 0, -5);
_cameraController.TranslationSpeed = 10;
TestLoadModel();
}
List<AnimationClip> Clips = new List<AnimationClip>() ~ DeleteContainerAndReleaseItems!(_);
Material animationMat;
void TestLoadModel()
{
var testEffect = Application.Get().EffectLibrary.Get("testShader");
var materialTestMaterial = new Material(testEffect);
animationMat = materialTestMaterial;
Matrix[] matrices = scope Matrix[255];
Matrix3x3[] matrices2 = scope Matrix3x3[255];
for(int i < 255)
{
matrices[i] = .Identity;
matrices2[i] = .Identity;
}
materialTestMaterial.SetVariable("SkinningMatrices", matrices);
materialTestMaterial.SetVariable("InvTransSkinningMatrices", matrices2);
materialTestMaterial.SetVariable("BaseColor", Color.White);
materialTestMaterial.SetVariable("LightDir", Vector3(1, 1, -0.5f).Normalized());
ModelLoader.LoadModel("content\\Models\\Figure\\Figure.gltf", testEffect, materialTestMaterial, _world, Clips);
materialTestMaterial.ReleaseRef();
testEffect.ReleaseRef();
for(var (entity, transform, mesh, meshRenderer) in _world.Enumerate<TransformComponent, MeshComponent, SkinnedMeshRendererComponent>())
{
var animation = _world.AssignComponent<AnimationComponent>(entity);
animation.AnimationClip = Clips[0];
animation.TimeScale = 1.0f;
animation.IsPlaying = true;
animation.[Friend]_pose = new SkeletonPose(meshRenderer.Skeleton);
}
}
Entity evenCrazierParent;
Entity crazyParent;
Material testMaterial1 ~ _?.ReleaseRef();
Material testMaterial2 ~ _?.ReleaseRef();
void InitEcs()
{
_world.Register<DebugNameComponent>();
_world.Register<TransformComponent>();
_world.Register<ParentComponent>();
_world.Register<MeshComponent>();
_world.Register<MeshRendererComponent>();
_world.Register<SkinnedMeshRendererComponent>();
_world.Register<CameraComponent>();
_world.Register<AnimationComponent>();
var basicEffect = Application.Get().EffectLibrary.Get("basicShader");
testMaterial1 = new Material(basicEffect);
testMaterial1.SetVariable("BaseColor", _squareColor0);
testMaterial2 = new Material(basicEffect);
testMaterial2.SetVariable("BaseColor", _squareColor1);
basicEffect.ReleaseRef();
/*
Entity[20][20] entities;
int i = 0;
for(int x < 20)
for(int y < 20)
{
Entity entity = _world.NewEntity();
entities[x][y] = entity;
var transform = _world.AssignComponent<TransformComponent>(entity);
*transform = TransformComponent();
transform.LocalTransform = Matrix.Translation(x * 0.2f, y * 0.2f, 0) * Matrix.Scaling(0.1f);
var mesh = _world.AssignComponent<MeshComponent>(entity);
mesh.Mesh = _quadGeometryBinding;
i++;
var meshRenderer = _world.AssignComponent<MeshRendererComponent>(entity);
if(i % 2 == 0)
meshRenderer.Material = testMaterial1;
else
meshRenderer.Material = testMaterial2;
}
crazyParent = _world.NewEntity();
evenCrazierParent = _world.NewEntity();
var crazyTransform = _world.AssignComponent<TransformComponent>(evenCrazierParent);
crazyTransform.Position = .Zero;
crazyTransform.Scale = .One;
crazyTransform.Rotation = .Identity;
var pp = _world.AssignComponent<ParentComponent>(crazyParent);
pp.Entity = evenCrazierParent;
crazyTransform = _world.AssignComponent<TransformComponent>(crazyParent);
crazyTransform.Position = .Zero;
crazyTransform.Scale = .(2.0f, 2.0f, 2.0f);
crazyTransform.Rotation = .Identity;
for(int x < 20)
for(int y < 20)
{
var parent = _world.AssignComponent<ParentComponent>(entities[x][y]);
parent.Entity = crazyParent;
}
*/
}
float f = 0.0f;
bool playAnimation = false;
public override void Update(GameTime gameTime)
{
f += (float)gameTime.FrameTime.TotalSeconds;
_cameraController.Update(gameTime);
RenderCommand.Clear(null, .(0.2f, 0.2f, 0.2f));
RenderCommand.Clear(_depthTarget, .Depth, 1.0f, 0);
// Draw test geometry
RenderCommand.SetRenderTarget(null);
RenderCommand.SetDepthStencilTarget(_depthTarget);
RenderCommand.BindRenderTargets();
RenderCommand.SetViewport(_context.SwapChain.BackbufferViewport);
Renderer.BeginScene(_cameraController.Camera);
RenderCommand.SetBlendState(_opaqueBlendState);
var basicEffect = Application.Get().EffectLibrary.Get("basicShader");
RenderCommand.SetRasterizerState(_rasterizerState);
TransformSystem.Update(_world);
for(var (entity, transform, mesh, meshRenderer) in _world.Enumerate<TransformComponent, MeshComponent, MeshRendererComponent>())
{
Renderer.Submit(mesh.Mesh, meshRenderer.Material, transform.WorldTransform);
}
for(var (entity, transform, mesh, meshRenderer, animation) in _world.Enumerate<TransformComponent, MeshComponent, SkinnedMeshRendererComponent, AnimationComponent>())
{
var material = meshRenderer.Material;
var timeIndex = ref animation.TimeIndex;
var currentClip = animation.AnimationClip;
var pose = animation.Pose;
// Only advance time index if animation is playing
if(animation.IsPlaying)
{
timeIndex += (float)gameTime.FrameTime.TotalSeconds * animation.TimeScale;
if(currentClip.IsLooping && currentClip.Duration != 0)
{
timeIndex %= currentClip.Duration;
// modulo can result in negative numbers
if(timeIndex < 0)
timeIndex += currentClip.Duration;
}
}
var skeleton = currentClip.Skeleton;
// Update joints
for(int i < skeleton.Joints.Count)
{
ref JointPose localPose = ref pose.LocalPose[i];
localPose = currentClip.JointAnimations[i].GetCurrentPose(timeIndex);
Matrix jointToParent =
Matrix.Translation(localPose.Translation) *
Matrix.RotationQuaternion(localPose.Rotation) *
Matrix.Scaling(localPose.Scale);
uint8 parentIndex = skeleton.Joints[i].ParentID;
ref Matrix globalPose = ref pose.GlobalPose[i];
if(parentIndex == uint8.MaxValue)
{
globalPose = jointToParent;
}
else
{
globalPose = pose.GlobalPose[parentIndex] * jointToParent;
}
pose.SkinningMatricies[i] = globalPose * skeleton.Joints[i].InverseBindPose;
pose.InvTransSkinningMatricies[i] = ((Matrix3x3)pose.SkinningMatricies[i]).Inverse().Transpose();
}
int i = 0;
for(var globalPose in pose.GlobalPose)
{
Joint currentJoint = meshRenderer.Skeleton.Joints[i];
Matrix bindPose = currentJoint.InverseBindPose.Invert();
// Draw skeleton
Matrix mat = pose.SkinningMatricies[i] * bindPose;
uint8 parentId = currentJoint.ParentID;
if(parentId != uint8.MaxValue)
{
Vector3 start = mat.Translation;
Joint parent = meshRenderer.Skeleton.Joints[parentId];
Matrix parentBindPose = parent.InverseBindPose.Invert();
Matrix parentMatrix = pose.SkinningMatricies[parentId] * parentBindPose;
Vector3 end = parentMatrix.Translation;
Renderer.DrawLine(start, end, .Black, transform.WorldTransform);
}
DebugRenderer.DrawCoordinateCross(transform.WorldTransform * mat, 0.5f);
i++;
}
material.SetVariable("SkinningMatrices", pose.SkinningMatricies);
material.SetVariable("InvTransSkinningMatrices", pose.InvTransSkinningMatricies);
// non engine
material.SetVariable("BaseColor", Color.White);
material.SetVariable("LightDir", Vector3(1, 1, -0.5f).Normalized());
Renderer.Submit(mesh.Mesh, material, transform.WorldTransform);
}
basicEffect.Variables["BaseColor"].SetData(_squareColor1);
_checkerMaterial.SetVariable("BaseColor", Color.White);
Renderer.Submit(_quadGeometryBinding, _checkerMaterial, Matrix.RotationZ(f) * .Scaling(1.5f));
RenderCommand.SetBlendState(_alphaBlendState);
_logoMaterial.SetVariable("BaseColor", Color.Pink);
Renderer.Submit(_quadGeometryBinding, _logoMaterial, .Translation(0, 0, -1) * .Scaling(2f));
DebugRenderer.Render(_world);
Renderer.EndScene();
basicEffect.ReleaseRef();
}
ColorRGBA _squareColor0 = ColorRGBA.CornflowerBlue;
ColorRGBA _squareColor1;
public override void OnEvent(Event event)
{
_cameraController.OnEvent(event);
EventDispatcher dispatcher = EventDispatcher(event);
dispatcher.Dispatch<ImGuiRenderEvent>(scope (e) => OnImGuiRender(e));
dispatcher.Dispatch<WindowResizeEvent>(scope (e) => OnWindowResize(e));
}
private bool OnImGuiRender(ImGuiRenderEvent e)
{
/*
ImGui.Begin("Test");
var v = ImGui.ColorEdit3("Square Color", ref _squareColor0);
if(v)
{
testMaterial1.SetVariable("BaseColor", _squareColor0);
testMaterial2.SetVariable("BaseColor", ColorRGBA.White - _squareColor0);
}
ImGui.End();
*/
return false;
}
private bool OnWindowResize(WindowResizeEvent e)
{
_depthTarget.ReleaseRef();
_depthTarget = new DepthStencilTarget(_context.SwapChain.Width, _context.SwapChain.Height);
return false;
}
}
class SandboxApp : Application class SandboxApp : Application
{ {
public this() public this()