billboarding implementation
parent
1c679b8323
commit
f08c89e327
|
@ -17,13 +17,13 @@
|
|||
"type": "mono",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "Build: Mono Debug",
|
||||
"program": "${workspaceFolder}/KavTest/bin/Debug/net48/KavTest.exe",
|
||||
"program": "${workspaceFolder}/KavTest/bin/x64/Debug/net48/KavTest.exe",
|
||||
"args": [],
|
||||
"env": {
|
||||
"LD_LIBRARY_PATH": "${workspaceFolder}/KavTest/bin/Debug/net48/lib64",
|
||||
"DYLD_LIBRARY_PATH": "${workspaceFolder}/KavTest/bin/Debug/net48/osx"
|
||||
"LD_LIBRARY_PATH": "./lib64",
|
||||
"DYLD_LIBRARY_PATH": "./osx"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"cwd": "${workspaceFolder}/KavTest/bin/x64/Debug/net48",
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen"
|
||||
},
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
"LD_LIBRARY_PATH": "./lib64",
|
||||
"DYLD_LIBRARY_PATH": "./osx"
|
||||
},
|
||||
"cwd": "${workspaceFolder}/KavTest/bin/Release/net48"
|
||||
"cwd": "${workspaceFolder}/KavTest/bin/x64/Release/net48"
|
||||
},
|
||||
"type": "process",
|
||||
"group": {
|
||||
|
@ -93,9 +93,10 @@
|
|||
"options": {
|
||||
"env": {
|
||||
"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",
|
||||
"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;
|
||||
IsMouseVisible = true;
|
||||
|
||||
|
||||
Microsoft.Xna.Framework.Input.Mouse.IsRelativeMouseModeEXT = true;
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ namespace KavTest
|
|||
var rustyBallModel = Kav.ModelLoader.Load(
|
||||
GraphicsDevice,
|
||||
Smuggler.Importer.ImportGLB(
|
||||
GraphicsDevice,
|
||||
GraphicsDevice,
|
||||
File.OpenRead("Content/rustysphere.glb")
|
||||
)
|
||||
);
|
||||
|
@ -169,6 +169,8 @@ namespace KavTest
|
|||
skybox.SetData(CubeMapFace.PositiveY, topPixels);
|
||||
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 AngularVelocityEngine());
|
||||
WorldBuilder.AddEngine(new MoveAlongCurve3DEngine());
|
||||
|
@ -178,6 +180,7 @@ namespace KavTest
|
|||
WorldBuilder.AddEngine(new LightBulbSpawner(lightBulbModel));
|
||||
WorldBuilder.AddEngine(new StaticModelSpawner());
|
||||
WorldBuilder.AddEngine(new DirectionalLightSpawner());
|
||||
WorldBuilder.AddEngine(new BillboardSpriteSpawner());
|
||||
WorldBuilder.AddGeneralRenderer(new SceneRenderer(GraphicsDevice), 0);
|
||||
|
||||
// WorldBuilder.SendMessage(new RustyBallSpawnMessage(
|
||||
|
@ -207,11 +210,11 @@ namespace KavTest
|
|||
|
||||
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
||||
new Transform3D(
|
||||
new Vector3(0, 1, 0),
|
||||
new Vector3(0, 1, 0),
|
||||
Quaternion.CreateFromAxisAngle(
|
||||
Vector3.Right,
|
||||
Vector3.Right,
|
||||
-Microsoft.Xna.Framework.MathHelper.PiOver2
|
||||
),
|
||||
),
|
||||
new Vector3(1f, 1f, 1f)
|
||||
),
|
||||
redCylinderModel
|
||||
|
@ -219,11 +222,11 @@ namespace KavTest
|
|||
|
||||
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
||||
new Transform3D(
|
||||
new Vector3(-3, 1, 0),
|
||||
new Vector3(-3, 1, 0),
|
||||
Quaternion.CreateFromAxisAngle(
|
||||
Vector3.Right,
|
||||
Vector3.Right,
|
||||
-Microsoft.Xna.Framework.MathHelper.PiOver2
|
||||
),
|
||||
),
|
||||
new Vector3(1f, 1f, 1f)
|
||||
),
|
||||
blueTorusModel
|
||||
|
@ -231,16 +234,24 @@ namespace KavTest
|
|||
|
||||
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
||||
new Transform3D(
|
||||
new Vector3(3, 1, 0),
|
||||
new Vector3(3, 1, 0),
|
||||
Quaternion.CreateFromAxisAngle(
|
||||
Vector3.Right,
|
||||
Vector3.Right,
|
||||
-Microsoft.Xna.Framework.MathHelper.PiOver2
|
||||
),
|
||||
),
|
||||
new Vector3(1f, 1f, 1f)
|
||||
),
|
||||
cubeModel
|
||||
));
|
||||
|
||||
|
||||
WorldBuilder.SendMessage(new BillboardSpriteSpawnMessage(
|
||||
mushroomGuyTexture,
|
||||
new Vector3(3, 1, 10),
|
||||
Vector2.Zero,
|
||||
0,
|
||||
Vector2.One
|
||||
));
|
||||
|
||||
// WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
||||
// Transform3D.Identity,
|
||||
// toonShadeRuinsModel
|
||||
|
@ -251,8 +262,8 @@ namespace KavTest
|
|||
// lightEntity,
|
||||
// new Transform3DComponent(
|
||||
// new Transform3D(
|
||||
// new Vector3(0, 3, 3),
|
||||
// Quaternion.Identity,
|
||||
// new Vector3(0, 3, 3),
|
||||
// Quaternion.Identity,
|
||||
// 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
|
||||
{
|
||||
private GraphicsDevice GraphicsDevice { get; }
|
||||
private SpriteBatch SpriteBatch { get; }
|
||||
|
||||
private Kav.Renderer Renderer { get; }
|
||||
private RenderTarget2D DeferredTarget { get; }
|
||||
private RenderTarget2D BillboardTarget { get; }
|
||||
|
||||
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)
|
||||
{
|
||||
Renderer = new Kav.Renderer(
|
||||
graphicsDevice,
|
||||
graphicsDevice.PresentationParameters.BackBufferWidth,
|
||||
graphicsDevice,
|
||||
graphicsDevice.PresentationParameters.BackBufferWidth,
|
||||
graphicsDevice.PresentationParameters.BackBufferHeight,
|
||||
4,
|
||||
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()
|
||||
|
@ -140,6 +192,7 @@ namespace KavTest.Renderers
|
|||
// );
|
||||
|
||||
Renderer.DeferredToonRender(
|
||||
DeferredTarget,
|
||||
camera,
|
||||
ModelTransforms,
|
||||
AmbientLight,
|
||||
|
@ -148,6 +201,19 @@ namespace KavTest.Renderers
|
|||
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)
|
||||
// {
|
||||
// Renderer.DepthRender(
|
||||
|
|
Loading…
Reference in New Issue