我正在为我拥有的所有图形用户界面对象创建一个Display list,如下所示:
glNewList(displayList, GL_COMPILE);
obj->draw();
glEndList();R6025 - pure virtual calldraw()方法是纯虚拟的。
编辑:
这是GUIObject类:
class GUIObject
{
protected:
int m_id;
int m_parentId;
int m_width;
int m_height;
Point m_position;
Point m_drawPosition;
bool m_bEnabled;
bool m_bVisible;
GLuint m_displayListId; // Id in display lists array in TGUIManager
virtual void onDrawStart() = 0;
virtual void onDrawFinish() = 0;
public:
virtual bool draw() = 0;
void setDisplayListId(GLuint id);
GLuint getDisplayListId();
virtual int getWidth() const;
virtual int getHeight() const;
virtual bool pointInObject(const TPoint& point);
GUIObject();
virtual ~GUIObject();
};
GUIObject::GUIObject() :
m_position(Point(0,0)),
m_width(0),
m_height(0),
{
m_drawPosition = m_position;
GUIManager::Instance().addObject(this);
}
GUIObject::~GUIObject()
{
}这是Button类,它派生自Component,它派生自GUIObject
class Button : public Component, public Clickable
{
private:
std::string m_text;
TBackground* m_pBackground;
public:
void setText(std::string text);
void setBackground(Background* pBg);
Background* getBackground() const;
void setBackgroundOnClick(Background* pBg);
Background* getBackgroundOnClick() const;
bool draw();
int getFontSize() const;
std::string getText() const;
Button& operator=(const Button & button);
// From Clickable
bool wasClicked(const Point& clickPos);
Button();
~Button();
};
bool Button::draw()
{
onDrawStart(); // This needs to be called in each object
if(!isClicked() && m_pBackground != nullptr)
m_pBackground->draw(m_drawPosition, m_width, m_height);
else if(m_pBackgroundOnClick != nullptr)
m_pBackgroundOnClick->draw(m_drawPosition, m_width, m_height);
FontManager::Instance().renderLineOfText(font, lineLength, pos, textToRender);
onDrawFinish(); // This needs to be called in each object
return true;
}
Button::Button() :
TComponent(Point(0,0)),
m_pBackground(nullptr),
m_pBackgroundOnClick(nullptr),
m_text("")
{
}
Button::~Button()
{
if(m_pBackground != nullptr)
{
delete m_pBackground;
m_pBackground = nullptr;
}
}
Button& Button::operator=(const Button & button)
{
m_position = Point(button.getPos());
m_pBackground = new Background()
return *this;
}绘图内容在Background的draw()方法中。
名为obj的对象是作为参数在GUIObject的构造函数内的addObject()方法中传递的对象:
GUIManager::Instance().addObject(this);发布于 2012-12-31 06:53:04
好吧,看起来这是我犯的一个非常愚蠢的错误。正如我在编辑中对我的问题所解释的那样,obj对象是在方法addObject()中作为参数传递的对象,该方法在GUIObject的构造函数中被调用,这意味着Button的对象本身还没有被创建。编译器没有抱怨,因为GUIObject类已经声明了draw()方法,但只有在运行时才发现该方法缺乏定义。
但是不管怎样,感谢你们所有人告诉我,在显示列表中调用纯虚拟方法是非常好的。这帮助我找到了一个解决方案。
发布于 2012-12-31 04:29:41
到目前为止,我看到的唯一的可能性是Component没有定义virtual void onDrawStart() = 0或virtual void onDrawFinish() = 0。但是当你实例化Button的时候,你应该已经得到了一个错误。
您不需要在任何地方声明m_pBackgroundOnClick。它应该是Button的成员吗
发布于 2012-12-31 04:51:15
但是我想知道,为什么我不能在显示列表中放入虚函数?
此问题与OpenGL显示列表无关。见鬼的OpenGL显示列表是在运行时编译的,甚至不会与编译单元级别的函数交互。
我的印象是,您可能认为OpenGL显示列表将“记录”其中的所有。事实并非如此。API显示只列出OpenGL OpenGL调用的一部分记录。
发生的情况是,obj是从基类派生的类的实例,在基类中,draw被声明为纯虚拟的。例如。
class A {
virtual void draw() = 0; // draw is a pure virtual function
};和一个派生类
class B : public A {
// does not implement draw()
};现在,如果你的程序中有一些指向A的指针,即
A *pA;那么编译器当然会允许在这个指针上调用draw
pA->draw();在有效的假设下,pA实际上可能指向B
B b;
A *pA = &b;但是b没有实现draw,所以调用到了nirvana。
https://stackoverflow.com/questions/14093984
复制相似问题