glfwSetCursorPosCallback to function in another class

孤街浪徒 提交于 2020-01-11 11:26:49

问题


I'm really stuck:

I have the mainWindow and in the main game loop I do:

// poll for input
glfwPollEvents();

this->controls->handleInput(window, world->getPlayer());
glfwSetCursorPosCallback(window, controls->handleMouse);

What I want to do is to have one class responsible for the controls and to have this class also handle the mouse.

I always get:

'Controls::handleMouse': function call missing argument list; use '&Controls::handleMouse' to create a pointer to member

Now when I try this I get:

'GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow *,GLFWcursorposfun)' : cannot convert argument 2 from 'void (__thiscall Controls::* )(GLFWwindow *,double,double)' to 'GLFWcursorposfun'

Not sure what I'm doing wrong here, as GLFWcursorposfun is just a typedef with a GLFWwindow and two doubles.

As the function is in another class I tried creating a prototype for it, like:

class Controls {
    void handleInput(GLFWwindow *window, object *gameObject);
    void handleMouse(GLFWwindow *window, double mouseXPos, double mouseYPos);
};

but to no avail.

edit: Of course I can set it to &Controls::handleMouse if I make the function static, but I'd rather be able to create multiple Controls-Objects with different cameras and gameObjects they manipulate.

Also, how to get in the correct camera/gameObject data then?


回答1:


You can't pass a class's member function as a function. glfwSetCursorPosCallback it's expecting a function and throwing the error because it gets a member function.

In other words your expected to provide a global function and pass that to glfwSetCursorPosCallback.

If you really want the controls object to get the cursor position callback you could store an instance of Controls in a global variable and pass on the callback to that instance. Something like this:

static Controls* g_controls;

void mousePosWrapper( double x, double y )
{
    if ( g_controls )
    {
        g_controls->handleMouse( x, y );
    }
}

Then when you call glfwSetCursorPosCallback you can pass the mousePosWrapper function:

glfwSetCursorPosCallback( window, mousePosWrapper );



回答2:


My solution: Do not use the callback-setter. Instead I do the following:

glfwPollEvents();

this->controls->handleInput(window, mainObj);
this->controls->handleMouse(window, mainObj);

And within handleMouse I do:

GLdouble xPos, yPos;
glfwGetCursorPos(window, &xPos, &yPos);



回答3:


An alternative solution would be to associate a pointer to controls to the GLFWindow. See glfwSetWindowUserPointer.

The pointer can be retrieved at an time form the GLFWWindow object by glfwGetWindowUserPointer. Of course the return type is void* and has to be casted to Controls*.

Instead of the global function or static method a Lambda expressions can be used. e.g:

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);
} );


来源:https://stackoverflow.com/questions/29356783/glfwsetcursorposcallback-to-function-in-another-class

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!