public TerrainPatchBuilder( )
        {
            int numVertices = 0;
            for ( int level = 0; level < MaxLodLevels; ++level )
            {
                numVertices += LevelPoolSize( level ) * NumberOfLevelVertices( level );
            }

            VertexBufferFormat format = new VertexBufferFormat( );
            format.Add( VertexFieldSemantic.Position, VertexFieldElementTypeId.Float32, 3 );
            format.Add( VertexFieldSemantic.Normal, VertexFieldElementTypeId.Float32, 3 );

            GraphicsLog.Info( "Allocating terrain patch builder VBO: {0} vertices in format {1}", numVertices, format );

            m_Buffer = Graphics.Factory.CreateVertexBuffer( );
            m_Buffer.Create( format, numVertices );

            int curVertexIndex = 0;
            for ( int level = 0; level < MaxLodLevels; ++level )
            {
                Lod newLod = new Lod( );
                m_LodLevels[ level ] = newLod;

                int numLevelVertices = NumberOfLevelVertices( level );
                int poolSize = LevelPoolSize( level );
                for ( int poolIndex = 0; poolIndex < poolSize; ++poolIndex )
                {
                    newLod.VbPool.Add( curVertexIndex );
                    curVertexIndex += numLevelVertices;
                }
                //	NOTE: BP: BABY P SAYS HELLO
            }
        }
        public SeaMesh( float width, float depth )
        {
            VertexBufferFormat vbFormat = new VertexBufferFormat( );
            vbFormat.Add( VertexFieldSemantic.Position, VertexFieldElementTypeId.Float32, 3 );
            vbFormat.Add( VertexFieldSemantic.Normal, VertexFieldElementTypeId.Float32, 3 );

            m_Vertices = Graphics.Factory.CreateVertexBuffer( );
        }
        /// <summary>
        /// Default constructor
        /// </summary>
        public TerrainPatchVertices( )
        {
            VertexBufferFormat format = new VertexBufferFormat( );
            format.Add( VertexFieldSemantic.Position, VertexFieldElementTypeId.Float32, 3 );
            format.Add( VertexFieldSemantic.Normal, VertexFieldElementTypeId.Float32, 3 );
            format.Add( VertexFieldSemantic.Texture0, VertexFieldElementTypeId.Float32, 2 );
            format.Add( VertexFieldSemantic.Texture1, VertexFieldElementTypeId.Float32, 2 );

            GraphicsLog.Info( "Creating terrain patch vertex pool using format {0}", format );

            m_Vb = Graphics.Factory.CreateVertexBuffer( );
            m_Vb.Create( format, TerrainPatchConstants.PatchTotalVertexCount * PoolSize );

            Clear( );
        }
        public PatchGrid( Terrain terrain, int gridWidth, int gridHeight )
        {
            int highestRes = Patch.GetLevelResolution( Patch.HighestDetailLod );
            highestRes *= highestRes;

            VertexBufferFormat format = new VertexBufferFormat( );
            format.Add( VertexFieldSemantic.Position, VertexFieldElementTypeId.Float32, 3 );
            m_Vb = RbGraphics.Factory.CreateVertexBuffer( );
            m_Vb.Create( format, gridWidth * gridHeight * highestRes );

            m_Patches = new Patch[ gridWidth, gridHeight ];

            float z = -PatchDepth * ( gridHeight / 2 );
            float xInc = PatchWidth;
            float zInc = PatchDepth;

            float maxWidth = gridWidth * PatchWidth;
            float maxHeight = gridWidth * PatchDepth;

            terrain.SetTerrainArea( maxWidth, maxHeight );

            int vbOffset = 0;

            for ( int row = 0; row < gridHeight; ++row, z += zInc )
            {
                float x = -PatchWidth * ( gridWidth / 2 );
                for ( int col = 0; col < gridWidth; ++col, x += xInc )
                {
                    Color c = ( ( col + row ) % 2 ) == 0 ? Color.Black : Color.White;

                    m_Patches[ col, row ] = new Patch( terrain, vbOffset, x, z, PatchWidth, PatchDepth, c );
                    vbOffset += highestRes;
                }
            }

            int maxCol = gridWidth - 1;
            int maxRow = gridHeight - 1;
            for ( int row = 0; row < gridHeight; ++row )
            {
                for ( int col = 0; col < gridWidth; ++col )
                {
                    Patch left	= ( col == 0 ) ? null : ( m_Patches[ col - 1, row ] );
                    Patch right	= ( col == maxCol ) ? null : ( m_Patches[ col + 1, row ] );
                    Patch up	= ( row == 0 ) ? null : ( m_Patches[ col, row - 1] );
                    Patch down	= ( row == maxRow ) ? null : ( m_Patches[ col, row + 1 ] );

                    m_Patches[ col, row ].Link( left, right, up, down );
                }
            }
        }
        public QuadPatchVertices( )
        {
            VertexBufferFormat format = new VertexBufferFormat( );
            format.Add( VertexFieldSemantic.Position, VertexFieldElementTypeId.Float32, 3 );

            m_Vb = Graphics.Factory.CreateVertexBuffer( );
            m_Vb.Create( format, QuadPatch.PatchResolution * QuadPatch.PatchResolution * PoolSize );

            int vertexIndex = 0;
            for ( int i = 0; i < PoolSize; ++i )
            {
                m_FreeList.Add( vertexIndex );
                vertexIndex += QuadPatch.PatchResolution * QuadPatch.PatchResolution;
            }
        }
        private void BuildBuffers( int maxParticles )
        {
            m_MaxParticles = maxParticles;
            m_Vb = Graphics.Factory.CreateVertexBuffer( );

            VertexBufferFormat vbFormat = new VertexBufferFormat( );
            vbFormat.Add( VertexFieldSemantic.Position, VertexFieldElementTypeId.Float32, 3 );
            vbFormat.Add( VertexFieldSemantic.Texture0, VertexFieldElementTypeId.Float32, 2 );
            vbFormat.Static = false;
            m_Vb.Create( vbFormat, maxParticles * 4 );

            m_Ib = Graphics.Factory.CreateIndexBuffer( );

            ushort[] indices = new ushort[ maxParticles * 6 ];
            int curIndex = 0;
            ushort indexValue = 0;
            for ( int particleCount = 0; particleCount < maxParticles; ++particleCount )
            {
                indices[ curIndex++ ] = indexValue;
                indices[ curIndex++ ] = ( ushort )( indexValue + 1 );
                indices[ curIndex++ ] = ( ushort )( indexValue + 3 );

                indices[ curIndex++ ] = ( ushort )( indexValue + 1 );
                indices[ curIndex++ ] = ( ushort )( indexValue + 2 );
                indices[ curIndex++ ] = ( ushort )( indexValue + 3 );

                indexValue += 4;
            }
            m_Ib.Create( indices, true );
        }
        /// <summary>
        /// Creates a geo sphere
        /// </summary>
        private IRenderable CreateGeoSphere( Units.Metres radius, int subdivisions )
        {
            m_GeometryRadius = radius;
            Vector3[] sideNormals = new Vector3[ 6 ]
                {
                    new Vector3( 1, 0, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),
                    new Vector3( -1, 0, 0 ), new Vector3( 0, -1, 0 ), new Vector3( 0, 0, -1 )
                };
            VertexBufferFormat format = new VertexBufferFormat( );
            format.Add<float>( VertexFieldSemantic.Position, 3 );
            format.Add<float>( VertexFieldSemantic.Normal, 3 );
            format.Add<float>( VertexFieldSemantic.Texture0, 2 );

            float renderRadius = radius.ToRenderUnits;
            float modelSideLength = 10.0f;
            float uvMul = 1.0f / subdivisions;

            VertexBufferBuilder vbBuilder = new VertexBufferBuilder( format );
            for ( int sideNormalIndex = 0; sideNormalIndex < sideNormals.Length; ++sideNormalIndex )
            {
                Vector3 sideNormal = sideNormals[ sideNormalIndex ];
                Vector3 xAxis = sideNormals[ ( sideNormalIndex + 1 ) % sideNormals.Length ];
                Vector3 yAxis = sideNormals[ ( sideNormalIndex + 2 ) % sideNormals.Length ];
                Vector3 xStride = xAxis * modelSideLength;
                Vector3 yStride = yAxis * modelSideLength;
                Vector3 xStep = xStride / subdivisions;
                Vector3 yStep = yStride / subdivisions;

                Point3 mid = Point3.Origin + sideNormal * modelSideLength / 2;

                Point3 topLeft = mid - ( xStride / 2 ) - ( yStride / 2 );
                Point3 sidePos = topLeft;
                for ( int y = 0; y < subdivisions; ++y )
                {
                    Point3 curPos = sidePos;
                    float v = y * uvMul;
                    float nV = ( y + 1 ) * uvMul;

                    for ( int x = 0; x < subdivisions; ++x )
                    {
                        Vector3 sphereNormal = curPos.ToVector3( ).MakeNormal( );
                        Vector3 sphereNxNormal = ( curPos + xStep ).ToVector3( ).MakeNormal( );
                        Vector3 sphereNyNormal = ( curPos + yStep ).ToVector3( ).MakeNormal( );
                        Vector3 sphereNxNyNormal = ( curPos + xStep + yStep ).ToVector3( ).MakeNormal( );

                        Point3 spherePos = ( sphereNormal * renderRadius ).ToPoint3( );
                        Point3 sphereNxPos = ( sphereNxNormal * renderRadius ).ToPoint3( );
                        Point3 sphereNyPos = ( sphereNyNormal * renderRadius ).ToPoint3( );
                        Point3 sphereNxNyPos = ( sphereNxNyNormal * renderRadius ).ToPoint3( );

                        float u = x * uvMul;
                        float nU = ( x + 1 ) * uvMul;

                        vbBuilder.Add( VertexFieldSemantic.Position, spherePos );
                        vbBuilder.Add( VertexFieldSemantic.Normal, sphereNormal );
                        vbBuilder.Add( VertexFieldSemantic.Texture0, u, v );

                        vbBuilder.Add( VertexFieldSemantic.Position, sphereNxPos );
                        vbBuilder.Add( VertexFieldSemantic.Normal, sphereNxNormal );
                        vbBuilder.Add( VertexFieldSemantic.Texture0, nU, v );

                        vbBuilder.Add( VertexFieldSemantic.Position, sphereNyPos );
                        vbBuilder.Add( VertexFieldSemantic.Normal, sphereNyNormal );
                        vbBuilder.Add( VertexFieldSemantic.Texture0, u, nV );

                        vbBuilder.Add( VertexFieldSemantic.Position, sphereNxPos );
                        vbBuilder.Add( VertexFieldSemantic.Normal, sphereNxNormal );
                        vbBuilder.Add( VertexFieldSemantic.Texture0, nU, v );

                        vbBuilder.Add( VertexFieldSemantic.Position, sphereNxNyPos );
                        vbBuilder.Add( VertexFieldSemantic.Normal, sphereNxNyNormal );
                        vbBuilder.Add( VertexFieldSemantic.Texture0, nU, nV );

                        vbBuilder.Add( VertexFieldSemantic.Position, sphereNyPos );
                        vbBuilder.Add( VertexFieldSemantic.Normal, sphereNyNormal );
                        vbBuilder.Add( VertexFieldSemantic.Texture0, u, nV );

                        curPos += xStep;
                    }
                    sidePos += yStep;
                }
            }

            return new VertexBufferRenderer( vbBuilder.Build( ), PrimitiveType.TriList );
        }