VertexDeclaration for XNATouch / MonoGame
This is a helper I created to use VertexDeclaration from XNA to openGLES.
GLStateManager is a manager that remembers what modes that have been set so they don’t need to be overly initialized. I don’t know if it saves any performance, but I sure hope so. The IntPtr arrayStart is a pointer to the array of Vertices in memory. Like VertexPositionColor[] vertices.
The IntPtr can be gotten by using IntPtr arrayStart = GCHandle.Alloc(vertexData, GCHandleType.Pinned).AddrOfPinnedObject();
Prepare vertices for use
using All11 = OpenTK.Graphics.ES11.All; using GL11 = OpenTK.Graphics.ES11.GL; public static void PrepareForUse(VertexDeclaration vd, IntPtr arrayStart) { GLStateManager.VertexArray(true); bool normal = false; bool color = false; bool texcoord = false; foreach (var ve in vd.GetVertexElements()) { switch (ve.VertexElementUsage) { case VertexElementUsage.Position: GL11.VertexPointer( ve.VertexElementFormat.OpenGLNumberOfElements(), ve.VertexElementFormat.OpenGLValueType(), vd.VertexStride, new IntPtr(arrayStart.ToInt32() + ve.Offset) ); break; case VertexElementUsage.Color: GL11.ColorPointer( ve.VertexElementFormat.OpenGLNumberOfElements(), ve.VertexElementFormat.OpenGLValueType(), vd.VertexStride, new IntPtr(arrayStart.ToInt32() + ve.Offset) ); color = true; break; case VertexElementUsage.Normal: GL11.NormalPointer( ve.VertexElementFormat.OpenGLValueType(), vd.VertexStride, new IntPtr(arrayStart.ToInt32() + ve.Offset) ); normal = true; break; case VertexElementUsage.TextureCoordinate: GL11.TexCoordPointer( ve.VertexElementFormat.OpenGLNumberOfElements(), ve.VertexElementFormat.OpenGLValueType(), vd.VertexStride, new IntPtr(arrayStart.ToInt32() + ve.Offset) ); texcoord = true; break; default: throw new NotImplementedException(); } } GLStateManager.TextureCoordArray(texcoord); GLStateManager.ColorArray(color); GLStateManager.NormalArray(normal); } public static int OpenGLNumberOfElements(this VertexElementFormat elementFormat) { switch (elementFormat) { case VertexElementFormat.Single: throw new NotImplementedException(); 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 2; case VertexElementFormat.NormalizedShort2: return 2; case VertexElementFormat.NormalizedShort4: return 4; case VertexElementFormat.HalfVector2: return 2; case VertexElementFormat.HalfVector4: return 4; } throw new NotImplementedException(); } public static All11 OpenGLValueType(this VertexElementFormat elementFormat) { switch (elementFormat) { case VertexElementFormat.Single: throw new NotImplementedException(); case VertexElementFormat.Vector2: return All11.Float; case VertexElementFormat.Vector3: return All11.Float; case VertexElementFormat.Vector4: return All11.Float; case VertexElementFormat.Color: return All11.UnsignedByte; case VertexElementFormat.Byte4: return All11.UnsignedByte; case VertexElementFormat.Short2: return All11.UnsignedShort; case VertexElementFormat.Short4: return All11.UnsignedShort; case VertexElementFormat.NormalizedShort2: return All11.UnsignedShort; case VertexElementFormat.NormalizedShort4: return All11.UnsignedShort; case VertexElementFormat.HalfVector2: return All11.Float; case VertexElementFormat.HalfVector4: return All11.Float; } throw new NotImplementedException(); }
leave a comment