1 module opengl.d.buffer;
2 
3 import opengl.gl4;
4 
5 ///
6 enum BufferTarget
7 {
8 	arrayBuffer = GL_ARRAY_BUFFER,
9 	atomicCounterBuffer = GL_ATOMIC_COUNTER_BUFFER,
10 	copyReadBuffer = GL_COPY_READ_BUFFER,
11 	copyWriteBuffer = GL_COPY_WRITE_BUFFER,
12 	drawIndirectBuffer = GL_DRAW_INDIRECT_BUFFER,
13 	dispatchIndirectBuffer = GL_DISPATCH_INDIRECT_BUFFER,
14 	elementArrayBuffer = GL_ELEMENT_ARRAY_BUFFER,
15 	pixelPackBuffer = GL_PIXEL_PACK_BUFFER,
16 	pixelUnpackBuffer = GL_PIXEL_UNPACK_BUFFER,
17 	queryBuffer = GL_QUERY_BUFFER,
18 	shaderStorageBuffer = GL_SHADER_STORAGE_BUFFER,
19 	textureBuffer = GL_TEXTURE_BUFFER,
20 	transformFeedbackBuffer = GL_TRANSFORM_FEEDBACK_BUFFER,
21 	uniformBuffer = GL_UNIFORM_BUFFER
22 }
23 
24 ///
25 enum BufferUsage
26 {
27 	streamDraw = GL_STREAM_DRAW,
28 	streamRead = GL_STREAM_READ,
29 	streamCopy = GL_STREAM_COPY,
30 	staticDraw = GL_STATIC_DRAW,
31 	staticRead = GL_STATIC_READ,
32 	staticCopy = GL_STATIC_COPY,
33 	dynamicDraw = GL_DYNAMIC_DRAW,
34 	dynamicRead = GL_DYNAMIC_READ,
35 	dynamicCopy = GL_DYNAMIC_COPY
36 }
37 
38 ///
39 struct Buffer
40 {
41 	///
42 	this(BufferTarget target)
43 	{
44 		glGenBuffers(1, &id);
45 		this.target = target;
46 	}
47 
48 	~this()
49 	{
50 		if (id)
51 		{
52 			glDeleteBuffers(1, &id);
53 		}
54 	}
55 
56 	///
57 	void bind()
58 	{
59 		if (id == boundBuffer && target == boundBufferTarget)
60 			return;
61 		glBindBuffer(target, id);
62 		boundBuffer = id;
63 		boundBufferTarget = target;
64 	}
65 
66 	///
67 	void setData(T)(T[] data, BufferUsage usage)
68 	{
69 		bind();
70 		glBufferData(target, cast(GLsizei)(data.length * T.sizeof), data.ptr, usage);
71 	}
72 
73 	///
74 	void setSubData(T)(int offset, T[] data)
75 	{
76 		bind();
77 		glBufferData(target, offset, cast(GLsizei)(data.length * T.sizeof), data.ptr);
78 	}
79 
80 	///
81 	void setStorage(T)(T[] data, MapBufferUsageMask flags)
82 	{
83 		bind();
84 		glBufferStorage(target, cast(GLsizei)(data.length * T.sizeof), data.ptr, flags);
85 	}
86 
87 	///
88 	void invalidate()
89 	{
90 		glInvalidateBufferData(id);
91 	}
92 
93 	///
94 	void invalidateSubData(int offset, uint length)
95 	{
96 		glInvalidateBufferSubData(id, offset, length);
97 	}
98 
99 	///
100 	void map(MapBufferUsageMask access)
101 	{
102 		bind();
103 		glMapBuffer(target, access);
104 	}
105 
106 	///
107 	void mapRange(int offset, uint length, MapBufferUsageMask access)
108 	{
109 		bind();
110 		glMapBufferRange(target, offset, length, access);
111 	}
112 
113 	///
114 	uint id;
115 	///
116 	BufferTarget target;
117 }
118 
119 private __gshared BufferTarget boundBufferTarget;
120 private __gshared uint boundBuffer;