1 module vadgl.types;
2 
3 // TODO: Be less dependant on this
4 import bindbc.opengl;
5 
6 // TODO: Check that all Args are string
7 private template buildEnumBodyString(Args...)
8 {
9     static if (Args.length == 1)
10         enum string buildEnumBodyString = Args[0]~"\n";
11     else
12         enum string buildEnumBodyString = Args[0]~", \n"~buildEnumBodyString!(Args[1..$]);
13 }
14 
15 // For some reason this doesn't work
16 /* private template FilterArgs(args...) */
17 /* { */
18 /*     import std.meta; */
19 /*     import std.range    : iota; */
20 
21 /*     alias FilterArgs_ = AliasSeq!(); */
22 /*     static foreach (i; iota(0, args.length, 2)) { */
23 /*         static if (args[i+1]) { */
24 /*             FilterArgs = AliasSeq!(FilterArgs, args[i]); */
25 /*         } */
26 /*     } */
27 /* } */
28 
29 private template FilterArgs(Args...) if (Args.length % 2 == 0)
30 {
31     import std.meta;
32     static if (Args.length == 2) {
33         static if (Args[1]) {
34             alias FilterArgs = AliasSeq!(Args[0]);
35         }
36         else {
37             alias FilterArgs = AliasSeq!();
38         }
39     }
40     else {
41         static if (Args[1]) {
42             alias FilterArgs = AliasSeq!(Args[0], FilterArgs!(Args[2..$]));
43         }
44         else {
45             alias FilterArgs = FilterArgs!(Args[2..$]);
46         }
47     }
48 
49 }
50 
51 private mixin template ConditionalEnum(string enum_name, Args...)
52 {
53     mixin("enum "~enum_name~" {\n "~
54             buildEnumBodyString!(FilterArgs!Args)~
55         "};\n"
56     );
57 }
58 
59 mixin ConditionalEnum!("GLType",
60     "BYTE = GL_BYTE",               glSupport >= GLSupport.gl11,
61     "UBYTE = GL_UNSIGNED_BYTE",     glSupport >= GLSupport.gl11,
62     "SHORT = GL_SHORT",             glSupport >= GLSupport.gl11,
63     "USHORT = GL_UNSIGNED_SHORT",   glSupport >= GLSupport.gl11,
64 
65     "INT = GL_INT",                 glSupport >= GLSupport.gl11,
66     "UINT = GL_UNSIGNED_INT",       glSupport >= GLSupport.gl11,
67 
68     "FLOAT = GL_FLOAT",             glSupport >= GLSupport.gl11,
69     "DOUBLE = GL_DOUBLE",           glSupport >= GLSupport.gl11,
70 
71     "VEC2 = GL_FLOAT_VEC2",         glSupport >= GLSupport.gl20,
72     "VEC3 = GL_FLOAT_VEC3",         glSupport >= GLSupport.gl20,
73     "VEC4 = GL_FLOAT_VEC4",         glSupport >= GLSupport.gl20,
74 
75     "IVEC2 = GL_INT_VEC2",          glSupport >= GLSupport.gl20,
76     "IVEC3 = GL_INT_VEC3",          glSupport >= GLSupport.gl20,
77     "IVEC4 = GL_INT_VEC4",          glSupport >= GLSupport.gl20,
78 
79     // OpenGL version 3.0 or above
80     "HALF_FLOAT = GL_HALF_FLOAT",   glSupport >= GLSupport.gl30,
81     "UVEC2 = GL_UNSIGNED_INT_VEC2", glSupport >= GLSupport.gl30,
82     "UVEC3 = GL_UNSIGNED_INT_VEC3", glSupport >= GLSupport.gl30,
83     "UVEC4 = GL_UNSIGNED_INT_VEC4", glSupport >= GLSupport.gl30,
84 );
85 
86 
87 // This is what the expression above should compile to
88 /* enum GLType */
89 /* { */
90 /*     // Basic GL types */
91 /*     //>> Accepted by `glVertexAttribPointer` and `glVertexAttribIPointer` */
92 /*     BYTE = GL_BYTE, */
93 /*     UBYTE = GL_UNSIGNED_BYTE, */
94 
95 /*     SHORT = GL_SHORT, */
96 /*     USHORT = GL_UNSIGNED_SHORT, */
97 
98 /*     INT = GL_INT, */
99 /*     UINT = GL_UNSIGNED_INT, */
100 /*     //<< end acceppted by `glVertexAttribIPointer` */
101 
102 /*     //>> Accepted by `glVertexAttribPointer` and `glVertexAttribLPointer` */
103 /*     FLOAT = GL_FLOAT, */
104 /*     HALF_FLOAT = GL_HALF_FLOAT, // requires OpenGL version >=3.0 */
105 /*     DOUBLE = GL_DOUBLE, */
106 /*     //<< End acceppted by `glVertexAttribPointer` and `glVertexAttribLPointer` */
107 
108 /*     // Vector types */
109 /*     VEC2 = GL_FLOAT_VEC2, */
110 /*     VEC3 = GL_FLOAT_VEC3, */
111 /*     VEC4 = GL_FLOAT_VEC4, */
112 
113 /*     IVEC2 = GL_INT_VEC2, */
114 /*     IVEC3 = GL_INT_VEC3, */
115 /*     IVEC4 = GL_INT_VEC4, */
116 
117 /*     // Add a bool vectors here */
118 
119 /*     // Requires gl30 */
120 /*     UVEC2 = GL_UNSIGNED_INT_VEC2, */
121 /*     UVEC3 = GL_UNSIGNED_INT_VEC3, */
122 /*     UVEC4 = GL_UNSIGNED_INT_VEC4, */
123 
124 /*     // TODO: Add matrix types */
125 /* } */
126 
127 // TODO: maybe make module
128 enum GLFuncEnum : string
129 {
130     UNKNOWN_GL_FUNCTION = "unknown_function", // General OpenGL error for any function
131     GL_CREATE_SHADER = "glCreateShader",
132     GL_SHADER_SOURCE = "glShaderSource",
133     GL_COMPILE_SHADER = "glCompileShader",
134 
135     GL_ATTACH_SHADER = "glAttachShader",
136     GL_LINK_PROGRAM = "glLinkProgram",
137 
138     GL_BIND_VERTEX_ARRAY = "glBindVertexArray",
139     GL_BUFFER_DATA = "glBufferData",
140     GL_BIND_BUFFER = "glBindBuffer",
141 
142     GL_VERTEX_ATTRIB_POINTER = "glVertexAttribPointer",
143     GL_VERTEX_ATTRIB_I_POINTER = "glVertexAttribIPointer",
144 
145     GL_ENABLE_VERTEX_ATTRIB_ARRAY = "glEnableVertexAttribArray",
146     GL_ENABLE_DISABLE_ATTRIB_ARRAY = "glDisableVertexAttrbArray",
147 
148 
149     CREATE_SHADER = "create_shader",
150     SHADER_COMPILE = "",
151 
152     PROGRAM_ATTACH = "",
153     PROGRAM_LINK = "",
154     PROGREM_VALIDATE = "",
155 
156     BIND = "",
157 }
158 
159 // This should all work with OpenGL version 1.1 or above so no need for condition
160 // TODO: make this support multiple OpenGL versions
161 enum GLInternalError : uint
162 {
163     NO_ERROR                       = GL_NO_ERROR,
164     INVALID_ENUM                   = GL_INVALID_ENUM,
165     INVALID_VALUE                  = GL_INVALID_VALUE,
166     INVALID_OPERATION              = GL_INVALID_OPERATION,
167     STACK_OVERFLOW                 = GL_STACK_OVERFLOW,
168     STACK_UNDERFLOW                = GL_STACK_UNDERFLOW,
169 }
170 
171 /* enum GLParam { */
172 /*     SHADER_TYPE               =  GL_SHADER_TYPE, */
173 /*     DELETE_STATUS             =  GL_DELETE_STATUS, */
174 /*     COMPILE_STATUS            =  GL_COMPILE_STATUS, */
175 /*     INFO_LOG_LENGTH           =  GL_INFO_LOG_LENGTH, */
176 /*     SHADER_SOURCE_LENGTH      =  GL_SHADER_SOURCE_LENGTH, */
177 
178 /*     LINK_STATUS               =  GL_LINK_STATUS, */
179 /*     VALIDATE_STATUS           =  GL_VALIDATE_STATUS, */
180 /*     ATTACHED_SHADERS          =  GL_ATTACHED_SHADERS, */
181 
182 /*     // Only in OpenGL >=  3.2 */
183 /*     GEOMETRY_VERTICES_OUT     =  GL_GEOMETRY_VERTICES_OUT, */
184 /*     GEOMETRY_INPUT_TYPE       =  GL_GEOMETRY_INPUT_TYPE, */
185 /*     GEOMETRY_OUTPUT_TYPE      =  GL_GEOMETRY_OUTPUT_TYPE, */
186 /* } */
187 
188 mixin ConditionalEnum!("GLParam",
189     "SHADER_TYPE = GL_SHADER_TYPE",                       glSupport >= GLSupport.gl20,
190     "DELETE_STATUS = GL_DELETE_STATUS",                   glSupport >= GLSupport.gl20,
191     "COMPILE_STATUS = GL_COMPILE_STATUS",                 glSupport >= GLSupport.gl20,
192     "INFO_LOG_LENGTH = GL_INFO_LOG_LENGTH",               glSupport >= GLSupport.gl20,
193     "SHADER_SOURCE_LENGTH = GL_SHADER_SOURCE_LENGTH",     glSupport >= GLSupport.gl20,
194 
195     "LINK_STATUS = GL_LINK_STATUS",                       glSupport >= GLSupport.gl20,
196     "VALIDATE_STATUS = GL_VALIDATE_STATUS",               glSupport >= GLSupport.gl20,
197     "ATTACHED_SHADERS = GL_ATTACHED_SHADERS",             glSupport >= GLSupport.gl20,
198 
199     // Only in OpenGL > = 3.2
200     "GEOMETRY_VERTICES_OUT = GL_GEOMETRY_VERTICES_OUT",   glSupport >= GLSupport.gl32,
201     "GEOMETRY_INPUT_TYPE = GL_GEOMETRY_INPUT_TYPE",       glSupport >= GLSupport.gl32,
202     "GEOMETRY_OUTPUT_TYPE = GL_GEOMETRY_OUTPUT_TYPE",     glSupport >= GLSupport.gl32,
203 );