编辑:即使问题仍然存在,我还没有能够经常重现这一点,以便更接近地检查它.在问题的最后查看更多信息.
我开始开发游戏,我正在为它编写基本库.我在Linux Mint 13(Maya)上使用D编程语言和SDL-2以及OpenGL 3(使用Derelict3绑定).编译器是DMD64 D Compiler v2.067.1,我每次使用'rdmd'重建二进制文件.
为了渲染(更改)文本,我按需创建了字形.我用于此的代码是:
class Font {
...
Texture render(char c) {
if(!(c in rendered)) rendered[c] = texture(to!string(c));
return rendered[c];
}
Texture texture(string text) {
SDL_Color color={255, 255, 255, 255};
auto bitmap = TTF_RenderText_Blended(
font,
std.string.toStringz(text),
color
);
if(!bitmap) {
throw new TTFError(
"TTF_RenderText_Blended: " ~
to!string(TTF_GetError()) ~ ": '" ~ text ~ "'"
);
}
auto texture = new Texture(bitmap);
SDL_FreeSurface(bitmap);
return texture;
}
Run Code Online (Sandbox Code Playgroud)
问题是,这完全是随机的.有时候它没有任何问题.当它无法渲染一个字形时,有趣的是它将无法一遍又一遍地渲染相同的字形.这是捕获我抛出的异常时的示例:
...
TTF_RenderText_Blended: Text has zero width: '9'
TTF_RenderText_Blended: Text …Run Code Online (Sandbox Code Playgroud) 注意:即使我的例子来自OpenGL,这不是一个OpenGL问题,而是一般的D问题.
背景:在我的游戏项目中,我有一个着色器类来帮助连接到GLSL代码.制服工作很好:
uniform(string name, float value) --> glUniform1f(...)
uniform(string name, mat4 m) --> glUniformMatrix4fv( ...)
etc. etc.
Run Code Online (Sandbox Code Playgroud)
也就是说,它根据参数的类型选择正确的函数,因此当我修改我的代码时,它会自动更改为使用正确的函数(假设我没有D和GLSL之间的类型冲突).
我的麻烦是实现一些绑定属性的类似机制.我有VERTEX结构:
struct VERTEX { ...; vec3 pos; ... }
Run Code Online (Sandbox Code Playgroud)
对于绑定属性,除了知道字段的类型外,我还需要偏移量,但我不需要这些值.我设法写了一个丛生的实现,其中调用如下:
vbo.attrib!(typeof(mesh.VERTEX.pos))("vert_pos", mesh.VERTEX.pos.offsetof);
Run Code Online (Sandbox Code Playgroud)
VBO.attrib实现如下:
void attrib(T: vec2)(string name, ulong offset) { /* 2 floats from offset */ }
void attrib(T: vec3)(string name, ulong offset) { /* 3 floats from offset */ }
Run Code Online (Sandbox Code Playgroud)
问题:有没有办法让这更简单,更优雅?一般来说,我不喜欢在调用时复制字段,也就是首先提取类型来选择正确的attrib绑定函数,然后分别发送offset.我希望函数调用看起来像这样:
vbo.attrib("vert_pos", mesh.VERTEX.pos);
Run Code Online (Sandbox Code Playgroud)
...以及从参数中提取类型和偏移量的模板.我已经阅读了D模板指南和教程,但我还没弄清楚如何实现这样的模板.有可能吗?怎么样?
澄清:我有一种感觉,我已经接近,我只是没有足够的想象力(以及来自D模板和mixins的知识)来实现第一阶段:
XXX(name, field)
--> some unknown magic
--> vbo.attrib!(typeof(field))(name,field.offsetof)
--> void attrib(T: vec2)(string name, …Run Code Online (Sandbox Code Playgroud)