/// <summary> /// 顶点属性Buffer。描述顶点的位置或颜色或UV等各种属性。 /// <para>每个<see cref="VertexAttributeBuffer<T>"/>仅描述其中一个属性。</para> /// <para>Vertex Buffer Object that describes vertex' property(position, color, uv coordinate, etc.).</para> /// <para>Each <see cref="VertexAttributeBuffer<T>"/> describes only 1 property.</para> /// <para>Note: If <typeparamref name="T"/> matches one of this.Config's value, then (Ptr.ByteLength / (Ptr.DataSize * Ptr.DataTypeByteLength)) equals (Ptr.Length).</para> /// <para><typeparamref name="T"/> is type of element of this array in application level.</para> /// </summary> /// <param name="varNameInVertexShader">此顶点属性VBO对应于vertex shader中的哪个in变量?<para>Mapping variable's name in vertex shader.</para></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> public VertexAttributeBuffer(string varNameInVertexShader, VertexAttributeConfig config, BufferUsage usage, uint instancedDivisor = 0, int patchVertexes = 0) : base(usage) { this.VarNameInVertexShader = varNameInVertexShader; this.Config = config; this.InstancedDivisor = instancedDivisor; this.PatchVertexes = patchVertexes; }
/// <summary> /// Vertex' attribute buffer's pointer. /// </summary> /// <param name="varNameInVertexShader">此顶点属性VBO对应于vertex shader中的哪个in变量?<para>Mapping variable's name in vertex shader.</para></param> /// <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 VertexAttributeBufferPtr(string varNameInVertexShader, uint bufferId, VertexAttributeConfig config, int length, int byteLength, uint instancedDivisor = 0, int patchVertexes = 0) : base(bufferId, length, byteLength) { if (glVertexAttribPointer == null) { glVertexAttribPointer = OpenGL.GetDelegateFor <OpenGL.glVertexAttribPointer>(); glEnableVertexAttribArray = OpenGL.GetDelegateFor <OpenGL.glEnableVertexAttribArray>(); glVertexAttribDivisor = OpenGL.GetDelegateFor <OpenGL.glVertexAttribDivisor>(); glPatchParameteri = OpenGL.GetDelegateFor <OpenGL.glPatchParameteri>(); glPatchParameterfv = OpenGL.GetDelegateFor <OpenGL.glPatchParameterfv>(); } this.VarNameInVertexShader = varNameInVertexShader; this.Config = config; this.InstancedDivisor = instancedDivisor; this.PatchVertexes = patchVertexes; }
/// <summary> /// Gets parameter values for glVertexAttribPointer() and glEnable/DisableVertexAttribArray(). /// </summary> /// <param name="config"></param> /// <param name="locationCount"></param> /// <param name="dataSize"></param> /// <param name="dataType"></param> /// <param name="stride"></param> /// <param name="startOffsetUnit"></param> public static void Parse(this VertexAttributeConfig config, out int locationCount, out int dataSize, out uint dataType, out int stride, out int startOffsetUnit) { locationCount = 1; //dataSize = 0; //dataType = 0; stride = 0; startOffsetUnit = 0; switch (config) { case VertexAttributeConfig.Byte: dataSize = 1; dataType = OpenGL.GL_BYTE; break; case VertexAttributeConfig.BVec2: dataSize = 2; dataType = OpenGL.GL_BYTE; break; case VertexAttributeConfig.BVec3: dataSize = 3; dataType = OpenGL.GL_BYTE; break; case VertexAttributeConfig.BVec4: dataSize = 4; dataType = OpenGL.GL_BYTE; break; case VertexAttributeConfig.Int: dataSize = 1; dataType = OpenGL.GL_INT; break; case VertexAttributeConfig.IVec2: dataSize = 2; dataType = OpenGL.GL_INT; break; case VertexAttributeConfig.IVec3: dataSize = 3; dataType = OpenGL.GL_INT; break; case VertexAttributeConfig.IVec4: dataSize = 4; dataType = OpenGL.GL_INT; break; case VertexAttributeConfig.UInt: dataSize = 1; dataType = OpenGL.GL_UNSIGNED_INT; break; case VertexAttributeConfig.UVec2: dataSize = 2; dataType = OpenGL.GL_UNSIGNED_INT; break; case VertexAttributeConfig.UVec3: dataSize = 3; dataType = OpenGL.GL_UNSIGNED_INT; break; case VertexAttributeConfig.UVec4: dataSize = 4; dataType = OpenGL.GL_UNSIGNED_INT; break; case VertexAttributeConfig.Float: dataSize = 1; dataType = OpenGL.GL_FLOAT; break; case VertexAttributeConfig.Vec2: dataSize = 2; dataType = OpenGL.GL_FLOAT; break; case VertexAttributeConfig.Vec3: dataSize = 3; dataType = OpenGL.GL_FLOAT; break; case VertexAttributeConfig.Vec4: dataSize = 4; dataType = OpenGL.GL_FLOAT; break; case VertexAttributeConfig.Double: dataSize = 1; dataType = OpenGL.GL_DOUBLE; break; case VertexAttributeConfig.DVec2: dataSize = 2; dataType = OpenGL.GL_DOUBLE; break; case VertexAttributeConfig.DVec3: dataSize = 3; dataType = OpenGL.GL_DOUBLE; break; case VertexAttributeConfig.DVec4: dataSize = 4; dataType = OpenGL.GL_DOUBLE; break; case VertexAttributeConfig.Mat2: locationCount = 2; dataSize = 2; dataType = OpenGL.GL_FLOAT; stride = Marshal.SizeOf(typeof(mat2)); startOffsetUnit = Marshal.SizeOf(typeof(vec2)); break; case VertexAttributeConfig.Mat3: locationCount = 3; dataSize = 3; dataType = OpenGL.GL_FLOAT; stride = Marshal.SizeOf(typeof(mat3)); startOffsetUnit = Marshal.SizeOf(typeof(vec3)); break; case VertexAttributeConfig.Mat4: locationCount = 4; dataSize = 4; dataType = OpenGL.GL_FLOAT; stride = Marshal.SizeOf(typeof(mat4)); startOffsetUnit = Marshal.SizeOf(typeof(vec4)); break; default: throw new System.NotImplementedException(); } }