kelthar

VertexDeclaration for XNATouch / MonoGame

Posted in iPhone Development by kelthar on February 25, 2011

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