diff --git a/Kav b/Kav index 66d4e5b..cb0baf0 160000 --- a/Kav +++ b/Kav @@ -1 +1 @@ -Subproject commit 66d4e5bf6e78949f6e5b2fc9eb1983d438047f0b +Subproject commit cb0baf0bf0b2c8c830c239c1566ca7a2fcacced9 diff --git a/KavTest/Components/AmbientLightComponent.cs b/KavTest/Components/AmbientLightComponent.cs new file mode 100644 index 0000000..ba13414 --- /dev/null +++ b/KavTest/Components/AmbientLightComponent.cs @@ -0,0 +1,15 @@ +using Encompass; +using Microsoft.Xna.Framework; + +namespace KavTest.Components +{ + public struct AmbientLightComponent : IComponent + { + public Color Color { get; } + + public AmbientLightComponent(Color color) + { + Color = color; + } + } +} diff --git a/KavTest/Components/ContinuousRotationComponent.cs b/KavTest/Components/ContinuousRotationComponent.cs new file mode 100644 index 0000000..647dafc --- /dev/null +++ b/KavTest/Components/ContinuousRotationComponent.cs @@ -0,0 +1,15 @@ +using Encompass; +using Microsoft.Xna.Framework; + +namespace KavTest +{ + public struct ContinuousRotationComponent : IComponent + { + public Quaternion Quaternion { get; } + + public ContinuousRotationComponent(Vector3 axis, float angle) + { + Quaternion = Quaternion.CreateFromAxisAngle(axis, angle); + } + } +} diff --git a/KavTest/Components/SkyboxComponent.cs b/KavTest/Components/SkyboxComponent.cs new file mode 100644 index 0000000..f7c9566 --- /dev/null +++ b/KavTest/Components/SkyboxComponent.cs @@ -0,0 +1,15 @@ +using Encompass; +using Microsoft.Xna.Framework.Graphics; + +namespace KavTest.Components +{ + public struct SkyboxComponent : IComponent + { + public TextureCube Skybox { get; } + + public SkyboxComponent(TextureCube skybox) + { + Skybox = skybox; + } + } +} diff --git a/KavTest/Content/Skybox/back.jpg b/KavTest/Content/Skybox/back.jpg new file mode 100644 index 0000000..470a679 Binary files /dev/null and b/KavTest/Content/Skybox/back.jpg differ diff --git a/KavTest/Content/Skybox/bottom.jpg b/KavTest/Content/Skybox/bottom.jpg new file mode 100644 index 0000000..893f394 Binary files /dev/null and b/KavTest/Content/Skybox/bottom.jpg differ diff --git a/KavTest/Content/Skybox/front.jpg b/KavTest/Content/Skybox/front.jpg new file mode 100644 index 0000000..4e17b77 Binary files /dev/null and b/KavTest/Content/Skybox/front.jpg differ diff --git a/KavTest/Content/Skybox/left.jpg b/KavTest/Content/Skybox/left.jpg new file mode 100644 index 0000000..5750b91 Binary files /dev/null and b/KavTest/Content/Skybox/left.jpg differ diff --git a/KavTest/Content/Skybox/right.jpg b/KavTest/Content/Skybox/right.jpg new file mode 100644 index 0000000..8963037 Binary files /dev/null and b/KavTest/Content/Skybox/right.jpg differ diff --git a/KavTest/Content/Skybox/top.jpg b/KavTest/Content/Skybox/top.jpg new file mode 100644 index 0000000..4db3c2a Binary files /dev/null and b/KavTest/Content/Skybox/top.jpg differ diff --git a/KavTest/Content/ToonShadeRuins.glb b/KavTest/Content/ToonShadeRuins.glb new file mode 100644 index 0000000..1bb4294 --- /dev/null +++ b/KavTest/Content/ToonShadeRuins.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7354917c7556bc5d6494f036215b6aad7a3303e27af084901faf5f4a3bdf7323 +size 1729868 diff --git a/KavTest/Content/bluetorus.glb b/KavTest/Content/bluetorus.glb new file mode 100644 index 0000000..d28ddb4 --- /dev/null +++ b/KavTest/Content/bluetorus.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ca325ede4de44908d99a68085b4af200aed5a39bacd54dab1ba6cd49913b3f1 +size 28768 diff --git a/KavTest/Content/pinkcone.glb b/KavTest/Content/pinkcone.glb new file mode 100644 index 0000000..f257c48 --- /dev/null +++ b/KavTest/Content/pinkcone.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:171a813b5bd49f44ab74aa554e3b5a65ba60dcb971e6cfa6143d653ee08cda74 +size 3892 diff --git a/KavTest/Content/redcylinder.glb b/KavTest/Content/redcylinder.glb new file mode 100644 index 0000000..4557b6b --- /dev/null +++ b/KavTest/Content/redcylinder.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:89b6b7fc5973c17bb6ce80993d52f5f1542e106693ce227bb629d50353dad172 +size 8344 diff --git a/KavTest/Engines/AngularVelocityEngine.cs b/KavTest/Engines/AngularVelocityEngine.cs index a8ce9fe..66efa09 100644 --- a/KavTest/Engines/AngularVelocityEngine.cs +++ b/KavTest/Engines/AngularVelocityEngine.cs @@ -5,7 +5,7 @@ using Microsoft.Xna.Framework; namespace KavTest.Engines { - [Reads(typeof(AngularVelocityComponent))] + [Reads(typeof(AngularVelocityComponent), typeof(ContinuousRotationComponent))] [Sends(typeof(LocalRotationMessage))] public class AngularVelocityEngine : Engine { @@ -18,6 +18,12 @@ namespace KavTest.Engines SendMessage(new LocalRotationMessage(entity, Quaternion.CreateFromYawPitchRoll(angularVelocity.X, angularVelocity.Y, angularVelocity.Z))); } + + foreach (var entity in ReadEntities()) + { + ref readonly var rotationComponent = ref GetComponent(entity); + SendMessage(new LocalRotationMessage(entity, rotationComponent.Quaternion)); + } } } } diff --git a/KavTest/Engines/Spawners/DirectionalLightSpawner.cs b/KavTest/Engines/Spawners/DirectionalLightSpawner.cs index 04186e8..9a05f2e 100644 --- a/KavTest/Engines/Spawners/DirectionalLightSpawner.cs +++ b/KavTest/Engines/Spawners/DirectionalLightSpawner.cs @@ -13,6 +13,8 @@ namespace KavTest.Spawners AddComponent(entity, new Transform3DComponent(new Transform3D(Vector3.Zero, message.Orientation))); AddComponent(entity, new DirectionalLightComponent(message.Color, message.Intensity)); + var forward = Matrix.CreateFromQuaternion(message.Orientation).Forward; + AddComponent(entity, new ContinuousRotationComponent(forward, 0.01f)); } } } diff --git a/KavTest/KavTestGame.cs b/KavTest/KavTestGame.cs index ed3d800..b53432c 100644 --- a/KavTest/KavTestGame.cs +++ b/KavTest/KavTestGame.cs @@ -23,8 +23,8 @@ namespace KavTest public KavTestGame() { graphics = new GraphicsDeviceManager(this); - graphics.PreferredBackBufferWidth = 1280; - graphics.PreferredBackBufferHeight = 720; + graphics.PreferredBackBufferWidth = 1600; + graphics.PreferredBackBufferHeight = 900; graphics.PreferMultiSampling = false; Content.RootDirectory = "Content"; @@ -50,8 +50,17 @@ namespace KavTest var rustyBallModel = Kav.ModelLoader.Load( GraphicsDevice, - Smuggler.Importer.ImportGLB(GraphicsDevice, File.OpenRead("Content/rustysphere.glb")) + Smuggler.Importer.ImportGLB( + GraphicsDevice, + File.OpenRead("Content/rustysphere.glb") + ) ); + rustyBallModel.DisableNormalMaps(); + rustyBallModel.DisableAlbedoMaps(); + rustyBallModel.DisableMetallicRoughnessMaps(); + rustyBallModel.Albedo = Color.DeepSkyBlue; + rustyBallModel.Metallic = 0.5f; + rustyBallModel.Roughness = 0.284f; var lightBulbModel = Kav.ModelLoader.Load( GraphicsDevice, @@ -62,12 +71,104 @@ namespace KavTest GraphicsDevice, Smuggler.Importer.ImportGLB(GraphicsDevice, File.OpenRead("Content/floor.glb")) ); + floorModel.Metallic = 0f; + floorModel.Roughness = 0f; var avocadoModel = Kav.ModelLoader.Load( GraphicsDevice, Smuggler.Importer.ImportGLB(GraphicsDevice, File.OpenRead("Content/avocado.glb")) ); + var redCylinderModel = Kav.ModelLoader.Load( + GraphicsDevice, + Smuggler.Importer.ImportGLB( + GraphicsDevice, + File.OpenRead("Content/redcylinder.glb") + ) + ); + + var pinkConeModel = Kav.ModelLoader.Load( + GraphicsDevice, + Smuggler.Importer.ImportGLB( + GraphicsDevice, + File.OpenRead("Content/pinkcone.glb") + ) + ); + + var blueTorusModel = Kav.ModelLoader.Load( + GraphicsDevice, + Smuggler.Importer.ImportGLB( + GraphicsDevice, + File.OpenRead("Content/bluetorus.glb") + ) + ); + + var cubeModel = Kav.ModelLoader.Load( + GraphicsDevice, + Smuggler.Importer.ImportGLB( + GraphicsDevice, + File.OpenRead("Content/cube.glb") + ) + ); + + var toonShadeRuinsModel = Kav.ModelLoader.Load( + GraphicsDevice, + Smuggler.Importer.ImportGLB( + GraphicsDevice, + File.OpenRead("Content/ToonShadeRuins.glb") + ) + ); + + Texture2D.TextureDataFromStreamEXT( + File.OpenRead("Content/Skybox/front.jpg"), + out var skyboxSize, + out _, + out byte[] frontPixels + ); + + Texture2D.TextureDataFromStreamEXT( + File.OpenRead("Content/Skybox/back.jpg"), + out _, + out _, + out byte[] backPixels + ); + + Texture2D.TextureDataFromStreamEXT( + File.OpenRead("Content/Skybox/right.jpg"), + out _, + out _, + out byte[] rightPixels + ); + + Texture2D.TextureDataFromStreamEXT( + File.OpenRead("Content/Skybox/left.jpg"), + out _, + out _, + out byte[] leftPixels + ); + + Texture2D.TextureDataFromStreamEXT( + File.OpenRead("Content/Skybox/top.jpg"), + out _, + out _, + out byte[] topPixels + ); + + Texture2D.TextureDataFromStreamEXT( + File.OpenRead("Content/Skybox/bottom.jpg"), + out _, + out _, + out byte[] bottomPixels + ); + + var skybox = new TextureCube(GraphicsDevice, skyboxSize, false, SurfaceFormat.Color); + skybox.SetData(CubeMapFace.PositiveZ, frontPixels); + skybox.SetData(CubeMapFace.NegativeZ, backPixels); + skybox.SetData(CubeMapFace.PositiveX, rightPixels); + skybox.SetData(CubeMapFace.NegativeX, leftPixels); + skybox.SetData(CubeMapFace.PositiveY, topPixels); + skybox.SetData(CubeMapFace.NegativeY, bottomPixels); + WorldBuilder.AddEngine(new InputEngine(this)); WorldBuilder.AddEngine(new AngularVelocityEngine()); WorldBuilder.AddEngine(new MoveAlongCurve3DEngine()); @@ -94,35 +195,97 @@ namespace KavTest // new Vector3(-1, 1, 1) // )); + // WorldBuilder.SendMessage(new StaticModelSpawnMessage( + // new Transform3D(new Vector3(0, 1, 0), Quaternion.Identity, new Vector3(1f, 1f, 1f)), + // rustyBallModel + // )); + WorldBuilder.SendMessage(new StaticModelSpawnMessage( new Transform3D(new Vector3(0, -3, 0), Quaternion.Identity, new Vector3(10f, 1f, 10f)), floorModel )); - var entity = WorldBuilder.CreateEntity(); - - WorldBuilder.SetComponent(entity, new Transform3DComponent( + WorldBuilder.SendMessage(new StaticModelSpawnMessage( new Transform3D( new Vector3(0, 1, 0), - Quaternion.CreateFromAxisAngle(Vector3.Right, -Microsoft.Xna.Framework.MathHelper.PiOver2), - new Vector3(30, 30, 30)) + Quaternion.CreateFromAxisAngle( + Vector3.Right, + -Microsoft.Xna.Framework.MathHelper.PiOver2 + ), + new Vector3(1f, 1f, 1f) + ), + redCylinderModel + )); + + WorldBuilder.SendMessage(new StaticModelSpawnMessage( + new Transform3D( + new Vector3(-3, 1, 0), + Quaternion.CreateFromAxisAngle( + Vector3.Right, + -Microsoft.Xna.Framework.MathHelper.PiOver2 + ), + new Vector3(1f, 1f, 1f) + ), + blueTorusModel + )); + + WorldBuilder.SendMessage(new StaticModelSpawnMessage( + new Transform3D( + new Vector3(3, 1, 0), + Quaternion.CreateFromAxisAngle( + Vector3.Right, + -Microsoft.Xna.Framework.MathHelper.PiOver2 + ), + new Vector3(1f, 1f, 1f) + ), + cubeModel + )); + + // WorldBuilder.SendMessage(new StaticModelSpawnMessage( + // Transform3D.Identity, + // toonShadeRuinsModel + // )); + + var lightEntity = WorldBuilder.CreateEntity(); + WorldBuilder.SetComponent( + lightEntity, + new Transform3DComponent( + new Transform3D( + new Vector3(0, 3, 3), + Quaternion.Identity, + new Vector3(0.1f, 0.1f, 0.1f) + ) ) ); - WorldBuilder.SetComponent(entity, new ModelComponent(avocadoModel)); + WorldBuilder.SetComponent( + lightEntity, + new PointLightComponent(Color.Blue, 1000f) + ); + WorldBuilder.SetComponent( + lightEntity, + new ModelComponent(cubeModel) + ); - for (var i = 0; i < 1; i++) - { - var start = RandomHelper.RandomVector3(-5, 5); + // for (var i = 0; i < 1; i++) + // { + // var start = RandomHelper.RandomVector3(2, 5); - WorldBuilder.SendMessage(new LightBulbSpawnMessage( - new Transform3D(start.ToXNAVector(), Quaternion.Identity, new Vector3(0.1f, 0.1f, 0.1f)), - RandomHelper.RandomColor(), - 1f, - RandomHelper.RandomLoop(start, -15, 15, 3, 10) - )); - } + // WorldBuilder.SendMessage(new LightBulbSpawnMessage( + // new Transform3D(start.ToXNAVector(), Quaternion.Identity, new Vector3(0.1f, 0.1f, 0.1f)), + // RandomHelper.RandomColor(), + // 5f, + // RandomHelper.RandomLoop(start, 2, 5, 3, 10) + // )); + // } + + var ambientLightEntity = WorldBuilder.CreateEntity(); + + WorldBuilder.SetComponent(ambientLightEntity, new AmbientLightComponent( + new Color(0.4f, 0.4f, 0.4f) + )); WorldBuilder.SendMessage(new DirectionalLightSpawnMessage( + //Quaternion.CreateFromAxisAngle(Vector3.Right, Microsoft.Xna.Framework.MathHelper.Pi / 3f), Quaternion.CreateFromAxisAngle(Vector3.Right, Microsoft.Xna.Framework.MathHelper.PiOver4), Color.LightGoldenrodYellow, 0.7f @@ -155,6 +318,11 @@ namespace KavTest 100f )); + var skyboxEntity = WorldBuilder.CreateEntity(); + WorldBuilder.SetComponent(skyboxEntity, new SkyboxComponent( + skybox + )); + World = WorldBuilder.Build(); } diff --git a/KavTest/Renderers/SceneRenderer.cs b/KavTest/Renderers/SceneRenderer.cs index 0bfe6c0..9384304 100644 --- a/KavTest/Renderers/SceneRenderer.cs +++ b/KavTest/Renderers/SceneRenderer.cs @@ -19,6 +19,7 @@ namespace KavTest.Renderers { foreach (var entity in ReadEntitiesAsEnumerable()) { + /* FIXME: this transformation should definitely not go here */ var transformComponent = GetComponent(entity); var modelComponent = GetComponent(entity); if (HasComponent(entity)) @@ -29,11 +30,8 @@ namespace KavTest.Renderers { foreach (var meshPart in mesh.MeshParts) { - if (meshPart.Effect is DeferredPBR_GBufferEffect gBufferEffect) - { - gBufferEffect.AlbedoTexture = null; - gBufferEffect.Albedo = overrideAlbedoComponent.Color; - } + meshPart.DisableAlbedoMap = true; + meshPart.Albedo = overrideAlbedoComponent.Color; } } } @@ -42,6 +40,21 @@ namespace KavTest.Renderers } } + private AmbientLight AmbientLight + { + get + { + if (SomeComponent()) + { + return new AmbientLight(ReadComponent().Color); + } + else + { + return new AmbientLight(Color.Black); + } + } + } + private IEnumerable PointLights { get @@ -118,11 +131,21 @@ namespace KavTest.Renderers // ); // } - Renderer.DeferredRender( + // Renderer.DeferredRender( + // camera, + // ModelTransforms, + // AmbientLight, + // PointLights, + // DirectionalLight() + // ); + + Renderer.DeferredToonRender( camera, ModelTransforms, + AmbientLight, PointLights, - DirectionalLight() + DirectionalLight(), + ReadComponent().Skybox ); // foreach (var directionalLight in DirectionalLights)