CSharpGL.VertexBuffer.Standby C# (CSharp) Method

Standby() public method

在使用VertexArrayObject后,此方法只会执行一次。 This method will only be invoked once when using VertexArrayObject.
public Standby ( ShaderProgram shaderProgram ) : void
shaderProgram ShaderProgram
return void
        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);
        }

Usage Example

        /// <summary>
        /// VAO是用来管理VBO的。可以进一步减少DrawCall。
        /// <para>VAO is used to reduce draw-call.</para>
        /// </summary>
        /// <param name="drawCommand">index buffer pointer that used to invoke draw command.</param>
        /// <param name="shaderProgram">shader program that <paramref name="vertexAttributes"/> bind to.</param>
        /// <param name="vertexAttributes">给出此VAO要管理的所有VBO。<para>All VBOs that are managed by this VAO.</para></param>
        public VertexArrayObject(IDrawCommand drawCommand, ShaderProgram shaderProgram, params VertexShaderAttribute[] vertexAttributes)
        {
            if (drawCommand == null)
            {
                throw new ArgumentNullException("drawCommand");
            }
            // Zero vertex attribute is allowed in GLSL.
            //if (vertexAttributeBuffers == null || vertexAttributeBuffers.Length == 0)
            //{
            //    throw new ArgumentNullException("vertexAttributeBuffers");
            //}

            this.DrawCommand      = drawCommand;
            this.VertexAttributes = vertexAttributes;

            glGenVertexArrays(1, ids);

            glBindVertexArray(this.Id); // this vertex array object will record all stand-by actions.

            foreach (var item in vertexAttributes)
            {
                VertexBuffer buffer = item.Buffer;
                buffer.Standby(shaderProgram, item.VarNameInVertexShader);
            }

            glBindVertexArray(0); // this vertex array object has recorded all stand-by actions.
        }