1 // Written in the D programming language.
2 /++
3  + Authors: KanzakiKino
4  + Copyright: KanzakiKino 2018
5  + License: LGPL-3.0
6 ++/
7 module g4d.gl.buffer;
8 import g4d.gl.lib;
9 
10 /// A baseclass of OpenGL buffers.
11 abstract class Buffer
12 {
13     protected static Buffer _bindedBuffer;
14 
15     /// Not valid buffer id.
16     enum NullId = 0;
17 
18     protected GLuint _id;
19     /// OpenGL buffer id.
20     const @property id () { return _id; }
21 
22     /// GL_ARRAY_BUFFER, GL_TEXTURE_BUFFER or etc...
23     const pure @property GLenum target ();
24 
25     ///
26     this ( void* ptr, size_t sz )
27     {
28         enforce!glGenBuffers( 1, &_id );
29         bind();
30         enforce!glBufferData( target, sz, ptr, GL_STATIC_DRAW );
31     }
32 
33     ///
34     ~this ()
35     {
36         dispose();
37     }
38     /// Checks if the buffer is disposed.
39     const @property disposed ()
40     {
41         return _id == NullId;
42     }
43     /// Deletes buffer.
44     void dispose ()
45     {
46         if ( !disposed ) {
47             enforce!glDeleteBuffers( 1, &_id );
48         }
49         if ( binded ) {
50             _bindedBuffer = null;
51         }
52         _id = NullId;
53     }
54 
55     /// Checks if the buffer is binded.
56     const @property binded ()
57     {
58         return _bindedBuffer is this;
59     }
60     /// Sets the buffer binded.
61     const void bind ()
62     {
63         if ( !binded ) {
64             enforce!glBindBuffer( target, _id );
65         }
66     }
67 
68     protected void overwrite ( size_t sz, in void* ptr, size_t offset = 0 )
69     {
70         bind();
71         enforce!glBufferSubData( target, offset, sz, ptr );
72     }
73 }
74 
75 /// A buffer for array data.
76 /// target property returns GL_ARRAY_BUFFER.
77 class ArrayBuffer : Buffer
78 {
79     ///
80     override const pure @property GLenum target ()
81     {
82         return GL_ARRAY_BUFFER;
83     }
84 
85     ///
86     this (T) ( T[] buf )
87     {
88         size_t size = T.sizeof*buf.length;
89         super( buf.ptr, size );
90     }
91 
92     /// Modifies the buffer.
93     void overwrite (T) ( in T[] buf, size_t offset = 0 )
94     {
95         super.overwrite( T.sizeof*buf.length, buf.ptr, T.sizeof*offset );
96     }
97 }