Esempio n. 1
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T">The type of the vertices</typeparam>
        /// <param name="primitiveT">The type of primitives to draw with the vertices</param>
        /// <param name="vertexData">An array of vertices to draw</param>
        /// <param name="vertexOffset">The index in the array of the first vertex to draw</param>
        /// <param name="numVertices">The number of vertices to draw</param>
        /// <param name="indexData">The index data</param>
        /// <param name="indexOffset">The index in the array of indices of the first index to use</param>
        /// <param name="primitiveCount">The number of primitives to draw</param>
        /// <param name="vertexDeclaration">The layout of the vertices</param>
        public void DrawUserIndexedPrimitives <T>(PrimitiveType primitiveT, T[] vertexData, int vertexOffset,
                                                  int numVertices, short[] indexData, int indexOffset, int primitiveCount, VertexDeclaration vertexDeclaration) where T : struct
        {
            if (vertexData == null || vertexData.Length == 0)
            {
                throw new ArgumentNullException("vertexData");
            }
            if (vertexOffset < 0 || vertexOffset >= vertexData.Length)
            {
                throw new ArgumentNullException("vertexOffset");
            }
            if (numVertices <= 0 || numVertices > vertexData.Length)
            {
                throw new ArgumentNullException("numVertices");
            }
            if (vertexOffset + numVertices > vertexData.Length)
            {
                throw new ArgumentOutOfRangeException("numVertices & vertexOffset out of index");
            }
            if (indexData == null || indexData.Length == 0)
            {
                throw new ArgumentNullException("indexData");
            }
            if (indexOffset < 0 || indexOffset >= indexData.Length)
            {
                throw new ArgumentOutOfRangeException("indexOffset");
            }
            if (primitiveCount <= 0)
            {
                throw new ArgumentOutOfRangeException("primitiveCount");
            }
            if (indexOffset + GetElementCountArray(primitiveT, primitiveCount) > indexData.Length)
            {
                throw new ArgumentOutOfRangeException("primitiveCount");
            }

            if (vertexDeclaration == null)
            {
                throw new ArgumentNullException("vertexDeclaration");
            }

            PlatformDrawUserIndexedPrimitives <T>(primitiveT, vertexData, vertexOffset, numVertices, indexData, indexOffset, primitiveCount, vertexDeclaration);

            unchecked
            {
                _graphicsMetrics._drawCount++;
                _graphicsMetrics._primitiveCount += primitiveCount;
            }
        }
Esempio n. 2
0
        private void PlatformDrawUserIndexedPrimitives <T>(PrimitiveType primitiveT, T[] vertexData, int vertexOffset, int numVertices, short[] indexData, int indexOffset, int primitiveCount, VertexDeclaration vertexDeclaration)
        {
            ApplyState(true);

            //Unbind current VBOs
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            GraphicsExtensions.CheckGLError();
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
            GraphicsExtensions.CheckGLError();
            _vertexBuffersDirty = _indexBufferDirty = true;

            //固定对象的地址,这样可以防止垃圾回收器移动对象,从而破坏垃圾收集器的效率,使用Free方法尽快释放分配的句柄
            var vbHandle = GCHandle.Alloc(vertexData, GCHandleType.Pinned);
            var ibHandle = GCHandle.Alloc(indexData, GCHandleType.Pinned);

            var vertexAddr = (IntPtr)(vbHandle.AddrOfPinnedObject().ToInt64() + vertexDeclaration.VertexStride * vertexOffset);

            vertexDeclaration.GraphicsDevice = this;

            //设置顶点声明指向VertexBuffer Data
            var programHash = _vertexShader.HashKey | _pixelShader.HashKey;

            vertexDeclaration.Apply(_vertexShader, vertexAddr, programHash);

            GL.DrawElements(PrimitiveTypeGL(primitiveT),
                            GetElementCountArray(primitiveT, primitiveCount),
                            DrawElementsType.UnsignedShort,
                            (IntPtr)(ibHandle.AddrOfPinnedObject().ToInt64() + (indexOffset * sizeof(short))));

            GraphicsExtensions.CheckGLError();

            //Release Handle
            ibHandle.Free();
            vbHandle.Free();
        }