From 91f727c3626e1c641ccdb54c36469fc8103cb647 Mon Sep 17 00:00:00 2001 From: Konstantin Koch Date: Wed, 4 Nov 2015 23:41:15 +0100 Subject: [PATCH] Added effect specific writers --- .../ANX.Framework.Content.Pipeline.csproj | 11 ++ .../AlphaTestEffectWriter.cs | 44 +++++++ .../GraphicTypeWriters/BasicEffectWriter.cs | 45 +++++++ .../DualTextureEffectWriter.cs | 43 ++++++ .../EffectMaterialWriter.cs | 59 +++++++++ .../EnvironmentMapEffectWriter.cs | 46 +++++++ .../GraphicTypeWriters/IndexBufferWriter.cs | 56 ++++++++ .../GraphicTypeWriters/ModelWriter.cs | 124 ++++++++++++++++++ .../GraphicTypeWriters/SkinnedEffectWriter.cs | 45 +++++++ .../GraphicTypeWriters/VertexBufferWriter.cs | 48 +++++++ .../VertexDeclarationWriter.cs | 49 +++++++ 11 files changed, 570 insertions(+) create mode 100644 ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/AlphaTestEffectWriter.cs create mode 100644 ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/BasicEffectWriter.cs create mode 100644 ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/DualTextureEffectWriter.cs create mode 100644 ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/EffectMaterialWriter.cs create mode 100644 ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/EnvironmentMapEffectWriter.cs create mode 100644 ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/IndexBufferWriter.cs create mode 100644 ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/ModelWriter.cs create mode 100644 ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/SkinnedEffectWriter.cs create mode 100644 ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/VertexBufferWriter.cs create mode 100644 ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/VertexDeclarationWriter.cs diff --git a/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline.csproj b/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline.csproj index d6a9e3aa..eecf9ec0 100644 --- a/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline.csproj +++ b/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline.csproj @@ -184,10 +184,20 @@ + + + + + + + + + + @@ -213,6 +223,7 @@ + diff --git a/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/AlphaTestEffectWriter.cs b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/AlphaTestEffectWriter.cs new file mode 100644 index 00000000..f62dc929 --- /dev/null +++ b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/AlphaTestEffectWriter.cs @@ -0,0 +1,44 @@ +using ANX.Framework.Content.Pipeline.Graphics; +using ANX.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace ANX.Framework.Content.Pipeline.Serialization.Compiler.GraphicTypeWriters +{ + [ContentTypeWriter] + internal class AlphaTestEffectWriter : BuiltinTypeWriter + { + protected override Assembly RuntimeAssembly + { + get + { + return typeof(AlphaTestEffect).Assembly; + } + } + + protected internal override void Write(ContentWriter output, AlphaTestMaterialContent value) + { + if (output == null) + throw new ArgumentNullException("output"); + + if (value == null) + throw new ArgumentNullException("value"); + + //Default values fetched from AlphaTestEffect class + output.WriteExternalReference(value.Texture); + output.Write((int)value.AlphaFunction.GetValueOrDefault(CompareFunction.Greater)); + output.Write(value.ReferenceAlpha.GetValueOrDefault(0)); + output.Write(value.DiffuseColor.GetValueOrDefault(Vector3.One)); + output.Write(value.Alpha.GetValueOrDefault(1f)); + output.Write(value.VertexColorEnabled.GetValueOrDefault(false)); + } + + public override string GetRuntimeType(TargetPlatform targetPlatform) + { + return ContentTypeWriter.GetStrongTypeName(typeof(AlphaTestEffect), targetPlatform); + } + } +} diff --git a/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/BasicEffectWriter.cs b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/BasicEffectWriter.cs new file mode 100644 index 00000000..da1c97cd --- /dev/null +++ b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/BasicEffectWriter.cs @@ -0,0 +1,45 @@ +using ANX.Framework.Content.Pipeline.Graphics; +using ANX.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace ANX.Framework.Content.Pipeline.Serialization.Compiler.GraphicTypeWriters +{ + [ContentTypeWriter] + internal class BasicEffectWriter : BuiltinTypeWriter + { + protected override Assembly RuntimeAssembly + { + get + { + return typeof(BasicEffect).Assembly; + } + } + + protected internal override void Write(ContentWriter output, BasicMaterialContent value) + { + if (output == null) + throw new ArgumentNullException("output"); + + if (value == null) + throw new ArgumentNullException("value"); + + //Default values fetched from BasicEffect class + output.WriteExternalReference(value.Texture); + output.Write(value.DiffuseColor.GetValueOrDefault(Vector3.One)); + output.Write(value.EmissiveColor.GetValueOrDefault(Vector3.Zero)); + output.Write(value.SpecularColor.GetValueOrDefault(Vector3.One)); + output.Write(value.SpecularPower.GetValueOrDefault(16f)); + output.Write(value.Alpha.GetValueOrDefault(1f)); + output.Write(value.VertexColorEnabled.GetValueOrDefault(false)); + } + + public override string GetRuntimeType(TargetPlatform targetPlatform) + { + return ContentTypeWriter.GetStrongTypeName(typeof(BasicEffect), targetPlatform); + } + } +} diff --git a/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/DualTextureEffectWriter.cs b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/DualTextureEffectWriter.cs new file mode 100644 index 00000000..947e239c --- /dev/null +++ b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/DualTextureEffectWriter.cs @@ -0,0 +1,43 @@ +using ANX.Framework.Content.Pipeline.Graphics; +using ANX.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace ANX.Framework.Content.Pipeline.Serialization.Compiler.GraphicTypeWriters +{ + [ContentTypeWriter] + internal class DualTextureEffectWriter : BuiltinTypeWriter + { + protected override Assembly RuntimeAssembly + { + get + { + return typeof(DualTextureEffect).Assembly; + } + } + + protected internal override void Write(ContentWriter output, DualTextureMaterialContent value) + { + if (output == null) + throw new ArgumentNullException("output"); + + if (value == null) + throw new ArgumentNullException("value"); + + //Default values fetched from DualTextureEffect class + output.WriteExternalReference(value.Texture); + output.WriteExternalReference(value.Texture2); + output.Write(value.DiffuseColor.GetValueOrDefault(Vector3.One)); + output.Write(value.Alpha.GetValueOrDefault(1f)); + output.Write(value.VertexColorEnabled.GetValueOrDefault(false)); + } + + public override string GetRuntimeType(TargetPlatform targetPlatform) + { + return ContentTypeWriter.GetStrongTypeName(typeof(DualTextureEffect), targetPlatform); + } + } +} diff --git a/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/EffectMaterialWriter.cs b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/EffectMaterialWriter.cs new file mode 100644 index 00000000..ad7f9531 --- /dev/null +++ b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/EffectMaterialWriter.cs @@ -0,0 +1,59 @@ +using ANX.Framework.Content.Pipeline.Graphics; +using ANX.Framework.Content.Pipeline.Processors; +using ANX.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace ANX.Framework.Content.Pipeline.Serialization.Compiler.GraphicTypeWriters +{ + [ContentTypeWriter] + internal class EffectMaterialWriter : BuiltinTypeWriter + { + protected override Assembly RuntimeAssembly + { + get + { + return typeof(EffectMaterial).Assembly; + } + } + + protected internal override void Write(ContentWriter output, EffectMaterialContent value) + { + if (output == null) + throw new ArgumentNullException("output"); + + if (value == null) + throw new ArgumentNullException("value"); + + if (value.CompiledEffect == null) + throw new InvalidContentException("The compiled effect is null", value.Identity); + + + output.WriteExternalReference(value.CompiledEffect); + + Dictionary collectedData = new Dictionary(); + foreach (var pair in value.OpaqueData) + { + if (!(pair.Key == "Effect") && !(pair.Key == "CompiledEffect")) + { + collectedData.Add(pair.Key, pair.Value); + } + } + + foreach (var pair in value.Textures) + { + collectedData.Add(pair.Key, pair.Value); + } + + output.WriteObject>(collectedData); + } + + public override string GetRuntimeType(TargetPlatform targetPlatform) + { + return ContentTypeWriter.GetStrongTypeName(typeof(EffectMaterial), targetPlatform); + } + } +} diff --git a/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/EnvironmentMapEffectWriter.cs b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/EnvironmentMapEffectWriter.cs new file mode 100644 index 00000000..5e5e7778 --- /dev/null +++ b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/EnvironmentMapEffectWriter.cs @@ -0,0 +1,46 @@ +using ANX.Framework.Content.Pipeline.Graphics; +using ANX.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace ANX.Framework.Content.Pipeline.Serialization.Compiler.GraphicTypeWriters +{ + [ContentTypeWriter] + internal class EnvironmentMapEffectWriter : BuiltinTypeWriter + { + protected override Assembly RuntimeAssembly + { + get + { + return typeof(EnvironmentMapEffect).Assembly; + } + } + + protected internal override void Write(ContentWriter output, EnvironmentMapMaterialContent value) + { + if (output == null) + throw new ArgumentNullException("output"); + + if (value == null) + throw new ArgumentNullException("value"); + + //Default values fetched from EnvironmentMapEffect class + output.WriteExternalReference(value.Texture); + output.WriteExternalReference(value.EnvironmentMap); + output.Write(value.EnvironmentMapAmount.GetValueOrDefault(1f)); + output.Write(value.EnvironmentMapSpecular.GetValueOrDefault(Vector3.Zero)); + output.Write(value.FresnelFactor.GetValueOrDefault(1f)); + output.Write(value.DiffuseColor.GetValueOrDefault(Vector3.One)); + output.Write(value.EmissiveColor.GetValueOrDefault(Vector3.Zero)); + output.Write(value.Alpha.GetValueOrDefault(1f)); + } + + public override string GetRuntimeType(TargetPlatform targetPlatform) + { + return ContentTypeWriter.GetStrongTypeName(typeof(EnvironmentMapEffect), targetPlatform); + } + } +} diff --git a/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/IndexBufferWriter.cs b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/IndexBufferWriter.cs new file mode 100644 index 00000000..06a62375 --- /dev/null +++ b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/IndexBufferWriter.cs @@ -0,0 +1,56 @@ +using ANX.Framework.Content.Pipeline.Graphics; +using ANX.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace ANX.Framework.Content.Pipeline.Serialization.Compiler.GraphicTypeWriters +{ + [ContentTypeWriter] + internal class IndexBufferWriter : BuiltinTypeWriter + { + protected override Assembly RuntimeAssembly + { + get + { + return typeof(IndexBuffer).Assembly; + } + } + + protected internal override void Write(ContentWriter output, IndexCollection value) + { + if (output == null) + throw new ArgumentNullException("output"); + + if (value == null) + throw new ArgumentNullException("value"); + + bool are16BitIndices = true; + for (int i = value.Count - 1; i >= 0; i--) + { + if (value[i] > ushort.MaxValue) + { + are16BitIndices = false; + break; + } + } + + output.Write(are16BitIndices); + output.Write(value.Count * (are16BitIndices ? 2 : 4)); + foreach (int index in value) + { + if (are16BitIndices) + output.Write((ushort)index); + else + output.Write(index); + } + } + + public override string GetRuntimeType(TargetPlatform targetPlatform) + { + return ContentTypeWriter.GetStrongTypeName(typeof(IndexBuffer), targetPlatform); + } + } +} diff --git a/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/ModelWriter.cs b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/ModelWriter.cs new file mode 100644 index 00000000..71606e43 --- /dev/null +++ b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/ModelWriter.cs @@ -0,0 +1,124 @@ +using ANX.Framework.Content.Pipeline.Graphics; +using ANX.Framework.Content.Pipeline.Processors; +using ANX.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace ANX.Framework.Content.Pipeline.Serialization.Compiler.GraphicTypeWriters +{ + [ContentTypeWriter] + internal class ModelWriter : BuiltinTypeWriter + { + protected override Assembly RuntimeAssembly + { + get + { + return typeof(Model).Assembly; + } + } + + protected internal override void Write(ContentWriter output, ModelContent value) + { + if (output == null) + throw new ArgumentNullException("output"); + + if (value == null) + throw new ArgumentNullException("value"); + + this.WriteBones(output, value); + this.WriteMeshes(output, value); + this.WriteBoneIndex(output, value, value.Root); + output.WriteObject(value.Tag); + } + + private void WriteBones(ContentWriter output, ModelContent model) + { + //Write bone data, except indices. + output.Write(model.Bones.Count); + foreach (var bone in model.Bones) + { + output.WriteObject(bone.Name); + output.Write(bone.Transform); + } + + //Write bone indices. + foreach (var bone in model.Bones) + { + this.WriteBoneIndex(output, model, bone.Parent); + output.Write(bone.Children.Count); + + foreach (ModelBoneContent child in bone.Children) + { + this.WriteBoneIndex(output, model, child); + } + } + } + + private void WriteMeshes(ContentWriter output, ModelContent model) + { + output.Write(model.Meshes.Count); + foreach (var mesh in model.Meshes) + { + output.WriteObject(mesh.Name); + this.WriteBoneIndex(output, model, mesh.ParentBone); + output.Write(mesh.BoundingSphere.Center); + output.Write(mesh.BoundingSphere.Radius); + output.WriteObject(mesh.Tag); + + this.WriteMeshParts(output, mesh.MeshParts); + } + } + + private void WriteMeshParts(ContentWriter output, IList meshParts) + { + output.Write(meshParts.Count); + foreach (ModelMeshPartContent current in meshParts) + { + output.Write(current.VertexOffset); + output.Write(current.NumVertices); + output.Write(current.StartIndex); + output.Write(current.PrimitiveCount); + output.WriteObject(current.Tag); + output.WriteSharedResource(current.VertexBuffer); + output.WriteSharedResource(current.IndexBuffer); + output.WriteSharedResource(current.Material); + } + } + + private void WriteBoneIndex(ContentWriter output, ModelContent model, ModelBoneContent bone) + { + //If the number of bones can be placed in a byte, we have to write the indices into bytes too, otherwise we write ints. + //To make sure we can write into a byte, we start the normal indices at 1, that means if a bone has an index of -1, we can still write it. + //We could make that only for the case where we write a byte, but XNA did it that way and we want to stay compatible with XNA, at least to a certain degree. + int boneIndex; + if (bone == null) + boneIndex = 0; + else + { + if (bone.Index < -1 || bone.Index >= model.Bones.Count) + throw new ArgumentOutOfRangeException(string.Format("Index of bone \"{0}\" is either less than -1 or greater or equal to the count of childs in his parent.", bone.Name)); + + boneIndex = bone.Index + 1; + } + + //The highest possible index is Count - 1, but the reader checks if the bones count is less than 255, so I just made the same check. + if (model.Bones.Count < byte.MaxValue) + { + output.Write((byte)boneIndex); + } + else + { + output.Write(boneIndex); + } + } + + + public override string GetRuntimeType(TargetPlatform targetPlatform) + { + return ContentTypeWriter.GetStrongTypeName(typeof(Model), targetPlatform); + } + } +} diff --git a/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/SkinnedEffectWriter.cs b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/SkinnedEffectWriter.cs new file mode 100644 index 00000000..84073e6d --- /dev/null +++ b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/SkinnedEffectWriter.cs @@ -0,0 +1,45 @@ +using ANX.Framework.Content.Pipeline.Graphics; +using ANX.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace ANX.Framework.Content.Pipeline.Serialization.Compiler.GraphicTypeWriters +{ + [ContentTypeWriter] + internal class SkinnedEffectWriter : BuiltinTypeWriter + { + protected override Assembly RuntimeAssembly + { + get + { + return typeof(SkinnedEffect).Assembly; + } + } + + protected internal override void Write(ContentWriter output, SkinnedMaterialContent value) + { + if (output == null) + throw new ArgumentNullException("output"); + + if (value == null) + throw new ArgumentNullException("value"); + + //Default values fetched from SkinnedEffect class + output.WriteExternalReference(value.Texture); + output.Write(value.WeightsPerVertex.GetValueOrDefault(4)); + output.Write(value.DiffuseColor.GetValueOrDefault(Vector3.One)); + output.Write(value.EmissiveColor.GetValueOrDefault(Vector3.Zero)); + output.Write(value.SpecularColor.GetValueOrDefault(Vector3.One)); + output.Write(value.SpecularPower.GetValueOrDefault(16f)); + output.Write(value.Alpha.GetValueOrDefault(1f)); + } + + public override string GetRuntimeType(TargetPlatform targetPlatform) + { + return ContentTypeWriter.GetStrongTypeName(typeof(SkinnedEffect), targetPlatform); + } + } +} diff --git a/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/VertexBufferWriter.cs b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/VertexBufferWriter.cs new file mode 100644 index 00000000..beef80f7 --- /dev/null +++ b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/VertexBufferWriter.cs @@ -0,0 +1,48 @@ +using ANX.Framework.Content.Pipeline.Processors; +using ANX.Framework.Graphics; +using ANX.Framework.NonXNA.Development; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace ANX.Framework.Content.Pipeline.Serialization.Compiler.GraphicTypeWriters +{ + [Developer("Konstantin Koch")] + [ContentTypeWriter] + internal class VertexBufferWriter : BuiltinTypeWriter + { + protected override Assembly RuntimeAssembly + { + get + { + return typeof(VertexBuffer).Assembly; + } + } + + protected internal override void Write(ContentWriter output, VertexBufferContent value) + { + if (output == null) + throw new ArgumentNullException("output"); + + if (value == null) + throw new ArgumentNullException("value"); + + if (value.VertexData.Length == 0) + throw new InvalidContentException("The vertex buffer is empty.", value.Identity); + + if (value.VertexData.Length % value.VertexDeclaration.VertexStride.Value != 0) + throw new InvalidContentException("The size of the vertex buffer is not a multiple of the vertex stride.", value.Identity); + + output.WriteRawObject(value.VertexDeclaration); + output.Write(value.VertexData.Length / value.VertexDeclaration.VertexStride.Value); + output.Write(value.VertexData); + } + + public override string GetRuntimeType(TargetPlatform targetPlatform) + { + return ContentTypeWriter.GetStrongTypeName(typeof(VertexBuffer), targetPlatform); + } + } +} diff --git a/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/VertexDeclarationWriter.cs b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/VertexDeclarationWriter.cs new file mode 100644 index 00000000..4f251f0c --- /dev/null +++ b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/VertexDeclarationWriter.cs @@ -0,0 +1,49 @@ +using ANX.Framework.Content.Pipeline.Processors; +using ANX.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace ANX.Framework.Content.Pipeline.Serialization.Compiler.GraphicTypeWriters +{ + [ContentTypeWriter] + internal class VertexDeclarationWriter : BuiltinTypeWriter + { + protected override Assembly RuntimeAssembly + { + get + { + return typeof(VertexDeclaration).Assembly; + } + } + + protected internal override void Write(ContentWriter output, VertexDeclarationContent value) + { + if (output == null) + throw new ArgumentNullException("output"); + + if (value == null) + throw new ArgumentNullException("value"); + + if (value.VertexElements.Count == 0) + throw new InvalidContentException("The vertex declaration has no vertex elements.", value.Identity); + + output.Write(value.VertexStride.Value); + output.Write(value.VertexElements.Count); + foreach (var element in value.VertexElements) + { + output.Write(element.Offset); + output.Write((int)element.VertexElementFormat); + output.Write((int)element.VertexElementUsage); + output.Write(element.UsageIndex); + } + } + + public override string GetRuntimeType(TargetPlatform targetPlatform) + { + return ContentTypeWriter.GetStrongTypeName(typeof(VertexDeclaration), targetPlatform); + } + } +}