Notice: even that my example are from OpenGL, this is not an OpenGL question, but general D question.
Background: In my gaming project, I have shader class to help interfacing to GLSL code. Setting uniforms work nicely:
uniform(string name, float value) --> glUniform1f(...)
uniform(string name, mat4 m) --> glUniformMatrix4fv( ...)
etc. etc.
That is, it chooses right function depending on the type of the parameter, and so when I modify my code, it automatically changes to use correct function (assuming that I don't have type conflicts between D and GLSL).
My troubles are implementing somewhat similar mechanism to bind attributes. I have VERTEX structure:
struct VERTEX { ...; vec3 pos; ... }
For binding attribute, in addition to know the type of the field, I need the offset, but I don't need the values. I managed to write clumpsy implementation, where call looks like:
vbo.attrib!(typeof(mesh.VERTEX.pos))("vert_pos", mesh.VERTEX.pos.offsetof);
And VBO.attrib is implemented like this:
void attrib(T: vec2)(string name, ulong offset) { /* 2 floats from offset */ }
void attrib(T: vec3)(string name, ulong offset) { /* 3 floats from offset */ }
Question: Is there a way to make this simpler and more elegant? Generally, I don't like duplicating the field when calling, that is, first extract the type to choose correct attrib binding function, and then separately send offset. I would like the function call look something like this:
vbo.attrib("vert_pos", mesh.VERTEX.pos);
...And the template to extract both type and offset from the argument. I have read D template guides and tutorials, but I have't yet figured out how to implement templates like that. Is it possible and how?
Clarification: I have a feeling that I'm already close, I just don't have enough imagination (and knowledge from D templates and mixins) to implement the first phase:
XXX(name, field)
--> some unknown magic
--> vbo.attrib!(typeof(field))(name,field.offsetof)
--> void attrib(T: vec2)(string name, ulong offset) { /* arguments for GL call */ }
EDIT: With mixins, I managed to make it look like this:
template attrib(string name, string field)
{
const char[] attrib =
"vbo.attrib!" ~
"(typeof(" ~ field ~ "))" ~
"(\"" ~ name ~ "\", " ~ field ~ ".offsetof);";
}
mixin(attrib!("vert_pos", "mesh.VERTEX.pos"));
mixin(attrib!("vert_uv", "mesh.VERTEX.uv"));
To be honest, it (calling) looks even more complex to use than my current one, so I keep my current and look for nicer-looking solution.
void attrib(alias field)(string name) { alias T = typeof(field); auto offset = field.offsetof; /* rest of your code */ }But I'm not sure that the offsetof will actually work on an alias like that. - Adam D. Ruppethis. :( - Adam D. Ruppe