tweak to mesh sprite draws

mesh_sprite_draw
cosmonaut 2020-12-10 00:34:06 -08:00
parent 7f0bf47f07
commit 8ff6e26887
3 changed files with 94 additions and 49 deletions

View File

@ -0,0 +1,24 @@
using Microsoft.Xna.Framework;
namespace Kav.Data
{
public struct MeshSpriteDrawData
{
public MeshSprite MeshSprite { get; }
public SpriteBillboardConstraint BillboardConstraint { get; }
public Matrix TransformMatrix { get; }
public UVOffsets UVOffsets { get; }
public MeshSpriteDrawData(
MeshSprite meshSprite,
SpriteBillboardConstraint billboardConstraint,
Matrix transformMatrix,
UVOffsets uVOffsets
) {
MeshSprite = meshSprite;
BillboardConstraint = billboardConstraint;
TransformMatrix = transformMatrix;
UVOffsets = uVOffsets;
}
}
}

22
Data/UVOffsets.cs Normal file
View File

@ -0,0 +1,22 @@
using Microsoft.Xna.Framework;
namespace Kav.Data
{
public struct UVOffsets
{
public static UVOffsets Default { get; } = new UVOffsets(
new Vector2(0, 0), new Vector2(1, 1)
);
// (start / width), (end / width)
public Vector2 StartUV { get; }
// (start / height), (end / height)
public Vector2 EndUV { get; }
public UVOffsets(Vector2 startUV, Vector2 endUV)
{
StartUV = startUV;
EndUV = endUV;
}
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using Kav.Data;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
@ -117,7 +118,7 @@ namespace Kav
public void MeshSpriteRender(
RenderTarget2D renderTarget,
PerspectiveCamera camera,
IEnumerable<(MeshSprite, SpriteBillboardConstraint, Matrix)> meshSpriteBillboardTransforms,
IEnumerable<MeshSpriteDrawData> meshSpriteDrawDatas,
AmbientLight ambientLight,
IEnumerable<PointLight> pointLights,
DirectionalLight? directionalLight
@ -158,17 +159,24 @@ namespace Kav
var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection);
foreach (var (sprite, transform) in FrustumCull(boundingFrustum, BillboardTransforms(camera, meshSpriteBillboardTransforms)))
foreach (var data in meshSpriteDrawDatas)
{
DiffuseLitSpriteEffect.NormalMapEnabled = sprite.Normal != null;
var matrix = BillboardTransforms(camera, data.TransformMatrix, data.BillboardConstraint);
DiffuseLitSpriteEffect.World = transform;
if (FrustumCull(boundingFrustum, data.MeshSprite, matrix))
{
continue;
}
GraphicsDevice.Textures[0] = sprite.Texture;
GraphicsDevice.Textures[1] = sprite.Normal;
DiffuseLitSpriteEffect.NormalMapEnabled = data.MeshSprite.Normal != null;
GraphicsDevice.SetVertexBuffer(sprite.VertexBuffer);
GraphicsDevice.Indices = sprite.IndexBuffer;
DiffuseLitSpriteEffect.World = matrix;
GraphicsDevice.Textures[0] = data.MeshSprite.Texture;
GraphicsDevice.Textures[1] = data.MeshSprite.Normal;
GraphicsDevice.SetVertexBuffer(data.MeshSprite.VertexBuffer);
GraphicsDevice.Indices = data.MeshSprite.IndexBuffer;
foreach (var pass in DiffuseLitSpriteEffect.CurrentTechnique.Passes)
{
@ -178,7 +186,7 @@ namespace Kav
PrimitiveType.TriangleList,
0,
0,
sprite.VertexBuffer.VertexCount,
data.MeshSprite.VertexBuffer.VertexCount,
0,
2
);
@ -186,36 +194,34 @@ namespace Kav
}
}
private static IEnumerable<(MeshSprite, Matrix)> BillboardTransforms(
private static Matrix BillboardTransforms(
PerspectiveCamera camera,
IEnumerable<(MeshSprite, SpriteBillboardConstraint, Matrix)> meshSpriteBillboardTransforms
Matrix transform,
SpriteBillboardConstraint billboardConstraint
) {
foreach (var (sprite, billboardConstraint, transform) in meshSpriteBillboardTransforms)
if (billboardConstraint == SpriteBillboardConstraint.None)
{
if (billboardConstraint == SpriteBillboardConstraint.None)
{
yield return (sprite, transform);
}
else if (billboardConstraint == SpriteBillboardConstraint.Horizontal)
{
yield return (sprite, Matrix.CreateConstrainedBillboard(
transform.Translation,
camera.Position,
Vector3.Up,
camera.Forward,
camera.Position - transform.Translation
));
}
else
{
yield return (sprite, Matrix.CreateConstrainedBillboard(
transform.Translation,
camera.Position,
Vector3.Up,
null,
null
));
}
return transform;
}
else if (billboardConstraint == SpriteBillboardConstraint.Horizontal)
{
return Matrix.CreateConstrainedBillboard(
transform.Translation,
camera.Position,
Vector3.Up,
camera.Forward,
camera.Position - transform.Translation
);
}
else
{
return Matrix.CreateConstrainedBillboard(
transform.Translation,
camera.Position,
Vector3.Up,
null,
null
);
}
}
@ -924,21 +930,14 @@ namespace Kav
}
}
private static IEnumerable<Matrix> FrustumCull<T>(
private static bool FrustumCull<T>(
BoundingFrustum boundingFrustum,
T cullable,
IEnumerable<Matrix> transforms
) where T : ICullable
{
foreach (var transform in transforms)
{
var boundingBox = TransformedBoundingBox(cullable.BoundingBox, transform);
var containment = boundingFrustum.Contains(boundingBox);
if (containment != ContainmentType.Disjoint)
{
yield return transform;
}
}
Matrix transform
) where T : ICullable {
var boundingBox = TransformedBoundingBox(cullable.BoundingBox, transform);
var containment = boundingFrustum.Contains(boundingBox);
return (containment == ContainmentType.Disjoint);
}
private static BoundingBox TransformedBoundingBox(BoundingBox boundingBox, Matrix matrix)