glfwSetCursorPosCallback 在另一个 class 中运行
glfwSetCursorPosCallback to function in another class
我真的卡住了:
我有主窗口,在主游戏循环中我这样做:
// poll for input
glfwPollEvents();
this->controls->handleInput(window, world->getPlayer());
glfwSetCursorPosCallback(window, controls->handleMouse);
我想做的是让一个 class 负责控制,并让这个 class 也处理鼠标。
我总是得到:
'Controls::handleMouse': function call missing argument list; use '&Controls::handleMouse' to create a pointer to member
现在,当我尝试这个时,我得到:
'GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow *,GLFWcursorposfun)' : cannot convert argument 2 from 'void (__thiscall Controls::* )(GLFWwindow *,double,double)' to 'GLFWcursorposfun'
不确定我在这里做错了什么,因为 GLFWcursorposfun 只是一个带有 GLFWwindow 和两个双打的 typedef。
由于该函数在另一个 class 中,我尝试为其创建一个原型,例如:
class Controls {
void handleInput(GLFWwindow *window, object *gameObject);
void handleMouse(GLFWwindow *window, double mouseXPos, double mouseYPos);
};
但无济于事。
编辑:当然我可以将它设置为 &Controls::handleMouse 如果我将函数设为静态,但我宁愿能够使用不同的相机和它们操纵的游戏对象创建多个控件对象。
另外,如何获取正确的camera/gameObject数据呢?
您不能将 class 的成员函数作为函数传递。 glfwSetCursorPosCallback
它期待一个函数并抛出错误,因为它获得了一个成员函数。
换句话说,您希望提供一个全局函数并将其传递给 glfwSetCursorPosCallback
。
如果您确实希望控件对象获得光标位置回调,您可以将控件实例存储在全局变量中并将回调传递给该实例。像这样:
static Controls* g_controls;
void mousePosWrapper( double x, double y )
{
if ( g_controls )
{
g_controls->handleMouse( x, y );
}
}
然后当你调用glfwSetCursorPosCallback
时你可以传递mousePosWrapper
函数:
glfwSetCursorPosCallback( window, mousePosWrapper );
我的解决方案:不使用回调-setter。相反,我执行以下操作:
glfwPollEvents();
this->controls->handleInput(window, mainObj);
this->controls->handleMouse(window, mainObj);
在 handleMouse 中我做的是:
GLdouble xPos, yPos;
glfwGetCursorPos(window, &xPos, &yPos);
另一种解决方案是将指向 controls
的指针关联到 GLFWindow
。参见 glfwSetWindowUserPointer
。
可以通过 glfwGetWindowUserPointer
从 GLFWWindow
对象中一次检索指针。当然 return 类型是 void*
并且必须转换为 Controls*
。
可以使用 Lambda expressions 而不是全局函数或静态方法。例如:
glfwSetWindowUserPointer(window, this->controls);
glfwSetCursorPosCallback( window, [](GLFWwindow *window, double x, double y)
{
if (Controls *controls = static_cast<Controls*>(glfwGetWindowUserPointer(window)))
controls->handleMouse(window, x, y);
} );
我真的卡住了:
我有主窗口,在主游戏循环中我这样做:
// poll for input
glfwPollEvents();
this->controls->handleInput(window, world->getPlayer());
glfwSetCursorPosCallback(window, controls->handleMouse);
我想做的是让一个 class 负责控制,并让这个 class 也处理鼠标。
我总是得到:
'Controls::handleMouse': function call missing argument list; use '&Controls::handleMouse' to create a pointer to member
现在,当我尝试这个时,我得到:
'GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow *,GLFWcursorposfun)' : cannot convert argument 2 from 'void (__thiscall Controls::* )(GLFWwindow *,double,double)' to 'GLFWcursorposfun'
不确定我在这里做错了什么,因为 GLFWcursorposfun 只是一个带有 GLFWwindow 和两个双打的 typedef。
由于该函数在另一个 class 中,我尝试为其创建一个原型,例如:
class Controls {
void handleInput(GLFWwindow *window, object *gameObject);
void handleMouse(GLFWwindow *window, double mouseXPos, double mouseYPos);
};
但无济于事。
编辑:当然我可以将它设置为 &Controls::handleMouse 如果我将函数设为静态,但我宁愿能够使用不同的相机和它们操纵的游戏对象创建多个控件对象。
另外,如何获取正确的camera/gameObject数据呢?
您不能将 class 的成员函数作为函数传递。 glfwSetCursorPosCallback
它期待一个函数并抛出错误,因为它获得了一个成员函数。
换句话说,您希望提供一个全局函数并将其传递给 glfwSetCursorPosCallback
。
如果您确实希望控件对象获得光标位置回调,您可以将控件实例存储在全局变量中并将回调传递给该实例。像这样:
static Controls* g_controls;
void mousePosWrapper( double x, double y )
{
if ( g_controls )
{
g_controls->handleMouse( x, y );
}
}
然后当你调用glfwSetCursorPosCallback
时你可以传递mousePosWrapper
函数:
glfwSetCursorPosCallback( window, mousePosWrapper );
我的解决方案:不使用回调-setter。相反,我执行以下操作:
glfwPollEvents();
this->controls->handleInput(window, mainObj);
this->controls->handleMouse(window, mainObj);
在 handleMouse 中我做的是:
GLdouble xPos, yPos;
glfwGetCursorPos(window, &xPos, &yPos);
另一种解决方案是将指向 controls
的指针关联到 GLFWindow
。参见 glfwSetWindowUserPointer
。
可以通过 glfwGetWindowUserPointer
从 GLFWWindow
对象中一次检索指针。当然 return 类型是 void*
并且必须转换为 Controls*
。
可以使用 Lambda expressions 而不是全局函数或静态方法。例如:
glfwSetWindowUserPointer(window, this->controls);
glfwSetCursorPosCallback( window, [](GLFWwindow *window, double x, double y)
{
if (Controls *controls = static_cast<Controls*>(glfwGetWindowUserPointer(window)))
controls->handleMouse(window, x, y);
} );