0

我正在开发一个简单的图形引擎,并且我有 Drawable 对象,这些对象应该在创建时(在构造函数中)将自己注册到渲染器(通过将它们插入到集合中)。它们还需要为渲染进行排序(通过透明度、深度掩码等),即它们需要通过一些布尔标志进行排序。

所以这是我的一套。

std::set<Drawable *, DrawableComp> drawable_set;

比较函子:

struct DrawableComp : public std::binary_function<const Drawable *, const Drawable *, bool> {
    bool operator() (const Drawable * lhs, const Drawable * rhs) const
    {
        return *lhs < *rhs;
    }
};

以及 Drawable 的重载 operator<:

bool Drawable::operator<(const Drawable & rhs) const
{
    if (writesDepth() != rhs.writesDepth())
        return !writesDepth() < !rhs.writesDepth();
    else
        return getSortNumber() < rhs.getSortNumber();
}

请注意,这应该按顺序将 Drawables 插入到集合中,以便首先进入写入深度缓冲区的对象,然后是那些不写入深度缓冲区的对象。每个对象的排序号都是唯一的。

问题是,这行不通。我得到在集合结束时写入深度缓冲区的 Drawable。

此外, writeDepth() 是虚拟布尔函数。Drawable 只是一个抽象接口。如果我将 writeDepth() 设为纯虚拟,则会收到运行时错误“调用纯虚拟方法”。我不太清楚为什么会这样,因为我从来没有把 Drawable 对象放在集合中,而是放在它的具体实现中。

4

1 回答 1

0

好的,我发现了问题。我正在从 Drawable 构造函数注册 Drawables。我在构造函数中有这个调用(registerDrawable 只是插入到集合中):

Application::get().getRenderer().registerDrawable(this);

问题是这会发送指向 Drawable 类型对象的指针,而不是某些派生类型,因此设置“不知道”派生类是什么,它只是调用基方法 writeDepth()。

简单的解决方案是将此调用移至派生构造函数。虽然它在我的设计中插入了一些混乱和冗余......

于 2012-10-20T06:12:08.357 回答