public VAO(ShaderProgram program, VBO <T1> vbo1, string attribName, VBO <int> elementArray) : base(program) { IGenericVBO[] vbos = new IGenericVBO[2]; vbos[0] = new GenericVBO <T1>(vbo1, attribName); vbos[1] = new GenericVBO <int>(elementArray); Init(vbos); }
public VAO(ShaderProgram program, VBO <T1> vbo1, string[] attribNames, VBO <int> elementArray) : base(program) { if (attribNames.Length != 1) { throw new Exception(string.Format("Expected an array of 1 name, but instead got {0}.", attribNames.Length)); } IGenericVBO[] vbos = new IGenericVBO[2]; vbos[0] = new GenericVBO <T1>(vbo1, attribNames[0]); vbos[1] = new GenericVBO <int>(elementArray); Init(vbos); }
public void BindAttributes(ShaderProgram program) { IGenericVBO elementArray = null; for (int i = 0; i < vbos.Length; i++) { if (vbos[i].BufferTarget == BufferTarget.ElementArrayBuffer) { elementArray = vbos[i]; // To not break compatibility with previous versions of this call, // int is allowed as an element type even though the specs don't allow it. // All cases where int is used as the default element type have been marked obsolete // but until it's completely removed, this will serve to support that use case. if (allowIntAsElementType && vbos[i].PointerType == VertexAttribPointerType.Int) { elementType = DrawElementsType.UnsignedInt; } else { // Check if the element array can be used as an indice buffer. if (!ValidElementTypes.ContainsKey(vbos[i].PointerType)) { throw new Exception($"The element buffer must be an unsigned integral type. See {nameof(DrawElementsType)} enum for valid types."); } elementType = ValidElementTypes[vbos[i].PointerType]; } continue; } // According to OGL spec then, if there is no location for an attribute, -1 is returned. // The same error representation is used here. int loc = program[vbos[i].Name]?.Location ?? -1; if (loc == -1) { throw new Exception(string.Format("Shader did not contain '{0}'.", vbos[i].Name)); } Gl.EnableVertexAttribArray((uint)loc); Gl.BindBuffer(vbos[i].BufferTarget, vbos[i].ID); if (vbos[i].CastToFloat) { Gl.VertexAttribPointer((uint)loc, vbos[i].Size, vbos[i].PointerType, vbos[i].Normalize, 0, IntPtr.Zero); } else if (vbos[i].IsIntegralType) { Gl.VertexAttribIPointer((uint)loc, vbos[i].Size, vbos[i].PointerType, 0, IntPtr.Zero); } else if (vbos[i].PointerType == VertexAttribPointerType.Double) { Gl.VertexAttribLPointer((uint)loc, vbos[i].Size, vbos[i].PointerType, 0, IntPtr.Zero); } else { throw new Exception("VBO shouldn't be cast to float, isn't an integral type and is not a float. No vertex attribute support this combination."); } // 0 is the divisors default value. // No need to set the divisor to its default value. if (vbos[i].Divisor != 0) { Gl.VertexAttribDivisor((uint)loc, vbos[i].Divisor); } } if (elementArray != null) { Gl.BindBuffer(BufferTarget.ElementArrayBuffer, elementArray.ID); VertexCount = elementArray.Length; } }