(ded4a3e0a) v0.9.0.7

This commit is contained in:
Joonas Rikkonen
2019-06-25 16:00:44 +03:00
parent e5ae622c77
commit 4a51db77b5
1777 changed files with 421528 additions and 917 deletions
@@ -0,0 +1,29 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// Defines the buffers for clearing when calling <see cref="GraphicsDevice.Clear(ClearOptions, Color, float, int)"/> operation.
/// </summary>
[Flags]
public enum ClearOptions
{
/// <summary>
/// Color buffer.
/// </summary>
Target = 1,
/// <summary>
/// Depth buffer.
/// </summary>
DepthBuffer = 2,
/// <summary>
/// Stencil buffer.
/// </summary>
Stencil = 4
}
}
@@ -0,0 +1,40 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// Defines the color channels for render target blending operations.
/// </summary>
[Flags]
public enum ColorWriteChannels
{
/// <summary>
/// No channels selected.
/// </summary>
None = 0,
/// <summary>
/// Red channel selected.
/// </summary>
Red = 1,
/// <summary>
/// Green channel selected.
/// </summary>
Green = 2,
/// <summary>
/// Blue channel selected.
/// </summary>
Blue = 4,
/// <summary>
/// Alpha channel selected.
/// </summary>
Alpha = 8,
/// <summary>
/// All channels selected.
/// </summary>
All = 15
}
}
@@ -0,0 +1,38 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// Defines the faces in a cube map for the <see cref="TextureCube"/> class.
/// </summary>
public enum CubeMapFace
{
/// <summary>
/// Positive X face in the cube map.
/// </summary>
PositiveX,
/// <summary>
/// Negative X face in the cube map.
/// </summary>
NegativeX,
/// <summary>
/// Positive Y face in the cube map.
/// </summary>
PositiveY,
/// <summary>
/// Negative Y face in the cube map.
/// </summary>
NegativeY,
/// <summary>
/// Positive Z face in the cube map.
/// </summary>
PositiveZ,
/// <summary>
/// Negative Z face in the cube map.
/// </summary>
NegativeZ
}
}
@@ -0,0 +1,27 @@
using System;
using System.Runtime.Serialization;
namespace Microsoft.Xna.Framework.Graphics
{
[DataContract]
public sealed class DeviceLostException : Exception
{
public DeviceLostException()
: base()
{
}
public DeviceLostException(string message)
: base(message)
{
}
public DeviceLostException(string message, Exception inner)
: base(message, inner)
{
}
}
}
@@ -0,0 +1,27 @@
using System;
using System.Runtime.Serialization;
namespace Microsoft.Xna.Framework.Graphics
{
[DataContract]
public sealed class DeviceNotResetException : Exception
{
public DeviceNotResetException()
: base()
{
}
public DeviceNotResetException(string message)
: base(message)
{
}
public DeviceNotResetException(string message, Exception inner)
: base(message, inner)
{
}
}
}
@@ -0,0 +1,142 @@
// #region License
// /*
// Microsoft Public License (Ms-PL)
// MonoGame - Copyright © 2009 The MonoGame Team
//
// All rights reserved.
//
// This license governs use of the accompanying software. If you use the software, you accept this license. If you do not
// accept the license, do not use the software.
//
// 1. Definitions
// The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under
// U.S. copyright law.
//
// A "contribution" is the original software, or any additions or changes to the software.
// A "contributor" is any person that distributes its contribution under this license.
// "Licensed patents" are a contributor's patent claims that read directly on its contribution.
//
// 2. Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
//
// 3. Conditions and Limitations
// (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
// your patent license from such contributor to the software ends automatically.
// (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source code form, you may do so only under this license by including
// a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object
// code form, you may only do so under a license that complies with this license.
// (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees
// or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
// permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular
// purpose and non-infringement.
// */
// #endregion License
//
using System;
using Microsoft.Xna.Framework.Graphics;
namespace Microsoft.Xna.Framework.Graphics
{
public sealed class DirectionalLight
{
internal EffectParameter diffuseColorParameter;
internal EffectParameter directionParameter;
internal EffectParameter specularColorParameter;
Vector3 diffuseColor;
Vector3 direction;
Vector3 specularColor;
bool enabled;
public DirectionalLight (EffectParameter directionParameter, EffectParameter diffuseColorParameter, EffectParameter specularColorParameter, DirectionalLight cloneSource)
{
this.diffuseColorParameter = diffuseColorParameter;
this.directionParameter = directionParameter;
this.specularColorParameter = specularColorParameter;
if (cloneSource != null) {
this.diffuseColor = cloneSource.diffuseColor;
this.direction = cloneSource.direction;
this.specularColor = cloneSource.specularColor;
this.enabled = cloneSource.enabled;
} else {
this.diffuseColorParameter = diffuseColorParameter;
this.directionParameter = directionParameter;
this.specularColorParameter = specularColorParameter;
}
}
public Vector3 DiffuseColor {
get {
return diffuseColor;
}
set {
diffuseColor = value;
if (this.enabled && this.diffuseColorParameter != null)
diffuseColorParameter.SetValue (diffuseColor);
}
}
public Vector3 Direction {
get {
return direction;
}
set {
direction = value;
if (this.directionParameter != null)
directionParameter.SetValue (direction);
}
}
public Vector3 SpecularColor {
get {
return specularColor;
}
set {
specularColor = value;
if (this.enabled && this.specularColorParameter != null)
specularColorParameter.SetValue (specularColor);
}
}
public bool Enabled
{
get { return enabled; }
set
{
if (this.enabled != value)
{
this.enabled = value;
if (this.enabled)
{
if (this.diffuseColorParameter != null)
{
this.diffuseColorParameter.SetValue(this.diffuseColor);
}
if (this.specularColorParameter != null)
{
this.specularColorParameter.SetValue(this.specularColor);
}
}
else
{
if (this.diffuseColorParameter != null)
{
this.diffuseColorParameter.SetValue(Vector3.Zero);
}
if (this.specularColorParameter != null)
{
this.specularColorParameter.SetValue(Vector3.Zero);
}
}
}
}
}
}
}
@@ -0,0 +1,126 @@
#region License
/*
MIT License
Copyright © 2006 The Mono.Xna Team
All rights reserved.
Authors:
* Rob Loach
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#endregion License
using System;
using System.Globalization;
using System.Runtime.Serialization;
namespace Microsoft.Xna.Framework.Graphics
{
[DataContract]
public class DisplayMode
{
#region Fields
private SurfaceFormat format;
private int height;
private int width;
#endregion Fields
#region Properties
public float AspectRatio {
get { return (float)width / (float)height; }
}
public SurfaceFormat Format {
get { return format; }
}
public int Height {
get { return this.height; }
}
public int Width {
get { return this.width; }
}
public Rectangle TitleSafeArea {
get { return GraphicsDevice.GetTitleSafeArea(0, 0, width, height); }
}
#endregion Properties
#region Constructors
internal DisplayMode(int width, int height, SurfaceFormat format)
{
this.width = width;
this.height = height;
this.format = format;
}
#endregion Constructors
#region Operators
public static bool operator !=(DisplayMode left, DisplayMode right)
{
return !(left == right);
}
public static bool operator ==(DisplayMode left, DisplayMode right)
{
if (ReferenceEquals(left, right)) //Same object or both are null
{
return true;
}
if (ReferenceEquals(left, null) || ReferenceEquals(right, null))
{
return false;
}
return (left.format == right.format) &&
(left.height == right.height) &&
(left.width == right.width);
}
#endregion Operators
#region Public Methods
public override bool Equals(object obj)
{
return obj is DisplayMode && this == (DisplayMode)obj;
}
public override int GetHashCode()
{
return (this.width.GetHashCode() ^ this.height.GetHashCode() ^ this.format.GetHashCode());
}
public override string ToString()
{
return "{Width:" + this.width + " Height:" + this.height + " Format:" + this.Format + " AspectRatio:" + this.AspectRatio + "}";
}
#endregion Public Methods
}
}
@@ -0,0 +1,81 @@
#region License
/*
MIT License
Copyright © 2006 The Mono.Xna Team
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#endregion License
using System;
using System.Collections;
using System.Collections.Generic;
namespace Microsoft.Xna.Framework.Graphics
{
public class DisplayModeCollection : IEnumerable<DisplayMode>
{
private readonly List<DisplayMode> _modes;
public IEnumerable<DisplayMode> this[SurfaceFormat format]
{
get
{
var list = new List<DisplayMode>();
foreach (var mode in _modes)
{
if (mode.Format == format)
list.Add(mode);
}
return list;
}
}
public IEnumerator<DisplayMode> GetEnumerator()
{
return _modes.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _modes.GetEnumerator();
}
internal DisplayModeCollection(List<DisplayMode> modes)
{
// Sort the modes in a consistent way that happens
// to match XNA behavior on some graphics devices.
modes.Sort(delegate(DisplayMode a, DisplayMode b)
{
if (a == b)
return 0;
if (a.Format <= b.Format && a.Width <= b.Width && a.Height <= b.Height)
return -1;
return 1;
});
_modes = modes;
}
}
}
@@ -0,0 +1,443 @@
// #region License
// /*
// Microsoft Public License (Ms-PL)
// MonoGame - Copyright © 2009 The MonoGame Team
//
// All rights reserved.
//
// This license governs use of the accompanying software. If you use the software, you accept this license. If you do not
// accept the license, do not use the software.
//
// 1. Definitions
// The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under
// U.S. copyright law.
//
// A "contribution" is the original software, or any additions or changes to the software.
// A "contributor" is any person that distributes its contribution under this license.
// "Licensed patents" are a contributor's patent claims that read directly on its contribution.
//
// 2. Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
//
// 3. Conditions and Limitations
// (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
// your patent license from such contributor to the software ends automatically.
// (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source code form, you may do so only under this license by including
// a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object
// code form, you may only do so under a license that complies with this license.
// (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees
// or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
// permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular
// purpose and non-infringement.
// */
// #endregion License
//
using System;
using System.IO;
namespace Microsoft.Xna.Framework.Graphics
{
internal static class DxtUtil
{
internal static byte[] DecompressDxt1(byte[] imageData, int width, int height)
{
using (MemoryStream imageStream = new MemoryStream(imageData))
return DecompressDxt1(imageStream, width, height);
}
internal static byte[] DecompressDxt1(Stream imageStream, int width, int height)
{
byte[] imageData = new byte[width * height * 4];
using (BinaryReader imageReader = new BinaryReader(imageStream))
{
int blockCountX = (width + 3) / 4;
int blockCountY = (height + 3) / 4;
for (int y = 0; y < blockCountY; y++)
{
for (int x = 0; x < blockCountX; x++)
{
DecompressDxt1Block(imageReader, x, y, blockCountX, width, height, imageData);
}
}
}
return imageData;
}
private static void DecompressDxt1Block(BinaryReader imageReader, int x, int y, int blockCountX, int width, int height, byte[] imageData)
{
ushort c0 = imageReader.ReadUInt16();
ushort c1 = imageReader.ReadUInt16();
byte r0, g0, b0;
byte r1, g1, b1;
ConvertRgb565ToRgb888(c0, out r0, out g0, out b0);
ConvertRgb565ToRgb888(c1, out r1, out g1, out b1);
uint lookupTable = imageReader.ReadUInt32();
for (int blockY = 0; blockY < 4; blockY++)
{
for (int blockX = 0; blockX < 4; blockX++)
{
byte r = 0, g = 0, b = 0, a = 255;
uint index = (lookupTable >> 2 * (4 * blockY + blockX)) & 0x03;
if (c0 > c1)
{
switch (index)
{
case 0:
r = r0;
g = g0;
b = b0;
break;
case 1:
r = r1;
g = g1;
b = b1;
break;
case 2:
r = (byte)((2 * r0 + r1) / 3);
g = (byte)((2 * g0 + g1) / 3);
b = (byte)((2 * b0 + b1) / 3);
break;
case 3:
r = (byte)((r0 + 2 * r1) / 3);
g = (byte)((g0 + 2 * g1) / 3);
b = (byte)((b0 + 2 * b1) / 3);
break;
}
}
else
{
switch (index)
{
case 0:
r = r0;
g = g0;
b = b0;
break;
case 1:
r = r1;
g = g1;
b = b1;
break;
case 2:
r = (byte)((r0 + r1) / 2);
g = (byte)((g0 + g1) / 2);
b = (byte)((b0 + b1) / 2);
break;
case 3:
r = 0;
g = 0;
b = 0;
a = 0;
break;
}
}
int px = (x << 2) + blockX;
int py = (y << 2) + blockY;
if ((px < width) && (py < height))
{
int offset = ((py * width) + px) << 2;
imageData[offset] = r;
imageData[offset + 1] = g;
imageData[offset + 2] = b;
imageData[offset + 3] = a;
}
}
}
}
internal static byte[] DecompressDxt3(byte[] imageData, int width, int height)
{
using (MemoryStream imageStream = new MemoryStream(imageData))
return DecompressDxt3(imageStream, width, height);
}
internal static byte[] DecompressDxt3(Stream imageStream, int width, int height)
{
byte[] imageData = new byte[width * height * 4];
using (BinaryReader imageReader = new BinaryReader(imageStream))
{
int blockCountX = (width + 3) / 4;
int blockCountY = (height + 3) / 4;
for (int y = 0; y < blockCountY; y++)
{
for (int x = 0; x < blockCountX; x++)
{
DecompressDxt3Block(imageReader, x, y, blockCountX, width, height, imageData);
}
}
}
return imageData;
}
private static void DecompressDxt3Block(BinaryReader imageReader, int x, int y, int blockCountX, int width, int height, byte[] imageData)
{
byte a0 = imageReader.ReadByte();
byte a1 = imageReader.ReadByte();
byte a2 = imageReader.ReadByte();
byte a3 = imageReader.ReadByte();
byte a4 = imageReader.ReadByte();
byte a5 = imageReader.ReadByte();
byte a6 = imageReader.ReadByte();
byte a7 = imageReader.ReadByte();
ushort c0 = imageReader.ReadUInt16();
ushort c1 = imageReader.ReadUInt16();
byte r0, g0, b0;
byte r1, g1, b1;
ConvertRgb565ToRgb888(c0, out r0, out g0, out b0);
ConvertRgb565ToRgb888(c1, out r1, out g1, out b1);
uint lookupTable = imageReader.ReadUInt32();
int alphaIndex = 0;
for (int blockY = 0; blockY < 4; blockY++)
{
for (int blockX = 0; blockX < 4; blockX++)
{
byte r = 0, g = 0, b = 0, a = 0;
uint index = (lookupTable >> 2 * (4 * blockY + blockX)) & 0x03;
switch (alphaIndex)
{
case 0:
a = (byte)((a0 & 0x0F) | ((a0 & 0x0F) << 4));
break;
case 1:
a = (byte)((a0 & 0xF0) | ((a0 & 0xF0) >> 4));
break;
case 2:
a = (byte)((a1 & 0x0F) | ((a1 & 0x0F) << 4));
break;
case 3:
a = (byte)((a1 & 0xF0) | ((a1 & 0xF0) >> 4));
break;
case 4:
a = (byte)((a2 & 0x0F) | ((a2 & 0x0F) << 4));
break;
case 5:
a = (byte)((a2 & 0xF0) | ((a2 & 0xF0) >> 4));
break;
case 6:
a = (byte)((a3 & 0x0F) | ((a3 & 0x0F) << 4));
break;
case 7:
a = (byte)((a3 & 0xF0) | ((a3 & 0xF0) >> 4));
break;
case 8:
a = (byte)((a4 & 0x0F) | ((a4 & 0x0F) << 4));
break;
case 9:
a = (byte)((a4 & 0xF0) | ((a4 & 0xF0) >> 4));
break;
case 10:
a = (byte)((a5 & 0x0F) | ((a5 & 0x0F) << 4));
break;
case 11:
a = (byte)((a5 & 0xF0) | ((a5 & 0xF0) >> 4));
break;
case 12:
a = (byte)((a6 & 0x0F) | ((a6 & 0x0F) << 4));
break;
case 13:
a = (byte)((a6 & 0xF0) | ((a6 & 0xF0) >> 4));
break;
case 14:
a = (byte)((a7 & 0x0F) | ((a7 & 0x0F) << 4));
break;
case 15:
a = (byte)((a7 & 0xF0) | ((a7 & 0xF0) >> 4));
break;
}
++alphaIndex;
switch (index)
{
case 0:
r = r0;
g = g0;
b = b0;
break;
case 1:
r = r1;
g = g1;
b = b1;
break;
case 2:
r = (byte)((2 * r0 + r1) / 3);
g = (byte)((2 * g0 + g1) / 3);
b = (byte)((2 * b0 + b1) / 3);
break;
case 3:
r = (byte)((r0 + 2 * r1) / 3);
g = (byte)((g0 + 2 * g1) / 3);
b = (byte)((b0 + 2 * b1) / 3);
break;
}
int px = (x << 2) + blockX;
int py = (y << 2) + blockY;
if ((px < width) && (py < height))
{
int offset = ((py * width) + px) << 2;
imageData[offset] = r;
imageData[offset + 1] = g;
imageData[offset + 2] = b;
imageData[offset + 3] = a;
}
}
}
}
internal static byte[] DecompressDxt5(byte[] imageData, int width, int height)
{
using (MemoryStream imageStream = new MemoryStream(imageData))
return DecompressDxt5(imageStream, width, height);
}
internal static byte[] DecompressDxt5(Stream imageStream, int width, int height)
{
byte[] imageData = new byte[width * height * 4];
using (BinaryReader imageReader = new BinaryReader(imageStream))
{
int blockCountX = (width + 3) / 4;
int blockCountY = (height + 3) / 4;
for (int y = 0; y < blockCountY; y++)
{
for (int x = 0; x < blockCountX; x++)
{
DecompressDxt5Block(imageReader, x, y, blockCountX, width, height, imageData);
}
}
}
return imageData;
}
private static void DecompressDxt5Block(BinaryReader imageReader, int x, int y, int blockCountX, int width, int height, byte[] imageData)
{
byte alpha0 = imageReader.ReadByte();
byte alpha1 = imageReader.ReadByte();
ulong alphaMask = (ulong)imageReader.ReadByte();
alphaMask += (ulong)imageReader.ReadByte() << 8;
alphaMask += (ulong)imageReader.ReadByte() << 16;
alphaMask += (ulong)imageReader.ReadByte() << 24;
alphaMask += (ulong)imageReader.ReadByte() << 32;
alphaMask += (ulong)imageReader.ReadByte() << 40;
ushort c0 = imageReader.ReadUInt16();
ushort c1 = imageReader.ReadUInt16();
byte r0, g0, b0;
byte r1, g1, b1;
ConvertRgb565ToRgb888(c0, out r0, out g0, out b0);
ConvertRgb565ToRgb888(c1, out r1, out g1, out b1);
uint lookupTable = imageReader.ReadUInt32();
for (int blockY = 0; blockY < 4; blockY++)
{
for (int blockX = 0; blockX < 4; blockX++)
{
byte r = 0, g = 0, b = 0, a = 255;
uint index = (lookupTable >> 2 * (4 * blockY + blockX)) & 0x03;
uint alphaIndex = (uint)((alphaMask >> 3 * (4 * blockY + blockX)) & 0x07);
if (alphaIndex == 0)
{
a = alpha0;
}
else if (alphaIndex == 1)
{
a = alpha1;
}
else if (alpha0 > alpha1)
{
a = (byte)(((8 - alphaIndex) * alpha0 + (alphaIndex - 1) * alpha1) / 7);
}
else if (alphaIndex == 6)
{
a = 0;
}
else if (alphaIndex == 7)
{
a = 0xff;
}
else
{
a = (byte)(((6 - alphaIndex) * alpha0 + (alphaIndex - 1) * alpha1) / 5);
}
switch (index)
{
case 0:
r = r0;
g = g0;
b = b0;
break;
case 1:
r = r1;
g = g1;
b = b1;
break;
case 2:
r = (byte)((2 * r0 + r1) / 3);
g = (byte)((2 * g0 + g1) / 3);
b = (byte)((2 * b0 + b1) / 3);
break;
case 3:
r = (byte)((r0 + 2 * r1) / 3);
g = (byte)((g0 + 2 * g1) / 3);
b = (byte)((b0 + 2 * b1) / 3);
break;
}
int px = (x << 2) + blockX;
int py = (y << 2) + blockY;
if ((px < width) && (py < height))
{
int offset = ((py * width) + px) << 2;
imageData[offset] = r;
imageData[offset + 1] = g;
imageData[offset + 2] = b;
imageData[offset + 3] = a;
}
}
}
}
private static void ConvertRgb565ToRgb888(ushort color, out byte r, out byte g, out byte b)
{
int temp;
temp = (color >> 11) * 255 + 16;
r = (byte)((temp / 32 + temp) / 32);
temp = ((color & 0x07E0) >> 5) * 255 + 32;
g = (byte)((temp / 64 + temp) / 64);
temp = (color & 0x001F) * 255 + 16;
b = (byte)((temp / 32 + temp) / 32);
}
}
}
@@ -0,0 +1,441 @@
#region File Description
//-----------------------------------------------------------------------------
// AlphaTestEffect.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
#endregion
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// Built-in effect that supports alpha testing.
/// </summary>
public class AlphaTestEffect : Effect, IEffectMatrices, IEffectFog
{
#region Effect Parameters
EffectParameter textureParam;
EffectParameter diffuseColorParam;
EffectParameter alphaTestParam;
EffectParameter fogColorParam;
EffectParameter fogVectorParam;
EffectParameter worldViewProjParam;
#endregion
#region Fields
bool fogEnabled;
bool vertexColorEnabled;
Matrix world = Matrix.Identity;
Matrix view = Matrix.Identity;
Matrix projection = Matrix.Identity;
Matrix worldView;
Vector3 diffuseColor = Vector3.One;
float alpha = 1;
float fogStart = 0;
float fogEnd = 1;
CompareFunction alphaFunction = CompareFunction.Greater;
int referenceAlpha;
bool isEqNe;
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
#endregion
#region Public Properties
/// <summary>
/// Gets or sets the world matrix.
/// </summary>
public Matrix World
{
get { return world; }
set
{
world = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.Fog;
}
}
/// <summary>
/// Gets or sets the view matrix.
/// </summary>
public Matrix View
{
get { return view; }
set
{
view = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.Fog;
}
}
/// <summary>
/// Gets or sets the projection matrix.
/// </summary>
public Matrix Projection
{
get { return projection; }
set
{
projection = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
}
}
/// <summary>
/// Gets or sets the material diffuse color (range 0 to 1).
/// </summary>
public Vector3 DiffuseColor
{
get { return diffuseColor; }
set
{
diffuseColor = value;
dirtyFlags |= EffectDirtyFlags.MaterialColor;
}
}
/// <summary>
/// Gets or sets the material alpha.
/// </summary>
public float Alpha
{
get { return alpha; }
set
{
alpha = value;
dirtyFlags |= EffectDirtyFlags.MaterialColor;
}
}
/// <summary>
/// Gets or sets the fog enable flag.
/// </summary>
public bool FogEnabled
{
get { return fogEnabled; }
set
{
if (fogEnabled != value)
{
fogEnabled = value;
dirtyFlags |= EffectDirtyFlags.ShaderIndex | EffectDirtyFlags.FogEnable;
}
}
}
/// <summary>
/// Gets or sets the fog start distance.
/// </summary>
public float FogStart
{
get { return fogStart; }
set
{
fogStart = value;
dirtyFlags |= EffectDirtyFlags.Fog;
}
}
/// <summary>
/// Gets or sets the fog end distance.
/// </summary>
public float FogEnd
{
get { return fogEnd; }
set
{
fogEnd = value;
dirtyFlags |= EffectDirtyFlags.Fog;
}
}
/// <summary>
/// Gets or sets the fog color.
/// </summary>
public Vector3 FogColor
{
get { return fogColorParam.GetValueVector3(); }
set { fogColorParam.SetValue(value); }
}
/// <summary>
/// Gets or sets the current texture.
/// </summary>
public Texture2D Texture
{
get { return textureParam.GetValueTexture2D(); }
set { textureParam.SetValue(value); }
}
/// <summary>
/// Gets or sets whether vertex color is enabled.
/// </summary>
public bool VertexColorEnabled
{
get { return vertexColorEnabled; }
set
{
if (vertexColorEnabled != value)
{
vertexColorEnabled = value;
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
}
}
}
/// <summary>
/// Gets or sets the alpha compare function (default Greater).
/// </summary>
public CompareFunction AlphaFunction
{
get { return alphaFunction; }
set
{
alphaFunction = value;
dirtyFlags |= EffectDirtyFlags.AlphaTest;
}
}
/// <summary>
/// Gets or sets the reference alpha value (default 0).
/// </summary>
public int ReferenceAlpha
{
get { return referenceAlpha; }
set
{
referenceAlpha = value;
dirtyFlags |= EffectDirtyFlags.AlphaTest;
}
}
#endregion
#region Methods
/// <summary>
/// Creates a new AlphaTestEffect with default parameter settings.
/// </summary>
public AlphaTestEffect(GraphicsDevice device)
: base(device, EffectResource.AlphaTestEffect.Bytecode)
{
CacheEffectParameters();
}
/// <summary>
/// Creates a new AlphaTestEffect by cloning parameter settings from an existing instance.
/// </summary>
protected AlphaTestEffect(AlphaTestEffect cloneSource)
: base(cloneSource)
{
CacheEffectParameters();
fogEnabled = cloneSource.fogEnabled;
vertexColorEnabled = cloneSource.vertexColorEnabled;
world = cloneSource.world;
view = cloneSource.view;
projection = cloneSource.projection;
diffuseColor = cloneSource.diffuseColor;
alpha = cloneSource.alpha;
fogStart = cloneSource.fogStart;
fogEnd = cloneSource.fogEnd;
alphaFunction = cloneSource.alphaFunction;
referenceAlpha = cloneSource.referenceAlpha;
}
/// <summary>
/// Creates a clone of the current AlphaTestEffect instance.
/// </summary>
public override Effect Clone()
{
return new AlphaTestEffect(this);
}
/// <summary>
/// Looks up shortcut references to our effect parameters.
/// </summary>
void CacheEffectParameters()
{
textureParam = Parameters["Texture"];
diffuseColorParam = Parameters["DiffuseColor"];
alphaTestParam = Parameters["AlphaTest"];
fogColorParam = Parameters["FogColor"];
fogVectorParam = Parameters["FogVector"];
worldViewProjParam = Parameters["WorldViewProj"];
}
/// <summary>
/// Lazily computes derived parameter values immediately before applying the effect.
/// </summary>
protected internal override void OnApply()
{
// Recompute the world+view+projection matrix or fog vector?
dirtyFlags = EffectHelpers.SetWorldViewProjAndFog(dirtyFlags, ref world, ref view, ref projection, ref worldView, fogEnabled, fogStart, fogEnd, worldViewProjParam, fogVectorParam);
// Recompute the diffuse/alpha material color parameter?
if ((dirtyFlags & EffectDirtyFlags.MaterialColor) != 0)
{
diffuseColorParam.SetValue(new Vector4(diffuseColor * alpha, alpha));
dirtyFlags &= ~EffectDirtyFlags.MaterialColor;
}
// Recompute the alpha test settings?
if ((dirtyFlags & EffectDirtyFlags.AlphaTest) != 0)
{
Vector4 alphaTest = new Vector4();
bool eqNe = false;
// Convert reference alpha from 8 bit integer to 0-1 float format.
float reference = (float)referenceAlpha / 255f;
// Comparison tolerance of half the 8 bit integer precision.
const float threshold = 0.5f / 255f;
switch (alphaFunction)
{
case CompareFunction.Less:
// Shader will evaluate: clip((a < x) ? z : w)
alphaTest.X = reference - threshold;
alphaTest.Z = 1;
alphaTest.W = -1;
break;
case CompareFunction.LessEqual:
// Shader will evaluate: clip((a < x) ? z : w)
alphaTest.X = reference + threshold;
alphaTest.Z = 1;
alphaTest.W = -1;
break;
case CompareFunction.GreaterEqual:
// Shader will evaluate: clip((a < x) ? z : w)
alphaTest.X = reference - threshold;
alphaTest.Z = -1;
alphaTest.W = 1;
break;
case CompareFunction.Greater:
// Shader will evaluate: clip((a < x) ? z : w)
alphaTest.X = reference + threshold;
alphaTest.Z = -1;
alphaTest.W = 1;
break;
case CompareFunction.Equal:
// Shader will evaluate: clip((abs(a - x) < Y) ? z : w)
alphaTest.X = reference;
alphaTest.Y = threshold;
alphaTest.Z = 1;
alphaTest.W = -1;
eqNe = true;
break;
case CompareFunction.NotEqual:
// Shader will evaluate: clip((abs(a - x) < Y) ? z : w)
alphaTest.X = reference;
alphaTest.Y = threshold;
alphaTest.Z = -1;
alphaTest.W = 1;
eqNe = true;
break;
case CompareFunction.Never:
// Shader will evaluate: clip((a < x) ? z : w)
alphaTest.Z = -1;
alphaTest.W = -1;
break;
case CompareFunction.Always:
default:
// Shader will evaluate: clip((a < x) ? z : w)
alphaTest.Z = 1;
alphaTest.W = 1;
break;
}
alphaTestParam.SetValue(alphaTest);
dirtyFlags &= ~EffectDirtyFlags.AlphaTest;
// If we changed between less/greater vs. equal/notequal
// compare modes, we must also update the shader index.
if (isEqNe != eqNe)
{
isEqNe = eqNe;
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
}
}
// Recompute the shader index?
if ((dirtyFlags & EffectDirtyFlags.ShaderIndex) != 0)
{
int shaderIndex = 0;
if (!fogEnabled)
shaderIndex += 1;
if (vertexColorEnabled)
shaderIndex += 2;
if (isEqNe)
shaderIndex += 4;
dirtyFlags &= ~EffectDirtyFlags.ShaderIndex;
CurrentTechnique = Techniques[shaderIndex];
}
}
#endregion
}
}
@@ -0,0 +1,501 @@
#region File Description
//-----------------------------------------------------------------------------
// BasicEffect.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
#endregion
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// Built-in effect that supports optional texturing, vertex coloring, fog, and lighting.
/// </summary>
public class BasicEffect : Effect, IEffectMatrices, IEffectLights, IEffectFog
{
#region Effect Parameters
EffectParameter textureParam;
EffectParameter diffuseColorParam;
EffectParameter emissiveColorParam;
EffectParameter specularColorParam;
EffectParameter specularPowerParam;
EffectParameter eyePositionParam;
EffectParameter fogColorParam;
EffectParameter fogVectorParam;
EffectParameter worldParam;
EffectParameter worldInverseTransposeParam;
EffectParameter worldViewProjParam;
#endregion
#region Fields
bool lightingEnabled;
bool preferPerPixelLighting;
bool oneLight;
bool fogEnabled;
bool textureEnabled;
bool vertexColorEnabled;
Matrix world = Matrix.Identity;
Matrix view = Matrix.Identity;
Matrix projection = Matrix.Identity;
Matrix worldView;
Vector3 diffuseColor = Vector3.One;
Vector3 emissiveColor = Vector3.Zero;
Vector3 ambientLightColor = Vector3.Zero;
float alpha = 1;
DirectionalLight light0;
DirectionalLight light1;
DirectionalLight light2;
float fogStart = 0;
float fogEnd = 1;
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
#endregion
#region Public Properties
/// <summary>
/// Gets or sets the world matrix.
/// </summary>
public Matrix World
{
get { return world; }
set
{
world = value;
dirtyFlags |= EffectDirtyFlags.World | EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.Fog;
}
}
/// <summary>
/// Gets or sets the view matrix.
/// </summary>
public Matrix View
{
get { return view; }
set
{
view = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.EyePosition | EffectDirtyFlags.Fog;
}
}
/// <summary>
/// Gets or sets the projection matrix.
/// </summary>
public Matrix Projection
{
get { return projection; }
set
{
projection = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
}
}
/// <summary>
/// Gets or sets the material diffuse color (range 0 to 1).
/// </summary>
public Vector3 DiffuseColor
{
get { return diffuseColor; }
set
{
diffuseColor = value;
dirtyFlags |= EffectDirtyFlags.MaterialColor;
}
}
/// <summary>
/// Gets or sets the material emissive color (range 0 to 1).
/// </summary>
public Vector3 EmissiveColor
{
get { return emissiveColor; }
set
{
emissiveColor = value;
dirtyFlags |= EffectDirtyFlags.MaterialColor;
}
}
/// <summary>
/// Gets or sets the material specular color (range 0 to 1).
/// </summary>
public Vector3 SpecularColor
{
get { return specularColorParam.GetValueVector3(); }
set { specularColorParam.SetValue(value); }
}
/// <summary>
/// Gets or sets the material specular power.
/// </summary>
public float SpecularPower
{
get { return specularPowerParam.GetValueSingle(); }
set { specularPowerParam.SetValue(value); }
}
/// <summary>
/// Gets or sets the material alpha.
/// </summary>
public float Alpha
{
get { return alpha; }
set
{
alpha = value;
dirtyFlags |= EffectDirtyFlags.MaterialColor;
}
}
/// <inheritdoc/>
public bool LightingEnabled
{
get { return lightingEnabled; }
set
{
if (lightingEnabled != value)
{
lightingEnabled = value;
dirtyFlags |= EffectDirtyFlags.ShaderIndex | EffectDirtyFlags.MaterialColor;
}
}
}
/// <summary>
/// Gets or sets the per-pixel lighting prefer flag.
/// </summary>
public bool PreferPerPixelLighting
{
get { return preferPerPixelLighting; }
set
{
if (preferPerPixelLighting != value)
{
preferPerPixelLighting = value;
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
}
}
}
/// <inheritdoc/>
public Vector3 AmbientLightColor
{
get { return ambientLightColor; }
set
{
ambientLightColor = value;
dirtyFlags |= EffectDirtyFlags.MaterialColor;
}
}
/// <inheritdoc/>
public DirectionalLight DirectionalLight0 { get { return light0; } }
/// <inheritdoc/>
public DirectionalLight DirectionalLight1 { get { return light1; } }
/// <inheritdoc/>
public DirectionalLight DirectionalLight2 { get { return light2; } }
/// <inheritdoc/>
public bool FogEnabled
{
get { return fogEnabled; }
set
{
if (fogEnabled != value)
{
fogEnabled = value;
dirtyFlags |= EffectDirtyFlags.ShaderIndex | EffectDirtyFlags.FogEnable;
}
}
}
/// <inheritdoc/>
public float FogStart
{
get { return fogStart; }
set
{
fogStart = value;
dirtyFlags |= EffectDirtyFlags.Fog;
}
}
/// <inheritdoc/>
public float FogEnd
{
get { return fogEnd; }
set
{
fogEnd = value;
dirtyFlags |= EffectDirtyFlags.Fog;
}
}
/// <inheritdoc/>
public Vector3 FogColor
{
get { return fogColorParam.GetValueVector3(); }
set { fogColorParam.SetValue(value); }
}
/// <summary>
/// Gets or sets whether texturing is enabled.
/// </summary>
public bool TextureEnabled
{
get { return textureEnabled; }
set
{
if (textureEnabled != value)
{
textureEnabled = value;
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
}
}
}
/// <summary>
/// Gets or sets the current texture.
/// </summary>
public Texture2D Texture
{
get { return textureParam.GetValueTexture2D(); }
set { textureParam.SetValue(value); }
}
/// <summary>
/// Gets or sets whether vertex color is enabled.
/// </summary>
public bool VertexColorEnabled
{
get { return vertexColorEnabled; }
set
{
if (vertexColorEnabled != value)
{
vertexColorEnabled = value;
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
}
}
}
#endregion
#region Methods
/// <summary>
/// Creates a new BasicEffect with default parameter settings.
/// </summary>
public BasicEffect(GraphicsDevice device)
: base(device, EffectResource.BasicEffect.Bytecode)
{
CacheEffectParameters(null);
DirectionalLight0.Enabled = true;
SpecularColor = Vector3.One;
SpecularPower = 16;
}
/// <summary>
/// Creates a new BasicEffect by cloning parameter settings from an existing instance.
/// </summary>
protected BasicEffect(BasicEffect cloneSource)
: base(cloneSource)
{
CacheEffectParameters(cloneSource);
lightingEnabled = cloneSource.lightingEnabled;
preferPerPixelLighting = cloneSource.preferPerPixelLighting;
fogEnabled = cloneSource.fogEnabled;
textureEnabled = cloneSource.textureEnabled;
vertexColorEnabled = cloneSource.vertexColorEnabled;
world = cloneSource.world;
view = cloneSource.view;
projection = cloneSource.projection;
diffuseColor = cloneSource.diffuseColor;
emissiveColor = cloneSource.emissiveColor;
ambientLightColor = cloneSource.ambientLightColor;
alpha = cloneSource.alpha;
fogStart = cloneSource.fogStart;
fogEnd = cloneSource.fogEnd;
}
/// <summary>
/// Creates a clone of the current BasicEffect instance.
/// </summary>
public override Effect Clone()
{
return new BasicEffect(this);
}
/// <inheritdoc/>
public void EnableDefaultLighting()
{
LightingEnabled = true;
AmbientLightColor = EffectHelpers.EnableDefaultLighting(light0, light1, light2);
}
/// <summary>
/// Looks up shortcut references to our effect parameters.
/// </summary>
void CacheEffectParameters(BasicEffect cloneSource)
{
textureParam = Parameters["Texture"];
diffuseColorParam = Parameters["DiffuseColor"];
emissiveColorParam = Parameters["EmissiveColor"];
specularColorParam = Parameters["SpecularColor"];
specularPowerParam = Parameters["SpecularPower"];
eyePositionParam = Parameters["EyePosition"];
fogColorParam = Parameters["FogColor"];
fogVectorParam = Parameters["FogVector"];
worldParam = Parameters["World"];
worldInverseTransposeParam = Parameters["WorldInverseTranspose"];
worldViewProjParam = Parameters["WorldViewProj"];
light0 = new DirectionalLight(Parameters["DirLight0Direction"],
Parameters["DirLight0DiffuseColor"],
Parameters["DirLight0SpecularColor"],
(cloneSource != null) ? cloneSource.light0 : null);
light1 = new DirectionalLight(Parameters["DirLight1Direction"],
Parameters["DirLight1DiffuseColor"],
Parameters["DirLight1SpecularColor"],
(cloneSource != null) ? cloneSource.light1 : null);
light2 = new DirectionalLight(Parameters["DirLight2Direction"],
Parameters["DirLight2DiffuseColor"],
Parameters["DirLight2SpecularColor"],
(cloneSource != null) ? cloneSource.light2 : null);
}
/// <summary>
/// Lazily computes derived parameter values immediately before applying the effect.
/// </summary>
protected internal override void OnApply()
{
// Recompute the world+view+projection matrix or fog vector?
dirtyFlags = EffectHelpers.SetWorldViewProjAndFog(dirtyFlags, ref world, ref view, ref projection, ref worldView, fogEnabled, fogStart, fogEnd, worldViewProjParam, fogVectorParam);
// Recompute the diffuse/emissive/alpha material color parameters?
if ((dirtyFlags & EffectDirtyFlags.MaterialColor) != 0)
{
EffectHelpers.SetMaterialColor(lightingEnabled, alpha, ref diffuseColor, ref emissiveColor, ref ambientLightColor, diffuseColorParam, emissiveColorParam);
dirtyFlags &= ~EffectDirtyFlags.MaterialColor;
}
if (lightingEnabled)
{
// Recompute the world inverse transpose and eye position?
dirtyFlags = EffectHelpers.SetLightingMatrices(dirtyFlags, ref world, ref view, worldParam, worldInverseTransposeParam, eyePositionParam);
// Check if we can use the only-bother-with-the-first-light shader optimization.
bool newOneLight = !light1.Enabled && !light2.Enabled;
if (oneLight != newOneLight)
{
oneLight = newOneLight;
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
}
}
// Recompute the shader index?
if ((dirtyFlags & EffectDirtyFlags.ShaderIndex) != 0)
{
int shaderIndex = 0;
if (!fogEnabled)
shaderIndex += 1;
if (vertexColorEnabled)
shaderIndex += 2;
if (textureEnabled)
shaderIndex += 4;
if (lightingEnabled)
{
if (preferPerPixelLighting)
shaderIndex += 24;
else if (oneLight)
shaderIndex += 16;
else
shaderIndex += 8;
}
dirtyFlags &= ~EffectDirtyFlags.ShaderIndex;
CurrentTechnique = Techniques[shaderIndex];
}
}
#endregion
}
}
@@ -0,0 +1,327 @@
#region File Description
//-----------------------------------------------------------------------------
// DualTextureEffect.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endregion
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// Built-in effect that supports two-layer multitexturing.
/// </summary>
public class DualTextureEffect : Effect, IEffectMatrices, IEffectFog
{
#region Effect Parameters
EffectParameter textureParam;
EffectParameter texture2Param;
EffectParameter diffuseColorParam;
EffectParameter fogColorParam;
EffectParameter fogVectorParam;
EffectParameter worldViewProjParam;
#endregion
#region Fields
bool fogEnabled;
bool vertexColorEnabled;
Matrix world = Matrix.Identity;
Matrix view = Matrix.Identity;
Matrix projection = Matrix.Identity;
Matrix worldView;
Vector3 diffuseColor = Vector3.One;
float alpha = 1;
float fogStart = 0;
float fogEnd = 1;
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
#endregion
#region Public Properties
/// <summary>
/// Gets or sets the world matrix.
/// </summary>
public Matrix World
{
get { return world; }
set
{
world = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.Fog;
}
}
/// <summary>
/// Gets or sets the view matrix.
/// </summary>
public Matrix View
{
get { return view; }
set
{
view = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.Fog;
}
}
/// <summary>
/// Gets or sets the projection matrix.
/// </summary>
public Matrix Projection
{
get { return projection; }
set
{
projection = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
}
}
/// <summary>
/// Gets or sets the material diffuse color (range 0 to 1).
/// </summary>
public Vector3 DiffuseColor
{
get { return diffuseColor; }
set
{
diffuseColor = value;
dirtyFlags |= EffectDirtyFlags.MaterialColor;
}
}
/// <summary>
/// Gets or sets the material alpha.
/// </summary>
public float Alpha
{
get { return alpha; }
set
{
alpha = value;
dirtyFlags |= EffectDirtyFlags.MaterialColor;
}
}
/// <summary>
/// Gets or sets the fog enable flag.
/// </summary>
public bool FogEnabled
{
get { return fogEnabled; }
set
{
if (fogEnabled != value)
{
fogEnabled = value;
dirtyFlags |= EffectDirtyFlags.ShaderIndex | EffectDirtyFlags.FogEnable;
}
}
}
/// <summary>
/// Gets or sets the fog start distance.
/// </summary>
public float FogStart
{
get { return fogStart; }
set
{
fogStart = value;
dirtyFlags |= EffectDirtyFlags.Fog;
}
}
/// <summary>
/// Gets or sets the fog end distance.
/// </summary>
public float FogEnd
{
get { return fogEnd; }
set
{
fogEnd = value;
dirtyFlags |= EffectDirtyFlags.Fog;
}
}
/// <summary>
/// Gets or sets the fog color.
/// </summary>
public Vector3 FogColor
{
get { return fogColorParam.GetValueVector3(); }
set { fogColorParam.SetValue(value); }
}
/// <summary>
/// Gets or sets the current base texture.
/// </summary>
public Texture2D Texture
{
get { return textureParam.GetValueTexture2D(); }
set { textureParam.SetValue(value); }
}
/// <summary>
/// Gets or sets the current overlay texture.
/// </summary>
public Texture2D Texture2
{
get { return texture2Param.GetValueTexture2D(); }
set { texture2Param.SetValue(value); }
}
/// <summary>
/// Gets or sets whether vertex color is enabled.
/// </summary>
public bool VertexColorEnabled
{
get { return vertexColorEnabled; }
set
{
if (vertexColorEnabled != value)
{
vertexColorEnabled = value;
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
}
}
}
#endregion
#region Methods
/// <summary>
/// Creates a new DualTextureEffect with default parameter settings.
/// </summary>
public DualTextureEffect(GraphicsDevice device)
: base(device, EffectResource.DualTextureEffect.Bytecode)
{
CacheEffectParameters();
}
/// <summary>
/// Creates a new DualTextureEffect by cloning parameter settings from an existing instance.
/// </summary>
protected DualTextureEffect(DualTextureEffect cloneSource)
: base(cloneSource)
{
CacheEffectParameters();
fogEnabled = cloneSource.fogEnabled;
vertexColorEnabled = cloneSource.vertexColorEnabled;
world = cloneSource.world;
view = cloneSource.view;
projection = cloneSource.projection;
diffuseColor = cloneSource.diffuseColor;
alpha = cloneSource.alpha;
fogStart = cloneSource.fogStart;
fogEnd = cloneSource.fogEnd;
}
/// <summary>
/// Creates a clone of the current DualTextureEffect instance.
/// </summary>
public override Effect Clone()
{
return new DualTextureEffect(this);
}
/// <summary>
/// Looks up shortcut references to our effect parameters.
/// </summary>
void CacheEffectParameters()
{
textureParam = Parameters["Texture"];
texture2Param = Parameters["Texture2"];
diffuseColorParam = Parameters["DiffuseColor"];
fogColorParam = Parameters["FogColor"];
fogVectorParam = Parameters["FogVector"];
worldViewProjParam = Parameters["WorldViewProj"];
}
/// <summary>
/// Lazily computes derived parameter values immediately before applying the effect.
/// </summary>
protected internal override void OnApply()
{
// Recompute the world+view+projection matrix or fog vector?
dirtyFlags = EffectHelpers.SetWorldViewProjAndFog(dirtyFlags, ref world, ref view, ref projection, ref worldView, fogEnabled, fogStart, fogEnd, worldViewProjParam, fogVectorParam);
// Recompute the diffuse/alpha material color parameter?
if ((dirtyFlags & EffectDirtyFlags.MaterialColor) != 0)
{
diffuseColorParam.SetValue(new Vector4(diffuseColor * alpha, alpha));
dirtyFlags &= ~EffectDirtyFlags.MaterialColor;
}
// Recompute the shader index?
if ((dirtyFlags & EffectDirtyFlags.ShaderIndex) != 0)
{
int shaderIndex = 0;
if (!fogEnabled)
shaderIndex += 1;
if (vertexColorEnabled)
shaderIndex += 2;
dirtyFlags &= ~EffectDirtyFlags.ShaderIndex;
CurrentTechnique = Techniques[shaderIndex];
}
}
#endregion
}
}
@@ -0,0 +1,459 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Diagnostics;
using System.IO;
namespace Microsoft.Xna.Framework.Graphics
{
public class Effect : GraphicsResource
{
struct MGFXHeader
{
/// <summary>
/// The MonoGame Effect file format header identifier ("MGFX").
/// </summary>
public static readonly int MGFXSignature = (BitConverter.IsLittleEndian) ? 0x5846474D: 0x4D474658;
/// <summary>
/// The current MonoGame Effect file format versions
/// used to detect old packaged content.
/// </summary>
/// <remarks>
/// We should avoid supporting old versions for very long if at all
/// as users should be rebuilding content when packaging their game.
/// </remarks>
public const int MGFXVersion = 8;
public int Signature;
public int Version;
public int Profile;
public int EffectKey;
public int HeaderSize;
}
public EffectParameterCollection Parameters { get; private set; }
public EffectTechniqueCollection Techniques { get; private set; }
public EffectTechnique CurrentTechnique { get; set; }
internal ConstantBuffer[] ConstantBuffers { get; private set; }
private Shader[] _shaders;
private readonly bool _isClone;
internal Effect(GraphicsDevice graphicsDevice)
{
if (graphicsDevice == null)
{
throw new ArgumentNullException("graphicsDevice", FrameworkResources.ResourceCreationWhenDeviceIsNull);
}
this.GraphicsDevice = graphicsDevice;
}
protected Effect(Effect cloneSource)
: this(cloneSource.GraphicsDevice)
{
_isClone = true;
Clone(cloneSource);
}
public Effect(GraphicsDevice graphicsDevice, byte[] effectCode)
: this(graphicsDevice, effectCode, 0, effectCode.Length)
{
}
public Effect (GraphicsDevice graphicsDevice, byte[] effectCode, int index, int count)
: this(graphicsDevice)
{
// By default we currently cache all unique byte streams
// and use cloning to populate the effect with parameters,
// techniques, and passes.
//
// This means all the immutable types in an effect:
//
// - Shaders
// - Annotations
// - Names
// - State Objects
//
// Are shared for every instance of an effect while the
// parameter values and constant buffers are copied.
//
// This might need to change slightly if/when we support
// shared constant buffers as 'new' should return unique
// effects without any shared instance state.
//Read the header
MGFXHeader header = ReadHeader(effectCode, index);
var effectKey = header.EffectKey;
int headerSize = header.HeaderSize;
// First look for it in the cache.
//
Effect cloneSource;
if (!graphicsDevice.EffectCache.TryGetValue(effectKey, out cloneSource))
{
using (var stream = new MemoryStream(effectCode, index + headerSize, count - headerSize, false))
using (var reader = new BinaryReader(stream))
{
// Create one.
cloneSource = new Effect(graphicsDevice);
cloneSource.ReadEffect(reader);
// Cache the effect for later in its original unmodified state.
graphicsDevice.EffectCache.Add(effectKey, cloneSource);
}
}
// Clone it.
_isClone = true;
Clone(cloneSource);
}
private MGFXHeader ReadHeader(byte[] effectCode, int index)
{
MGFXHeader header;
header.Signature = BitConverter.ToInt32(effectCode, index); index += 4;
header.Version = (int)effectCode[index++];
header.Profile = (int)effectCode[index++];
header.EffectKey = BitConverter.ToInt32(effectCode, index); index += 4;
header.HeaderSize = index;
if (header.Signature != MGFXHeader.MGFXSignature)
throw new Exception("This does not appear to be a MonoGame MGFX file!");
if (header.Version < MGFXHeader.MGFXVersion)
throw new Exception("This MGFX effect is for an older release of MonoGame and needs to be rebuilt.");
if (header.Version > MGFXHeader.MGFXVersion)
throw new Exception("This MGFX effect seems to be for a newer release of MonoGame.");
if (header.Profile != Shader.Profile)
throw new Exception("This MGFX effect was built for a different platform!");
return header;
}
/// <summary>
/// Clone the source into this existing object.
/// </summary>
/// <remarks>
/// Note this is not overloaded in derived classes on purpose. This is
/// only a reason this exists is for caching effects.
/// </remarks>
/// <param name="cloneSource">The source effect to clone from.</param>
private void Clone(Effect cloneSource)
{
Debug.Assert(_isClone, "Cannot clone into non-cloned effect!");
// Copy the mutable members of the effect.
Parameters = cloneSource.Parameters.Clone();
Techniques = cloneSource.Techniques.Clone(this);
// Make a copy of the immutable constant buffers.
ConstantBuffers = new ConstantBuffer[cloneSource.ConstantBuffers.Length];
for (var i = 0; i < cloneSource.ConstantBuffers.Length; i++)
ConstantBuffers[i] = new ConstantBuffer(cloneSource.ConstantBuffers[i]);
// Find and set the current technique.
for (var i = 0; i < cloneSource.Techniques.Count; i++)
{
if (cloneSource.Techniques[i] == cloneSource.CurrentTechnique)
{
CurrentTechnique = Techniques[i];
break;
}
}
// Take a reference to the original shader list.
_shaders = cloneSource._shaders;
}
/// <summary>
/// Returns a deep copy of the effect where immutable types
/// are shared and mutable data is duplicated.
/// </summary>
/// <remarks>
/// See "Cloning an Effect" in MSDN:
/// http://msdn.microsoft.com/en-us/library/windows/desktop/ff476138(v=vs.85).aspx
/// </remarks>
/// <returns>The cloned effect.</returns>
public virtual Effect Clone()
{
return new Effect(this);
}
protected internal virtual void OnApply()
{
}
protected override void Dispose(bool disposing)
{
if (!IsDisposed)
{
if (disposing)
{
if (!_isClone)
{
// Only the clone source can dispose the shaders.
if (_shaders != null)
{
foreach (var shader in _shaders)
shader.Dispose();
}
}
if (ConstantBuffers != null)
{
foreach (var buffer in ConstantBuffers)
buffer.Dispose();
ConstantBuffers = null;
}
}
}
base.Dispose(disposing);
}
internal protected override void GraphicsDeviceResetting()
{
for (var i = 0; i < ConstantBuffers.Length; i++)
ConstantBuffers[i].Clear();
}
#region Effect File Reader
private void ReadEffect (BinaryReader reader)
{
// TODO: Maybe we should be reading in a string
// table here to save some bytes in the file.
// Read in all the constant buffers.
var buffers = (int)reader.ReadByte ();
ConstantBuffers = new ConstantBuffer[buffers];
for (var c = 0; c < buffers; c++)
{
var name = reader.ReadString ();
// Create the backing system memory buffer.
var sizeInBytes = (int)reader.ReadInt16 ();
// Read the parameter index values.
var parameters = new int[reader.ReadByte ()];
var offsets = new int[parameters.Length];
for (var i = 0; i < parameters.Length; i++)
{
parameters [i] = (int)reader.ReadByte ();
offsets [i] = (int)reader.ReadUInt16 ();
}
var buffer = new ConstantBuffer(GraphicsDevice,
sizeInBytes,
parameters,
offsets,
name);
ConstantBuffers[c] = buffer;
}
// Read in all the shader objects.
var shaders = (int)reader.ReadByte();
_shaders = new Shader[shaders];
for (var s = 0; s < shaders; s++)
_shaders[s] = new Shader(GraphicsDevice, reader);
// Read in the parameters.
Parameters = ReadParameters(reader);
// Read the techniques.
var techniqueCount = (int)reader.ReadByte();
var techniques = new EffectTechnique[techniqueCount];
for (var t = 0; t < techniqueCount; t++)
{
var name = reader.ReadString();
var annotations = ReadAnnotations(reader);
var passes = ReadPasses(reader, this, _shaders);
techniques[t] = new EffectTechnique(this, name, passes, annotations);
}
Techniques = new EffectTechniqueCollection(techniques);
CurrentTechnique = Techniques[0];
}
private static EffectAnnotationCollection ReadAnnotations(BinaryReader reader)
{
var count = (int)reader.ReadByte();
if (count == 0)
return EffectAnnotationCollection.Empty;
var annotations = new EffectAnnotation[count];
// TODO: Annotations are not implemented!
return new EffectAnnotationCollection(annotations);
}
private static EffectPassCollection ReadPasses(BinaryReader reader, Effect effect, Shader[] shaders)
{
var count = (int)reader.ReadByte();
var passes = new EffectPass[count];
for (var i = 0; i < count; i++)
{
var name = reader.ReadString();
var annotations = ReadAnnotations(reader);
// Get the vertex shader.
Shader vertexShader = null;
var shaderIndex = (int)reader.ReadByte();
if (shaderIndex != 255)
vertexShader = shaders[shaderIndex];
// Get the pixel shader.
Shader pixelShader = null;
shaderIndex = (int)reader.ReadByte();
if (shaderIndex != 255)
pixelShader = shaders[shaderIndex];
BlendState blend = null;
DepthStencilState depth = null;
RasterizerState raster = null;
if (reader.ReadBoolean())
{
blend = new BlendState
{
AlphaBlendFunction = (BlendFunction)reader.ReadByte(),
AlphaDestinationBlend = (Blend)reader.ReadByte(),
AlphaSourceBlend = (Blend)reader.ReadByte(),
BlendFactor = new Color(reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte()),
ColorBlendFunction = (BlendFunction)reader.ReadByte(),
ColorDestinationBlend = (Blend)reader.ReadByte(),
ColorSourceBlend = (Blend)reader.ReadByte(),
ColorWriteChannels = (ColorWriteChannels)reader.ReadByte(),
ColorWriteChannels1 = (ColorWriteChannels)reader.ReadByte(),
ColorWriteChannels2 = (ColorWriteChannels)reader.ReadByte(),
ColorWriteChannels3 = (ColorWriteChannels)reader.ReadByte(),
MultiSampleMask = reader.ReadInt32(),
};
}
if (reader.ReadBoolean())
{
depth = new DepthStencilState
{
CounterClockwiseStencilDepthBufferFail = (StencilOperation)reader.ReadByte(),
CounterClockwiseStencilFail = (StencilOperation)reader.ReadByte(),
CounterClockwiseStencilFunction = (CompareFunction)reader.ReadByte(),
CounterClockwiseStencilPass = (StencilOperation)reader.ReadByte(),
DepthBufferEnable = reader.ReadBoolean(),
DepthBufferFunction = (CompareFunction)reader.ReadByte(),
DepthBufferWriteEnable = reader.ReadBoolean(),
ReferenceStencil = reader.ReadInt32(),
StencilDepthBufferFail = (StencilOperation)reader.ReadByte(),
StencilEnable = reader.ReadBoolean(),
StencilFail = (StencilOperation)reader.ReadByte(),
StencilFunction = (CompareFunction)reader.ReadByte(),
StencilMask = reader.ReadInt32(),
StencilPass = (StencilOperation)reader.ReadByte(),
StencilWriteMask = reader.ReadInt32(),
TwoSidedStencilMode = reader.ReadBoolean(),
};
}
if (reader.ReadBoolean())
{
raster = new RasterizerState
{
CullMode = (CullMode)reader.ReadByte(),
DepthBias = reader.ReadSingle(),
FillMode = (FillMode)reader.ReadByte(),
MultiSampleAntiAlias = reader.ReadBoolean(),
ScissorTestEnable = reader.ReadBoolean(),
SlopeScaleDepthBias = reader.ReadSingle(),
};
}
passes[i] = new EffectPass(effect, name, vertexShader, pixelShader, blend, depth, raster, annotations);
}
return new EffectPassCollection(passes);
}
private static EffectParameterCollection ReadParameters(BinaryReader reader)
{
var count = (int)reader.ReadByte();
if (count == 0)
return EffectParameterCollection.Empty;
var parameters = new EffectParameter[count];
for (var i = 0; i < count; i++)
{
var class_ = (EffectParameterClass)reader.ReadByte();
var type = (EffectParameterType)reader.ReadByte();
var name = reader.ReadString();
var semantic = reader.ReadString();
var annotations = ReadAnnotations(reader);
var rowCount = (int)reader.ReadByte();
var columnCount = (int)reader.ReadByte();
var elements = ReadParameters(reader);
var structMembers = ReadParameters(reader);
object data = null;
if (elements.Count == 0 && structMembers.Count == 0)
{
switch (type)
{
case EffectParameterType.Bool:
case EffectParameterType.Int32:
#if !OPENGL
// Under most platforms we properly store integers and
// booleans in an integer type.
//
// MojoShader on the otherhand stores everything in float
// types which is why this code is disabled under OpenGL.
{
var buffer = new int[rowCount * columnCount];
for (var j = 0; j < buffer.Length; j++)
buffer[j] = reader.ReadInt32();
data = buffer;
break;
}
#endif
case EffectParameterType.Single:
{
var buffer = new float[rowCount * columnCount];
for (var j = 0; j < buffer.Length; j++)
buffer[j] = reader.ReadSingle();
data = buffer;
break;
}
case EffectParameterType.String:
// TODO: We have not investigated what a string
// type should do in the parameter list. Till then
// throw to let the user know.
throw new NotSupportedException();
default:
// NOTE: We skip over all other types as they
// don't get added to the constant buffer.
break;
}
}
parameters[i] = new EffectParameter(
class_, type, name, rowCount, columnCount, semantic,
annotations, elements, structMembers, data);
}
return new EffectParameterCollection(parameters);
}
#endregion // Effect File Reader
}
}
@@ -0,0 +1,44 @@
using System;
namespace Microsoft.Xna.Framework.Graphics
{
// TODO: This class needs to be finished!
public class EffectAnnotation
{
internal EffectAnnotation (
EffectParameterClass class_,
EffectParameterType type,
string name,
int rowCount,
int columnCount,
string semantic,
object data)
{
ParameterClass = class_;
ParameterType = type;
Name = name;
RowCount = rowCount;
ColumnCount = columnCount;
Semantic = semantic;
}
internal EffectAnnotation (EffectParameter parameter)
{
ParameterClass = parameter.ParameterClass;
ParameterType = parameter.ParameterType;
Name = parameter.Name;
RowCount = parameter.RowCount;
ColumnCount = parameter.ColumnCount;
Semantic = parameter.Semantic;
}
public EffectParameterClass ParameterClass {get; private set;}
public EffectParameterType ParameterType {get; private set;}
public string Name {get; private set;}
public int RowCount {get; private set;}
public int ColumnCount {get; private set;}
public string Semantic {get; private set;}
}
}
@@ -0,0 +1,50 @@
using System.Collections.Generic;
namespace Microsoft.Xna.Framework.Graphics
{
public class EffectAnnotationCollection : IEnumerable<EffectAnnotation>
{
internal static readonly EffectAnnotationCollection Empty = new EffectAnnotationCollection(new EffectAnnotation[0]);
private readonly EffectAnnotation[] _annotations;
internal EffectAnnotationCollection(EffectAnnotation[] annotations)
{
_annotations = annotations;
}
public int Count
{
get { return _annotations.Length; }
}
public EffectAnnotation this[int index]
{
get { return _annotations[index]; }
}
public EffectAnnotation this[string name]
{
get
{
foreach (var annotation in _annotations)
{
if (annotation.Name == name)
return annotation;
}
return null;
}
}
public IEnumerator<EffectAnnotation> GetEnumerator()
{
return ((IEnumerable<EffectAnnotation>)_annotations).GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _annotations.GetEnumerator();
}
}
}
@@ -0,0 +1,241 @@
//#region File Description
//-----------------------------------------------------------------------------
// EffectHelpers.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
//#endregion
//#region Using Statements
using System;
//#endregion
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// Track which effect parameters need to be recomputed during the next OnApply.
/// </summary>
[Flags]
internal enum EffectDirtyFlags
{
WorldViewProj = 1,
World = 2,
EyePosition = 4,
MaterialColor = 8,
Fog = 16,
FogEnable = 32,
AlphaTest = 64,
ShaderIndex = 128,
All = -1
}
/// <summary>
/// Helper code shared between the various built-in effects.
/// </summary>
internal static class EffectHelpers
{
/// <summary>
/// Sets up the standard key/fill/back lighting rig.
/// </summary>
internal static Vector3 EnableDefaultLighting(DirectionalLight light0, DirectionalLight light1, DirectionalLight light2)
{
// Key light.
light0.Direction = new Vector3(-0.5265408f, -0.5735765f, -0.6275069f);
light0.DiffuseColor = new Vector3(1, 0.9607844f, 0.8078432f);
light0.SpecularColor = new Vector3(1, 0.9607844f, 0.8078432f);
light0.Enabled = true;
// Fill light.
light1.Direction = new Vector3(0.7198464f, 0.3420201f, 0.6040227f);
light1.DiffuseColor = new Vector3(0.9647059f, 0.7607844f, 0.4078432f);
light1.SpecularColor = Vector3.Zero;
light1.Enabled = true;
// Back light.
light2.Direction = new Vector3(0.4545195f, -0.7660444f, 0.4545195f);
light2.DiffuseColor = new Vector3(0.3231373f, 0.3607844f, 0.3937255f);
light2.SpecularColor = new Vector3(0.3231373f, 0.3607844f, 0.3937255f);
light2.Enabled = true;
// Ambient light.
return new Vector3(0.05333332f, 0.09882354f, 0.1819608f);
}
/// <summary>
/// Lazily recomputes the world+view+projection matrix and
/// fog vector based on the current effect parameter settings.
/// </summary>
internal static EffectDirtyFlags SetWorldViewProjAndFog(EffectDirtyFlags dirtyFlags,
ref Matrix world, ref Matrix view, ref Matrix projection, ref Matrix worldView,
bool fogEnabled, float fogStart, float fogEnd,
EffectParameter worldViewProjParam, EffectParameter fogVectorParam)
{
// Recompute the world+view+projection matrix?
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0)
{
Matrix worldViewProj;
Matrix.Multiply(ref world, ref view, out worldView);
Matrix.Multiply(ref worldView, ref projection, out worldViewProj);
worldViewProjParam.SetValue(worldViewProj);
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
}
if (fogEnabled)
{
// Recompute the fog vector?
if ((dirtyFlags & (EffectDirtyFlags.Fog | EffectDirtyFlags.FogEnable)) != 0)
{
SetFogVector(ref worldView, fogStart, fogEnd, fogVectorParam);
dirtyFlags &= ~(EffectDirtyFlags.Fog | EffectDirtyFlags.FogEnable);
}
}
else
{
// When fog is disabled, make sure the fog vector is reset to zero.
if ((dirtyFlags & EffectDirtyFlags.FogEnable) != 0)
{
fogVectorParam.SetValue(Vector4.Zero);
dirtyFlags &= ~EffectDirtyFlags.FogEnable;
}
}
return dirtyFlags;
}
/// <summary>
/// Sets a vector which can be dotted with the object space vertex position to compute fog amount.
/// </summary>
static void SetFogVector(ref Matrix worldView, float fogStart, float fogEnd, EffectParameter fogVectorParam)
{
if (fogStart == fogEnd)
{
// Degenerate case: force everything to 100% fogged if start and end are the same.
fogVectorParam.SetValue(new Vector4(0, 0, 0, 1));
}
else
{
// We want to transform vertex positions into view space, take the resulting
// Z value, then scale and offset according to the fog start/end distances.
// Because we only care about the Z component, the shader can do all this
// with a single dot product, using only the Z row of the world+view matrix.
float scale = 1f / (fogStart - fogEnd);
Vector4 fogVector = new Vector4();
fogVector.X = worldView.M13 * scale;
fogVector.Y = worldView.M23 * scale;
fogVector.Z = worldView.M33 * scale;
fogVector.W = (worldView.M43 + fogStart) * scale;
fogVectorParam.SetValue(fogVector);
}
}
/// <summary>
/// Lazily recomputes the world inverse transpose matrix and
/// eye position based on the current effect parameter settings.
/// </summary>
internal static EffectDirtyFlags SetLightingMatrices(EffectDirtyFlags dirtyFlags, ref Matrix world, ref Matrix view,
EffectParameter worldParam, EffectParameter worldInverseTransposeParam, EffectParameter eyePositionParam)
{
// Set the world and world inverse transpose matrices.
if ((dirtyFlags & EffectDirtyFlags.World) != 0)
{
Matrix worldTranspose;
Matrix worldInverseTranspose;
Matrix.Invert(ref world, out worldTranspose);
Matrix.Transpose(ref worldTranspose, out worldInverseTranspose);
worldParam.SetValue(world);
worldInverseTransposeParam.SetValue(worldInverseTranspose);
dirtyFlags &= ~EffectDirtyFlags.World;
}
// Set the eye position.
if ((dirtyFlags & EffectDirtyFlags.EyePosition) != 0)
{
Matrix viewInverse;
Matrix.Invert(ref view, out viewInverse);
eyePositionParam.SetValue(viewInverse.Translation);
dirtyFlags &= ~EffectDirtyFlags.EyePosition;
}
return dirtyFlags;
}
/// <summary>
/// Sets the diffuse/emissive/alpha material color parameters.
/// </summary>
internal static void SetMaterialColor(bool lightingEnabled, float alpha,
ref Vector3 diffuseColor, ref Vector3 emissiveColor, ref Vector3 ambientLightColor,
EffectParameter diffuseColorParam, EffectParameter emissiveColorParam)
{
// Desired lighting model:
//
// ((AmbientLightColor + sum(diffuse directional light)) * DiffuseColor) + EmissiveColor
//
// When lighting is disabled, ambient and directional lights are ignored, leaving:
//
// DiffuseColor + EmissiveColor
//
// For the lighting disabled case, we can save one shader instruction by precomputing
// diffuse+emissive on the CPU, after which the shader can use DiffuseColor directly,
// ignoring its emissive parameter.
//
// When lighting is enabled, we can merge the ambient and emissive settings. If we
// set our emissive parameter to emissive+(ambient*diffuse), the shader no longer
// needs to bother adding the ambient contribution, simplifying its computation to:
//
// (sum(diffuse directional light) * DiffuseColor) + EmissiveColor
//
// For futher optimization goodness, we merge material alpha with the diffuse
// color parameter, and premultiply all color values by this alpha.
if (lightingEnabled)
{
Vector4 diffuse = new Vector4();
Vector3 emissive = new Vector3();
diffuse.X = diffuseColor.X * alpha;
diffuse.Y = diffuseColor.Y * alpha;
diffuse.Z = diffuseColor.Z * alpha;
diffuse.W = alpha;
emissive.X = (emissiveColor.X + ambientLightColor.X * diffuseColor.X) * alpha;
emissive.Y = (emissiveColor.Y + ambientLightColor.Y * diffuseColor.Y) * alpha;
emissive.Z = (emissiveColor.Z + ambientLightColor.Z * diffuseColor.Z) * alpha;
diffuseColorParam.SetValue(diffuse);
emissiveColorParam.SetValue(emissive);
}
else
{
Vector4 diffuse = new Vector4();
diffuse.X = (diffuseColor.X + emissiveColor.X) * alpha;
diffuse.Y = (diffuseColor.Y + emissiveColor.Y) * alpha;
diffuse.Z = (diffuseColor.Z + emissiveColor.Z) * alpha;
diffuse.W = alpha;
diffuseColorParam.SetValue(diffuse);
}
}
}
}
@@ -0,0 +1,51 @@
#region License
/*
Microsoft Public License (Ms-PL)
MonoGame - Copyright © 2009 The MonoGame Team
All rights reserved.
This license governs use of the accompanying software. If you use the software, you accept this license. If you do not
accept the license, do not use the software.
1. Definitions
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under
U.S. copyright law.
A "contribution" is the original software, or any additions or changes to the software.
A "contributor" is any person that distributes its contribution under this license.
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
2. Grant of Rights
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
3. Conditions and Limitations
(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
your patent license from such contributor to the software ends automatically.
(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
notices that are present in the software.
(D) If you distribute any portion of the software in source code form, you may do so only under this license by including
a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object
code form, you may only do so under a license that complies with this license.
(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees
or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular
purpose and non-infringement.
*/
#endregion License
using System;
namespace Microsoft.Xna.Framework.Graphics
{
public class EffectMaterial : Effect
{
public EffectMaterial (Effect cloneSource) : base(cloneSource)
{
}
}
}
@@ -0,0 +1,886 @@
using System;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace Microsoft.Xna.Framework.Graphics
{
[DebuggerDisplay("{DebugDisplayString}")]
public class EffectParameter
{
/// <summary>
/// The next state key used when an effect parameter
/// is updated by any of the 'set' methods.
/// </summary>
internal static ulong NextStateKey { get; private set; }
internal EffectParameter( EffectParameterClass class_,
EffectParameterType type,
string name,
int rowCount,
int columnCount,
string semantic,
EffectAnnotationCollection annotations,
EffectParameterCollection elements,
EffectParameterCollection structMembers,
object data )
{
ParameterClass = class_;
ParameterType = type;
Name = name;
Semantic = semantic;
Annotations = annotations;
RowCount = rowCount;
ColumnCount = columnCount;
Elements = elements;
StructureMembers = structMembers;
Data = data;
StateKey = unchecked(NextStateKey++);
}
internal EffectParameter(EffectParameter cloneSource)
{
// Share all the immutable types.
ParameterClass = cloneSource.ParameterClass;
ParameterType = cloneSource.ParameterType;
Name = cloneSource.Name;
Semantic = cloneSource.Semantic;
Annotations = cloneSource.Annotations;
RowCount = cloneSource.RowCount;
ColumnCount = cloneSource.ColumnCount;
// Clone the mutable types.
Elements = cloneSource.Elements.Clone();
StructureMembers = cloneSource.StructureMembers.Clone();
// The data is mutable, so we have to clone it.
var array = cloneSource.Data as Array;
if (array != null)
Data = array.Clone();
StateKey = unchecked(NextStateKey++);
}
public string Name { get; private set; }
public string Semantic { get; private set; }
public EffectParameterClass ParameterClass { get; private set; }
public EffectParameterType ParameterType { get; private set; }
public int RowCount { get; private set; }
public int ColumnCount { get; private set; }
public EffectParameterCollection Elements { get; private set; }
public EffectParameterCollection StructureMembers { get; private set; }
public EffectAnnotationCollection Annotations { get; private set; }
// TODO: Using object adds alot of boxing/unboxing overhead
// and garbage generation. We should consider a templated
// type implementation to fix this!
internal object Data { get; private set; }
/// <summary>
/// The current state key which is used to detect
/// if the parameter value has been changed.
/// </summary>
internal ulong StateKey { get; private set; }
/// <summary>
/// Property referenced by the DebuggerDisplayAttribute.
/// </summary>
private string DebugDisplayString
{
get
{
var semanticStr = string.Empty;
if (!string.IsNullOrEmpty(Semantic))
semanticStr = string.Concat(" <", Semantic, ">");
return string.Concat("[", ParameterClass, " ", ParameterType, "]", semanticStr, " ", Name, " : ", GetDataValueString());
}
}
private string GetDataValueString()
{
string valueStr;
if (Data == null)
{
if (Elements == null)
valueStr = "(null)";
else
valueStr = string.Join(", ", Elements.Select(e => e.GetDataValueString()));
}
else
{
switch (ParameterClass)
{
// Object types are stored directly in the Data property.
// Display Data's string value.
case EffectParameterClass.Object:
valueStr = Data.ToString();
break;
// Matrix types are stored in a float[16] which we don't really have room for.
// Display "...".
case EffectParameterClass.Matrix:
valueStr = "...";
break;
// Scalar types are stored as a float[1].
// Display the first (and only) element's string value.
case EffectParameterClass.Scalar:
valueStr = (Data as Array).GetValue(0).ToString();
break;
// Vector types are stored as an Array<Type>.
// Display the string value of each array element.
case EffectParameterClass.Vector:
var array = Data as Array;
var arrayStr = new string[array.Length];
var idx = 0;
foreach (var e in array)
{
arrayStr[idx] = array.GetValue(idx).ToString();
idx++;
}
valueStr = string.Join(" ", arrayStr);
break;
// Handle additional cases here...
default:
valueStr = Data.ToString();
break;
}
}
return string.Concat("{", valueStr, "}");
}
public bool GetValueBoolean ()
{
if (ParameterClass != EffectParameterClass.Scalar || ParameterType != EffectParameterType.Bool)
throw new InvalidCastException();
#if OPENGL
// MojoShader encodes even booleans into a float.
return ((float[])Data)[0] != 0.0f;
#else
return ((int[])Data)[0] != 0;
#endif
}
/*
public bool[] GetValueBooleanArray ()
{
throw new NotImplementedException();
}
*/
public int GetValueInt32 ()
{
if (ParameterClass != EffectParameterClass.Scalar || ParameterType != EffectParameterType.Int32)
throw new InvalidCastException();
#if OPENGL
// MojoShader encodes integers into a float.
return (int)((float[])Data)[0];
#else
return ((int[])Data)[0];
#endif
}
/*
public int[] GetValueInt32Array ()
{
throw new NotImplementedException();
}
*/
public Matrix GetValueMatrix ()
{
if (ParameterClass != EffectParameterClass.Matrix || ParameterType != EffectParameterType.Single)
throw new InvalidCastException();
if (RowCount != 4 || ColumnCount != 4)
throw new InvalidCastException();
var floatData = (float[])Data;
return new Matrix( floatData[0], floatData[4], floatData[8], floatData[12],
floatData[1], floatData[5], floatData[9], floatData[13],
floatData[2], floatData[6], floatData[10], floatData[14],
floatData[3], floatData[7], floatData[11], floatData[15]);
}
public Matrix[] GetValueMatrixArray (int count)
{
if (ParameterClass != EffectParameterClass.Matrix || ParameterType != EffectParameterType.Single)
throw new InvalidCastException();
var ret = new Matrix[count];
for (var i = 0; i < count; i++)
ret[i] = Elements[i].GetValueMatrix();
return ret;
}
public Quaternion GetValueQuaternion ()
{
if (ParameterClass != EffectParameterClass.Vector || ParameterType != EffectParameterType.Single)
throw new InvalidCastException();
var vecInfo = (float[])Data;
return new Quaternion(vecInfo[0], vecInfo[1], vecInfo[2], vecInfo[3]);
}
/*
public Quaternion[] GetValueQuaternionArray ()
{
throw new NotImplementedException();
}
*/
public Single GetValueSingle ()
{
// TODO: Should this fetch int and bool as a float?
if (ParameterClass != EffectParameterClass.Scalar || ParameterType != EffectParameterType.Single)
throw new InvalidCastException();
return ((float[])Data)[0];
}
public Single[] GetValueSingleArray ()
{
if (Elements != null && Elements.Count > 0)
{
var ret = new Single[RowCount * ColumnCount * Elements.Count];
for (int i=0; i<Elements.Count; i++)
{
var elmArray = Elements[i].GetValueSingleArray();
for (var j = 0; j < elmArray.Length; j++)
ret[RowCount*ColumnCount*i+j] = elmArray[j];
}
return ret;
}
switch(ParameterClass)
{
case EffectParameterClass.Scalar:
return new Single[] { GetValueSingle () };
case EffectParameterClass.Vector:
case EffectParameterClass.Matrix:
if (Data is Matrix)
return Matrix.ToFloatArray((Matrix)Data);
else
return (float[])Data;
default:
throw new NotImplementedException();
}
}
public string GetValueString ()
{
if (ParameterClass != EffectParameterClass.Object || ParameterType != EffectParameterType.String)
throw new InvalidCastException();
return ((string[])Data)[0];
}
public Texture2D GetValueTexture2D ()
{
if (ParameterClass != EffectParameterClass.Object || ParameterType != EffectParameterType.Texture2D)
throw new InvalidCastException();
return (Texture2D)Data;
}
#if !GLES
public Texture3D GetValueTexture3D ()
{
if (ParameterClass != EffectParameterClass.Object || ParameterType != EffectParameterType.Texture3D)
throw new InvalidCastException();
return (Texture3D)Data;
}
#endif
public TextureCube GetValueTextureCube ()
{
if (ParameterClass != EffectParameterClass.Object || ParameterType != EffectParameterType.TextureCube)
throw new InvalidCastException();
return (TextureCube)Data;
}
public Vector2 GetValueVector2 ()
{
if (ParameterClass != EffectParameterClass.Vector || ParameterType != EffectParameterType.Single)
throw new InvalidCastException();
var vecInfo = (float[])Data;
return new Vector2(vecInfo[0],vecInfo[1]);
}
public Vector2[] GetValueVector2Array()
{
if (ParameterClass != EffectParameterClass.Vector || ParameterType != EffectParameterType.Single)
throw new InvalidCastException();
if (Elements != null && Elements.Count > 0)
{
Vector2[] result = new Vector2[Elements.Count];
for (int i = 0; i < Elements.Count; i++)
{
var v = Elements[i].GetValueSingleArray();
result[i] = new Vector2(v[0], v[1]);
}
return result;
}
return null;
}
public Vector3 GetValueVector3 ()
{
if (ParameterClass != EffectParameterClass.Vector || ParameterType != EffectParameterType.Single)
throw new InvalidCastException();
var vecInfo = (float[])Data;
return new Vector3(vecInfo[0],vecInfo[1],vecInfo[2]);
}
public Vector3[] GetValueVector3Array()
{
if (ParameterClass != EffectParameterClass.Vector || ParameterType != EffectParameterType.Single)
throw new InvalidCastException();
if (Elements != null && Elements.Count > 0)
{
Vector3[] result = new Vector3[Elements.Count];
for (int i = 0; i < Elements.Count; i++)
{
var v = Elements[i].GetValueSingleArray();
result[i] = new Vector3(v[0], v[1], v[2]);
}
return result;
}
return null;
}
public Vector4 GetValueVector4 ()
{
if (ParameterClass != EffectParameterClass.Vector || ParameterType != EffectParameterType.Single)
throw new InvalidCastException();
var vecInfo = (float[])Data;
return new Vector4(vecInfo[0],vecInfo[1],vecInfo[2],vecInfo[3]);
}
public Vector4[] GetValueVector4Array()
{
if (ParameterClass != EffectParameterClass.Vector || ParameterType != EffectParameterType.Single)
throw new InvalidCastException();
if (Elements != null && Elements.Count > 0)
{
Vector4[] result = new Vector4[Elements.Count];
for (int i = 0; i < Elements.Count; i++)
{
var v = Elements[i].GetValueSingleArray();
result[i] = new Vector4(v[0], v[1],v[2], v[3]);
}
return result;
}
return null;
}
public void SetValue (bool value)
{
if (ParameterClass != EffectParameterClass.Scalar || ParameterType != EffectParameterType.Bool)
throw new InvalidCastException();
#if OPENGL
// MojoShader encodes even booleans into a float.
((float[])Data)[0] = value ? 1 : 0;
#else
((int[])Data)[0] = value ? 1 : 0;
#endif
StateKey = unchecked(NextStateKey++);
}
/*
public void SetValue (bool[] value)
{
throw new NotImplementedException();
}
*/
public void SetValue (int value)
{
if (ParameterClass != EffectParameterClass.Scalar || ParameterType != EffectParameterType.Int32)
throw new InvalidCastException();
#if OPENGL
// MojoShader encodes integers into a float.
((float[])Data)[0] = value;
#else
((int[])Data)[0] = value;
#endif
StateKey = unchecked(NextStateKey++);
}
/*
public void SetValue (int[] value)
{
throw new NotImplementedException();
}
*/
public void SetValue(Matrix value)
{
if (ParameterClass != EffectParameterClass.Matrix || ParameterType != EffectParameterType.Single)
throw new InvalidCastException();
// HLSL expects matrices to be transposed by default.
// These unrolled loops do the transpose during assignment.
if (RowCount == 4 && ColumnCount == 4)
{
var fData = (float[])Data;
fData[0] = value.M11;
fData[1] = value.M21;
fData[2] = value.M31;
fData[3] = value.M41;
fData[4] = value.M12;
fData[5] = value.M22;
fData[6] = value.M32;
fData[7] = value.M42;
fData[8] = value.M13;
fData[9] = value.M23;
fData[10] = value.M33;
fData[11] = value.M43;
fData[12] = value.M14;
fData[13] = value.M24;
fData[14] = value.M34;
fData[15] = value.M44;
}
else if (RowCount == 4 && ColumnCount == 3)
{
var fData = (float[])Data;
fData[0] = value.M11;
fData[1] = value.M21;
fData[2] = value.M31;
fData[3] = value.M41;
fData[4] = value.M12;
fData[5] = value.M22;
fData[6] = value.M32;
fData[7] = value.M42;
fData[8] = value.M13;
fData[9] = value.M23;
fData[10] = value.M33;
fData[11] = value.M43;
}
else if (RowCount == 3 && ColumnCount == 4)
{
var fData = (float[])Data;
fData[0] = value.M11;
fData[1] = value.M21;
fData[2] = value.M31;
fData[3] = value.M12;
fData[4] = value.M22;
fData[5] = value.M32;
fData[6] = value.M13;
fData[7] = value.M23;
fData[8] = value.M33;
fData[9] = value.M14;
fData[10] = value.M24;
fData[11] = value.M34;
}
else if (RowCount == 3 && ColumnCount == 3)
{
var fData = (float[])Data;
fData[0] = value.M11;
fData[1] = value.M21;
fData[2] = value.M31;
fData[3] = value.M12;
fData[4] = value.M22;
fData[5] = value.M32;
fData[6] = value.M13;
fData[7] = value.M23;
fData[8] = value.M33;
}
else if (RowCount == 3 && ColumnCount == 2)
{
var fData = (float[])Data;
fData[0] = value.M11;
fData[1] = value.M21;
fData[2] = value.M31;
fData[3] = value.M12;
fData[4] = value.M22;
fData[5] = value.M32;
}
StateKey = unchecked(NextStateKey++);
}
public void SetValueTranspose(Matrix value)
{
if (ParameterClass != EffectParameterClass.Matrix || ParameterType != EffectParameterType.Single)
throw new InvalidCastException();
// HLSL expects matrices to be transposed by default, so copying them straight
// from the in-memory version effectively transposes them back to row-major.
if (RowCount == 4 && ColumnCount == 4)
{
var fData = (float[])Data;
fData[0] = value.M11;
fData[1] = value.M12;
fData[2] = value.M13;
fData[3] = value.M14;
fData[4] = value.M21;
fData[5] = value.M22;
fData[6] = value.M23;
fData[7] = value.M24;
fData[8] = value.M31;
fData[9] = value.M32;
fData[10] = value.M33;
fData[11] = value.M34;
fData[12] = value.M41;
fData[13] = value.M42;
fData[14] = value.M43;
fData[15] = value.M44;
}
else if (RowCount == 4 && ColumnCount == 3)
{
var fData = (float[])Data;
fData[0] = value.M11;
fData[1] = value.M12;
fData[2] = value.M13;
fData[3] = value.M21;
fData[4] = value.M22;
fData[5] = value.M23;
fData[6] = value.M31;
fData[7] = value.M32;
fData[8] = value.M33;
fData[9] = value.M41;
fData[10] = value.M42;
fData[11] = value.M43;
}
else if (RowCount == 3 && ColumnCount == 4)
{
var fData = (float[])Data;
fData[0] = value.M11;
fData[1] = value.M12;
fData[2] = value.M13;
fData[3] = value.M14;
fData[4] = value.M21;
fData[5] = value.M22;
fData[6] = value.M23;
fData[7] = value.M24;
fData[8] = value.M31;
fData[9] = value.M32;
fData[10] = value.M33;
fData[11] = value.M34;
}
else if (RowCount == 3 && ColumnCount == 3)
{
var fData = (float[])Data;
fData[0] = value.M11;
fData[1] = value.M12;
fData[2] = value.M13;
fData[3] = value.M21;
fData[4] = value.M22;
fData[5] = value.M23;
fData[6] = value.M31;
fData[7] = value.M32;
fData[8] = value.M33;
}
else if (RowCount == 3 && ColumnCount == 2)
{
var fData = (float[])Data;
fData[0] = value.M11;
fData[1] = value.M12;
fData[2] = value.M13;
fData[3] = value.M21;
fData[4] = value.M22;
fData[5] = value.M23;
}
StateKey = unchecked(NextStateKey++);
}
public void SetValue (Matrix[] value)
{
if (ParameterClass != EffectParameterClass.Matrix || ParameterType != EffectParameterType.Single)
throw new InvalidCastException();
if (RowCount == 4 && ColumnCount == 4)
{
for (var i = 0; i < value.Length; i++)
{
var fData = (float[])Elements[i].Data;
fData[0] = value[i].M11;
fData[1] = value[i].M21;
fData[2] = value[i].M31;
fData[3] = value[i].M41;
fData[4] = value[i].M12;
fData[5] = value[i].M22;
fData[6] = value[i].M32;
fData[7] = value[i].M42;
fData[8] = value[i].M13;
fData[9] = value[i].M23;
fData[10] = value[i].M33;
fData[11] = value[i].M43;
fData[12] = value[i].M14;
fData[13] = value[i].M24;
fData[14] = value[i].M34;
fData[15] = value[i].M44;
}
}
else if (RowCount == 4 && ColumnCount == 3)
{
for (var i = 0; i < value.Length; i++)
{
var fData = (float[])Elements[i].Data;
fData[0] = value[i].M11;
fData[1] = value[i].M21;
fData[2] = value[i].M31;
fData[3] = value[i].M41;
fData[4] = value[i].M12;
fData[5] = value[i].M22;
fData[6] = value[i].M32;
fData[7] = value[i].M42;
fData[8] = value[i].M13;
fData[9] = value[i].M23;
fData[10] = value[i].M33;
fData[11] = value[i].M43;
}
}
else if (RowCount == 3 && ColumnCount == 4)
{
for (var i = 0; i < value.Length; i++)
{
var fData = (float[])Elements[i].Data;
fData[0] = value[i].M11;
fData[1] = value[i].M21;
fData[2] = value[i].M31;
fData[3] = value[i].M12;
fData[4] = value[i].M22;
fData[5] = value[i].M32;
fData[6] = value[i].M13;
fData[7] = value[i].M23;
fData[8] = value[i].M33;
fData[9] = value[i].M14;
fData[10] = value[i].M24;
fData[11] = value[i].M34;
}
}
else if (RowCount == 3 && ColumnCount == 3)
{
for (var i = 0; i < value.Length; i++)
{
var fData = (float[])Elements[i].Data;
fData[0] = value[i].M11;
fData[1] = value[i].M21;
fData[2] = value[i].M31;
fData[3] = value[i].M12;
fData[4] = value[i].M22;
fData[5] = value[i].M32;
fData[6] = value[i].M13;
fData[7] = value[i].M23;
fData[8] = value[i].M33;
}
}
else if (RowCount == 3 && ColumnCount == 2)
{
for (var i = 0; i < value.Length; i++)
{
var fData = (float[])Elements[i].Data;
fData[0] = value[i].M11;
fData[1] = value[i].M21;
fData[2] = value[i].M31;
fData[3] = value[i].M12;
fData[4] = value[i].M22;
fData[5] = value[i].M32;
}
}
StateKey = unchecked(NextStateKey++);
}
public void SetValue (Quaternion value)
{
if (ParameterClass != EffectParameterClass.Vector || ParameterType != EffectParameterType.Single)
throw new InvalidCastException();
var fData = (float[])Data;
fData[0] = value.X;
fData[1] = value.Y;
fData[2] = value.Z;
fData[3] = value.W;
StateKey = unchecked(NextStateKey++);
}
/*
public void SetValue (Quaternion[] value)
{
throw new NotImplementedException();
}
*/
public void SetValue (Single value)
{
if (ParameterType != EffectParameterType.Single)
throw new InvalidCastException();
((float[])Data)[0] = value;
StateKey = unchecked(NextStateKey++);
}
public void SetValue (Single[] value)
{
for (var i=0; i<value.Length; i++)
Elements[i].SetValue (value[i]);
StateKey = unchecked(NextStateKey++);
}
/*
public void SetValue (string value)
{
throw new NotImplementedException();
}
*/
public void SetValue (Texture value)
{
if (this.ParameterType != EffectParameterType.Texture &&
this.ParameterType != EffectParameterType.Texture1D &&
this.ParameterType != EffectParameterType.Texture2D &&
this.ParameterType != EffectParameterType.Texture3D &&
this.ParameterType != EffectParameterType.TextureCube)
{
throw new InvalidCastException();
}
Data = value;
StateKey = unchecked(NextStateKey++);
}
public void SetValue (Vector2 value)
{
if (ParameterClass != EffectParameterClass.Vector || ParameterType != EffectParameterType.Single)
throw new InvalidCastException();
var fData = (float[])Data;
fData[0] = value.X;
fData[1] = value.Y;
StateKey = unchecked(NextStateKey++);
}
public void SetValue (Vector2[] value)
{
for (var i = 0; i < value.Length; i++)
Elements[i].SetValue (value[i]);
StateKey = unchecked(NextStateKey++);
}
public void SetValue (Vector3 value)
{
if (ParameterClass != EffectParameterClass.Vector || ParameterType != EffectParameterType.Single)
throw new InvalidCastException();
var fData = (float[])Data;
fData[0] = value.X;
fData[1] = value.Y;
fData[2] = value.Z;
StateKey = unchecked(NextStateKey++);
}
public void SetValue (Vector3[] value)
{
for (var i = 0; i < value.Length; i++)
Elements[i].SetValue (value[i]);
StateKey = unchecked(NextStateKey++);
}
public void SetValue (Vector4 value)
{
if (ParameterClass != EffectParameterClass.Vector || ParameterType != EffectParameterType.Single)
throw new InvalidCastException();
var fData = (float[])Data;
fData[0] = value.X;
fData[1] = value.Y;
fData[2] = value.Z;
fData[3] = value.W;
StateKey = unchecked(NextStateKey++);
}
public void SetValue (Vector4[] value)
{
for (var i = 0; i < value.Length; i++)
Elements[i].SetValue (value[i]);
StateKey = unchecked(NextStateKey++);
}
}
}
@@ -0,0 +1,34 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// Defines classes for effect parameters and shader constants.
/// </summary>
public enum EffectParameterClass
{
/// <summary>
/// Scalar class type.
/// </summary>
Scalar,
/// <summary>
/// Vector class type.
/// </summary>
Vector,
/// <summary>
/// Matrix class type.
/// </summary>
Matrix,
/// <summary>
/// Class type for textures, shaders or strings.
/// </summary>
Object,
/// <summary>
/// Structure class type.
/// </summary>
Struct
}
}
@@ -0,0 +1,73 @@
using System.Collections.Generic;
namespace Microsoft.Xna.Framework.Graphics
{
public class EffectParameterCollection : IEnumerable<EffectParameter>
{
internal static readonly EffectParameterCollection Empty = new EffectParameterCollection(new EffectParameter[0]);
private readonly EffectParameter[] _parameters;
private readonly Dictionary<string, int> _indexLookup;
internal EffectParameterCollection(EffectParameter[] parameters)
{
_parameters = parameters;
_indexLookup = new Dictionary<string, int>(_parameters.Length);
for (int i = 0; i < _parameters.Length; i++)
{
string name = _parameters[i].Name;
if(!string.IsNullOrWhiteSpace(name))
_indexLookup.Add(name, i);
}
}
private EffectParameterCollection(EffectParameter[] parameters, Dictionary<string, int> indexLookup)
{
_parameters = parameters;
_indexLookup = indexLookup;
}
internal EffectParameterCollection Clone()
{
if (_parameters.Length == 0)
return Empty;
var parameters = new EffectParameter[_parameters.Length];
for (var i = 0; i < _parameters.Length; i++)
parameters[i] = new EffectParameter(_parameters[i]);
return new EffectParameterCollection(parameters, _indexLookup);
}
public int Count
{
get { return _parameters.Length; }
}
public EffectParameter this[int index]
{
get { return _parameters[index]; }
}
public EffectParameter this[string name]
{
get
{
int index;
if (_indexLookup.TryGetValue(name, out index))
return _parameters[index];
return null;
}
}
public IEnumerator<EffectParameter> GetEnumerator()
{
return ((IEnumerable<EffectParameter>)_parameters).GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _parameters.GetEnumerator();
}
}
}
@@ -0,0 +1,53 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// Defines types for effect parameters and shader constants.
/// </summary>
public enum EffectParameterType
{
/// <summary>
/// Pointer to void type.
/// </summary>
Void,
/// <summary>
/// Boolean type. Any non-zero will be <c>true</c>; <c>false</c> otherwise.
/// </summary>
Bool,
/// <summary>
/// 32-bit integer type.
/// </summary>
Int32,
/// <summary>
/// Float type.
/// </summary>
Single,
/// <summary>
/// String type.
/// </summary>
String,
/// <summary>
/// Any texture type.
/// </summary>
Texture,
/// <summary>
/// 1D-texture type.
/// </summary>
Texture1D,
/// <summary>
/// 2D-texture type.
/// </summary>
Texture2D,
/// <summary>
/// 3D-texture type.
/// </summary>
Texture3D,
/// <summary>
/// Cubic texture type.
/// </summary>
TextureCube
}
}
@@ -0,0 +1,133 @@
using System.Diagnostics;
namespace Microsoft.Xna.Framework.Graphics
{
public class EffectPass
{
private readonly Effect _effect;
private readonly Shader _pixelShader;
private readonly Shader _vertexShader;
private readonly BlendState _blendState;
private readonly DepthStencilState _depthStencilState;
private readonly RasterizerState _rasterizerState;
public string Name { get; private set; }
public EffectAnnotationCollection Annotations { get; private set; }
internal EffectPass( Effect effect,
string name,
Shader vertexShader,
Shader pixelShader,
BlendState blendState,
DepthStencilState depthStencilState,
RasterizerState rasterizerState,
EffectAnnotationCollection annotations )
{
Debug.Assert(effect != null, "Got a null effect!");
Debug.Assert(annotations != null, "Got a null annotation collection!");
_effect = effect;
Name = name;
_vertexShader = vertexShader;
_pixelShader = pixelShader;
_blendState = blendState;
_depthStencilState = depthStencilState;
_rasterizerState = rasterizerState;
Annotations = annotations;
}
internal EffectPass(Effect effect, EffectPass cloneSource)
{
Debug.Assert(effect != null, "Got a null effect!");
Debug.Assert(cloneSource != null, "Got a null cloneSource!");
_effect = effect;
// Share all the immutable types.
Name = cloneSource.Name;
_blendState = cloneSource._blendState;
_depthStencilState = cloneSource._depthStencilState;
_rasterizerState = cloneSource._rasterizerState;
Annotations = cloneSource.Annotations;
_vertexShader = cloneSource._vertexShader;
_pixelShader = cloneSource._pixelShader;
}
public void Apply()
{
// Set/get the correct shader handle/cleanups.
var current = _effect.CurrentTechnique;
_effect.OnApply();
if (_effect.CurrentTechnique != current)
{
_effect.CurrentTechnique.Passes[0].Apply();
return;
}
var device = _effect.GraphicsDevice;
if (_vertexShader != null)
{
device.VertexShader = _vertexShader;
// Update the texture parameters.
SetShaderSamplers(_vertexShader, device.VertexTextures, device.VertexSamplerStates);
// Update the constant buffers.
for (var c = 0; c < _vertexShader.CBuffers.Length; c++)
{
var cb = _effect.ConstantBuffers[_vertexShader.CBuffers[c]];
cb.Update(_effect.Parameters);
device.SetConstantBuffer(ShaderStage.Vertex, c, cb);
}
}
if (_pixelShader != null)
{
device.PixelShader = _pixelShader;
// Update the texture parameters.
SetShaderSamplers(_pixelShader, device.Textures, device.SamplerStates);
// Update the constant buffers.
for (var c = 0; c < _pixelShader.CBuffers.Length; c++)
{
var cb = _effect.ConstantBuffers[_pixelShader.CBuffers[c]];
cb.Update(_effect.Parameters);
device.SetConstantBuffer(ShaderStage.Pixel, c, cb);
}
}
// Set the render states if we have some.
if (_rasterizerState != null)
device.RasterizerState = _rasterizerState;
if (_blendState != null)
device.BlendState = _blendState;
if (_depthStencilState != null)
device.DepthStencilState = _depthStencilState;
}
private void SetShaderSamplers(Shader shader, TextureCollection textures, SamplerStateCollection samplerStates)
{
foreach (var sampler in shader.Samplers)
{
var param = _effect.Parameters[sampler.parameter];
var texture = param.Data as Texture;
textures[sampler.textureSlot] = texture;
// If there is a sampler state set it.
if (sampler.state != null)
samplerStates[sampler.samplerSlot] = sampler.state;
}
}
}
}
@@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
namespace Microsoft.Xna.Framework.Graphics
{
public class EffectPassCollection : IEnumerable<EffectPass>
{
private readonly EffectPass[] _passes;
internal EffectPassCollection(EffectPass [] passes)
{
_passes = passes;
}
internal EffectPassCollection Clone(Effect effect)
{
var passes = new EffectPass[_passes.Length];
for (var i = 0; i < _passes.Length; i++)
passes[i] = new EffectPass(effect, _passes[i]);
return new EffectPassCollection(passes);
}
public EffectPass this[int index]
{
get { return _passes[index]; }
}
public EffectPass this[string name]
{
get
{
// TODO: Add a name to pass lookup table.
foreach (var pass in _passes)
{
if (pass.Name == name)
return pass;
}
return null;
}
}
public int Count
{
get { return _passes.Length; }
}
public Enumerator GetEnumerator()
{
return new Enumerator(_passes);
}
IEnumerator<EffectPass> IEnumerable<EffectPass>.GetEnumerator()
{
return ((IEnumerable<EffectPass>)_passes).GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _passes.GetEnumerator();
}
public struct Enumerator : IEnumerator<EffectPass>
{
private readonly EffectPass[] _array;
private int _index;
private EffectPass _current;
internal Enumerator(EffectPass[] array)
{
_array = array;
_index = 0;
_current = null;
}
public bool MoveNext()
{
if (_index < _array.Length)
{
_current = _array[_index];
_index++;
return true;
}
_index = _array.Length + 1;
_current = null;
return false;
}
public EffectPass Current
{
get { return _current; }
}
public void Dispose()
{
}
object System.Collections.IEnumerator.Current
{
get
{
if (_index == _array.Length + 1)
throw new InvalidOperationException();
return Current;
}
}
void System.Collections.IEnumerator.Reset()
{
_index = 0;
_current = null;
}
}
}
}
@@ -0,0 +1,16 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
namespace Microsoft.Xna.Framework.Graphics
{
internal partial class EffectResource
{
const string AlphaTestEffectName = "Microsoft.Xna.Framework.Graphics.Effect.Resources.AlphaTestEffect.dx11.mgfxo";
const string BasicEffectName = "Microsoft.Xna.Framework.Graphics.Effect.Resources.BasicEffect.dx11.mgfxo";
const string DualTextureEffectName = "Microsoft.Xna.Framework.Graphics.Effect.Resources.DualTextureEffect.dx11.mgfxo";
const string EnvironmentMapEffectName = "Microsoft.Xna.Framework.Graphics.Effect.Resources.EnvironmentMapEffect.dx11.mgfxo";
const string SkinnedEffectName = "Microsoft.Xna.Framework.Graphics.Effect.Resources.SkinnedEffect.dx11.mgfxo";
const string SpriteEffectName = "Microsoft.Xna.Framework.Graphics.Effect.Resources.SpriteEffect.dx11.mgfxo";
}
}
@@ -0,0 +1,16 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
namespace Microsoft.Xna.Framework.Graphics
{
internal partial class EffectResource
{
const string AlphaTestEffectName = "Microsoft.Xna.Framework.Graphics.Effect.Resources.AlphaTestEffect.ogl.mgfxo";
const string BasicEffectName = "Microsoft.Xna.Framework.Graphics.Effect.Resources.BasicEffect.ogl.mgfxo";
const string DualTextureEffectName = "Microsoft.Xna.Framework.Graphics.Effect.Resources.DualTextureEffect.ogl.mgfxo";
const string EnvironmentMapEffectName = "Microsoft.Xna.Framework.Graphics.Effect.Resources.EnvironmentMapEffect.ogl.mgfxo";
const string SkinnedEffectName = "Microsoft.Xna.Framework.Graphics.Effect.Resources.SkinnedEffect.ogl.mgfxo";
const string SpriteEffectName = "Microsoft.Xna.Framework.Graphics.Effect.Resources.SpriteEffect.ogl.mgfxo";
}
}
@@ -0,0 +1,57 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System.IO;
using MonoGame.Utilities;
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// Internal helper for accessing the bytecode for stock effects.
/// </summary>
internal partial class EffectResource
{
public static readonly EffectResource AlphaTestEffect = new EffectResource(AlphaTestEffectName);
public static readonly EffectResource BasicEffect = new EffectResource(BasicEffectName);
public static readonly EffectResource DualTextureEffect = new EffectResource(DualTextureEffectName);
public static readonly EffectResource EnvironmentMapEffect = new EffectResource(EnvironmentMapEffectName);
public static readonly EffectResource SkinnedEffect = new EffectResource(SkinnedEffectName);
public static readonly EffectResource SpriteEffect = new EffectResource(SpriteEffectName);
private readonly object _locker = new object();
private readonly string _name;
private volatile byte[] _bytecode;
private EffectResource(string name)
{
_name = name;
}
public byte[] Bytecode
{
get
{
if (_bytecode == null)
{
lock (_locker)
{
if (_bytecode != null)
return _bytecode;
var assembly = ReflectionHelpers.GetAssembly(typeof(EffectResource));
var stream = assembly.GetManifestResourceStream(_name);
using (var ms = new MemoryStream())
{
stream.CopyTo(ms);
_bytecode = ms.ToArray();
}
}
}
return _bytecode;
}
}
}
}
@@ -0,0 +1,32 @@
using System;
namespace Microsoft.Xna.Framework.Graphics
{
public class EffectTechnique
{
public EffectPassCollection Passes { get; private set; }
public EffectAnnotationCollection Annotations { get; private set; }
public string Name { get; private set; }
internal EffectTechnique(Effect effect, EffectTechnique cloneSource)
{
// Share all the immutable types.
Name = cloneSource.Name;
Annotations = cloneSource.Annotations;
// Clone the mutable types.
Passes = cloneSource.Passes.Clone(effect);
}
internal EffectTechnique(Effect effect, string name, EffectPassCollection passes, EffectAnnotationCollection annotations)
{
Name = name;
Passes = passes;
Annotations = annotations;
}
}
}
@@ -0,0 +1,55 @@
using System.Collections.Generic;
namespace Microsoft.Xna.Framework.Graphics
{
public class EffectTechniqueCollection : IEnumerable<EffectTechnique>
{
private readonly EffectTechnique[] _techniques;
public int Count { get { return _techniques.Length; } }
internal EffectTechniqueCollection(EffectTechnique[] techniques)
{
_techniques = techniques;
}
internal EffectTechniqueCollection Clone(Effect effect)
{
var techniques = new EffectTechnique[_techniques.Length];
for (var i = 0; i < _techniques.Length; i++)
techniques[i] = new EffectTechnique(effect, _techniques[i]);
return new EffectTechniqueCollection(techniques);
}
public EffectTechnique this[int index]
{
get { return _techniques [index]; }
}
public EffectTechnique this[string name]
{
get
{
// TODO: Add a name to technique lookup table.
foreach (var technique in _techniques)
{
if (technique.Name == name)
return technique;
}
return null;
}
}
public IEnumerator<EffectTechnique> GetEnumerator()
{
return ((IEnumerable<EffectTechnique>)_techniques).GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _techniques.GetEnumerator();
}
}
}
@@ -0,0 +1,510 @@
#region File Description
//-----------------------------------------------------------------------------
// EnvironmentMapEffect.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endregion
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// Built-in effect that supports environment mapping.
/// </summary>
public class EnvironmentMapEffect : Effect, IEffectMatrices, IEffectLights, IEffectFog
{
#region Effect Parameters
EffectParameter textureParam;
EffectParameter environmentMapParam;
EffectParameter environmentMapAmountParam;
EffectParameter environmentMapSpecularParam;
EffectParameter fresnelFactorParam;
EffectParameter diffuseColorParam;
EffectParameter emissiveColorParam;
EffectParameter eyePositionParam;
EffectParameter fogColorParam;
EffectParameter fogVectorParam;
EffectParameter worldParam;
EffectParameter worldInverseTransposeParam;
EffectParameter worldViewProjParam;
#endregion
#region Fields
bool oneLight;
bool fogEnabled;
bool fresnelEnabled;
bool specularEnabled;
Matrix world = Matrix.Identity;
Matrix view = Matrix.Identity;
Matrix projection = Matrix.Identity;
Matrix worldView;
Vector3 diffuseColor = Vector3.One;
Vector3 emissiveColor = Vector3.Zero;
Vector3 ambientLightColor = Vector3.Zero;
float alpha = 1;
DirectionalLight light0;
DirectionalLight light1;
DirectionalLight light2;
float fogStart = 0;
float fogEnd = 1;
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
#endregion
#region Public Properties
/// <summary>
/// Gets or sets the world matrix.
/// </summary>
public Matrix World
{
get { return world; }
set
{
world = value;
dirtyFlags |= EffectDirtyFlags.World | EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.Fog;
}
}
/// <summary>
/// Gets or sets the view matrix.
/// </summary>
public Matrix View
{
get { return view; }
set
{
view = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.EyePosition | EffectDirtyFlags.Fog;
}
}
/// <summary>
/// Gets or sets the projection matrix.
/// </summary>
public Matrix Projection
{
get { return projection; }
set
{
projection = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
}
}
/// <summary>
/// Gets or sets the material diffuse color (range 0 to 1).
/// </summary>
public Vector3 DiffuseColor
{
get { return diffuseColor; }
set
{
diffuseColor = value;
dirtyFlags |= EffectDirtyFlags.MaterialColor;
}
}
/// <summary>
/// Gets or sets the material emissive color (range 0 to 1).
/// </summary>
public Vector3 EmissiveColor
{
get { return emissiveColor; }
set
{
emissiveColor = value;
dirtyFlags |= EffectDirtyFlags.MaterialColor;
}
}
/// <summary>
/// Gets or sets the material alpha.
/// </summary>
public float Alpha
{
get { return alpha; }
set
{
alpha = value;
dirtyFlags |= EffectDirtyFlags.MaterialColor;
}
}
/// <summary>
/// Gets or sets the ambient light color (range 0 to 1).
/// </summary>
public Vector3 AmbientLightColor
{
get { return ambientLightColor; }
set
{
ambientLightColor = value;
dirtyFlags |= EffectDirtyFlags.MaterialColor;
}
}
/// <summary>
/// Gets the first directional light.
/// </summary>
public DirectionalLight DirectionalLight0 { get { return light0; } }
/// <summary>
/// Gets the second directional light.
/// </summary>
public DirectionalLight DirectionalLight1 { get { return light1; } }
/// <summary>
/// Gets the third directional light.
/// </summary>
public DirectionalLight DirectionalLight2 { get { return light2; } }
/// <summary>
/// Gets or sets the fog enable flag.
/// </summary>
public bool FogEnabled
{
get { return fogEnabled; }
set
{
if (fogEnabled != value)
{
fogEnabled = value;
dirtyFlags |= EffectDirtyFlags.ShaderIndex | EffectDirtyFlags.FogEnable;
}
}
}
/// <summary>
/// Gets or sets the fog start distance.
/// </summary>
public float FogStart
{
get { return fogStart; }
set
{
fogStart = value;
dirtyFlags |= EffectDirtyFlags.Fog;
}
}
/// <summary>
/// Gets or sets the fog end distance.
/// </summary>
public float FogEnd
{
get { return fogEnd; }
set
{
fogEnd = value;
dirtyFlags |= EffectDirtyFlags.Fog;
}
}
/// <summary>
/// Gets or sets the fog color.
/// </summary>
public Vector3 FogColor
{
get { return fogColorParam.GetValueVector3(); }
set { fogColorParam.SetValue(value); }
}
/// <summary>
/// Gets or sets the current texture.
/// </summary>
public Texture2D Texture
{
get { return textureParam.GetValueTexture2D(); }
set { textureParam.SetValue(value); }
}
/// <summary>
/// Gets or sets the current environment map texture.
/// </summary>
public TextureCube EnvironmentMap
{
get { return environmentMapParam.GetValueTextureCube(); }
set { environmentMapParam.SetValue(value); }
}
/// <summary>
/// Gets or sets the amount of the environment map RGB that will be blended over
/// the base texture. Range 0 to 1, default 1. If set to zero, the RGB channels
/// of the environment map will completely ignored (but the environment map alpha
/// may still be visible if EnvironmentMapSpecular is greater than zero).
/// </summary>
public float EnvironmentMapAmount
{
get { return environmentMapAmountParam.GetValueSingle(); }
set { environmentMapAmountParam.SetValue(value); }
}
/// <summary>
/// Gets or sets the amount of the environment map alpha channel that will
/// be added to the base texture. Range 0 to 1, default 0. This can be used
/// to implement cheap specular lighting, by encoding one or more specular
/// highlight patterns into the environment map alpha channel, then setting
/// EnvironmentMapSpecular to the desired specular light color.
/// </summary>
public Vector3 EnvironmentMapSpecular
{
get { return environmentMapSpecularParam.GetValueVector3(); }
set
{
environmentMapSpecularParam.SetValue(value);
bool enabled = (value != Vector3.Zero);
if (specularEnabled != enabled)
{
specularEnabled = enabled;
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
}
}
}
/// <summary>
/// Gets or sets the Fresnel factor used for the environment map blending.
/// Higher values make the environment map only visible around the silhouette
/// edges of the object, while lower values make it visible everywhere.
/// Setting this property to 0 disables Fresnel entirely, making the
/// environment map equally visible regardless of view angle. The default is
/// 1. Fresnel only affects the environment map RGB (the intensity of which is
/// controlled by EnvironmentMapAmount). The alpha contribution (controlled by
/// EnvironmentMapSpecular) is not affected by the Fresnel setting.
/// </summary>
public float FresnelFactor
{
get { return fresnelFactorParam.GetValueSingle(); }
set
{
fresnelFactorParam.SetValue(value);
bool enabled = (value != 0);
if (fresnelEnabled != enabled)
{
fresnelEnabled = enabled;
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
}
}
}
/// <summary>
/// This effect requires lighting, so we explicitly implement
/// IEffectLights.LightingEnabled, and do not allow turning it off.
/// </summary>
bool IEffectLights.LightingEnabled
{
get { return true; }
set { if (!value) throw new NotSupportedException("EnvironmentMapEffect does not support setting LightingEnabled to false."); }
}
#endregion
#region Methods
/// <summary>
/// Creates a new EnvironmentMapEffect with default parameter settings.
/// </summary>
public EnvironmentMapEffect(GraphicsDevice device)
: base(device, EffectResource.EnvironmentMapEffect.Bytecode)
{
CacheEffectParameters(null);
DirectionalLight0.Enabled = true;
EnvironmentMapAmount = 1;
EnvironmentMapSpecular = Vector3.Zero;
FresnelFactor = 1;
}
/// <summary>
/// Creates a new EnvironmentMapEffect by cloning parameter settings from an existing instance.
/// </summary>
protected EnvironmentMapEffect(EnvironmentMapEffect cloneSource)
: base(cloneSource)
{
CacheEffectParameters(cloneSource);
fogEnabled = cloneSource.fogEnabled;
fresnelEnabled = cloneSource.fresnelEnabled;
specularEnabled = cloneSource.specularEnabled;
world = cloneSource.world;
view = cloneSource.view;
projection = cloneSource.projection;
diffuseColor = cloneSource.diffuseColor;
emissiveColor = cloneSource.emissiveColor;
ambientLightColor = cloneSource.ambientLightColor;
alpha = cloneSource.alpha;
fogStart = cloneSource.fogStart;
fogEnd = cloneSource.fogEnd;
}
/// <summary>
/// Creates a clone of the current EnvironmentMapEffect instance.
/// </summary>
public override Effect Clone()
{
return new EnvironmentMapEffect(this);
}
/// <summary>
/// Sets up the standard key/fill/back lighting rig.
/// </summary>
public void EnableDefaultLighting()
{
AmbientLightColor = EffectHelpers.EnableDefaultLighting(light0, light1, light2);
}
/// <summary>
/// Looks up shortcut references to our effect parameters.
/// </summary>
void CacheEffectParameters(EnvironmentMapEffect cloneSource)
{
textureParam = Parameters["Texture"];
environmentMapParam = Parameters["EnvironmentMap"];
environmentMapAmountParam = Parameters["EnvironmentMapAmount"];
environmentMapSpecularParam = Parameters["EnvironmentMapSpecular"];
fresnelFactorParam = Parameters["FresnelFactor"];
diffuseColorParam = Parameters["DiffuseColor"];
emissiveColorParam = Parameters["EmissiveColor"];
eyePositionParam = Parameters["EyePosition"];
fogColorParam = Parameters["FogColor"];
fogVectorParam = Parameters["FogVector"];
worldParam = Parameters["World"];
worldInverseTransposeParam = Parameters["WorldInverseTranspose"];
worldViewProjParam = Parameters["WorldViewProj"];
light0 = new DirectionalLight(Parameters["DirLight0Direction"],
Parameters["DirLight0DiffuseColor"],
null,
(cloneSource != null) ? cloneSource.light0 : null);
light1 = new DirectionalLight(Parameters["DirLight1Direction"],
Parameters["DirLight1DiffuseColor"],
null,
(cloneSource != null) ? cloneSource.light1 : null);
light2 = new DirectionalLight(Parameters["DirLight2Direction"],
Parameters["DirLight2DiffuseColor"],
null,
(cloneSource != null) ? cloneSource.light2 : null);
}
/// <summary>
/// Lazily computes derived parameter values immediately before applying the effect.
/// </summary>
protected internal override void OnApply()
{
// Recompute the world+view+projection matrix or fog vector?
dirtyFlags = EffectHelpers.SetWorldViewProjAndFog(dirtyFlags, ref world, ref view, ref projection, ref worldView, fogEnabled, fogStart, fogEnd, worldViewProjParam, fogVectorParam);
// Recompute the world inverse transpose and eye position?
dirtyFlags = EffectHelpers.SetLightingMatrices(dirtyFlags, ref world, ref view, worldParam, worldInverseTransposeParam, eyePositionParam);
// Recompute the diffuse/emissive/alpha material color parameters?
if ((dirtyFlags & EffectDirtyFlags.MaterialColor) != 0)
{
EffectHelpers.SetMaterialColor(true, alpha, ref diffuseColor, ref emissiveColor, ref ambientLightColor, diffuseColorParam, emissiveColorParam);
dirtyFlags &= ~EffectDirtyFlags.MaterialColor;
}
// Check if we can use the only-bother-with-the-first-light shader optimization.
bool newOneLight = !light1.Enabled && !light2.Enabled;
if (oneLight != newOneLight)
{
oneLight = newOneLight;
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
}
// Recompute the shader index?
if ((dirtyFlags & EffectDirtyFlags.ShaderIndex) != 0)
{
int shaderIndex = 0;
if (!fogEnabled)
shaderIndex += 1;
if (fresnelEnabled)
shaderIndex += 2;
if (specularEnabled)
shaderIndex += 4;
if (oneLight)
shaderIndex += 8;
dirtyFlags &= ~EffectDirtyFlags.ShaderIndex;
CurrentTechnique = Techniques[shaderIndex];
}
}
#endregion
}
}
@@ -0,0 +1,79 @@
// #region License
// /*
// Microsoft Public License (Ms-PL)
// MonoGame - Copyright © 2009 The MonoGame Team
//
// All rights reserved.
//
// This license governs use of the accompanying software. If you use the software, you accept this license. If you do not
// accept the license, do not use the software.
//
// 1. Definitions
// The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under
// U.S. copyright law.
//
// A "contribution" is the original software, or any additions or changes to the software.
// A "contributor" is any person that distributes its contribution under this license.
// "Licensed patents" are a contributor's patent claims that read directly on its contribution.
//
// 2. Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
//
// 3. Conditions and Limitations
// (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
// your patent license from such contributor to the software ends automatically.
// (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source code form, you may do so only under this license by including
// a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object
// code form, you may only do so under a license that complies with this license.
// (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees
// or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
// permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular
// purpose and non-infringement.
// */
// #endregion License
//
using System;
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// The common effect fog rendering parameters.
/// </summary>
public interface IEffectFog
{
/// <summary>
/// The floating point fog color.
/// </summary>
Vector3 FogColor { get; set; }
/// <summary>
/// Used to toggle the rendering of fog.
/// </summary>
bool FogEnabled { get; set; }
/// <summary>
/// The world space distance from the camera at which fogging is fully applied.
/// </summary>
/// <remarks>
/// FogEnd should be greater than FogStart. If FogEnd and FogStart
/// are the same value everything is fully fogged.
/// </remarks>
float FogEnd { get; set; }
/// <summary>
/// The world space distance from the camera at which fogging begins.
/// </summary>
/// <remarks>
/// FogStart should be less than FogEnd. If FogEnd and FogStart are the
/// same value everything is fully fogged.
/// </remarks>
float FogStart { get; set; }
}
}
@@ -0,0 +1,81 @@
// #region License
// /*
// Microsoft Public License (Ms-PL)
// MonoGame - Copyright © 2009 The MonoGame Team
//
// All rights reserved.
//
// This license governs use of the accompanying software. If you use the software, you accept this license. If you do not
// accept the license, do not use the software.
//
// 1. Definitions
// The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under
// U.S. copyright law.
//
// A "contribution" is the original software, or any additions or changes to the software.
// A "contributor" is any person that distributes its contribution under this license.
// "Licensed patents" are a contributor's patent claims that read directly on its contribution.
//
// 2. Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
//
// 3. Conditions and Limitations
// (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
// your patent license from such contributor to the software ends automatically.
// (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source code form, you may do so only under this license by including
// a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object
// code form, you may only do so under a license that complies with this license.
// (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees
// or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
// permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular
// purpose and non-infringement.
// */
// #endregion License
//
using System;
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// The common effect light rendering parameters.
/// </summary>
public interface IEffectLights
{
/// <summary>
/// The floating point ambient light color.
/// </summary>
Vector3 AmbientLightColor { get; set; }
/// <summary>
/// Returns the first directional light.
/// </summary>
DirectionalLight DirectionalLight0 { get; }
/// <summary>
/// Returns the second directional light.
/// </summary>
DirectionalLight DirectionalLight1 { get; }
/// <summary>
/// Returns the third directional light.
/// </summary>
DirectionalLight DirectionalLight2 { get; }
/// <summary>
/// Toggles the rendering of lighting.
/// </summary>
bool LightingEnabled { get; set; }
/// <summary>
/// Initializes the lights to the standard key/fill/back lighting rig.
/// </summary>
void EnableDefaultLighting ();
}
}
@@ -0,0 +1,52 @@
// #region License
// /*
// Microsoft Public License (Ms-PL)
// MonoGame - Copyright © 2009 The MonoGame Team
//
// All rights reserved.
//
// This license governs use of the accompanying software. If you use the software, you accept this license. If you do not
// accept the license, do not use the software.
//
// 1. Definitions
// The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under
// U.S. copyright law.
//
// A "contribution" is the original software, or any additions or changes to the software.
// A "contributor" is any person that distributes its contribution under this license.
// "Licensed patents" are a contributor's patent claims that read directly on its contribution.
//
// 2. Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
//
// 3. Conditions and Limitations
// (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
// your patent license from such contributor to the software ends automatically.
// (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source code form, you may do so only under this license by including
// a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object
// code form, you may only do so under a license that complies with this license.
// (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees
// or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
// permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular
// purpose and non-infringement.
// */
// #endregion License
//
using System;
namespace Microsoft.Xna.Framework.Graphics
{
public interface IEffectMatrices
{
Matrix Projection { get; set; }
Matrix View { get; set; }
Matrix World { get; set; }
}
}
@@ -0,0 +1,151 @@
//-----------------------------------------------------------------------------
// AlphaTestEffect.fx
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include "Macros.fxh"
DECLARE_TEXTURE(Texture, 0);
BEGIN_CONSTANTS
float4 DiffuseColor _vs(c0) _cb(c0);
float4 AlphaTest _ps(c0) _cb(c1);
float3 FogColor _ps(c1) _cb(c2);
float4 FogVector _vs(c5) _cb(c3);
MATRIX_CONSTANTS
float4x4 WorldViewProj _vs(c1) _cb(c0);
END_CONSTANTS
#include "Structures.fxh"
#include "Common.fxh"
// Vertex shader: basic.
VSOutputTx VSAlphaTest(VSInputTx vin)
{
VSOutputTx vout;
CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
SetCommonVSOutputParams;
vout.TexCoord = vin.TexCoord;
return vout;
}
// Vertex shader: no fog.
VSOutputTxNoFog VSAlphaTestNoFog(VSInputTx vin)
{
VSOutputTxNoFog vout;
CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
SetCommonVSOutputParamsNoFog;
vout.TexCoord = vin.TexCoord;
return vout;
}
// Vertex shader: vertex color.
VSOutputTx VSAlphaTestVc(VSInputTxVc vin)
{
VSOutputTx vout;
CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
SetCommonVSOutputParams;
vout.TexCoord = vin.TexCoord;
vout.Diffuse *= vin.Color;
return vout;
}
// Vertex shader: vertex color, no fog.
VSOutputTxNoFog VSAlphaTestVcNoFog(VSInputTxVc vin)
{
VSOutputTxNoFog vout;
CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
SetCommonVSOutputParamsNoFog;
vout.TexCoord = vin.TexCoord;
vout.Diffuse *= vin.Color;
return vout;
}
// Pixel shader: less/greater compare function.
float4 PSAlphaTestLtGt(VSOutputTx pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
clip((color.a < AlphaTest.x) ? AlphaTest.z : AlphaTest.w);
ApplyFog(color, pin.Specular.w);
return color;
}
// Pixel shader: less/greater compare function, no fog.
float4 PSAlphaTestLtGtNoFog(VSOutputTxNoFog pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
clip((color.a < AlphaTest.x) ? AlphaTest.z : AlphaTest.w);
return color;
}
// Pixel shader: equal/notequal compare function.
float4 PSAlphaTestEqNe(VSOutputTx pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
clip((abs(color.a - AlphaTest.x) < AlphaTest.y) ? AlphaTest.z : AlphaTest.w);
ApplyFog(color, pin.Specular.w);
return color;
}
// Pixel shader: equal/notequal compare function, no fog.
float4 PSAlphaTestEqNeNoFog(VSOutputTxNoFog pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
clip((abs(color.a - AlphaTest.x) < AlphaTest.y) ? AlphaTest.z : AlphaTest.w);
return color;
}
// NOTE: The order of the techniques here are
// defined to match the indexing in AlphaTestEffect.cs.
TECHNIQUE( AlphaTestEffect_LTGT, VSAlphaTest, PSAlphaTestLtGt );
TECHNIQUE( AlphaTestEffect_LTGT_NoFog, VSAlphaTestNoFog, PSAlphaTestLtGtNoFog );
TECHNIQUE( AlphaTestEffect_LTGT_VertexColor, VSAlphaTestVc, PSAlphaTestLtGt );
TECHNIQUE( AlphaTestEffect_LTGT_VertexColor_NoFog, VSAlphaTestVcNoFog, PSAlphaTestLtGtNoFog );
TECHNIQUE( AlphaTestEffect_EQNE, VSAlphaTest, PSAlphaTestEqNe );
TECHNIQUE( AlphaTestEffect_EQNE_NoFog, VSAlphaTestNoFog, PSAlphaTestEqNeNoFog );
TECHNIQUE( AlphaTestEffect_EQNE_VertexColor, VSAlphaTestVc, PSAlphaTestEqNe );
TECHNIQUE( AlphaTestEffect_EQNE_VertexColor_NoFog, VSAlphaTestVcNoFog, PSAlphaTestEqNeNoFog );
@@ -0,0 +1,490 @@
//-----------------------------------------------------------------------------
// BasicEffect.fx
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include "Macros.fxh"
DECLARE_TEXTURE(Texture, 0);
BEGIN_CONSTANTS
float4 DiffuseColor _vs(c0) _ps(c1) _cb(c0);
float3 EmissiveColor _vs(c1) _ps(c2) _cb(c1);
float3 SpecularColor _vs(c2) _ps(c3) _cb(c2);
float SpecularPower _vs(c3) _ps(c4) _cb(c2.w);
float3 DirLight0Direction _vs(c4) _ps(c5) _cb(c3);
float3 DirLight0DiffuseColor _vs(c5) _ps(c6) _cb(c4);
float3 DirLight0SpecularColor _vs(c6) _ps(c7) _cb(c5);
float3 DirLight1Direction _vs(c7) _ps(c8) _cb(c6);
float3 DirLight1DiffuseColor _vs(c8) _ps(c9) _cb(c7);
float3 DirLight1SpecularColor _vs(c9) _ps(c10) _cb(c8);
float3 DirLight2Direction _vs(c10) _ps(c11) _cb(c9);
float3 DirLight2DiffuseColor _vs(c11) _ps(c12) _cb(c10);
float3 DirLight2SpecularColor _vs(c12) _ps(c13) _cb(c11);
float3 EyePosition _vs(c13) _ps(c14) _cb(c12);
float3 FogColor _ps(c0) _cb(c13);
float4 FogVector _vs(c14) _cb(c14);
float4x4 World _vs(c19) _cb(c15);
float3x3 WorldInverseTranspose _vs(c23) _cb(c19);
MATRIX_CONSTANTS
float4x4 WorldViewProj _vs(c15) _cb(c0);
END_CONSTANTS
#include "Structures.fxh"
#include "Common.fxh"
#include "Lighting.fxh"
// Vertex shader: basic.
VSOutput VSBasic(VSInput vin)
{
VSOutput vout;
CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
SetCommonVSOutputParams;
return vout;
}
// Vertex shader: no fog.
VSOutputNoFog VSBasicNoFog(VSInput vin)
{
VSOutputNoFog vout;
CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
SetCommonVSOutputParamsNoFog;
return vout;
}
// Vertex shader: vertex color.
VSOutput VSBasicVc(VSInputVc vin)
{
VSOutput vout;
CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
SetCommonVSOutputParams;
vout.Diffuse *= vin.Color;
return vout;
}
// Vertex shader: vertex color, no fog.
VSOutputNoFog VSBasicVcNoFog(VSInputVc vin)
{
VSOutputNoFog vout;
CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
SetCommonVSOutputParamsNoFog;
vout.Diffuse *= vin.Color;
return vout;
}
// Vertex shader: texture.
VSOutputTx VSBasicTx(VSInputTx vin)
{
VSOutputTx vout;
CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
SetCommonVSOutputParams;
vout.TexCoord = vin.TexCoord;
return vout;
}
// Vertex shader: texture, no fog.
VSOutputTxNoFog VSBasicTxNoFog(VSInputTx vin)
{
VSOutputTxNoFog vout;
CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
SetCommonVSOutputParamsNoFog;
vout.TexCoord = vin.TexCoord;
return vout;
}
// Vertex shader: texture + vertex color.
VSOutputTx VSBasicTxVc(VSInputTxVc vin)
{
VSOutputTx vout;
CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
SetCommonVSOutputParams;
vout.TexCoord = vin.TexCoord;
vout.Diffuse *= vin.Color;
return vout;
}
// Vertex shader: texture + vertex color, no fog.
VSOutputTxNoFog VSBasicTxVcNoFog(VSInputTxVc vin)
{
VSOutputTxNoFog vout;
CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
SetCommonVSOutputParamsNoFog;
vout.TexCoord = vin.TexCoord;
vout.Diffuse *= vin.Color;
return vout;
}
// Vertex shader: vertex lighting.
VSOutput VSBasicVertexLighting(VSInputNm vin)
{
VSOutput vout;
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 3);
SetCommonVSOutputParams;
return vout;
}
// Vertex shader: vertex lighting + vertex color.
VSOutput VSBasicVertexLightingVc(VSInputNmVc vin)
{
VSOutput vout;
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 3);
SetCommonVSOutputParams;
vout.Diffuse *= vin.Color;
return vout;
}
// Vertex shader: vertex lighting + texture.
VSOutputTx VSBasicVertexLightingTx(VSInputNmTx vin)
{
VSOutputTx vout;
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 3);
SetCommonVSOutputParams;
vout.TexCoord = vin.TexCoord;
return vout;
}
// Vertex shader: vertex lighting + texture + vertex color.
VSOutputTx VSBasicVertexLightingTxVc(VSInputNmTxVc vin)
{
VSOutputTx vout;
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 3);
SetCommonVSOutputParams;
vout.TexCoord = vin.TexCoord;
vout.Diffuse *= vin.Color;
return vout;
}
// Vertex shader: one light.
VSOutput VSBasicOneLight(VSInputNm vin)
{
VSOutput vout;
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 1);
SetCommonVSOutputParams;
return vout;
}
// Vertex shader: one light + vertex color.
VSOutput VSBasicOneLightVc(VSInputNmVc vin)
{
VSOutput vout;
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 1);
SetCommonVSOutputParams;
vout.Diffuse *= vin.Color;
return vout;
}
// Vertex shader: one light + texture.
VSOutputTx VSBasicOneLightTx(VSInputNmTx vin)
{
VSOutputTx vout;
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 1);
SetCommonVSOutputParams;
vout.TexCoord = vin.TexCoord;
return vout;
}
// Vertex shader: one light + texture + vertex color.
VSOutputTx VSBasicOneLightTxVc(VSInputNmTxVc vin)
{
VSOutputTx vout;
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 1);
SetCommonVSOutputParams;
vout.TexCoord = vin.TexCoord;
vout.Diffuse *= vin.Color;
return vout;
}
// Vertex shader: pixel lighting.
VSOutputPixelLighting VSBasicPixelLighting(VSInputNm vin)
{
VSOutputPixelLighting vout;
CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal);
SetCommonVSOutputParamsPixelLighting;
vout.Diffuse = float4(1, 1, 1, DiffuseColor.a);
return vout;
}
// Vertex shader: pixel lighting + vertex color.
VSOutputPixelLighting VSBasicPixelLightingVc(VSInputNmVc vin)
{
VSOutputPixelLighting vout;
CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal);
SetCommonVSOutputParamsPixelLighting;
vout.Diffuse.rgb = vin.Color.rgb;
vout.Diffuse.a = vin.Color.a * DiffuseColor.a;
return vout;
}
// Vertex shader: pixel lighting + texture.
VSOutputPixelLightingTx VSBasicPixelLightingTx(VSInputNmTx vin)
{
VSOutputPixelLightingTx vout;
CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal);
SetCommonVSOutputParamsPixelLighting;
vout.Diffuse = float4(1, 1, 1, DiffuseColor.a);
vout.TexCoord = vin.TexCoord;
return vout;
}
// Vertex shader: pixel lighting + texture + vertex color.
VSOutputPixelLightingTx VSBasicPixelLightingTxVc(VSInputNmTxVc vin)
{
VSOutputPixelLightingTx vout;
CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal);
SetCommonVSOutputParamsPixelLighting;
vout.Diffuse.rgb = vin.Color.rgb;
vout.Diffuse.a = vin.Color.a * DiffuseColor.a;
vout.TexCoord = vin.TexCoord;
return vout;
}
// Pixel shader: basic.
float4 PSBasic(VSOutput pin) : SV_Target0
{
float4 color = pin.Diffuse;
ApplyFog(color, pin.Specular.w);
return color;
}
// Pixel shader: no fog.
float4 PSBasicNoFog(VSOutputNoFog pin) : SV_Target0
{
return pin.Diffuse;
}
// Pixel shader: texture.
float4 PSBasicTx(VSOutputTx pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
ApplyFog(color, pin.Specular.w);
return color;
}
// Pixel shader: texture, no fog.
float4 PSBasicTxNoFog(VSOutputTxNoFog pin) : SV_Target0
{
return SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
}
// Pixel shader: vertex lighting.
float4 PSBasicVertexLighting(VSOutput pin) : SV_Target0
{
float4 color = pin.Diffuse;
AddSpecular(color, pin.Specular.rgb);
ApplyFog(color, pin.Specular.w);
return color;
}
// Pixel shader: vertex lighting, no fog.
float4 PSBasicVertexLightingNoFog(VSOutput pin) : SV_Target0
{
float4 color = pin.Diffuse;
AddSpecular(color, pin.Specular.rgb);
return color;
}
// Pixel shader: vertex lighting + texture.
float4 PSBasicVertexLightingTx(VSOutputTx pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
AddSpecular(color, pin.Specular.rgb);
ApplyFog(color, pin.Specular.w);
return color;
}
// Pixel shader: vertex lighting + texture, no fog.
float4 PSBasicVertexLightingTxNoFog(VSOutputTx pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
AddSpecular(color, pin.Specular.rgb);
return color;
}
// Pixel shader: pixel lighting.
float4 PSBasicPixelLighting(VSOutputPixelLighting pin) : SV_Target0
{
float4 color = pin.Diffuse;
float3 eyeVector = normalize(EyePosition - pin.PositionWS.xyz);
float3 worldNormal = normalize(pin.NormalWS);
ColorPair lightResult = ComputeLights(eyeVector, worldNormal, 3);
color.rgb *= lightResult.Diffuse;
AddSpecular(color, lightResult.Specular);
ApplyFog(color, pin.PositionWS.w);
return color;
}
// Pixel shader: pixel lighting + texture.
float4 PSBasicPixelLightingTx(VSOutputPixelLightingTx pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
float3 eyeVector = normalize(EyePosition - pin.PositionWS.xyz);
float3 worldNormal = normalize(pin.NormalWS);
ColorPair lightResult = ComputeLights(eyeVector, worldNormal, 3);
color.rgb *= lightResult.Diffuse;
AddSpecular(color, lightResult.Specular);
ApplyFog(color, pin.PositionWS.w);
return color;
}
// NOTE: The order of the techniques here are
// defined to match the indexing in BasicEffect.cs.
TECHNIQUE( BasicEffect, VSBasic, PSBasic );
TECHNIQUE( BasicEffect_NoFog, VSBasicNoFog, PSBasicNoFog );
TECHNIQUE( BasicEffect_VertexColor, VSBasicVc, PSBasic );
TECHNIQUE( BasicEffect_VertexColor_NoFog, VSBasicVcNoFog, PSBasicNoFog );
TECHNIQUE( BasicEffect_Texture, VSBasicTx, PSBasicTx );
TECHNIQUE( BasicEffect_Texture_NoFog, VSBasicTxNoFog, PSBasicTxNoFog );
TECHNIQUE( BasicEffect_Texture_VertexColor, VSBasicTxVc, PSBasicTx );
TECHNIQUE( BasicEffect_Texture_VertexColor_NoFog, VSBasicTxVcNoFog, PSBasicTxNoFog );
TECHNIQUE( BasicEffect_VertexLighting, VSBasicVertexLighting, PSBasicVertexLighting );
TECHNIQUE( BasicEffect_VertexLighting_NoFog, VSBasicVertexLighting, PSBasicVertexLightingNoFog );
TECHNIQUE( BasicEffect_VertexLighting_VertexColor, VSBasicVertexLightingVc, PSBasicVertexLighting );
TECHNIQUE( BasicEffect_VertexLighting_VertexColor_NoFog, VSBasicVertexLightingVc, PSBasicVertexLightingNoFog );
TECHNIQUE( BasicEffect_VertexLighting_Texture, VSBasicVertexLightingTx, PSBasicVertexLightingTx );
TECHNIQUE( BasicEffect_VertexLighting_Texture_NoFog, VSBasicVertexLightingTx, PSBasicVertexLightingTxNoFog );
TECHNIQUE( BasicEffect_VertexLighting_Texture_VertexColor, VSBasicVertexLightingTxVc, PSBasicVertexLightingTx );
TECHNIQUE( BasicEffect_VertexLighting_Texture_VertexColor_NoFog, VSBasicVertexLightingTxVc, PSBasicVertexLightingTxNoFog );
TECHNIQUE( BasicEffect_OneLight, VSBasicOneLight, PSBasicVertexLighting );
TECHNIQUE( BasicEffect_OneLight_NoFog, VSBasicOneLight, PSBasicVertexLightingNoFog );
TECHNIQUE( BasicEffect_OneLight_VertexColor, VSBasicOneLightVc, PSBasicVertexLighting );
TECHNIQUE( BasicEffect_OneLight_VertexColor_NoFog, VSBasicOneLightVc, PSBasicVertexLightingNoFog );
TECHNIQUE( BasicEffect_OneLight_Texture, VSBasicOneLightTx, PSBasicVertexLightingTx );
TECHNIQUE( BasicEffect_OneLight_Texture_NoFog, VSBasicOneLightTx, PSBasicVertexLightingTxNoFog );
TECHNIQUE( BasicEffect_OneLight_Texture_VertexColor, VSBasicOneLightTxVc, PSBasicVertexLightingTx );
TECHNIQUE( BasicEffect_OneLight_Texture_VertexColor_NoFog, VSBasicOneLightTxVc, PSBasicVertexLightingTxNoFog );
TECHNIQUE( BasicEffect_PixelLighting, VSBasicPixelLighting, PSBasicPixelLighting );
TECHNIQUE( BasicEffect_PixelLighting_NoFog, VSBasicPixelLighting, PSBasicPixelLighting );
TECHNIQUE( BasicEffect_PixelLighting_VertexColor, VSBasicPixelLightingVc, PSBasicPixelLighting );
TECHNIQUE( BasicEffect_PixelLighting_VertexColor_NoFog, VSBasicPixelLightingVc, PSBasicPixelLighting );
TECHNIQUE( BasicEffect_PixelLighting_Texture, VSBasicPixelLightingTx, PSBasicPixelLightingTx );
TECHNIQUE( BasicEffect_PixelLighting_Texture_NoFog, VSBasicPixelLightingTx, PSBasicPixelLightingTx );
TECHNIQUE( BasicEffect_PixelLighting_Texture_VertexColor, VSBasicPixelLightingTxVc, PSBasicPixelLightingTx );
TECHNIQUE( BasicEffect_PixelLighting_Texture_VertexColor_NoFog, VSBasicPixelLightingTxVc, PSBasicPixelLightingTx );
@@ -0,0 +1,58 @@
//-----------------------------------------------------------------------------
// Common.fxh
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
float ComputeFogFactor(float4 position)
{
return saturate(dot(position, FogVector));
}
void ApplyFog(inout float4 color, float fogFactor)
{
color.rgb = lerp(color.rgb, FogColor * color.a, fogFactor);
}
void AddSpecular(inout float4 color, float3 specular)
{
color.rgb += specular * color.a;
}
struct CommonVSOutput
{
float4 Pos_ps;
float4 Diffuse;
float3 Specular;
float FogFactor;
};
CommonVSOutput ComputeCommonVSOutput(float4 position)
{
CommonVSOutput vout;
vout.Pos_ps = mul(position, WorldViewProj);
vout.Diffuse = DiffuseColor;
vout.Specular = 0;
vout.FogFactor = ComputeFogFactor(position);
return vout;
}
#define SetCommonVSOutputParams \
vout.PositionPS = cout.Pos_ps; \
vout.Diffuse = cout.Diffuse; \
vout.Specular = float4(cout.Specular, cout.FogFactor);
#define SetCommonVSOutputParamsNoFog \
vout.PositionPS = cout.Pos_ps; \
vout.Diffuse = cout.Diffuse;
@@ -0,0 +1,128 @@
//-----------------------------------------------------------------------------
// DualTextureEffect.fx
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include "Macros.fxh"
DECLARE_TEXTURE(Texture, 0);
DECLARE_TEXTURE(Texture2, 1);
BEGIN_CONSTANTS
float4 DiffuseColor _vs(c0) _cb(c0);
float3 FogColor _ps(c0) _cb(c1);
float4 FogVector _vs(c5) _cb(c2);
MATRIX_CONSTANTS
float4x4 WorldViewProj _vs(c1) _cb(c0);
END_CONSTANTS
#include "Structures.fxh"
#include "Common.fxh"
// Vertex shader: basic.
VSOutputTx2 VSDualTexture(VSInputTx2 vin)
{
VSOutputTx2 vout;
CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
SetCommonVSOutputParams;
vout.TexCoord = vin.TexCoord;
vout.TexCoord2 = vin.TexCoord2;
return vout;
}
// Vertex shader: no fog.
VSOutputTx2NoFog VSDualTextureNoFog(VSInputTx2 vin)
{
VSOutputTx2NoFog vout;
CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
SetCommonVSOutputParamsNoFog;
vout.TexCoord = vin.TexCoord;
vout.TexCoord2 = vin.TexCoord2;
return vout;
}
// Vertex shader: vertex color.
VSOutputTx2 VSDualTextureVc(VSInputTx2Vc vin)
{
VSOutputTx2 vout;
CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
SetCommonVSOutputParams;
vout.TexCoord = vin.TexCoord;
vout.TexCoord2 = vin.TexCoord2;
vout.Diffuse *= vin.Color;
return vout;
}
// Vertex shader: vertex color, no fog.
VSOutputTx2NoFog VSDualTextureVcNoFog(VSInputTx2Vc vin)
{
VSOutputTx2NoFog vout;
CommonVSOutput cout = ComputeCommonVSOutput(vin.Position);
SetCommonVSOutputParamsNoFog;
vout.TexCoord = vin.TexCoord;
vout.TexCoord2 = vin.TexCoord2;
vout.Diffuse *= vin.Color;
return vout;
}
// Pixel shader: basic.
float4 PSDualTexture(VSOutputTx2 pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord);
float4 overlay = SAMPLE_TEXTURE(Texture2, pin.TexCoord2);
color.rgb *= 2;
color *= overlay * pin.Diffuse;
ApplyFog(color, pin.Specular.w);
return color;
}
// Pixel shader: no fog.
float4 PSDualTextureNoFog(VSOutputTx2NoFog pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord);
float4 overlay = SAMPLE_TEXTURE(Texture2, pin.TexCoord2);
color.rgb *= 2;
color *= overlay * pin.Diffuse;
return color;
}
// NOTE: The order of the techniques here are
// defined to match the indexing in DualTextureEffect.cs.
TECHNIQUE( DualTextureEffect, VSDualTexture, PSDualTexture );
TECHNIQUE( DualTextureEffect_NoFog, VSDualTextureNoFog, PSDualTextureNoFog );
TECHNIQUE( DualTextureEffect_VertexColor, VSDualTextureVc, PSDualTexture );
TECHNIQUE( DualTextureEffect_VertexColor_NoFog, VSDualTextureVcNoFog, PSDualTextureNoFog );
@@ -0,0 +1,196 @@
//-----------------------------------------------------------------------------
// EnvironmentMapEffect.fx
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include "Macros.fxh"
DECLARE_TEXTURE(Texture, 0);
DECLARE_CUBEMAP(EnvironmentMap, 1);
BEGIN_CONSTANTS
float3 EnvironmentMapSpecular _ps(c0) _cb(c0);
float FresnelFactor _vs(c0) _cb(c0.w);
float EnvironmentMapAmount _vs(c1) _cb(c2.w);
float4 DiffuseColor _vs(c2) _cb(c1);
float3 EmissiveColor _vs(c3) _cb(c2);
float3 DirLight0Direction _vs(c4) _cb(c3);
float3 DirLight0DiffuseColor _vs(c5) _cb(c4);
float3 DirLight1Direction _vs(c6) _cb(c5);
float3 DirLight1DiffuseColor _vs(c7) _cb(c6);
float3 DirLight2Direction _vs(c8) _cb(c7);
float3 DirLight2DiffuseColor _vs(c9) _cb(c8);
float3 EyePosition _vs(c10) _cb(c9);
float3 FogColor _ps(c1) _cb(c10);
float4 FogVector _vs(c11) _cb(c11);
float4x4 World _vs(c16) _cb(c12);
float3x3 WorldInverseTranspose _vs(c19) _cb(c16);
MATRIX_CONSTANTS
float4x4 WorldViewProj _vs(c12) _cb(c0);
END_CONSTANTS
// We don't use these parameters, but Lighting.fxh won't compile without them.
#define SpecularPower 0
#define SpecularColor float3(0, 0, 0)
#define DirLight0SpecularColor float3(0, 0, 0)
#define DirLight1SpecularColor float3(0, 0, 0)
#define DirLight2SpecularColor float3(0, 0, 0)
#include "Structures.fxh"
#include "Common.fxh"
#include "Lighting.fxh"
float ComputeFresnelFactor(float3 eyeVector, float3 worldNormal)
{
float viewAngle = dot(eyeVector, worldNormal);
return pow(max(1 - abs(viewAngle), 0), FresnelFactor) * EnvironmentMapAmount;
}
VSOutputTxEnvMap ComputeEnvMapVSOutput(VSInputNmTx vin, uniform bool useFresnel, uniform int numLights)
{
VSOutputTxEnvMap vout;
float4 pos_ws = mul(vin.Position, World);
float3 eyeVector = normalize(EyePosition - pos_ws.xyz);
float3 worldNormal = normalize(mul(vin.Normal, WorldInverseTranspose));
ColorPair lightResult = ComputeLights(eyeVector, worldNormal, numLights);
vout.PositionPS = mul(vin.Position, WorldViewProj);
vout.Diffuse = float4(lightResult.Diffuse, DiffuseColor.a);
if (useFresnel)
vout.Specular.rgb = ComputeFresnelFactor(eyeVector, worldNormal);
else
vout.Specular.rgb = EnvironmentMapAmount;
vout.Specular.a = ComputeFogFactor(vin.Position);
vout.TexCoord = vin.TexCoord;
vout.EnvCoord = reflect(-eyeVector, worldNormal);
return vout;
}
// Vertex shader: basic.
VSOutputTxEnvMap VSEnvMap(VSInputNmTx vin)
{
return ComputeEnvMapVSOutput(vin, false, 3);
}
// Vertex shader: fresnel.
VSOutputTxEnvMap VSEnvMapFresnel(VSInputNmTx vin)
{
return ComputeEnvMapVSOutput(vin, true, 3);
}
// Vertex shader: one light.
VSOutputTxEnvMap VSEnvMapOneLight(VSInputNmTx vin)
{
return ComputeEnvMapVSOutput(vin, false, 1);
}
// Vertex shader: one light, fresnel.
VSOutputTxEnvMap VSEnvMapOneLightFresnel(VSInputNmTx vin)
{
return ComputeEnvMapVSOutput(vin, true, 1);
}
// Pixel shader: basic.
float4 PSEnvMap(VSOutputTxEnvMap pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
float4 envmap = SAMPLE_CUBEMAP(EnvironmentMap, pin.EnvCoord) * color.a;
color.rgb = lerp(color.rgb, envmap.rgb, pin.Specular.rgb);
ApplyFog(color, pin.Specular.w);
return color;
}
// Pixel shader: no fog.
float4 PSEnvMapNoFog(VSOutputTxEnvMap pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
float4 envmap = SAMPLE_CUBEMAP(EnvironmentMap, pin.EnvCoord) * color.a;
color.rgb = lerp(color.rgb, envmap.rgb, pin.Specular.rgb);
return color;
}
// Pixel shader: specular.
float4 PSEnvMapSpecular(VSOutputTxEnvMap pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
float4 envmap = SAMPLE_CUBEMAP(EnvironmentMap, pin.EnvCoord) * color.a;
color.rgb = lerp(color.rgb, envmap.rgb, pin.Specular.rgb);
color.rgb += EnvironmentMapSpecular * envmap.a;
ApplyFog(color, pin.Specular.w);
return color;
}
// Pixel shader: specular, no fog.
float4 PSEnvMapSpecularNoFog(VSOutputTxEnvMap pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
float4 envmap = SAMPLE_CUBEMAP(EnvironmentMap, pin.EnvCoord) * color.a;
color.rgb = lerp(color.rgb, envmap.rgb, pin.Specular.rgb);
color.rgb += EnvironmentMapSpecular * envmap.a;
return color;
}
// NOTE: The order of the techniques here are
// defined to match the indexing in EnvironmentMapEffect.cs.
TECHNIQUE( EnvironmentMapEffect, VSEnvMap, PSEnvMap );
TECHNIQUE( EnvironmentMapEffect_NoFog, VSEnvMap, PSEnvMapNoFog );
TECHNIQUE( EnvironmentMapEffect_Fresnel, VSEnvMapFresnel, PSEnvMap );
TECHNIQUE( EnvironmentMapEffect_Fresnel_NoFog, VSEnvMapFresnel, PSEnvMapNoFog );
TECHNIQUE( EnvironmentMapEffect_Specular, VSEnvMap, PSEnvMapSpecular );
TECHNIQUE( EnvironmentMapEffect_Specular_NoFog, VSEnvMap, PSEnvMapSpecularNoFog );
TECHNIQUE( EnvironmentMapEffect_Fresnel_Specular, VSEnvMapFresnel, PSEnvMapSpecular );
TECHNIQUE( EnvironmentMapEffect_Fresnel_Specular_NoFog, VSEnvMapFresnel, PSEnvMapSpecularNoFog );
TECHNIQUE( EnvironmentMapEffect_OneLight, VSEnvMapOneLight, PSEnvMap );
TECHNIQUE( EnvironmentMapEffect_OneLight_NoFog, VSEnvMapOneLight, PSEnvMapNoFog );
TECHNIQUE( EnvironmentMapEffect_OneLight_Fresnel, VSEnvMapOneLightFresnel, PSEnvMap );
TECHNIQUE( EnvironmentMapEffect_OneLight_Fresnel_NoFog, VSEnvMapOneLightFresnel, PSEnvMapNoFog );
TECHNIQUE( EnvironmentMapEffect_OneLight_Specular, VSEnvMapOneLight, PSEnvMapSpecular );
TECHNIQUE( EnvironmentMapEffect_OneLight_Specular_NoFog, VSEnvMapOneLight, PSEnvMapSpecularNoFog );
TECHNIQUE( EnvironmentMapEffect_OneLight_Fresnel_Specular, VSEnvMapOneLightFresnel, PSEnvMapSpecular );
TECHNIQUE( EnvironmentMapEffect_OneLight_Fresnel_Specular_NoFog, VSEnvMapOneLightFresnel, PSEnvMapSpecularNoFog );
@@ -0,0 +1,94 @@
//-----------------------------------------------------------------------------
// Lighting.fxh
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
struct ColorPair
{
float3 Diffuse;
float3 Specular;
};
ColorPair ComputeLights(float3 eyeVector, float3 worldNormal, uniform int numLights)
{
float3x3 lightDirections = 0;
float3x3 lightDiffuse = 0;
float3x3 lightSpecular = 0;
float3x3 halfVectors = 0;
[unroll]
for (int i = 0; i < numLights; i++)
{
lightDirections[i] = float3x3(DirLight0Direction, DirLight1Direction, DirLight2Direction) [i];
lightDiffuse[i] = float3x3(DirLight0DiffuseColor, DirLight1DiffuseColor, DirLight2DiffuseColor) [i];
lightSpecular[i] = float3x3(DirLight0SpecularColor, DirLight1SpecularColor, DirLight2SpecularColor)[i];
halfVectors[i] = normalize(eyeVector - lightDirections[i]);
}
float3 dotL = mul(-lightDirections, worldNormal);
float3 dotH = mul(halfVectors, worldNormal);
float3 zeroL = step(float3(0,0,0), dotL);
float3 diffuse = zeroL * dotL;
float3 specular = pow(max(dotH, 0) * zeroL, SpecularPower);
ColorPair result;
result.Diffuse = mul(diffuse, lightDiffuse) * DiffuseColor.rgb + EmissiveColor;
result.Specular = mul(specular, lightSpecular) * SpecularColor;
return result;
}
CommonVSOutput ComputeCommonVSOutputWithLighting(float4 position, float3 normal, uniform int numLights)
{
CommonVSOutput vout;
float4 pos_ws = mul(position, World);
float3 eyeVector = normalize(EyePosition - pos_ws.xyz);
float3 worldNormal = normalize(mul(normal, WorldInverseTranspose));
ColorPair lightResult = ComputeLights(eyeVector, worldNormal, numLights);
vout.Pos_ps = mul(position, WorldViewProj);
vout.Diffuse = float4(lightResult.Diffuse, DiffuseColor.a);
vout.Specular = lightResult.Specular;
vout.FogFactor = ComputeFogFactor(position);
return vout;
}
struct CommonVSOutputPixelLighting
{
float4 Pos_ps;
float3 Pos_ws;
float3 Normal_ws;
float FogFactor;
};
CommonVSOutputPixelLighting ComputeCommonVSOutputPixelLighting(float4 position, float3 normal)
{
CommonVSOutputPixelLighting vout;
vout.Pos_ps = mul(position, WorldViewProj);
vout.Pos_ws = mul(position, World).xyz;
vout.Normal_ws = normalize(mul(normal, WorldInverseTranspose));
vout.FogFactor = ComputeFogFactor(position);
return vout;
}
#define SetCommonVSOutputParamsPixelLighting \
vout.PositionPS = cout.Pos_ps; \
vout.PositionWS = float4(cout.Pos_ws, cout.FogFactor); \
vout.NormalWS = cout.Normal_ws;
@@ -0,0 +1,61 @@
//-----------------------------------------------------------------------------
// Macros.fxh
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#ifdef SM4
// Macros for targetting shader model 4.0 (DX11)
#define TECHNIQUE(name, vsname, psname ) \
technique name { pass { VertexShader = compile vs_4_0_level_9_1 vsname (); PixelShader = compile ps_4_0_level_9_1 psname(); } }
#define BEGIN_CONSTANTS cbuffer Parameters : register(b0) {
#define MATRIX_CONSTANTS
#define END_CONSTANTS };
#define _vs(r)
#define _ps(r)
#define _cb(r)
#define DECLARE_TEXTURE(Name, index) \
Texture2D<float4> Name : register(t##index); \
sampler Name##Sampler : register(s##index)
#define DECLARE_CUBEMAP(Name, index) \
TextureCube<float4> Name : register(t##index); \
sampler Name##Sampler : register(s##index)
#define SAMPLE_TEXTURE(Name, texCoord) Name.Sample(Name##Sampler, texCoord)
#define SAMPLE_CUBEMAP(Name, texCoord) Name.Sample(Name##Sampler, texCoord)
#else
// Macros for targetting shader model 2.0 (DX9)
#define TECHNIQUE(name, vsname, psname ) \
technique name { pass { VertexShader = compile vs_2_0 vsname (); PixelShader = compile ps_2_0 psname(); } }
#define BEGIN_CONSTANTS
#define MATRIX_CONSTANTS
#define END_CONSTANTS
#define _vs(r) : register(vs, r)
#define _ps(r) : register(ps, r)
#define _cb(r)
#define DECLARE_TEXTURE(Name, index) \
sampler2D Name : register(s##index);
#define DECLARE_CUBEMAP(Name, index) \
samplerCUBE Name : register(s##index);
#define SAMPLE_TEXTURE(Name, texCoord) tex2D(Name, texCoord)
#define SAMPLE_CUBEMAP(Name, texCoord) texCUBE(Name, texCoord)
#endif
@@ -0,0 +1,230 @@
{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff1\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;}
{\f34\fbidi \froman\fcharset1\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\f36\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;}{\f38\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Tahoma;}
{\f40\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Verdana;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;}
{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}
{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f41\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f42\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
{\f44\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f45\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f46\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f47\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
{\f48\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f49\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f51\fbidi \fswiss\fcharset238\fprq2 Arial CE;}{\f52\fbidi \fswiss\fcharset204\fprq2 Arial Cyr;}
{\f54\fbidi \fswiss\fcharset161\fprq2 Arial Greek;}{\f55\fbidi \fswiss\fcharset162\fprq2 Arial Tur;}{\f56\fbidi \fswiss\fcharset177\fprq2 Arial (Hebrew);}{\f57\fbidi \fswiss\fcharset178\fprq2 Arial (Arabic);}
{\f58\fbidi \fswiss\fcharset186\fprq2 Arial Baltic;}{\f59\fbidi \fswiss\fcharset163\fprq2 Arial (Vietnamese);}{\f401\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\f402\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}
{\f404\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\f405\fbidi \froman\fcharset162\fprq2 Cambria Tur;}{\f408\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\f421\fbidi \fswiss\fcharset238\fprq2 Tahoma CE;}
{\f422\fbidi \fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f424\fbidi \fswiss\fcharset161\fprq2 Tahoma Greek;}{\f425\fbidi \fswiss\fcharset162\fprq2 Tahoma Tur;}{\f426\fbidi \fswiss\fcharset177\fprq2 Tahoma (Hebrew);}
{\f427\fbidi \fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f428\fbidi \fswiss\fcharset186\fprq2 Tahoma Baltic;}{\f429\fbidi \fswiss\fcharset163\fprq2 Tahoma (Vietnamese);}{\f430\fbidi \fswiss\fcharset222\fprq2 Tahoma (Thai);}
{\f441\fbidi \fswiss\fcharset238\fprq2 Verdana CE;}{\f442\fbidi \fswiss\fcharset204\fprq2 Verdana Cyr;}{\f444\fbidi \fswiss\fcharset161\fprq2 Verdana Greek;}{\f445\fbidi \fswiss\fcharset162\fprq2 Verdana Tur;}
{\f448\fbidi \fswiss\fcharset186\fprq2 Verdana Baltic;}{\f449\fbidi \fswiss\fcharset163\fprq2 Verdana (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;}
{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}
{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}
{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;
\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;
\red192\green192\blue192;}{\*\defchp }{\*\defpap \ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af1\afs24\alang1025
\ltrch\fcs0 \f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{\s1\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0
\f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink15 \sqformat \spriority9 heading 1;}{\s2\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\outlinelevel1\rin0\lin0\itap0 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0
\f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext0 \slink16 \sqformat \spriority9 heading 2;}{\*\cs10 \additive \ssemihidden Default Paragraph Font;}{\*
\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv
\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused \sqformat Normal Table;}{\*\cs15
\additive \rtlch\fcs1 \ab\af0\afs32 \ltrch\fcs0 \b\f36\fs32\kerning32 \sbasedon10 \slink1 \slocked \spriority9 Heading 1 Char;}{\*\cs16 \additive \rtlch\fcs1 \ab\ai\af0\afs28 \ltrch\fcs0 \b\i\f36\fs28 \sbasedon10 \slink2 \slocked \spriority9
Heading 2 Char;}{\s17\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af38\afs16\alang1025 \ltrch\fcs0 \f38\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033
\sbasedon0 \snext17 \slink18 \ssemihidden \sunhideused \styrsid7424395 Balloon Text;}{\*\cs18 \additive \rtlch\fcs1 \af38\afs16 \ltrch\fcs0 \f38\fs16 \sbasedon10 \slink17 \slocked \ssemihidden \styrsid7424395 Balloon Text Char;}{\*\cs19 \additive
\rtlch\fcs1 \af0\afs16 \ltrch\fcs0 \fs16 \sbasedon10 \ssemihidden \sunhideused \styrsid4538388 annotation reference;}{\s20\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af1\afs20\alang1025 \ltrch\fcs0
\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext20 \slink21 \ssemihidden \sunhideused \styrsid4538388 annotation text;}{\*\cs21 \additive \rtlch\fcs1 \af1 \ltrch\fcs0 \f1
\sbasedon10 \slink20 \slocked \ssemihidden \styrsid4538388 Comment Text Char;}{\s22\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \ab\af1\afs20\alang1025 \ltrch\fcs0 \b\f1\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033
\sbasedon20 \snext20 \slink23 \ssemihidden \sunhideused \styrsid4538388 annotation subject;}{\*\cs23 \additive \rtlch\fcs1 \ab\af1 \ltrch\fcs0 \b\f1 \sbasedon21 \slink22 \slocked \ssemihidden \styrsid4538388 Comment Subject Char;}}{\*\rsidtbl \rsid213160
\rsid284417\rsid417145\rsid481196\rsid551334\rsid723397\rsid786968\rsid1382437\rsid1390003\rsid1521043\rsid1530955\rsid1708989\rsid1783212\rsid1903779\rsid2431884\rsid3165084\rsid3416120\rsid3419781\rsid3754103\rsid3768194\rsid3831520\rsid4538130
\rsid4538388\rsid4552277\rsid4680449\rsid4729674\rsid4865270\rsid4987534\rsid5128131\rsid5186068\rsid5864350\rsid6186044\rsid6311778\rsid6384507\rsid6434687\rsid6561471\rsid6910344\rsid6947552\rsid7033180\rsid7424395\rsid7682010\rsid7690850\rsid7744081
\rsid8151618\rsid8196281\rsid8198206\rsid8342723\rsid8350925\rsid8722561\rsid8852349\rsid8934457\rsid8944153\rsid9573035\rsid9635349\rsid9638545\rsid9724918\rsid10044820\rsid10095979\rsid10228618\rsid10449644\rsid10494075\rsid11166278\rsid11166751
\rsid11285353\rsid11366513\rsid11494815\rsid11932529\rsid12061202\rsid12533699\rsid12536400\rsid12916885\rsid13264736\rsid13322831\rsid13440556\rsid13455614\rsid13597357\rsid13768671\rsid14097590\rsid14157399\rsid14229900\rsid14305025\rsid14314735
\rsid14436896\rsid14565916\rsid14572556\rsid14688892\rsid14752433\rsid14904394\rsid15086147\rsid15749945\rsid15814398\rsid15927751\rsid16071312\rsid16126175\rsid16279402\rsid16391569\rsid16404661\rsid16452939\rsid16537688\rsid16606866\rsid16674896}
{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\title Microsoft Permissive License (Ms-PL)}{\author Jonr}{\operator Dean Johnson}{\creatim\yr2007\mo2\dy23\hr15\min10}
{\revtim\yr2007\mo2\dy23\hr15\min10}{\printim\yr2006\mo9\dy28\hr8\min46}{\version2}{\edmins1}{\nofpages1}{\nofwords404}{\nofchars2221}{\*\company Microsoft}{\nofcharsws2620}{\vern32859}{\*\saveprevpict}}{\*\userprops {\propname _NewReviewCycle}\proptype30
{\staticval }}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}{\xmlns2 urn:schemas-microsoft-com:office:smarttags}}\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect
\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\hyphcaps0\horzdoc\dghspace120\dgvspace120
\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale100\splytwnine\ftnlytwnine\htmautsp\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct\asianbrkrule\rsidroot10494075
\newtblstyruls\nogrowautofit\utinl \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}
{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}
{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar
\s1\ql \li0\ri0\sb180\nowidctlpar\wrapdefault\faauto\outlinelevel0\rin0\lin0\itap0 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0 \f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af1\afs31 \ltrch\fcs0
\fs31\cf1\kerning36\insrsid10494075\charrsid14688892 Microsoft}{\rtlch\fcs1 \af1\afs31 \ltrch\fcs0 \fs31\cf1\kerning36\insrsid10494075 Permissive}{\rtlch\fcs1 \af1\afs31 \ltrch\fcs0 \fs31\cf1\kerning36\insrsid14688892 }{\rtlch\fcs1 \af1\afs31
\ltrch\fcs0 \fs31\cf1\kerning36\insrsid10494075 License (Ms-PL}{\rtlch\fcs1 \af1\afs31 \ltrch\fcs0 \fs31\cf1\kerning36\insrsid4552277 )}{\rtlch\fcs1 \af1\afs31 \ltrch\fcs0 \fs31\cf1\kerning36\insrsid10494075
\par }\pard\plain \ltrpar\ql \li0\ri0\sl336\slmult1\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0 \f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \ab\af40\afs17 \ltrch\fcs0
\b\f40\fs17\insrsid10494075
\par This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.
\par }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid6910344
\par }\pard\plain \ltrpar\s2\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\outlinelevel1\rin0\lin0\itap0 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0 \f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \ab\af40\afs23 \ltrch\fcs0
\b\f40\fs23\insrsid10494075 1. Definitions
\par }\pard\plain \ltrpar\ql \li0\ri0\sl336\slmult1\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0 \f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af40\afs17 \ltrch\fcs0
\f40\fs17\insrsid10494075 The terms \'93reproduce,\'94 \'93reproduction}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid7744081 ,}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 \'94 }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0
\f40\fs17\insrsid551334 \'93derivative works,\'94}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid7744081\charrsid7744081 }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 and \'93distribution\'94 have the same meaning here as under
{\*\xmlopen\xmlns2{\factoidname country-region}}{\*\xmlopen\xmlns2{\factoidname place}}U.S.{\*\xmlclose}{\*\xmlclose} copyright law.
\par }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid12536400 A \'93contribution\'94 is the original software}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid4865270 ,}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid12536400 }{\rtlch\fcs1
\af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid11932529 or}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid12536400 any additions or changes to the software.
\par }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid551334 A \'93c}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid551334\charrsid551334 ontributor\'94 }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid12536400 is}{\rtlch\fcs1 \af40\afs17
\ltrch\fcs0 \f40\fs17\insrsid12536400\charrsid551334 }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid551334\charrsid551334 any person that }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid12536400
distributes its contribution under this license.}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075
\par }\pard \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0\pararsid14229900 {\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid4729674\delrsid4729674 }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 \'93Licensed patents
\'94 }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid12536400 are }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid3831520 a contributor\rquote s }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 patent claims }{\rtlch\fcs1
\af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid3831520 that }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 read directly on }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid3831520 its contribution.}{\rtlch\fcs1 \af1 \ltrch\fcs0
\insrsid14229900\charrsid14229900
\par }\pard\plain \ltrpar\s2\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\outlinelevel1\rin0\lin0\itap0 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0 \f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \ab\af40\afs23 \ltrch\fcs0
\b\f40\fs23\insrsid5186068
\par }{\rtlch\fcs1 \ab\af40\afs23 \ltrch\fcs0 \b\f40\fs23\insrsid10494075 2. Grant of Rights
\par }\pard\plain \ltrpar\ql \li0\ri0\sl336\slmult1\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0 \f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af40\afs17 \ltrch\fcs0
\f40\fs17\insrsid10494075 (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid3754103 each contributor }{\rtlch\fcs1 \af40\afs17
\ltrch\fcs0 \f40\fs17\insrsid10494075 grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid3754103 its contribution}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0
\f40\fs17\insrsid10494075 , prepare derivative works of }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid3754103 its contribution}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid12536400 ,}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0
\f40\fs17\insrsid10494075 and distribute }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid3754103 its contribution}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 or any derivative works that you create.
\par (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid9724918 each contributor }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0
\f40\fs17\insrsid10494075 grants you a non-exclusive, worldwide, royalty-free license under }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid15814398 its }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 licensed patents
to make, have made, use, sell, offer for sale, }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid1390003 import, }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 and/or otherwise dispose of }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0
\f40\fs17\insrsid8944153 its contribution in }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 the software or derivative works of }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid8944153 the contribution in }{\rtlch\fcs1 \af40\afs17
\ltrch\fcs0 \f40\fs17\insrsid10494075 the software.
\par }\pard\plain \ltrpar\s2\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\outlinelevel1\rin0\lin0\itap0 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0 \f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \ab\af40\afs23 \ltrch\fcs0
\b\f40\fs23\insrsid5186068
\par }{\rtlch\fcs1 \ab\af40\afs23 \ltrch\fcs0 \b\f40\fs23\insrsid10494075 3. Conditions and Limitations
\par }\pard\plain \ltrpar\ql \li0\ri0\sl336\slmult1\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af1\afs24\alang1025 \ltrch\fcs0 \f1\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af40\afs17 \ltrch\fcs0
\f40\fs17\insrsid1530955 }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 (A) No Trademark License- This license does not grant you rights to use }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid1708989 any contributors\rquote }{
\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 name, logo, or trademarks.
\par (B) If you }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid8934457 bring a patent claim against }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10095979 any contributor}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075
over patents that you }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid6947552 claim }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid7682010 are }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid6947552 infringe}{\rtlch\fcs1
\af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid7682010 d by}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 the software, your }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid7682010 patent }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0
\f40\fs17\insrsid10494075 license}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid7682010 from such contributor}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 to the software ends automatically.
\par (C) If you distribute }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid3165084 any portion of }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075
the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
\par (D) If you distribute }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid15749945 any portion of the }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 software in source code form}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0
\f40\fs17\insrsid14904394 ,}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 you may do so only under this license}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid6384507 }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0
\f40\fs17\insrsid14904394 by including }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 a complete copy of this license with your distribution}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid6384507 .}{\rtlch\fcs1 \af40\afs17
\ltrch\fcs0 \f40\fs17\insrsid10494075 }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid6384507 I}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 f you distribute }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid15749945
any portion of }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 the software in compiled or object code form}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid16452939 ,}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075
you may only do so under a license that complies with this license.
\par }\pard \ltrpar\ql \li0\ri0\sl336\slmult1\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0\pararsid14572556 {\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 (E) The software is licensed \'93as-is.\'94 You bear the risk of using it. }{
\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid284417 The contributors }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075
give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0
\f40\fs17\insrsid1783212 the contributors }{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0 \f40\fs17\insrsid10494075 exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.}{\rtlch\fcs1 \af40\afs17 \ltrch\fcs0
\f40\fs17\insrsid10494075\charrsid14572556
\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8
72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7
2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b
44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7
065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000
00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08
84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc
52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353
bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468
656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c
070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7
29e245eb2b260a0238fd010000ffff0300504b03041400060008000000210096b5ade296060000501b0000160000007468656d652f7468656d652f7468656d65
312e786d6cec594f6fdb3614bf0fd87720746f6327761a07758ad8b19b2d4d1bc46e871e698996d850a240d2497d1bdae38001c3ba618715d86d87615b8116d8
a5fb34d93a6c1dd0afb0475292c5585e9236d88aad3e2412f9e3fbff1e1fa9abd7eec70c1d1221294fda5efd72cd4324f1794093b0eddd1ef62fad79482a9c04
98f184b4bd2991deb58df7dfbb8ad755446282607d22d771db8b944ad79796a40fc3585ee62949606ecc458c15bc8a702910f808e8c66c69b9565b5d8a314d3c
94e018c8de1a8fa94fd05093f43672e23d06af89927ac06762a049136785c10607758d9053d965021d62d6f6804fc08f86e4bef210c352c144dbab999fb7b471
7509af678b985ab0b6b4ae6f7ed9ba6c4170b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83a6569632cd467faddec9699640f671
9e76b7d6ac355c7c89feca9cccad4ea7d36c65b258a206641f1b73f8b5da6a6373d9c11b90c537e7f08dce66b7bbeae00dc8e257e7f0fd2badd5868b37a088d1
e4600ead1ddaef67d40bc898b3ed4af81ac0d76a197c86826828a24bb318f3442d8ab518dfe3a20f000d6458d104a9694ac6d88728eee2782428d60cf03ac1a5
193be4cbb921cd0b495fd054b5bd0f530c1931a3f7eaf9f7af9e3f45c70f9e1d3ff8e9f8e1c3e3073f5a42ceaa6d9c84e5552fbffdeccfc71fa33f9e7ef3f2d1
17d57859c6fffac327bffcfc793510d26726ce8b2f9ffcf6ecc98baf3efdfdbb4715f04d814765f890c644a29be408edf3181433567125272371be15c308d3f2
8acd249438c19a4b05fd9e8a1cf4cd296699771c393ac4b5e01d01e5a30a787d72cf1178108989a2159c77a2d801ee72ce3a5c545a6147f32a99793849c26ae6
6252c6ed637c58c5bb8b13c7bfbd490a75330f4b47f16e441c31f7184e140e494214d273fc80900aedee52ead87597fa824b3e56e82e451d4c2b4d32a423279a
668bb6690c7e9956e90cfe766cb37b077538abd27a8b1cba48c80acc2a841f12e698f13a9e281c57911ce298950d7e03aba84ac8c154f8655c4f2af074481847
bd804859b5e696007d4b4edfc150b12addbecba6b18b148a1e54d1bc81392f23b7f84137c2715a851dd0242a633f900710a218ed715505dfe56e86e877f0034e
16bafb0e258ebb4faf06b769e888340b103d3311da9750aa9d0a1cd3e4efca31a3508f6d0c5c5c398602f8e2ebc71591f5b616e24dd893aa3261fb44f95d843b
5974bb5c04f4edafb95b7892ec1108f3f98de75dc97d5772bdff7cc95d94cf672db4b3da0a6557f70db629362d72bcb0431e53c6066acac80d699a6409fb44d0
8741bdce9c0e4971624a2378cceaba830b05366b90e0ea23aaa241845368b0eb9e2612ca8c742851ca251ceccc70256d8d87265dd96361531f186c3d9058edf2
c00eafe8e1fc5c509031bb4d680e9f39a3154de0accc56ae644441edd76156d7429d995bdd88664a9dc3ad50197c38af1a0c16d684060441db02565e85f3b966
0d0713cc48a0ed6ef7dedc2dc60b17e92219e180643ed27acffba86e9c94c78ab90980d8a9f0913ee49d62b512b79626fb06dccee2a432bbc60276b9f7dec44b
7904cfbca4f3f6443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc399161ee314bc2e75cf8759081743be1236ec4f4d6693e5336fb672c5dc24a8c33585b5fb
9cc24e1d4885545b58463634cc5416022cd19cacfccb4d30eb45296023fd35a458598360f8d7a4003bbaae25e331f155d9d9a5116d3bfb9a95523e51440ca2e0
088dd844ec6370bf0e55d027a012ae264c45d02f708fa6ad6da6dce29c255df9f6cae0ec38666984b372ab5334cf640b37795cc860de4ae2816e95b21be5ceaf
8a49f90b52a51cc6ff3355f47e0237052b81f6800fd7b802239daf6d8f0b1571a8426944fdbe80c6c1d40e8816b88b8569082ab84c36ff0539d4ff6dce591a26
ade1c0a7f669880485fd484582903d284b26fa4e2156cff62e4b9265844c4495c495a9157b440e091bea1ab8aaf7760f4510eaa69a6465c0e04ec69ffb9e65d0
28d44d4e39df9c1a52ecbd3607fee9cec7263328e5d661d3d0e4f62f44acd855ed7ab33cdf7bcb8ae889599bd5c8b3029895b6825696f6af29c239b75a5bb1e6
345e6ee6c28117e73586c1a2214ae1be07e93fb0ff51e133fb65426fa843be0fb515c187064d0cc206a2fa926d3c902e907670048d931db4c1a44959d366ad93
b65abe595f70a75bf03d616c2dd959fc7d4e6317cd99cbcec9c58b34766661c7d6766ca1a9c1b327531486c6f941c638c67cd22a7f75e2a37be0e82db8df9f30
254d30c1372581a1f51c983c80e4b71ccdd28dbf000000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f74
68656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f24
51eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e3198
720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d9850528
a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c0200001300000000000000000000000000
000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b000000000000000000000000
002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c00000000000000000000000000140200007468
656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d001400060008000000210096b5ade296060000501b000016000000000000000000
00000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b010000270000000000
00000000000000009b0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000960a00000000}
{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d
617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169
6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363
656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e}
{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;
\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;
\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;
\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdqformat1 \lsdpriority39 \lsdlocked0 toc 1;\lsdqformat1 \lsdpriority39 \lsdlocked0 toc 2;\lsdqformat1 \lsdpriority39 \lsdlocked0 toc 3;\lsdqformat1 \lsdpriority39 \lsdlocked0 toc 4;
\lsdqformat1 \lsdpriority39 \lsdlocked0 toc 5;\lsdqformat1 \lsdpriority39 \lsdlocked0 toc 6;\lsdqformat1 \lsdpriority39 \lsdlocked0 toc 7;\lsdqformat1 \lsdpriority39 \lsdlocked0 toc 8;\lsdqformat1 \lsdpriority39 \lsdlocked0 toc 9;
\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;
\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;
\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;
\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;
\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;
\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;
\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;
\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 0105000002000000180000004d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000
d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f000000000000000000000000d070
a7c59f57c701feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000105000000000000}}
@@ -0,0 +1,14 @@
@echo off
setlocal
SET TWOMGFX="..\..\..\..\Tools\2MGFX\bin\Windows\AnyCPU\Release\2mgfx.exe"
@for /f %%f IN ('dir /b *.fx') do (
call %TWOMGFX% %%~nf.fx %%~nf.ogl.mgfxo
call %TWOMGFX% %%~nf.fx %%~nf.dx11.mgfxo /Profile:DirectX_11
)
endlocal
@@ -0,0 +1,283 @@
//-----------------------------------------------------------------------------
// SkinnedEffect.fx
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include "Macros.fxh"
#define SKINNED_EFFECT_MAX_BONES 72
DECLARE_TEXTURE(Texture, 0);
BEGIN_CONSTANTS
float4 DiffuseColor _vs(c0) _ps(c1) _cb(c0);
float3 EmissiveColor _vs(c1) _ps(c2) _cb(c1);
float3 SpecularColor _vs(c2) _ps(c3) _cb(c2);
float SpecularPower _vs(c3) _ps(c4) _cb(c2.w);
float3 DirLight0Direction _vs(c4) _ps(c5) _cb(c3);
float3 DirLight0DiffuseColor _vs(c5) _ps(c6) _cb(c4);
float3 DirLight0SpecularColor _vs(c6) _ps(c7) _cb(c5);
float3 DirLight1Direction _vs(c7) _ps(c8) _cb(c6);
float3 DirLight1DiffuseColor _vs(c8) _ps(c9) _cb(c7);
float3 DirLight1SpecularColor _vs(c9) _ps(c10) _cb(c8);
float3 DirLight2Direction _vs(c10) _ps(c11) _cb(c9);
float3 DirLight2DiffuseColor _vs(c11) _ps(c12) _cb(c10);
float3 DirLight2SpecularColor _vs(c12) _ps(c13) _cb(c11);
float3 EyePosition _vs(c13) _ps(c14) _cb(c12);
float3 FogColor _ps(c0) _cb(c13);
float4 FogVector _vs(c14) _cb(c14);
float4x4 World _vs(c19) _cb(c15);
float3x3 WorldInverseTranspose _vs(c23) _cb(c19);
float4x3 Bones[SKINNED_EFFECT_MAX_BONES] _vs(c26) _cb(c22);
MATRIX_CONSTANTS
float4x4 WorldViewProj _vs(c15) _cb(c0);
END_CONSTANTS
#include "Structures.fxh"
#include "Common.fxh"
#include "Lighting.fxh"
void Skin(inout VSInputNmTxWeights vin, uniform int boneCount)
{
float4x3 skinning = 0;
[unroll]
for (int i = 0; i < boneCount; i++)
{
skinning += Bones[vin.Indices[i]] * vin.Weights[i];
}
vin.Position.xyz = mul(vin.Position, skinning);
vin.Normal = mul(vin.Normal, (float3x3)skinning);
}
// Vertex shader: vertex lighting, one bone.
VSOutputTx VSSkinnedVertexLightingOneBone(VSInputNmTxWeights vin)
{
VSOutputTx vout;
Skin(vin, 1);
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 3);
SetCommonVSOutputParams;
vout.TexCoord = vin.TexCoord;
return vout;
}
// Vertex shader: vertex lighting, two bones.
VSOutputTx VSSkinnedVertexLightingTwoBones(VSInputNmTxWeights vin)
{
VSOutputTx vout;
Skin(vin, 2);
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 3);
SetCommonVSOutputParams;
vout.TexCoord = vin.TexCoord;
return vout;
}
// Vertex shader: vertex lighting, four bones.
VSOutputTx VSSkinnedVertexLightingFourBones(VSInputNmTxWeights vin)
{
VSOutputTx vout;
Skin(vin, 4);
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 3);
SetCommonVSOutputParams;
vout.TexCoord = vin.TexCoord;
return vout;
}
// Vertex shader: one light, one bone.
VSOutputTx VSSkinnedOneLightOneBone(VSInputNmTxWeights vin)
{
VSOutputTx vout;
Skin(vin, 1);
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 1);
SetCommonVSOutputParams;
vout.TexCoord = vin.TexCoord;
return vout;
}
// Vertex shader: one light, two bones.
VSOutputTx VSSkinnedOneLightTwoBones(VSInputNmTxWeights vin)
{
VSOutputTx vout;
Skin(vin, 2);
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 1);
SetCommonVSOutputParams;
vout.TexCoord = vin.TexCoord;
return vout;
}
// Vertex shader: one light, four bones.
VSOutputTx VSSkinnedOneLightFourBones(VSInputNmTxWeights vin)
{
VSOutputTx vout;
Skin(vin, 4);
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(vin.Position, vin.Normal, 1);
SetCommonVSOutputParams;
vout.TexCoord = vin.TexCoord;
return vout;
}
// Vertex shader: pixel lighting, one bone.
VSOutputPixelLightingTx VSSkinnedPixelLightingOneBone(VSInputNmTxWeights vin)
{
VSOutputPixelLightingTx vout;
Skin(vin, 1);
CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal);
SetCommonVSOutputParamsPixelLighting;
vout.Diffuse = float4(1, 1, 1, DiffuseColor.a);
vout.TexCoord = vin.TexCoord;
return vout;
}
// Vertex shader: pixel lighting, two bones.
VSOutputPixelLightingTx VSSkinnedPixelLightingTwoBones(VSInputNmTxWeights vin)
{
VSOutputPixelLightingTx vout;
Skin(vin, 2);
CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal);
SetCommonVSOutputParamsPixelLighting;
vout.Diffuse = float4(1, 1, 1, DiffuseColor.a);
vout.TexCoord = vin.TexCoord;
return vout;
}
// Vertex shader: pixel lighting, four bones.
VSOutputPixelLightingTx VSSkinnedPixelLightingFourBones(VSInputNmTxWeights vin)
{
VSOutputPixelLightingTx vout;
Skin(vin, 4);
CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal);
SetCommonVSOutputParamsPixelLighting;
vout.Diffuse = float4(1, 1, 1, DiffuseColor.a);
vout.TexCoord = vin.TexCoord;
return vout;
}
// Pixel shader: vertex lighting.
float4 PSSkinnedVertexLighting(VSOutputTx pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
AddSpecular(color, pin.Specular.rgb);
ApplyFog(color, pin.Specular.w);
return color;
}
// Pixel shader: vertex lighting, no fog.
float4 PSSkinnedVertexLightingNoFog(VSOutputTx pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
AddSpecular(color, pin.Specular.rgb);
return color;
}
// Pixel shader: pixel lighting.
float4 PSSkinnedPixelLighting(VSOutputPixelLightingTx pin) : SV_Target0
{
float4 color = SAMPLE_TEXTURE(Texture, pin.TexCoord) * pin.Diffuse;
float3 eyeVector = normalize(EyePosition - pin.PositionWS.xyz);
float3 worldNormal = normalize(pin.NormalWS);
ColorPair lightResult = ComputeLights(eyeVector, worldNormal, 3);
color.rgb *= lightResult.Diffuse;
AddSpecular(color, lightResult.Specular);
ApplyFog(color, pin.PositionWS.w);
return color;
}
// NOTE: The order of the techniques here are
// defined to match the indexing in SkinnedEffect.cs.
TECHNIQUE( SkinnedEffect_VertexLighting_OneBone, VSSkinnedVertexLightingOneBone, PSSkinnedVertexLighting );
TECHNIQUE( SkinnedEffect_VertexLighting_OneBone_NoFog, VSSkinnedVertexLightingOneBone, PSSkinnedVertexLightingNoFog );
TECHNIQUE( SkinnedEffect_VertexLighting_TwoBone, VSSkinnedVertexLightingTwoBones, PSSkinnedVertexLighting );
TECHNIQUE( SkinnedEffect_VertexLighting_TwoBone_NoFog, VSSkinnedVertexLightingTwoBones, PSSkinnedVertexLightingNoFog );
TECHNIQUE( SkinnedEffect_VertexLighting_FourBone, VSSkinnedVertexLightingFourBones, PSSkinnedVertexLighting );
TECHNIQUE( SkinnedEffect_VertexLighting_FourBone_NoFog, VSSkinnedVertexLightingFourBones, PSSkinnedVertexLightingNoFog );
TECHNIQUE( SkinnedEffect_OneLight_OneBone, VSSkinnedOneLightOneBone, PSSkinnedVertexLighting );
TECHNIQUE( SkinnedEffect_OneLight_OneBone_NoFog, VSSkinnedOneLightOneBone, PSSkinnedVertexLightingNoFog );
TECHNIQUE( SkinnedEffect_OneLight_TwoBone, VSSkinnedOneLightTwoBones, PSSkinnedVertexLighting );
TECHNIQUE( SkinnedEffect_OneLight_TwoBone_NoFog, VSSkinnedOneLightTwoBones, PSSkinnedVertexLightingNoFog );
TECHNIQUE( SkinnedEffect_OneLight_FourBone, VSSkinnedOneLightFourBones, PSSkinnedVertexLighting );
TECHNIQUE( SkinnedEffect_OneLight_FourBone_NoFog, VSSkinnedOneLightFourBones, PSSkinnedVertexLightingNoFog );
TECHNIQUE( SkinnedEffect_PixelLighting_OneBone, VSSkinnedPixelLightingOneBone, PSSkinnedPixelLighting );
TECHNIQUE( SkinnedEffect_PixelLighting_OneBone_NoFog, VSSkinnedPixelLightingOneBone, PSSkinnedPixelLighting );
TECHNIQUE( SkinnedEffect_PixelLighting_TwoBone, VSSkinnedPixelLightingTwoBones, PSSkinnedPixelLighting );
TECHNIQUE( SkinnedEffect_PixelLighting_TwoBone_NoFog, VSSkinnedPixelLightingTwoBones, PSSkinnedPixelLighting );
TECHNIQUE( SkinnedEffect_PixelLighting_FourBone, VSSkinnedPixelLightingFourBones, PSSkinnedPixelLighting );
TECHNIQUE( SkinnedEffect_PixelLighting_FourBone_NoFog, VSSkinnedPixelLightingFourBones, PSSkinnedPixelLighting );
@@ -0,0 +1,46 @@
//-----------------------------------------------------------------------------
// SpriteEffect.fx
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include "Macros.fxh"
DECLARE_TEXTURE(Texture, 0);
BEGIN_CONSTANTS
MATRIX_CONSTANTS
float4x4 MatrixTransform _vs(c0) _cb(c0);
END_CONSTANTS
struct VSOutput
{
float4 position : SV_Position;
float4 color : COLOR0;
float2 texCoord : TEXCOORD0;
};
VSOutput SpriteVertexShader( float4 position : POSITION0,
float4 color : COLOR0,
float2 texCoord : TEXCOORD0)
{
VSOutput output;
output.position = mul(position, MatrixTransform);
output.color = color;
output.texCoord = texCoord;
return output;
}
float4 SpritePixelShader(VSOutput input) : SV_Target0
{
return SAMPLE_TEXTURE(Texture, input.texCoord) * input.color;
}
TECHNIQUE( SpriteBatch, SpriteVertexShader, SpritePixelShader );
@@ -0,0 +1,161 @@
//-----------------------------------------------------------------------------
// Structurs.fxh
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
// Vertex shader input structures.
struct VSInput
{
float4 Position : POSITION;
};
struct VSInputVc
{
float4 Position : POSITION;
float4 Color : COLOR;
};
struct VSInputTx
{
float4 Position : POSITION;
float2 TexCoord : TEXCOORD;
};
struct VSInputTxVc
{
float4 Position : POSITION;
float2 TexCoord : TEXCOORD;
float4 Color : COLOR;
};
struct VSInputNm
{
float4 Position : POSITION;
float3 Normal : NORMAL;
};
struct VSInputNmVc
{
float4 Position : POSITION;
float3 Normal : NORMAL;
float4 Color : COLOR;
};
struct VSInputNmTx
{
float4 Position : POSITION;
float3 Normal : NORMAL;
float2 TexCoord : TEXCOORD;
};
struct VSInputNmTxVc
{
float4 Position : POSITION;
float3 Normal : NORMAL;
float2 TexCoord : TEXCOORD;
float4 Color : COLOR;
};
struct VSInputTx2
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
float2 TexCoord2 : TEXCOORD1;
};
struct VSInputTx2Vc
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
float2 TexCoord2 : TEXCOORD1;
float4 Color : COLOR;
};
struct VSInputNmTxWeights
{
float4 Position : POSITION0;
float3 Normal : NORMAL0;
float2 TexCoord : TEXCOORD0;
uint4 Indices : BLENDINDICES0;
float4 Weights : BLENDWEIGHT0;
};
// Vertex shader output structures.
struct VSOutput
{
float4 PositionPS : SV_Position;
float4 Diffuse : COLOR0;
float4 Specular : COLOR1;
};
struct VSOutputNoFog
{
float4 PositionPS : SV_Position;
float4 Diffuse : COLOR0;
};
struct VSOutputTx
{
float4 PositionPS : SV_Position;
float4 Diffuse : COLOR0;
float4 Specular : COLOR1;
float2 TexCoord : TEXCOORD0;
};
struct VSOutputTxNoFog
{
float4 PositionPS : SV_Position;
float4 Diffuse : COLOR0;
float2 TexCoord : TEXCOORD0;
};
struct VSOutputPixelLighting
{
float4 PositionPS : SV_Position;
float4 PositionWS : TEXCOORD0;
float3 NormalWS : TEXCOORD1;
float4 Diffuse : COLOR0;
};
struct VSOutputPixelLightingTx
{
float4 PositionPS : SV_Position;
float2 TexCoord : TEXCOORD0;
float4 PositionWS : TEXCOORD1;
float3 NormalWS : TEXCOORD2;
float4 Diffuse : COLOR0;
};
struct VSOutputTx2
{
float4 PositionPS : SV_Position;
float4 Diffuse : COLOR0;
float4 Specular : COLOR1;
float2 TexCoord : TEXCOORD0;
float2 TexCoord2 : TEXCOORD1;
};
struct VSOutputTx2NoFog
{
float4 PositionPS : SV_Position;
float4 Diffuse : COLOR0;
float2 TexCoord : TEXCOORD0;
float2 TexCoord2 : TEXCOORD1;
};
struct VSOutputTxEnvMap
{
float4 PositionPS : SV_Position;
float4 Diffuse : COLOR0;
float4 Specular : COLOR1;
float2 TexCoord : TEXCOORD0;
float3 EnvCoord : TEXCOORD1;
};
@@ -0,0 +1,538 @@
#region File Description
//-----------------------------------------------------------------------------
// SkinnedEffect.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endregion
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// Built-in effect for rendering skinned character models.
/// </summary>
public class SkinnedEffect : Effect, IEffectMatrices, IEffectLights, IEffectFog
{
public const int MaxBones = 72;
#region Effect Parameters
EffectParameter textureParam;
EffectParameter diffuseColorParam;
EffectParameter emissiveColorParam;
EffectParameter specularColorParam;
EffectParameter specularPowerParam;
EffectParameter eyePositionParam;
EffectParameter fogColorParam;
EffectParameter fogVectorParam;
EffectParameter worldParam;
EffectParameter worldInverseTransposeParam;
EffectParameter worldViewProjParam;
EffectParameter bonesParam;
#endregion
#region Fields
bool preferPerPixelLighting;
bool oneLight;
bool fogEnabled;
Matrix world = Matrix.Identity;
Matrix view = Matrix.Identity;
Matrix projection = Matrix.Identity;
Matrix worldView;
Vector3 diffuseColor = Vector3.One;
Vector3 emissiveColor = Vector3.Zero;
Vector3 ambientLightColor = Vector3.Zero;
float alpha = 1;
DirectionalLight light0;
DirectionalLight light1;
DirectionalLight light2;
float fogStart = 0;
float fogEnd = 1;
int weightsPerVertex = 4;
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
#endregion
#region Public Properties
/// <summary>
/// Gets or sets the world matrix.
/// </summary>
public Matrix World
{
get { return world; }
set
{
world = value;
dirtyFlags |= EffectDirtyFlags.World | EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.Fog;
}
}
/// <summary>
/// Gets or sets the view matrix.
/// </summary>
public Matrix View
{
get { return view; }
set
{
view = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.EyePosition | EffectDirtyFlags.Fog;
}
}
/// <summary>
/// Gets or sets the projection matrix.
/// </summary>
public Matrix Projection
{
get { return projection; }
set
{
projection = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
}
}
/// <summary>
/// Gets or sets the material diffuse color (range 0 to 1).
/// </summary>
public Vector3 DiffuseColor
{
get { return diffuseColor; }
set
{
diffuseColor = value;
dirtyFlags |= EffectDirtyFlags.MaterialColor;
}
}
/// <summary>
/// Gets or sets the material emissive color (range 0 to 1).
/// </summary>
public Vector3 EmissiveColor
{
get { return emissiveColor; }
set
{
emissiveColor = value;
dirtyFlags |= EffectDirtyFlags.MaterialColor;
}
}
/// <summary>
/// Gets or sets the material specular color (range 0 to 1).
/// </summary>
public Vector3 SpecularColor
{
get { return specularColorParam.GetValueVector3(); }
set { specularColorParam.SetValue(value); }
}
/// <summary>
/// Gets or sets the material specular power.
/// </summary>
public float SpecularPower
{
get { return specularPowerParam.GetValueSingle(); }
set { specularPowerParam.SetValue(value); }
}
/// <summary>
/// Gets or sets the material alpha.
/// </summary>
public float Alpha
{
get { return alpha; }
set
{
alpha = value;
dirtyFlags |= EffectDirtyFlags.MaterialColor;
}
}
/// <summary>
/// Gets or sets the per-pixel lighting prefer flag.
/// </summary>
public bool PreferPerPixelLighting
{
get { return preferPerPixelLighting; }
set
{
if (preferPerPixelLighting != value)
{
preferPerPixelLighting = value;
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
}
}
}
/// <summary>
/// Gets or sets the ambient light color (range 0 to 1).
/// </summary>
public Vector3 AmbientLightColor
{
get { return ambientLightColor; }
set
{
ambientLightColor = value;
dirtyFlags |= EffectDirtyFlags.MaterialColor;
}
}
/// <summary>
/// Gets the first directional light.
/// </summary>
public DirectionalLight DirectionalLight0 { get { return light0; } }
/// <summary>
/// Gets the second directional light.
/// </summary>
public DirectionalLight DirectionalLight1 { get { return light1; } }
/// <summary>
/// Gets the third directional light.
/// </summary>
public DirectionalLight DirectionalLight2 { get { return light2; } }
/// <summary>
/// Gets or sets the fog enable flag.
/// </summary>
public bool FogEnabled
{
get { return fogEnabled; }
set
{
if (fogEnabled != value)
{
fogEnabled = value;
dirtyFlags |= EffectDirtyFlags.ShaderIndex | EffectDirtyFlags.FogEnable;
}
}
}
/// <summary>
/// Gets or sets the fog start distance.
/// </summary>
public float FogStart
{
get { return fogStart; }
set
{
fogStart = value;
dirtyFlags |= EffectDirtyFlags.Fog;
}
}
/// <summary>
/// Gets or sets the fog end distance.
/// </summary>
public float FogEnd
{
get { return fogEnd; }
set
{
fogEnd = value;
dirtyFlags |= EffectDirtyFlags.Fog;
}
}
/// <summary>
/// Gets or sets the fog color.
/// </summary>
public Vector3 FogColor
{
get { return fogColorParam.GetValueVector3(); }
set { fogColorParam.SetValue(value); }
}
/// <summary>
/// Gets or sets the current texture.
/// </summary>
public Texture2D Texture
{
get { return textureParam.GetValueTexture2D(); }
set { textureParam.SetValue(value); }
}
/// <summary>
/// Gets or sets the number of skinning weights to evaluate for each vertex (1, 2, or 4).
/// </summary>
public int WeightsPerVertex
{
get { return weightsPerVertex; }
set
{
if ((value != 1) &&
(value != 2) &&
(value != 4))
{
throw new ArgumentOutOfRangeException("value");
}
weightsPerVertex = value;
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
}
}
/// <summary>
/// Sets an array of skinning bone transform matrices.
/// </summary>
public void SetBoneTransforms(Matrix[] boneTransforms)
{
if ((boneTransforms == null) || (boneTransforms.Length == 0))
throw new ArgumentNullException("boneTransforms");
if (boneTransforms.Length > MaxBones)
throw new ArgumentException();
bonesParam.SetValue(boneTransforms);
}
/// <summary>
/// Gets a copy of the current skinning bone transform matrices.
/// </summary>
public Matrix[] GetBoneTransforms(int count)
{
if (count <= 0 || count > MaxBones)
throw new ArgumentOutOfRangeException("count");
Matrix[] bones = bonesParam.GetValueMatrixArray(count);
// Convert matrices from 43 to 44 format.
for (int i = 0; i < bones.Length; i++)
{
bones[i].M44 = 1;
}
return bones;
}
/// <summary>
/// This effect requires lighting, so we explicitly implement
/// IEffectLights.LightingEnabled, and do not allow turning it off.
/// </summary>
bool IEffectLights.LightingEnabled
{
get { return true; }
set { if (!value) throw new NotSupportedException("SkinnedEffect does not support setting LightingEnabled to false."); }
}
#endregion
#region Methods
/// <summary>
/// Creates a new SkinnedEffect with default parameter settings.
/// </summary>
public SkinnedEffect(GraphicsDevice device)
: base(device, EffectResource.SkinnedEffect.Bytecode)
{
CacheEffectParameters(null);
DirectionalLight0.Enabled = true;
SpecularColor = Vector3.One;
SpecularPower = 16;
Matrix[] identityBones = new Matrix[MaxBones];
for (int i = 0; i < MaxBones; i++)
{
identityBones[i] = Matrix.Identity;
}
SetBoneTransforms(identityBones);
}
/// <summary>
/// Creates a new SkinnedEffect by cloning parameter settings from an existing instance.
/// </summary>
protected SkinnedEffect(SkinnedEffect cloneSource)
: base(cloneSource)
{
CacheEffectParameters(cloneSource);
preferPerPixelLighting = cloneSource.preferPerPixelLighting;
fogEnabled = cloneSource.fogEnabled;
world = cloneSource.world;
view = cloneSource.view;
projection = cloneSource.projection;
diffuseColor = cloneSource.diffuseColor;
emissiveColor = cloneSource.emissiveColor;
ambientLightColor = cloneSource.ambientLightColor;
alpha = cloneSource.alpha;
fogStart = cloneSource.fogStart;
fogEnd = cloneSource.fogEnd;
weightsPerVertex = cloneSource.weightsPerVertex;
}
/// <summary>
/// Creates a clone of the current SkinnedEffect instance.
/// </summary>
public override Effect Clone()
{
return new SkinnedEffect(this);
}
/// <summary>
/// Sets up the standard key/fill/back lighting rig.
/// </summary>
public void EnableDefaultLighting()
{
AmbientLightColor = EffectHelpers.EnableDefaultLighting(light0, light1, light2);
}
/// <summary>
/// Looks up shortcut references to our effect parameters.
/// </summary>
void CacheEffectParameters(SkinnedEffect cloneSource)
{
textureParam = Parameters["Texture"];
diffuseColorParam = Parameters["DiffuseColor"];
emissiveColorParam = Parameters["EmissiveColor"];
specularColorParam = Parameters["SpecularColor"];
specularPowerParam = Parameters["SpecularPower"];
eyePositionParam = Parameters["EyePosition"];
fogColorParam = Parameters["FogColor"];
fogVectorParam = Parameters["FogVector"];
worldParam = Parameters["World"];
worldInverseTransposeParam = Parameters["WorldInverseTranspose"];
worldViewProjParam = Parameters["WorldViewProj"];
bonesParam = Parameters["Bones"];
light0 = new DirectionalLight(Parameters["DirLight0Direction"],
Parameters["DirLight0DiffuseColor"],
Parameters["DirLight0SpecularColor"],
(cloneSource != null) ? cloneSource.light0 : null);
light1 = new DirectionalLight(Parameters["DirLight1Direction"],
Parameters["DirLight1DiffuseColor"],
Parameters["DirLight1SpecularColor"],
(cloneSource != null) ? cloneSource.light1 : null);
light2 = new DirectionalLight(Parameters["DirLight2Direction"],
Parameters["DirLight2DiffuseColor"],
Parameters["DirLight2SpecularColor"],
(cloneSource != null) ? cloneSource.light2 : null);
}
/// <summary>
/// Lazily computes derived parameter values immediately before applying the effect.
/// </summary>
protected internal override void OnApply()
{
// Recompute the world+view+projection matrix or fog vector?
dirtyFlags = EffectHelpers.SetWorldViewProjAndFog(dirtyFlags, ref world, ref view, ref projection, ref worldView, fogEnabled, fogStart, fogEnd, worldViewProjParam, fogVectorParam);
// Recompute the world inverse transpose and eye position?
dirtyFlags = EffectHelpers.SetLightingMatrices(dirtyFlags, ref world, ref view, worldParam, worldInverseTransposeParam, eyePositionParam);
// Recompute the diffuse/emissive/alpha material color parameters?
if ((dirtyFlags & EffectDirtyFlags.MaterialColor) != 0)
{
EffectHelpers.SetMaterialColor(true, alpha, ref diffuseColor, ref emissiveColor, ref ambientLightColor, diffuseColorParam, emissiveColorParam);
dirtyFlags &= ~EffectDirtyFlags.MaterialColor;
}
// Check if we can use the only-bother-with-the-first-light shader optimization.
bool newOneLight = !light1.Enabled && !light2.Enabled;
if (oneLight != newOneLight)
{
oneLight = newOneLight;
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
}
// Recompute the shader index?
if ((dirtyFlags & EffectDirtyFlags.ShaderIndex) != 0)
{
int shaderIndex = 0;
if (!fogEnabled)
shaderIndex += 1;
if (weightsPerVertex == 2)
shaderIndex += 2;
else if (weightsPerVertex == 4)
shaderIndex += 4;
if (preferPerPixelLighting)
shaderIndex += 12;
else if (oneLight)
shaderIndex += 6;
dirtyFlags &= ~EffectDirtyFlags.ShaderIndex;
CurrentTechnique = Techniques[shaderIndex];
}
}
#endregion
}
}
@@ -0,0 +1,79 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// The default effect used by SpriteBatch.
/// </summary>
public class SpriteEffect : Effect
{
#region Effect Parameters
EffectParameter matrixParam;
#endregion
#region Methods
/// <summary>
/// Creates a new SpriteEffect.
/// </summary>
public SpriteEffect(GraphicsDevice device)
: base(device, EffectResource.SpriteEffect.Bytecode)
{
CacheEffectParameters();
}
/// <summary>
/// Creates a new SpriteEffect by cloning parameter settings from an existing instance.
/// </summary>
protected SpriteEffect(SpriteEffect cloneSource)
: base(cloneSource)
{
CacheEffectParameters();
}
/// <summary>
/// Creates a clone of the current SpriteEffect instance.
/// </summary>
public override Effect Clone()
{
return new SpriteEffect(this);
}
/// <summary>
/// Looks up shortcut references to our effect parameters.
/// </summary>
void CacheEffectParameters()
{
matrixParam = Parameters["MatrixTransform"];
}
/// <summary>
/// Lazily computes derived parameter values immediately before applying the effect.
/// </summary>
protected internal override void OnApply()
{
var viewport = GraphicsDevice.Viewport;
var projection = Matrix.CreateOrthographicOffCenter(0, viewport.Width, viewport.Height, 0, 0, 1);
var halfPixelOffset = Matrix.CreateTranslation(0, 0, 0);
if (SpriteBatch.NeedsHalfPixelOffset){
halfPixelOffset += Matrix.CreateTranslation(-0.5f, -0.5f, 0);
}
matrixParam.SetValue(halfPixelOffset * projection);
}
#endregion
}
}
@@ -0,0 +1,142 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using SharpDX.Direct3D;
namespace Microsoft.Xna.Framework.Graphics
{
partial class GraphicsAdapter
{
SharpDX.DXGI.Adapter1 _adapter;
private static void PlatformInitializeAdapters(out ReadOnlyCollection<GraphicsAdapter> adapters)
{
var factory = new SharpDX.DXGI.Factory1();
var adapterCount = factory.GetAdapterCount();
var adapterList = new List<GraphicsAdapter>(adapterCount);
for (var i = 0; i < adapterCount; i++)
{
var device = factory.GetAdapter1(i);
var monitorCount = device.GetOutputCount();
for (var j = 0; j < monitorCount; j++)
{
var monitor = device.GetOutput(j);
var adapter = CreateAdapter(device, monitor);
adapterList.Add(adapter);
monitor.Dispose();
}
}
factory.Dispose();
adapters = new ReadOnlyCollection<GraphicsAdapter>(adapterList);
}
private static readonly Dictionary<SharpDX.DXGI.Format, SurfaceFormat> FormatTranslations = new Dictionary<SharpDX.DXGI.Format, SurfaceFormat>
{
{ SharpDX.DXGI.Format.R8G8B8A8_UNorm, SurfaceFormat.Color },
{ SharpDX.DXGI.Format.B8G8R8A8_UNorm, SurfaceFormat.Color },
{ SharpDX.DXGI.Format.B5G6R5_UNorm, SurfaceFormat.Bgr565 },
};
private static GraphicsAdapter CreateAdapter(SharpDX.DXGI.Adapter1 device, SharpDX.DXGI.Output monitor)
{
var adapter = new GraphicsAdapter();
adapter._adapter = device;
adapter.DeviceName = monitor.Description.DeviceName.TrimEnd(new char[] {'\0'});
adapter.Description = device.Description1.Description.TrimEnd(new char[] {'\0'});
adapter.DeviceId = device.Description1.DeviceId;
adapter.Revision = device.Description1.Revision;
adapter.VendorId = device.Description1.VendorId;
adapter.SubSystemId = device.Description1.SubsystemId;
adapter.MonitorHandle = monitor.Description.MonitorHandle;
var desktopWidth = monitor.Description.DesktopBounds.Right - monitor.Description.DesktopBounds.Left;
var desktopHeight = monitor.Description.DesktopBounds.Bottom - monitor.Description.DesktopBounds.Top;
var modes = new List<DisplayMode>();
foreach (var formatTranslation in FormatTranslations)
{
SharpDX.DXGI.ModeDescription[] displayModes;
// This can fail on headless machines, so just assume the desktop size
// is a valid mode and return that... so at least our unit tests work.
try
{
displayModes = monitor.GetDisplayModeList(formatTranslation.Key, 0);
}
catch (SharpDX.SharpDXException)
{
var mode = new DisplayMode(desktopWidth, desktopHeight, SurfaceFormat.Color);
modes.Add(mode);
adapter._currentDisplayMode = mode;
break;
}
foreach (var displayMode in displayModes)
{
var mode = new DisplayMode(displayMode.Width, displayMode.Height, formatTranslation.Value);
// Skip duplicate modes with the same width/height/formats.
if (modes.Contains(mode))
continue;
modes.Add(mode);
if (adapter._currentDisplayMode == null)
{
if (mode.Width == desktopWidth && mode.Height == desktopHeight && mode.Format == SurfaceFormat.Color)
adapter._currentDisplayMode = mode;
}
}
}
adapter._supportedDisplayModes = new DisplayModeCollection(modes);
if (adapter._currentDisplayMode == null) //(i.e. desktop mode wasn't found in the available modes)
adapter._currentDisplayMode = new DisplayMode(desktopWidth, desktopHeight, SurfaceFormat.Color);
return adapter;
}
private bool PlatformIsProfileSupported(GraphicsProfile graphicsProfile)
{
if(UseReferenceDevice)
return true;
FeatureLevel highestSupportedLevel;
try
{
highestSupportedLevel = SharpDX.Direct3D11.Device.GetSupportedFeatureLevel(_adapter);
}
catch (SharpDX.SharpDXException ex)
{
if (ex.ResultCode == SharpDX.DXGI.ResultCode.Unsupported) // No supported feature levels!
return false;
throw;
}
switch(graphicsProfile)
{
case GraphicsProfile.Reach:
return (highestSupportedLevel >= FeatureLevel.Level_9_1);
case GraphicsProfile.HiDef:
return (highestSupportedLevel >= FeatureLevel.Level_10_0);
default:
throw new InvalidOperationException();
}
}
}
}
@@ -0,0 +1,408 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
#if IOS
using UIKit;
#elif ANDROID
using Android.Views;
using Android.Runtime;
#endif
// NOTE: This is the legacy graphics adapter implementation
// which should no longer be updated. All new development
// should go into the new one.
namespace Microsoft.Xna.Framework.Graphics
{
public sealed class GraphicsAdapter : IDisposable
{
/// <summary>
/// Defines the driver type for graphics adapter. Usable only on DirectX platforms for now.
/// </summary>
public enum DriverType
{
/// <summary>
/// Hardware device been used for rendering. Maximum speed and performance.
/// </summary>
Hardware,
/// <summary>
/// Emulates the hardware device on CPU. Slowly, only for testing.
/// </summary>
Reference,
/// <summary>
/// Useful when <see cref="DriverType.Hardware"/> acceleration does not work.
/// </summary>
FastSoftware
}
private static ReadOnlyCollection<GraphicsAdapter> _adapters;
private DisplayModeCollection _supportedDisplayModes;
#if IOS
private UIScreen _screen;
internal GraphicsAdapter(UIScreen screen)
{
_screen = screen;
}
#elif DESKTOPGL
int _displayIndex;
#else
internal GraphicsAdapter()
{
}
#endif
public void Dispose()
{
}
string _description = string.Empty;
public string Description { get { return _description; } private set { _description = value; } }
public DisplayMode CurrentDisplayMode
{
get
{
#if IOS
return new DisplayMode((int)(_screen.Bounds.Width * _screen.Scale),
(int)(_screen.Bounds.Height * _screen.Scale),
SurfaceFormat.Color);
#elif ANDROID
View view = ((AndroidGameWindow)Game.Instance.Window).GameView;
return new DisplayMode(view.Width, view.Height, SurfaceFormat.Color);
#elif DESKTOPGL
var displayIndex = Sdl.Display.GetWindowDisplayIndex(SdlGameWindow.Instance.Handle);
Sdl.Display.Mode mode;
Sdl.Display.GetCurrentDisplayMode(displayIndex, out mode);
return new DisplayMode(mode.Width, mode.Height, SurfaceFormat.Color);
#elif WINDOWS
using (var graphics = System.Drawing.Graphics.FromHwnd(IntPtr.Zero))
{
var dc = graphics.GetHdc();
int width = GetDeviceCaps(dc, HORZRES);
int height = GetDeviceCaps(dc, VERTRES);
graphics.ReleaseHdc(dc);
return new DisplayMode(width, height, SurfaceFormat.Color);
}
#else
return new DisplayMode(800, 600, SurfaceFormat.Color);
#endif
}
}
public static GraphicsAdapter DefaultAdapter
{
get { return Adapters[0]; }
}
public static ReadOnlyCollection<GraphicsAdapter> Adapters
{
get
{
if (_adapters == null)
{
#if IOS
_adapters = new ReadOnlyCollection<GraphicsAdapter>(
new [] {new GraphicsAdapter(UIScreen.MainScreen)});
#else
_adapters = new ReadOnlyCollection<GraphicsAdapter>(new[] { new GraphicsAdapter() });
#endif
}
return _adapters;
}
}
/// <summary>
/// Used to request creation of the reference graphics device,
/// or the default hardware accelerated device (when set to false).
/// </summary>
/// <remarks>
/// This only works on DirectX platforms where a reference graphics
/// device is available and must be defined before the graphics device
/// is created. It defaults to false.
/// </remarks>
public static bool UseReferenceDevice
{
get { return UseDriverType == DriverType.Reference; }
set { UseDriverType = value ? DriverType.Reference : DriverType.Hardware; }
}
/// <summary>
/// Used to request creation of a specific kind of driver.
/// </summary>
/// <remarks>
/// These values only work on DirectX platforms and must be defined before the graphics device
/// is created. <see cref="DriverType.Hardware"/> by default.
/// </remarks>
public static DriverType UseDriverType { get; set; }
/// <summary>
/// Queries for support of the requested render target format on the adaptor.
/// </summary>
/// <param name="graphicsProfile">The graphics profile.</param>
/// <param name="format">The requested surface format.</param>
/// <param name="depthFormat">The requested depth stencil format.</param>
/// <param name="multiSampleCount">The requested multisample count.</param>
/// <param name="selectedFormat">Set to the best format supported by the adaptor for the requested surface format.</param>
/// <param name="selectedDepthFormat">Set to the best format supported by the adaptor for the requested depth stencil format.</param>
/// <param name="selectedMultiSampleCount">Set to the best count supported by the adaptor for the requested multisample count.</param>
/// <returns>True if the requested format is supported by the adaptor. False if one or more of the values was changed.</returns>
public bool QueryRenderTargetFormat(
GraphicsProfile graphicsProfile,
SurfaceFormat format,
DepthFormat depthFormat,
int multiSampleCount,
out SurfaceFormat selectedFormat,
out DepthFormat selectedDepthFormat,
out int selectedMultiSampleCount)
{
selectedFormat = format;
selectedDepthFormat = depthFormat;
selectedMultiSampleCount = multiSampleCount;
// fallback for unsupported renderTarget surface formats.
if (selectedFormat == SurfaceFormat.Alpha8 ||
selectedFormat == SurfaceFormat.NormalizedByte2 ||
selectedFormat == SurfaceFormat.NormalizedByte4 ||
selectedFormat == SurfaceFormat.Dxt1 ||
selectedFormat == SurfaceFormat.Dxt3 ||
selectedFormat == SurfaceFormat.Dxt5 ||
selectedFormat == SurfaceFormat.Dxt1a ||
selectedFormat == SurfaceFormat.Dxt1SRgb ||
selectedFormat == SurfaceFormat.Dxt3SRgb ||
selectedFormat == SurfaceFormat.Dxt5SRgb)
selectedFormat = SurfaceFormat.Color;
return (format == selectedFormat) && (depthFormat == selectedDepthFormat) && (multiSampleCount == selectedMultiSampleCount);
}
/*
public string Description
{
get
{
throw new NotImplementedException();
}
}
public int DeviceId
{
get
{
throw new NotImplementedException();
}
}
public Guid DeviceIdentifier
{
get
{
throw new NotImplementedException();
}
}
public string DeviceName
{
get
{
throw new NotImplementedException();
}
}
public string DriverDll
{
get
{
throw new NotImplementedException();
}
}
public Version DriverVersion
{
get
{
throw new NotImplementedException();
}
}
public bool IsDefaultAdapter
{
get
{
throw new NotImplementedException();
}
}
public bool IsWideScreen
{
get
{
throw new NotImplementedException();
}
}
public IntPtr MonitorHandle
{
get
{
throw new NotImplementedException();
}
}
public int Revision
{
get
{
throw new NotImplementedException();
}
}
public int SubSystemId
{
get
{
throw new NotImplementedException();
}
}
*/
#if DIRECTX
private static readonly Dictionary<SharpDX.DXGI.Format, SurfaceFormat> FormatTranslations = new Dictionary<SharpDX.DXGI.Format, SurfaceFormat>
{
{ SharpDX.DXGI.Format.R8G8B8A8_UNorm, SurfaceFormat.Color },
{ SharpDX.DXGI.Format.B8G8R8A8_UNorm, SurfaceFormat.Color },
{ SharpDX.DXGI.Format.B5G6R5_UNorm, SurfaceFormat.Bgr565 },
};
#endif
public DisplayModeCollection SupportedDisplayModes
{
get
{
bool displayChanged = false;
#if DESKTOPGL
var displayIndex = Sdl.Display.GetWindowDisplayIndex (SdlGameWindow.Instance.Handle);
displayChanged = displayIndex != _displayIndex;
#endif
if (_supportedDisplayModes == null || displayChanged)
{
var modes = new List<DisplayMode>(new[] { CurrentDisplayMode, });
#if DESKTOPGL
_displayIndex = displayIndex;
modes.Clear();
var modeCount = Sdl.Display.GetNumDisplayModes(displayIndex);
for (int i = 0;i < modeCount;i++)
{
Sdl.Display.Mode mode;
Sdl.Display.GetDisplayMode(displayIndex, i, out mode);
// We are only using one format, Color
// mode.Format gets the Color format from SDL
var displayMode = new DisplayMode(mode.Width, mode.Height, SurfaceFormat.Color);
if (!modes.Contains(displayMode))
modes.Add(displayMode);
}
#elif DIRECTX
var dxgiFactory = new SharpDX.DXGI.Factory1();
var adapter = dxgiFactory.GetAdapter(0);
var output = adapter.Outputs[0];
modes.Clear();
foreach (var formatTranslation in FormatTranslations)
{
var displayModes = output.GetDisplayModeList(formatTranslation.Key, 0);
foreach (var displayMode in displayModes)
{
var xnaDisplayMode = new DisplayMode(displayMode.Width, displayMode.Height, formatTranslation.Value);
if (!modes.Contains(xnaDisplayMode))
modes.Add(xnaDisplayMode);
}
}
output.Dispose();
adapter.Dispose();
dxgiFactory.Dispose();
#endif
modes.Sort(delegate(DisplayMode a, DisplayMode b)
{
if (a == b) return 0;
if (a.Format <= b.Format && a.Width <= b.Width && a.Height <= b.Height) return -1;
else return 1;
});
_supportedDisplayModes = new DisplayModeCollection(modes);
}
return _supportedDisplayModes;
}
}
/*
public int VendorId
{
get
{
throw new NotImplementedException();
}
}
*/
/// <summary>
/// Gets a <see cref="System.Boolean"/> indicating whether
/// <see cref="GraphicsAdapter.CurrentDisplayMode"/> has a
/// Width:Height ratio corresponding to a widescreen <see cref="DisplayMode"/>.
/// Common widescreen modes include 16:9, 16:10 and 2:1.
/// </summary>
public bool IsWideScreen
{
get
{
// Common non-widescreen modes: 4:3, 5:4, 1:1
// Common widescreen modes: 16:9, 16:10, 2:1
// XNA does not appear to account for rotated displays on the desktop
const float limit = 4.0f / 3.0f;
var aspect = CurrentDisplayMode.AspectRatio;
return aspect > limit;
}
}
public bool IsProfileSupported(GraphicsProfile graphicsProfile)
{
if(UseReferenceDevice)
return true;
switch(graphicsProfile)
{
case GraphicsProfile.Reach:
return true;
case GraphicsProfile.HiDef:
bool result = true;
// TODO: check adapter capabilities...
return result;
default:
throw new InvalidOperationException();
}
}
#if WINDOWS && !OPENGL
[System.Runtime.InteropServices.DllImport("gdi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true, ExactSpelling = true)]
public static extern int GetDeviceCaps(IntPtr hDC, int nIndex);
private const int HORZRES = 8;
private const int VERTRES = 10;
#endif
}
}
@@ -0,0 +1,180 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.ObjectModel;
namespace Microsoft.Xna.Framework.Graphics
{
public sealed partial class GraphicsAdapter : IDisposable
{
/// <summary>
/// Defines the driver type for graphics adapter. Usable only on DirectX platforms for now.
/// </summary>
public enum DriverType
{
/// <summary>
/// Hardware device been used for rendering. Maximum speed and performance.
/// </summary>
Hardware,
/// <summary>
/// Emulates the hardware device on CPU. Slowly, only for testing.
/// </summary>
Reference,
/// <summary>
/// Useful when <see cref="DriverType.Hardware"/> acceleration does not work.
/// </summary>
FastSoftware
}
private static readonly ReadOnlyCollection<GraphicsAdapter> _adapters;
private DisplayModeCollection _supportedDisplayModes;
private DisplayMode _currentDisplayMode;
static GraphicsAdapter()
{
// NOTE: An adapter is a monitor+device combination, so we expect
// at lease one adapter per connected monitor.
PlatformInitializeAdapters(out _adapters);
// The first adapter is considered the default.
_adapters[0].IsDefaultAdapter = true;
}
public static GraphicsAdapter DefaultAdapter
{
get { return _adapters[0]; }
}
public static ReadOnlyCollection<GraphicsAdapter> Adapters
{
get { return _adapters; }
}
/// <summary>
/// Used to request creation of the reference graphics device,
/// or the default hardware accelerated device (when set to false).
/// </summary>
/// <remarks>
/// This only works on DirectX platforms where a reference graphics
/// device is available and must be defined before the graphics device
/// is created. It defaults to false.
/// </remarks>
public static bool UseReferenceDevice
{
get { return UseDriverType == DriverType.Reference; }
set { UseDriverType = value ? DriverType.Reference : DriverType.Hardware; }
}
/// <summary>
/// Used to request creation of a specific kind of driver.
/// </summary>
/// <remarks>
/// These values only work on DirectX platforms and must be defined before the graphics device
/// is created. <see cref="DriverType.Hardware"/> by default.
/// </remarks>
public static DriverType UseDriverType { get; set; }
/// <summary>
/// Used to request the graphics device should be created with debugging
/// features enabled.
/// </summary>
public static bool UseDebugLayers { get; set; }
public string Description { get; private set; }
public int DeviceId { get; private set; }
public string DeviceName { get; private set; }
public int VendorId { get; private set; }
public bool IsDefaultAdapter { get; private set; }
public IntPtr MonitorHandle { get; private set; }
public int Revision { get; private set; }
public int SubSystemId { get; private set; }
public DisplayModeCollection SupportedDisplayModes
{
get { return _supportedDisplayModes; }
}
public DisplayMode CurrentDisplayMode
{
get { return _currentDisplayMode; }
}
/// <summary>
/// Returns true if the <see cref="GraphicsAdapter.CurrentDisplayMode"/> is widescreen.
/// </summary>
/// <remarks>
/// Common widescreen modes include 16:9, 16:10 and 2:1.
/// </remarks>
public bool IsWideScreen
{
get
{
// Seems like XNA treats aspect ratios above 16:10 as wide screen.
const float minWideScreenAspect = 16.0f / 10.0f;
return CurrentDisplayMode.AspectRatio >= minWideScreenAspect;
}
}
/// <summary>
/// Queries for support of the requested render target format on the adaptor.
/// </summary>
/// <param name="graphicsProfile">The graphics profile.</param>
/// <param name="format">The requested surface format.</param>
/// <param name="depthFormat">The requested depth stencil format.</param>
/// <param name="multiSampleCount">The requested multisample count.</param>
/// <param name="selectedFormat">Set to the best format supported by the adaptor for the requested surface format.</param>
/// <param name="selectedDepthFormat">Set to the best format supported by the adaptor for the requested depth stencil format.</param>
/// <param name="selectedMultiSampleCount">Set to the best count supported by the adaptor for the requested multisample count.</param>
/// <returns>True if the requested format is supported by the adaptor. False if one or more of the values was changed.</returns>
public bool QueryRenderTargetFormat(
GraphicsProfile graphicsProfile,
SurfaceFormat format,
DepthFormat depthFormat,
int multiSampleCount,
out SurfaceFormat selectedFormat,
out DepthFormat selectedDepthFormat,
out int selectedMultiSampleCount)
{
selectedFormat = format;
selectedDepthFormat = depthFormat;
selectedMultiSampleCount = multiSampleCount;
// fallback for unsupported renderTarget surface formats.
if (selectedFormat == SurfaceFormat.Alpha8 ||
selectedFormat == SurfaceFormat.NormalizedByte2 ||
selectedFormat == SurfaceFormat.NormalizedByte4 ||
selectedFormat == SurfaceFormat.Dxt1 ||
selectedFormat == SurfaceFormat.Dxt3 ||
selectedFormat == SurfaceFormat.Dxt5 ||
selectedFormat == SurfaceFormat.Dxt1a ||
selectedFormat == SurfaceFormat.Dxt1SRgb ||
selectedFormat == SurfaceFormat.Dxt3SRgb ||
selectedFormat == SurfaceFormat.Dxt5SRgb)
selectedFormat = SurfaceFormat.Color;
return (format == selectedFormat) && (depthFormat == selectedDepthFormat) && (multiSampleCount == selectedMultiSampleCount);
}
public bool IsProfileSupported(GraphicsProfile graphicsProfile)
{
return PlatformIsProfileSupported(graphicsProfile);
}
public void Dispose()
{
// We don't keep any resources, so we have
// nothing to do... just here for XNA compatibility.
}
}
}
@@ -0,0 +1,56 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
namespace Microsoft.Xna.Framework.Graphics
{
internal partial class GraphicsCapabilities
{
private void PlatformInitialize(GraphicsDevice device)
{
SupportsNonPowerOfTwo = device.GraphicsProfile == GraphicsProfile.HiDef;
SupportsTextureFilterAnisotropic = true;
SupportsDepth24 = true;
SupportsPackedDepthStencil = true;
SupportsDepthNonLinear = false;
SupportsTextureMaxLevel = true;
// Texture compression
SupportsDxt1 = true;
SupportsS3tc = true;
SupportsSRgb = true;
SupportsTextureArrays = device.GraphicsProfile == GraphicsProfile.HiDef;
SupportsDepthClamp = device.GraphicsProfile == GraphicsProfile.HiDef;
SupportsVertexTextures = device.GraphicsProfile == GraphicsProfile.HiDef;
SupportsFloatTextures = true;
SupportsHalfFloatTextures = true;
SupportsNormalized = true;
SupportsInstancing = true;
MaxTextureAnisotropy = (device.GraphicsProfile == GraphicsProfile.Reach) ? 2 : 16;
_maxMultiSampleCount = GetMaxMultiSampleCount(device);
}
private int GetMaxMultiSampleCount(GraphicsDevice device)
{
var format = SharpDXHelper.ToFormat(device.PresentationParameters.BackBufferFormat);
// Find the maximum supported level starting with the game's requested multisampling level
// and halving each time until reaching 0 (meaning no multisample support).
var qualityLevels = 0;
var maxLevel = MultiSampleCountLimit;
while (maxLevel > 0)
{
qualityLevels = device._d3dDevice.CheckMultisampleQualityLevels(format, maxLevel);
if (qualityLevels > 0)
break;
maxLevel /= 2;
}
return maxLevel;
}
}
}
@@ -0,0 +1,120 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
#if OPENGL
using MonoGame.OpenGL;
using GetParamName = MonoGame.OpenGL.GetPName;
#endif
namespace Microsoft.Xna.Framework.Graphics
{
internal partial class GraphicsCapabilities
{
/// <summary>
/// True, if GL_ARB_framebuffer_object is supported; false otherwise.
/// </summary>
internal bool SupportsFramebufferObjectARB { get; private set; }
/// <summary>
/// True, if GL_EXT_framebuffer_object is supported; false otherwise.
/// </summary>
internal bool SupportsFramebufferObjectEXT { get; private set; }
/// <summary>
/// True, if GL_IMG_multisampled_render_to_texture is supported; false otherwise.
/// </summary>
internal bool SupportsFramebufferObjectIMG { get; private set; }
private void PlatformInitialize(GraphicsDevice device)
{
#if GLES
SupportsNonPowerOfTwo = GL.Extensions.Contains("GL_OES_texture_npot") ||
GL.Extensions.Contains("GL_ARB_texture_non_power_of_two") ||
GL.Extensions.Contains("GL_IMG_texture_npot") ||
GL.Extensions.Contains("GL_NV_texture_npot_2D_mipmap");
#else
// Unfortunately non PoT texture support is patchy even on desktop systems and we can't
// rely on the fact that GL2.0+ supposedly supports npot in the core.
// Reference: http://aras-p.info/blog/2012/10/17/non-power-of-two-textures/
SupportsNonPowerOfTwo = device._maxTextureSize >= 8192;
#endif
SupportsTextureFilterAnisotropic = GL.Extensions.Contains("GL_EXT_texture_filter_anisotropic");
#if GLES
SupportsDepth24 = GL.Extensions.Contains("GL_OES_depth24");
SupportsPackedDepthStencil = GL.Extensions.Contains("GL_OES_packed_depth_stencil");
SupportsDepthNonLinear = GL.Extensions.Contains("GL_NV_depth_nonlinear");
SupportsTextureMaxLevel = GL.Extensions.Contains("GL_APPLE_texture_max_level");
#else
SupportsDepth24 = true;
SupportsPackedDepthStencil = true;
SupportsDepthNonLinear = false;
SupportsTextureMaxLevel = true;
#endif
// Texture compression
SupportsS3tc = GL.Extensions.Contains("GL_EXT_texture_compression_s3tc") ||
GL.Extensions.Contains("GL_OES_texture_compression_S3TC") ||
GL.Extensions.Contains("GL_EXT_texture_compression_dxt3") ||
GL.Extensions.Contains("GL_EXT_texture_compression_dxt5");
SupportsDxt1 = SupportsS3tc || GL.Extensions.Contains("GL_EXT_texture_compression_dxt1");
SupportsPvrtc = GL.Extensions.Contains("GL_IMG_texture_compression_pvrtc");
SupportsEtc1 = GL.Extensions.Contains("GL_OES_compressed_ETC1_RGB8_texture");
SupportsAtitc = GL.Extensions.Contains("GL_ATI_texture_compression_atitc") ||
GL.Extensions.Contains("GL_AMD_compressed_ATC_texture");
// Framebuffer objects
#if GLES
SupportsFramebufferObjectARB = GL.BoundApi == GL.RenderApi.ES && (device.glMajorVersion >= 2 || GL.Extensions.Contains("GL_ARB_framebuffer_object")); // always supported on GLES 2.0+
SupportsFramebufferObjectEXT = GL.Extensions.Contains("GL_EXT_framebuffer_object");;
SupportsFramebufferObjectIMG = GL.Extensions.Contains("GL_IMG_multisampled_render_to_texture") |
GL.Extensions.Contains("GL_APPLE_framebuffer_multisample") |
GL.Extensions.Contains("GL_EXT_multisampled_render_to_texture") |
GL.Extensions.Contains("GL_NV_framebuffer_multisample");
#else
// if we're on GL 3.0+, frame buffer extensions are guaranteed to be present, but extensions may be missing
// it is then safe to assume that GL_ARB_framebuffer_object is present so that the standard function are loaded
SupportsFramebufferObjectARB = device.glMajorVersion >= 3 || GL.Extensions.Contains("GL_ARB_framebuffer_object");
SupportsFramebufferObjectEXT = GL.Extensions.Contains("GL_EXT_framebuffer_object");
#endif
// Anisotropic filtering
int anisotropy = 0;
if (SupportsTextureFilterAnisotropic)
{
GL.GetInteger((GetPName)GetParamName.MaxTextureMaxAnisotropyExt, out anisotropy);
GraphicsExtensions.CheckGLError();
}
MaxTextureAnisotropy = anisotropy;
// sRGB
#if GLES
SupportsSRgb = GL.Extensions.Contains("GL_EXT_sRGB");
SupportsFloatTextures = GL.BoundApi == GL.RenderApi.ES && (device.glMajorVersion >= 3 || GL.Extensions.Contains("GL_EXT_color_buffer_float"));
SupportsHalfFloatTextures = GL.BoundApi == GL.RenderApi.ES && (device.glMajorVersion >= 3 || GL.Extensions.Contains("GL_EXT_color_buffer_half_float"));
SupportsNormalized = GL.BoundApi == GL.RenderApi.ES && (device.glMajorVersion >= 3 && GL.Extensions.Contains("GL_EXT_texture_norm16"));
#else
SupportsSRgb = GL.Extensions.Contains("GL_EXT_texture_sRGB") && GL.Extensions.Contains("GL_EXT_framebuffer_sRGB");
SupportsFloatTextures = GL.BoundApi == GL.RenderApi.GL && (device.glMajorVersion >= 3 || GL.Extensions.Contains("GL_ARB_texture_float"));
SupportsHalfFloatTextures = GL.BoundApi == GL.RenderApi.GL && (device.glMajorVersion >= 3 || GL.Extensions.Contains("GL_ARB_half_float_pixel"));;
SupportsNormalized = GL.BoundApi == GL.RenderApi.GL && (device.glMajorVersion >= 3 || GL.Extensions.Contains("GL_EXT_texture_norm16"));;
#endif
// TODO: Implement OpenGL support for texture arrays
// once we can author shaders that use texture arrays.
SupportsTextureArrays = false;
SupportsDepthClamp = GL.Extensions.Contains("GL_ARB_depth_clamp");
SupportsVertexTextures = false; // For now, until we implement vertex textures in OpenGL.
GL.GetInteger((GetPName)GetParamName.MaxSamples, out _maxMultiSampleCount);
SupportsInstancing = GL.VertexAttribDivisor != null;
}
}
}
@@ -0,0 +1,17 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Graphics
{
internal partial class GraphicsCapabilities
{
private void PlatformInitialize(GraphicsDevice device)
{
throw new NotImplementedException();
}
}
}
@@ -0,0 +1,120 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// Provides information about the capabilities of the
/// current graphics device. A very useful thread for investigating GL extenion names
/// http://stackoverflow.com/questions/3881197/opengl-es-2-0-extensions-on-android-devices
/// </summary>
internal partial class GraphicsCapabilities
{
internal void Initialize(GraphicsDevice device)
{
PlatformInitialize(device);
}
/// <summary>
/// Whether the device fully supports non power-of-two textures, including
/// mip maps and wrap modes other than CLAMP_TO_EDGE
/// </summary>
internal bool SupportsNonPowerOfTwo { get; private set; }
/// <summary>
/// Whether the device supports anisotropic texture filtering
/// </summary>
internal bool SupportsTextureFilterAnisotropic { get; private set; }
internal bool SupportsDepth24 { get; private set; }
internal bool SupportsPackedDepthStencil { get; private set; }
internal bool SupportsDepthNonLinear { get; private set; }
/// <summary>
/// Gets the support for DXT1
/// </summary>
internal bool SupportsDxt1 { get; private set; }
/// <summary>
/// Gets the support for S3TC (DXT1, DXT3, DXT5)
/// </summary>
internal bool SupportsS3tc { get; private set; }
/// <summary>
/// Gets the support for PVRTC
/// </summary>
internal bool SupportsPvrtc { get; private set; }
/// <summary>
/// Gets the support for ETC1
/// </summary>
internal bool SupportsEtc1 { get; private set; }
/// <summary>
/// Gets the support for ATITC
/// </summary>
internal bool SupportsAtitc { get; private set; }
internal bool SupportsTextureMaxLevel { get; private set; }
/// <summary>
/// True, if sRGB is supported. On Direct3D platforms, this is always <code>true</code>.
/// On OpenGL platforms, it is <code>true</code> if both framebuffer sRGB
/// and texture sRGB are supported.
/// </summary>
internal bool SupportsSRgb { get; private set; }
internal bool SupportsTextureArrays { get; private set; }
internal bool SupportsDepthClamp { get; private set; }
internal bool SupportsVertexTextures { get; private set; }
/// <summary>
/// True, if the underlying platform supports floating point textures.
/// For Direct3D platforms this is always <code>true</code>.
/// For OpenGL Desktop platforms it is always <code>true</code>.
/// For OpenGL Mobile platforms it requires `GL_EXT_color_buffer_float`.
/// If the requested format is not supported an <code>NotSupportedException</code>
/// will be thrown.
/// </summary>
internal bool SupportsFloatTextures { get; private set; }
/// <summary>
/// True, if the underlying platform supports half floating point textures.
/// For Direct3D platforms this is always <code>true</code>.
/// For OpenGL Desktop platforms it is always <code>true</code>.
/// For OpenGL Mobile platforms it requires `GL_EXT_color_buffer_half_float`.
/// If the requested format is not supported an <code>NotSupportedException</code>
/// will be thrown.
/// </summary>
internal bool SupportsHalfFloatTextures { get; private set; }
internal bool SupportsNormalized { get; private set; }
/// <summary>
/// Gets the max texture anisotropy. This value typically lies
/// between 0 and 16, where 0 means anisotropic filtering is not
/// supported.
/// </summary>
internal int MaxTextureAnisotropy { get; private set; }
// The highest possible MSCount
private const int MultiSampleCountLimit = 32;
private int _maxMultiSampleCount;
internal int MaxMultiSampleCount
{
get { return _maxMultiSampleCount; }
}
internal bool SupportsInstancing { get; private set; }
}
}
@@ -0,0 +1,94 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using Microsoft.Xna.Framework.Graphics;
namespace MonoGame.OpenGL
{
internal class GraphicsContext : IGraphicsContext, IDisposable
{
private IntPtr _context;
private IntPtr _winHandle;
private bool _disposed;
public int SwapInterval
{
get
{
return Sdl.GL.GetSwapInterval();
}
set
{
Sdl.GL.SetSwapInterval(value);
}
}
public bool IsDisposed
{
get { return _disposed; }
}
public bool IsCurrent
{
get { return true; }
}
public GraphicsContext(IWindowInfo info)
{
if (_disposed)
return;
SetWindowHandle(info);
_context = Sdl.GL.CreateContext(_winHandle);
// GL entry points must be loaded after the GL context creation, otherwise some Windows drivers will return only GL 1.3 compatible functions
try
{
OpenGL.GL.LoadEntryPoints();
}
catch (EntryPointNotFoundException)
{
throw new PlatformNotSupportedException(
"MonoGame requires OpenGL 3.0 compatible drivers, or either ARB_framebuffer_object or EXT_framebuffer_object extensions. " +
"Try updating your graphics drivers.");
}
}
public void MakeCurrent(IWindowInfo info)
{
if (_disposed)
return;
SetWindowHandle(info);
Sdl.GL.MakeCurrent(_winHandle, _context);
}
public void SwapBuffers()
{
if (_disposed)
return;
Sdl.GL.SwapWindow(_winHandle);
}
public void Dispose()
{
if (_disposed)
return;
GraphicsDevice.DisposeContext(_context);
_context = IntPtr.Zero;
_disposed = true;
}
private void SetWindowHandle(IWindowInfo info)
{
if (info == null)
_winHandle = IntPtr.Zero;
else
_winHandle = info.Handle;
}
}
}
@@ -0,0 +1,15 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
namespace Microsoft.Xna.Framework.Graphics
{
public partial class GraphicsDebug
{
private bool PlatformTryDequeueMessage(out GraphicsDebugMessage message)
{
message = null;
return false;
}
}
}
@@ -0,0 +1,82 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using SharpDX.Direct3D11;
using System.Collections.Generic;
namespace Microsoft.Xna.Framework.Graphics
{
public partial class GraphicsDebug
{
private readonly GraphicsDevice _device;
private readonly InfoQueue _infoQueue;
private readonly Queue<GraphicsDebugMessage> _cachedMessages;
private bool _hasPushedFilters = false;
public GraphicsDebug(GraphicsDevice device)
{
_device = device;
_infoQueue = _device._d3dDevice.QueryInterfaceOrNull<InfoQueue>();
_cachedMessages = new Queue<GraphicsDebugMessage>();
if (_infoQueue != null)
{
_infoQueue.PushEmptyRetrievalFilter();
_infoQueue.PushEmptyStorageFilter();
_hasPushedFilters = true;
}
}
private bool PlatformTryDequeueMessage(out GraphicsDebugMessage message)
{
if (_infoQueue == null)
{
message = null;
return false;
}
if (!_hasPushedFilters)
{
_infoQueue.PushEmptyRetrievalFilter();
_infoQueue.PushEmptyStorageFilter();
_hasPushedFilters = true;
}
if (_cachedMessages.Count > 0)
{
message = _cachedMessages.Dequeue();
return true;
}
if (_infoQueue.NumStoredMessagesAllowedByRetrievalFilter > 0)
{
// Grab all current messages and put them in the cached messages queue.
for (var i = 0; i < _infoQueue.NumStoredMessagesAllowedByRetrievalFilter; i++)
{
var dxMessage = _infoQueue.GetMessage(i);
_cachedMessages.Enqueue(new GraphicsDebugMessage
{
Message = dxMessage.Description,
Id = (int)dxMessage.Id,
IdName = dxMessage.Id.ToString(),
Severity = dxMessage.Severity.ToString(),
Category = dxMessage.Category.ToString()
});
}
_infoQueue.ClearStoredMessages();
}
if (_cachedMessages.Count > 0)
{
message = _cachedMessages.Dequeue();
return true;
}
// No messages to grab from DirectX.
message = null;
return false;
}
}
}
@@ -0,0 +1,24 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
namespace Microsoft.Xna.Framework.Graphics
{
public partial class GraphicsDebug
{
/// <summary>
/// Attempt to dequeue a debugging message from the graphics subsystem.
/// </summary>
/// <remarks>
/// When running on a graphics device with debugging enabled, this allows you to retrieve
/// subsystem-specific (e.g. DirectX, OpenGL, etc.) debugging messages including information
/// about improper usage of shaders and APIs.
/// </remarks>
/// <param name="message">The graphics debugging message if retrieved, null otherwise.</param>
/// <returns>True if a graphics debugging message was retrieved, false otherwise.</returns>
public bool TryDequeueMessage(out GraphicsDebugMessage message)
{
return PlatformTryDequeueMessage(out message);
}
}
}
@@ -0,0 +1,19 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
namespace Microsoft.Xna.Framework.Graphics
{
public class GraphicsDebugMessage
{
public string Message { get; set; }
public string Severity { get; set; }
public int Id { get; set; }
public string IdName { get; set; }
public string Category { get; set; }
}
}
@@ -0,0 +1,175 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using MonoGame.OpenGL;
using System.Security;
namespace Microsoft.Xna.Framework.Graphics
{
// ARB_framebuffer_object implementation
partial class GraphicsDevice
{
internal class FramebufferHelper
{
private static FramebufferHelper _instance;
public static FramebufferHelper Create(GraphicsDevice gd)
{
if (gd.GraphicsCapabilities.SupportsFramebufferObjectARB || gd.GraphicsCapabilities.SupportsFramebufferObjectEXT)
{
_instance = new FramebufferHelper(gd);
}
else
{
throw new PlatformNotSupportedException(
"MonoGame requires either ARB_framebuffer_object or EXT_framebuffer_object." +
"Try updating your graphics drivers.");
}
return _instance;
}
public static FramebufferHelper Get()
{
if (_instance == null)
throw new InvalidOperationException("The FramebufferHelper has not been created yet!");
return _instance;
}
public bool SupportsInvalidateFramebuffer { get; private set; }
public bool SupportsBlitFramebuffer { get; private set; }
internal FramebufferHelper(GraphicsDevice graphicsDevice)
{
this.SupportsBlitFramebuffer = GL.BlitFramebuffer != null;
this.SupportsInvalidateFramebuffer = GL.InvalidateFramebuffer != null;
}
internal virtual void GenRenderbuffer(out int renderbuffer)
{
GL.GenRenderbuffers(1, out renderbuffer);
GraphicsExtensions.CheckGLError();
}
internal virtual void BindRenderbuffer(int renderbuffer)
{
GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, renderbuffer);
GraphicsExtensions.CheckGLError();
}
internal virtual void DeleteRenderbuffer(int renderbuffer)
{
GL.DeleteRenderbuffers(1, ref renderbuffer);
GraphicsExtensions.CheckGLError();
}
internal virtual void RenderbufferStorageMultisample(int samples, int internalFormat, int width, int height)
{
if (samples > 0 && GL.RenderbufferStorageMultisample != null)
GL.RenderbufferStorageMultisample(RenderbufferTarget.RenderbufferExt, samples, (RenderbufferStorage)internalFormat, width, height);
else
GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, (RenderbufferStorage)internalFormat, width, height);
GraphicsExtensions.CheckGLError();
}
internal virtual void GenFramebuffer(out int framebuffer)
{
GL.GenFramebuffers(1, out framebuffer);
GraphicsExtensions.CheckGLError();
}
internal virtual void BindFramebuffer(int framebuffer)
{
GL.BindFramebuffer(FramebufferTarget.Framebuffer, framebuffer);
GraphicsExtensions.CheckGLError();
}
internal virtual void BindReadFramebuffer(int readFramebuffer)
{
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, readFramebuffer);
GraphicsExtensions.CheckGLError();
}
static readonly FramebufferAttachment [] FramebufferAttachements = {
FramebufferAttachment.ColorAttachment0,
FramebufferAttachment.DepthAttachment,
FramebufferAttachment.StencilAttachment,
};
internal virtual void InvalidateDrawFramebuffer()
{
Debug.Assert(this.SupportsInvalidateFramebuffer);
GL.InvalidateFramebuffer (FramebufferTarget.Framebuffer, 3, FramebufferAttachements);
}
internal virtual void InvalidateReadFramebuffer()
{
Debug.Assert(this.SupportsInvalidateFramebuffer);
GL.InvalidateFramebuffer(FramebufferTarget.Framebuffer, 3, FramebufferAttachements);
}
internal virtual void DeleteFramebuffer(int framebuffer)
{
GL.DeleteFramebuffers(1, ref framebuffer);
GraphicsExtensions.CheckGLError();
}
internal virtual void FramebufferTexture2D(int attachement, int target, int texture, int level = 0, int samples = 0)
{
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, (FramebufferAttachment)attachement, (TextureTarget)target, texture, level);
GraphicsExtensions.CheckGLError();
}
internal virtual void FramebufferRenderbuffer(int attachement, int renderbuffer, int level = 0)
{
GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, (FramebufferAttachment)attachement, RenderbufferTarget.Renderbuffer, renderbuffer);
GraphicsExtensions.CheckGLError();
}
internal virtual void GenerateMipmap(int target)
{
GL.GenerateMipmap((GenerateMipmapTarget)target);
GraphicsExtensions.CheckGLError();
}
internal virtual void BlitFramebuffer(int iColorAttachment, int width, int height)
{
GL.ReadBuffer(ReadBufferMode.ColorAttachment0 + iColorAttachment);
GraphicsExtensions.CheckGLError();
GL.DrawBuffer(DrawBufferMode.ColorAttachment0 + iColorAttachment);
GraphicsExtensions.CheckGLError();
GL.BlitFramebuffer(0, 0, width, height, 0, 0, width, height, ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Nearest);
GraphicsExtensions.CheckGLError();
}
internal virtual void CheckFramebufferStatus()
{
var status = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);
if (status != FramebufferErrorCode.FramebufferComplete)
{
string message = "Framebuffer Incomplete.";
switch (status)
{
case FramebufferErrorCode.FramebufferIncompleteAttachment: message = "Not all framebuffer attachment points are framebuffer attachment complete."; break;
case FramebufferErrorCode.FramebufferIncompleteMissingAttachment: message = "No images are attached to the framebuffer."; break;
case FramebufferErrorCode.FramebufferUnsupported: message = "The combination of internal formats of the attached images violates an implementation-dependent set of restrictions."; break;
case FramebufferErrorCode.FramebufferIncompleteMultisample: message = "Not all attached images have the same number of samples."; break;
}
throw new InvalidOperationException(message);
}
}
}
}
}
@@ -0,0 +1,118 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input.Touch;
using System.Diagnostics;
namespace Microsoft.Xna.Framework.Graphics
{
using MonoGame.Web;
public partial class GraphicsDevice
{
private void PlatformSetup()
{
}
private void PlatformInitialize()
{
}
internal void OnPresentationChanged()
{
}
public void PlatformClear(ClearOptions options, Vector4 color, float depth, int stencil)
{
WebGL.gl.enable(WebGL.gl.DEPTH_TEST);
WebGL.gl.depthFunc(WebGL.gl.LEQUAL);
WebGL.gl.clearColor(color.X, color.Y, color.Z, color.W);
WebGL.gl.clear(WebGL.gl.COLOR_BUFFER_BIT | WebGL.gl.DEPTH_BUFFER_BIT);
}
private void PlatformDispose()
{
}
public void PlatformPresent()
{
}
private void PlatformSetViewport(ref Viewport value)
{
}
private void PlatformApplyDefaultRenderTarget()
{
}
internal void PlatformResolveRenderTargets()
{
// Resolving MSAA render targets should be done here.
}
private IRenderTarget PlatformApplyRenderTargets()
{
return null;
}
internal void PlatformBeginApplyState()
{
}
private void PlatformApplyBlend()
{
}
internal void PlatformApplyState(bool applyShaders)
{
}
private void PlatformDrawIndexedPrimitives(PrimitiveType primitiveType, int baseVertex, int startIndex, int primitiveCount)
{
}
private void PlatformDrawUserPrimitives<T>(PrimitiveType primitiveType, T[] vertexData, int vertexOffset, VertexDeclaration vertexDeclaration, int vertexCount) where T : struct
{
}
private void PlatformDrawPrimitives(PrimitiveType primitiveType, int vertexStart, int vertexCount)
{
}
private void PlatformDrawUserIndexedPrimitives<T>(PrimitiveType primitiveType, T[] vertexData, int vertexOffset, int numVertices, short[] indexData, int indexOffset, int primitiveCount, VertexDeclaration vertexDeclaration) where T : struct
{
}
private void PlatformDrawUserIndexedPrimitives<T>(PrimitiveType primitiveType, T[] vertexData, int vertexOffset, int numVertices, int[] indexData, int indexOffset, int primitiveCount, VertexDeclaration vertexDeclaration) where T : struct
{
}
private void PlatformDrawInstancedPrimitives(PrimitiveType primitiveType, int baseVertex, int startIndex, int primitiveCount, int instanceCount)
{
}
private void PlatformGetBackBufferData<T>(Rectangle? rect, T[] data, int startIndex, int count) where T : struct
{
throw new NotImplementedException();
}
private static Rectangle PlatformGetTitleSafeArea(int x, int y, int width, int height)
{
return new Rectangle(x, y, width, height);
}
internal void PlatformSetMultiSamplingToMaximum(PresentationParameters presentationParameters, out int quality)
{
presentationParameters.MultiSampleCount = 0;
quality = 0;
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,26 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// Describes the status of the <see cref="GraphicsDevice"/>.
/// </summary>
public enum GraphicsDeviceStatus
{
/// <summary>
/// The device is normal.
/// </summary>
Normal,
/// <summary>
/// The device has been lost.
/// </summary>
Lost,
/// <summary>
/// The device has not been reset.
/// </summary>
NotReset
}
}
@@ -0,0 +1,947 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Diagnostics;
#if OPENGL
#if DESKTOPGL || GLES
using MonoGame.OpenGL;
using GLPixelFormat = MonoGame.OpenGL.PixelFormat;
using PixelFormat = MonoGame.OpenGL.PixelFormat;
#elif ANGLE
using OpenTK.Graphics;
#endif
#endif
namespace Microsoft.Xna.Framework.Graphics
{
static class GraphicsExtensions
{
#if OPENGL
public static int OpenGLNumberOfElements(this VertexElementFormat elementFormat)
{
switch (elementFormat)
{
case VertexElementFormat.Single:
return 1;
case VertexElementFormat.Vector2:
return 2;
case VertexElementFormat.Vector3:
return 3;
case VertexElementFormat.Vector4:
return 4;
case VertexElementFormat.Color:
return 4;
case VertexElementFormat.Byte4:
return 4;
case VertexElementFormat.Short2:
return 2;
case VertexElementFormat.Short4:
return 4;
case VertexElementFormat.NormalizedShort2:
return 2;
case VertexElementFormat.NormalizedShort4:
return 4;
case VertexElementFormat.HalfVector2:
return 2;
case VertexElementFormat.HalfVector4:
return 4;
}
throw new ArgumentException();
}
public static VertexPointerType OpenGLVertexPointerType(this VertexElementFormat elementFormat)
{
switch (elementFormat)
{
case VertexElementFormat.Single:
return VertexPointerType.Float;
case VertexElementFormat.Vector2:
return VertexPointerType.Float;
case VertexElementFormat.Vector3:
return VertexPointerType.Float;
case VertexElementFormat.Vector4:
return VertexPointerType.Float;
case VertexElementFormat.Color:
return VertexPointerType.Short;
case VertexElementFormat.Byte4:
return VertexPointerType.Short;
case VertexElementFormat.Short2:
return VertexPointerType.Short;
case VertexElementFormat.Short4:
return VertexPointerType.Short;
case VertexElementFormat.NormalizedShort2:
return VertexPointerType.Short;
case VertexElementFormat.NormalizedShort4:
return VertexPointerType.Short;
case VertexElementFormat.HalfVector2:
return VertexPointerType.Float;
case VertexElementFormat.HalfVector4:
return VertexPointerType.Float;
}
throw new ArgumentException();
}
public static VertexAttribPointerType OpenGLVertexAttribPointerType(this VertexElementFormat elementFormat)
{
switch (elementFormat)
{
case VertexElementFormat.Single:
return VertexAttribPointerType.Float;
case VertexElementFormat.Vector2:
return VertexAttribPointerType.Float;
case VertexElementFormat.Vector3:
return VertexAttribPointerType.Float;
case VertexElementFormat.Vector4:
return VertexAttribPointerType.Float;
case VertexElementFormat.Color:
return VertexAttribPointerType.UnsignedByte;
case VertexElementFormat.Byte4:
return VertexAttribPointerType.UnsignedByte;
case VertexElementFormat.Short2:
return VertexAttribPointerType.Short;
case VertexElementFormat.Short4:
return VertexAttribPointerType.Short;
case VertexElementFormat.NormalizedShort2:
return VertexAttribPointerType.Short;
case VertexElementFormat.NormalizedShort4:
return VertexAttribPointerType.Short;
#if WINDOWS || DESKTOPGL
case VertexElementFormat.HalfVector2:
return VertexAttribPointerType.HalfFloat;
case VertexElementFormat.HalfVector4:
return VertexAttribPointerType.HalfFloat;
#endif
}
throw new ArgumentException();
}
public static bool OpenGLVertexAttribNormalized(this VertexElement element)
{
// TODO: This may or may not be the right behavor.
//
// For instance the VertexElementFormat.Byte4 format is not supposed
// to be normalized, but this line makes it so.
//
// The question is in MS XNA are types normalized based on usage or
// normalized based to their format?
//
if (element.VertexElementUsage == VertexElementUsage.Color)
return true;
switch (element.VertexElementFormat)
{
case VertexElementFormat.NormalizedShort2:
case VertexElementFormat.NormalizedShort4:
return true;
default:
return false;
}
}
public static ColorPointerType OpenGLColorPointerType(this VertexElementFormat elementFormat)
{
switch (elementFormat)
{
case VertexElementFormat.Single:
return ColorPointerType.Float;
case VertexElementFormat.Vector2:
return ColorPointerType.Float;
case VertexElementFormat.Vector3:
return ColorPointerType.Float;
case VertexElementFormat.Vector4:
return ColorPointerType.Float;
case VertexElementFormat.Color:
return ColorPointerType.UnsignedByte;
case VertexElementFormat.Byte4:
return ColorPointerType.UnsignedByte;
case VertexElementFormat.Short2:
return ColorPointerType.Short;
case VertexElementFormat.Short4:
return ColorPointerType.Short;
case VertexElementFormat.NormalizedShort2:
return ColorPointerType.UnsignedShort;
case VertexElementFormat.NormalizedShort4:
return ColorPointerType.UnsignedShort;
#if MONOMAC
case VertexElementFormat.HalfVector2:
return ColorPointerType.HalfFloat;
case VertexElementFormat.HalfVector4:
return ColorPointerType.HalfFloat;
#endif
}
throw new ArgumentException();
}
public static NormalPointerType OpenGLNormalPointerType(this VertexElementFormat elementFormat)
{
switch (elementFormat)
{
case VertexElementFormat.Single:
return NormalPointerType.Float;
case VertexElementFormat.Vector2:
return NormalPointerType.Float;
case VertexElementFormat.Vector3:
return NormalPointerType.Float;
case VertexElementFormat.Vector4:
return NormalPointerType.Float;
case VertexElementFormat.Color:
return NormalPointerType.Byte;
case VertexElementFormat.Byte4:
return NormalPointerType.Byte;
case VertexElementFormat.Short2:
return NormalPointerType.Short;
case VertexElementFormat.Short4:
return NormalPointerType.Short;
case VertexElementFormat.NormalizedShort2:
return NormalPointerType.Short;
case VertexElementFormat.NormalizedShort4:
return NormalPointerType.Short;
#if MONOMAC
case VertexElementFormat.HalfVector2:
return NormalPointerType.HalfFloat;
case VertexElementFormat.HalfVector4:
return NormalPointerType.HalfFloat;
#endif
}
throw new ArgumentException();
}
public static TexCoordPointerType OpenGLTexCoordPointerType(this VertexElementFormat elementFormat)
{
switch (elementFormat)
{
case VertexElementFormat.Single:
return TexCoordPointerType.Float;
case VertexElementFormat.Vector2:
return TexCoordPointerType.Float;
case VertexElementFormat.Vector3:
return TexCoordPointerType.Float;
case VertexElementFormat.Vector4:
return TexCoordPointerType.Float;
case VertexElementFormat.Color:
return TexCoordPointerType.Float;
case VertexElementFormat.Byte4:
return TexCoordPointerType.Float;
case VertexElementFormat.Short2:
return TexCoordPointerType.Short;
case VertexElementFormat.Short4:
return TexCoordPointerType.Short;
case VertexElementFormat.NormalizedShort2:
return TexCoordPointerType.Short;
case VertexElementFormat.NormalizedShort4:
return TexCoordPointerType.Short;
#if MONOMAC
case VertexElementFormat.HalfVector2:
return TexCoordPointerType.HalfFloat;
case VertexElementFormat.HalfVector4:
return TexCoordPointerType.HalfFloat;
#endif
}
throw new ArgumentException();
}
public static BlendEquationMode GetBlendEquationMode (this BlendFunction function)
{
switch (function) {
case BlendFunction.Add:
return BlendEquationMode.FuncAdd;
#if WINDOWS || DESKTOPGL || IOS
case BlendFunction.Max:
return BlendEquationMode.Max;
case BlendFunction.Min:
return BlendEquationMode.Min;
#endif
case BlendFunction.ReverseSubtract:
return BlendEquationMode.FuncReverseSubtract;
case BlendFunction.Subtract:
return BlendEquationMode.FuncSubtract;
default:
throw new ArgumentException();
}
}
public static BlendingFactorSrc GetBlendFactorSrc (this Blend blend)
{
switch (blend) {
case Blend.BlendFactor:
return BlendingFactorSrc.ConstantColor;
case Blend.DestinationAlpha:
return BlendingFactorSrc.DstAlpha;
case Blend.DestinationColor:
return BlendingFactorSrc.DstColor;
case Blend.InverseBlendFactor:
return BlendingFactorSrc.OneMinusConstantColor;
case Blend.InverseDestinationAlpha:
return BlendingFactorSrc.OneMinusDstAlpha;
case Blend.InverseDestinationColor:
return BlendingFactorSrc.OneMinusDstColor;
case Blend.InverseSourceAlpha:
return BlendingFactorSrc.OneMinusSrcAlpha;
case Blend.InverseSourceColor:
return BlendingFactorSrc.OneMinusSrcColor;
case Blend.One:
return BlendingFactorSrc.One;
case Blend.SourceAlpha:
return BlendingFactorSrc.SrcAlpha;
case Blend.SourceAlphaSaturation:
return BlendingFactorSrc.SrcAlphaSaturate;
case Blend.SourceColor:
return BlendingFactorSrc.SrcColor;
case Blend.Zero:
return BlendingFactorSrc.Zero;
default:
throw new ArgumentOutOfRangeException("blend", "The specified blend function is not implemented.");
}
}
public static BlendingFactorDest GetBlendFactorDest (this Blend blend)
{
switch (blend) {
case Blend.BlendFactor:
return BlendingFactorDest.ConstantColor;
case Blend.DestinationAlpha:
return BlendingFactorDest.DstAlpha;
case Blend.DestinationColor:
return BlendingFactorDest.DstColor;
case Blend.InverseBlendFactor:
return BlendingFactorDest.OneMinusConstantColor;
case Blend.InverseDestinationAlpha:
return BlendingFactorDest.OneMinusDstAlpha;
case Blend.InverseDestinationColor:
return BlendingFactorDest.OneMinusDstColor;
case Blend.InverseSourceAlpha:
return BlendingFactorDest.OneMinusSrcAlpha;
case Blend.InverseSourceColor:
return BlendingFactorDest.OneMinusSrcColor;
case Blend.One:
return BlendingFactorDest.One;
case Blend.SourceAlpha:
return BlendingFactorDest.SrcAlpha;
case Blend.SourceAlphaSaturation:
return BlendingFactorDest.SrcAlphaSaturate;
case Blend.SourceColor:
return BlendingFactorDest.SrcColor;
case Blend.Zero:
return BlendingFactorDest.Zero;
default:
throw new ArgumentOutOfRangeException("blend", "The specified blend function is not implemented.");
}
}
public static DepthFunction GetDepthFunction(this CompareFunction compare)
{
switch (compare)
{
default:
case CompareFunction.Always:
return DepthFunction.Always;
case CompareFunction.Equal:
return DepthFunction.Equal;
case CompareFunction.Greater:
return DepthFunction.Greater;
case CompareFunction.GreaterEqual:
return DepthFunction.Gequal;
case CompareFunction.Less:
return DepthFunction.Less;
case CompareFunction.LessEqual:
return DepthFunction.Lequal;
case CompareFunction.Never:
return DepthFunction.Never;
case CompareFunction.NotEqual:
return DepthFunction.Notequal;
}
}
#if WINDOWS || DESKTOPGL || ANGLE
/// <summary>
/// Convert a <see cref="SurfaceFormat"/> to an OpenTK.Graphics.ColorFormat.
/// This is used for setting up the backbuffer format of the OpenGL context.
/// </summary>
/// <returns>An OpenTK.Graphics.ColorFormat instance.</returns>
/// <param name="format">The <see cref="SurfaceFormat"/> to convert.</param>
internal static ColorFormat GetColorFormat(this SurfaceFormat format)
{
switch (format)
{
case SurfaceFormat.Alpha8:
return new ColorFormat(0, 0, 0, 8);
case SurfaceFormat.Bgr565:
return new ColorFormat(5, 6, 5, 0);
case SurfaceFormat.Bgra4444:
return new ColorFormat(4, 4, 4, 4);
case SurfaceFormat.Bgra5551:
return new ColorFormat(5, 5, 5, 1);
case SurfaceFormat.Bgr32:
return new ColorFormat(8, 8, 8, 0);
case SurfaceFormat.Bgra32:
case SurfaceFormat.Color:
case SurfaceFormat.ColorSRgb:
return new ColorFormat(8, 8, 8, 8);
case SurfaceFormat.Rgba1010102:
return new ColorFormat(10, 10, 10, 2);
default:
// Floating point backbuffers formats could be implemented
// but they are not typically used on the backbuffer. In
// those cases it is better to create a render target instead.
throw new NotSupportedException();
}
}
/// <summary>
/// Converts <see cref="PresentInterval"/> to OpenGL swap interval.
/// </summary>
/// <returns>A value according to EXT_swap_control</returns>
/// <param name="interval">The <see cref="PresentInterval"/> to convert.</param>
internal static int GetSwapInterval(this PresentInterval interval)
{
// See http://www.opengl.org/registry/specs/EXT/swap_control.txt
// and https://www.opengl.org/registry/specs/EXT/glx_swap_control_tear.txt
// OpenTK checks for EXT_swap_control_tear:
// if supported, a swap interval of -1 enables adaptive vsync;
// otherwise -1 is converted to 1 (vsync enabled.)
switch (interval)
{
case PresentInterval.Immediate:
return 0;
case PresentInterval.One:
return 1;
case PresentInterval.Two:
return 2;
case PresentInterval.Default:
default:
return -1;
}
}
#endif
const SurfaceFormat InvalidFormat = (SurfaceFormat)int.MaxValue;
internal static void GetGLFormat (this SurfaceFormat format,
GraphicsDevice graphicsDevice,
out PixelInternalFormat glInternalFormat,
out PixelFormat glFormat,
out PixelType glType)
{
glInternalFormat = PixelInternalFormat.Rgba;
glFormat = PixelFormat.Rgba;
glType = PixelType.UnsignedByte;
var supportsSRgb = graphicsDevice.GraphicsCapabilities.SupportsSRgb;
var supportsS3tc = graphicsDevice.GraphicsCapabilities.SupportsS3tc;
var supportsPvrtc = graphicsDevice.GraphicsCapabilities.SupportsPvrtc;
var supportsEtc1 = graphicsDevice.GraphicsCapabilities.SupportsEtc1;
var supportsAtitc = graphicsDevice.GraphicsCapabilities.SupportsAtitc;
var supportsFloat = graphicsDevice.GraphicsCapabilities.SupportsFloatTextures;
var supportsHalfFloat = graphicsDevice.GraphicsCapabilities.SupportsHalfFloatTextures;
var supportsNormalized = graphicsDevice.GraphicsCapabilities.SupportsNormalized;
var isGLES2 = GL.BoundApi == GL.RenderApi.ES && graphicsDevice.glMajorVersion == 2;
switch (format) {
case SurfaceFormat.Color:
glInternalFormat = PixelInternalFormat.Rgba;
glFormat = PixelFormat.Rgba;
glType = PixelType.UnsignedByte;
break;
case SurfaceFormat.ColorSRgb:
if (!supportsSRgb)
goto case SurfaceFormat.Color;
glInternalFormat = PixelInternalFormat.Srgb;
glFormat = PixelFormat.Rgba;
glType = PixelType.UnsignedByte;
break;
case SurfaceFormat.Bgr565:
glInternalFormat = PixelInternalFormat.Rgb;
glFormat = PixelFormat.Rgb;
glType = PixelType.UnsignedShort565;
break;
case SurfaceFormat.Bgra4444:
#if IOS || ANDROID
glInternalFormat = PixelInternalFormat.Rgba;
#else
glInternalFormat = PixelInternalFormat.Rgba4;
#endif
glFormat = PixelFormat.Rgba;
glType = PixelType.UnsignedShort4444;
break;
case SurfaceFormat.Bgra5551:
glInternalFormat = PixelInternalFormat.Rgba;
glFormat = PixelFormat.Rgba;
glType = PixelType.UnsignedShort5551;
break;
case SurfaceFormat.Alpha8:
glInternalFormat = PixelInternalFormat.Luminance;
glFormat = PixelFormat.Luminance;
glType = PixelType.UnsignedByte;
break;
case SurfaceFormat.Dxt1:
if (!supportsS3tc)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.CompressedRgbS3tcDxt1Ext;
glFormat = (PixelFormat)GLPixelFormat.CompressedTextureFormats;
break;
case SurfaceFormat.Dxt1SRgb:
if (!supportsSRgb)
goto case SurfaceFormat.Dxt1;
glInternalFormat = PixelInternalFormat.CompressedSrgbS3tcDxt1Ext;
glFormat = (PixelFormat)GLPixelFormat.CompressedTextureFormats;
break;
case SurfaceFormat.Dxt1a:
if (!supportsS3tc)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt1Ext;
glFormat = (PixelFormat)GLPixelFormat.CompressedTextureFormats;
break;
case SurfaceFormat.Dxt3:
if (!supportsS3tc)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt3Ext;
glFormat = (PixelFormat)GLPixelFormat.CompressedTextureFormats;
break;
case SurfaceFormat.Dxt3SRgb:
if (!supportsSRgb)
goto case SurfaceFormat.Dxt3;
glInternalFormat = PixelInternalFormat.CompressedSrgbAlphaS3tcDxt3Ext;
glFormat = (PixelFormat)GLPixelFormat.CompressedTextureFormats;
break;
case SurfaceFormat.Dxt5:
if (!supportsS3tc)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt5Ext;
glFormat = (PixelFormat)GLPixelFormat.CompressedTextureFormats;
break;
case SurfaceFormat.Dxt5SRgb:
if (!supportsSRgb)
goto case SurfaceFormat.Dxt5;
glInternalFormat = PixelInternalFormat.CompressedSrgbAlphaS3tcDxt5Ext;
glFormat = (PixelFormat)GLPixelFormat.CompressedTextureFormats;
break;
#if !IOS && !ANDROID && !ANGLE
case SurfaceFormat.Rgba1010102:
glInternalFormat = PixelInternalFormat.Rgb10A2ui;
glFormat = PixelFormat.Rgba;
glType = PixelType.UnsignedInt1010102;
break;
#endif
case SurfaceFormat.Single:
if (!supportsFloat)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.R32f;
glFormat = PixelFormat.Red;
glType = PixelType.Float;
break;
case SurfaceFormat.HalfVector2:
if (!supportsHalfFloat)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.Rg16f;
glFormat = PixelFormat.Rg;
glType = PixelType.HalfFloat;
break;
// HdrBlendable implemented as HalfVector4 (see http://blogs.msdn.com/b/shawnhar/archive/2010/07/09/surfaceformat-hdrblendable.aspx)
case SurfaceFormat.HdrBlendable:
case SurfaceFormat.HalfVector4:
if (!supportsHalfFloat)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.Rgba16f;
glFormat = PixelFormat.Rgba;
glType = PixelType.HalfFloat;
break;
case SurfaceFormat.HalfSingle:
if (!supportsHalfFloat)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.R16f;
glFormat = PixelFormat.Red;
glType = isGLES2 ? PixelType.HalfFloatOES : PixelType.HalfFloat;
break;
case SurfaceFormat.Vector2:
if (!supportsFloat)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.Rg32f;
glFormat = PixelFormat.Rg;
glType = PixelType.Float;
break;
case SurfaceFormat.Vector4:
if (!supportsFloat)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.Rgba32f;
glFormat = PixelFormat.Rgba;
glType = PixelType.Float;
break;
case SurfaceFormat.NormalizedByte2:
glInternalFormat = PixelInternalFormat.Rg8i;
glFormat = PixelFormat.Rg;
glType = PixelType.Byte;
break;
case SurfaceFormat.NormalizedByte4:
glInternalFormat = PixelInternalFormat.Rgba8i;
glFormat = PixelFormat.Rgba;
glType = PixelType.Byte;
break;
case SurfaceFormat.Rg32:
if (!supportsNormalized)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.Rg16ui;
glFormat = PixelFormat.Rg;
glType = PixelType.UnsignedShort;
break;
case SurfaceFormat.Rgba64:
if (!supportsNormalized)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.Rgba16;
glFormat = PixelFormat.Rgba;
glType = PixelType.UnsignedShort;
break;
case SurfaceFormat.RgbaAtcExplicitAlpha:
if (!supportsAtitc)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.AtcRgbaExplicitAlphaAmd;
glFormat = PixelFormat.CompressedTextureFormats;
break;
case SurfaceFormat.RgbaAtcInterpolatedAlpha:
if (!supportsAtitc)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.AtcRgbaInterpolatedAlphaAmd;
glFormat = PixelFormat.CompressedTextureFormats;
break;
case SurfaceFormat.RgbEtc1:
if (!supportsEtc1)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.Etc1; // GL_ETC1_RGB8_OES
glFormat = PixelFormat.CompressedTextureFormats;
break;
case SurfaceFormat.RgbPvrtc2Bpp:
if (!supportsPvrtc)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.CompressedRgbPvrtc2Bppv1Img;
glFormat = PixelFormat.CompressedTextureFormats;
break;
case SurfaceFormat.RgbPvrtc4Bpp:
if (!supportsPvrtc)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.CompressedRgbPvrtc4Bppv1Img;
glFormat = PixelFormat.CompressedTextureFormats;
break;
case SurfaceFormat.RgbaPvrtc2Bpp:
if (!supportsPvrtc)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.CompressedRgbaPvrtc2Bppv1Img;
glFormat = PixelFormat.CompressedTextureFormats;
break;
case SurfaceFormat.RgbaPvrtc4Bpp:
if (!supportsPvrtc)
goto case InvalidFormat;
glInternalFormat = PixelInternalFormat.CompressedRgbaPvrtc4Bppv1Img;
glFormat = PixelFormat.CompressedTextureFormats;
break;
case InvalidFormat:
default:
throw new NotSupportedException(string.Format("The requested SurfaceFormat `{0}` is not supported.", format));
}
}
#endif // OPENGL
public static int GetSyncInterval(this PresentInterval interval)
{
switch (interval)
{
case PresentInterval.Immediate:
return 0;
case PresentInterval.Two:
return 2;
default:
return 1;
}
}
public static bool IsCompressedFormat(this SurfaceFormat format)
{
switch (format)
{
case SurfaceFormat.Dxt1:
case SurfaceFormat.Dxt1a:
case SurfaceFormat.Dxt1SRgb:
case SurfaceFormat.Dxt3:
case SurfaceFormat.Dxt3SRgb:
case SurfaceFormat.Dxt5:
case SurfaceFormat.Dxt5SRgb:
case SurfaceFormat.RgbaAtcExplicitAlpha:
case SurfaceFormat.RgbaAtcInterpolatedAlpha:
case SurfaceFormat.RgbaPvrtc2Bpp:
case SurfaceFormat.RgbaPvrtc4Bpp:
case SurfaceFormat.RgbEtc1:
case SurfaceFormat.RgbPvrtc2Bpp:
case SurfaceFormat.RgbPvrtc4Bpp:
return true;
}
return false;
}
public static int GetSize(this SurfaceFormat surfaceFormat)
{
switch (surfaceFormat)
{
case SurfaceFormat.Dxt1:
case SurfaceFormat.Dxt1SRgb:
case SurfaceFormat.Dxt1a:
case SurfaceFormat.RgbPvrtc2Bpp:
case SurfaceFormat.RgbaPvrtc2Bpp:
case SurfaceFormat.RgbPvrtc4Bpp:
case SurfaceFormat.RgbaPvrtc4Bpp:
case SurfaceFormat.RgbEtc1:
// One texel in DXT1, PVRTC (2bpp and 4bpp) and ETC1 is a minimum 4x4 block (8x4 for PVRTC 2bpp), which is 8 bytes
return 8;
case SurfaceFormat.Dxt3:
case SurfaceFormat.Dxt3SRgb:
case SurfaceFormat.Dxt5:
case SurfaceFormat.Dxt5SRgb:
case SurfaceFormat.RgbaAtcExplicitAlpha:
case SurfaceFormat.RgbaAtcInterpolatedAlpha:
// One texel in DXT3 and DXT5 is a minimum 4x4 block, which is 16 bytes
return 16;
case SurfaceFormat.Alpha8:
return 1;
case SurfaceFormat.Bgr565:
case SurfaceFormat.Bgra4444:
case SurfaceFormat.Bgra5551:
case SurfaceFormat.HalfSingle:
case SurfaceFormat.NormalizedByte2:
return 2;
case SurfaceFormat.Color:
case SurfaceFormat.ColorSRgb:
case SurfaceFormat.Single:
case SurfaceFormat.Rg32:
case SurfaceFormat.HalfVector2:
case SurfaceFormat.NormalizedByte4:
case SurfaceFormat.Rgba1010102:
case SurfaceFormat.Bgra32:
case SurfaceFormat.Bgra32SRgb:
case SurfaceFormat.Bgr32:
case SurfaceFormat.Bgr32SRgb:
return 4;
case SurfaceFormat.HalfVector4:
case SurfaceFormat.Rgba64:
case SurfaceFormat.Vector2:
return 8;
case SurfaceFormat.Vector4:
return 16;
default:
throw new ArgumentException();
}
}
public static int GetSize(this VertexElementFormat elementFormat)
{
switch (elementFormat)
{
case VertexElementFormat.Single:
return 4;
case VertexElementFormat.Vector2:
return 8;
case VertexElementFormat.Vector3:
return 12;
case VertexElementFormat.Vector4:
return 16;
case VertexElementFormat.Color:
return 4;
case VertexElementFormat.Byte4:
return 4;
case VertexElementFormat.Short2:
return 4;
case VertexElementFormat.Short4:
return 8;
case VertexElementFormat.NormalizedShort2:
return 4;
case VertexElementFormat.NormalizedShort4:
return 8;
case VertexElementFormat.HalfVector2:
return 4;
case VertexElementFormat.HalfVector4:
return 8;
}
return 0;
}
public static void GetBlockSize(this SurfaceFormat surfaceFormat, out int width, out int height)
{
switch (surfaceFormat)
{
case SurfaceFormat.RgbPvrtc2Bpp:
case SurfaceFormat.RgbaPvrtc2Bpp:
width = 8;
height = 4;
break;
case SurfaceFormat.Dxt1:
case SurfaceFormat.Dxt1SRgb:
case SurfaceFormat.Dxt1a:
case SurfaceFormat.Dxt3:
case SurfaceFormat.Dxt3SRgb:
case SurfaceFormat.Dxt5:
case SurfaceFormat.Dxt5SRgb:
case SurfaceFormat.RgbPvrtc4Bpp:
case SurfaceFormat.RgbaPvrtc4Bpp:
case SurfaceFormat.RgbEtc1:
case SurfaceFormat.RgbaAtcExplicitAlpha:
case SurfaceFormat.RgbaAtcInterpolatedAlpha:
width = 4;
height = 4;
break;
default:
width = 1;
height = 1;
break;
}
}
#if OPENGL
public static int GetBoundTexture2D()
{
var prevTexture = 0;
GL.GetInteger(GetPName.TextureBinding2D, out prevTexture);
GraphicsExtensions.LogGLError("GraphicsExtensions.GetBoundTexture2D() GL.GetInteger");
return prevTexture;
}
[Conditional("DEBUG")]
[DebuggerHidden]
public static void CheckGLError()
{
var error = GL.GetError();
//Console.WriteLine(error);
if (error != ErrorCode.NoError)
throw new MonoGameGLException("GL.GetError() returned " + error.ToString());
}
#endif
#if OPENGL
[Conditional("DEBUG")]
public static void LogGLError(string location)
{
try
{
GraphicsExtensions.CheckGLError();
}
catch (MonoGameGLException ex)
{
#if ANDROID
// Todo: Add generic MonoGame logging interface
Android.Util.Log.Debug("MonoGame", "MonoGameGLException at " + location + " - " + ex.Message);
#else
Debug.WriteLine("MonoGameGLException at " + location + " - " + ex.Message);
#endif
}
}
#endif
}
internal class MonoGameGLException : Exception
{
public MonoGameGLException(string message)
: base(message)
{
}
}
}
@@ -0,0 +1,103 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// A snapshot of rendering statistics from <see cref="GraphicsDevice.Metrics"/> to be used for runtime debugging and profiling.
/// </summary>
public struct GraphicsMetrics
{
internal long _clearCount;
internal long _drawCount;
internal long _pixelShaderCount;
internal long _primitiveCount;
internal long _spriteCount;
internal long _targetCount;
internal long _textureCount;
internal long _vertexShaderCount;
/// <summary>
/// Number of times Clear was called.
/// </summary>
public long ClearCount { get { return _clearCount; } }
/// <summary>
/// Number of times Draw was called.
/// </summary>
public long DrawCount { get { return _drawCount; } }
/// <summary>
/// Number of times the pixel shader was changed on the GPU.
/// </summary>
public long PixelShaderCount { get { return _pixelShaderCount; } }
/// <summary>
/// Number of rendered primitives.
/// </summary>
public long PrimitiveCount { get { return _primitiveCount; } }
/// <summary>
/// Number of sprites and text characters rendered via <see cref="SpriteBatch"/>.
/// </summary>
public long SpriteCount { get { return _spriteCount; } }
/// <summary>
/// Number of times a target was changed on the GPU.
/// </summary>
public long TargetCount {get { return _targetCount; } }
/// <summary>
/// Number of times a texture was changed on the GPU.
/// </summary>
public long TextureCount { get { return _textureCount; } }
/// <summary>
/// Number of times the vertex shader was changed on the GPU.
/// </summary>
public long VertexShaderCount { get { return _vertexShaderCount; } }
/// <summary>
/// Returns the difference between two sets of metrics.
/// </summary>
/// <param name="value1">Source <see cref="GraphicsMetrics"/> on the left of the sub sign.</param>
/// <param name="value2">Source <see cref="GraphicsMetrics"/> on the right of the sub sign.</param>
/// <returns>Difference between two sets of metrics.</returns>
public static GraphicsMetrics operator -(GraphicsMetrics value1, GraphicsMetrics value2)
{
return new GraphicsMetrics()
{
_clearCount = value1._clearCount - value2._clearCount,
_drawCount = value1._drawCount - value2._drawCount,
_pixelShaderCount = value1._pixelShaderCount - value2._pixelShaderCount,
_primitiveCount = value1._primitiveCount - value2._primitiveCount,
_spriteCount = value1._spriteCount - value2._spriteCount,
_targetCount = value1._targetCount - value2._targetCount,
_textureCount = value1._textureCount - value2._textureCount,
_vertexShaderCount = value1._vertexShaderCount - value2._vertexShaderCount
};
}
/// <summary>
/// Returns the combination of two sets of metrics.
/// </summary>
/// <param name="value1">Source <see cref="GraphicsMetrics"/> on the left of the add sign.</param>
/// <param name="value2">Source <see cref="GraphicsMetrics"/> on the right of the add sign.</param>
/// <returns>Combination of two sets of metrics.</returns>
public static GraphicsMetrics operator +(GraphicsMetrics value1, GraphicsMetrics value2)
{
return new GraphicsMetrics()
{
_clearCount = value1._clearCount + value2._clearCount,
_drawCount = value1._drawCount + value2._drawCount,
_pixelShaderCount = value1._pixelShaderCount + value2._pixelShaderCount,
_primitiveCount = value1._primitiveCount + value2._primitiveCount,
_spriteCount = value1._spriteCount + value2._spriteCount,
_targetCount = value1._targetCount + value2._targetCount,
_textureCount = value1._textureCount + value2._textureCount,
_vertexShaderCount = value1._vertexShaderCount + value2._vertexShaderCount
};
}
}
}
@@ -0,0 +1,21 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// Defines a set of graphic capabilities.
/// </summary>
public enum GraphicsProfile
{
/// <summary>
/// Use a limited set of graphic features and capabilities, allowing the game to support the widest variety of devices.
/// </summary>
Reach,
/// <summary>
/// Use the largest available set of graphic features and capabilities to target devices, that have more enhanced graphic capabilities.
/// </summary>
HiDef
}
}
@@ -0,0 +1,168 @@
#region License
// /*
// Microsoft Public License (Ms-PL)
// MonoGame - Copyright © 2009 The MonoGame Team
//
// All rights reserved.
//
// This license governs use of the accompanying software. If you use the software, you accept this license. If you do not
// accept the license, do not use the software.
//
// 1. Definitions
// The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under
// U.S. copyright law.
//
// A "contribution" is the original software, or any additions or changes to the software.
// A "contributor" is any person that distributes its contribution under this license.
// "Licensed patents" are a contributor's patent claims that read directly on its contribution.
//
// 2. Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
//
// 3. Conditions and Limitations
// (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
// your patent license from such contributor to the software ends automatically.
// (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source code form, you may do so only under this license by including
// a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object
// code form, you may only do so under a license that complies with this license.
// (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees
// or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
// permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular
// purpose and non-infringement.
// */
#endregion License
using System;
using System.Diagnostics;
namespace Microsoft.Xna.Framework.Graphics
{
public abstract class GraphicsResource : IDisposable
{
bool disposed;
// The GraphicsDevice property should only be accessed in Dispose(bool) if the disposing
// parameter is true. If disposing is false, the GraphicsDevice may or may not be
// disposed yet.
GraphicsDevice graphicsDevice;
private WeakReference _selfReference;
internal GraphicsResource()
{
}
~GraphicsResource()
{
// Pass false so the managed objects are not released
Dispose(false);
}
/// <summary>
/// Called before the device is reset. Allows graphics resources to
/// invalidate their state so they can be recreated after the device reset.
/// Warning: This may be called after a call to Dispose() up until
/// the resource is garbage collected.
/// </summary>
internal protected virtual void GraphicsDeviceResetting()
{
}
public void Dispose()
{
// Dispose of managed objects as well
Dispose(true);
// Since we have been manually disposed, do not call the finalizer on this object
GC.SuppressFinalize(this);
}
/// <summary>
/// The method that derived classes should override to implement disposing of managed and native resources.
/// </summary>
/// <param name="disposing">True if managed objects should be disposed.</param>
/// <remarks>Native resources should always be released regardless of the value of the disposing parameter.</remarks>
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Release managed objects
// ...
}
// Release native objects
// ...
// Do not trigger the event if called from the finalizer
if (disposing)
EventHelpers.Raise(this, Disposing, EventArgs.Empty);
// Remove from the global list of graphics resources
if (graphicsDevice != null)
graphicsDevice.RemoveResourceReference(_selfReference);
_selfReference = null;
graphicsDevice = null;
disposed = true;
}
}
public event EventHandler<EventArgs> Disposing;
public GraphicsDevice GraphicsDevice
{
get
{
return graphicsDevice;
}
internal set
{
Debug.Assert(value != null);
if (graphicsDevice == value)
return;
// VertexDeclaration objects can be bound to multiple GraphicsDevice objects
// during their lifetime. But only one GraphicsDevice should retain ownership.
if (graphicsDevice != null)
{
graphicsDevice.RemoveResourceReference(_selfReference);
_selfReference = null;
}
graphicsDevice = value;
_selfReference = new WeakReference(this);
graphicsDevice.AddResourceReference(_selfReference);
}
}
public bool IsDisposed
{
get
{
return disposed;
}
}
public string Name { get; set; }
public Object Tag { get; set; }
public override string ToString()
{
return string.IsNullOrEmpty(Name) ? base.ToString() : Name;
}
}
}
@@ -0,0 +1,17 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace MonoGame.OpenGL
{
internal interface IGraphicsContext : IDisposable
{
int SwapInterval { get; set; }
bool IsDisposed { get; }
void MakeCurrent(IWindowInfo info);
void SwapBuffers();
bool IsCurrent { get; }
}
}
@@ -0,0 +1,55 @@
#region License
/*
Microsoft Public License (Ms-PL)
MonoGame - Copyright © 2009 The MonoGame Team
All rights reserved.
This license governs use of the accompanying software. If you use the software, you accept this license. If you do not
accept the license, do not use the software.
1. Definitions
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under
U.S. copyright law.
A "contribution" is the original software, or any additions or changes to the software.
A "contributor" is any person that distributes its contribution under this license.
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
2. Grant of Rights
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
3. Conditions and Limitations
(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
your patent license from such contributor to the software ends automatically.
(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
notices that are present in the software.
(D) If you distribute any portion of the software in source code form, you may do so only under this license by including
a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object
code form, you may only do so under a license that complies with this license.
(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees
or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular
purpose and non-infringement.
*/
#endregion License
using System;
namespace Microsoft.Xna.Framework.Graphics
{
public interface IGraphicsDeviceService
{
Microsoft.Xna.Framework.Graphics.GraphicsDevice GraphicsDevice { get; }
event EventHandler<EventArgs> DeviceCreated;
event EventHandler<EventArgs> DeviceDisposing;
event EventHandler<EventArgs> DeviceReset;
event EventHandler<EventArgs> DeviceResetting;
}
}
@@ -0,0 +1,102 @@
#region License
// Microsoft Public License (Ms-PL)
// MonoGame - Copyright © 2009 The MonoGame Team
//
// All rights reserved.
//
// This license governs use of the accompanying software. If you use the software, you accept this license. If you do not
// accept the license, do not use the software.
//
// 1. Definitions
// The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under
// U.S. copyright law.
//
// A "contribution" is the original software, or any additions or changes to the software.
// A "contributor" is any person that distributes its contribution under this license.
// "Licensed patents" are a contributor's patent claims that read directly on its contribution.
//
// 2. Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
//
// 3. Conditions and Limitations
// (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
// your patent license from such contributor to the software ends automatically.
// (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source code form, you may do so only under this license by including
// a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object
// code form, you may only do so under a license that complies with this license.
// (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees
// or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
// permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular
// purpose and non-infringement.
#endregion License
#if DIRECTX
using SharpDX.Direct3D11;
#endif
#if OPENGL
using MonoGame.OpenGL;
#endif
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// Represents a render target.
/// </summary>
internal interface IRenderTarget
{
/// <summary>
/// Gets the width of the render target in pixels
/// </summary>
/// <value>The width of the render target in pixels.</value>
int Width { get; }
/// <summary>
/// Gets the height of the render target in pixels
/// </summary>
/// <value>The height of the render target in pixels.</value>
int Height { get; }
/// <summary>
/// Gets the usage mode of the render target.
/// </summary>
/// <value>The usage mode of the render target.</value>
RenderTargetUsage RenderTargetUsage { get; }
#if DIRECTX
/// <summary>
/// Gets the <see cref="RenderTargetView"/> for the specified array slice.
/// </summary>
/// <param name="arraySlice">The array slice.</param>
/// <returns>The <see cref="RenderTargetView"/>.</returns>
/// <remarks>
/// For texture cubes: The array slice is the index of the cube map face.
/// </remarks>
RenderTargetView GetRenderTargetView(int arraySlice);
/// <summary>
/// Gets the <see cref="DepthStencilView"/>.
/// </summary>
/// <returns>The <see cref="DepthStencilView"/>. Can be <see langword="null"/>.</returns>
DepthStencilView GetDepthStencilView();
#endif
#if OPENGL
int GLTexture { get; }
TextureTarget GLTarget { get; }
int GLColorBuffer { get; set; }
int GLDepthBuffer { get; set; }
int GLStencilBuffer { get; set; }
int MultiSampleCount { get; }
int LevelCount { get; }
TextureTarget GetFramebufferTarget(RenderTargetBinding renderTargetBinding);
#endif
}
}
@@ -0,0 +1,13 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace MonoGame.OpenGL
{
public interface IWindowInfo
{
IntPtr Handle { get; }
}
}
@@ -0,0 +1,219 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// A basic 3D model with per mesh parent bones.
/// </summary>
public sealed class Model
{
private static Matrix[] sharedDrawBoneMatrices;
private GraphicsDevice graphicsDevice;
/// <summary>
/// A collection of <see cref="ModelBone"/> objects which describe how each mesh in the
/// mesh collection for this model relates to its parent mesh.
/// </summary>
public ModelBoneCollection Bones { get; private set; }
/// <summary>
/// A collection of <see cref="ModelMesh"/> objects which compose the model. Each <see cref="ModelMesh"/>
/// in a model may be moved independently and may be composed of multiple materials
/// identified as <see cref="ModelMeshPart"/> objects.
/// </summary>
public ModelMeshCollection Meshes { get; private set; }
/// <summary>
/// Root bone for this model.
/// </summary>
public ModelBone Root { get; set; }
/// <summary>
/// Custom attached object.
/// <remarks>
/// Skinning data is example of attached object for model.
/// </remarks>
/// </summary>
public object Tag { get; set; }
internal Model()
{
}
/// <summary>
/// Constructs a model.
/// </summary>
/// <param name="graphicsDevice">A valid reference to <see cref="GraphicsDevice"/>.</param>
/// <param name="bones">The collection of bones.</param>
/// <param name="meshes">The collection of meshes.</param>
/// <exception cref="ArgumentNullException">
/// <paramref name="graphicsDevice"/> is null.
/// </exception>
/// <exception cref="ArgumentNullException">
/// <paramref name="bones"/> is null.
/// </exception>
/// <exception cref="ArgumentNullException">
/// <paramref name="meshes"/> is null.
/// </exception>
public Model(GraphicsDevice graphicsDevice, List<ModelBone> bones, List<ModelMesh> meshes)
{
if (graphicsDevice == null)
{
throw new ArgumentNullException("graphicsDevice", FrameworkResources.ResourceCreationWhenDeviceIsNull);
}
// TODO: Complete member initialization
this.graphicsDevice = graphicsDevice;
Bones = new ModelBoneCollection(bones);
Meshes = new ModelMeshCollection(meshes);
}
internal void BuildHierarchy()
{
var globalScale = Matrix.CreateScale(0.01f);
foreach(var node in this.Root.Children)
{
BuildHierarchy(node, this.Root.Transform * globalScale, 0);
}
}
private void BuildHierarchy(ModelBone node, Matrix parentTransform, int level)
{
node.ModelTransform = node.Transform * parentTransform;
foreach (var child in node.Children)
{
BuildHierarchy(child, node.ModelTransform, level + 1);
}
//string s = string.Empty;
//
//for (int i = 0; i < level; i++)
//{
// s += "\t";
//}
//
//Debug.WriteLine("{0}:{1}", s, node.Name);
}
/// <summary>
/// Draws the model meshes.
/// </summary>
/// <param name="world">The world transform.</param>
/// <param name="view">The view transform.</param>
/// <param name="projection">The projection transform.</param>
public void Draw(Matrix world, Matrix view, Matrix projection)
{
int boneCount = this.Bones.Count;
if (sharedDrawBoneMatrices == null ||
sharedDrawBoneMatrices.Length < boneCount)
{
sharedDrawBoneMatrices = new Matrix[boneCount];
}
// Look up combined bone matrices for the entire model.
CopyAbsoluteBoneTransformsTo(sharedDrawBoneMatrices);
// Draw the model.
foreach (ModelMesh mesh in Meshes)
{
foreach (Effect effect in mesh.Effects)
{
IEffectMatrices effectMatricies = effect as IEffectMatrices;
if (effectMatricies == null) {
throw new InvalidOperationException();
}
effectMatricies.World = sharedDrawBoneMatrices[mesh.ParentBone.Index] * world;
effectMatricies.View = view;
effectMatricies.Projection = projection;
}
mesh.Draw();
}
}
/// <summary>
/// Copies bone transforms relative to all parent bones of the each bone from this model to a given array.
/// </summary>
/// <param name="destinationBoneTransforms">The array receiving the transformed bones.</param>
public void CopyAbsoluteBoneTransformsTo(Matrix[] destinationBoneTransforms)
{
if (destinationBoneTransforms == null)
throw new ArgumentNullException("destinationBoneTransforms");
if (destinationBoneTransforms.Length < this.Bones.Count)
throw new ArgumentOutOfRangeException("destinationBoneTransforms");
int count = this.Bones.Count;
for (int index1 = 0; index1 < count; ++index1)
{
ModelBone modelBone = (this.Bones)[index1];
if (modelBone.Parent == null)
{
destinationBoneTransforms[index1] = modelBone.transform;
}
else
{
int index2 = modelBone.Parent.Index;
Matrix.Multiply(ref modelBone.transform, ref destinationBoneTransforms[index2], out destinationBoneTransforms[index1]);
}
}
}
/// <summary>
/// Copies bone transforms relative to <see cref="Model.Root"/> bone from a given array to this model.
/// </summary>
/// <param name="sourceBoneTransforms">The array of prepared bone transform data.</param>
/// <exception cref="ArgumentNullException">
/// <paramref name="sourceBoneTransforms"/> is null.
/// </exception>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="sourceBoneTransforms"/> is invalid.
/// </exception>
public void CopyBoneTransformsFrom(Matrix[] sourceBoneTransforms)
{
if (sourceBoneTransforms == null)
throw new ArgumentNullException("sourceBoneTransforms");
if (sourceBoneTransforms.Length < Bones.Count)
throw new ArgumentOutOfRangeException("sourceBoneTransforms");
int count = Bones.Count;
for (int i = 0; i < count; i++)
{
Bones[i].Transform = sourceBoneTransforms[i];
}
}
/// <summary>
/// Copies bone transforms relative to <see cref="Model.Root"/> bone from this model to a given array.
/// </summary>
/// <param name="destinationBoneTransforms">The array receiving the transformed bones.</param>
/// <exception cref="ArgumentNullException">
/// <paramref name="destinationBoneTransforms"/> is null.
/// </exception>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="destinationBoneTransforms"/> is invalid.
/// </exception>
public void CopyBoneTransformsTo(Matrix[] destinationBoneTransforms)
{
if (destinationBoneTransforms == null)
throw new ArgumentNullException("destinationBoneTransforms");
if (destinationBoneTransforms.Length < Bones.Count)
throw new ArgumentOutOfRangeException("destinationBoneTransforms");
int count = Bones.Count;
for (int i = 0; i < count; i++)
{
destinationBoneTransforms[i] = Bones[i].Transform;
}
}
}
}
@@ -0,0 +1,102 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
namespace Microsoft.Xna.Framework.Graphics
{
// Summary:
// Represents bone data for a model. Reference page contains links to related
// conceptual articles.
public sealed class ModelBone
{
private List<ModelBone> children = new List<ModelBone>();
private List<ModelMesh> meshes = new List<ModelMesh>();
public List<ModelMesh> Meshes {
get {
return this.meshes;
}
private set {
meshes = value;
}
}
// Summary:
// Gets a collection of bones that are children of this bone.
public ModelBoneCollection Children { get; private set; }
//
// Summary:
// Gets the index of this bone in the Bones collection.
public int Index { get; set; }
//
// Summary:
// Gets the name of this bone.
public string Name { get; set; }
//
// Summary:
// Gets the parent of this bone.
public ModelBone Parent { get; set; }
//
// Summary:
// Gets or sets the matrix used to transform this bone relative to its parent
// bone.
internal Matrix transform;
public Matrix Transform
{
get { return this.transform; }
set { this.transform = value; }
}
/// <summary>
/// Transform of this node from the root of the model not from the parent
/// </summary>
public Matrix ModelTransform {
get;
set;
}
public ModelBone ()
{
Children = new ModelBoneCollection(new List<ModelBone>());
}
public void AddMesh(ModelMesh mesh)
{
meshes.Add(mesh);
}
public void AddChild(ModelBone modelBone)
{
children.Add(modelBone);
Children = new ModelBoneCollection(children);
}
}
//// Summary:
//// Represents bone data for a model. Reference page contains links to related
//// conceptual articles.
//public sealed class ModelBone
//{
// // Summary:
// // Gets a collection of bones that are children of this bone.
// public ModelBoneCollection Children { get { throw new NotImplementedException(); } }
// //
// // Summary:
// // Gets the index of this bone in the Bones collection.
// public int Index { get { throw new NotImplementedException(); } }
// //
// // Summary:
// // Gets the name of this bone.
// public string Name { get { throw new NotImplementedException(); } }
// //
// // Summary:
// // Gets the parent of this bone.
// public ModelBone Parent { get { throw new NotImplementedException(); } }
// //
// // Summary:
// // Gets or sets the matrix used to transform this bone relative to its parent
// // bone.
// public Matrix Transform { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } }
//}
}
@@ -0,0 +1,126 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// Represents a set of bones associated with a model.
/// </summary>
public class ModelBoneCollection : ReadOnlyCollection<ModelBone>
{
public ModelBoneCollection(IList<ModelBone> list)
: base(list)
{
}
/// <summary>
/// Retrieves a ModelBone from the collection, given the name of the bone.
/// </summary>
/// <param name="boneName">The name of the bone to retrieve.</param>
public ModelBone this[string boneName]
{
get
{
ModelBone ret;
if (!TryGetValue(boneName, out ret))
throw new KeyNotFoundException();
return ret;
}
}
/// <summary>
/// Finds a bone with a given name if it exists in the collection.
/// </summary>
/// <param name="boneName">The name of the bone to find.</param>
/// <param name="value">The bone named boneName, if found.</param>
/// <returns>true if the bone was found</returns>
public bool TryGetValue(string boneName, out ModelBone value)
{
if (string.IsNullOrEmpty(boneName))
throw new ArgumentNullException("boneName");
foreach (ModelBone bone in this)
{
if (bone.Name == boneName)
{
value = bone;
return true;
}
}
value = null;
return false;
}
/// <summary>
/// Returns a ModelMeshCollection.Enumerator that can iterate through a ModelMeshCollection.
/// </summary>
/// <returns></returns>
public new Enumerator GetEnumerator()
{
return new Enumerator(this);
}
/// <summary>
/// Provides the ability to iterate through the bones in an ModelMeshCollection.
/// </summary>
public struct Enumerator : IEnumerator<ModelBone>
{
private readonly ModelBoneCollection _collection;
private int _position;
internal Enumerator(ModelBoneCollection collection)
{
_collection = collection;
_position = -1;
}
/// <summary>
/// Gets the current element in the ModelMeshCollection.
/// </summary>
public ModelBone Current { get { return _collection[_position]; } }
/// <summary>
/// Advances the enumerator to the next element of the ModelMeshCollection.
/// </summary>
public bool MoveNext()
{
_position++;
return (_position < _collection.Count);
}
#region IDisposable
/// <summary>
/// Immediately releases the unmanaged resources used by this object.
/// </summary>
public void Dispose()
{
}
#endregion
#region IEnumerator Members
object IEnumerator.Current
{
get { return _collection[_position]; }
}
public void Reset()
{
_position = -1;
}
#endregion
}
}
}
@@ -0,0 +1,88 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Microsoft.Xna.Framework.Graphics
{
// Summary:
// Represents a collection of effects associated with a model.
public sealed class ModelEffectCollection : ReadOnlyCollection<Effect>
{
internal ModelEffectCollection(IList<Effect> list)
: base(list)
{
}
internal ModelEffectCollection() : base(new List<Effect>())
{
}
//ModelMeshPart needs to be able to add to ModelMesh's effects list
internal void Add(Effect item)
{
Items.Add (item);
}
internal void Remove(Effect item)
{
Items.Remove (item);
}
// Summary:
// Returns a ModelEffectCollection.Enumerator that can iterate through a ModelEffectCollection.
public new ModelEffectCollection.Enumerator GetEnumerator()
{
return new ModelEffectCollection.Enumerator((List<Effect>)Items);
}
// Summary:
// Provides the ability to iterate through the bones in an ModelEffectCollection.
public struct Enumerator : IEnumerator<Effect>, IDisposable, IEnumerator
{
List<Effect>.Enumerator enumerator;
bool disposed;
internal Enumerator(List<Effect> list)
{
enumerator = list.GetEnumerator();
disposed = false;
}
// Summary:
// Gets the current element in the ModelEffectCollection.
public Effect Current { get { return enumerator.Current; } }
// Summary:
// Immediately releases the unmanaged resources used by this object.
public void Dispose()
{
if (!disposed)
{
enumerator.Dispose();
disposed = true;
}
}
//
// Summary:
// Advances the enumerator to the next element of the ModelEffectCollection.
public bool MoveNext() { return enumerator.MoveNext(); }
#region IEnumerator Members
object IEnumerator.Current
{
get { return Current; }
}
void IEnumerator.Reset()
{
IEnumerator resetEnumerator = enumerator;
resetEnumerator.Reset ();
enumerator = (List<Effect>.Enumerator)resetEnumerator;
}
#endregion
}
}
}
@@ -0,0 +1,131 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
namespace Microsoft.Xna.Framework.Graphics
{
// Summary:
// Represents a mesh that is part of a Model.
public sealed class ModelMesh
{
private GraphicsDevice graphicsDevice;
public ModelMesh(GraphicsDevice graphicsDevice, System.Collections.Generic.List<ModelMeshPart> parts)
{
// TODO: Complete member initialization
this.graphicsDevice = graphicsDevice;
MeshParts = new ModelMeshPartCollection(parts);
for (int i = 0; i < parts.Count; i++) {
parts[i].parent = this;
}
Effects = new ModelEffectCollection();
}
/*internal void BuildEffectList()
{
List<Effect> effects = new List<Effect>();
foreach (ModelMeshPart item in parts)
{
if (!effects.Contains(item.Effect))
{
if (item.Effect != null)
effects.Add(item.Effect);
}
}
Effects = new ModelEffectCollection(effects);
}*/
// Summary:
// Gets the BoundingSphere that contains this mesh.
public BoundingSphere BoundingSphere { get; set; }
//
// Summary:
// Gets a collection of effects associated with this mesh.
public ModelEffectCollection Effects { get; internal set; }
//
// Summary:
// Gets the ModelMeshPart objects that make up this mesh. Each part of a mesh
// is composed of a set of primitives that share the same material.
public ModelMeshPartCollection MeshParts { get; set; }
//
// Summary:
// Gets the name of this mesh.
public string Name { get; set; }
//
// Summary:
// Gets the parent bone for this mesh. The parent bone of a mesh contains a
// transformation matrix that describes how the mesh is located relative to
// any parent meshes in a model.
public ModelBone ParentBone { get; set; }
//
// Summary:
// Gets or sets an object identifying this mesh.
public object Tag { get; set; }
// Summary:
// Draws all of the ModelMeshPart objects in this mesh, using their current
// Effect settings.
public void Draw()
{
for(int i = 0; i < MeshParts.Count; i++)
{
var part = MeshParts[i];
var effect = part.Effect;
if (part.PrimitiveCount > 0)
{
this.graphicsDevice.SetVertexBuffer(part.VertexBuffer);
this.graphicsDevice.Indices = part.IndexBuffer;
for (int j = 0; j < effect.CurrentTechnique.Passes.Count; j++)
{
effect.CurrentTechnique.Passes[j].Apply ();
graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, part.VertexOffset, part.StartIndex, part.PrimitiveCount);
}
}
}
}
}
//// Summary:
//// Represents a mesh that is part of a Model.
//public sealed class ModelMesh
//{
// // Summary:
// // Gets the BoundingSphere that contains this mesh.
// public BoundingSphere BoundingSphere { get { throw new NotImplementedException(); } }
// //
// // Summary:
// // Gets a collection of effects associated with this mesh.
// public ModelEffectCollection Effects { get { throw new NotImplementedException(); } }
// //
// // Summary:
// // Gets the ModelMeshPart objects that make up this mesh. Each part of a mesh
// // is composed of a set of primitives that share the same material.
// public ModelMeshPartCollection MeshParts { get { throw new NotImplementedException(); } }
// //
// // Summary:
// // Gets the name of this mesh.
// public string Name { get { throw new NotImplementedException(); } }
// //
// // Summary:
// // Gets the parent bone for this mesh. The parent bone of a mesh contains a
// // transformation matrix that describes how the mesh is located relative to
// // any parent meshes in a model.
// public ModelBone ParentBone { get { throw new NotImplementedException(); } }
// //
// // Summary:
// // Gets or sets an object identifying this mesh.
// public object Tag { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } }
// // Summary:
// // Draws all of the ModelMeshPart objects in this mesh, using their current
// // Effect settings.
// public void Draw() { throw new NotImplementedException(); }
//}
}
@@ -0,0 +1,126 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Microsoft.Xna.Framework.Graphics
{
/// <summary>
/// Represents a collection of ModelMesh objects.
/// </summary>
public sealed class ModelMeshCollection : ReadOnlyCollection<ModelMesh>
{
internal ModelMeshCollection(IList<ModelMesh> list)
: base(list)
{
}
/// <summary>
/// Retrieves a ModelMesh from the collection, given the name of the mesh.
/// </summary>
/// <param name="meshName">The name of the mesh to retrieve.</param>
public ModelMesh this[string meshName]
{
get
{
ModelMesh ret;
if (!TryGetValue(meshName, out ret))
throw new KeyNotFoundException();
return ret;
}
}
/// <summary>
/// Finds a mesh with a given name if it exists in the collection.
/// </summary>
/// <param name="meshName">The name of the mesh to find.</param>
/// <param name="value">The mesh named meshName, if found.</param>
/// <returns>true if a mesh was found</returns>
public bool TryGetValue(string meshName, out ModelMesh value)
{
if (string.IsNullOrEmpty(meshName))
throw new ArgumentNullException("meshName");
foreach (var mesh in this)
{
if (string.Compare(mesh.Name, meshName, StringComparison.Ordinal) == 0)
{
value = mesh;
return true;
}
}
value = null;
return false;
}
/// <summary>
/// Returns a ModelMeshCollection.Enumerator that can iterate through a ModelMeshCollection.
/// </summary>
/// <returns></returns>
public new Enumerator GetEnumerator()
{
return new Enumerator(this);
}
/// <summary>
/// Provides the ability to iterate through the bones in an ModelMeshCollection.
/// </summary>
public struct Enumerator : IEnumerator<ModelMesh>
{
private readonly ModelMeshCollection _collection;
private int _position;
internal Enumerator(ModelMeshCollection collection)
{
_collection = collection;
_position = -1;
}
/// <summary>
/// Gets the current element in the ModelMeshCollection.
/// </summary>
public ModelMesh Current { get { return _collection[_position]; } }
/// <summary>
/// Advances the enumerator to the next element of the ModelMeshCollection.
/// </summary>
public bool MoveNext()
{
_position++;
return (_position < _collection.Count);
}
#region IDisposable
/// <summary>
/// Immediately releases the unmanaged resources used by this object.
/// </summary>
public void Dispose()
{
}
#endregion
#region IEnumerator Members
object IEnumerator.Current
{
get { return _collection[_position]; }
}
public void Reset()
{
_position = -1;
}
#endregion
}
}
}
@@ -0,0 +1,131 @@
using System;
namespace Microsoft.Xna.Framework.Graphics
{
public sealed class ModelMeshPart
{
// Summary:
// Gets or sets the material Effect for this mesh part. Reference page contains
// code sample.
private Effect _effect;
public Effect Effect
{
get
{
return _effect;
}
set
{
if (value == _effect)
return;
if (_effect != null)
{
// First check to see any other parts are also using this effect.
var removeEffect = true;
foreach (var part in parent.MeshParts)
{
if (part != this && part._effect == _effect)
{
removeEffect = false;
break;
}
}
if (removeEffect)
parent.Effects.Remove(_effect);
}
// Set the new effect.
_effect = value;
if (_effect != null && !parent.Effects.Contains(_effect))
parent.Effects.Add(_effect);
}
}
//
// Summary:
// Gets the index buffer for this mesh part.
public IndexBuffer IndexBuffer { get; set; }
//
// Summary:
// Gets the number of vertices used during a draw call.
public int NumVertices { get; set; }
//
// Summary:
// Gets the number of primitives to render.
public int PrimitiveCount { get; set; }
//
// Summary:
// Gets the location in the index array at which to start reading vertices.
public int StartIndex { get; set; }
//
// Summary:
// Gets or sets an object identifying this model mesh part.
public object Tag { get; set; }
//
// Summary:
// Gets the vertex buffer for this mesh part.
public VertexBuffer VertexBuffer { get; set; }
//
// Summary:
// Gets the offset (in vertices) from the top of vertex buffer.
public int VertexOffset { get; set; }
internal int VertexBufferIndex { get; set; }
internal int IndexBufferIndex { get; set; }
internal int EffectIndex { get; set; }
internal ModelMesh parent;
}
//// Summary:
//// Represents a batch of geometry information to submit to the graphics device
//// during rendering. Each ModelMeshPart is a subdivision of a ModelMesh object.
//// The ModelMesh class is split into multiple ModelMeshPart objects, typically
//// based on material information.
//public sealed class ModelMeshPart
//{
// // Summary:
// // Gets or sets the material Effect for this mesh part. Reference page contains
// // code sample.
// public Effect Effect { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } }
// //
// // Summary:
// // Gets the index buffer for this mesh part.
// public IndexBuffer IndexBuffer { get { throw new NotImplementedException(); } }
// //
// // Summary:
// // Gets the number of vertices used during a draw call.
// public int NumVertices { get { throw new NotImplementedException(); } }
// //
// // Summary:
// // Gets the number of primitives to render.
// public int PrimitiveCount { get { throw new NotImplementedException(); } }
// //
// // Summary:
// // Gets the location in the index array at which to start reading vertices.
// public int StartIndex { get { throw new NotImplementedException(); } }
// //
// // Summary:
// // Gets or sets an object identifying this model mesh part.
// public object Tag { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } }
// //
// // Summary:
// // Gets the vertex buffer for this mesh part.
// public VertexBuffer VertexBuffer { get { throw new NotImplementedException(); } }
// //
// // Summary:
// // Gets the offset (in vertices) from the top of vertex buffer.
// public int VertexOffset { get { throw new NotImplementedException(); } }
//}
}
@@ -0,0 +1,63 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Microsoft.Xna.Framework.Graphics
{
public sealed class ModelMeshPartCollection : ReadOnlyCollection<ModelMeshPart>
{
public ModelMeshPartCollection(IList<ModelMeshPart> list)
: base(list)
{
}
}
//// Summary:
//// Represents a collection of ModelMeshPart objects.
//public sealed class ModelMeshPartCollection : ReadOnlyCollection<ModelMeshPart>
//{
// internal ModelMeshPartCollection()
// : base(new List<ModelMeshPart>())
// {
// }
// // Summary:
// // Returns a ModelMeshPartCollection.Enumerator that can iterate through a ModelMeshPartCollection.
// public ModelMeshPartCollection.Enumerator GetEnumerator() { throw new NotImplementedException(); }
// // Summary:
// // Provides the ability to iterate through the bones in an ModelMeshPartCollection.
// public struct Enumerator : IEnumerator<ModelMeshPart>, IDisposable, IEnumerator
// {
// // Summary:
// // Gets the current element in the ModelMeshPartCollection.
// public ModelMeshPart Current { get { throw new NotImplementedException(); } }
// // Summary:
// // Immediately releases the unmanaged resources used by this object.
// public void Dispose() { throw new NotImplementedException(); }
// //
// // Summary:
// // Advances the enumerator to the next element of the ModelMeshPartCollection.
// public bool MoveNext() { throw new NotImplementedException(); }
// #region IEnumerator Members
// object IEnumerator.Current
// {
// get { throw new NotImplementedException(); }
// }
// public void Reset()
// {
// throw new NotImplementedException();
// }
// #endregion
// }
//}
}
@@ -0,0 +1,27 @@
using System;
using System.Runtime.Serialization;
namespace Microsoft.Xna.Framework.Graphics
{
[DataContract]
public sealed class NoSuitableGraphicsDeviceException : Exception
{
public NoSuitableGraphicsDeviceException()
: base()
{
}
public NoSuitableGraphicsDeviceException(string message)
: base(message)
{
}
public NoSuitableGraphicsDeviceException(string message, Exception inner)
: base(message, inner)
{
}
}
}
@@ -0,0 +1,65 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using SharpDX.Direct3D11;
namespace Microsoft.Xna.Framework.Graphics
{
partial class OcclusionQuery
{
private Query _query;
private void PlatformConstruct()
{
//if (graphicsDevice._d3dDevice.FeatureLevel == SharpDX.Direct3D.FeatureLevel.Level_9_1)
// throw new NotSupportedException("The Reach profile does not support occlusion queries.");
var queryDescription = new QueryDescription
{
Flags = QueryFlags.None,
Type = QueryType.Occlusion
};
_query = new Query(GraphicsDevice._d3dDevice, queryDescription);
}
private void PlatformBegin()
{
var d3dContext = GraphicsDevice._d3dContext;
lock(d3dContext)
d3dContext.Begin(_query);
}
private void PlatformEnd()
{
var d3dContext = GraphicsDevice._d3dContext;
lock (d3dContext)
d3dContext.End(_query);
}
private bool PlatformGetResult(out int pixelCount)
{
var d3dContext = GraphicsDevice._d3dContext;
ulong count;
bool isComplete;
lock (d3dContext)
isComplete = d3dContext.GetData(_query, out count);
pixelCount = (int)count;
return isComplete;
}
protected override void Dispose(bool disposing)
{
if (!IsDisposed)
{
if (disposing)
_query.Dispose();
}
base.Dispose(disposing);
}
}
}
@@ -0,0 +1,28 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
namespace Microsoft.Xna.Framework.Graphics
{
partial class OcclusionQuery
{
private void PlatformConstruct()
{
}
private void PlatformBegin()
{
}
private void PlatformEnd()
{
}
private bool PlatformGetResult(out int pixelCount)
{
pixelCount = 0;
return false;
}
}
}
@@ -0,0 +1,64 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using MonoGame.OpenGL;
namespace Microsoft.Xna.Framework.Graphics
{
partial class OcclusionQuery
{
private int glQueryId = -1;
private void PlatformConstruct()
{
GL.GenQueries(1, out glQueryId);
GraphicsExtensions.CheckGLError();
}
private void PlatformBegin()
{
GL.BeginQuery(QueryTarget.SamplesPassed, glQueryId);
GraphicsExtensions.CheckGLError();
}
private void PlatformEnd()
{
GL.EndQuery(QueryTarget.SamplesPassed);
GraphicsExtensions.CheckGLError();
}
private bool PlatformGetResult(out int pixelCount)
{
int resultReady = 0;
GL.GetQueryObject(glQueryId, GetQueryObjectParam.QueryResultAvailable, out resultReady);
GraphicsExtensions.CheckGLError();
if (resultReady == 0)
{
pixelCount = 0;
return false;
}
GL.GetQueryObject(glQueryId, GetQueryObjectParam.QueryResult, out pixelCount);
GraphicsExtensions.CheckGLError();
return true;
}
protected override void Dispose(bool disposing)
{
if (!IsDisposed)
{
if (glQueryId > -1)
{
GraphicsDevice.DisposeQuery(glQueryId);
glQueryId = -1;
}
}
base.Dispose(disposing);
}
}
}
@@ -0,0 +1,114 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace Microsoft.Xna.Framework.Graphics
{
public partial class OcclusionQuery : GraphicsResource
{
private bool _inBeginEndPair; // true if Begin was called and End was not yet called.
private bool _queryPerformed; // true if Begin+End were called at least once.
private bool _isComplete; // true if the result is available in _pixelCount.
private int _pixelCount; // The query result.
/// <summary>
/// Gets a value indicating whether the occlusion query has completed.
/// </summary>
/// <value>
/// <see langword="true"/> if the occlusion query has completed; otherwise,
/// <see langword="false"/>.
/// </value>
public bool IsComplete
{
get
{
if (_isComplete)
return true;
if (!_queryPerformed || _inBeginEndPair)
return false;
_isComplete = PlatformGetResult(out _pixelCount);
return _isComplete;
}
}
/// <summary>
/// Gets the number of visible pixels.
/// </summary>
/// <value>The number of visible pixels.</value>
/// <exception cref="InvalidOperationException">
/// The occlusion query has not yet completed. Check <see cref="IsComplete"/> before reading
/// the result!
/// </exception>
public int PixelCount
{
get
{
if (!IsComplete)
throw new InvalidOperationException("The occlusion query has not yet completed. Check IsComplete before reading the result.");
return _pixelCount;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="OcclusionQuery"/> class.
/// </summary>
/// <param name="graphicsDevice">The graphics device.</param>
/// <exception cref="ArgumentNullException">
/// <paramref name="graphicsDevice"/> is <see langword="null"/>.
/// </exception>
/// <exception cref="NotSupportedException">
/// The current graphics profile does not support occlusion queries.
/// </exception>
public OcclusionQuery(GraphicsDevice graphicsDevice)
{
if (graphicsDevice == null)
throw new ArgumentNullException("graphicsDevice");
if (graphicsDevice.GraphicsProfile == GraphicsProfile.Reach)
throw new NotSupportedException("The Reach profile does not support occlusion queries.");
GraphicsDevice = graphicsDevice;
PlatformConstruct();
}
/// <summary>
/// Begins the occlusion query.
/// </summary>
/// <exception cref="InvalidOperationException">
/// <see cref="Begin"/> is called again before calling <see cref="End"/>.
/// </exception>
public void Begin()
{
if (_inBeginEndPair)
throw new InvalidOperationException("End() must be called before calling Begin() again.");
_inBeginEndPair = true;
_isComplete = false;
PlatformBegin();
}
/// <summary>
/// Ends the occlusion query.
/// </summary>
/// <exception cref="InvalidOperationException">
/// <see cref="End"/> is called before calling <see cref="Begin"/>.
/// </exception>
public void End()
{
if (!_inBeginEndPair)
throw new InvalidOperationException("Begin() must be called before calling End().");
_inBeginEndPair = false;
_queryPerformed = true;
PlatformEnd();
}
}
}
@@ -0,0 +1,105 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;
using Android.Opengl;
using Javax.Microedition.Khronos.Egl;
using MonoGame.Utilities;
namespace MonoGame.OpenGL
{
internal partial class GL
{
// internal for Android is not used on other platforms
// it allows us to use either GLES or Full GL (if the GPU supports it)
internal delegate bool BindAPIDelegate (RenderApi api);
internal static BindAPIDelegate BindAPI;
public static IntPtr Library;
public static IntPtr libES1 = FuncLoader.LoadLibrary("libGLESv1_CM.so");
public static IntPtr libES2 = FuncLoader.LoadLibrary("libGLESv2.so");
public static IntPtr libES3 = FuncLoader.LoadLibrary("libGLESv3.so");
public static IntPtr libGL = FuncLoader.LoadLibrary("libGL.so");
static partial void LoadPlatformEntryPoints()
{
Android.Util.Log.Verbose("GL", "Loading Entry Points");
var eglBindLoaded = false;
try
{
BindAPI = FuncLoader.LoadFunction<BindAPIDelegate>(libGL, "eglBindAPI", true);
eglBindLoaded = true;
}
catch { }
var supportsFullGL = eglBindLoaded && BindAPI (RenderApi.GL);
if (!supportsFullGL) {
if (eglBindLoaded)
BindAPI (RenderApi.ES);
BoundApi = RenderApi.ES;
}
Android.Util.Log.Verbose("GL", "Bound {0}", BoundApi);
if (GL.BoundApi == GL.RenderApi.ES && libES3 != IntPtr.Zero)
Library = libES3;
if (GL.BoundApi == GL.RenderApi.ES && libES2 != IntPtr.Zero)
Library = libES2;
else if (GL.BoundApi == GL.RenderApi.GL && libGL != IntPtr.Zero)
Library = libGL;
}
private static T LoadFunction<T>(string function, bool throwIfNotFound = false)
{
return FuncLoader.LoadFunction<T>(Library, function, throwIfNotFound);
}
private static IGraphicsContext PlatformCreateContext (IWindowInfo info)
{
return null;//new GraphicsContext(info);
}
}
struct GLESVersion
{
const int EglContextClientVersion = 0x3098;
const int EglContextMinorVersion = 0x30fb;
public int Major;
public int Minor;
internal int[] GetAttributes()
{
int minor = Minor > -1 ? EglContextMinorVersion : EGL10.EglNone;
return new int[] { EglContextClientVersion, Major, minor, Minor, EGL10.EglNone };
}
public override string ToString()
{
return string.Format("{0}.{1}", Major, Minor == -1 ? 0 : Minor);
}
internal static IEnumerable<GLESVersion> GetSupportedGLESVersions()
{
if (GL.libES3 != IntPtr.Zero)
{
yield return new GLESVersion { Major = 3, Minor = 2 };
yield return new GLESVersion { Major = 3, Minor = 1 };
yield return new GLESVersion { Major = 3, Minor = 0 };
}
if (GL.libES2 != IntPtr.Zero)
{
// We pass -1 becuase when requesting a GLES 2.0 context we
// dont provide the Minor version.
yield return new GLESVersion { Major = 2, Minor = -1 };
}
yield return new GLESVersion();
}
}
}
@@ -0,0 +1,12 @@
using System;
namespace MonoGame.OpenGL
{
// Required to allow platforms other than iOS use the same code.
// just don't include this on iOS
[AttributeUsage (AttributeTargets.Delegate)]
internal sealed class MonoNativeFunctionWrapper : Attribute
{
}
}
@@ -0,0 +1,128 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Runtime.InteropServices;
using ObjCRuntime;
using AppKit;
using System.Security;
using MonoGame.Utilities;
namespace OpenGL
{
public partial class GL
{
public static IntPtr Library = FuncLoader.LoadLibrary("/System/Library/Frameworks/OpenGL.framework/OpenGL");
static partial void LoadPlatformEntryPoints()
{
BoundApi = RenderApi.GL;
}
private static T LoadFunction<T>(string function, bool throwIfNotFound = false)
{
return FuncLoader.LoadFunction<T>(Library, function, throwIfNotFound);
}
private static IGraphicsContext PlatformCreateContext (IWindowInfo info)
{
return new GraphicsContext ((MacWindowInfo)info);
}
}
public class MacWindowInfo : IWindowInfo
{
public IntPtr Handle
{
get
{
return IntPtr.Zero;
}
}
public int ColorSize { get; private set; }
public int DepthSize { get; private set; }
public int StencilSize { get; private set; }
public int MultiSample { get; private set; }
public MacWindowInfo(int colorSize, int depthSize, int stencils, int multipSample)
{
ColorSize = colorSize;
DepthSize = depthSize;
MultiSample = multipSample;
}
}
public class GraphicsContext : IGraphicsContext
{
public GraphicsContext (MacWindowInfo info)
{
var attribs = new object[] {
NSOpenGLPixelFormatAttribute.Accelerated,
NSOpenGLPixelFormatAttribute.NoRecovery,
NSOpenGLPixelFormatAttribute.DoubleBuffer,
NSOpenGLPixelFormatAttribute.ColorSize, info.ColorSize,
NSOpenGLPixelFormatAttribute.DepthSize, info.DepthSize,
NSOpenGLPixelFormatAttribute.StencilSize , info.StencilSize,
NSOpenGLPixelFormatAttribute.Multisample, info.MultiSample,
};
PixelFormat = new NSOpenGLPixelFormat(attribs);
if (PixelFormat == null)
Console.WriteLine("No OpenGL pixel format");
Context = new NSOpenGLContext (PixelFormat, null);
Context.MakeCurrentContext();
}
public bool IsCurrent {
get {
return NSOpenGLContext.CurrentContext == this.Context;
}
}
public bool IsDisposed {
get {
return this.Context == null;
}
}
public int SwapInterval {
get {
throw new NotImplementedException ();
}
set {
throw new NotImplementedException ();
}
}
public void Dispose ()
{
if (this.Context != null) {
this.Context.Dispose ();
}
this.Context = null;
}
public void MakeCurrent (IWindowInfo info)
{
this.Context.MakeCurrentContext();
}
public void SwapBuffers ()
{
//if (!this.Context.PresentRenderBuffer (36161u)) {
// throw new InvalidOperationException ("EAGLContext.PresentRenderbuffer failed.");
//}
}
internal NSOpenGLContext Context { get; private set; }
internal NSOpenGLPixelFormat PixelFormat { get; private set; }
}
}

Some files were not shown because too many files have changed in this diff Show More