/// <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); }
/// <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); }