由于draw
是一个非静态成员函数,它需要一个类的实例来操作。
在纯 C++ 中,您将使用函数对象(又名“函子”,参见std::function
或其前身boost::function
)。遗憾的是,这不是 C 或 C API 中的选项。
在这种情况下,由于没有数据传递给回调,因此您必须创建某种静态函数(类静态或文件静态),以便在调用时执行正确的操作。
如果你只有一个Mesh
,那么很容易:要么将类中的所有内容设为静态(在这种情况下,它基本上是一个命名空间),要么有一个非成员函数调用draw
你的一个实例Mesh
:
// at some global-ish file scope...
// we define our class
class Mesh { ... };
// and here's the one global instance of it
Mesh myOneMesh;
// and here is our global / static function that "knows"
// which instance to draw
void drawMyOneMesh() { myOneMesh.draw(); }
// then, in the main flow of your program:
glutDisplayFunc( &drawMyOneMesh );
如果您有多个网格,看起来您能做的最好的事情就是将其从当前窗口中关闭。在不了解您的应用程序或 GLUT API 的情况下,我可能会做这样的事情来启用每个窗口的网格回调:
#include <map>
// this could also be a class with all-static members, if one
// were so inclined. might be worth it, if only to protect 'map'
// from external meddling.
namespace WindowToMesh
{
typedef std::map< int, Mesh * > Map;
Map map;
void addMapping( int win, Mesh * mesh )
{
map.insert( { win, mesh } );
}
void removeMapping( int win )
{
map.erase( win );
}
void draw()
{
int win = glutGetWindow();
Map::iterator it = map.find( win );
if ( it != map.end() )
it.second->draw();
}
} // end namespace WindowToMesh
现在,在您的主程序中,您可以将新Mesh
窗口与当前窗口相关联:
Mesh * m = new Mesh( ... );
WindowToMesh::addMapping( glutGetWindow(), m );
您可以将(有效静态)WindowToMesh::draw
函数关联为回调:
glutDisplayFunc( &WindowToMesh::draw );
当您准备好销毁 时Mesh
,请确保您在同一个窗口中,然后:
WindowToMesh::removeMapping( glutGetWindow() );
根据其他因素,进行双向映射可能是有意义的(因此您可以通过Mesh *
而不只是通过 window找到东西int
,或者对罕见的取消注册进行暴力扫描等。
我没有可以测试的环境,但它应该很接近。祝你好运!