Пример #1
0
        /// <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;
            }
        }
Пример #2
0
        /// <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;
 }