为bindbc.sfml编写OO包装器后图形无法显示的问题排查
问题:自定义bindbc-sfml面向对象包装器中矩形不显示的排查
我正在为bindbc.sfml编写面向对象包装器,原因是CSFML的C风格语法不太适合面向对象语言,而且频繁处理指针存在安全隐患。需要说明的是,CSFML本身很优秀,我已经用bindbc-sfml开发过一些应用,只是希望通过包装器让接口更贴近C++ SFML的语法风格。
实现的Shape基类
首先实现了模仿C++ SFML的Shape类,继承Transformable类和Drawable接口,设计和SFML大致匹配:
class Shape : Transformable, Drawable { void setTexture(sfTexture* texture, bool resetRect) { ptr.sfShape_setTexture(texture, resetRect); } void setTextureRect(IntRect rect) { ptr.sfShape_setTextureRect(rect.to_sfIntRect()); } void setFillColor(Color color) { ptr.sfShape_setFillColor(color.to_sfColor()); } void setOutlineColor(Color color) { ptr.sfShape_setOutlineColor(color.to_sfColor()); } void setOutlineThickness(float thickness) { ptr.sfShape_setOutlineThickness(thickness); } const(sfTexture)* getTexture() { return ptr.sfShape_getTexture(); } IntRect getTextureRect() { return ptr.sfShape_getTextureRect().toIntRect(); } Color getFillColor() { return ptr.sfShape_getFillColor().toColor(); } Color getOutlineColor() { return ptr.sfShape_getOutlineColor().toColor(); } float getOutlineThickness() { return ptr.sfShape_getOutlineThickness(); } size_t getPointCount() nothrow { return ptr.sfShape_getPointCount(); } Vector2f getPoint(size_t index) nothrow { return ptr.sfShape_getPoint(index).toVector2f_noThrow(); } FloatRect getLocalBounds() { return ptr.sfShape_getLocalBounds().toFloatRect(); } FloatRect getGlobalBounds() { return ptr.sfShape_getGlobalBounds().toFloatRect(); } private sfShape* ptr; }
该类的sfShape*指针暂未初始化,后续补充了相关逻辑。
RectangleShape子类实现
接着实现了Shape的子类RectangleShape,仅重写getPointCount和getPoint方法,供父类构建可绘制图形:
class RectangleShape : Shape { this(Vector2f size) { _size = size; setSize(_size); } Vector2f getSize() { return _size; } void setSize(Vector2f size) { _size = size; } override { size_t getPointCount() { return 4; } Vector2f getPoint(size_t index) { final switch (index) { case 0: return Vector2f(0, 0); case 1: return Vector2f(_size.x, 0); case 2: return Vector2f(_size.x, _size.y); case 3: return Vector2f(0, _size.y); } } } private Vector2f _size; }
为Shape添加构造与回调逻辑
之后为Shape类补充了构造函数和C风格回调函数,通过子类的方法初始化sfShape*指针:
class Shape : Transformable, Drawable { this() { ptr = sfShape_create(&getPointCount, &getPoint, cast(void*)this); } extern(C) private static ulong getPointCount(void* data) nothrow { return (cast(Shape)data).getPointCount(); } extern(C) private static sfVector2f getPoint(size_t index, void* data) nothrow { return (cast(Shape)data).getPoint(index).to_sfVector2f_noThrow(); } // 其余原有方法省略 }
这里通过函数指针传入回调,并将当前对象作为void*类型的data参数传递。
测试代码
编写了如下测试代码:
void main() { loadSFML(); RectangleShape rectangleShape = new RectangleShape(Vector2f(50, 50)); rectangleShape.setPosition(Vector2f(50, 50)); rectangleShape.setFillColor(Color.Blue); RenderWindow renderWindow = new RenderWindow(sfVideoMode(500, 500), "Tests", sfWindowStyle.sfDefaultStyle, null); sfEvent event; while (renderWindow.isOpen()) { while (renderWindow.pollEvent(&event)) { if (event.type == sfEventType.sfEvtClosed) { renderWindow.close(); } } renderWindow.clear(Color.Yellow); renderWindow.ptr.sfRenderWindow_drawShape(rectangleShape.ptr, null); renderWindow.display(); } }
问题现象
预期会显示一个位于(50,50)位置、尺寸50x50的蓝色矩形,但运行后仅显示黄色窗口,矩形未出现。无法确定是自身实现错误还是bindbc-sfml的bug,需要排查问题原因。
内容的提问来源于stack exchange,提问作者thebluepandabear
相关产品推荐
相关产品推荐

