user4063815
user4063815

Reputation:

glfwSetCursorPosCallback to function in another class

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?

Upvotes: 3

Views: 5360

Answers (3)

Rabbid76
Rabbid76

Reputation: 211176

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

Upvotes: 3

user4063815
user4063815

Reputation:

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

Upvotes: 3

David Saxon
David Saxon

Reputation: 1436

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

Upvotes: 4

Related Questions