private void SetNormalAttribute(GraphicsContext ctx) { if (ArrayBuffer != null) { ArrayBufferObjectBase.IArraySection arraySection = ArrayBuffer.GetArraySection(ArraySectionIndex); int arrayLength = (int)arraySection.ItemType.GetArrayLength(); if (arrayLength != 3) { throw new NotSupportedException(String.Format("normal pointer of length {0} not supported", arrayLength)); } // Bind the array buffer ctx.Bind(ArrayBuffer); // Set vertex pointer Gl.NormalPointer( arraySection.ItemType.GetNormalPointerType(), arraySection.Stride.ToInt32(), arraySection.Pointer ); // Enable vertex attribute Gl.EnableClientState(EnableCap.NormalArray); } else { Gl.DisableClientState(EnableCap.NormalArray); } }
private void SetTexCoordAttribute(GraphicsContext ctx) { if (ArrayBuffer != null) { ArrayBufferObjectBase.IArraySection arraySection = ArrayBuffer.GetArraySection(ArraySectionIndex); int arrayLength = (int)arraySection.ItemType.GetArrayLength(); int arrayStride = arraySection.Stride.ToInt32(); // Bind the array buffer ctx.Bind(ArrayBuffer); // Set vertex pointer Gl.TexCoordPointer( arrayLength, arraySection.ItemType.GetTexCoordPointerType(), arraySection.Stride.ToInt32(), arraySection.Pointer ); // Enable vertex attribute Gl.EnableClientState(EnableCap.TextureCoordArray); } else { Gl.DisableClientState(EnableCap.TextureCoordArray); } }
private void SetColorAttribute(GraphicsContext ctx) { if (ArrayBuffer != null) { ArrayBufferObjectBase.IArraySection arraySection = ArrayBuffer.GetArraySection(ArraySectionIndex); int arrayLength = (int)ArrayBufferItem.GetArrayLength(arraySection.ItemType); int arrayStride = arraySection.Stride.ToInt32(); // Bind the array buffer ArrayBuffer.Bind(ctx); // Set vertex pointer Gl.ColorPointer( arrayLength, ArrayBufferItem.GetColorPointerType(arraySection.ItemType), arrayStride, arraySection.Pointer ); // Enable vertex attribute Gl.EnableClientState(EnableCap.ColorArray); } else { Gl.DisableClientState(EnableCap.ColorArray); } }
private void MapBufferObjects(GraphicsContext ctx) { foreach (KeyValuePair <uint, ArrayAttachment> pair in _AttachedArrays) { ArrayAttachment arrayAttachment = pair.Value; ArrayBufferObjectBase.IArraySection arraySection = arrayAttachment.ArrayBuffer.GetArraySection(arrayAttachment.ArraySectionIndex); Gl.BindBufferRange(Gl.TRANSFORM_FEEDBACK_BUFFER, pair.Key, arrayAttachment.ArrayBuffer.ObjectName, arraySection.Offset, arrayAttachment.ArrayBuffer.BufferSize - (uint)arraySection.Offset.ToInt32()); } }
/// <summary> /// Enable the generic vertex attribute. /// </summary> /// <param name="ctx"> /// The <see cref="GraphicsContext"/> on which the shader program is bound. /// </param> /// <param name="attributeBinding"> /// The <see cref="ShaderProgram.AttributeBinding"/> representing the generic vertex attribute. /// </param> internal virtual void EnableVertexAttribute(GraphicsContext ctx, uint location, ShaderAttributeType type) { ArrayBufferObjectBase.IArraySection arraySection = ArrayBuffer.GetArraySection(ArraySectionIndex); int arrayBaseType = (int)arraySection.ItemType.GetVertexBaseType(); int arrayLength = (int)arraySection.ItemType.GetArrayLength(); int arrayStride = arraySection.Stride.ToInt32(); // Avoid rendundant buffer binding and relative vertex array setup if (ctx.Extensions.VertexArrayObject_ARB && IsDirty == false) { // CheckVertexAttribute(ctx, location); return; } // Bind the array buffer ctx.Bind(ArrayBuffer); // Bind varying attribute to currently bound buffer object switch (ArrayBufferItem.GetArrayBaseType(type)) { case VertexBaseType.Float: Gl.VertexAttribPointer( location, arrayLength, arrayBaseType, arraySection.Normalized, arrayStride, arraySection.Offset ); break; case VertexBaseType.Int: case VertexBaseType.UInt: Gl.VertexAttribIPointer( location, arrayLength, arrayBaseType, arrayStride, arraySection.Offset ); break; case VertexBaseType.Double: Gl.VertexAttribLPointer( location, arrayLength, arrayBaseType, arrayStride, arraySection.Offset ); break; default: throw new NotSupportedException(String.Format("vertex attribute type {0} not supported", type)); } // Enable vertex attribute Gl.EnableVertexAttribArray(location); }
internal void CheckVertexAttribute(GraphicsContext ctx, uint location) { if (ArrayBuffer != null) { ArrayBufferObjectBase.IArraySection arraySection = ArrayBuffer.GetArraySection(ArraySectionIndex); int arrayBaseType = (int)arraySection.ItemType.GetVertexBaseType(); int arrayLength = (int)arraySection.ItemType.GetArrayLength(); int arrayStride = arraySection.Stride.ToInt32(); // Check effective state IntPtr vertexAttribPointer; int vertexAttribArrayBufferBinding; int vertexAttribArraySize; int vertexAttribArrayType; int vertexAttribArrayNormalized; int vertexAttribArrayStride; int vertexAttribArrayEnabled; // Attribute pointer/offset Gl.GetVertexAttribPointer(location, Gl.VERTEX_ATTRIB_ARRAY_POINTER, out vertexAttribPointer); Debug.Assert(vertexAttribPointer == new IntPtr(arraySection.Pointer.ToInt64() + arraySection.Offset.ToInt64())); // Array buffer binding Gl.GetVertexAttrib(location, Gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, out vertexAttribArrayBufferBinding); Debug.Assert(vertexAttribArrayBufferBinding == ArrayBuffer.ObjectName); // Array size Gl.GetVertexAttrib(location, Gl.VERTEX_ATTRIB_ARRAY_SIZE, out vertexAttribArraySize); Debug.Assert(vertexAttribArraySize == arrayLength); // Array type Gl.GetVertexAttrib(location, Gl.VERTEX_ATTRIB_ARRAY_TYPE, out vertexAttribArrayType); Debug.Assert(vertexAttribArrayType == arrayBaseType); // Array normalized Gl.GetVertexAttrib(location, Gl.VERTEX_ATTRIB_ARRAY_NORMALIZED, out vertexAttribArrayNormalized); Debug.Assert((vertexAttribArrayNormalized != 0) == arraySection.Normalized); // Array size Gl.GetVertexAttrib(location, Gl.VERTEX_ATTRIB_ARRAY_STRIDE, out vertexAttribArrayStride); Debug.Assert(vertexAttribArrayStride == arrayStride); // Attribute enabled Gl.GetVertexAttrib(location, Gl.VERTEX_ATTRIB_ARRAY_ENABLED, out vertexAttribArrayEnabled); Debug.Assert(vertexAttribArrayEnabled == Gl.TRUE); } else { int vertexAttribArrayEnabled; // Attribute disabled Gl.GetVertexAttrib(location, Gl.VERTEX_ATTRIB_ARRAY_ENABLED, out vertexAttribArrayEnabled); Debug.Assert(vertexAttribArrayEnabled == Gl.FALSE); } }
/// <summary> /// Draw the elements. /// </summary> /// <param name="ctx"> /// The <see cref="GraphicsContext"/> used for drawing. /// </param> public override void Draw(GraphicsContext ctx) { if (ctx == null) { throw new ArgumentNullException("ctx"); } if (ctx.IsCurrent == false) { throw new ArgumentException("not current", "ctx"); } ArrayBufferObjectBase.IArraySection arraySection = ArrayIndices.GetArraySection(0); Debug.Assert(arraySection != null); // Element array must be (re)bound ArrayIndices.Bind(ctx); // Enable restart primitive? if (ArrayIndices.RestartIndexEnabled) { Debug.Assert(ElementCount != 0, "specified ElementCount but primitive restart enabled"); if (PrimitiveRestart.IsPrimitiveRestartSupported(ctx)) { // Enable primitive restart PrimitiveRestart.EnablePrimitiveRestart(ctx, ArrayIndices.ElementsType); // Draw elements as usual Gl.DrawElements(ElementsMode, (int)ElementCount, ArrayIndices.ElementsType, arraySection.Pointer); // Disable primitive restart PrimitiveRestart.DisablePrimitiveRestart(ctx); } else { // Note: uses MultiDrawElements to emulate the primitive restart feature; PrimitiveRestartOffsets and // PrimitiveRestartCounts are computed at element buffer creation time Gl.MultiDrawElements(ElementsMode, ArrayIndices.PrimitiveRestartOffsets, ArrayIndices.ElementsType, ArrayIndices.PrimitiveRestartCounts, ArrayIndices.PrimitiveRestartOffsets.Length); } } else { uint count = (ElementCount == 0) ? ArrayIndices.ItemCount : ElementCount; Debug.Assert(count - ElementOffset <= ArrayIndices.ItemCount, "element indices array out of bounds"); // Draw vertex arrays by indices Gl.DrawElements(ElementsMode, (int)count, ArrayIndices.ElementsType, arraySection.Pointer); } }
/// <summary> /// Draw the elements instances /// </summary> /// <param name="ctx"> /// The <see cref="GraphicsContext"/> used for drawing. /// </param> /// <param name="instances"> /// A <see cref="UInt32"/> that specify the number of instances to draw. /// </param> public override void DrawInstanced(GraphicsContext ctx, uint instances) { if (ctx == null) { throw new ArgumentNullException("ctx"); } if (ctx.IsCurrent == false) { throw new ArgumentException("not current", "ctx"); } ArrayBufferObjectBase.IArraySection arraySection = ArrayIndices.GetArraySection(0); Debug.Assert(arraySection != null); // Element array must be (re)bound ctx.Bind(ArrayIndices); // Enable restart primitive? if (ArrayIndices.RestartIndexEnabled) { if (PrimitiveRestart.IsPrimitiveRestartSupported(ctx)) { // Enable primitive restart PrimitiveRestart.EnablePrimitiveRestart(ctx, ArrayIndices.ElementsType); // Draw elements as usual DrawElementsInstanced(ctx, arraySection.Pointer, instances); // Disable primitive restart PrimitiveRestart.DisablePrimitiveRestart(ctx); } else { throw new NotSupportedException(); } } else { uint count = (ElementCount == 0) ? ArrayIndices.ItemCount : ElementCount; Debug.Assert(count - ElementOffset <= ArrayIndices.ItemCount, "element indices array out of bounds"); // Draw vertex arrays by indices DrawElementsInstanced(ctx, arraySection.Pointer, instances); } }
/// <summary> /// Draw the elements. /// </summary> /// <param name="ctx"> /// The <see cref="GraphicsContext"/> used for drawing. /// </param> public override void Draw(GraphicsContext ctx) { CheckCurrentContext(ctx); ArrayBufferObjectBase.IArraySection arraySection = ArrayIndices.GetArraySection(0); Debug.Assert(arraySection != null); // Element array must be (re)bound ctx.Bind(ArrayIndices, true); // Enable restart primitive? if (ArrayIndices.RestartIndexEnabled) { if (PrimitiveRestart.IsPrimitiveRestartSupported(ctx)) { // Draw elements with primitive restart PrimitiveRestart.EnablePrimitiveRestart(ctx, ArrayIndices.ElementsType); DrawElements(ctx, arraySection.Pointer); PrimitiveRestart.DisablePrimitiveRestart(ctx); } else { // Note: uses MultiDrawElements to emulate the primitive restart feature; PrimitiveRestartOffsets and // PrimitiveRestartCounts are computed at element buffer creation time Gl.MultiDrawElements(ElementsMode, ArrayIndices.PrimitiveRestartOffsets, ArrayIndices.ElementsType, ArrayIndices.PrimitiveRestartCounts, ArrayIndices.PrimitiveRestartOffsets.Length); } } else { uint count = (ElementCount == 0) ? ArrayIndices.ItemCount : ElementCount; Debug.Assert(count - ElementOffset <= ArrayIndices.ItemCount, "element indices array out of bounds"); // Draw vertex arrays by indices DrawElements(ctx, arraySection.Pointer); } }