1 module glamour.vao;
2 
3 private {
4     import glamour.gl : glGenVertexArrays, glBindVertexArray, glVertexAttribPointer,
5                         glEnableVertexAttribArray, glDisableVertexAttribArray,
6                         glDeleteVertexArrays,
7                         GLuint, GLenum, GLint, GLsizei, GLboolean, GL_FALSE;
8     import glamour.shader : Shader;
9     import glamour.util : checkgl;
10 
11     debug {
12         import std.stdio : stderr;
13     }
14 }
15 
16 ///
17 interface IVAO {
18     void bind(); ///
19     void unbind(); ///
20     void remove(); ///
21 }
22 
23 /// Represents an OpenGL VertrexArrayObject
24 class VAO : IVAO {
25     /// The OpenGL vao name
26     GLuint vao;
27     /// Alias this to vao
28     alias vao this;
29 
30     /// Initializes the VAO
31     this() {
32         checkgl!glGenVertexArrays(1, &vao);
33     }
34 
35     ~this() {
36         debug if(vao != 0) stderr.writefln("OpenGL: VAO resources not released.");
37     }
38 
39     /// Binds the VAO
40     void bind() {
41         checkgl!glBindVertexArray(vao);
42     }
43 
44     /// Unbinds the VAO
45     void unbind() {
46         checkgl!glBindVertexArray(0);
47     }
48 
49     /// Deletes the VAO
50     void remove() {
51         checkgl!glDeleteVertexArrays(1, &vao);
52         vao = 0;
53     }
54 
55     /// Binds the VAO and sets the vertex attrib pointer.
56     /// Params:
57     /// type = Specifies the data type of each component in the array.
58     /// size = Specifies the number of components per generic vertex attribute.
59     /// offset = Specifies a offset of the first component of the first generic vertex attribute in the array in the data store of the buffer.
60     /// stride = Specifies the byte offset between consecutive generic vertex attributes.
61     /// normalized = Specifies whether fixed-point data values should be normalized (GL_TRUE) or
62     ///                converted directly as fixed-point values (GL_FALSE = default) when they are accessed.
63     void set_attrib_pointer(GLuint attrib_location, GLenum type, GLint size, GLsizei offset,
64               GLsizei stride, GLboolean normalized=GL_FALSE) {
65         checkgl!glBindVertexArray(vao);
66         checkgl!glEnableVertexAttribArray(attrib_location);
67         checkgl!glVertexAttribPointer(attrib_location, size, type, normalized, stride, cast(void *)offset);
68     }
69 
70     /// ditto
71     void set_attrib_pointer(Shader shader, string location, GLenum type, GLint size, GLsizei offset,
72               GLsizei stride, GLboolean normalized=GL_FALSE) {
73         set_attrib_pointer(shader.get_attrib_location(location), type, size, offset, stride, normalized);
74     }
75 }