1 
2 
3 module glwt.program;
4 
5 import std.conv : to;
6 
7 import cst_	;
8 
9 import derelict.opengl	;
10 
11 import glwt.shader;
12 
13 
14 
15 
16 
17 
18 
19 
20 /**	A wrapper for a program.*/
21 struct Program {
22 	uint id = 0;
23 }
24 
25 
26 
27 
28 
29 /**	glCreateShader wrapper.
30 */
31 void
32 create(ref Program program)
33 {
34 	import std.stdio;
35 	program.id = glCreateProgram();
36 }
37 /**	glDeleteProgram wrapper.
38 */
39 void
40 del(ref Program program)
41 {
42 	glDeleteProgram(program.id);
43 }
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 enum string program_ensureGen_m = "version(assert){assert(program.id!=0, \"Program not created.  Call `program.create` before using this function.\");}";
56 enum string program_ensureBound_m = program_ensureGen_m~"version(assert){
57 	uint bp;//bound program
58 	glGetIntegerv(GL_CURRENT_PROGRAM, cast(int*)&bp);
59 	assert(program.id==bp, \"Program not in use (bound).  Call `program.use` before using this function.\");
60 }";
61 
62 
63 
64 
65 
66 void checkError(T)(T id) {
67 	import std.stdio;
68 	auto glErr = glGetError();
69 	if (glErr != GL_NO_ERROR) {
70 		id.writeln;
71 		writeln(glErr);
72 		if (glErr==GL_INVALID_VALUE	) {writeln("glErrGL_INVALID_VALUE"	);}
73 		if (glErr==GL_INVALID_OPERATION	) {writeln("glErrGL_INVALID_OPERATION"	);}
74 		if (glErr==GL_INVALID_FRAMEBUFFER_OPERATION	) {writeln("glErrGL_INVALID_FRAMEBUFFER_OPERATION"	);}
75 		if (glErr==GL_OUT_OF_MEMORY	) {writeln("glErrGL_OUT_OF_MEMORY"	);}
76 		////if (glErr==GL_STACK_UNDERFLOW	) {writeln("glErrGL_STACK_UNDERFLOW	");}
77 		////if (glErr==GL_STACK_OVERFLOW	) {writeln("glErrGL_STACK_OVERFLOW	");}
78 	}
79 }
80 
81 
82 
83 /**	glUseProgram wrapper.  
84 Binds program to be used by future calls.
85 */
86 void 
87 use(Program program)
88 {
89 	"a".checkError;
90 	mixin(program_ensureGen_m);
91 	"b".checkError;
92 	glUseProgram(program.id);
93 	"c".checkError;
94 	uint bp;//bound program
95 	glGetIntegerv(GL_CURRENT_PROGRAM, cast(int*)&bp);
96 	"d".checkError;
97 }
98 /**ditto*/
99 alias bind=use;
100 
101 
102 
103 
104 
105 
106 
107 
108 
109 
110 
111 
112 /**	glAttachShader wrapper
113 */
114 void
115 attach(ShaderType shaderType)(Program program, Shader!shaderType shader) 
116 {
117 	mixin(program_ensureGen_m);
118 	mixin(shader_ensureGen_m);
119 	glAttachShader(program.id, shader.id);
120 }
121 
122 
123 /**	glLinkProgram wrapper
124 */
125 void
126 link(Program program)
127 {
128 	mixin(program_ensureGen_m);
129 	glLinkProgram(program.id);
130 }
131 
132 
133 
134 
135 
136 
137 
138 
139 /**	glGetAttribLocation wrapper
140 */
141 int getAttribute(Program program, string name) {
142 	mixin(program_ensureGen_m);
143 	import std.string : toStringz;
144 	return glGetAttribLocation(program.id, name.toStringz);
145 }
146 ///ditto
147 alias getAttributeLocation = getAttribute;
148 ///ditto
149 alias getAttribLocation = getAttribute;
150 /**	glGetUniformLocation
151 */
152 int getUniform(Program program, string name) {
153 	mixin(program_ensureBound_m);
154 	import std.string : toStringz;
155 	return glGetUniformLocation(program.id, name.toStringz);
156 }
157 ///ditto
158 alias getUniformLocation = getUniform;
159 
160 
161 
162 
163 
164 
165 /**	glUniform wrapper
166 */
167 void uniform	(Type)	(Program program, int uniform, Type value )	if (mixin(constrainTypeWBool_m))	{	mixin(program_ensureBound_m); mixin("glUniform1"~mixin(typeToLetterWBool_m))	(uniform, value);	}
168 void uniformVector	(Type, int size:1)	(Program program, int uniform, Type[size] value )	if (mixin(constrainTypeWBool_m) && size>0)	{	mixin(program_ensureBound_m); mixin("glUniform"~size.to!string~mixin(typeToLetterWBool_m))	(uniform, value[0]);	}
169 void uniformVector	(Type, int size:2)	(Program program, int uniform, Type[size] value )	if (mixin(constrainTypeWBool_m) && size>0)	{	mixin(program_ensureBound_m); mixin("glUniform"~size.to!string~mixin(typeToLetterWBool_m))	(uniform, value[0],value[1]);	}
170 void uniformVector	(Type, int size:3)	(Program program, int uniform, Type[size] value )	if (mixin(constrainTypeWBool_m) &&  size>0)	{	mixin(program_ensureBound_m); mixin("glUniform"~size.to!string~mixin(typeToLetterWBool_m))	(uniform, value[0],value[1],value[2]);	}
171 void uniformVector	(Type, int size:4)	(Program program, int uniform, Type[size] value )	if (mixin(constrainTypeWBool_m) &&  size>0)	{	mixin(program_ensureBound_m); mixin("glUniform"~size.to!string~mixin(typeToLetterWBool_m))	(uniform, value[0],value[1],value[2],value[3]);	}
172 void uniformArray	(Type, int size, int length)	(Program program, int uniform, Type[size][length] value )	if (mixin(constrainTypeWOBool_m) && size>0&&size<=4 && length>0)	{	mixin(program_ensureBound_m); mixin("glUniform"~size.to!string~mixin(typeToLetterWOBool_m)~"v")	(uniform, length, value.ptr.cst!(Type*));	}
173 void uniformMatrix	(Type, int width, int height)	(Program program, int uniform, Type[width][height] value, bool transpose=false )	if (mixin(constrainTypeWOBool_m) && width>1&&width<=4 && height>1&&height<=4)	{	static if (width==height) {
174 						mixin(program_ensureBound_m); mixin("glUniformMatrix"~width.to!string~mixin(typeToLetterWOBool_m)~"v")	(uniform, 1, transpose, value.ptr.cst!(Type*));
175 					} else {
176 						mixin(program_ensureBound_m); mixin("glUniformMatrix"~width.to!string~"x"~height.to!string~mixin(typeToLetterWOBool_m)~"v")	(uniform, 1, transpose, value.ptr.cst!(Type*));
177 					}
178 				}
179 void uniformMatrices	(int width, int height, int length, Type)	(Program program, int uniform, Type[width][height][amount] value, bool transpose=false )	if (mixin(constrainTypeWOBool_m) && width>1&&width<=4 && height>1&&height<=4  && amount>0)	{	static if (width==height) {
180 						mixin(program_ensureBound_m); mixin("glUniformMatrix"~width.to!string~mixin(typeToLetterWOBool_m)~"v")	(uniform, length, transpose, value.ptr.cst!(Type*));
181 					} else {
182 						mixin(program_ensureBound_m); mixin("glUniformMatrix"~width.to!string~"x"~height.to!string~mixin(typeToLetterWOBool_m)~"v")	(uniform, length, transpose, value.ptr.cst!(Type*));
183 					}
184 				}
185 
186 alias setUniform	= uniform	;
187 alias setUniformVector	= uniformVector	;
188 alias setUniformArray	= uniformArray	;
189 alias setUniformMatrix	= uniformMatrix	;
190 alias setUniformMatrices	= uniformMatrices	;
191 
192 private enum string typeToLetterWBool_m = "((is(Type:int)||is(Type:bool))?\"i\":(is(Type:float)?\"f\":\"ui\"))";
193 private enum string typeToLetterWOBool_m = "(is(Type:int)?\"i\":(is(Type:float)?\"f\":\"ui\"))";
194 private enum string constrainTypeWBool_m = "(is(Type:int)||is(Type:float)||is(Type:uint)||is(Type:bool))";
195 private enum string constrainTypeWOBool_m = "(is(Type:int)||is(Type:float)||is(Type:uint))";
196 
197 
198 
199 
200 
201