1 
2 module glwt.buffer;
3 
4 import cst_	;
5 
6 import derelict.opengl	;
7 
8 
9 /**	Unittest to ensure Compiler works as expected*/
10 unittest {
11 	ArrayBuffer	ab;
12 	uint	au = *(cast(uint*)cast(void*)&ab);
13 	assert(ab.id==au, "Error, byte data for Struct is not as expected.");
14 	uint	bu;
15 	ArrayBuffer	bb = *(cast(ArrayBuffer*)cast(void*)&bu);
16 	assert(bb.id==bu, "Error, byte data for Struct is not as expected.");
17 	ArrayBuffer	[2]	cb;
18 	uint	[2]	cu = cast(uint[])cast(void[])cb;
19 	assert(cb[0].id==cu[0], "Error, byte data for Struct is not as expected.");
20 	assert(cb[1].id==cu[1], "Error, byte data for Struct is not as expected.");
21 }
22 
23 
24 /**	A wrapper for buffers.*/
25 struct Buffer(BufferType bufferType) {
26 	uint id = 0;
27 	static Buffer!bufferType opCall(void[] data, BufferUsage usage) {
28 		import std.stdio;
29 		bufferType.writeln;
30 		Buffer!bufferType buffer;
31 		buffer.gen;
32 		buffer.bind;
33 		buffer.data(data,usage);
34 		return buffer;
35 	}
36 }
37 alias ArrayBuffer	= Buffer!(BufferType.Array	) ;
38 alias AtomicCounterBuffer	= Buffer!(BufferType.AtomicCounter	) ;
39 alias CopyReadBuffer	= Buffer!(BufferType.CopyRead	) ;
40 alias CopyWriteBuffer	= Buffer!(BufferType.CopyWrite	) ;
41 alias DispatchIndirectBuffer	= Buffer!(BufferType.DispatchIndirect	) ;
42 alias DrawIndirectBuffer	= Buffer!(BufferType.DrawIndirect	) ;
43 alias ElementArrayBuffer	= Buffer!(BufferType.ElementArray	) ;
44 alias PixelPackBuffer	= Buffer!(BufferType.PixelPack	) ;
45 alias PixelUnpackBuffer	= Buffer!(BufferType.PixelUnpack	) ;
46 alias QueryBuffer	= Buffer!(BufferType.Query	) ;
47 alias ShaderStorageBuffer	= Buffer!(BufferType.ShaderStorage	) ;
48 alias TextureBuffer	= Buffer!(BufferType.Texture	) ;
49 alias TransformFeedbackBuffer	= Buffer!(BufferType.TransformFeedback	) ;
50 alias UniformBuffer	= Buffer!(BufferType.Uniform	) ;
51 
52 
53 
54 
55 enum BufferType {
56 	Array	= GL_ARRAY_BUFFER	,
57 	AtomicCounter	= GL_ATOMIC_COUNTER_BUFFER	,
58 	CopyRead	= GL_COPY_READ_BUFFER	,
59 	CopyWrite	= GL_COPY_WRITE_BUFFER	,
60 	DispatchIndirect	= GL_DISPATCH_INDIRECT_BUFFER	,
61 	DrawIndirect	= GL_DRAW_INDIRECT_BUFFER	,
62 	ElementArray	= GL_ELEMENT_ARRAY_BUFFER	,
63 	PixelPack	= GL_PIXEL_PACK_BUFFER	,
64 	PixelUnpack	= GL_PIXEL_UNPACK_BUFFER	,
65 	Query	= GL_QUERY_BUFFER	,
66 	ShaderStorage	= GL_SHADER_STORAGE_BUFFER	,
67 	Texture	= GL_TEXTURE_BUFFER	,
68 	TransformFeedback	= GL_TRANSFORM_FEEDBACK_BUFFER	,
69 	Uniform	= GL_UNIFORM_BUFFER	,
70 }
71 
72 
73 enum BufferUsage {
74 	StreamDraw	= GL_STREAM_DRAW	,
75 	StreamRead	= GL_STREAM_READ	,
76 	StreamCopy	= GL_STREAM_COPY	,
77 	StaticDraw	= GL_STATIC_DRAW	,
78 	StaticRead	= GL_STATIC_READ	,
79 	StaticCopy	= GL_STATIC_COPY	,
80 	DynamicDraw	= GL_DYNAMIC_DRAW	,
81 	DynamicRead	= GL_DYNAMIC_READ	,
82 	DynamicCopy	= GL_DYNAMIC_COPY	,
83 }
84 
85 
86 
87 
88 /**	glGenBuffers() wrapper.
89 */
90 void
91 gen(BufferType bufferType)(ref Buffer!bufferType buffer)
92 {
93 	glGenBuffers(1, &buffer.id);
94 }
95 /**	glGenBuffers() wrapper.
96 */
97 void
98 gen(BufferType bufferType)(ref Buffer!bufferType[] buffers)
99 {
100 	// Works because a struct with a single var has the same byte data and size as its only var.
101 	glGenBuffers(buffers.length, buffers.ptr);
102 }
103 
104 
105 /**	glDeleteBuffers() wrapper.
106 */
107 void
108 del(BufferType bufferType)(ref Buffer!bufferType buffer)
109 {
110 	glDeleteBuffers(1, &buffer.id);
111 }
112 
113 
114 
115 
116 
117 
118 
119 
120 enum string buffer_ensureGen_m = "version(assert){assert(buffer.id!=0, \"Buffer not generated.  Call `buffer.gen` before using this function.\");}";
121 enum string buffer_ensureBound_m = buffer_ensureGen_m~"version(assert){
122 static if(is(typeof(buffer)==ArrayBuffer)) {
123 	uint bb;//bound buffer
124 	glGetIntegerv(GL_ARRAY_BUFFER_BINDING, cast(int*)&bb);
125 	assert(buffer.id==bb, \"Buffer not bound.  Call `buffer.bind` before using this function.\");
126 }
127 else {
128 	pragma(msg, \"No test for this buffer being bound (currently), be sure it is (to bind call `bind` method).\");
129 }}";
130 
131 
132 
133 
134 
135 
136 /**	glBindBuffer() wrapper.  
137 	Binds buffer to be used by future calls.
138 */
139 void 
140 bind(BufferType bufferType)(Buffer!bufferType buffer)
141 {
142 	mixin(buffer_ensureGen_m);
143 	glBindBuffer(bufferType, buffer.id);
144 }
145 /**ditto*/
146 alias use=bind;
147 
148 
149 
150 
151 
152 
153 /**	glBufferData() wrapper.  
154 	Sets the buffer's data.
155 */
156 void 
157 data(BufferType bufferType)(Buffer!bufferType buffer, void[] data, BufferUsage usage)
158 {
159 	mixin(buffer_ensureBound_m);
160 	glBufferData(bufferType, data.length, data.ptr, usage);
161 }
162 
163 
164 
165 /**	body() wrapper.  
166 	Sets the buffer's sub data.
167 */
168 void 
169 subData(BufferType bufferType)(Buffer!bufferType buffer, void[] data, size_t offset)
170 {
171 	mixin(buffer_ensureBound_m);
172 	glBufferSubData(bufferType, offset, data.length, data.ptr);
173 }
174 
175 
176 
177 /**	glGetBufferSubData() wrapper.  
178 	Gets the buffer's sub data.
179 */
180 void 
181 getSubData(BufferType bufferType)(Buffer!bufferType buffer, void* data, size_t offset, size_t length)
182 {
183 	mixin(buffer_ensureBound_m);
184 	glGetBufferSubData(bufferType, offset, length, data);
185 }