/// <summary> /// Creates a <see cref="VertexBuffer"/> object(actually an array) directly in server side(GPU) without initializing its value. /// </summary> /// <param name="elementType">element's type of this 'array'.</param> /// <param name="length">How many elements are there?</param> /// <param name="config">mapping to vertex shader's 'in' type.</param> /// <param name="varNameInVertexShader">mapping to vertex shader's 'in' name.</param> /// <param name="usage"></param> /// <param name="instanceDivisor"></param> /// <param name="patchVertexes"></param> /// <returns></returns> public static VertexBuffer Create(Type elementType, int length, VBOConfig config, string varNameInVertexShader, BufferUsage usage, uint instanceDivisor = 0, int patchVertexes = 0) { if (!elementType.IsValueType) { throw new ArgumentException(string.Format("{0} must be a value type!", elementType)); } if (glGenBuffers == null) { glGenBuffers = OpenGL.GetDelegateFor <OpenGL.glGenBuffers>(); } if (glBindBuffer == null) { glBindBuffer = OpenGL.GetDelegateFor <OpenGL.glBindBuffer>(); } if (glBufferData == null) { glBufferData = OpenGL.GetDelegateFor <OpenGL.glBufferData>(); } int byteLength = Marshal.SizeOf(elementType) * length; uint[] buffers = new uint[1]; glGenBuffers(1, buffers); const uint target = OpenGL.GL_ARRAY_BUFFER; glBindBuffer(target, buffers[0]); glBufferData(target, byteLength, IntPtr.Zero, (uint)usage); glBindBuffer(target, 0); var buffer = new VertexBuffer( buffers[0], config, varNameInVertexShader, length, byteLength, instanceDivisor, patchVertexes); return(buffer); }
/// <summary> /// Vertex' attribute buffer's pointer. /// </summary> /// <param name="bufferId">用glGenBuffers()得到的VBO的Id。<para>Id got from glGenBuffers();</para></param> /// <param name="config">This <paramref name="config"/> decides parameters' values in glVertexAttribPointer(attributeLocation, size, type, false, 0, IntPtr.Zero); /// </param> /// <param name="length">此VBO含有多个个元素?<para>How many elements?</para></param> /// <param name="byteLength">此VBO中的数据在内存中占用多少个字节?<para>How many bytes in this buffer?</para></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> internal VertexBuffer( uint bufferId, VBOConfig config, int length, int byteLength, uint instancedDivisor = 0, int patchVertexes = 0) : base(bufferId, length, byteLength) { this.Config = config; this.InstancedDivisor = instancedDivisor; this.PatchVertexes = patchVertexes; }
/// <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="usage"></param> /// <param name="first"></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, BufferUsage usage, int first, uint instancedDivisor = 0, int patchVertexes = 0) where T : struct { if (array == null) { throw new ArgumentNullException("array"); } return(GenVertexBuffer(array, config, usage, first, array.Length, instancedDivisor, patchVertexes)); }
/// <summary> /// Vertex' attribute buffer's pointer. /// </summary> /// <param name="bufferId">用glGenBuffers()得到的VBO的Id。<para>Id got from glGenBuffers();</para></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="length">此VBO含有多个个元素?<para>How many elements?</para></param> /// <param name="byteLength">此VBO中的数据在内存中占用多少个字节?<para>How many bytes in this buffer?</para></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> internal VertexBuffer( uint bufferId, VBOConfig config, string varNameInVertexShader, int length, int byteLength, uint instancedDivisor = 0, int patchVertexes = 0) : base(bufferId, length, byteLength) { this.VarNameInVertexShader = varNameInVertexShader; this.Config = config; this.InstancedDivisor = instancedDivisor; this.PatchVertexes = patchVertexes; }
/// <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="usage"></param> /// <param name="blockSize">How many elements in a block?</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[] GenVertexBuffers <T>(this T[] array, VBOConfig config, BufferUsage usage, int blockSize, uint instancedDivisor = 0, int patchVertexes = 0) where T : struct { if (array == null) { throw new ArgumentNullException("array"); } const int first = 0; return(GenVertexBuffers(array, config, usage, first, blockSize, instancedDivisor, patchVertexes)); }
/// <summary> /// Vertex' attribute buffer's pointer. /// </summary> /// <param name="bufferId">用glGenBuffers()得到的VBO的Id。<para>Id got from glGenBuffers();</para></param> /// <param name="config">This <paramref name="config"/> decides parameters' values in glVertexAttribPointer(attributeLocation, size, type, false, 0, IntPtr.Zero); /// </param> /// <param name="vertexCount">此VBO含有多个个元素?<para>How many elements?</para></param> /// <param name="byteLength">此VBO中的数据在内存中占用多少个字节?<para>How many bytes in this buffer?</para></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> internal VertexBuffer( uint bufferId, VBOConfig config, int vertexCount, int byteLength, uint instancedDivisor = 0, int patchVertexes = 0) : base(bufferId, vertexCount, byteLength) { this.Target = BufferTarget.ArrayBuffer; this.Config = config; this.InstancedDivisor = instancedDivisor; this.PatchVertexes = patchVertexes; }
/// <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); }
/// <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="data"></param> /// <param name="config">This <paramref name="config"/> decides parameters' values in glVertexAttribPointer(attributeLocation, size, type, false, 0, IntPtr.Zero);</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 data, VBOConfig config, BufferUsage usage, uint instancedDivisor = 0, int patchVertexes = 0) where T : struct { var array = new T[] { data }; return(GenVertexBuffer(array, config, usage, instancedDivisor, patchVertexes)); // another way to do this: //using (UnmanagedArrayBase unmanagedArray = new UnmanagedArray<T>(1)) //{ // Marshal.StructureToPtr(data, unmanagedArray.Header, false); // VertexBuffer buffer = GetVertexBufferObject(unmanagedArray, config, usage, instancedDivisor, patchVertexes); // return buffer; //} }
/// <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(this UnmanagedArrayBase array, VBOConfig config, string varNameInVertexShader, BufferUsage usage, uint instancedDivisor = 0, int patchVertexes = 0) { uint[] buffers = new uint[1]; glGenBuffers(1, buffers); const uint target = OpenGL.GL_ARRAY_BUFFER; glBindBuffer(target, buffers[0]); glBufferData(target, array.ByteLength, array.Header, (uint)usage); glBindBuffer(target, 0); var buffer = new VertexBuffer( buffers[0], config, array.Length, array.ByteLength, instancedDivisor, patchVertexes); return(buffer); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="array"></param> /// <param name="config"></param> /// <param name="varNameInVertexShader"></param> /// <param name="usage"></param> /// <param name="instancedDivisor"></param> /// <param name="patchVertexes"></param> /// <returns></returns> public static GLVertexNode Create <T>(T[] array, VBOConfig config, string varNameInVertexShader, BufferUsage usage, uint instancedDivisor = 0, int patchVertexes = 0) { var node = new GLVertexNode(); node.array = array; node.length = array.Length; node.byteLength = array.Length * Marshal.SizeOf(typeof(T)); node.config = config; node.varNameInVertexShader = varNameInVertexShader; node.usage = usage; node.instancedDivisor = instancedDivisor; node.patchVertexes = patchVertexes; return(node); }
/// <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="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(this UnmanagedArrayBase array, VBOConfig config, BufferUsage usage, uint instancedDivisor = 0, int patchVertexes = 0) { var ids = new uint[1]; { glGenBuffers(1, ids); const uint target = GL.GL_ARRAY_BUFFER; glBindBuffer(target, ids[0]); glBufferData(target, array.ByteLength, array.Header, (uint)usage); glBindBuffer(target, 0); } var buffer = new VertexBuffer( ids[0], config, array.Length, array.ByteLength, instancedDivisor, patchVertexes); return(buffer); }
/// <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(this UnmanagedArrayBase array, VBOConfig config, string varNameInVertexShader, BufferUsage usage, uint instancedDivisor = 0, int patchVertexes = 0) { if (glGenBuffers == null) { InitFunctions(); } uint[] buffers = new uint[1]; glGenBuffers(1, buffers); const uint target = OpenGL.GL_ARRAY_BUFFER; glBindBuffer(target, buffers[0]); glBufferData(target, array.ByteLength, array.Header, (uint)usage); glBindBuffer(target, 0); var buffer = new VertexBuffer( buffers[0], config, varNameInVertexShader, array.Length, array.ByteLength, instancedDivisor, patchVertexes); return buffer; }
/// <summary> /// Creates a <see cref="VertexBuffer"/> object(actually an array) directly in server side(GPU) without initializing its value. /// </summary> /// <param name="elementType">element's type of this 'array'.</param> /// <param name="length">How many elements are there?</param> /// <param name="config">mapping to vertex shader's 'in' type.</param> /// <param name="varNameInVertexShader">mapping to vertex shader's 'in' name.</param> /// <param name="usage"></param> /// <param name="instanceDivisor"></param> /// <param name="patchVertexes"></param> /// <returns></returns> public static VertexBuffer Create(Type elementType, int length, VBOConfig config, string varNameInVertexShader, BufferUsage usage, uint instanceDivisor = 0, int patchVertexes = 0) { if (!elementType.IsValueType) { throw new ArgumentException(string.Format("{0} must be a value type!", elementType)); } if (glGenBuffers == null) { glGenBuffers = OpenGL.GetDelegateFor<OpenGL.glGenBuffers>(); } if (glBindBuffer == null) { glBindBuffer = OpenGL.GetDelegateFor<OpenGL.glBindBuffer>(); } if (glBufferData == null) { glBufferData = OpenGL.GetDelegateFor<OpenGL.glBufferData>(); } int byteLength = Marshal.SizeOf(elementType) * length; uint[] buffers = new uint[1]; glGenBuffers(1, buffers); const uint target = OpenGL.GL_ARRAY_BUFFER; glBindBuffer(target, buffers[0]); glBufferData(target, byteLength, IntPtr.Zero, (uint)usage); glBindBuffer(target, 0); var buffer = new VertexBuffer( buffers[0], config, varNameInVertexShader, length, byteLength, instanceDivisor, patchVertexes); return buffer; }
/// <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="usage"></param> /// <param name="first"></param> /// <param name="blockSize">How many elements per index buffer?(sometimes except the last one)</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[] GenVertexBuffers <T>(this T[] array, VBOConfig config, BufferUsage usage, int first, int blockSize, uint instancedDivisor = 0, int patchVertexes = 0) 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 <VertexBuffer>(); 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. VertexBuffer buffer = GenVertexBuffer(unmanagedArray, config, usage, instancedDivisor, patchVertexes); list.Add(buffer); current += length; } while (current < totalLength); pinned.Free(); return(list.ToArray()); }
internal static int GetDataTypeByteLength(this VBOConfig config) { int result = 0; switch (config) { case VBOConfig.Byte: result = sizeof(byte); break; case VBOConfig.BVec2: result = sizeof(byte); break; case VBOConfig.BVec3: result = sizeof(byte); break; case VBOConfig.BVec4: result = sizeof(byte); break; case VBOConfig.Int: result = sizeof(int); break; case VBOConfig.IVec2: result = sizeof(int); break; case VBOConfig.IVec3: result = sizeof(int); break; case VBOConfig.IVec4: result = sizeof(int); break; case VBOConfig.UInt: result = sizeof(uint); break; case VBOConfig.UVec2: result = sizeof(uint); break; case VBOConfig.UVec3: result = sizeof(uint); break; case VBOConfig.UVec4: result = sizeof(uint); break; case VBOConfig.Float: result = sizeof(float); break; case VBOConfig.Vec2: result = sizeof(float); break; case VBOConfig.Vec3: result = sizeof(float); break; case VBOConfig.Vec4: result = sizeof(float); break; case VBOConfig.Double: result = sizeof(double); break; case VBOConfig.DVec2: result = sizeof(double); break; case VBOConfig.DVec3: result = sizeof(double); break; case VBOConfig.DVec4: result = sizeof(double); break; case VBOConfig.Mat2: result = sizeof(float); break; case VBOConfig.Mat3: result = sizeof(float); break; case VBOConfig.Mat4: result = sizeof(float); break; default: throw new System.NotImplementedException(); } return(result); }
internal static int GetDataTypeByteLength(this VBOConfig config) { int result = 0; switch (config) { case VBOConfig.Byte: result = sizeof(byte); break; case VBOConfig.BVec2: result = sizeof(byte); break; case VBOConfig.BVec3: result = sizeof(byte); break; case VBOConfig.BVec4: result = sizeof(byte); break; case VBOConfig.Int: result = sizeof(int); break; case VBOConfig.IVec2: result = sizeof(int); break; case VBOConfig.IVec3: result = sizeof(int); break; case VBOConfig.IVec4: result = sizeof(int); break; case VBOConfig.UInt: result = sizeof(uint); break; case VBOConfig.UVec2: result = sizeof(uint); break; case VBOConfig.UVec3: result = sizeof(uint); break; case VBOConfig.UVec4: result = sizeof(uint); break; case VBOConfig.Float: result = sizeof(float); break; case VBOConfig.Vec2: result = sizeof(float); break; case VBOConfig.Vec3: result = sizeof(float); break; case VBOConfig.Vec4: result = sizeof(float); break; case VBOConfig.Double: result = sizeof(double); break; case VBOConfig.DVec2: result = sizeof(double); break; case VBOConfig.DVec3: result = sizeof(double); break; case VBOConfig.DVec4: result = sizeof(double); break; case VBOConfig.Mat2: result = sizeof(float); break; case VBOConfig.Mat3: result = sizeof(float); break; case VBOConfig.Mat4: result = sizeof(float); break; default: throw new NotDealWithNewEnumItemException(typeof(VBOConfig)); } return(result); }
/// <summary> /// Use this <see cref="UniformBuffer"/> as a <see cref="VertexBuffer"/>. /// </summary> /// <param name="config"></param> /// <returns></returns> public VertexBuffer AsVertexBuffer(VBOConfig config) { var buffer = new VertexBuffer(this.BufferId, config, this.Length, this.ByteLength); return(buffer); }
/// <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="header">array's Header.</param> /// <param name="length">array's Length.</param> /// <param name="byteLength">array's ByteLength.</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(IntPtr header, int length, int byteLength, VBOConfig config, string varNameInVertexShader, BufferUsage usage, uint instancedDivisor = 0, int patchVertexes = 0) { if (glGenBuffers == null) { InitFunctions(); } uint[] buffers = new uint[1]; glGenBuffers(1, buffers); const uint target = OpenGL.GL_ARRAY_BUFFER; glBindBuffer(target, buffers[0]); glBufferData(target, byteLength, header, (uint)usage); glBindBuffer(target, 0); var buffer = new VertexBuffer( buffers[0], config, varNameInVertexShader, length, byteLength, instancedDivisor, patchVertexes); return(buffer); }
/// <summary> /// Gets parameter values for glVertexAttribPointer() and glEnable/DisableVertexAttribArray(). /// <para>second parameter in glVertexAttribPointer(uint index, int size, uint type, bool normalized, int stride, IntPtr pointer);</para> /// <para>How many primitive data type(float/int/uint etc) are there in a data unit?</para> /// </summary> /// <param name="config"></param> internal static int GetDataSize(this VBOConfig config) { int dataSize = 0; switch (config) { case VBOConfig.Byte: dataSize = 1; break; case VBOConfig.BVec2: dataSize = 2; break; case VBOConfig.BVec3: dataSize = 3; break; case VBOConfig.BVec4: dataSize = 4; break; case VBOConfig.Int: dataSize = 1; break; case VBOConfig.IVec2: dataSize = 2; break; case VBOConfig.IVec3: dataSize = 3; break; case VBOConfig.IVec4: dataSize = 4; break; case VBOConfig.UInt: dataSize = 1; break; case VBOConfig.UVec2: dataSize = 2; break; case VBOConfig.UVec3: dataSize = 3; break; case VBOConfig.UVec4: dataSize = 4; break; case VBOConfig.Float: dataSize = 1; break; case VBOConfig.Vec2: dataSize = 2; break; case VBOConfig.Vec3: dataSize = 3; break; case VBOConfig.Vec4: dataSize = 4; break; case VBOConfig.Double: dataSize = 1; break; case VBOConfig.DVec2: dataSize = 2; break; case VBOConfig.DVec3: dataSize = 3; break; case VBOConfig.DVec4: dataSize = 4; break; case VBOConfig.Mat2: dataSize = 2; break; case VBOConfig.Mat3: dataSize = 3; break; case VBOConfig.Mat4: dataSize = 4; break; default: throw new NotDealWithNewEnumItemException(typeof(VBOConfig)); } return(dataSize); }
/// <summary> /// Gets parameter values for glVertexAttribPointer() and glEnable/DisableVertexAttribArray(). /// <para>second parameter in glVertexAttribPointer(uint index, int size, uint type, bool normalized, int stride, IntPtr pointer);</para> /// <para>How many primitive data type(float/int/uint etc) are there in a data unit?</para> /// </summary> /// <param name="config"></param> internal static int GetDataSize(this VBOConfig config) { int dataSize = 0; switch (config) { case VBOConfig.Byte: dataSize = 1; break; case VBOConfig.BVec2: dataSize = 2; break; case VBOConfig.BVec3: dataSize = 3; break; case VBOConfig.BVec4: dataSize = 4; break; case VBOConfig.Int: dataSize = 1; break; case VBOConfig.IVec2: dataSize = 2; break; case VBOConfig.IVec3: dataSize = 3; break; case VBOConfig.IVec4: dataSize = 4; break; case VBOConfig.UInt: dataSize = 1; break; case VBOConfig.UVec2: dataSize = 2; break; case VBOConfig.UVec3: dataSize = 3; break; case VBOConfig.UVec4: dataSize = 4; break; case VBOConfig.Float: dataSize = 1; break; case VBOConfig.Vec2: dataSize = 2; break; case VBOConfig.Vec3: dataSize = 3; break; case VBOConfig.Vec4: dataSize = 4; break; case VBOConfig.Double: dataSize = 1; break; case VBOConfig.DVec2: dataSize = 2; break; case VBOConfig.DVec3: dataSize = 3; break; case VBOConfig.DVec4: dataSize = 4; break; case VBOConfig.Mat2: dataSize = 2; break; case VBOConfig.Mat3: dataSize = 3; break; case VBOConfig.Mat4: dataSize = 4; break; default: throw new NotImplementedException(); } return(dataSize); }
/// <summary> /// Gets parameter values for glVertexAttribPointer() and glEnable/DisableVertexAttribArray(). /// </summary> /// <param name="config"></param> internal static VBOConfigDetail Parse(this VBOConfig config) { var result = new VBOConfigDetail(); switch (config) { case VBOConfig.Byte: result.dataSize = 1; result.dataType = GL.GL_BYTE; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.BVec2: result.dataSize = 2; result.dataType = GL.GL_BYTE; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.BVec3: result.dataSize = 3; result.dataType = GL.GL_BYTE; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.BVec4: result.dataSize = 4; result.dataType = GL.GL_BYTE; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.Int: result.dataSize = 1; result.dataType = GL.GL_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.IVec2: result.dataSize = 2; result.dataType = GL.GL_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.IVec3: result.dataSize = 3; result.dataType = GL.GL_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.IVec4: result.dataSize = 4; result.dataType = GL.GL_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.UInt: result.dataSize = 1; result.dataType = GL.GL_UNSIGNED_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.UVec2: result.dataSize = 2; result.dataType = GL.GL_UNSIGNED_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.UVec3: result.dataSize = 3; result.dataType = GL.GL_UNSIGNED_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.UVec4: result.dataSize = 4; result.dataType = GL.GL_UNSIGNED_INT; result.pointerType = VertexAttribPointerType.Integer; break; case VBOConfig.Float: result.dataSize = 1; result.dataType = GL.GL_FLOAT; result.pointerType = VertexAttribPointerType.Default; break; case VBOConfig.Vec2: result.dataSize = 2; result.dataType = GL.GL_FLOAT; result.pointerType = VertexAttribPointerType.Default; break; case VBOConfig.Vec3: result.dataSize = 3; result.dataType = GL.GL_FLOAT; result.pointerType = VertexAttribPointerType.Default; break; case VBOConfig.Vec4: result.dataSize = 4; result.dataType = GL.GL_FLOAT; result.pointerType = VertexAttribPointerType.Default; break; case VBOConfig.Double: result.dataSize = 1; result.dataType = GL.GL_DOUBLE; result.pointerType = VertexAttribPointerType.Long; break; case VBOConfig.DVec2: result.dataSize = 2; result.dataType = GL.GL_DOUBLE; result.pointerType = VertexAttribPointerType.Long; break; case VBOConfig.DVec3: result.dataSize = 3; result.dataType = GL.GL_DOUBLE; result.pointerType = VertexAttribPointerType.Long; break; case VBOConfig.DVec4: result.dataSize = 4; result.dataType = GL.GL_DOUBLE; result.pointerType = VertexAttribPointerType.Long; break; case VBOConfig.Mat2: result.locationCount = 2; result.dataSize = 2; result.dataType = GL.GL_FLOAT; result.stride = Marshal.SizeOf(typeof(mat2)); result.startOffsetUnit = Marshal.SizeOf(typeof(vec2)); result.pointerType = VertexAttribPointerType.Default; break; case VBOConfig.Mat3: result.locationCount = 3; result.dataSize = 3; result.dataType = GL.GL_FLOAT; result.stride = Marshal.SizeOf(typeof(mat3)); result.startOffsetUnit = Marshal.SizeOf(typeof(vec3)); result.pointerType = VertexAttribPointerType.Default; break; case VBOConfig.Mat4: result.locationCount = 4; result.dataSize = 4; result.dataType = GL.GL_FLOAT; result.stride = Marshal.SizeOf(typeof(mat4)); result.startOffsetUnit = Marshal.SizeOf(typeof(vec4)); result.pointerType = VertexAttribPointerType.Default; break; default: throw new Exception("Unexpected VBOConfig!"); } return(result); }
/// <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(this UnmanagedArrayBase array, VBOConfig config, string varNameInVertexShader, BufferUsage usage, uint instancedDivisor = 0, int patchVertexes = 0) { return(GenVertexBuffer(array.Header, array.Length, array.ByteLength, config, varNameInVertexShader, usage, instancedDivisor, patchVertexes)); }