Ejemplo n.º 1
0
            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);
                }
            }
Ejemplo n.º 2
0
            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);
                }
            }
Ejemplo n.º 3
0
            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);
                }
            }
Ejemplo n.º 4
0
        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());
            }
        }
Ejemplo n.º 5
0
            /// <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);
            }
Ejemplo n.º 6
0
            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);
                }
            }