billboarding implementation
parent
1c679b8323
commit
f08c89e327
|
@ -17,13 +17,13 @@
|
||||||
"type": "mono",
|
"type": "mono",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "Build: Mono Debug",
|
"preLaunchTask": "Build: Mono Debug",
|
||||||
"program": "${workspaceFolder}/KavTest/bin/Debug/net48/KavTest.exe",
|
"program": "${workspaceFolder}/KavTest/bin/x64/Debug/net48/KavTest.exe",
|
||||||
"args": [],
|
"args": [],
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "${workspaceFolder}/KavTest/bin/Debug/net48/lib64",
|
"LD_LIBRARY_PATH": "./lib64",
|
||||||
"DYLD_LIBRARY_PATH": "${workspaceFolder}/KavTest/bin/Debug/net48/osx"
|
"DYLD_LIBRARY_PATH": "./osx"
|
||||||
},
|
},
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}/KavTest/bin/x64/Debug/net48",
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
"internalConsoleOptions": "neverOpen"
|
"internalConsoleOptions": "neverOpen"
|
||||||
},
|
},
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
"LD_LIBRARY_PATH": "./lib64",
|
"LD_LIBRARY_PATH": "./lib64",
|
||||||
"DYLD_LIBRARY_PATH": "./osx"
|
"DYLD_LIBRARY_PATH": "./osx"
|
||||||
},
|
},
|
||||||
"cwd": "${workspaceFolder}/KavTest/bin/Release/net48"
|
"cwd": "${workspaceFolder}/KavTest/bin/x64/Release/net48"
|
||||||
},
|
},
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"group": {
|
"group": {
|
||||||
|
@ -93,9 +93,10 @@
|
||||||
"options": {
|
"options": {
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "./lib64",
|
"LD_LIBRARY_PATH": "./lib64",
|
||||||
"DYLD_LIBRARY_PATH": "./osx"
|
"DYLD_LIBRARY_PATH": "./osx",
|
||||||
|
"FNA3D_FORCE_DRIVER": "Vulkan"
|
||||||
},
|
},
|
||||||
"cwd": "${workspaceFolder}/KavTest/bin/Debug/net48"
|
"cwd": "${workspaceFolder}/KavTest/bin/x64/Debug/net48"
|
||||||
},
|
},
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"group": {
|
"group": {
|
||||||
|
|
2
Kav
2
Kav
|
@ -1 +1 @@
|
||||||
Subproject commit d83aacd57f692c9732987fe755cc860fee3c5456
|
Subproject commit acaafdcdcd3d1e8c7262879d70e0cf5c7c1f4c78
|
|
@ -0,0 +1,19 @@
|
||||||
|
using Encompass;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace KavTest.Components
|
||||||
|
{
|
||||||
|
public struct SpotLightComponent : IComponent
|
||||||
|
{
|
||||||
|
public Color Color { get; }
|
||||||
|
public float Intensity { get; }
|
||||||
|
public float Angle { get; }
|
||||||
|
|
||||||
|
public SpotLightComponent(Color color, float intensity, float angleInRadians)
|
||||||
|
{
|
||||||
|
Color = color;
|
||||||
|
Intensity = intensity;
|
||||||
|
Angle = angleInRadians;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using Encompass;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace KavTest
|
||||||
|
{
|
||||||
|
public struct SpriteComponent : IComponent
|
||||||
|
{
|
||||||
|
public Texture2D Texture { get; }
|
||||||
|
public Vector2 Origin { get; }
|
||||||
|
|
||||||
|
public SpriteComponent(Texture2D texture, Vector2 origin)
|
||||||
|
{
|
||||||
|
Texture = texture;
|
||||||
|
Origin = origin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,25 @@
|
||||||
|
using Encompass;
|
||||||
|
using KavTest.Components;
|
||||||
|
using KavTest.Messages;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace KavTest.Spawners
|
||||||
|
{
|
||||||
|
public class BillboardSpriteSpawner : Spawner<BillboardSpriteSpawnMessage>
|
||||||
|
{
|
||||||
|
protected override void Spawn(in BillboardSpriteSpawnMessage message)
|
||||||
|
{
|
||||||
|
var entity = CreateEntity();
|
||||||
|
|
||||||
|
var transform = new Transform3D(
|
||||||
|
message.Position,
|
||||||
|
Quaternion.Identity,
|
||||||
|
new Vector3(message.Scale, 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
AddComponent(entity, new Transform3DComponent(transform));
|
||||||
|
AddComponent(entity, new SpriteComponent(message.Texture, message.Origin));
|
||||||
|
AddComponent(entity, new AngularVelocityComponent(new Vector3(2f, 0, 0)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace KavTest.Extensions
|
||||||
|
{
|
||||||
|
public static class QuaternionExtensions
|
||||||
|
{
|
||||||
|
public static Vector3 EulerAngles(this Quaternion q)
|
||||||
|
{
|
||||||
|
Vector3 angles;
|
||||||
|
|
||||||
|
double sinr_cosp = 2 * (q.W * q.X + q.Y * q.Z);
|
||||||
|
double cosr_cosp = 1 - 2 * (q.X * q.X + q.Y * q.Y);
|
||||||
|
angles.X = (float) System.Math.Atan2(sinr_cosp, cosr_cosp);
|
||||||
|
|
||||||
|
double sinp = 2 * (q.W * q.Y - q.Z * q.X);
|
||||||
|
if (System.Math.Abs(sinp) >= 1)
|
||||||
|
{
|
||||||
|
angles.Y = (float) System.Math.PI / 2 * System.Math.Sign(sinp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
angles.Y = (float) System.Math.Asin(sinp);
|
||||||
|
}
|
||||||
|
|
||||||
|
double siny_cosp = 2 * (q.W * q.Z + q.X * q.Y);
|
||||||
|
double cosy_cosp = 1 - 2 * (q.Y * q.Y + q.Z * q.Z);
|
||||||
|
angles.Z = (float) System.Math.Atan2(siny_cosp, cosy_cosp);
|
||||||
|
|
||||||
|
return angles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,7 +30,7 @@ namespace KavTest
|
||||||
|
|
||||||
Window.AllowUserResizing = true;
|
Window.AllowUserResizing = true;
|
||||||
IsMouseVisible = true;
|
IsMouseVisible = true;
|
||||||
|
|
||||||
Microsoft.Xna.Framework.Input.Mouse.IsRelativeMouseModeEXT = true;
|
Microsoft.Xna.Framework.Input.Mouse.IsRelativeMouseModeEXT = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ namespace KavTest
|
||||||
var rustyBallModel = Kav.ModelLoader.Load(
|
var rustyBallModel = Kav.ModelLoader.Load(
|
||||||
GraphicsDevice,
|
GraphicsDevice,
|
||||||
Smuggler.Importer.ImportGLB(
|
Smuggler.Importer.ImportGLB(
|
||||||
GraphicsDevice,
|
GraphicsDevice,
|
||||||
File.OpenRead("Content/rustysphere.glb")
|
File.OpenRead("Content/rustysphere.glb")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -169,6 +169,8 @@ namespace KavTest
|
||||||
skybox.SetData(CubeMapFace.PositiveY, topPixels);
|
skybox.SetData(CubeMapFace.PositiveY, topPixels);
|
||||||
skybox.SetData(CubeMapFace.NegativeY, bottomPixels);
|
skybox.SetData(CubeMapFace.NegativeY, bottomPixels);
|
||||||
|
|
||||||
|
var mushroomGuyTexture = Texture2D.FromStream(GraphicsDevice, new FileStream("Content/Sprites/mushroomguy.png", FileMode.Open));
|
||||||
|
|
||||||
WorldBuilder.AddEngine(new InputEngine(this));
|
WorldBuilder.AddEngine(new InputEngine(this));
|
||||||
WorldBuilder.AddEngine(new AngularVelocityEngine());
|
WorldBuilder.AddEngine(new AngularVelocityEngine());
|
||||||
WorldBuilder.AddEngine(new MoveAlongCurve3DEngine());
|
WorldBuilder.AddEngine(new MoveAlongCurve3DEngine());
|
||||||
|
@ -178,6 +180,7 @@ namespace KavTest
|
||||||
WorldBuilder.AddEngine(new LightBulbSpawner(lightBulbModel));
|
WorldBuilder.AddEngine(new LightBulbSpawner(lightBulbModel));
|
||||||
WorldBuilder.AddEngine(new StaticModelSpawner());
|
WorldBuilder.AddEngine(new StaticModelSpawner());
|
||||||
WorldBuilder.AddEngine(new DirectionalLightSpawner());
|
WorldBuilder.AddEngine(new DirectionalLightSpawner());
|
||||||
|
WorldBuilder.AddEngine(new BillboardSpriteSpawner());
|
||||||
WorldBuilder.AddGeneralRenderer(new SceneRenderer(GraphicsDevice), 0);
|
WorldBuilder.AddGeneralRenderer(new SceneRenderer(GraphicsDevice), 0);
|
||||||
|
|
||||||
// WorldBuilder.SendMessage(new RustyBallSpawnMessage(
|
// WorldBuilder.SendMessage(new RustyBallSpawnMessage(
|
||||||
|
@ -207,11 +210,11 @@ namespace KavTest
|
||||||
|
|
||||||
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
||||||
new Transform3D(
|
new Transform3D(
|
||||||
new Vector3(0, 1, 0),
|
new Vector3(0, 1, 0),
|
||||||
Quaternion.CreateFromAxisAngle(
|
Quaternion.CreateFromAxisAngle(
|
||||||
Vector3.Right,
|
Vector3.Right,
|
||||||
-Microsoft.Xna.Framework.MathHelper.PiOver2
|
-Microsoft.Xna.Framework.MathHelper.PiOver2
|
||||||
),
|
),
|
||||||
new Vector3(1f, 1f, 1f)
|
new Vector3(1f, 1f, 1f)
|
||||||
),
|
),
|
||||||
redCylinderModel
|
redCylinderModel
|
||||||
|
@ -219,11 +222,11 @@ namespace KavTest
|
||||||
|
|
||||||
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
||||||
new Transform3D(
|
new Transform3D(
|
||||||
new Vector3(-3, 1, 0),
|
new Vector3(-3, 1, 0),
|
||||||
Quaternion.CreateFromAxisAngle(
|
Quaternion.CreateFromAxisAngle(
|
||||||
Vector3.Right,
|
Vector3.Right,
|
||||||
-Microsoft.Xna.Framework.MathHelper.PiOver2
|
-Microsoft.Xna.Framework.MathHelper.PiOver2
|
||||||
),
|
),
|
||||||
new Vector3(1f, 1f, 1f)
|
new Vector3(1f, 1f, 1f)
|
||||||
),
|
),
|
||||||
blueTorusModel
|
blueTorusModel
|
||||||
|
@ -231,16 +234,24 @@ namespace KavTest
|
||||||
|
|
||||||
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
||||||
new Transform3D(
|
new Transform3D(
|
||||||
new Vector3(3, 1, 0),
|
new Vector3(3, 1, 0),
|
||||||
Quaternion.CreateFromAxisAngle(
|
Quaternion.CreateFromAxisAngle(
|
||||||
Vector3.Right,
|
Vector3.Right,
|
||||||
-Microsoft.Xna.Framework.MathHelper.PiOver2
|
-Microsoft.Xna.Framework.MathHelper.PiOver2
|
||||||
),
|
),
|
||||||
new Vector3(1f, 1f, 1f)
|
new Vector3(1f, 1f, 1f)
|
||||||
),
|
),
|
||||||
cubeModel
|
cubeModel
|
||||||
));
|
));
|
||||||
|
|
||||||
|
WorldBuilder.SendMessage(new BillboardSpriteSpawnMessage(
|
||||||
|
mushroomGuyTexture,
|
||||||
|
new Vector3(3, 1, 10),
|
||||||
|
Vector2.Zero,
|
||||||
|
0,
|
||||||
|
Vector2.One
|
||||||
|
));
|
||||||
|
|
||||||
// WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
// WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
||||||
// Transform3D.Identity,
|
// Transform3D.Identity,
|
||||||
// toonShadeRuinsModel
|
// toonShadeRuinsModel
|
||||||
|
@ -251,8 +262,8 @@ namespace KavTest
|
||||||
// lightEntity,
|
// lightEntity,
|
||||||
// new Transform3DComponent(
|
// new Transform3DComponent(
|
||||||
// new Transform3D(
|
// new Transform3D(
|
||||||
// new Vector3(0, 3, 3),
|
// new Vector3(0, 3, 3),
|
||||||
// Quaternion.Identity,
|
// Quaternion.Identity,
|
||||||
// new Vector3(0.1f, 0.1f, 0.1f)
|
// new Vector3(0.1f, 0.1f, 0.1f)
|
||||||
// )
|
// )
|
||||||
// )
|
// )
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
using Encompass;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace KavTest.Messages
|
||||||
|
{
|
||||||
|
public struct BillboardSpriteSpawnMessage : IMessage
|
||||||
|
{
|
||||||
|
public Texture2D Texture { get; }
|
||||||
|
public Vector3 Position { get; }
|
||||||
|
public Vector2 Origin { get; }
|
||||||
|
public float Rotation { get; }
|
||||||
|
public Vector2 Scale { get; }
|
||||||
|
|
||||||
|
public BillboardSpriteSpawnMessage(
|
||||||
|
Texture2D texture,
|
||||||
|
Vector3 position,
|
||||||
|
float rotation,
|
||||||
|
Vector2 scale
|
||||||
|
) {
|
||||||
|
Texture = texture;
|
||||||
|
Origin = new Vector2(texture.Width / 2, texture.Height / 2);
|
||||||
|
Position = position;
|
||||||
|
Rotation = rotation;
|
||||||
|
Scale = scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,7 +11,12 @@ namespace KavTest.Renderers
|
||||||
{
|
{
|
||||||
public class SceneRenderer : GeneralRenderer
|
public class SceneRenderer : GeneralRenderer
|
||||||
{
|
{
|
||||||
|
private GraphicsDevice GraphicsDevice { get; }
|
||||||
|
private SpriteBatch SpriteBatch { get; }
|
||||||
|
|
||||||
private Kav.Renderer Renderer { get; }
|
private Kav.Renderer Renderer { get; }
|
||||||
|
private RenderTarget2D DeferredTarget { get; }
|
||||||
|
private RenderTarget2D BillboardTarget { get; }
|
||||||
|
|
||||||
private IEnumerable<(Kav.Model, Matrix)> ModelTransforms
|
private IEnumerable<(Kav.Model, Matrix)> ModelTransforms
|
||||||
{
|
{
|
||||||
|
@ -86,15 +91,62 @@ namespace KavTest.Renderers
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IEnumerable<Sprite> Sprites()
|
||||||
|
{
|
||||||
|
foreach (var entity in ReadEntitiesAsEnumerable<SpriteComponent>())
|
||||||
|
{
|
||||||
|
var transformComponent = GetComponent<Transform3DComponent>(entity);
|
||||||
|
var spriteComponent = GetComponent<SpriteComponent>(entity);
|
||||||
|
|
||||||
|
var angles = transformComponent.Transform.Orientation.EulerAngles();
|
||||||
|
|
||||||
|
yield return new Sprite(
|
||||||
|
spriteComponent.Texture,
|
||||||
|
transformComponent.Transform.Position,
|
||||||
|
spriteComponent.Origin,
|
||||||
|
angles.X,
|
||||||
|
new Vector2(
|
||||||
|
transformComponent.Transform.Scale.X,
|
||||||
|
transformComponent.Transform.Scale.Y
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public SceneRenderer(GraphicsDevice graphicsDevice)
|
public SceneRenderer(GraphicsDevice graphicsDevice)
|
||||||
{
|
{
|
||||||
Renderer = new Kav.Renderer(
|
Renderer = new Kav.Renderer(
|
||||||
graphicsDevice,
|
graphicsDevice,
|
||||||
graphicsDevice.PresentationParameters.BackBufferWidth,
|
graphicsDevice.PresentationParameters.BackBufferWidth,
|
||||||
graphicsDevice.PresentationParameters.BackBufferHeight,
|
graphicsDevice.PresentationParameters.BackBufferHeight,
|
||||||
4,
|
4,
|
||||||
4096
|
4096
|
||||||
);
|
);
|
||||||
|
|
||||||
|
DeferredTarget = new RenderTarget2D(
|
||||||
|
graphicsDevice,
|
||||||
|
graphicsDevice.PresentationParameters.BackBufferWidth,
|
||||||
|
graphicsDevice.PresentationParameters.BackBufferHeight,
|
||||||
|
false,
|
||||||
|
SurfaceFormat.Color,
|
||||||
|
DepthFormat.Depth24Stencil8,
|
||||||
|
0,
|
||||||
|
RenderTargetUsage.PreserveContents
|
||||||
|
);
|
||||||
|
|
||||||
|
BillboardTarget = new RenderTarget2D(
|
||||||
|
graphicsDevice,
|
||||||
|
graphicsDevice.PresentationParameters.BackBufferWidth,
|
||||||
|
graphicsDevice.PresentationParameters.BackBufferHeight,
|
||||||
|
false,
|
||||||
|
SurfaceFormat.Color,
|
||||||
|
DepthFormat.Depth24Stencil8,
|
||||||
|
0,
|
||||||
|
RenderTargetUsage.PreserveContents
|
||||||
|
);
|
||||||
|
|
||||||
|
GraphicsDevice = graphicsDevice;
|
||||||
|
SpriteBatch = new SpriteBatch(GraphicsDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Render()
|
public override void Render()
|
||||||
|
@ -140,6 +192,7 @@ namespace KavTest.Renderers
|
||||||
// );
|
// );
|
||||||
|
|
||||||
Renderer.DeferredToonRender(
|
Renderer.DeferredToonRender(
|
||||||
|
DeferredTarget,
|
||||||
camera,
|
camera,
|
||||||
ModelTransforms,
|
ModelTransforms,
|
||||||
AmbientLight,
|
AmbientLight,
|
||||||
|
@ -148,6 +201,19 @@ namespace KavTest.Renderers
|
||||||
ReadComponent<SkyboxComponent>().Skybox
|
ReadComponent<SkyboxComponent>().Skybox
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Renderer.BillboardSpriteRender(
|
||||||
|
BillboardTarget,
|
||||||
|
camera,
|
||||||
|
ModelTransforms,
|
||||||
|
Sprites()
|
||||||
|
);
|
||||||
|
|
||||||
|
GraphicsDevice.SetRenderTarget(null);
|
||||||
|
SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null);
|
||||||
|
SpriteBatch.Draw(DeferredTarget, Vector2.Zero, Color.White);
|
||||||
|
SpriteBatch.Draw(BillboardTarget, Vector2.Zero, Color.White);
|
||||||
|
SpriteBatch.End();
|
||||||
|
|
||||||
// foreach (var directionalLight in DirectionalLights)
|
// foreach (var directionalLight in DirectionalLights)
|
||||||
// {
|
// {
|
||||||
// Renderer.DepthRender(
|
// Renderer.DepthRender(
|
||||||
|
|
Loading…
Reference in New Issue