/// <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;
        }
Example #2
0
        /// <summary>
        /// 在使用<see cref="VertexArrayObject"/>后,此方法只会执行一次。
        /// This method will only be invoked once when using <see cref="VertexArrayObject"/>.
        /// </summary>
        /// <param name="shaderProgram"></param>
        public void Standby(ShaderProgram shaderProgram)
        {
            int location = shaderProgram.GetAttributeLocation(this.VarNameInVertexShader);

            if (location < 0)
            {
                throw new ArgumentException();
            }

            uint            loc           = (uint)location;
            VBOConfigDetail detail        = this.Config.Parse();
            int             patchVertexes = this.PatchVertexes;
            uint            divisor       = this.InstancedDivisor;

            // 选中此VBO
            // select this VBO.
            if (glBindBuffer == null)
            {
                glBindBuffer = OpenGL.GetDelegateFor <OpenGL.glBindBuffer>();
            }
            glBindBuffer(OpenGL.GL_ARRAY_BUFFER, this.BufferId);
            for (uint i = 0; i < detail.locationCount; i++)
            {
                // 指定格式
                // set up data format.
                switch (detail.pointerType)
                {
                case VertexAttribPointerType.Default:
                    if (glVertexAttribPointer == null)
                    {
                        glVertexAttribPointer = OpenGL.GetDelegateFor <OpenGL.glVertexAttribPointer>();
                    }
                    glVertexAttribPointer(loc + i, detail.dataSize, detail.dataType, false, detail.stride, new IntPtr(i * detail.startOffsetUnit));
                    break;

                case VertexAttribPointerType.Integer:
                    if (glVertexAttribIPointer != null)
                    {
                        if (glVertexAttribIPointer == null)
                        {
                            glVertexAttribIPointer = OpenGL.GetDelegateFor <OpenGL.glVertexAttribIPointer>();
                        }
                        glVertexAttribIPointer(loc + i, detail.dataSize, detail.dataType, detail.stride, new IntPtr(i * detail.startOffsetUnit));
                    }
                    else
                    {
                        if (glVertexAttribPointer == null)
                        {
                            glVertexAttribPointer = OpenGL.GetDelegateFor <OpenGL.glVertexAttribPointer>();
                        }
                        glVertexAttribPointer(loc + i, detail.dataSize, detail.dataType, false, detail.stride, new IntPtr(i * detail.startOffsetUnit));
                    }
                    break;

                case VertexAttribPointerType.Long:
                    if (glVertexAttribLPointer != null)
                    {
                        if (glVertexAttribLPointer == null)
                        {
                            glVertexAttribLPointer = OpenGL.GetDelegateFor <OpenGL.glVertexAttribLPointer>();
                        }
                        glVertexAttribLPointer(loc + i, detail.dataSize, detail.dataType, detail.stride, new IntPtr(i * detail.startOffsetUnit));
                    }
                    else
                    {
                        if (glVertexAttribPointer == null)
                        {
                            glVertexAttribPointer = OpenGL.GetDelegateFor <OpenGL.glVertexAttribPointer>();
                        }
                        glVertexAttribPointer(loc + i, detail.dataSize, detail.dataType, false, detail.stride, new IntPtr(i * detail.startOffsetUnit));
                    }
                    break;

                default:
                    throw new NotImplementedException();
                }

                if (patchVertexes > 0)// tessellation shading.
                {
                    if (glPatchParameteri != null)
                    {
                        if (glPatchParameteri == null)
                        {
                            glPatchParameteri = OpenGL.GetDelegateFor <OpenGL.glPatchParameteri>();
                        }
                        glPatchParameteri(OpenGL.GL_PATCH_VERTICES, patchVertexes);
                    }
                }
                // 启用
                // enable this VBO.
                if (glEnableVertexAttribArray == null)
                {
                    glEnableVertexAttribArray = OpenGL.GetDelegateFor <OpenGL.glEnableVertexAttribArray>();
                }
                glEnableVertexAttribArray(loc + i);
                if (divisor > 0)// instanced rendering.
                {
                    if (glVertexAttribDivisor == null)
                    {
                        glVertexAttribDivisor = OpenGL.GetDelegateFor <OpenGL.glVertexAttribDivisor>();
                    }
                    glVertexAttribDivisor(loc + i, divisor);
                }
            }
            glBindBuffer(OpenGL.GL_ARRAY_BUFFER, 0);
        }
Example #3
0
        /// <summary>
        /// 在使用<see cref="VertexArrayObject"/>后,此方法只会执行一次。
        /// This method will only be invoked once when using <see cref="VertexArrayObject"/>.
        /// </summary>
        /// <param name="shaderProgram"></param>
        public void Standby(ShaderProgram shaderProgram)
        {
            int location = shaderProgram.GetAttributeLocation(this.VarNameInVertexShader);
            if (location < 0) { throw new ArgumentException(); }

            uint loc = (uint)location;
            VBOConfigDetail detail = this.Config.Parse();
            int patchVertexes = this.PatchVertexes;
            uint divisor = this.InstancedDivisor;
            // 选中此VBO
            // select this VBO.
            if (glBindBuffer == null) { glBindBuffer = OpenGL.GetDelegateFor<OpenGL.glBindBuffer>(); }
            glBindBuffer(OpenGL.GL_ARRAY_BUFFER, this.BufferId);
            for (uint i = 0; i < detail.locationCount; i++)
            {
                // 指定格式
                // set up data format.
                switch (detail.pointerType)
                {
                    case VertexAttribPointerType.Default:
                        if (glVertexAttribPointer == null) { glVertexAttribPointer = OpenGL.GetDelegateFor<OpenGL.glVertexAttribPointer>(); }
                        glVertexAttribPointer(loc + i, detail.dataSize, detail.dataType, false, detail.stride, new IntPtr(i * detail.startOffsetUnit));
                        break;

                    case VertexAttribPointerType.Integer:
                        if (glVertexAttribIPointer != null)
                        {
                            if (glVertexAttribIPointer == null) { glVertexAttribIPointer = OpenGL.GetDelegateFor<OpenGL.glVertexAttribIPointer>(); }
                            glVertexAttribIPointer(loc + i, detail.dataSize, detail.dataType, detail.stride, new IntPtr(i * detail.startOffsetUnit));
                        }
                        else
                        {
                            if (glVertexAttribPointer == null) { glVertexAttribPointer = OpenGL.GetDelegateFor<OpenGL.glVertexAttribPointer>(); }
                            glVertexAttribPointer(loc + i, detail.dataSize, detail.dataType, false, detail.stride, new IntPtr(i * detail.startOffsetUnit));
                        }
                        break;

                    case VertexAttribPointerType.Long:
                        if (glVertexAttribLPointer != null)
                        {
                            if (glVertexAttribLPointer == null) { glVertexAttribLPointer = OpenGL.GetDelegateFor<OpenGL.glVertexAttribLPointer>(); }
                            glVertexAttribLPointer(loc + i, detail.dataSize, detail.dataType, detail.stride, new IntPtr(i * detail.startOffsetUnit));
                        }
                        else
                        {
                            if (glVertexAttribPointer == null) { glVertexAttribPointer = OpenGL.GetDelegateFor<OpenGL.glVertexAttribPointer>(); }
                            glVertexAttribPointer(loc + i, detail.dataSize, detail.dataType, false, detail.stride, new IntPtr(i * detail.startOffsetUnit));
                        }
                        break;

                    default:
                        throw new NotImplementedException();
                }

                if (patchVertexes > 0)// tessellation shading.
                {
                    if (glPatchParameteri != null)
                    {
                        if (glPatchParameteri == null) { glPatchParameteri = OpenGL.GetDelegateFor<OpenGL.glPatchParameteri>(); }
                        glPatchParameteri(OpenGL.GL_PATCH_VERTICES, patchVertexes);
                    }
                }
                // 启用
                // enable this VBO.
                if (glEnableVertexAttribArray == null) { glEnableVertexAttribArray = OpenGL.GetDelegateFor<OpenGL.glEnableVertexAttribArray>(); }
                glEnableVertexAttribArray(loc + i);
                if (divisor > 0)// instanced rendering.
                {
                    if (glVertexAttribDivisor == null) { glVertexAttribDivisor = OpenGL.GetDelegateFor<OpenGL.glVertexAttribDivisor>(); }
                    glVertexAttribDivisor(loc + i, divisor);
                }
            }
            glBindBuffer(OpenGL.GL_ARRAY_BUFFER, 0);
        }