/// <summary> /// Binds the specified buffer's vertex attributes to the currently cached program using the old API. /// </summary> private unsafe void BindVertexAttributesForBuffer_OldAPI(OpenGLVertexBuffer vbuffer, UInt32 binding, UInt32 frequency, UInt32?program, UInt32?offset) { OpenGLState.BindArrayBuffer(vbuffer.OpenGLName); var position = offset ?? this.offset; foreach (var element in vbuffer.VertexDeclaration) { var name = GetVertexAttributeNameFromUsage(element.Usage, element.Index); var size = 0; var stride = 0; var normalize = false; var type = GetVertexFormatGL(element.Format, out size, out stride, out normalize); var category = OpenGLAttribCategory.Single; var location = (UInt32)OpenGLState.CurrentProgram.GetAttribLocation(name, out category); if (location >= 0) { if (program.HasValue) { if (gl.IsInstancedRenderingAvailable) { gl.VertexAttribDivisor(location, frequency); gl.ThrowIfError(); } else { if (frequency != 0) { throw new NotSupportedException(OpenGLStrings.InstancedRenderingNotSupported); } } gl.EnableVertexAttribArray(location); gl.ThrowIfError(); } switch (category) { case OpenGLAttribCategory.Single: { gl.VertexAttribPointer(location, size, type, normalize, vbuffer.VertexDeclaration.VertexStride, (void *)(position)); gl.ThrowIfError(); } break; case OpenGLAttribCategory.Double: { if (!gl.IsDoublePrecisionVertexAttribAvailable) { throw new NotSupportedException(OpenGLStrings.DoublePrecisionVAttribsNotSupported); } gl.VertexAttribLPointer(location, size, type, vbuffer.VertexDeclaration.VertexStride, (void *)(position)); gl.ThrowIfError(); } break; case OpenGLAttribCategory.Integer: { if (!gl.IsIntegerVertexAttribAvailable) { throw new NotSupportedException(OpenGLStrings.IntegerVAttribsNotSupported); } gl.VertexAttribIPointer(location, size, type, vbuffer.VertexDeclaration.VertexStride, (void *)(position)); gl.ThrowIfError(); } break; } } position += (uint)stride; } }
/// <summary> /// Binds the specified buffer's vertex attributes to the currently cached program using the new API. /// </summary> private unsafe void BindVertexAttributesForBuffer_NewAPI(OpenGLVertexBuffer vbuffer, UInt32 binding, UInt32 frequency, UInt32?program, UInt32?offset) { using (OpenGLState.ScopedBindVertexArrayObject(vao, glElementArrayBufferBinding ?? 0)) { if (program.HasValue || offset.HasValue) { gl.VertexArrayVertexBuffer(vao, binding, vbuffer.OpenGLName, (IntPtr)(offset ?? 0), vbuffer.VertexDeclaration.VertexStride); gl.ThrowIfError(); } if (program.HasValue) { gl.VertexArrayBindingDivisor(vao, binding, frequency); gl.ThrowIfError(); var position = 0u; foreach (var element in vbuffer.VertexDeclaration) { var name = GetVertexAttributeNameFromUsage(element.Usage, element.Index); var size = 0; var stride = 0; var normalize = false; var type = GetVertexFormatGL(element.Format, out size, out stride, out normalize); var category = OpenGLAttribCategory.Single; var location = (UInt32)OpenGLState.CurrentProgram.GetAttribLocation(name, out category); if (location >= 0) { gl.VertexArrayAttribBinding(vao, location, binding); gl.ThrowIfError(); gl.EnableVertexArrayAttrib(vao, location); gl.ThrowIfError(); unsafe { switch (category) { case OpenGLAttribCategory.Single: { gl.VertexArrayAttribFormat(vao, location, size, type, normalize, position); gl.ThrowIfError(); } break; case OpenGLAttribCategory.Double: { if (!gl.IsDoublePrecisionVertexAttribAvailable) { throw new NotSupportedException(OpenGLStrings.DoublePrecisionVAttribsNotSupported); } gl.VertexArrayAttribLFormat(vao, location, size, type, position); gl.ThrowIfError(); } break; case OpenGLAttribCategory.Integer: { if (!gl.IsIntegerVertexAttribAvailable) { throw new NotSupportedException(OpenGLStrings.IntegerVAttribsNotSupported); } gl.VertexArrayAttribIFormat(vao, location, size, type, position); gl.ThrowIfError(); } break; } } } position += (uint)stride; } } } }
/// <summary> /// Initializes a new instance of the <see cref="VertexBufferBinding"/> structure. /// </summary> /// <param name="vbuffer">The vertex buffer which is bound to the geometry stream.</param> /// <param name="instanceFrequency">The number of instances which are drawn for each /// set of data in the vertex buffer.</param> public VertexBufferBinding(OpenGLVertexBuffer vbuffer, Int32 instanceFrequency) { this.VertexBuffer = vbuffer; this.InstanceFrequency = instanceFrequency; }