1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
using System;
using System.Runtime.InteropServices;
#if MONOMAC
using MonoMac.OpenGL;
#else
using OpenTK.Graphics.OpenGL;
#endif
namespace Microsoft.Xna.Framework.Graphics
{
public class VertexDeclaration : GraphicsResource
{
// Fields
internal VertexElement[] _elements;
internal int _vertexStride;
public VertexDeclaration(params VertexElement[] elements)
{
if ((elements == null) || (elements.Length == 0))
{
throw new ArgumentNullException("elements", "Elements cannot be empty");
}
else
{
VertexElement[] elementArray = (VertexElement[]) elements.Clone();
this._elements = elementArray;
this._vertexStride = getVertexStride(elementArray);
}
}
private static int getVertexStride(VertexElement[] elements)
{
int max = 0;
for (int i = 0; i < elements.Length; i++)
{
int start = elements[i].Offset + elements[i].VertexElementFormat.GetTypeSize();
if (max < start)
{
max = start;
}
}
return max;
}
public VertexDeclaration(int vertexStride, params VertexElement[] elements)
{
if ((elements == null) || (elements.Length == 0))
{
throw new ArgumentNullException("elements", "Elements cannot be empty");
}
else
{
VertexElement[] elementArray = (VertexElement[]) elements.Clone();
this._elements = elementArray;
this._vertexStride = vertexStride;
}
}
internal static VertexDeclaration FromType(Type vertexType)
{
if (vertexType == null)
{
throw new ArgumentNullException("vertexType", "Cannot be null");
}
if (!vertexType.IsValueType)
{
object[] args = new object[] { vertexType };
throw new ArgumentException("vertexType", "Must be value type");
}
IVertexType type = Activator.CreateInstance(vertexType) as IVertexType;
if (type == null)
{
object[] objArray3 = new object[] { vertexType };
throw new ArgumentException("vertexData does not inherit IVertexType");
}
VertexDeclaration vertexDeclaration = type.VertexDeclaration;
if (vertexDeclaration == null)
{
object[] objArray2 = new object[] { vertexType };
throw new Exception("VertexDeclaration cannot be null");
}
return vertexDeclaration;
}
public static void PrepareForUse(VertexDeclaration vd)
{
GLStateManager.VertexArray(true);
bool normal = false;
bool color = false;
bool texcoord = false;
foreach (var ve in vd.GetVertexElements())
{
switch (ve.VertexElementUsage)
{
case VertexElementUsage.Position:
GL.VertexPointer(
ve.VertexElementFormat.OpenGLNumberOfElements(),
ve.VertexElementFormat.OpenGLVertexPointerType(),
vd.VertexStride,
(IntPtr)ve.Offset
);
break;
case VertexElementUsage.Color:
GL.ColorPointer(
ve.VertexElementFormat.OpenGLNumberOfElements(),
ve.VertexElementFormat.OpenGLColorPointerType(),
vd.VertexStride,
(IntPtr)ve.Offset
);
color = true;
break;
case VertexElementUsage.Normal:
GL.NormalPointer(
ve.VertexElementFormat.OpenGLNormalPointerType(),
vd.VertexStride,
(IntPtr)ve.Offset
);
normal = true;
break;
case VertexElementUsage.TextureCoordinate:
GL.TexCoordPointer(
ve.VertexElementFormat.OpenGLNumberOfElements(),
ve.VertexElementFormat.OpenGLTexCoordPointerType(),
vd.VertexStride,
(IntPtr)ve.Offset
);
texcoord = true;
break;
default:
throw new NotImplementedException();
}
}
GLStateManager.TextureCoordArray(texcoord);
GLStateManager.ColorArray(color);
GLStateManager.NormalArray(normal);
}
public VertexElement[] GetVertexElements()
{
return (VertexElement[]) this._elements.Clone();
}
// Properties
public int VertexStride
{
get
{
return this._vertexStride;
}
}
}
}
|