port from perforce

This commit is contained in:
2026-04-18 22:31:51 +02:00
commit 8d0ab5b7cc
8409 changed files with 3972376 additions and 0 deletions

View File

@@ -0,0 +1,154 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{EA73561A-0B57-4FDC-8AF3-52E959BA67E7}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Aiwaz.Resources</RootNamespace>
<AssemblyName>Aiwaz.Resources</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>3.5</OldToolsVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="SlimDX, Version=2.0.8.42, Culture=neutral, PublicKeyToken=b1b0c32fd1ffe4f9, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Extern\SlimDX\x86\SlimDX.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Attributes\CreationParameters.cs" />
<Compile Include="Attributes\ReadOnly.cs" />
<Compile Include="Attributes\RequiredParameter.cs" />
<Compile Include="BluImporter\BluImporter.cs" />
<Compile Include="Bone.cs" />
<Compile Include="Camera.cs" />
<Compile Include="Commands\CommandBuffer.cs" />
<Compile Include="Commands\CommandUser.cs" />
<Compile Include="CreationParams.cs" />
<Compile Include="GeometryBuffer.cs" />
<Compile Include="PickHull.cs" />
<Compile Include="Prefab\Quad.cs" />
<Compile Include="Prefab\Cube.cs" />
<Compile Include="Prefab\PingPongBuffer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RenderCommandNode.cs" />
<Compile Include="RenderTarget.cs" />
<Compile Include="RenderTargetTexture.cs" />
<Compile Include="Resource.cs" />
<Compile Include="Shader.cs" />
<Compile Include="ShaderParameterSet.cs" />
<Compile Include="SwapChain.cs" />
<Compile Include="Texture.cs" />
<Compile Include="Transformation.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Aiwaz.Common\Aiwaz.Common.csproj">
<Project>{0F7D7168-08C1-45AE-AAE3-80506939D7E6}</Project>
<Name>Aiwaz.Common</Name>
</ProjectReference>
<ProjectReference Include="..\Aiwaz.Contracts\Aiwaz.Contracts.csproj">
<Project>{DE4D6FE6-D1FB-41A1-8ABA-19635B8FFD7A}</Project>
<Name>Aiwaz.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\Aiwaz.Core\Aiwaz.Core.csproj">
<Project>{B7AB4BB3-6FFC-453E-928D-852A6FF8C508}</Project>
<Name>Aiwaz.Core</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishUrlHistory />
<InstallUrlHistory />
<SupportUrlHistory />
<UpdateUrlHistory />
<BootstrapperUrlHistory />
<ErrorReportUrlHistory />
<FallbackCulture>en-US</FallbackCulture>
<VerifyUploadedFiles>false</VerifyUploadedFiles>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Aiwaz.Resources.Attributes
{
public class CreationParametersAttribute : System.Attribute
{
public string Description { get; protected set; }
public CreationParametersAttribute(string description)
{
this.Description = description;
}
}
}

View File

@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Aiwaz.Resources.Attributes
{
public class ReadOnlyAttribute : System.Attribute
{
}
}

View File

@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Aiwaz.Resources.Attributes
{
public class RequiredParameterAttribute : System.Attribute
{
}
}

View File

@@ -0,0 +1,323 @@
using System;
using System.IO;
using System.Linq;
using Aiwaz.Common;
using Aiwaz.Contracts;
using Aiwaz.Core;
using System.Collections.Generic;
using Aiwaz.Resources.Attributes;
using System.Collections.ObjectModel;
using SlimDX;
namespace Aiwaz.Resources
{
public class FileInegrityBroken : Exception
{
public FileInegrityBroken() : base() { }
public FileInegrityBroken(string message) : base(message) { }
}
[CreationParameters("Blu Model from file")]
public class BluModelParams : ICreationParams
{
public string FileName;
public BluModelParams()
{
}
}
[AiwazResource("Blu Model", "A model loaded from a .blu file")]
public class BluModel : Resource
{
private enum BluSectionType
{
Mesh = 0,
Material = 1,
Bone = 2,
Animation = 3,
LastKnownType = 3
};
private class BluImportResult
{
public struct BluImportedGeometryBuffer
{
public IGeometryBuffer GeometryBuffer;
public string MaterialName;
};
public string FileName;
public Dictionary<string, BluImportedGeometryBuffer> GeometryBuffers = new Dictionary<string, BluImportedGeometryBuffer>();
public Dictionary<string, IShaderParameterSet> ShaderParamererSets = new Dictionary<string, IShaderParameterSet>();
public Dictionary<string, IShader> Shaders = new Dictionary<string, IShader>();
};
public string FileName { get; protected set; }
public RenderCommandNode RootNode { get; protected set; }
public Transformation RootTransformation { get; protected set; }
public BluModel(BluModelParams parameters)
{
this.FileName = parameters.FileName;
creationParams = parameters;
this.RootNode = new RenderCommandNode();
this.RootTransformation = new Transformation(new DefaultTransformationBindings());
Engine.FileSystem.Attach(parameters.FileName, OnFileChanged);
}
private void OnFileChanged(Stream stream)
{
var result = new BluImportResult();
result.FileName = this.FileName;
using (stream) using (var reader = new BinaryReader(stream))
{
var magic = reader.ReadNullTerminatedString();
if (magic != "BLUF")
throw new FileInegrityBroken();
var fileVersion = reader.ReadInt32();
// sections
while (stream.Position < stream.Length)
{
var objectType = (BluSectionType)reader.ReadInt32();
if (objectType > BluSectionType.LastKnownType)
throw new FileInegrityBroken("Unknown object section detected.");
var objectName = reader.ReadNullTerminatedString();
if (string.IsNullOrEmpty(objectName))
throw new FileInegrityBroken("Object name not set.");
// content
switch (objectType)
{
case BluSectionType.Mesh:
this.ImportMesh(reader, objectName, result);
break;
case BluSectionType.Material:
this.ImportMaterial(reader, objectName, result);
break;
case BluSectionType.Bone:
this.ImportBone(reader, objectName, result);
break;
case BluSectionType.Animation:
this.ImportAnimation(reader, objectName, result);
break;
}
}
}
this.RootNode.Children.Clear();
// Create sub nodes
foreach (var geoBufferInfo in result.GeometryBuffers)
{
var meshInfo = geoBufferInfo.Value;
var shader = result.Shaders[meshInfo.MaterialName];
var shaderParameter = result.ShaderParamererSets[meshInfo.MaterialName];
if (shader != null && shaderParameter != null)
{
var subNode = new RenderCommandNode();
subNode.Children.Add((CommandUser)shader);
subNode.Children.Add((CommandUser)this.RootTransformation);
subNode.Children.Add((CommandUser)shaderParameter);
subNode.Children.Add((CommandUser)meshInfo.GeometryBuffer);
this.RootNode.Children.Add(subNode);
}
}
}
private void ImportMesh(BinaryReader reader, string objectName, BluImportResult result)
{
var materialName = reader.ReadNullTerminatedString();
var vertexCount = reader.ReadInt32();
var vertexElementCount = reader.ReadInt32();
var vertexElements = new VertexElement[vertexElementCount];
for (int i = 0; i < vertexElementCount; ++i)
{
int vertexElementOldId = reader.ReadInt32();
switch (vertexElementOldId)
{
case 1: vertexElements[i] = new VertexElement(VertexElement.Format.Position); break;
case 3: vertexElements[i] = new VertexElement(VertexElement.Format.Normal); break;
case 8: vertexElements[i] = new VertexElement(VertexElement.Format.Texture2D); break;
case 11: vertexElements[i] = new VertexElement(VertexElement.Format.Tangent); break;
case 13: vertexElements[i] = new VertexElement(VertexElement.Format.BlendIndices); break;
case 14: vertexElements[i] = new VertexElement(VertexElement.Format.BlendWeight); break;
}
}
var vertexData = reader.ReadBytes(vertexCount * vertexElements.Sum(v => v.Size));
var indexCount = reader.ReadInt32();
var indexRawData = reader.ReadBytes(sizeof(Int32) * indexCount);
int[] indexData = new int[indexCount];
for (int i = 0; i < indexCount; ++i)
indexData[i] = (int)BitConverter.ToInt32(indexRawData, i * sizeof(uint));
string uniqueName = result.FileName + "." + objectName;
var vBuffer = new DataStream(vertexData, true, true);
var iBuffer = new DataStream(indexData, true, true);
var geoBuffer = new GeometryBuffer(
indexCount,
iBuffer,
vertexCount,
vBuffer,
vertexElements,
false);
geoBuffer.IsPickable = true;
//geoBuffer.ConvertToAdjacency();
var mesh = new BluImportResult.BluImportedGeometryBuffer();
mesh.GeometryBuffer = geoBuffer;
mesh.MaterialName = result.FileName + "." + materialName;
result.GeometryBuffers.Add(uniqueName, mesh);
}
private string GetPath(string orignalPath)
{
if (string.IsNullOrEmpty(orignalPath))
return orignalPath;
return Path.Combine(Path.GetDirectoryName(this.FileName), Path.GetFileName(orignalPath));
}
private void ImportMaterial(BinaryReader reader, string objectName, BluImportResult result)
{
string diffuseTexture = this.GetPath(reader.ReadNullTerminatedString());
string specularTexture = this.GetPath(reader.ReadNullTerminatedString());
string normalTexture = this.GetPath(reader.ReadNullTerminatedString());
string glowTexture = this.GetPath(reader.ReadNullTerminatedString());
string reflectionTexture = this.GetPath(reader.ReadNullTerminatedString());
var ambientColor = new SlimDX.Vector4();
ambientColor.X = reader.ReadSingle() / 255.0f;
ambientColor.Y = reader.ReadSingle() / 255.0f;
ambientColor.Z = reader.ReadSingle() / 255.0f;
ambientColor.W = reader.ReadSingle() / 255.0f;
var diffuseColor = new SlimDX.Vector4();
diffuseColor.X = reader.ReadSingle() / 255.0f;
diffuseColor.Y = reader.ReadSingle() / 255.0f;
diffuseColor.Z = reader.ReadSingle() / 255.0f;
diffuseColor.W = reader.ReadSingle() / 255.0f;
var specularColor = new SlimDX.Vector4();
specularColor.X = reader.ReadSingle() / 255.0f;
specularColor.Y = reader.ReadSingle() / 255.0f;
specularColor.Z = reader.ReadSingle() / 255.0f;
specularColor.W = reader.ReadSingle() / 255.0f;
var emissiveColor = new SlimDX.Vector4();
emissiveColor.X = reader.ReadSingle() / 255.0f;
emissiveColor.Y = reader.ReadSingle() / 255.0f;
emissiveColor.Z = reader.ReadSingle() / 255.0f;
emissiveColor.W = reader.ReadSingle() / 255.0f;
var specularlevel = reader.ReadSingle();
var glossiness = reader.ReadSingle();
string uniqueName = result.FileName + "." + objectName;
var material = new ShaderParameterSet();
material.SetParameter("AmbientColor", ambientColor, ParameterBindType.BindBySemantic);
material.SetParameter("DiffuseColor", diffuseColor, ParameterBindType.BindBySemantic);
material.SetParameter("SpecularColor", specularColor * glossiness, ParameterBindType.BindBySemantic);
material.SetParameter("EmissiveColor", emissiveColor, ParameterBindType.BindBySemantic);
material.SetParameter("Shininess", specularlevel, ParameterBindType.BindBySemantic);
var modelShader = new Shader(new ShaderParams() { FileName = "Data/NormalOutput.fx", TechniqueName = "Render" });
result.Shaders.Add(uniqueName, modelShader);
if (!string.IsNullOrEmpty(diffuseTexture))
{
Texture tex = Engine.FindNamedObject(diffuseTexture) as Texture;
if (tex == null)
{
tex = new Texture(new FileTextureParams() { FileName = diffuseTexture });
tex.WellKnownName = diffuseTexture;
}
material.SetParameter("Diffuse", tex, ParameterBindType.BindBySemantic);
}
if (!string.IsNullOrEmpty(specularTexture))
{
Texture tex = Engine.FindNamedObject(specularTexture) as Texture;
if (tex == null)
{
tex = new Texture(new FileTextureParams() { FileName = specularTexture });
tex.WellKnownName = specularTexture;
}
material.SetParameter("Specular", tex, ParameterBindType.BindBySemantic);
}
if (!string.IsNullOrEmpty(normalTexture))
{
Texture tex = Engine.FindNamedObject(normalTexture) as Texture;
if (tex == null)
{
tex = new Texture(new FileTextureParams() { FileName = normalTexture });
tex.WellKnownName = normalTexture;
}
material.SetParameter("Normal", tex, ParameterBindType.BindBySemantic);
}
if (!string.IsNullOrEmpty(glowTexture))
{
Texture tex = Engine.FindNamedObject(glowTexture) as Texture;
if (tex == null)
{
tex = new Texture(new FileTextureParams() { FileName = glowTexture });
tex.WellKnownName = glowTexture;
}
material.SetParameter("Glow", tex, ParameterBindType.BindBySemantic);
}
if (!string.IsNullOrEmpty(reflectionTexture))
{
Texture tex = Engine.FindNamedObject(reflectionTexture) as Texture;
if (tex == null)
{
tex = new Texture(new FileTextureParams() { FileName = reflectionTexture });
tex.WellKnownName = reflectionTexture;
}
material.SetParameter("Reflection", tex, ParameterBindType.BindBySemantic);
}
result.ShaderParamererSets.Add(uniqueName, material);
}
private void ImportBone(BinaryReader reader, string objectName, BluImportResult result)
{
throw new NotImplementedException();
}
private void ImportAnimation(BinaryReader reader, string objectName, BluImportResult result)
{
throw new NotImplementedException();
}
private ICreationParams creationParams;
public override ICreationParams CreationParams
{
get { return creationParams; }
}
private ObservableCollection<IResource> children;
[ReadOnly]
public override ObservableCollection<IResource> Children
{
get
{
if (children == null)
{
children = new ObservableCollection<IResource>();
children.Add(RootNode);
}
return children;
}
}
};
}

View File

@@ -0,0 +1,115 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aiwaz.Contracts;
namespace Aiwaz.Resources
{
public class Bone : IBone
{
#region IBone Members
private SlimDX.Matrix transformation;
private SlimDX.Matrix invPoseTransformation;
private float lastAnimationTime = float.MinValue;
private IBone parent;
private SlimDX.Matrix[] matrixArray = new SlimDX.Matrix[0];
private ITransformationAnimation transformationAnimation;
private Dictionary<int, IBone> boneIndexList = new Dictionary<int, IBone>();
public Bone(string name, int index, SlimDX.Vector3 poseTranslation, SlimDX.Vector3 poseScale, SlimDX.Quaternion poseRotation)
{
PoseTransformation = SlimDX.Matrix.Transformation(SlimDX.Vector3.Zero, SlimDX.Quaternion.Identity, poseScale, SlimDX.Vector3.Zero, poseRotation, poseTranslation);
invPoseTransformation = this.PoseTransformation;
invPoseTransformation.Invert();
this.Index = index;
this.ChildBones = new List<IBone>();
}
public SlimDX.Matrix GetTransformationAtTime(float time, SlimDX.Matrix rootTransformationMatrix)
{
if (this.TransformationAnimation != null)
{
if (time != lastAnimationTime)
{
if (this.Parent != null)
{
transformation = (this.TransformationAnimation.GetTransformationAtTime(time) * invPoseTransformation) * this.Parent.GetTransformationAtTime(time, rootTransformationMatrix);
transformation = invPoseTransformation * this.TransformationAnimation.GetTransformationAtTime(time);
//m_Transformation = m_Transformation * ( * m_InvPoseTransformation);
}
else
transformation = this.TransformationAnimation.GetTransformationAtTime(time) * invPoseTransformation;
}
}
return transformation;
}
public Dictionary<int, IBone> BoneIndexList
{
get
{
if (parent != null)
return parent.BoneIndexList;
if (boneIndexList.Count == 0)
this.FillBoneIndexList(this);
return boneIndexList;
}
}
public List<IBone> ChildBones { get; protected set; }
public int Index { get; protected set; }
public SlimDX.Matrix[] MatrixArray
{
get
{
if (matrixArray == null)
matrixArray = new SlimDX.Matrix[this.BoneIndexList.Count];
return matrixArray;
}
}
public string Name { get; protected set; }
public SlimDX.Matrix PoseTransformation { get; protected set; }
public IBone Parent
{
get { return parent; }
set
{
if (parent != null)
parent.ChildBones.Remove(this);
parent = value;
if (parent != null)
parent.ChildBones.Add(this);
}
}
public ITransformationAnimation TransformationAnimation
{
get { return transformationAnimation; }
set
{
transformationAnimation = value;
lastAnimationTime = float.MinValue;
transformation = new SlimDX.Matrix();
}
}
internal void FillBoneIndexList(IBone currentBone)
{
boneIndexList[currentBone.Index] = currentBone;
foreach (var childBone in currentBone.ChildBones)
this.FillBoneIndexList(childBone);
}
#endregion
}
}

View File

@@ -0,0 +1,277 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aiwaz.Contracts;
using Aiwaz.Core;
using Aiwaz.Common.Animations;
using Aiwaz.Resources.Attributes;
namespace Aiwaz.Resources
{
[CreationParameters("Standard orthographic camera")]
public class OrthographicCameraParams
{
public float width;
public float height;
public OrthographicCameraParams()
{
width = 512;
height = 512;
}
}
[AiwazResource("Orthographic Camera", "An orthographic camera for orthogonal views.")]
public class OrthographicCamera : BaseCamera, IOrthographicCamera
{
#region IOrthographicCamera Members
private float width;
private float height;
private OrthographicCamera()
: base()
{
}
public OrthographicCamera(OrthographicCameraParams parameters)
: this()
{
Console.WriteLine(string.Format("Creating OrthographicCamera ({0}x{1})..", parameters.width, parameters.height));
this.Width = parameters.width;
this.Height = parameters.height;
}
public float Width
{
get { return width; }
set
{
width = value;
WantsUpdate = true;
}
}
public float Height
{
get { return height; }
set
{
height = value;
WantsUpdate = true;
}
}
public override void Update(bool forceUpdate)
{
base.Update(forceUpdate);
this.ProjectionMatrix = SlimDX.Matrix.OrthoLH(width, height, this.NearClip, this.FarClip);
this.ViewMatrix = SlimDX.Matrix.LookAtLH(this.WorldPosition, this.WorldPosition + this.WorldDirection, this.WorldUpDirection);
// generate view frustum
var viewProj = this.ViewMatrix * this.ProjectionMatrix;
// Left plane
this.ViewFrustum.Plane[0] = new SlimDX.Plane(viewProj.M14 + viewProj.M11,
viewProj.M24 + viewProj.M21,
viewProj.M34 + viewProj.M31,
viewProj.M44 + viewProj.M41);
// Right plane
this.ViewFrustum.Plane[1] = new SlimDX.Plane(viewProj.M14 - viewProj.M11,
viewProj.M24 - viewProj.M21,
viewProj.M34 - viewProj.M31,
viewProj.M44 - viewProj.M41);
// Top plane
this.ViewFrustum.Plane[2] = new SlimDX.Plane(viewProj.M14 - viewProj.M12,
viewProj.M24 - viewProj.M22,
viewProj.M34 - viewProj.M32,
viewProj.M44 - viewProj.M42);
// Bottom plane
this.ViewFrustum.Plane[3] = new SlimDX.Plane(viewProj.M14 + viewProj.M12,
viewProj.M24 + viewProj.M22,
viewProj.M34 + viewProj.M32,
viewProj.M44 + viewProj.M42);
// Near plane
this.ViewFrustum.Plane[4] = new SlimDX.Plane(viewProj.M13,
viewProj.M23,
viewProj.M33,
viewProj.M43);
// Far plane
this.ViewFrustum.Plane[5] = new SlimDX.Plane(viewProj.M14 - viewProj.M13,
viewProj.M24 - viewProj.M23,
viewProj.M34 - viewProj.M33,
viewProj.M44 - viewProj.M43);
}
#endregion
}
[CreationParameters("Standard orthographic camera")]
public class PerspectiveCameraParams
{
public float fov;
public float aspectRatio;
public PerspectiveCameraParams()
{
fov = 90.0f;
aspectRatio = 1.0f;
}
}
[AiwazResource("Perspective Camera", "An perspective camera for perspective correct views.")]
public class PerspectiveCamera : BaseCamera, IPerspectiveCamera
{
#region IPerspectiveCamera Members
private float fov;
private float aspectRatio;
private PerspectiveCamera()
: base()
{
}
public PerspectiveCamera(PerspectiveCameraParams parameters)
: this()
{
Console.WriteLine(string.Format("Creating PerspectiveCamera (Fov: {0} AspectRatio: {1})..", parameters.fov, parameters.aspectRatio));
this.Fov = parameters.fov;
this.AspectRatio = parameters.aspectRatio;
}
[Animateable]
public float Fov
{
get { return fov; }
set
{
fov = value;
WantsUpdate = true;
}
}
[Animateable]
public float AspectRatio
{
get { return aspectRatio; }
set
{
aspectRatio = value;
WantsUpdate = true;
}
}
public override void Update(bool forceUpdate)
{
base.Update(forceUpdate);
this.ProjectionMatrix = SlimDX.Matrix.PerspectiveFovLH((float)((Math.PI / 180) * fov), this.AspectRatio, this.NearClip, this.FarClip);
this.ViewMatrix = SlimDX.Matrix.LookAtLH(this.WorldPosition, this.WorldPosition + this.WorldDirection, this.WorldUpDirection);
// generate view frustum
var viewProj = this.ViewMatrix * this.ProjectionMatrix;
// Left plane
this.ViewFrustum.Plane[0] = new SlimDX.Plane(
viewProj.M14 + viewProj.M11,
viewProj.M24 + viewProj.M21,
viewProj.M34 + viewProj.M31,
viewProj.M44 + viewProj.M41);
// Right plane
this.ViewFrustum.Plane[1] = new SlimDX.Plane(viewProj.M14 - viewProj.M11,
viewProj.M24 - viewProj.M21,
viewProj.M34 - viewProj.M31,
viewProj.M44 - viewProj.M41);
// Top plane
this.ViewFrustum.Plane[2] = new SlimDX.Plane(viewProj.M14 - viewProj.M12,
viewProj.M24 - viewProj.M22,
viewProj.M34 - viewProj.M32,
viewProj.M44 - viewProj.M42);
// Bottom plane
this.ViewFrustum.Plane[3] = new SlimDX.Plane(viewProj.M14 + viewProj.M12,
viewProj.M24 + viewProj.M22,
viewProj.M34 + viewProj.M32,
viewProj.M44 + viewProj.M42);
// Near plane
this.ViewFrustum.Plane[4] = new SlimDX.Plane(viewProj.M13,
viewProj.M23,
viewProj.M33,
viewProj.M43);
// Far plane
this.ViewFrustum.Plane[5] = new SlimDX.Plane(viewProj.M14 - viewProj.M13,
viewProj.M24 - viewProj.M23,
viewProj.M34 - viewProj.M33,
viewProj.M44 - viewProj.M43);
}
#endregion
}
public abstract class BaseCamera : Transformation, ICamera
{
#region ICamera Members
private float nearClip = 1.0f;
private float farClip = 1000.0f;
Reference projectionMatrix = new Reference(new SlimDX.Matrix());
Reference viewMatrix = new Reference(new SlimDX.Matrix());
public SlimDX.Matrix ProjectionMatrix { get { return (SlimDX.Matrix)projectionMatrix.RawValue; } protected set { projectionMatrix.RawValue = value; } }
public SlimDX.Matrix ViewMatrix { get { return (SlimDX.Matrix)viewMatrix.RawValue; } protected set { viewMatrix.RawValue = value; } }
public BaseCamera()
: base(new CameraTransformationBindings())
{
this.ViewFrustum = new ViewFrustum();
this.IsPreconditionForFollowingShaders = true;
this.RecreateAllShaderParameters();
}
public float FarClip
{
get { return farClip; }
set
{
farClip = value;
WantsUpdate = true;
}
}
public float NearClip
{
get { return nearClip; }
set
{
nearClip = value;
WantsUpdate = true;
}
}
public ViewFrustum ViewFrustum { get; protected set; }
protected override void RecreateAllShaderParameters()
{
this.SetParameter("ViewMatrix", viewMatrix, ParameterBindType.BindBySemantic);
this.SetParameter("ProjectionMatrix", projectionMatrix, ParameterBindType.BindBySemantic);
base.RecreateAllShaderParameters();
}
#endregion
}
}

View File

@@ -0,0 +1,342 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aiwaz.Contracts;
using Aiwaz.Core;
namespace Aiwaz.Resources
{
public class CommandBuffer
{
private class CommandChainInternal
{
public int Priority = 0;
public List<Command> Chain;
public void UpdatePriority()
{
Priority = -1;
foreach (var command in Chain)
if ((command.Flags & CommandFlags.SubChainStart) != CommandFlags.None)
{
Priority = command.SubPriority;
break;
}
}
public class CommandComparsion : IComparer<Command>
{
public int Compare(Command x, Command y)
{
return x.Priority.CompareTo(y.Priority);
}
}
public class CommandChainComparsion : IComparer<CommandChainInternal>
{
public int Compare(CommandChainInternal x, CommandChainInternal y)
{
if (x.Priority == y.Priority)
return x.Chain.Count.CompareTo(y.Chain.Count);
return x.Priority.CompareTo(y.Priority);
}
}
}
private CommandBuffer optimizedCommandBuffer = null;
private List<CommandChainInternal> gatheredCommandChains = new List<CommandChainInternal>();
public List<Command> BufferedCommands { get; protected set; }
public List<CommandBuffer> ChildCommandBuffers { get; protected set; }
public CommandBuffer ParentBuffer { get; set; }
#region ICommandBuffer Members
public CommandBuffer()
{
BufferedCommands = new List<Command>();
ChildCommandBuffers = new List<CommandBuffer>();
}
public void Clear()
{
BufferedCommands.Clear();
ChildCommandBuffers.Clear();
gatheredCommandChains.Clear();
if (optimizedCommandBuffer != null)
optimizedCommandBuffer.Clear();
}
public void Perform(bool useOptimizedList)
{
if (!useOptimizedList)
{
int subChainStartCommandIndex = -1;
for (int i = 0; i < BufferedCommands.Count;)
{
var command = BufferedCommands[i];
if ((command.Flags & CommandFlags.SubChainStart) != CommandFlags.None)
subChainStartCommandIndex = i;
switch (command.Owner.ExecuteCommand(command.Type, this, i))
{
case CommandExecuteResult.None:
if ((command.Flags & CommandFlags.SubChainEnd) != CommandFlags.None)
subChainStartCommandIndex = -1;
i++;
break;
case CommandExecuteResult.RetrySubChain:
if (subChainStartCommandIndex == -1)
throw new ActionFailedException("Failed to restart sub command chain.");
else
i = subChainStartCommandIndex;
break;
case CommandExecuteResult.RetrySubChainSkipHead:
if (subChainStartCommandIndex == -1)
throw new ActionFailedException("Failed to restart headless sub command chain.");
else
i = subChainStartCommandIndex + 1;
break;
}
}
}
else
{
if (optimizedCommandBuffer != null)
optimizedCommandBuffer.Perform(false);
}
}
public void Optimize()
{
if (optimizedCommandBuffer == null)
optimizedCommandBuffer = new CommandBuffer();
optimizedCommandBuffer.Clear();
List<Command> tempChain = new List<Command>();
this.SearchDrawableCommandChain(this, ref tempChain);
this.FlushGatheredCommandChains();
}
public void AddChildCommandBuffer(CommandBuffer commandBuffer)
{
ChildCommandBuffers.Add(commandBuffer);
commandBuffer.ParentBuffer = this;
}
public void RemoveChildCommandBuffer(CommandBuffer commandBuffer)
{
if (ChildCommandBuffers.Remove(commandBuffer))
commandBuffer.ParentBuffer = null;
}
private void SearchDrawableCommandChain(CommandBuffer incomingBuffer, ref List<Command> currentChain)
{
for (int i = 0; i < incomingBuffer.BufferedCommands.Count;)
{
var currentCommand = incomingBuffer.BufferedCommands[i];
var commandFlags = currentCommand.Flags;
// A command is start AND end of a command chain, this indicates that a serious state change will come,
// so we will need to flush the current command chains.
if ((commandFlags & CommandFlags.FlushChain) != 0)
{
this.FlushGatheredCommandChains();
currentChain.Clear();
}
// Old way commented out due problems with transformations before shaders
// A command was found which does not belong to a build up current chain (due no chain is building herself up..)
// so we drop it, we simply do not care about some run away
/*if (currentChain.empty()
&& (commandFlags & CommandFlags.StartChain) == 0
&& (commandFlags & CommandFlags.EndChain) == 0)
{
++i;
continue;
}*/
// New way is to search the list for a start chain command, then we put this command after the start chain command
if (currentChain.Count == 0
&& (commandFlags & CommandFlags.StartChain) == 0
&& (commandFlags & CommandFlags.EndChain) == 0)
{
var foundPlace = false;
var commands = incomingBuffer.BufferedCommands;
for (int k = i + 1; k < commands.Count; ++k)
if ((commands[k].Flags & CommandFlags.StartChain) != CommandFlags.None)
{
commands.Insert(k + 1, currentCommand);
commands.RemoveAt(i);
foundPlace = true;
break;
}
if (!foundPlace)
++i;
continue;
}
// A new command chain should be initialized, clear our current temp chain and add this command into it.
// All old commands remaining in the chain are already used or where completely useless (SetShader . SetParameter . NextPass).
else if ((commandFlags & CommandFlags.StartChain) != 0 && currentChain.Count > 0)
{
currentChain.Clear();
currentChain.Add(currentCommand);
++i;
}
// We should end our chain, now we need to optimize this chain and add this into the gathered chain list,
// at the next flush command we will put this list into our optimized list, with some more optimizations.
else if ((commandFlags & CommandFlags.EndChain) != 0)
{
// We have a filled chain (at least 1 operation following by this operation)
if (currentChain.Count > 0)
{
var commandChainInternal = new CommandChainInternal();
commandChainInternal.Chain = new List<Command>(currentChain);
commandChainInternal.Chain.Add(currentCommand);
commandChainInternal.Chain.Sort(new CommandChainInternal.CommandComparsion());
//m_OptimizedCommandBuffer.get_BufferedCommands().insert(m_OptimizedCommandBuffer.get_BufferedCommands().end(), chain.begin(), chain.end());
gatheredCommandChains.Add(commandChainInternal);
// Search for the SubChainEnd flagged command , this should be found right after the SubChainStart flagged commands
// both commands will mark the beginning of our chain . delete everything behind this command will ensure
// that we will use a fresh new command chain, only filled with what we need (StartSubChain . EndSubChain)
for (int k = 0; k < currentChain.Count; ++k)
if ((currentChain[k].Flags & CommandFlags.SubChainEnd) != CommandFlags.None)
{
currentChain.RemoveRange(k + 1, currentChain.Count - (k + 1));
break;
}
}
// Our chain was empty, this means a solo command was found, put it into our optimized list and continue,
// there is not much to do here.
else
{
optimizedCommandBuffer.BufferedCommands.Add(currentCommand);
}
++i;
}
// No start and no end of the command chain, just put this command into our chain,
// commands of this type are for example, SetVertexBuffer, SetIndexBuffer, SetTransformation,...
else
{
currentChain.Add(currentCommand);
++i;
}
}
// We may have child buffers, continue our search there.
foreach (var buffer in incomingBuffer.ChildCommandBuffers)
{
var newCurrentChain = new List<Command>(currentChain);
this.SearchDrawableCommandChain(buffer, ref currentChain);
currentChain = newCurrentChain;
}
}
void FlushGatheredCommandChains()
{
var flushedCommands = new List<Command>();
gatheredCommandChains.ForEach(item => item.UpdatePriority());
while (gatheredCommandChains.Count > 0)
{
gatheredCommandChains.Sort(new CommandChainInternal.CommandChainComparsion());
int currentPriority = 0;
List<int> checkables = new List<int>();
for (int i = 0; i < gatheredCommandChains.Count;)
{
if (gatheredCommandChains[i].Chain.Count == 0)
gatheredCommandChains.RemoveAt(i);
else if (checkables.Count == 0 || currentPriority == gatheredCommandChains[i].Priority)
{
currentPriority = gatheredCommandChains[i].Priority;
checkables.Add(i);
++i;
}
else
break;
}
if (checkables.Count == 1)
{
int thisIndex = checkables.First();
flushedCommands.AddRange(gatheredCommandChains[thisIndex].Chain);
gatheredCommandChains.RemoveAt(thisIndex);
if (gatheredCommandChains.Count == 0)
break;
}
List<Command> optimizedCommandChain = new List<Command>();
Command lastCommand = null;
while (checkables.Count > 1)
{
if (checkables.Count > 0 && checkables.First() != 0)
break;
for (int i = 0; i < checkables.Count;)
{
int thisIndex = checkables[i];
var currentCommandChainInternal = gatheredCommandChains[thisIndex];
var thisCommand = currentCommandChainInternal.Chain.First();
if (i == 0 || (thisCommand.CommandInfo.RawValue == lastCommand.CommandInfo.RawValue && thisCommand.Owner == lastCommand.Owner))
{
// we found a similarity (or the first element), put this into our optimized temp list
lastCommand = thisCommand;
if (i == 0 || (thisCommand.Flags & CommandFlags.Unique) != 0)
optimizedCommandChain.Add(thisCommand);
currentCommandChainInternal.Chain.RemoveAt(0);
if (currentCommandChainInternal.Chain.Count == 0)
{
checkables.RemoveAt(i);
break;
}
else
++i;
}
else
{
// do not check this list further, a difference was detected
checkables.RemoveAt(i);
}
}
// resort our gatheredCommandChains so that we could use the remaining content of a list properly, only do that if the checkable list has no direct preceeding elements ({0,2,3} instead {0,1,2})
if (checkables.Count > 0)
for (int i = checkables.First() + 1; i < checkables.Count; ++i)
if (checkables[i] != i)
{
var tmp = gatheredCommandChains[i];
gatheredCommandChains[i] = gatheredCommandChains[checkables[i]];
gatheredCommandChains[checkables[i]] = tmp;
checkables[i] = i;
}
}
flushedCommands.AddRange(optimizedCommandChain);
}
// remove unnecessary SubChainEnd commands
bool openPass = false;
for (int i = flushedCommands.Count - 1; i >= 0; --i)
{
if ((flushedCommands[i].Flags & CommandFlags.SubChainEnd) == CommandFlags.SubChainEnd)
{
if (!openPass)
openPass = true;
else
flushedCommands.RemoveAt(i);
}
else if ((flushedCommands[i].Flags & CommandFlags.SubChainStart) == CommandFlags.SubChainStart)
openPass = false;
}
optimizedCommandBuffer.BufferedCommands.AddRange(flushedCommands);
}
#endregion
}
}

View File

@@ -0,0 +1,137 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aiwaz.Contracts;
using System.Runtime.InteropServices;
using Aiwaz.Core;
namespace Aiwaz.Resources
{
public enum CommandFlags : byte
{
None = 0x00,
SubChainStart = 0x01, // Command will start a new command chain (UseShader for example)
SubChainEnd = 0x02, // Command will end a command chain (Render)
Unique = 0x04, // Similar commands should not be reduced to one Command
StartChain = 0x08, // Command will generate a new command chain
EndChain = 0x10, // Command will end the command chain (RenderGeometry for example)
FlushChain = 0x20, // Command will end the command chain (RenderGeometry for example)
}
public class Command
{
[StructLayout(LayoutKind.Explicit)]
public struct CommandInfoUnion
{
[FieldOffset(0)]
public uint RawValue;
[FieldOffset(0)]
public byte Priority;
[FieldOffset(1)]
public byte SubPriority;
[FieldOffset(2)]
public CommandFlags Flags;
[FieldOffset(3)]
public byte Type;
}
public Command(CommandUser argOwner, CommandFlags argFlags, byte argType)
: this(argOwner, argFlags, argType, 0, 0)
{
}
public Command(CommandUser argOwner, CommandFlags argFlags, byte argType, byte argPriority)
: this(argOwner, argFlags, argType, argPriority, 0)
{
}
public Command(CommandUser argOwner, CommandFlags argFlags, byte argType, byte argPriority, byte argSubPriority)
{
CommandInfo.RawValue = 0;
Owner = argOwner;
Flags = argFlags;
Priority = argPriority;
SubPriority = argSubPriority;
Type = argType;
}
public CommandInfoUnion CommandInfo;
public byte Priority { get { return CommandInfo.Priority; } set { CommandInfo.Priority = value; } }
public byte SubPriority { get { return CommandInfo.SubPriority; } set { CommandInfo.SubPriority = value; } }
public CommandFlags Flags { get { return CommandInfo.Flags; } set { CommandInfo.Flags = value; } }
public byte Type { get { return CommandInfo.Type; } set { CommandInfo.Type = value; } }
public CommandUser Owner;
};
public enum CommandExecuteResult
{
None, // Execution done, proceed to the next Command
RetrySubChain, // Execution should start from a previous "SubChainStart"-flagged Command
RetrySubChainSkipHead // Equal to the above result but skips the as "SubChainStart"-flagged Command
};
public abstract class CommandUser : Resource, IDisposable
{
private List<RenderCommandNode> assignedRenderCommandNodes = new List<RenderCommandNode>();
public List<Command> Commands { get; private set; }
public bool IsPreconditionForNextCommands { get; set; }
public CommandUser()
{
this.Commands = new List<Command>();
Engine.RegisterEngineDisposable(this);
}
~CommandUser()
{
if (!Engine.Initialized)
return;
if (Engine.UnregisterEngineDisposable(this))
this.Dispose();
}
public abstract CommandExecuteResult ExecuteCommand(byte argCommandType, CommandBuffer argCurrentBuffer, int argCurrentPositon);
public void AssignToRenderCommandNode(RenderCommandNode node)
{
assignedRenderCommandNodes.Add(node);
node.MarkDirty();
}
public void UnassignFromRenderCommandNode(RenderCommandNode node)
{
if (assignedRenderCommandNodes.Remove(node))
node.MarkDirty();
}
protected void UnassignFromSceneNodes()
{
for (var i = 0; i < assignedRenderCommandNodes.Count; ++i )
assignedRenderCommandNodes[i].Children.Remove(this);
assignedRenderCommandNodes.Clear();
}
protected void MarkCommandsAsDirty()
{
foreach (var node in assignedRenderCommandNodes)
node.MarkDirty();
}
public new virtual void Dispose()
{
this.WellKnownName = null;
this.UnassignFromSceneNodes();
Engine.UnregisterEngineDisposable(this);
base.Dispose();
}
}
}

View File

@@ -0,0 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Aiwaz.Resources
{
}

View File

@@ -0,0 +1,554 @@
using System.Collections.Generic;
using Aiwaz.Core;
using Aiwaz.Contracts;
using System;
using System.Linq;
using SlimDX.Direct3D10;
using SlimDX;
using System.Collections.ObjectModel;
namespace Aiwaz.Resources
{
[AiwazResource("Geometry Buffer", "Renderable buffer with vertex or index data.")]
public class GeometryBuffer : CommandUser, IDisposable, IGeometryBuffer
{
#region Constructor
public GeometryBuffer()
: base()
{
Console.WriteLine("Creating GeometryBuffer..");
PrimitiveTopology = PrimitiveTopology.TriangleList;
Commands.Add(new Command(this, CommandFlags.None, SetIndexBufferCommandType, 1));
Commands.Add(new Command(this, CommandFlags.None, SetVertexBufferCommandType, 0));
Commands.Add(new Command(this, CommandFlags.EndChain | CommandFlags.Unique, DrawGeometryCommandType, 6));
}
public GeometryBuffer(IEnumerable<uint> argIndexData, bool argNeedsDynamicAccess)
: this()
{
this.SetIndexData(argIndexData, argNeedsDynamicAccess);
}
public GeometryBuffer(int argIndexCount, SlimDX.DataStream argIndexData, int argVertexCount, SlimDX.DataStream argVertexData, VertexElement[] argVertexElements, bool argNeedsDynamicAccess)
: this()
{
this.SetIndexData(argIndexCount, argIndexData, argNeedsDynamicAccess);
this.SetVertexData(argVertexCount, argVertexData, argVertexElements, argNeedsDynamicAccess);
}
public static GeometryBuffer Create<TVertex>(IEnumerable<TVertex> argVertexData, VertexElement[] argVertexElements, bool argNeedsDynamicAccess) where TVertex : struct
{
var geoBuffer = new GeometryBuffer();
geoBuffer.SetVertexData(argVertexData, argVertexElements, argNeedsDynamicAccess);
return geoBuffer;
}
public static GeometryBuffer Create<TVertex>(IEnumerable<uint> argIndexData, IEnumerable<TVertex> argVertexData, VertexElement[] argVertexElements, bool argNeedsDynamicAccess) where TVertex : struct
{
var geoBuffer = new GeometryBuffer();
geoBuffer.SetIndexData(argIndexData, argNeedsDynamicAccess);
geoBuffer.SetVertexData(argVertexData, argVertexElements, argNeedsDynamicAccess);
return geoBuffer;
}
#endregion
#region Methods
public void SetVertexData(int argVertexCount, DataStream argVertexData, VertexElement[] argVertexElements, bool argNeedsDynamicAccess)
{
Console.WriteLine(string.Format("Vertex data: {0} bytes ({1} elements).", argVertexData.Length, argVertexCount));
var usePickHull = this.IsPickable;
DeleteVertexData();
BufferDescription desc = new BufferDescription((int)argVertexData.Length,
argNeedsDynamicAccess ? ResourceUsage.Dynamic : ResourceUsage.Default,
SlimDX.Direct3D10.BindFlags.VertexBuffer,
argNeedsDynamicAccess ? CpuAccessFlags.Write : 0, ResourceOptionFlags.None);
vertexBuffer = new SlimDX.Direct3D10.Buffer(Engine.Device, argVertexData, desc);
if (vertexBuffer == null)
{
throw new ActionFailedException("GeometryBuffer: Couldn't create vertex buffer!");
}
VertexBufferLength = argVertexCount;
vertexElementSize = (int)argVertexData.Length / argVertexCount;
vertexElements = argVertexElements;
rawVertexData = argVertexData;
if (inputElementDesc == null)
{
if (vertexElements.Length > 0)
{
inputElementDesc = new InputElement[vertexElements.Length];
int i = 0;
foreach (var element in vertexElements)
{
inputElementDesc[i++] = new InputElement(element.SemanticName, element.NameIndex, element.ElementFormat, -1, 0, InputClassification.PerVertexData, 0);
}
}
}
this.IsPickable = usePickHull;
}
public void DeleteVertexData()
{
if (vertexBuffer != null)
Engine.Device.ClearState();
vertexElements = new VertexElement[0];
if (vertexBuffer != null)
vertexBuffer.Dispose();
if (rawVertexData != null)
rawVertexData.Dispose();
vertexBuffer = null;
VertexBufferLength = 0;
vertexElementSize = 0;
rawMappedVertexData = null;
typeMappedVertexData = null;
rawVertexData = null;
inputElementDesc = null;
PickHull = null;
}
public void SetIndexData(int argIndexCount, DataStream argIndexData, bool argNeedsDynamicAccess)
{
Console.WriteLine(string.Format("Index data: {0} bytes ({1} elements).", argIndexData.Length, argIndexCount));
bool usePickHull = this.IsPickable;
DeleteIndexData();
BufferDescription desc = new BufferDescription(
sizeof(uint) * argIndexCount,
ResourceUsage.Default,
SlimDX.Direct3D10.BindFlags.IndexBuffer,
argNeedsDynamicAccess ? CpuAccessFlags.Write : 0, ResourceOptionFlags.None);
indexBuffer = new SlimDX.Direct3D10.Buffer(Engine.Device, argIndexData, desc);
if (indexBuffer == null)
{
throw new ActionFailedException("GeometryBuffer: Couldn't create index buffer!");
}
IndexBufferLength = argIndexCount;
IndexBufferUsableLength = argIndexCount;
IndexBufferOffset = 0;
rawIndexData = argIndexData;
this.IsPickable = usePickHull;
}
public void DeleteIndexData()
{
if (indexBuffer != null)
Engine.Device.ClearState();
if (indexBuffer != null)
indexBuffer.Dispose();
if (rawIndexData != null)
rawIndexData.Dispose();
indexBuffer = null;
rawIndexData = null;
IndexBufferLength = 0;
foreach (var inputLayouts in vertexLayoutsPerShaderAndPass.Values)
foreach (var inputLayout in inputLayouts)
inputLayout.Dispose();
vertexLayoutsPerShaderAndPass.Clear();
PickHull = null;
}
public DataStream MapVertexBufferRaw(MapMode argAccessMode)
{
if (vertexBuffer == null)
throw new NullReferenceException("GeometryBuffer: Access forbidden until resource has been initialized.");
if (rawMappedVertexData != null)
throw new InvalidOperationException("GeometryBuffer: Only one access to the vertex buffer at one time possible.");
try
{
rawMappedVertexData = vertexBuffer.Map(argAccessMode, MapFlags.None);
return rawMappedVertexData;
}
catch (Exception ex)
{
throw new ActionFailedException("GeometryBuffer: Access to the vertex buffer was not successful. " + ex.ToString());
}
}
public void UnmapVertexBuffer()
{
if (vertexBuffer == null)
throw new NullReferenceException("GeometryBuffer: Access forbidden until resource has been initialized.");
if (rawMappedVertexData == null)
throw new InvalidOperationException("GeometryBuffer: No access was done, ending the access to the vertex buffer is not possible.");
if (typeMappedVertexData != null)
{
rawMappedVertexData.Position = 0;
var tmp = (byte[])typeMappedVertexData;
rawMappedVertexData.WriteRange(tmp);
}
vertexBuffer.Unmap();
rawMappedVertexData = null;
typeMappedVertexData = null;
}
public DataStream MapIndexBufferRaw(MapMode argAccessMode)
{
if (indexBuffer == null)
throw new NullReferenceException("GeometryBuffer: Access forbidden until resource has been initialized.");
if (rawMappedIndexData != null)
throw new InvalidOperationException("GeometryBuffer: Only one access to the index buffer at one time possible.");
try
{
rawMappedIndexData = indexBuffer.Map(argAccessMode, MapFlags.None);
return rawMappedIndexData;
}
catch (Exception ex)
{
throw new ActionFailedException("GeometryBuffer: Access to the index buffer was not successful. " + ex.ToString());
}
}
public void UnmapIndexBuffer()
{
if (indexBuffer == null)
throw new NullReferenceException("GeometryBuffer: Access forbidden until resource has been initialized.");
if (rawMappedIndexData == null)
throw new InvalidOperationException("GeometryBuffer: No access was done ending, the access to the index buffer is not possible.");
if (typeMappedIndexData != null)
{
rawMappedIndexData.Position = 0;
rawMappedIndexData.WriteRange(typeMappedIndexData);
}
indexBuffer.Unmap();
rawMappedIndexData = null;
typeMappedIndexData = null;
}
public void ConvertToAdjacency()
{
Console.WriteLine(string.Format("Convert to adjacency."));
switch (PrimitiveTopology)
{
case PrimitiveTopology.LineList:
case PrimitiveTopology.LineStrip:
case PrimitiveTopology.TriangleList:
case PrimitiveTopology.TriangleStrip:
break;
default:
return;
}
InputElement[] inputLayout = new InputElement[2];
inputLayout[0] = new InputElement("POSITION", 0, SlimDX.DXGI.Format.R32G32B32_Float, 0, 0, InputClassification.PerVertexData, 0);
inputLayout[1] = new InputElement("END", 0, SlimDX.DXGI.Format.R8_UInt, vertexElementSize - 1, 0, InputClassification.PerVertexData, 0);
// create the mesh
int numVertices = VertexBufferLength;
int numIndices = IndexBufferLength;
Mesh mesh = null;
try
{
mesh = new Mesh(Engine.Device, inputLayout, inputLayout[0].SemanticName, numVertices, numIndices / 3, MeshFlags.Has32BitIndices);
}
catch (System.Exception ex)
{
throw new ActionFailedException("GeometryBuffer: Unable to create temp. mesh for adjacency data generation. " + ex.ToString());
}
//set the VB
mesh.SetVertexData(0, rawVertexData);
//set the IB
mesh.SetIndexData(rawIndexData, numIndices);
//generate adjacency
const float epsilon = 0.0f;
mesh.GenerateAdjacencyAndPointRepresentation(epsilon);
//generate adjacency indices
mesh.GenerateGeometryShaderAdjacency();
//get the adjacency data out of the mesh
MeshBuffer indexBufferMesh = null;
DataStream adjIndices = null;
try
{
indexBufferMesh = mesh.GetIndexBuffer();
adjIndices = indexBufferMesh.Map();
}
catch (System.Exception ex)
{
throw new ActionFailedException("GeometryBuffer: Unable to retrive indexdata for adjacency data generation. " + ex.ToString());
}
SetIndexData((int)(adjIndices.Length / sizeof(uint)), adjIndices, false);
//cleanup
indexBufferMesh.Unmap();
indexBufferMesh.Dispose();
mesh.Dispose();
switch (this.PrimitiveTopology)
{
case PrimitiveTopology.LineList:
PrimitiveTopology = PrimitiveTopology.LineListWithAdjacency;
break;
case PrimitiveTopology.LineStrip:
PrimitiveTopology = PrimitiveTopology.LineStripWithAdjacency;
break;
case PrimitiveTopology.TriangleList:
PrimitiveTopology = PrimitiveTopology.TriangleListWithAdjacency;
break;
case PrimitiveTopology.TriangleStrip:
PrimitiveTopology = PrimitiveTopology.TriangleStripWithAdjacency;
break;
}
}
private void Render(IShader argShader)
{
if (vertexElements.Length == 0)
return;
if (argShader.Technique == null)
return;
int currentPass = argShader.CurrentPass;
EffectPass currentEffectPass = argShader.Technique.GetPassByIndex(currentPass);
InputLayout vertexLayout = null;
List<InputLayout> ilList;
if (vertexLayoutsPerShaderAndPass.TryGetValue(argShader, out ilList) && ilList.Count > currentPass)
{
vertexLayout = ilList[currentPass];
}
else
{
vertexLayout = new InputLayout(Engine.Device, inputElementDesc, currentEffectPass.Description.Signature);
if (vertexLayout != null)
{
if (ilList == null)
{
ilList = new List<InputLayout>();
ilList.Add(vertexLayout);
vertexLayoutsPerShaderAndPass[argShader] = ilList;
}
else
{
ilList.Add(vertexLayout);
}
}
}
if (vertexLayout != null)
{
currentEffectPass.Apply();
Engine.Device.InputAssembler.SetInputLayout(vertexLayout);
if (indexBuffer == null)
Engine.Device.Draw(VertexBufferLength, 0);
else
Engine.Device.DrawIndexed(IndexBufferUsableLength, IndexBufferOffset, 0);
}
}
#endregion
#region Properties
public int IndexBufferOffset { get; set; }
public int IndexBufferUsableLength { get; set; }
public int IndexBufferLength { get; private set; }
public int VertexBufferLength { get; private set; }
public PrimitiveTopology PrimitiveTopology { get; set; }
public bool IsPickable
{
get
{
return this.PickHull != null;
}
set
{
if (this.IsPickable == value)
return;
this.PickHull = new PickHull(rawVertexData, VertexBufferLength, vertexElements, rawIndexData, IndexBufferLength);
}
}
public IPickHull PickHull { get; protected set; }
#endregion
#region Constants
public static byte SetIndexBufferCommandType = 0;
public static byte SetVertexBufferCommandType = 1;
public static byte DrawGeometryCommandType = 2;
#endregion
#region Private members
SlimDX.Direct3D10.Buffer indexBuffer;
DataStream rawIndexData;
uint[] typeMappedIndexData;
DataStream rawMappedIndexData;
int vertexElementSize;
SlimDX.Direct3D10.Buffer vertexBuffer;
DataStream rawVertexData;
object typeMappedVertexData;
Type typeMappedVertexDataType;
DataStream rawMappedVertexData;
VertexElement[] vertexElements;
InputElement[] inputElementDesc;
Dictionary<IShader, List<InputLayout>> vertexLayoutsPerShaderAndPass = new Dictionary<IShader, List<InputLayout>>();
#endregion
#region CommandUser Members
public override CommandExecuteResult ExecuteCommand(byte argCommandType, CommandBuffer argCurrentBuffer, int argCurrentPositon)
{
if (argCommandType == GeometryBuffer.SetIndexBufferCommandType)
{
if (Engine.EngineStates.LastIndexBufferProvider != this)
{
Engine.Device.InputAssembler.SetIndexBuffer(indexBuffer, SlimDX.DXGI.Format.R32_UInt, IndexBufferOffset);
Engine.EngineStates.LastIndexBufferProvider = this;
}
}
else if (argCommandType == GeometryBuffer.SetVertexBufferCommandType)
{
if (Engine.EngineStates.LastVertexBufferProvider != this)
{
Engine.Device.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertexBuffer, vertexElementSize, 0));
Engine.Device.InputAssembler.SetPrimitiveTopology(PrimitiveTopology);
Engine.EngineStates.LastVertexBufferProvider = this;
}
}
else if (argCommandType == GeometryBuffer.DrawGeometryCommandType)
{
if (Engine.EngineStates.LastShader == null)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("GeometryBuffer could not render without a valid shader.");
Console.ForegroundColor = ConsoleColor.White;
}
else if (Engine.EngineStates.LastVertexBufferProvider == null)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("GeometryBuffer could not render without a valid vertex buffer.");
Console.ForegroundColor = ConsoleColor.White;
}
else
{
Render(Engine.EngineStates.LastShader);
}
}
return CommandExecuteResult.None;
}
#endregion
#region IDisposable Members
void IDisposable.Dispose()
{
if (Engine.EngineStates.LastIndexBufferProvider == this)
Engine.EngineStates.LastIndexBufferProvider = null;
if (Engine.EngineStates.LastVertexBufferProvider == this)
Engine.EngineStates.LastVertexBufferProvider = null;
DeleteVertexData();
DeleteIndexData();
base.Dispose();
}
#endregion
public override ICreationParams CreationParams
{
get { return null; }
}
public override ObservableCollection<IResource> Children
{
get { return null; }
}
#region IGeometryBuffer Members
public void SetIndexData(IEnumerable<uint> argIndexData, bool argNeedsDynamicAccess)
{
this.SetIndexData(argIndexData.Count(), new DataStream(argIndexData.ToArray(), true, true), argNeedsDynamicAccess);
}
public uint[] MapIndexBuffer(MapMode argAccessMode)
{
var rawData = this.MapIndexBufferRaw(argAccessMode);
this.typeMappedIndexData = new uint[this.IndexBufferLength];
rawData.Position = 0;
rawData.ReadRange(this.typeMappedIndexData, 0, this.IndexBufferLength);
rawData.Position = 0;
return this.typeMappedIndexData;
}
#endregion
#region IGeometryBuffer<TVertex> Members
public void SetVertexData<TVertex>(IEnumerable<TVertex> argVertexData, VertexElement[] argVertexElements, bool argNeedsDynamicAccess) where TVertex : struct
{
this.SetVertexData(argVertexData.Count(), new DataStream(argVertexData.ToArray(), true, true), argVertexElements, argNeedsDynamicAccess);
}
public TVertex[] MapVertexBuffer<TVertex>(MapMode argAccessMode) where TVertex : struct
{
var rawData = this.MapVertexBufferRaw(argAccessMode);
typeMappedVertexDataType = typeof(TVertex);
var tmp = new TVertex[this.VertexBufferLength];
typeMappedVertexData = tmp;
rawData.Position = 0;
rawData.ReadRange<TVertex>(tmp, 0, this.VertexBufferLength);
rawData.Position = 0;
return tmp;
}
#endregion
};
}

View File

@@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aiwaz.Contracts;
using SlimDX;
namespace Aiwaz.Resources
{
public class PickHull : IPickHull
{
private VertexElement positionElement;
private int strideToPosition;
private DataStream vertexData;
private int vertexCount;
private VertexElement[] vertexElements;
private int vertexElementSize;
private DataStream indexData;
private int indexCount;
private Vector3 boxMaxVector;
private Vector3 boxMinVector;
public PickHull(DataStream vertexData, int vertexCount, VertexElement[] vertexElements, DataStream indexData, int indexCount)
{
this.vertexData = vertexData;
this.vertexCount = vertexCount;
this.vertexElements = vertexElements;
this.indexData = indexData;
this.indexCount = indexCount;
this.vertexElementSize = (int)vertexData.Length / vertexCount;
this.positionElement = vertexElements.First(e => e.WellKnownFormat == VertexElement.Format.Position);
foreach (var element in vertexElements)
{
if (!element.Equals(positionElement))
strideToPosition += element.Size;
else
break;
}
this.Precalculate();
}
public bool TryPick(Ray pickRay, Matrix worldMatrix, out float distance)
{
distance = float.MaxValue;
var boundingSphere = CalcBoundingSphere(worldMatrix);
if (!Ray.Intersects(pickRay, boundingSphere, out distance))
return false;
distance = float.MaxValue;
indexData.Position = 0;
for (var i = 0; i < indexCount / 3; ++i)
{
var triangle = new Vector3[3];
triangle[0] = Vector3.TransformCoordinate(this.GetPositionFromData(indexData.Read<uint>()), worldMatrix);
triangle[1] = Vector3.TransformCoordinate(this.GetPositionFromData(indexData.Read<uint>()), worldMatrix);
triangle[2] = Vector3.TransformCoordinate(this.GetPositionFromData(indexData.Read<uint>()), worldMatrix);
float newDistance;
if (!Ray.Intersects(pickRay, triangle[0], triangle[1], triangle[2], out newDistance)
|| newDistance > distance)
continue;
distance = newDistance;
}
return distance != float.MaxValue;
}
private Vector3 GetPositionFromData(uint index)
{
vertexData.Position = index * vertexElementSize + strideToPosition;
return vertexData.Read<Vector3>();
}
protected void Precalculate()
{
boxMinVector = Vector3.Zero;
boxMaxVector = Vector3.Zero;
for (uint i = 0; i < vertexCount; ++i)
{
boxMinVector = i == 0 ? this.GetPositionFromData(i) : Vector3.Maximize(boxMinVector, this.GetPositionFromData(i));
boxMaxVector = i == 0 ? this.GetPositionFromData(i) : Vector3.Minimize(boxMaxVector, this.GetPositionFromData(i));
}
}
public BoundingSphere CalcBoundingSphere(Matrix worldMatrix)
{
var centerPosition = Vector3.TransformCoordinate(Vector3.Zero, worldMatrix);
var maxVec = Vector3.TransformCoordinate(boxMaxVector, worldMatrix);
return new BoundingSphere(centerPosition, maxVec.Length());
}
public BoundingBox CalcBoundingBox(Matrix worldMatrix)
{
var minVec = Vector3.TransformCoordinate(boxMinVector, worldMatrix);
var maxVec = Vector3.TransformCoordinate(boxMaxVector, worldMatrix);
return new BoundingBox(minVec, maxVec);
}
}
}

View File

@@ -0,0 +1,133 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aiwaz.Contracts;
using SlimDX;
using Aiwaz.Resources.Attributes;
using System.Collections.ObjectModel;
namespace Aiwaz.Resources.Prefab
{
[CreationParameters("Standard unity-sized non-inverted cube")]
public class CubeParams : ICreationParams
{
public float Width;
public float Height;
public float Depth;
public bool IsInverted;
public CubeParams()
{
Width = 1.0f;
Height = 1.0f;
Depth = 1.0f;
IsInverted = false;
}
}
[AiwazResource("Cube", "A simple non-uniform cube")]
public class Cube : Resource
{
public struct CommonCubeVertex
{
public CommonCubeVertex(SlimDX.Vector3 pos,
SlimDX.Vector3 normal,
SlimDX.Vector3 tangent,
SlimDX.Vector2 tex)
{
this.Pos = pos;
this.Normal = normal;
this.Tangent = tangent;
this.Tex = tex;
}
public SlimDX.Vector3 Pos;
public SlimDX.Vector3 Normal;
public SlimDX.Vector3 Tangent;
public SlimDX.Vector2 Tex;
};
public GeometryBuffer GeometryBuffer { get; protected set; }
public Cube(CubeParams parameters)
{
creationParams = parameters;
float width = parameters.Width * 0.5f;
float height = parameters.Height * 0.5f;
float depth = parameters.Depth * 0.5f;
float normal = parameters.IsInverted ? -1.0f : 1.0f;
float tangent = 1.0f;//isInverted ? -1.0f : 1.0f;
CommonCubeVertex[] vertices = new CommonCubeVertex[]
{
new CommonCubeVertex ( new SlimDX.Vector3( -width, height, -depth ), new SlimDX.Vector3(0.0f, normal, 0.0f), new SlimDX.Vector3(-tangent, 0.0f, 0.0f), new SlimDX.Vector2( 0.0f, 0.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( width, height, -depth ), new SlimDX.Vector3(0.0f, normal, 0.0f), new SlimDX.Vector3(-tangent, 0.0f, 0.0f), new SlimDX.Vector2( 1.0f, 0.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( width, height, depth ), new SlimDX.Vector3(0.0f, normal, 0.0f), new SlimDX.Vector3(-tangent, 0.0f, 0.0f), new SlimDX.Vector2( 1.0f, 1.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( -width, height, depth ), new SlimDX.Vector3(0.0f, normal, 0.0f), new SlimDX.Vector3(-tangent, 0.0f, 0.0f), new SlimDX.Vector2( 0.0f, 1.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( -width, -height, -depth ), new SlimDX.Vector3(0.0f, -normal, 0.0f), new SlimDX.Vector3(-tangent, 0.0f, 0.0f), new SlimDX.Vector2( 0.0f, 0.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( width, -height, -depth ), new SlimDX.Vector3(0.0f, -normal, 0.0f), new SlimDX.Vector3(-tangent, 0.0f, 0.0f), new SlimDX.Vector2( 1.0f, 0.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( width, -height, depth ), new SlimDX.Vector3(0.0f, -normal, 0.0f), new SlimDX.Vector3(-tangent, 0.0f, 0.0f), new SlimDX.Vector2( 1.0f, 1.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( -width, -height, depth ), new SlimDX.Vector3(0.0f, -normal, 0.0f), new SlimDX.Vector3(-tangent, 0.0f, 0.0f), new SlimDX.Vector2( 0.0f, 1.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( -width, -height, depth ), new SlimDX.Vector3(-normal, 0.0f, 0.0f), new SlimDX.Vector3(0.0f, tangent, 0.0f), new SlimDX.Vector2( 0.0f, 1.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( -width, -height, -depth ), new SlimDX.Vector3(-normal, 0.0f, 0.0f), new SlimDX.Vector3(0.0f, tangent, 0.0f), new SlimDX.Vector2( 1.0f, 1.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( -width, height, -depth ), new SlimDX.Vector3(-normal, 0.0f, 0.0f), new SlimDX.Vector3(0.0f, tangent, 0.0f), new SlimDX.Vector2( 1.0f, 0.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( -width, height, depth ), new SlimDX.Vector3(-normal, 0.0f, 0.0f), new SlimDX.Vector3(0.0f, tangent, 0.0f), new SlimDX.Vector2( 0.0f, 0.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( width, -height, depth ), new SlimDX.Vector3(normal, 0.0f, 0.0f), new SlimDX.Vector3(0.0f, -tangent, 0.0f), new SlimDX.Vector2( 1.0f, 1.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( width, -height, -depth ), new SlimDX.Vector3(normal, 0.0f, 0.0f), new SlimDX.Vector3(0.0f, -tangent, 0.0f), new SlimDX.Vector2( 0.0f, 1.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( width, height, -depth ), new SlimDX.Vector3(normal, 0.0f, 0.0f), new SlimDX.Vector3(0.0f, -tangent, 0.0f), new SlimDX.Vector2( 0.0f, 0.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( width, height, depth ), new SlimDX.Vector3(normal, 0.0f, 0.0f), new SlimDX.Vector3(0.0f, -tangent, 0.0f), new SlimDX.Vector2( 1.0f, 0.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( -width, -height, -depth ), new SlimDX.Vector3(0.0f, 0.0f, -normal), new SlimDX.Vector3(-tangent, 0.0f, 0.0f), new SlimDX.Vector2( 0.0f, 1.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( width, -height, -depth ), new SlimDX.Vector3(0.0f, 0.0f, -normal), new SlimDX.Vector3(-tangent, 0.0f, 0.0f), new SlimDX.Vector2( 1.0f, 1.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( width, height, -depth ), new SlimDX.Vector3(0.0f, 0.0f, -normal), new SlimDX.Vector3(-tangent, 0.0f, 0.0f), new SlimDX.Vector2( 1.0f, 0.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( -width, height, -depth ), new SlimDX.Vector3(0.0f, 0.0f, -normal), new SlimDX.Vector3(-tangent, 0.0f, 0.0f), new SlimDX.Vector2( 0.0f, 0.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( -width, -height, depth ), new SlimDX.Vector3(0.0f, 0.0f, normal), new SlimDX.Vector3(-tangent, 0.0f, 0.0f), new SlimDX.Vector2( 1.0f, 1.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( width, -height, depth ), new SlimDX.Vector3(0.0f, 0.0f, normal), new SlimDX.Vector3(-tangent, 0.0f, 0.0f), new SlimDX.Vector2( 0.0f, 1.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( width, height, depth ), new SlimDX.Vector3(0.0f, 0.0f, normal), new SlimDX.Vector3(-tangent, 0.0f, 0.0f), new SlimDX.Vector2( 0.0f, 0.0f ) ),
new CommonCubeVertex ( new SlimDX.Vector3( -width, height, depth ), new SlimDX.Vector3(0.0f, 0.0f, normal), new SlimDX.Vector3(-tangent, 0.0f, 0.0f), new SlimDX.Vector2( 1.0f, 0.0f ) ),
};
var vertexElements = new VertexElement[]
{
new VertexElement(VertexElement.Format.Position),
new VertexElement(VertexElement.Format.Normal),
new VertexElement(VertexElement.Format.Tangent),
new VertexElement(VertexElement.Format.Texture2D)
};
var invertedIndices = new uint[] { 0,1,3, 3,1,2, 5,4,6, 6,4,7, 8,9,11, 11,9,10, 13,12,14, 14,12,15, 16,17,19, 19,17,18, 21,20,22, 22,20,23 };
var normalIndices = new uint[] { 3,1,0, 2,1,3, 6,4,5, 7,4,6, 11,9,8, 10,9,11, 14,12,13, 15,12,14, 19,17,16, 18,17,19, 22,20,21, 23,20,22 };
this.GeometryBuffer = GeometryBuffer.Create<CommonCubeVertex>(
parameters.IsInverted ? invertedIndices : normalIndices,
vertices,
vertexElements,
false);
}
private ICreationParams creationParams;
public override ICreationParams CreationParams
{
get { return creationParams; }
}
private ObservableCollection<IResource> children;
[ReadOnly]
public override ObservableCollection<IResource> Children
{
get
{
if (children == null)
{
children = new ObservableCollection<IResource>();
children.Add(GeometryBuffer);
}
return children;
}
}
}
}

View File

@@ -0,0 +1,135 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aiwaz.Contracts;
using Aiwaz.Resources.Attributes;
using System.Collections.ObjectModel;
namespace Aiwaz.Resources.Prefab
{
public struct PingPongBufferDescription
{
public int LoopCount;
public string ShaderFileName;
public string ShaderTechniqueA;
public string ShaderTechniqueB;
public string PreProcessShaderTechnique;
public int TextureWidth;
public int TextureHeight;
public SlimDX.DXGI.Format TextureFormat;
};
[CreationParameters("Standard ping-pong buffer")]
public class PingPongBufferParams : ICreationParams
{
public PingPongBufferDescription Desc;
public Texture InputTexture;
public PingPongBufferParams()
{
}
}
[AiwazResource("PingPong buffer", "Two buffers that alternate each other")]
public class PingPongBuffer : Resource
{
public Texture InputTexture { get; protected set;}
public Texture OutputTexture { get { return textureB.Texture; } }
public RenderCommandNode RootNode { get; protected set; }
public RenderCommandNode PreProcessNode { get; protected set; }
RenderCommandNode renderTargetNodeA;
RenderCommandNode renderTargetNodeB;
Shader shaderA;
Shader shaderB;
Shader shaderPreProcess;
RenderTargetTexture textureA;
RenderTargetTexture textureB;
GeometryBuffer screenQuad;
ShaderParameterSet shaderParameterA;
ShaderParameterSet shaderParameterB;
ShaderParameterSet shaderParameterPreProcess;
public PingPongBuffer(PingPongBufferParams parameters)
{
creationParams = parameters;
if (string.IsNullOrEmpty(parameters.Desc.ShaderFileName))
throw new ArgumentNullException("ShaderFileName");
shaderA = new Shader(new ShaderParams() { FileName = parameters.Desc.ShaderFileName, TechniqueName = parameters.Desc.ShaderTechniqueA } );
shaderB = new Shader(new ShaderParams() { FileName = parameters.Desc.ShaderFileName, TechniqueName = parameters.Desc.ShaderTechniqueB } );
shaderPreProcess = new Shader(new ShaderParams() { FileName = parameters.Desc.ShaderFileName, TechniqueName = parameters.Desc.PreProcessShaderTechnique });
textureA = new RenderTargetTexture(new RenderTargetTextureParams() { width = parameters.Desc.TextureWidth, height = parameters.Desc.TextureHeight, format = parameters.Desc.TextureFormat } );
textureB = new RenderTargetTexture(new RenderTargetTextureParams() { width = parameters.Desc.TextureWidth, height = parameters.Desc.TextureHeight, format = parameters.Desc.TextureFormat } );
shaderParameterA = new ShaderParameterSet();
shaderParameterA.SetParameter("InputTexture", textureB.Texture, ParameterBindType.BindBySemantic);
shaderParameterB = new ShaderParameterSet();
shaderParameterB.SetParameter("InputTexture", textureA.Texture, ParameterBindType.BindBySemantic);
this.InputTexture = parameters.InputTexture;
shaderParameterPreProcess = new ShaderParameterSet();
shaderParameterPreProcess.SetParameter("InputTexture", this.InputTexture, ParameterBindType.BindBySemantic);
var quad = new Quad(new QuadParams() { Width = 2.0f, Height = 2.0f } );
screenQuad = quad.GeometryBuffer;
renderTargetNodeA = new RenderCommandNode();
renderTargetNodeA.Children.Add(textureA);
renderTargetNodeA.Children.Add(shaderA);
renderTargetNodeA.Children.Add(shaderParameterA);
renderTargetNodeA.Children.Add(screenQuad);
renderTargetNodeB = new RenderCommandNode();
renderTargetNodeB.Children.Add(textureB);
renderTargetNodeB.Children.Add(shaderB);
renderTargetNodeB.Children.Add(shaderParameterB);
renderTargetNodeB.Children.Add(screenQuad);
this.RootNode = new RenderCommandNode();
this.PreProcessNode = new RenderCommandNode();
// preprocessing
this.RootNode.Children.Add(textureB);
this.RootNode.Children.Add(shaderPreProcess);
this.RootNode.Children.Add(shaderParameterPreProcess);
this.RootNode.Children.Add(screenQuad);
this.RootNode.Children.Add(this.PreProcessNode);
// real pingpongs
for (int i = 0; i < parameters.Desc.LoopCount; ++i)
{
this.RootNode.Children.Add(renderTargetNodeA);
this.RootNode.Children.Add(renderTargetNodeB);
}
}
private ICreationParams creationParams;
public override ICreationParams CreationParams
{
get { return creationParams; }
}
private ObservableCollection<IResource> children;
[ReadOnly]
public override ObservableCollection<IResource> Children
{
get
{
if (children == null)
{
children = new ObservableCollection<IResource>();
children.Add(InputTexture);
children.Add(OutputTexture);
children.Add(RootNode);
children.Add(PreProcessNode);
}
return children;
}
}
}
}

View File

@@ -0,0 +1,119 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aiwaz.Contracts;
using SlimDX;
using Aiwaz.Resources.Attributes;
using System.Collections.ObjectModel;
namespace Aiwaz.Resources.Prefab
{
[CreationParameters("Unity-sized one-sided quad")]
public class QuadParams : ICreationParams
{
public float Width;
public float Height;
public bool IsTwoSided;
public QuadParams()
{
Width = 1.0f;
Height = 1.0f;
IsTwoSided = false;
}
}
[AiwazResource("Quad", "A simple 2d non-uniform Quad")]
public class Quad : Resource
{
public struct CommonQuadVertex
{
public CommonQuadVertex(SlimDX.Vector3 pos,
SlimDX.Vector3 normal,
SlimDX.Vector2 tex)
{
this.Pos = pos;
this.Normal = normal;
this.Tex = tex;
}
public SlimDX.Vector3 Pos;
public SlimDX.Vector3 Normal;
public SlimDX.Vector2 Tex;
};
public GeometryBuffer GeometryBuffer { get; protected set; }
public Quad(QuadParams parameters)
{
this.creationParams = parameters;
float width = parameters.Width * 0.5f;
float height = parameters.Height * 0.5f;
CommonQuadVertex[] quadOneSidedVertices = new CommonQuadVertex[]
{
new CommonQuadVertex( new SlimDX.Vector3( -width, height, 0.0f ), new SlimDX.Vector3(0.0f, 0.0f, -1.0f), new SlimDX.Vector2( 0.0f, 0.0f ) ),
new CommonQuadVertex( new SlimDX.Vector3( width, -height, 0.0f ), new SlimDX.Vector3(0.0f, 0.0f, -1.0f), new SlimDX.Vector2( 1.0f, 1.0f ) ),
new CommonQuadVertex( new SlimDX.Vector3( -width, -height, 0.0f ), new SlimDX.Vector3(0.0f, 0.0f, -1.0f), new SlimDX.Vector2( 0.0f, 1.0f ) ),
new CommonQuadVertex( new SlimDX.Vector3( -width, height, 0.0f ), new SlimDX.Vector3(0.0f, 0.0f, -1.0f), new SlimDX.Vector2( 0.0f, 0.0f ) ),
new CommonQuadVertex( new SlimDX.Vector3( width, height, 0.0f ), new SlimDX.Vector3(0.0f, 0.0f, -1.0f), new SlimDX.Vector2( 1.0f, 0.0f ) ),
new CommonQuadVertex( new SlimDX.Vector3( width, -height, 0.0f ), new SlimDX.Vector3(0.0f, 0.0f, -1.0f), new SlimDX.Vector2( 1.0f, 1.0f ) ),
};
CommonQuadVertex[] quadTwoSidedVertices = new CommonQuadVertex[]
{
new CommonQuadVertex( new SlimDX.Vector3( -width, height, 0.0f ), new SlimDX.Vector3(0.0f, 0.0f, -1.0f), new SlimDX.Vector2( 0.0f, 0.0f ) ),
new CommonQuadVertex( new SlimDX.Vector3( width, -height, 0.0f ), new SlimDX.Vector3(0.0f, 0.0f, -1.0f), new SlimDX.Vector2( 1.0f, 1.0f ) ),
new CommonQuadVertex( new SlimDX.Vector3( -width, -height, 0.0f ), new SlimDX.Vector3(0.0f, 0.0f, -1.0f), new SlimDX.Vector2( 0.0f, 1.0f ) ),
new CommonQuadVertex( new SlimDX.Vector3( -width, height, 0.0f ), new SlimDX.Vector3(0.0f, 0.0f, -1.0f), new SlimDX.Vector2( 0.0f, 0.0f ) ),
new CommonQuadVertex( new SlimDX.Vector3( width, height, 0.0f ), new SlimDX.Vector3(0.0f, 0.0f, -1.0f), new SlimDX.Vector2( 1.0f, 0.0f ) ),
new CommonQuadVertex( new SlimDX.Vector3( width, -height, 0.0f ), new SlimDX.Vector3(0.0f, 0.0f, -1.0f), new SlimDX.Vector2( 1.0f, 1.0f ) ),
new CommonQuadVertex( new SlimDX.Vector3( -width, height, 0.0f ), new SlimDX.Vector3(0.0f, 0.0f, 1.0f), new SlimDX.Vector2( 1.0f, 0.0f ) ),
new CommonQuadVertex( new SlimDX.Vector3( width, -height, 0.0f ), new SlimDX.Vector3(0.0f, 0.0f, 1.0f), new SlimDX.Vector2( 0.0f, 1.0f ) ),
new CommonQuadVertex( new SlimDX.Vector3( -width, -height, 0.0f ), new SlimDX.Vector3(0.0f, 0.0f, 1.0f), new SlimDX.Vector2( 1.0f, 1.0f ) ),
new CommonQuadVertex( new SlimDX.Vector3( -width, height, 0.0f ), new SlimDX.Vector3(0.0f, 0.0f, 1.0f), new SlimDX.Vector2( 1.0f, 0.0f ) ),
new CommonQuadVertex( new SlimDX.Vector3( width, height, 0.0f ), new SlimDX.Vector3(0.0f, 0.0f, 1.0f), new SlimDX.Vector2( 0.0f, 0.0f ) ),
new CommonQuadVertex( new SlimDX.Vector3( width, -height, 0.0f ), new SlimDX.Vector3(0.0f, 0.0f, 1.0f), new SlimDX.Vector2( 0.0f, 1.0f ) ),
};
var vertexElements = new VertexElement[]
{
new VertexElement(VertexElement.Format.Position),
new VertexElement(VertexElement.Format.Normal),
new VertexElement(VertexElement.Format.Texture2D)
};
var oneSidedIndices = new uint[] { 0,1,2, 3,4,5 };
var twoSidedIndices = new uint[] { 0, 1, 2, 3, 4, 5, 11, 10, 9, 8, 7, 6 };
this.GeometryBuffer = GeometryBuffer.Create<CommonQuadVertex>(
parameters.IsTwoSided ? twoSidedIndices : oneSidedIndices,
parameters.IsTwoSided ? quadTwoSidedVertices : quadOneSidedVertices,
vertexElements,
false);
}
private ICreationParams creationParams;
public override ICreationParams CreationParams
{
get { return creationParams; }
}
private ObservableCollection<IResource> children;
[ReadOnly]
public override ObservableCollection<IResource> Children
{
get
{
if (children == null)
{
children = new ObservableCollection<IResource>();
children.Add(GeometryBuffer);
}
return children;
}
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("AiwazResources")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("AiwazResources")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("db9f92df-997d-4870-b687-8cc93789465e")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,179 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aiwaz.Contracts;
using Aiwaz.Core;
using Aiwaz.Resources.Attributes;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
namespace Aiwaz.Resources
{
[AiwazResource("RenderCommand Node", "Node to update and perform other nodes.")]
public class RenderCommandNode : CommandUser, IUpdatable
{
#region IRenderCommandNode Members
private ObservableCollection<IResource> children;
public CommandBuffer CommandBuffer { get; protected set; }
public bool IsDirty { get; protected set;}
public RenderCommandNode ParentRenderCommandNode { get; set; }
public RenderCommandNode()
{
Console.WriteLine(string.Format("Creating RenderCommandNode.."));
children = new ObservableCollection<IResource>();
children.CollectionChanged += new NotifyCollectionChangedEventHandler(children_CollectionChanged);
CommandBuffer = new CommandBuffer();
}
void children_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
List<CommandUser> commandUsers = new List<CommandUser>();
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (IResource resource in e.NewItems)
GetCommandUsers(resource, ref commandUsers);
foreach (CommandUser user in commandUsers)
{
user.AssignToRenderCommandNode(this);
var node = user as RenderCommandNode;
if (node != null)
node.ParentRenderCommandNode = this;
}
this.MarkDirty();
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
foreach (IResource resource in e.OldItems)
GetCommandUsers(resource, ref commandUsers);
foreach (CommandUser user in commandUsers)
{
var node = user as RenderCommandNode;
if (node != null)
node.ParentRenderCommandNode = null;
user.UnassignFromRenderCommandNode(this);
}
this.MarkDirty();
}
}
public void MarkDirty()
{
IsDirty = true;
if (ParentRenderCommandNode != null)
ParentRenderCommandNode.MarkDirty();
}
public void ProcessCommands()
{
if (IsDirty)
{
this.GenerateDeviceCommands();
CommandBuffer.Optimize();
}
CommandBuffer.Perform(true);
}
public void GenerateDeviceCommands()
{
if (!IsDirty)
return;
IsDirty = false;
CommandBuffer.Clear();
List<CommandUser> commandUsers = new List<CommandUser>();
foreach (var child in children)
GetCommandUsers(child, ref commandUsers);
foreach (CommandUser user in commandUsers)
{
// Add the commands all commands
CommandBuffer.BufferedCommands.AddRange(user.Commands);
// Walk further if we found another RenderCommandNode
var node = user as RenderCommandNode;
if (node != null)
{
node.GenerateDeviceCommands();
// Merge the buffers
CommandBuffer.AddChildCommandBuffer(node.CommandBuffer);
}
}
}
private void GetCommandUsers(IResource resource, ref List<CommandUser> commandUsers)
{
if (resource as CommandUser != null)
commandUsers.Add(resource as CommandUser);
else foreach (var child in resource.Children)
GetCommandUsers(child, ref commandUsers);
}
#endregion
public override CommandExecuteResult ExecuteCommand(byte argCommandType, CommandBuffer argCurrentBuffer, int argCurrentPositon)
{
return CommandExecuteResult.None;
}
#region IUpdatable Members
public void Update(bool forceUpdate)
{
List<CommandUser> commandUsers = new List<CommandUser>();
foreach (var child in children)
GetCommandUsers(child, ref commandUsers);
// Walk through all updatables and update them.
foreach (var user in commandUsers)
{
var updatable = user as IUpdatable;
if (updatable != null && (updatable.WantsUpdate || forceUpdate))
updatable.Update(forceUpdate);
}
}
public bool WantsUpdate
{
get { return true; }
}
#endregion
#region IDisposable Members
public override void Dispose()
{
if (ParentRenderCommandNode != null)
ParentRenderCommandNode.Children.Remove(this);
while (Children.Count > 0)
Children.RemoveAt(0);
base.Dispose();
}
#endregion
public override ICreationParams CreationParams
{
get { return null; }
}
public override ObservableCollection<IResource> Children
{
get { return children; }
}
}
}

View File

@@ -0,0 +1,296 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aiwaz.Contracts;
using Aiwaz.Core;
namespace Aiwaz.Resources
{
public abstract class RenderTarget : CommandUser, IRenderTargetBase, IDisposable
{
public RenderTarget()
: base()
{
Commands.Add(new Command(this, CommandFlags.EndChain | CommandFlags.FlushChain, setRenderTargetCommandType, 0, 0));
this.ClearDepth = 1.0f;
}
~RenderTarget()
{
if (Engine.Initialized)
this.Dispose();
}
#region IRenderTargetBase Members
internal static SlimDX.Direct3D10.ShaderResourceView[] emptyShaderResView = new SlimDX.Direct3D10.ShaderResourceView[128];
private SlimDX.Direct3D10.RenderTargetView[] renderTargetViews;
private List<IRenderTargetBase> additionalRenderTargets = new List<IRenderTargetBase>();
private SlimDX.Direct3D10.Viewport[] viewports;
protected int multiSampleCount = 1;
protected int multiSampleQuality = 0;
private BindFlags lastBindFlags = BindFlags.Default;
public float ClearDepth { get; set; }
public byte ClearStencil { get; set; }
public SlimDX.Color4 ClearColor { get; set; }
private ViewPort viewPort;
public ViewPort ViewPort
{
get { return viewPort; }
set
{
viewPort = value;
this.KillViewPortAndRenderTargetData();
this.BuildViewPortAndRenderTargetData();
}
}
public abstract int RenderTargetWidth { get; }
public abstract int RenderTargetHeight { get; }
public abstract SlimDX.DXGI.Format RenderTargetFormat { get; }
private bool hasDepthStencilBuffer;
public bool HasDepthStencilBuffer
{
get { return hasDepthStencilBuffer; }
set
{
hasDepthStencilBuffer = value;
Engine.Device.ClearState();
if (DX10DepthStencilView != null)
DX10DepthStencilView.Dispose();
DX10DepthStencilView = null;
if (DX10DepthStencilTexture != null)
DX10DepthStencilTexture.Dispose();
DX10DepthStencilTexture = null;
if (!hasDepthStencilBuffer)
return; // no further effort needed here
var depthTextureDesc = new SlimDX.Direct3D10.Texture2DDescription()
{
Width = this.RenderTargetWidth,
Height = this.RenderTargetHeight,
MipLevels = 1,
ArraySize = 1,
Format = SlimDX.DXGI.Format.D24_UNorm_S8_UInt,
SampleDescription = new SlimDX.DXGI.SampleDescription(multiSampleCount == 0 ? 1 : multiSampleCount, multiSampleQuality),
Usage = SlimDX.Direct3D10.ResourceUsage.Default,
BindFlags = SlimDX.Direct3D10.BindFlags.DepthStencil,
CpuAccessFlags = SlimDX.Direct3D10.CpuAccessFlags.None,
OptionFlags = SlimDX.Direct3D10.ResourceOptionFlags.None
};
DX10DepthStencilTexture = new SlimDX.Direct3D10.Texture2D(Engine.Device, depthTextureDesc);
if (DX10DepthStencilTexture == null)
throw new Aiwaz.Core.ActionFailedException("RenderTarget: Unable to create depth stencil texture.");
var depthStencilViewDesc = new SlimDX.Direct3D10.DepthStencilViewDescription()
{
Format = depthTextureDesc.Format,
Dimension = multiSampleCount >= 1 ? SlimDX.Direct3D10.DepthStencilViewDimension.Texture2DMultisampled : SlimDX.Direct3D10.DepthStencilViewDimension.Texture2D,
MipSlice = 0
};
DX10DepthStencilView = new SlimDX.Direct3D10.DepthStencilView(Engine.Device, DX10DepthStencilTexture, depthStencilViewDesc);
if (DX10DepthStencilView == null)
throw new Aiwaz.Core.ActionFailedException("RenderTarget: Unable to create depth stencil view.");
}
}
public SlimDX.Direct3D10.RenderTargetView DX10RenderTargetView { get; protected set; }
public SlimDX.Direct3D10.DepthStencilView DX10DepthStencilView { get; protected set; }
public SlimDX.Direct3D10.Texture2D DX10DepthStencilTexture { get; protected set; }
public void AddAdditionalRenderTarget(IRenderTargetBase target)
{
this.RemoveAdditionalRenderTarget(target);
//if (AdditionalRenderTargets.Count + 1 == D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT)
// throw new Aiwaz.Core.ActionFailedException("RenderTarget: Unable to add an additional rendering target, list is full.");
additionalRenderTargets.Add(target);
this.KillViewPortAndRenderTargetData();
this.BuildViewPortAndRenderTargetData();
}
public void RemoveAdditionalRenderTarget(IRenderTargetBase target)
{
if (additionalRenderTargets.Remove(target))
{
this.KillViewPortAndRenderTargetData();
this.BuildViewPortAndRenderTargetData();
}
}
public void Bind(BindFlags bindFlags)
{
if ((bindFlags & ~ BindFlags.ClearAll) != (lastBindFlags & ~ BindFlags.ClearAll))
{
lastBindFlags = bindFlags;
this.KillViewPortAndRenderTargetData();
this.BuildViewPortAndRenderTargetData();
}
else
lastBindFlags = bindFlags;
this.Clear(bindFlags);
Engine.Device.PixelShader.SetShaderResources(emptyShaderResView, 0, 128);
Engine.Device.OutputMerger.SetTargets(DX10DepthStencilView, renderTargetViews);
Engine.Device.Rasterizer.SetViewports(viewports);
Engine.EngineStates.LastRenderTarget = this;
}
public void UnbindAllRenderTargets()
{
if (Engine.EngineStates.LastRenderTarget == this)
{
Engine.Device.OutputMerger.SetTargets(new SlimDX.Direct3D10.RenderTargetView[0]);
Engine.Device.Rasterizer.SetViewports(new SlimDX.Direct3D10.Viewport[0]);
Engine.EngineStates.LastRenderTarget = null;
}
}
protected void BuildViewPortAndRenderTargetData()
{
// Rebuild render targets
if (renderTargetViews == null && viewports == null)
{
if ((lastBindFlags & BindFlags.BindAllTextures) == BindFlags.BindAllTextures)
{
renderTargetViews = new SlimDX.Direct3D10.RenderTargetView[additionalRenderTargets.Count + 1];
viewports = new SlimDX.Direct3D10.Viewport[additionalRenderTargets.Count + 1];
renderTargetViews[0] = this.DX10RenderTargetView;
viewports[0] = this.ViewPort;
for (int i = 0; i < additionalRenderTargets.Count; ++i)
{
renderTargetViews[i + 1] = additionalRenderTargets[i].DX10RenderTargetView;
viewports[i + 1] = additionalRenderTargets[i].ViewPort;
}
}
else if ((lastBindFlags & BindFlags.BindAllTextures) != BindFlags.None)
{
var activeRenderTargetCount = 0;
if ((lastBindFlags & BindFlags.BindBaseTexture) != BindFlags.None) ++activeRenderTargetCount;
if ((lastBindFlags & BindFlags.BindAdditionalTexture0) != BindFlags.None) ++activeRenderTargetCount;
if ((lastBindFlags & BindFlags.BindAdditionalTexture1) != BindFlags.None) ++activeRenderTargetCount;
if ((lastBindFlags & BindFlags.BindAdditionalTexture2) != BindFlags.None) ++activeRenderTargetCount;
if ((lastBindFlags & BindFlags.BindAdditionalTexture3) != BindFlags.None) ++activeRenderTargetCount;
renderTargetViews = new SlimDX.Direct3D10.RenderTargetView[activeRenderTargetCount];
viewports = new SlimDX.Direct3D10.Viewport[activeRenderTargetCount];
int bufferIndex = 0;
if ((lastBindFlags & BindFlags.BindBaseTexture) != BindFlags.None)
{
renderTargetViews[bufferIndex] = this.DX10RenderTargetView;
viewports[bufferIndex++] = this.ViewPort;
}
if ((lastBindFlags & BindFlags.BindAdditionalTexture0) != BindFlags.None)
{
renderTargetViews[bufferIndex] = additionalRenderTargets[0].DX10RenderTargetView;
viewports[bufferIndex++] = additionalRenderTargets[0].ViewPort;
}
if ((lastBindFlags & BindFlags.BindAdditionalTexture1) != BindFlags.None)
{
renderTargetViews[bufferIndex] = additionalRenderTargets[1].DX10RenderTargetView;
viewports[bufferIndex++] = additionalRenderTargets[1].ViewPort;
}
if ((lastBindFlags & BindFlags.BindAdditionalTexture2) != BindFlags.None)
{
renderTargetViews[bufferIndex] = additionalRenderTargets[2].DX10RenderTargetView;
viewports[bufferIndex++] = additionalRenderTargets[2].ViewPort;
}
if ((lastBindFlags & BindFlags.BindAdditionalTexture3) != BindFlags.None)
{
renderTargetViews[bufferIndex] = additionalRenderTargets[3].DX10RenderTargetView;
viewports[bufferIndex++] = additionalRenderTargets[3].ViewPort;
}
}
else
throw new ActionFailedException("No render target bindable.");
}
}
protected void KillViewPortAndRenderTargetData()
{
renderTargetViews = null;
viewports = null;
if (Engine.EngineStates.LastRenderTarget == this)
Engine.EngineStates.LastRenderTarget = null;
}
#endregion
#region IDisposable Members
protected void DisposeInternal()
{
this.KillViewPortAndRenderTargetData();
this.UnbindAllRenderTargets();
if (DX10RenderTargetView != null)
DX10RenderTargetView.Dispose();
DX10RenderTargetView = null;
if (DX10DepthStencilView != null)
DX10DepthStencilView.Dispose();
DX10DepthStencilView = null;
if (DX10DepthStencilTexture != null)
DX10DepthStencilTexture.Dispose();
DX10DepthStencilTexture = null;
}
public override void Dispose()
{
this.DisposeInternal();
base.Dispose();
}
#endregion
#region CommandUser
const byte setRenderTargetCommandType = 0;
public override CommandExecuteResult ExecuteCommand(byte commandType, CommandBuffer currentBuffer, int currentPositon)
{
if (commandType == setRenderTargetCommandType)
{
if (Engine.EngineStates.LastRenderTarget != this)
{
this.UnbindAllRenderTargets();
this.Bind(BindFlags.Default);
}
else
this.Clear(BindFlags.Default);
}
return CommandExecuteResult.None;
}
protected void Clear(BindFlags bindFlags)
{
if ((bindFlags & BindFlags.ClearColor) != BindFlags.None)
Engine.Device.ClearRenderTargetView(DX10RenderTargetView, ClearColor);
if ((bindFlags & BindFlags.ClearDepthStencil) != BindFlags.None && DX10DepthStencilView != null)
Engine.Device.ClearDepthStencilView(DX10DepthStencilView, SlimDX.Direct3D10.DepthStencilClearFlags.Depth | SlimDX.Direct3D10.DepthStencilClearFlags.Stencil, ClearDepth, ClearStencil);
}
#endregion
}
}

View File

@@ -0,0 +1,147 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aiwaz.Contracts;
using Aiwaz.Core;
using Aiwaz.Resources.Attributes;
using System.Collections.ObjectModel;
namespace Aiwaz.Resources
{
[CreationParameters("Create an empty RenderTarget texture")]
public class RenderTargetTextureParams : ICreationParams
{
public int width;
public int height;
public SlimDX.DXGI.Format format;
public int multiSampleCount;
public int multiSampleQuality;
public RenderTargetTextureParams()
{
width = 512;
height = 512;
format = SlimDX.DXGI.Format.Unknown;
multiSampleCount = 0;
multiSampleQuality = 0;
}
}
[AiwazResource("RenderTarget texture", "An output target for render operations which could be used as texture input.")]
public class RenderTargetTexture : RenderTarget
{
public RenderTargetTexture(RenderTargetTextureParams parameters)
: base()
{
creationParams = parameters;
Console.WriteLine(string.Format("Creating RenderTargetTexture ({0}x{1} {2})..", parameters.width, parameters.height, parameters.format.ToString()));
this.BuildRenderTargetTexture(parameters.width, parameters.height, parameters.format, parameters.multiSampleCount, parameters.multiSampleQuality);
}
protected void BuildRenderTargetTexture(int width, int height, SlimDX.DXGI.Format format, int multiSampleCount, int multiSampleQuality)
{
if (this.Texture != null &&
width == this.RenderTargetWidth &&
height == this.RenderTargetHeight &&
format == this.RenderTargetFormat &&
this.multiSampleCount == multiSampleCount &&
this.multiSampleQuality == multiSampleQuality)
{
return;
}
this.DisposeInternal();
// get missing information
if (multiSampleCount == 0)
multiSampleCount = 1;
if (width == 0)
width = 1;
if (height == 0)
height = 1;
if (format == SlimDX.DXGI.Format.Unknown)
format = SlimDX.DXGI.Format.R8G8B8A8_UNorm;
this.multiSampleCount = multiSampleCount;
this.multiSampleQuality = multiSampleQuality;
if (this.Texture == null)
this.Texture = new Texture(new EmptyTextureParams()
{
Width = width,
Height = height,
Elements = 1,
MipLevels = 0,
Format = format,
AccessType = SlimDX.Direct3D10.ResourceUsage.Staging,
RenderTarget = true,
MultiSampleCount = multiSampleCount,
MultiSampleQuality = multiSampleQuality
});
else if (this.Texture is Texture)
((Texture)this.Texture).CreateRenderTargetTexture(width, height, format, multiSampleCount, multiSampleQuality);
this.DX10RenderTargetView = new SlimDX.Direct3D10.RenderTargetView(Engine.Device, this.Texture.Texture2D);
this.ViewPort = new ViewPort()
{
Width = width,
Height = height
};
}
public override int RenderTargetWidth
{
get { return Texture.TextureWidth; }
}
public override int RenderTargetHeight
{
get { return Texture.TextureHeight; }
}
public override SlimDX.DXGI.Format RenderTargetFormat
{
get { return Texture.TextureFormat; }
}
#region IRenderTargetTexture Members
public void Resize(int width, int height)
{
if (this.RenderTargetWidth == width || this.RenderTargetHeight == height)
return;
var usedDepthStencilBuffer = this.HasDepthStencilBuffer;
this.BuildRenderTargetTexture(width, height, RenderTargetFormat, multiSampleCount, multiSampleQuality);
this.HasDepthStencilBuffer = usedDepthStencilBuffer;
}
public Texture Texture { get; protected set; }
#endregion
private ICreationParams creationParams;
public override ICreationParams CreationParams
{
get { return creationParams; }
}
private ObservableCollection<IResource> children;
[ReadOnly]
public override ObservableCollection<IResource> Children
{
get
{
if (children == null)
{
children = new ObservableCollection<IResource>();
children.Add(Texture);
}
return children;
}
}
}
}

View File

@@ -0,0 +1,123 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aiwaz.Contracts;
using Aiwaz.Core;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace Aiwaz.Resources
{
public abstract class Resource : IResource, INotifyPropertyChanged, IDisposable
{
#region IResource Members
public abstract ICreationParams CreationParams
{
get;
}
protected string wellKnownName;
public string WellKnownName
{
get
{
if (wellKnownName == null)
{
string resourceName = null;
foreach (var attribute in this.GetType().GetCustomAttributes(true))
{
if (attribute.GetType().Equals(typeof(AiwazResourceAttribute)))
{
resourceName = ((AiwazResourceAttribute)attribute).Name;
}
}
if (resourceName == null)
resourceName = "Unknown resource";
int count = 1;
do
{
wellKnownName = string.Format("{0} {1}", resourceName, count++);
} while (Engine.ExistsName(wellKnownName));
Engine.RegisterNamedObject(wellKnownName, this);
}
return wellKnownName;
}
set
{
string newName = value;
if (Engine.ExistsName(newName))
{
int count = 1;
do
{
newName = string.Format("{0} {1}", value, count++);
} while (Engine.ExistsName(newName));
}
if (!string.IsNullOrEmpty(wellKnownName))
Engine.UnregisterNamedObject(wellKnownName);
wellKnownName = newName;
if (!string.IsNullOrEmpty(wellKnownName))
Engine.RegisterNamedObject(wellKnownName, this);
}
}
public IResource Parent
{
get;
set;
}
public abstract ObservableCollection<IResource> Children
{
get;
}
#endregion
#region INotifyPropertyChanged Members
protected void NotifyPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region IDisposable Members
private bool _disposed = false;
protected bool Disposed
{
get { return _disposed; }
}
protected virtual void Dispose(bool disposing)
{
if (!Disposed)
{
_disposed = true;
}
}
public virtual void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~Resource() { Dispose(false); }
#endregion
}
}

View File

@@ -0,0 +1,232 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aiwaz.Contracts;
using Aiwaz.Common;
using Aiwaz.Core;
using Aiwaz.Resources.Attributes;
using System.Collections.ObjectModel;
using System.IO;
namespace Aiwaz.Resources
{
public class TechniqueNotFoundException : Exception { }
public class UnableToLoadShaderException : Exception
{
public UnableToLoadShaderException(string errors)
: base(errors)
{
}
}
[CreationParameters("Load a shader from file")]
public class ShaderParams : ICreationParams
{
[RequiredParameter]
public string FileName;
public string TechniqueName;
public ShaderParams()
{
FileName = null;
TechniqueName = null;
}
}
[AiwazResource("Shader", "A complex shader to perform individual shading operations when rendering geometry buffers.")]
public class Shader : CommandUser, IShader
{
#region IShader Members
const byte applyFirstPassCommandType = 0;
const byte nextPassCommandType = 1;
private InternalShader internalShader;
private string techniqueName;
private byte priority = 0;
public bool Changed { get; set; }
public Shader(ShaderParams parameters)
{
creationParams = parameters;
Console.WriteLine(string.Format("Creating Shader ({0} Technique: {1})..", parameters.FileName, parameters.TechniqueName));
internalShader = Engine.FindNamedObject(parameters.FileName) as InternalShader;
if (internalShader == null)
internalShader = new InternalShader(parameters.FileName);
internalShader.OnChanged += internalShader_OnChanged;
Commands.Add(new Command(this, CommandFlags.StartChain | CommandFlags.SubChainStart, applyFirstPassCommandType, 2, this.Priority));
Commands.Add(new Command(this, CommandFlags.SubChainEnd, nextPassCommandType, byte.MaxValue, this.Priority));
this.TechniqueName = creationParams.TechniqueName;
}
void internalShader_OnChanged(object sender, EventArgs e)
{
this.TechniqueName = creationParams.TechniqueName;
Changed = true;
}
public string TechniqueName
{
get { return techniqueName; }
set
{
techniqueName = value;
if (string.IsNullOrEmpty(techniqueName))
{
this.Technique = internalShader.Effect.GetTechniqueByIndex(0);
if (this.Technique != null)
techniqueName = this.Technique.Description.Name;
}
else
this.Technique = internalShader.Effect.GetTechniqueByName(TechniqueName);
if (this.Technique == null)
throw new TechniqueNotFoundException();
CurrentPass = 0;
}
}
public SlimDX.Direct3D10.EffectTechnique Technique { get; protected set; }
public SlimDX.Direct3D10.Effect Effect { get { return internalShader.Effect; } }
public byte Priority
{
get
{
return priority;
}
set
{
priority = value;
foreach (var command in Commands)
if (command.Type == applyFirstPassCommandType)
command.SubPriority = priority;
}
}
public int CurrentPass { get; protected set; }
#endregion
public override CommandExecuteResult ExecuteCommand(byte commandType, CommandBuffer currentBuffer, int currentPositon)
{
if (commandType == applyFirstPassCommandType)
{
CurrentPass = 0;
Engine.EngineStates.LastShader = this;
}
else if (commandType == nextPassCommandType)
{
if (this.Technique == null)
return CommandExecuteResult.None;
if (CurrentPass >= this.Technique.Description.PassCount)
CurrentPass = this.Technique.Description.PassCount;
else
CurrentPass++;
if (CurrentPass >= this.Technique.Description.PassCount)
return CommandExecuteResult.None;
return CommandExecuteResult.RetrySubChainSkipHead;
}
return CommandExecuteResult.None;
}
#region IDisposable Members
public override void Dispose()
{
Engine.EngineStates.LastShader = null;
base.Dispose();
}
#endregion
private ShaderParams creationParams;
public override ICreationParams CreationParams
{
get { return creationParams; }
}
public override ObservableCollection<IResource> Children
{
get { return null; }
}
}
internal class InternalShader : IDisposable
{
#region IInternalShader Members
private string fileName;
public InternalShader(string fileName)
{
this.fileName = fileName;
Engine.RegisterNamedObject(fileName, this);
Engine.RegisterEngineDisposable(this);
Engine.FileSystem.Attach(fileName, OnShaderChanged);
}
public event EventHandler OnChanged;
private void OnShaderChanged(Stream stream)
{
using (stream)
{
if (Effect != null)
Effect.Dispose();
string errors;
Effect = SlimDX.Direct3D10.Effect.FromStream(Engine.Device, stream, "fx_4_0",
#if DEBUG
SlimDX.Direct3D10.ShaderFlags.EnableStrictness | SlimDX.Direct3D10.ShaderFlags.Debug,
#else
SlimDX.Direct3D10.ShaderFlags.EnableStrictness,
#endif
SlimDX.Direct3D10.EffectFlags.None, null, null, out errors);
if (!string.IsNullOrEmpty(errors))
throw new UnableToLoadShaderException(errors);
else if (OnChanged != null)
OnChanged(this, EventArgs.Empty);
}
}
~InternalShader()
{
if (!Engine.Initialized)
return;
Engine.UnregisterNamedObject(fileName);
if (Engine.UnregisterEngineDisposable(this))
this.Dispose();
}
public SlimDX.Direct3D10.Effect Effect { get; protected set; }
#endregion
#region IDisposable Members
public void Dispose()
{
if (this.Effect != null)
this.Effect.Dispose();
this.Effect = null;
Engine.UnregisterNamedObject(fileName);
Engine.UnregisterEngineDisposable(this);
}
#endregion
}
}

View File

@@ -0,0 +1,323 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aiwaz.Contracts;
using Aiwaz.Core;
using Aiwaz.Common;
using System.Collections.ObjectModel;
namespace Aiwaz.Resources
{
public class ShaderNotSetException : Exception {}
public class UnsupportedShaderParameterTypeException : Exception {}
[AiwazResource("Shader parameter set", "A set of parameters for one or more shaders.")]
public class ShaderParameterSet : CommandUser, IShaderParameterSet
{
#region IShaderParameterSet Members
const byte setShaderParameterCollectionCommandType = 0;
const byte setFollowingShaderParameterCollectionCommandType = 1;
private bool isPreconditionForFollowingShaders;
private byte basePriority;
protected BaseShaderParameterSet baseShaderParameterSet = new BaseShaderParameterSet();
public ShaderParameterSet()
: this(4)
{
}
protected ShaderParameterSet(byte basePriority)
{
this.basePriority = basePriority;
this.IsPreconditionForFollowingShaders = false;
}
public bool IsPreconditionForFollowingShaders
{
get
{
return isPreconditionForFollowingShaders;
}
set
{
if (Commands.Count > 0 && value == isPreconditionForFollowingShaders)
return;
isPreconditionForFollowingShaders = value;
Commands.Clear();
if (isPreconditionForFollowingShaders)
Commands.Add(new Command(this, CommandFlags.EndChain | CommandFlags.FlushChain, setFollowingShaderParameterCollectionCommandType, 0, 0));
else
Commands.Add(new Command(this, CommandFlags.None, setShaderParameterCollectionCommandType, basePriority, 0));
this.MarkCommandsAsDirty();
}
}
public void SetParameter(string parameterName, IShaderParameter parameter)
{
baseShaderParameterSet.SetShaderParameter(parameterName, parameter);
}
public void SetParameter(string parameterName, ITexture argParameter, ParameterBindType argParamNameType)
{
this.SetParameter(parameterName, new Reference(argParameter), argParamNameType);
}
public void SetParameter(string parameterName, float argParameter, ParameterBindType argParamNameType)
{
this.SetParameter(parameterName, new Reference(argParameter), argParamNameType);
}
public void SetParameter(string parameterName, SlimDX.Vector3 argParameter, ParameterBindType argParamNameType)
{
this.SetParameter(parameterName, new Reference(argParameter), argParamNameType);
}
public void SetParameter(string parameterName, SlimDX.Vector4 argParameter, ParameterBindType argParamNameType)
{
this.SetParameter(parameterName, new Reference(argParameter), argParamNameType);
}
public void SetParameter(string parameterName, SlimDX.Matrix argParameter, ParameterBindType argParamNameType)
{
this.SetParameter(parameterName, new Reference(argParameter), argParamNameType);
}
public void SetParameter(string parameterName, bool argParameter, ParameterBindType argParamNameType)
{
this.SetParameter(parameterName, new Reference(argParameter), argParamNameType);
}
public void SetParameter(string parameterName, Reference argParameter, ParameterBindType argParamNameType)
{
baseShaderParameterSet.SetShaderParameter(parameterName, new ShaderParameter(argParamNameType, argParameter));
}
public void RemoveParameter(string name)
{
baseShaderParameterSet.RemoveShaderParameter(name);
}
#endregion
public override CommandExecuteResult ExecuteCommand(byte commandType, CommandBuffer currentBuffer, int currentPositon)
{
if (commandType == setShaderParameterCollectionCommandType)
{
if (Engine.EngineStates.LastShader == null)
throw new ShaderNotSetException();
baseShaderParameterSet.UseParametersOnShader(Engine.EngineStates.LastShader);
}
else if (commandType == setFollowingShaderParameterCollectionCommandType)
{
var shaders = currentBuffer.BufferedCommands.Where(c => c.Owner is IShader && c.Type == 0).Select(c => c.Owner as IShader);
foreach (var shader in shaders)
baseShaderParameterSet.UseParametersOnShader(shader);
}
return CommandExecuteResult.None;
}
#region IDisposable Members
public override void Dispose()
{
base.Dispose();
}
#endregion
public override ICreationParams CreationParams
{
get { return null; }
}
public override ObservableCollection<IResource> Children
{
get { return null; }
}
}
public class BaseShaderParameterSet
{
Dictionary<string, IShaderParameter> parameterMap = new Dictionary<string, IShaderParameter>();
Dictionary<WeakReference, List<Pair<IShaderParameter, SlimDX.Direct3D10.EffectVariable>>> shaderToParameterMap = new Dictionary<WeakReference, List<Pair<IShaderParameter, SlimDX.Direct3D10.EffectVariable>>>();
public void UseParametersOnShader(IShader shader)
{
if (parameterMap.Count == 0)
return;
List<Pair<IShaderParameter, SlimDX.Direct3D10.EffectVariable>> shaderParams = null;
var searchedShaderPair = shaderToParameterMap.FirstOrDefault(a => a.Key.IsAlive && a.Key.Target == shader);
if (searchedShaderPair.Key != null)
shaderParams = searchedShaderPair.Value;
if (shaderParams == null || shader.Changed)
{
shader.Changed = false;
shaderParams = new List<Pair<IShaderParameter, SlimDX.Direct3D10.EffectVariable>>();
// (re)create shader entries
foreach (var parameter in parameterMap)
if (parameter.Value != null)
{
SlimDX.Direct3D10.EffectVariable effectvar = null;
if (parameter.Value.ParameterNameType == ParameterBindType.BindByVariable)
effectvar = shader.Effect.GetVariableByName(parameter.Key);
else if (parameter.Value.ParameterNameType == ParameterBindType.BindBySemantic)
effectvar = shader.Effect.GetVariableBySemantic(parameter.Key);
if (effectvar != null && effectvar.IsValid)
shaderParams.Add(new Pair<IShaderParameter, SlimDX.Direct3D10.EffectVariable>(parameter.Value, effectvar));
}
if (shaderParams.Count == 0)
return;
shaderToParameterMap[new WeakReference(shader)] = shaderParams;
}
foreach (var parameter in shaderParams)
parameter.First.ApplyValue(parameter.Second);
}
private void InitFromShader(IShader shader)
{
}
public void SetShaderParameter(string name, IShaderParameter parameter)
{
this.RemoveShaderParameter(name);
parameterMap[name] = parameter;
}
public void RemoveShaderParameter(string name)
{
shaderToParameterMap.Clear();
parameterMap.Remove(name);
}
public void RemoveAllShaderParameters()
{
parameterMap.Clear();
shaderToParameterMap.Clear();
}
}
public class ShaderParameter : IShaderParameter
{
private enum ObjectType
{
Int,
IntArray,
Float,
FloatArray,
Bool,
BoolArray,
Vector2,
Vector3,
Vector4,
Vector4Array,
Matrix,
MatrixArray,
Texture
}
private Reference valueObject;
private ObjectType type;
public ShaderParameter(ParameterBindType parameterNameType, Reference valueObject)
{
this.ParameterNameType = parameterNameType;
this.valueObject = valueObject;
if (valueObject.RawValue is bool)
this.type = ObjectType.Bool;
else if (valueObject.RawValue is bool[])
this.type = ObjectType.BoolArray;
else if (valueObject.RawValue is int)
this.type = ObjectType.Int;
else if (valueObject.RawValue is int[])
this.type = ObjectType.IntArray;
else if (valueObject.RawValue is float)
this.type = ObjectType.Float;
else if (valueObject.RawValue is float[])
this.type = ObjectType.FloatArray;
else if (valueObject.RawValue is SlimDX.Matrix)
this.type = ObjectType.Matrix;
else if (valueObject.RawValue is SlimDX.Matrix[])
this.type = ObjectType.MatrixArray;
else if (valueObject.RawValue is SlimDX.Vector2)
this.type = ObjectType.Vector2;
else if (valueObject.RawValue is SlimDX.Vector3)
this.type = ObjectType.Vector3;
else if (valueObject.RawValue is SlimDX.Vector4)
this.type = ObjectType.Vector4;
else if (valueObject.RawValue is SlimDX.Vector4[])
this.type = ObjectType.Vector4Array;
else if (valueObject.RawValue is ITexture)
this.type = ObjectType.Texture;
else
throw new UnsupportedShaderParameterTypeException();
}
#region IShaderParameter Members
public ParameterBindType ParameterNameType { get; protected set; }
public void ApplyValue(SlimDX.Direct3D10.EffectVariable variable)
{
switch (this.type)
{
case ObjectType.Bool:
variable.AsScalar().Set((bool)valueObject.RawValue);
break;
case ObjectType.BoolArray:
variable.AsScalar().Set((bool[])valueObject.RawValue);
break;
case ObjectType.Int:
variable.AsScalar().Set((int)valueObject.RawValue);
break;
case ObjectType.IntArray:
variable.AsScalar().Set((int[])valueObject.RawValue);
break;
case ObjectType.Float:
variable.AsScalar().Set((float)valueObject.RawValue);
break;
case ObjectType.FloatArray:
variable.AsScalar().Set((float[])valueObject.RawValue);
break;
case ObjectType.Vector2:
variable.AsVector().Set((SlimDX.Vector2)valueObject.RawValue);
break;
case ObjectType.Vector3:
variable.AsVector().Set((SlimDX.Vector3)valueObject.RawValue);
break;
case ObjectType.Vector4:
variable.AsVector().Set((SlimDX.Vector4)valueObject.RawValue);
break;
case ObjectType.Vector4Array:
variable.AsVector().Set((SlimDX.Vector4[])valueObject.RawValue);
break;
case ObjectType.Matrix:
variable.AsMatrix().SetMatrix((SlimDX.Matrix)valueObject.RawValue);
break;
case ObjectType.MatrixArray:
variable.AsMatrix().SetMatrix((SlimDX.Matrix[])valueObject.RawValue);
break;
case ObjectType.Texture:
variable.AsResource().SetResource(((ITexture)valueObject.RawValue).ResourceView);
break;
}
}
#endregion
}
}

View File

@@ -0,0 +1,234 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aiwaz.Contracts;
using System.Runtime.InteropServices;
using Aiwaz.Core;
using System.Collections.ObjectModel;
namespace Aiwaz.Resources
{
[AiwazResource("SwapChain", "An output target for render operations, the output could be displayed directly into a window.")]
public class SwapChain : RenderTarget, ISwapChain
{
[DllImport("user32.dll")]
static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
[Serializable, StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
public RECT(int left_, int top_, int right_, int bottom_)
{
Left = left_;
Top = top_;
Right = right_;
Bottom = bottom_;
}
public int Height { get { return Bottom - Top; } }
public int Width { get { return Right - Left; } }
}
private SlimDX.DXGI.SwapChainDescription swapChainDescription;
private SlimDX.DXGI.SwapChain swapChain;
public SwapChain(IntPtr windowHandle)
: this(windowHandle, 0, 0, 0, SlimDX.DXGI.Format.Unknown, 0, 0)
{
}
public SwapChain(IntPtr windowHandle, int width, int height, int refreshRate, SlimDX.DXGI.Format format)
: this (windowHandle, width, height, refreshRate, format, 0, 0)
{
}
public SwapChain(IntPtr windowHandle, int width, int height, int refreshRate, SlimDX.DXGI.Format format, int multiSampleCount, int multiSampleQuality)
: base()
{
VSync = true;
// get missing information
if (multiSampleCount <= 0)
multiSampleCount = 1;
if (width == 0 || height == 0)
{
RECT windowRect = new RECT();
GetClientRect(windowHandle, out windowRect);
if (width == 0)
width = windowRect.Right - windowRect.Left;
if (height == 0)
height = windowRect.Bottom - windowRect.Top;
}
if (refreshRate == 0)
refreshRate = 60; // 60Hz
if (format == SlimDX.DXGI.Format.Unknown)
format = SlimDX.DXGI.Format.R8G8B8A8_UNorm; // RGBA(X) 8Bit per channel -> 32Bit
swapChainDescription = new SlimDX.DXGI.SwapChainDescription()
{
BufferCount = 1,
Usage = SlimDX.DXGI.Usage.RenderTargetOutput,
OutputHandle = windowHandle,
IsWindowed = true,
ModeDescription = new SlimDX.DXGI.ModeDescription()
{
Width = width,
Height = height,
Format = (SlimDX.DXGI.Format)format,
RefreshRate = new SlimDX.Rational(refreshRate, 1)
},
SampleDescription = new SlimDX.DXGI.SampleDescription()
{
Count = multiSampleCount,
Quality = multiSampleQuality
}
};
this.multiSampleCount = multiSampleCount;
this.multiSampleQuality = multiSampleQuality;
Console.WriteLine(string.Format("Creating SwapChain ({0}x{1}x{2} {3})..", width, height, refreshRate, format.ToString()));
swapChain = new SlimDX.DXGI.SwapChain(Engine.Factory, Engine.Device, swapChainDescription);
if (swapChain == null)
throw new InitializingFailedException(this.GetType().Name, "Unable to create internal swap chain.");
this.RetriveData();
this.ViewPort = new ViewPort()
{
Width = width,
Height = height
};
}
public override int RenderTargetWidth
{
get { return swapChainDescription.ModeDescription.Width; }
}
public override int RenderTargetHeight
{
get { return swapChainDescription.ModeDescription.Height; }
}
public override SlimDX.DXGI.Format RenderTargetFormat
{
get { return swapChainDescription.ModeDescription.Format; }
}
#region ISwapChain Members
public void Resize(int width, int height)
{
if (width <= 0 || height <= 0)
{
RECT windowRect = new RECT();
GetClientRect(swapChainDescription.OutputHandle, out windowRect);
if (width <= 0)
width = windowRect.Right - windowRect.Left;
if (height <= 0)
height = windowRect.Bottom - windowRect.Top;
}
if (swapChainDescription.ModeDescription.Width == width &&
swapChainDescription.ModeDescription.Height == height)
return;
var depthStencilBuffer = this.HasDepthStencilBuffer;
Engine.Device.ClearState();
this.HasDepthStencilBuffer = false;
if (this.DX10RenderTargetView != null)
this.DX10RenderTargetView.Dispose();
this.DX10RenderTargetView = null;
swapChain.ResizeBuffers(swapChainDescription.BufferCount, width, height, swapChainDescription.ModeDescription.Format, SlimDX.DXGI.SwapChainFlags.AllowModeSwitch);
var desc = swapChainDescription.ModeDescription;
desc.Width = width;
desc.Height = height;
swapChainDescription.ModeDescription = desc;
this.RetriveData();
this.HasDepthStencilBuffer = depthStencilBuffer;
this.ViewPort = new ViewPort()
{
Width = width,
Height = height
};
}
public void Present()
{
swapChain.Present(VSync ? 1 : 0, SlimDX.DXGI.PresentFlags.None);
}
public bool Fullscreen
{
get { return !swapChainDescription.IsWindowed; }
set
{
if (swapChainDescription.IsWindowed == !value)
return;
swapChainDescription.IsWindowed = !value;
var hasDepthStencilBuffer = this.HasDepthStencilBuffer;
Engine.Device.ClearState();
this.HasDepthStencilBuffer = false;
if (this.DX10RenderTargetView != null)
this.DX10RenderTargetView.Dispose();
this.DX10RenderTargetView = null;
swapChain.SetFullScreenState(value, Engine.DeviceEnumerator.FindBestOutput(false).Output);
this.RetriveData();
this.HasDepthStencilBuffer = hasDepthStencilBuffer;
}
}
public bool VSync { get; set; }
private void RetriveData()
{
using (var backbufferTexture = SlimDX.Direct3D10.Texture2D.FromSwapChain<SlimDX.Direct3D10.Texture2D>(swapChain, 0))
{
DX10RenderTargetView = new SlimDX.Direct3D10.RenderTargetView(Engine.Device, backbufferTexture);
}
}
#endregion
#region IDisposable Members
public override void Dispose()
{
if (swapChain != null)
swapChain.Dispose();
swapChain = null;
base.Dispose();
}
#endregion
public override ICreationParams CreationParams
{
get { return null; }
}
public override ObservableCollection<IResource> Children
{
get { return null; }
}
}
}

View File

@@ -0,0 +1,278 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aiwaz.Contracts;
using Aiwaz.Core;
using SlimDX.Direct3D10;
using Aiwaz.Resources.Attributes;
namespace Aiwaz.Resources
{
[CreationParameters("Create an empty texture")]
public class EmptyTextureParams : ICreationParams
{
public int Width;
public int Height;
public int Elements;
public int MipLevels;
public SlimDX.DXGI.Format Format;
public ResourceUsage AccessType;
public TextureInitialData InitialData;
public bool RenderTarget;
public int MultiSampleCount;
public int MultiSampleQuality;
public EmptyTextureParams()
{
Width = 512;
Height = 512;
Elements = 1;
MipLevels = 1;
Format = SlimDX.DXGI.Format.Unknown;
AccessType = ResourceUsage.Default;
InitialData = null;
RenderTarget = false;
MultiSampleCount = 0;
MultiSampleQuality = 0;
}
}
[CreationParameters("Load a texture from file")]
public class FileTextureParams : ICreationParams
{
[RequiredParameter]
public string FileName;
public SlimDX.Direct3D10.ResourceUsage AccessType;
public FileTextureParams()
{
AccessType = ResourceUsage.Default;
}
}
[AiwazResource("Texture", "A placeholder of multidimensional data")]
public class Texture : ShaderParameterSet, ITexture
{
#region ITexture Members
private string bindingName = "Diffuse";
private SlimDX.Direct3D10.Resource resource;
private int lockedSubResource = 0;
private bool isLocked = false;
private ResourceUsage accessType;
private Texture()
: base(3)
{
}
public Texture(FileTextureParams descriptor)
: this()
{
Console.WriteLine(string.Format("Creating Texture ({0})..", descriptor.FileName));
this.LoadFromFile(descriptor.FileName, descriptor.AccessType);
this.WellKnownName = descriptor.FileName;
}
public Texture(EmptyTextureParams descriptor)
: this()
{
this.CreateTexture(descriptor.Width, descriptor.Height, descriptor.MipLevels, descriptor.Elements, descriptor.Format, descriptor.InitialData, descriptor.AccessType, descriptor.RenderTarget, descriptor.MultiSampleCount, descriptor.MultiSampleQuality);
}
public string BindingName
{
get { return bindingName; }
set
{
if (!string.IsNullOrEmpty(bindingName))
this.RemoveParameter(bindingName);
bindingName = value;;
if (!string.IsNullOrEmpty(bindingName))
this.SetParameter(bindingName, this, ParameterBindType.BindBySemantic);
}
}
public int TextureWidth { get; protected set; }
public int TextureHeight { get; protected set; }
public int TextureArraySize { get; protected set; }
public SlimDX.DXGI.Format TextureFormat { get; protected set; }
public SlimDX.Direct3D10.ShaderResourceView ResourceView { get; protected set; }
public SlimDX.Direct3D10.Texture2D Texture2D { get; protected set; }
public SlimDX.DataRectangle MapTextureBuffer(SlimDX.Direct3D10.MapMode mode)
{
return this.MapTextureBuffer(mode, 0);
}
public SlimDX.DataRectangle MapTextureBuffer(SlimDX.Direct3D10.MapMode mode, int arrayElement)
{
if (isLocked)
throw new ActionFailedException("Texture is already locked.");
isLocked = true;
lockedSubResource = arrayElement;
return this.Texture2D.Map(arrayElement, mode, SlimDX.Direct3D10.MapFlags.None);
}
public void UnmapTextureBuffer()
{
if (!isLocked)
return;
isLocked = false;
this.Texture2D.Unmap(lockedSubResource);
}
private void LoadFromFile(string fileName, SlimDX.Direct3D10.ResourceUsage accessType)
{
this.accessType = accessType;
Engine.FileSystem.Attach(fileName, OnFileChanged);
this.TextureArraySize = 0;
}
private void OnFileChanged(System.IO.Stream stream)
{
if (this.Texture2D != null)
this.Texture2D.Dispose();
if (this.ResourceView != null)
this.ResourceView.Dispose();
var loadInfo = SlimDX.Direct3D10.ImageLoadInformation.FromDefaults();
if (accessType == SlimDX.Direct3D10.ResourceUsage.Staging)
{
loadInfo.BindFlags = 0;
loadInfo.Usage = SlimDX.Direct3D10.ResourceUsage.Staging;
loadInfo.CpuAccessFlags = SlimDX.Direct3D10.CpuAccessFlags.Write | SlimDX.Direct3D10.CpuAccessFlags.Read;
}
else if (accessType == SlimDX.Direct3D10.ResourceUsage.Dynamic)
{
loadInfo.Usage = SlimDX.Direct3D10.ResourceUsage.Dynamic;
loadInfo.CpuAccessFlags = SlimDX.Direct3D10.CpuAccessFlags.Write;
}
using (stream)
{
this.Texture2D = SlimDX.Direct3D10.Texture2D.FromStream(Engine.Device, stream, (int)stream.Length, loadInfo);
resource = this.Texture2D;
}
if (accessType != SlimDX.Direct3D10.ResourceUsage.Staging)
{
var texViewDesc = new SlimDX.Direct3D10.ShaderResourceViewDescription();
texViewDesc.Format = this.Texture2D.Description.Format;
texViewDesc.Dimension = SlimDX.Direct3D10.ShaderResourceViewDimension.Texture2D;
texViewDesc.MostDetailedMip = 0;
texViewDesc.MipLevels = this.Texture2D.Description.MipLevels;
this.ResourceView = new SlimDX.Direct3D10.ShaderResourceView(Engine.Device, this.Texture2D, texViewDesc);
}
this.TextureWidth = this.Texture2D.Description.Width;
this.TextureHeight = this.Texture2D.Description.Height;
this.TextureFormat = this.Texture2D.Description.Format;
}
internal void CreateRenderTargetTexture(int width, int height, SlimDX.DXGI.Format format, int multiSampleCount, int multiSampleQuality)
{
this.CreateTexture(width, height, 1, 0, format, null, SlimDX.Direct3D10.ResourceUsage.Staging, true, multiSampleCount, multiSampleQuality);
}
private void DisposeInternal()
{
if (this.ResourceView != null)
this.ResourceView.Dispose();
this.ResourceView = null;
if (this.resource != null)
this.resource.Dispose();
this.resource = null;
this.Texture2D = null;
}
private void CreateTexture(int width, int height, int mipLevels, int elements, SlimDX.DXGI.Format format, TextureInitialData initialData, SlimDX.Direct3D10.ResourceUsage accessType, bool renderTarget, int multiSampleCount, int multiSampleQuality)
{
Console.WriteLine(string.Format("Creating Texture ({0}x{1} {2})..", width, height, format.ToString()));
this.DisposeInternal();
// calculate the needed amount of mipmap levels
int mipMapLevels = 1;
for (int tmp = Math.Min(height, width); tmp > 1; tmp /= 2, ++mipMapLevels);
mipMapLevels = Math.Max(1, Math.Min(mipMapLevels, mipLevels == 0 ? mipMapLevels : mipLevels));
// create the resource
var texDesc = new SlimDX.Direct3D10.Texture2DDescription();
texDesc.Width = width;
texDesc.Height = height;
texDesc.MipLevels = mipMapLevels;
texDesc.ArraySize = Math.Max(1, elements);
texDesc.Format = format;
texDesc.SampleDescription = new SlimDX.DXGI.SampleDescription(multiSampleCount, multiSampleQuality);
if (accessType == SlimDX.Direct3D10.ResourceUsage.Dynamic)
{
texDesc.Usage = SlimDX.Direct3D10.ResourceUsage.Dynamic;
texDesc.CpuAccessFlags = SlimDX.Direct3D10.CpuAccessFlags.Write;
}
if (accessType == SlimDX.Direct3D10.ResourceUsage.Staging)
texDesc.BindFlags = ((mipMapLevels > 1 || renderTarget) ? SlimDX.Direct3D10.BindFlags.RenderTarget : SlimDX.Direct3D10.BindFlags.None) | SlimDX.Direct3D10.BindFlags.ShaderResource;
if (mipMapLevels > 1)
texDesc.OptionFlags = SlimDX.Direct3D10.ResourceOptionFlags.GenerateMipMaps;
resource = this.Texture2D = new SlimDX.Direct3D10.Texture2D(Engine.Device, texDesc);
// create the resource view when possible
if (accessType != SlimDX.Direct3D10.ResourceUsage.Staging)
{
var texViewDesc = new SlimDX.Direct3D10.ShaderResourceViewDescription();
texViewDesc.Format = texDesc.Format;
texViewDesc.ElementWidth = elements;
if (elements > 0)
texViewDesc.Dimension = multiSampleCount == 1 ? SlimDX.Direct3D10.ShaderResourceViewDimension.Texture2DArray : SlimDX.Direct3D10.ShaderResourceViewDimension.Texture2DMultisampledArray;
else
texViewDesc.Dimension = multiSampleCount == 1 ? SlimDX.Direct3D10.ShaderResourceViewDimension.Texture2D : SlimDX.Direct3D10.ShaderResourceViewDimension.Texture2DMultisampled;
texViewDesc.MostDetailedMip = 0;
texViewDesc.MipLevels = texDesc.MipLevels;
texViewDesc.ArraySize = elements;
this.ResourceView = new SlimDX.Direct3D10.ShaderResourceView(Engine.Device, resource, texViewDesc);
}
// finalize
this.TextureWidth = width;
this.TextureHeight = height;
this.TextureFormat = format;
this.TextureArraySize = 1;
this.BindingName = this.BindingName;
}
#region IDisposable Members
public override void Dispose()
{
this.DisposeInternal();
base.Dispose();
}
#endregion
#endregion
}
}

View File

@@ -0,0 +1,306 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aiwaz.Contracts;
using Aiwaz.Resources.Attributes;
namespace Aiwaz.Resources
{
public class TransformationBindings : ICreationParams
{
public string WorldMatrixSemanticName;
public string LocalMatrixSemanticName;
public string WorldPositionSemanticName;
public string LocalPositionSemanticName;
public string WorldDirectionSemanticName;
public string LocalDirectionSemanticName;
public string WorldUpDirectionSemanticName;
public string LocalUpDirectionSemanticName;
public string WorldRightDirectionSemanticName;
public string LocalRightDirectionSemanticName;
}
[CreationParameters("Default transformation")]
public class DefaultTransformationBindings : TransformationBindings
{
public DefaultTransformationBindings()
{
WorldMatrixSemanticName = "WorldMatrix";
LocalMatrixSemanticName = "LocalMatrix";
WorldPositionSemanticName = "WorldPosition";
LocalPositionSemanticName = "LocalPosition";
WorldDirectionSemanticName = "WorldDirection";
LocalDirectionSemanticName = "LocalDirection";
WorldUpDirectionSemanticName = "WorldUpDirection";
LocalUpDirectionSemanticName = "LocalUpDirection";
WorldRightDirectionSemanticName = "WorldUpDirection";
LocalRightDirectionSemanticName = "LocalUpDirection";
}
}
[CreationParameters("Camera transformation")]
public class CameraTransformationBindings : TransformationBindings
{
public CameraTransformationBindings()
{
WorldPositionSemanticName = "CamPos";
WorldDirectionSemanticName = "CamDir";
}
}
[AiwazResource("Transformation", "Common transformations for a shader and geometry buffers like position, scale and rotation.")]
public class Transformation : ShaderParameterSet, IUpdatable
{
#region ITransformation Members
Reference worldMatrixRef = new Reference(new SlimDX.Matrix());
Reference worldPositionRef = new Reference(new SlimDX.Vector3());
Reference worldDirectionRef = new Reference(new SlimDX.Vector3());
Reference worldUpDirectionRef = new Reference(new SlimDX.Vector3());
Reference worldRightDirectionRef = new Reference(new SlimDX.Vector3());
Reference localMatrixRef = new Reference(new SlimDX.Matrix());
Reference localPositionRef = new Reference(new SlimDX.Vector3());
Reference localDirectionRef = new Reference(new SlimDX.Vector3());
Reference localUpDirectionRef = new Reference(new SlimDX.Vector3());
Reference localRightDirectionRef = new Reference(new SlimDX.Vector3());
private TransformationBindings transformationBindings;
private SlimDX.Vector3 lastKnownYawPitchRoll;
private SlimDX.Quaternion localRotation;
private SlimDX.Vector3 localScale;
private Transformation transformationParent;
private List<Transformation> transformations = new List<Transformation>();
private Transformation()
: base(5)
{
}
private Transformation(TransformationBindings transformationBindings)
: this()
{
this.WorldScale = this.LocalScale = new SlimDX.Vector3(1.0f, 1.0f, 1.0f);
this.LocalDirection = this.WorldDirection = new SlimDX.Vector3(0.0f, 0.0f, 1.0f);
this.LocalUpDirection = this.WorldUpDirection = new SlimDX.Vector3(0.0f, 1.0f, 0.0f);
this.LocalRightDirection = this.WorldRightDirection = new SlimDX.Vector3(1.0f, 0.0f, 0.0f);
this.TransformationBindings = transformationBindings;
}
public Transformation(DefaultTransformationBindings transformationBindings)
: this((TransformationBindings)transformationBindings)
{
}
public Transformation(CameraTransformationBindings transformationBindings)
: this((TransformationBindings)transformationBindings)
{
}
public TransformationBindings TransformationBindings
{
get { return transformationBindings; }
set
{
transformationBindings = value;
baseShaderParameterSet.RemoveAllShaderParameters();
this.RecreateAllShaderParameters();
}
}
public SlimDX.Vector3 LocalPosition
{
get { return (SlimDX.Vector3)localPositionRef.RawValue; }
set
{
localPositionRef.RawValue = value;
WantsUpdate = true;
}
}
public SlimDX.Vector3 WorldPosition { get { return (SlimDX.Vector3)worldPositionRef.RawValue; } protected set { worldPositionRef.RawValue = value; } }
public SlimDX.Vector3 LocalRotationYPR
{
get
{
return lastKnownYawPitchRoll;
}
set
{
lastKnownYawPitchRoll = value;
LocalRotation = SlimDX.Quaternion.RotationYawPitchRoll(value.X, value.Y, value.Z);
WantsUpdate = true;
}
}
public SlimDX.Quaternion LocalRotation
{
get { return localRotation; }
set
{
localRotation = value;
WantsUpdate = true;
}
}
public SlimDX.Quaternion WorldRotation { get; protected set; }
public SlimDX.Vector3 LocalDirection { get { return (SlimDX.Vector3)localDirectionRef.RawValue; } protected set { localDirectionRef.RawValue = value; } }
public SlimDX.Vector3 WorldDirection { get { return (SlimDX.Vector3)worldDirectionRef.RawValue; } protected set { worldDirectionRef.RawValue = value; } }
public SlimDX.Vector3 LocalUpDirection { get { return (SlimDX.Vector3)localUpDirectionRef.RawValue; } protected set { localUpDirectionRef.RawValue = value; } }
public SlimDX.Vector3 WorldUpDirection { get { return (SlimDX.Vector3)worldUpDirectionRef.RawValue; } protected set { worldUpDirectionRef.RawValue = value; } }
public SlimDX.Vector3 LocalRightDirection { get { return (SlimDX.Vector3)localRightDirectionRef.RawValue; } protected set { localRightDirectionRef.RawValue = value; } }
public SlimDX.Vector3 WorldRightDirection { get { return (SlimDX.Vector3)worldRightDirectionRef.RawValue; } protected set { worldRightDirectionRef.RawValue = value; } }
public SlimDX.Vector3 LocalScale
{
get { return localScale; }
set
{
localScale = value;
WantsUpdate = true;
}
}
public SlimDX.Vector3 WorldScale { get; protected set; }
public SlimDX.Matrix WorldMatrix { get { return (SlimDX.Matrix)worldMatrixRef.RawValue; } protected set { worldMatrixRef.RawValue = value; } }
public SlimDX.Matrix LocalMatrix { get { return (SlimDX.Matrix)localMatrixRef.RawValue; } protected set { localMatrixRef.RawValue = value; } }
public Transformation TransformationParent
{
get { return transformationParent; }
set
{
var oldTransformationParent = transformationParent;
transformationParent = value;
WantsUpdate = true;
if (oldTransformationParent != null)
oldTransformationParent.RemoveTransformation(this);
}
}
public IEnumerable<Transformation> Transformations { get { return transformations; } }
public void AddTransformation(Transformation transformation)
{
if (!transformations.Contains(transformation))
{
transformation.TransformationParent = this;
transformations.Add(transformation);
WantsUpdate = true;
}
}
public void RemoveTransformation(Transformation transformation)
{
if (transformations.Remove(transformation))
transformation.TransformationParent = null;
}
protected virtual void RecreateAllShaderParameters()
{
if (transformationBindings == null)
return;
if (!string.IsNullOrEmpty(transformationBindings.WorldMatrixSemanticName))
this.SetParameter(transformationBindings.WorldMatrixSemanticName, worldMatrixRef, ParameterBindType.BindBySemantic);
if (!string.IsNullOrEmpty(transformationBindings.LocalMatrixSemanticName))
this.SetParameter(transformationBindings.LocalMatrixSemanticName, localMatrixRef, ParameterBindType.BindBySemantic);
if (!string.IsNullOrEmpty(transformationBindings.WorldPositionSemanticName))
this.SetParameter(transformationBindings.WorldPositionSemanticName, worldPositionRef, ParameterBindType.BindBySemantic);
if (!string.IsNullOrEmpty(transformationBindings.LocalPositionSemanticName))
this.SetParameter(transformationBindings.LocalPositionSemanticName, localPositionRef, ParameterBindType.BindBySemantic);
if (!string.IsNullOrEmpty(transformationBindings.WorldDirectionSemanticName))
this.SetParameter(transformationBindings.WorldDirectionSemanticName, worldDirectionRef, ParameterBindType.BindBySemantic);
if (!string.IsNullOrEmpty(transformationBindings.LocalDirectionSemanticName))
this.SetParameter(transformationBindings.LocalDirectionSemanticName, localDirectionRef, ParameterBindType.BindBySemantic);
if (!string.IsNullOrEmpty(transformationBindings.WorldUpDirectionSemanticName))
this.SetParameter(transformationBindings.WorldUpDirectionSemanticName, worldUpDirectionRef, ParameterBindType.BindBySemantic);
if (!string.IsNullOrEmpty(transformationBindings.LocalUpDirectionSemanticName))
this.SetParameter(transformationBindings.LocalUpDirectionSemanticName, localUpDirectionRef, ParameterBindType.BindBySemantic);
if (!string.IsNullOrEmpty(transformationBindings.WorldRightDirectionSemanticName))
this.SetParameter(transformationBindings.WorldRightDirectionSemanticName, worldRightDirectionRef, ParameterBindType.BindBySemantic);
if (!string.IsNullOrEmpty(transformationBindings.LocalRightDirectionSemanticName))
this.SetParameter(transformationBindings.LocalRightDirectionSemanticName, localRightDirectionRef, ParameterBindType.BindBySemantic);
}
#endregion
#region IUpdatable Members
public virtual void Update(bool forceUpdate)
{
if (!WantsUpdate && !forceUpdate)
return;
WantsUpdate = false;
var localMatrix = SlimDX.Matrix.Transformation(SlimDX.Vector3.Zero, SlimDX.Quaternion.Identity, localScale, SlimDX.Vector3.Zero, localRotation, this.LocalPosition);
var direction = new SlimDX.Vector3(0.0f, 0.0f, 1.0f);
var upDirection = new SlimDX.Vector3(0.0f, 1.0f, 0.0f);
var rightDirection = new SlimDX.Vector3(1.0f, 0.0f, 0.0f);
{
var rotMat = SlimDX.Matrix.RotationQuaternion(localRotation);
LocalDirection = SlimDX.Vector3.TransformNormal(direction, rotMat);
LocalUpDirection = SlimDX.Vector3.TransformNormal(upDirection, rotMat);
LocalRightDirection = SlimDX.Vector3.TransformNormal(rightDirection, rotMat);
}
WorldMatrix = localMatrix;
// stack parent matrix
if (transformationParent != null)
WorldMatrix = localMatrix * transformationParent.WorldMatrix;
// extract world related data
SlimDX.Vector3 tmpScale;
SlimDX.Vector3 tmpPos;
SlimDX.Quaternion tmpRot;
WorldMatrix.Decompose(out tmpScale, out tmpRot, out tmpPos);
WorldPosition = tmpPos;
WorldRotation = tmpRot;
WorldScale = tmpScale;
{
var rotMat = SlimDX.Matrix.RotationQuaternion(WorldRotation);
WorldDirection = SlimDX.Vector3.TransformNormal(direction, rotMat);
WorldUpDirection = SlimDX.Vector3.TransformNormal(upDirection, rotMat);
WorldRightDirection = SlimDX.Vector3.TransformNormal(rightDirection, rotMat);
}
// update following transformations
foreach (var transformation in transformations)
if (transformation is IUpdatable)
{
var updatable = transformation as IUpdatable;
if (updatable != null && (updatable.WantsUpdate || forceUpdate))
updatable.Update(forceUpdate);
}
}
public bool WantsUpdate { get; protected set; }
#endregion
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,26 @@
D:\Code\blu-flame.org\aiwaz\Aiwaz.Resources\obj\Debug\ResolveAssemblyReference.cache
D:\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\Aiwaz.Contracts.dll
D:\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\Aiwaz.Contracts.pdb
D:\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\Aiwaz.Resources.dll
D:\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\Aiwaz.Resources.pdb
D:\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\Aiwaz.Core.dll
D:\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\Aiwaz.Core.pdb
D:\Code\blu-flame.org\aiwaz\Aiwaz.Resources\obj\Debug\Aiwaz.Resources.dll
D:\Code\blu-flame.org\aiwaz\Aiwaz.Resources\obj\Debug\Aiwaz.Resources.pdb
D:\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\Ionic.Zip.dll
D:\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\Aiwaz.Common.dll
D:\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\Aiwaz.Common.pdb
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\Aiwaz.Resources.dll
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\Aiwaz.Resources.pdb
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\Aiwaz.Common.dll
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\Aiwaz.Contracts.dll
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\Aiwaz.Core.dll
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\SlimDX.dll
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\Ionic.Zip.dll
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\Aiwaz.Common.pdb
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\Aiwaz.Contracts.pdb
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\Aiwaz.Core.pdb
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\Debug\SlimDX.xml
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\obj\Debug\Aiwaz.Resources.csprojResolveAssemblyReference.cache
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\obj\Debug\Aiwaz.Resources.dll
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\obj\Debug\Aiwaz.Resources.pdb

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,14 @@
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\x86\Debug\Aiwaz.Resources.dll
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\x86\Debug\Aiwaz.Resources.pdb
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\x86\Debug\Aiwaz.Common.dll
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\x86\Debug\Aiwaz.Contracts.dll
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\x86\Debug\Aiwaz.Core.dll
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\x86\Debug\SlimDX.dll
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\x86\Debug\Ionic.Zip.dll
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\x86\Debug\Aiwaz.Common.pdb
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\x86\Debug\Aiwaz.Contracts.pdb
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\x86\Debug\Aiwaz.Core.pdb
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\bin\x86\Debug\SlimDX.xml
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\obj\x86\Debug\Aiwaz.Resources.csprojResolveAssemblyReference.cache
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\obj\x86\Debug\Aiwaz.Resources.dll
D:\Private\Frank\Code\blu-flame.org\aiwaz\Aiwaz.Resources\obj\x86\Debug\Aiwaz.Resources.pdb