port from perforce
This commit is contained in:
154
aiwaz/Aiwaz.Resources/Aiwaz.Resources.csproj
Normal file
154
aiwaz/Aiwaz.Resources/Aiwaz.Resources.csproj
Normal 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>
|
||||
13
aiwaz/Aiwaz.Resources/Aiwaz.Resources.csproj.user
Normal file
13
aiwaz/Aiwaz.Resources/Aiwaz.Resources.csproj.user
Normal 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>
|
||||
16
aiwaz/Aiwaz.Resources/Attributes/CreationParameters.cs
Normal file
16
aiwaz/Aiwaz.Resources/Attributes/CreationParameters.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
aiwaz/Aiwaz.Resources/Attributes/ReadOnly.cs
Normal file
11
aiwaz/Aiwaz.Resources/Attributes/ReadOnly.cs
Normal 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
|
||||
{
|
||||
}
|
||||
}
|
||||
11
aiwaz/Aiwaz.Resources/Attributes/RequiredParameter.cs
Normal file
11
aiwaz/Aiwaz.Resources/Attributes/RequiredParameter.cs
Normal 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
|
||||
{
|
||||
}
|
||||
}
|
||||
323
aiwaz/Aiwaz.Resources/BluImporter/BluImporter.cs
Normal file
323
aiwaz/Aiwaz.Resources/BluImporter/BluImporter.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
115
aiwaz/Aiwaz.Resources/Bone.cs
Normal file
115
aiwaz/Aiwaz.Resources/Bone.cs
Normal 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
|
||||
}
|
||||
}
|
||||
277
aiwaz/Aiwaz.Resources/Camera.cs
Normal file
277
aiwaz/Aiwaz.Resources/Camera.cs
Normal 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
|
||||
}
|
||||
}
|
||||
342
aiwaz/Aiwaz.Resources/Commands/CommandBuffer.cs
Normal file
342
aiwaz/Aiwaz.Resources/Commands/CommandBuffer.cs
Normal 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
|
||||
}
|
||||
}
|
||||
137
aiwaz/Aiwaz.Resources/Commands/CommandUser.cs
Normal file
137
aiwaz/Aiwaz.Resources/Commands/CommandUser.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
8
aiwaz/Aiwaz.Resources/CreationParams.cs
Normal file
8
aiwaz/Aiwaz.Resources/CreationParams.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Aiwaz.Resources
|
||||
{
|
||||
}
|
||||
554
aiwaz/Aiwaz.Resources/GeometryBuffer.cs
Normal file
554
aiwaz/Aiwaz.Resources/GeometryBuffer.cs
Normal 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
|
||||
};
|
||||
}
|
||||
106
aiwaz/Aiwaz.Resources/PickHull.cs
Normal file
106
aiwaz/Aiwaz.Resources/PickHull.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
133
aiwaz/Aiwaz.Resources/Prefab/Cube.cs
Normal file
133
aiwaz/Aiwaz.Resources/Prefab/Cube.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
135
aiwaz/Aiwaz.Resources/Prefab/PingPongBuffer.cs
Normal file
135
aiwaz/Aiwaz.Resources/Prefab/PingPongBuffer.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
119
aiwaz/Aiwaz.Resources/Prefab/Quad.cs
Normal file
119
aiwaz/Aiwaz.Resources/Prefab/Quad.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
36
aiwaz/Aiwaz.Resources/Properties/AssemblyInfo.cs
Normal file
36
aiwaz/Aiwaz.Resources/Properties/AssemblyInfo.cs
Normal 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")]
|
||||
179
aiwaz/Aiwaz.Resources/RenderCommandNode.cs
Normal file
179
aiwaz/Aiwaz.Resources/RenderCommandNode.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
296
aiwaz/Aiwaz.Resources/RenderTarget.cs
Normal file
296
aiwaz/Aiwaz.Resources/RenderTarget.cs
Normal 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
|
||||
}
|
||||
}
|
||||
147
aiwaz/Aiwaz.Resources/RenderTargetTexture.cs
Normal file
147
aiwaz/Aiwaz.Resources/RenderTargetTexture.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
123
aiwaz/Aiwaz.Resources/Resource.cs
Normal file
123
aiwaz/Aiwaz.Resources/Resource.cs
Normal 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
|
||||
}
|
||||
}
|
||||
232
aiwaz/Aiwaz.Resources/Shader.cs
Normal file
232
aiwaz/Aiwaz.Resources/Shader.cs
Normal 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
|
||||
}
|
||||
}
|
||||
323
aiwaz/Aiwaz.Resources/ShaderParameterSet.cs
Normal file
323
aiwaz/Aiwaz.Resources/ShaderParameterSet.cs
Normal 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
|
||||
}
|
||||
}
|
||||
234
aiwaz/Aiwaz.Resources/SwapChain.cs
Normal file
234
aiwaz/Aiwaz.Resources/SwapChain.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
278
aiwaz/Aiwaz.Resources/Texture.cs
Normal file
278
aiwaz/Aiwaz.Resources/Texture.cs
Normal 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
|
||||
}
|
||||
}
|
||||
306
aiwaz/Aiwaz.Resources/Transformation.cs
Normal file
306
aiwaz/Aiwaz.Resources/Transformation.cs
Normal 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
|
||||
}
|
||||
}
|
||||
BIN
aiwaz/Aiwaz.Resources/bin/Debug/Aiwaz.Common.dll
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/Debug/Aiwaz.Common.dll
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/bin/Debug/Aiwaz.Common.pdb
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/Debug/Aiwaz.Common.pdb
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/bin/Debug/Aiwaz.Contracts.dll
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/Debug/Aiwaz.Contracts.dll
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/bin/Debug/Aiwaz.Contracts.pdb
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/Debug/Aiwaz.Contracts.pdb
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/bin/Debug/Aiwaz.Core.dll
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/Debug/Aiwaz.Core.dll
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/bin/Debug/Aiwaz.Core.pdb
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/Debug/Aiwaz.Core.pdb
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/bin/Debug/Aiwaz.Resources.dll
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/Debug/Aiwaz.Resources.dll
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/bin/Debug/Aiwaz.Resources.pdb
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/Debug/Aiwaz.Resources.pdb
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/bin/Debug/Ionic.Zip.dll
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/Debug/Ionic.Zip.dll
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/bin/Debug/SlimDX.dll
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/Debug/SlimDX.dll
Normal file
Binary file not shown.
43576
aiwaz/Aiwaz.Resources/bin/Debug/SlimDX.xml
Normal file
43576
aiwaz/Aiwaz.Resources/bin/Debug/SlimDX.xml
Normal file
File diff suppressed because it is too large
Load Diff
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/Aiwaz.Common.dll
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/Aiwaz.Common.dll
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/Aiwaz.Common.pdb
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/Aiwaz.Common.pdb
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/Aiwaz.Contracts.dll
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/Aiwaz.Contracts.dll
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/Aiwaz.Contracts.pdb
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/Aiwaz.Contracts.pdb
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/Aiwaz.Core.dll
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/Aiwaz.Core.dll
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/Aiwaz.Core.pdb
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/Aiwaz.Core.pdb
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/Aiwaz.Resources.dll
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/Aiwaz.Resources.dll
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/Aiwaz.Resources.pdb
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/Aiwaz.Resources.pdb
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/Ionic.Zip.dll
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/Ionic.Zip.dll
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/SlimDX.dll
Normal file
BIN
aiwaz/Aiwaz.Resources/bin/x86/Debug/SlimDX.dll
Normal file
Binary file not shown.
43576
aiwaz/Aiwaz.Resources/bin/x86/Debug/SlimDX.xml
Normal file
43576
aiwaz/Aiwaz.Resources/bin/x86/Debug/SlimDX.xml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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.
BIN
aiwaz/Aiwaz.Resources/obj/Debug/Aiwaz.Resources.dll
Normal file
BIN
aiwaz/Aiwaz.Resources/obj/Debug/Aiwaz.Resources.dll
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/obj/Debug/Aiwaz.Resources.pdb
Normal file
BIN
aiwaz/Aiwaz.Resources/obj/Debug/Aiwaz.Resources.pdb
Normal file
Binary file not shown.
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/obj/Debug/Refactor/Aiwaz.Resources.dll
Normal file
BIN
aiwaz/Aiwaz.Resources/obj/Debug/Refactor/Aiwaz.Resources.dll
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/obj/Debug/Refactor/AiwazResources.dll
Normal file
BIN
aiwaz/Aiwaz.Resources/obj/Debug/Refactor/AiwazResources.dll
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/obj/Debug/ResolveAssemblyReference.cache
Normal file
BIN
aiwaz/Aiwaz.Resources/obj/Debug/ResolveAssemblyReference.cache
Normal file
Binary file not shown.
Binary file not shown.
0
aiwaz/Aiwaz.Resources/obj/Release/build.force
Normal file
0
aiwaz/Aiwaz.Resources/obj/Release/build.force
Normal 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
|
||||
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/obj/x86/Debug/Aiwaz.Resources.dll
Normal file
BIN
aiwaz/Aiwaz.Resources/obj/x86/Debug/Aiwaz.Resources.dll
Normal file
Binary file not shown.
BIN
aiwaz/Aiwaz.Resources/obj/x86/Debug/Aiwaz.Resources.pdb
Normal file
BIN
aiwaz/Aiwaz.Resources/obj/x86/Debug/Aiwaz.Resources.pdb
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user