private void BindVertexLayout(GalPipelineState New) { foreach (GalVertexBinding Binding in New.VertexBindings) { if (!Binding.Enabled || !Rasterizer.TryGetVbo(Binding.VboKey, out int VboHandle)) { continue; } if (VaoHandle == 0) { VaoHandle = GL.GenVertexArray(); //Vertex arrays shouldn't be used anywhere else in OpenGL's backend //if you want to use it, move this line out of the if GL.BindVertexArray(VaoHandle); } foreach (GalVertexAttrib Attrib in Binding.Attribs) { //Skip uninitialized attributes. if (Attrib.Size == 0) { continue; } GL.BindBuffer(BufferTarget.ArrayBuffer, VboHandle); bool Unsigned = Attrib.Type == GalVertexAttribType.Unorm || Attrib.Type == GalVertexAttribType.Uint || Attrib.Type == GalVertexAttribType.Uscaled; bool Normalize = Attrib.Type == GalVertexAttribType.Snorm || Attrib.Type == GalVertexAttribType.Unorm; VertexAttribPointerType Type = 0; if (Attrib.Type == GalVertexAttribType.Float) { Type = GetType(FloatAttribTypes, Attrib); } else { if (Unsigned) { Type = GetType(UnsignedAttribTypes, Attrib); } else { Type = GetType(SignedAttribTypes, Attrib); } } if (!AttribElements.TryGetValue(Attrib.Size, out int Size)) { throw new InvalidOperationException("Invalid attribute size \"" + Attrib.Size + "\"!"); } int Offset = Attrib.Offset; if (Binding.Stride != 0) { GL.EnableVertexAttribArray(Attrib.Index); if (Attrib.Type == GalVertexAttribType.Sint || Attrib.Type == GalVertexAttribType.Uint) { IntPtr Pointer = new IntPtr(Offset); VertexAttribIntegerType IType = (VertexAttribIntegerType)Type; GL.VertexAttribIPointer(Attrib.Index, Size, IType, Binding.Stride, Pointer); } else { GL.VertexAttribPointer(Attrib.Index, Size, Type, Normalize, Binding.Stride, Offset); } } else { GL.DisableVertexAttribArray(Attrib.Index); SetConstAttrib(Attrib); } if (Binding.Instanced && Binding.Divisor != 0) { GL.VertexAttribDivisor(Attrib.Index, 1); } else { GL.VertexAttribDivisor(Attrib.Index, 0); } } } }
private void BindVertexLayout(GalPipelineState New) { foreach (GalVertexBinding Binding in New.VertexBindings) { if (!Binding.Enabled || !Rasterizer.TryGetVbo(Binding.VboKey, out int VboHandle)) { continue; } if (VaoHandle == 0) { VaoHandle = GL.GenVertexArray(); //Vertex arrays shouldn't be used anywhere else in OpenGL's backend //if you want to use it, move this line out of the if GL.BindVertexArray(VaoHandle); } foreach (GalVertexAttrib Attrib in Binding.Attribs) { GL.EnableVertexAttribArray(Attrib.Index); GL.BindBuffer(BufferTarget.ArrayBuffer, VboHandle); bool Unsigned = Attrib.Type == GalVertexAttribType.Unorm || Attrib.Type == GalVertexAttribType.Uint || Attrib.Type == GalVertexAttribType.Uscaled; bool Normalize = Attrib.Type == GalVertexAttribType.Snorm || Attrib.Type == GalVertexAttribType.Unorm; VertexAttribPointerType Type = 0; if (Attrib.Type == GalVertexAttribType.Float) { Type = VertexAttribPointerType.Float; } else { Type = AttribTypes[Attrib.Size] + (Unsigned ? 1 : 0); } int Size = AttribElements[Attrib.Size]; int Offset = Attrib.Offset; if (Attrib.Type == GalVertexAttribType.Sint || Attrib.Type == GalVertexAttribType.Uint) { IntPtr Pointer = new IntPtr(Offset); VertexAttribIntegerType IType = (VertexAttribIntegerType)Type; GL.VertexAttribIPointer(Attrib.Index, Size, IType, Binding.Stride, Pointer); } else { GL.VertexAttribPointer(Attrib.Index, Size, Type, Normalize, Binding.Stride, Offset); } } } }