コード例 #1
0
        /// <summary>
        /// 生成一个用于存储索引的IBO。索引指定了<see cref="VertexBuffer"/>里各个顶点的渲染顺序。
        /// Generates a Index Buffer Object storing vertexes' indexes, which indicate the rendering order of each vertex.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="type"></param>
        /// <param name="usage"></param>
        /// <param name="first"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public static IndexBuffer GenIndexBuffer <T>(this T[] array, IndexBufferElementType type, BufferUsage usage, int first, int count) where T : struct
        {
            if (array == null)
            {
                throw new ArgumentNullException("array");
            }
            if (first < 0)
            {
                throw new ArgumentOutOfRangeException("first");
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count");
            }
            if (array.Length < first + count)
            {
                throw new ArgumentOutOfRangeException("first + count");
            }

            GCHandle pinned = GCHandle.Alloc(array, GCHandleType.Pinned);
            //IntPtr header = pinned.AddrOfPinnedObject();
            // same result with: IntPtr header = Marshal.UnsafeAddrOfPinnedArrayElement(array, 0);
            IntPtr             header         = Marshal.UnsafeAddrOfPinnedArrayElement(array, first);
            UnmanagedArrayBase unmanagedArray = new TempUnmanagedArray <T>(header, count);// It's not necessary to call Dispose() for this unmanaged array.
            IndexBuffer        buffer         = GenIndexBuffer(unmanagedArray, type, usage);

            pinned.Free();

            return(buffer);
        }
コード例 #2
0
        /// <summary>
        /// 获取顶点属性Buffer。描述顶点的位置或颜色或UV等各种属性。
        /// <para>每个<see cref="VertexBuffer"/>仅描述其中一个属性。</para>
        /// <para>Vertex Buffer Object that describes vertex' property(position, color, uv coordinate, etc.).</para>
        /// <para>Each <see cref="VertexBuffer"/> describes only 1 property.</para>
        /// </summary>
        /// <param name="array"></param>
        /// <param name="config">This <paramref name="config"/> decides parameters' values in glVertexAttribPointer(attributeLocation, size, type, false, 0, IntPtr.Zero);</param>
        /// <param name="varNameInVertexShader">此顶点属性VBO对应于vertex shader中的哪个in变量?<para>Mapping variable's name in vertex shader.</para></param>
        /// <param name="usage"></param>
        /// <param name="instancedDivisor">0: not instanced. 1: instanced divisor is 1.</param>
        /// <param name="patchVertexes">How many vertexes makes a patch? No patch if <paramref name="patchVertexes"/> is 0.</param>
        /// <returns></returns>
        public static VertexBuffer GenVertexBuffer <T>(this T[] array, VBOConfig config, string varNameInVertexShader, BufferUsage usage, uint instancedDivisor = 0, int patchVertexes = 0) where T : struct
        {
            GCHandle           pinned         = GCHandle.Alloc(array, GCHandleType.Pinned);
            IntPtr             header         = Marshal.UnsafeAddrOfPinnedArrayElement(array, 0);
            UnmanagedArrayBase unmanagedArray = new TempUnmanagedArray <T>(header, array.Length);// It's not neecessary to call Dispose() for this unmanaged array.
            VertexBuffer       buffer         = GenVertexBuffer(unmanagedArray, config, varNameInVertexShader, usage, instancedDivisor, patchVertexes);

            pinned.Free();

            return(buffer);
        }
コード例 #3
0
        /// <summary>
        /// Generates an independent buffer.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="array"></param>
        /// <param name="target"></param>
        /// <param name="usage"></param>
        /// <returns></returns>
        private static GLBuffer GenIndependentBuffer <T>(this T[] array, IndependentBufferTarget target, BufferUsage usage) where T : struct
        {
            GCHandle           pinned         = GCHandle.Alloc(array, GCHandleType.Pinned);
            IntPtr             header         = Marshal.UnsafeAddrOfPinnedArrayElement(array, 0);
            UnmanagedArrayBase unmanagedArray = new TempUnmanagedArray <T>(header, array.Length);// It's not neecessary to call Dispose() for this unmanaged array.
            GLBuffer           buffer         = GenIndependentBuffer(unmanagedArray, target, usage);

            pinned.Free();

            return(buffer);
        }
コード例 #4
0
        /// <summary>
        /// Fill all or part of buffer object's data store with a fixed value.
        /// </summary>
        /// <param name="offset">The offset, in basic machine units into the buffer object's data store at which to start filling.</param>
        /// <param name="size">The size, in basic machine units of the range of the data store to fill.</param>
        /// <param name="data">Specifies a pointer to a single pixel of data to upload. This parameter may not be null.</param>
        /// <param name="autoBind">Automatically call glBindBuffer() inside this method.</param>
        /// <returns></returns>
        public bool ClearBufferSubData(int offset, uint size, vec3 data, bool autoBind = true)
        {
            var                array          = new vec3[] { data };
            GCHandle           pin            = GCHandle.Alloc(array, GCHandleType.Pinned);
            IntPtr             header         = Marshal.UnsafeAddrOfPinnedArrayElement(array, 0);
            UnmanagedArrayBase unmanagedArray = new TempUnmanagedArray <vec3>(header, 1);
            bool               result         = ClearBufferSubData(OpenGL.GL_RGB32F, new IntPtr(offset), size, OpenGL.GL_RGB, OpenGL.GL_FLOAT, unmanagedArray, autoBind);

            pin.Free();

            return(result);
        }
コード例 #5
0
        /// <summary>
        /// Fill a buffer object's data store with a fixed value.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="autoBind">Automatically call glBindBuffer() inside this method.</param>
        /// <returns></returns>
        public bool ClearBufferData(vec3 data, bool autoBind = true)
        {
            //buffer.ClearBufferData(GL.GL_RGB32F, GL.GL_RGB, GL.GL_FLOAT, array);
            var                array          = new vec3[] { data };
            GCHandle           pin            = GCHandle.Alloc(array, GCHandleType.Pinned);
            IntPtr             header         = Marshal.UnsafeAddrOfPinnedArrayElement(array, 0);
            UnmanagedArrayBase unmanagedArray = new TempUnmanagedArray <vec3>(header, 1);
            bool               result         = ClearBufferData(GL.GL_RGB32F, GL.GL_RGB, GL.GL_FLOAT, unmanagedArray, autoBind);

            pin.Free();

            return(result);
        }
コード例 #6
0
        /// <summary>
        /// 生成一个用于存储索引的VBO。索引指定了<see cref="VertexBuffer"/>里各个顶点的渲染顺序。
        /// Generates a Vertex Buffer Object storing vertexes' indexes, which indicate the rendering order of each vertex.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="mode">用哪种方式渲染各个顶点?(OpenGL.GL_TRIANGLES etc.)</param>
        /// <param name="usage"></param>
        /// <param name="primCount">primCount in instanced rendering.</param>
        /// <returns></returns>
        private static OneIndexBuffer GenIndexBuffer <T>(this T[] array, DrawMode mode, BufferUsage usage, int primCount = 1) where T : struct
        {
            IndexBufferElementType elementType;

            if (typeof(T) == typeof(uint))
            {
                elementType = IndexBufferElementType.UInt;
            }
            else if (typeof(T) == typeof(ushort))
            {
                elementType = IndexBufferElementType.UShort;
            }
            else if (typeof(T) == typeof(byte))
            {
                elementType = IndexBufferElementType.UByte;
            }
            else
            {
                throw new ArgumentException(string.Format("Only uint/ushort/byte are allowed!"));
            }

            if (glGenBuffers == null)
            {
                InitFunctions();
            }

            GCHandle           pinned         = GCHandle.Alloc(array, GCHandleType.Pinned);
            IntPtr             header         = Marshal.UnsafeAddrOfPinnedArrayElement(array, 0);
            UnmanagedArrayBase unmanagedArray = new TempUnmanagedArray <T>(header, array.Length);// It's not neecessary to call Dispose() for this unmanaged array.
            var buffers = new uint[1];

            {
                glGenBuffers(1, buffers);
                const uint target = OpenGL.GL_ELEMENT_ARRAY_BUFFER;
                glBindBuffer(target, buffers[0]);
                glBufferData(target, unmanagedArray.ByteLength, unmanagedArray.Header, (uint)usage);
                glBindBuffer(target, 0);
            }
            pinned.Free();

            var buffer = new OneIndexBuffer(buffers[0], mode, elementType, unmanagedArray.Length, unmanagedArray.ByteLength, primCount);


            return(buffer);
        }
コード例 #7
0
        /// <summary>
        /// 生成若干用于存储索引的IBO。索引指定了<see cref="VertexBuffer"/>里各个顶点的渲染顺序。
        /// Generates some Index Buffer Objects storing vertexes' indexes, which indicate the rendering order of each vertex.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="type"></param>
        /// <param name="usage"></param>
        /// <param name="first"></param>
        /// <param name="blockSize">How many elements per index buffer?(sometimes except the last one)</param>
        /// <returns></returns>
        public static IndexBuffer[] GenIndexBuffers <T>(this T[] array, IndexBufferElementType type, BufferUsage usage, int first, int blockSize) where T : struct
        {
            if (array == null)
            {
                throw new ArgumentNullException("array");
            }
            if (first < 0)
            {
                throw new ArgumentOutOfRangeException("first");
            }
            if (blockSize <= 0)
            {
                throw new ArgumentOutOfRangeException("count");
            }
            if (array.Length <= first)
            {
                throw new ArgumentOutOfRangeException("first");
            }

            GCHandle pinned = GCHandle.Alloc(array, GCHandleType.Pinned);
            //IntPtr header = pinned.AddrOfPinnedObject();
            // same result with: IntPtr header = Marshal.UnsafeAddrOfPinnedArrayElement(array, 0);
            var list        = new List <IndexBuffer>();
            int current     = first;
            int totalLength = array.Length;

            do
            {
                IntPtr             header         = Marshal.UnsafeAddrOfPinnedArrayElement(array, current);
                int                length         = (current + blockSize <= totalLength) ? blockSize : (totalLength - current);
                UnmanagedArrayBase unmanagedArray = new TempUnmanagedArray <T>(header, length);// It's not necessary to call Dispose() for this unmanaged array.
                IndexBuffer        buffer         = GenIndexBuffer(unmanagedArray, type, usage);
                list.Add(buffer);

                current += length;
            } while (current < totalLength);
            pinned.Free();

            return(list.ToArray());
        }
コード例 #8
0
        /// <summary>
        /// Creates a <see cref="OneIndexBuffer"/> object directly in server side(GPU) without initializing its value.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="type"></param>
        /// <param name="mode"></param>
        /// <param name="usage"></param>
        /// <returns></returns>
        public static OneIndexBuffer GenIndexBuffer <T>(this T[] array, IndexBufferElementType type, DrawMode mode, BufferUsage usage) where T : struct
        {
            GCHandle pinned = GCHandle.Alloc(array, GCHandleType.Pinned);
            IntPtr   header = pinned.AddrOfPinnedObject();
            // same result with: IntPtr header = Marshal.UnsafeAddrOfPinnedArrayElement(array, 0);
            UnmanagedArrayBase unmanagedArray = new TempUnmanagedArray <T>(header, array.Length);// It's not neecessary to call Dispose() for this unmanaged array.
            int byteLength = unmanagedArray.ByteLength;

            uint[] buffers = new uint[1];
            {
                glGenBuffers(1, buffers);
                const uint target = GL.GL_ELEMENT_ARRAY_BUFFER;
                glBindBuffer(target, buffers[0]);
                glBufferData(target, byteLength, unmanagedArray.Header, (uint)usage);
                glBindBuffer(target, 0);
            }
            pinned.Free();

            var buffer = new OneIndexBuffer(
                buffers[0], mode, type, byteLength / type.GetSize(), byteLength);

            return(buffer);
        }