0 votes

Erreur C2664 lors d'une tentative d'utilisation d'OpenGl en c++.

Voici un résumé de mon code. J'essaie d'utiliser glutSpecialFunc pour dire à glut d'utiliser ma fonction KeyPress.

class Car : public WorldObject
{
public:
 void KeyPress(int key, int x, int y)
 {
 }

 Car()
 {
  glutSpecialFunc(&Car::KeyPress); // C2664 error
 }
}

Le message d'erreur que je reçois est le suivant :

Error 1 error C2664: 'glutSpecialFunc' : cannot convert parameter 1 from 'void (__thiscall Car::* )(int,int,int)' to 'void (__cdecl *)(int,int,int)' c:\users\thorgeir\desktop\programmingproject1\quickness\quickness\car.cpp 18 Quickness

2voto

GManNickG Points 155079

Votre fonction est un membre d'une classe. Lorsque vous faites quelque chose comme Car c; c.drive() que drive() La fonction a besoin d'une voiture pour travailler. C'est le this pointeur. Donc glut ne peut pas appeler cette fonction s'il n'a pas de voiture sur laquelle travailler, il attend une fonction libre.

Vous pourriez faire en sorte que votre fonction static glut pourra alors l'appeler, mais je suppose que vous voulez manipuler une voiture. La solution est de faire en sorte que la fonction passe son appel à un objet, comme ceci :

void key_press(int key, int x, int y)
{
    activeCar->KeyPress(key, x, y);
}

activeCar est un pointeur globalement accessible vers la voiture. Vous pouvez le faire avec une sorte de CarManager singleton.

CarManager garde la trace de la voiture active contrôlée, de sorte que lorsqu'une touche est enfoncée, vous pouvez la transmettre : CarManager::reference().active_car().KeyPress(key, x, y) .

Un singleton est un objet qui n'a qu'une seule instance globalement accessible. Cela n'entre pas dans le cadre de cette réponse, mais vous pouvez rechercher sur Google diverses ressources pour en créer un. Recherchez Meyers Singleton pour une solution simple de singleton.

Une autre approche consiste à disposer d'une sorte d'InputManager singleton, et ce gestionnaire conservera une liste d'objets à notifier des pressions sur les touches. Cela peut être fait de plusieurs façons, la plus simple étant quelque chose comme ceci :

class InputListener;

class InputManager
{
public:
    // ...

    void register_listener(InputListener *listener)
    {
        _listeners.push_back(listener);
    }

    void unregister_listener(InputListener *listener)
    {
        _listeners.erase(std::find(_listeners.begin(), _listeners.end(), listener));
    }

   // ...

private:
    // types
    typedef std::vector<InputListener*> container;        

    // global KeyPress function, you can register this in the constructor
    // of InputManager, by calling glutSpecialFunc
    static void KeyPress(int key, int x, int y)
    {
        // singleton method to get a reference to the instance
        reference().handle_key_press(key, x, y);
    }

    void handle_key_press(int key, int x, int y) const
    {
        for (container::const_iterator iter = _listeners.begin();
             iter != _listenders.end(), ++iter)
        {
            iter->KeyPress(key, x, y);
        }
    }

    container _listeners;
};

class InputListener
{
public:
    // creation
    InputListener(void)
    {
        // automatically add to manager
        InputManager::reference().register_listener(this);
    }

    virtual ~InputListener(void)
    {
        // unregister
        InputManager::reference().unregister_listener(this);
    }

    // this will be implemented to handle input
    virtual void KeyPress(int key, int x, int y) = 0;
};

class Car : public InputListener
{
    // implement input handler
    void KeyPress(int key, int x, int y)
    {
        // ...
    }
};

Bien sûr, n'hésitez pas à poser d'autres questions si cela n'a pas de sens.

0voto

Thorgeir Points 579

Ce que j'ai fini par faire, c'est

En ajoutant :

virtual void KeyPress(int key, int x, int y) {};

à la classe WorldObject

Et mettez l'événement dans la voiture.

    void KeyPressed(int key, int x, int y)
    {
        KeyPress(key,x,y);

        list<WorldObject*>::iterator iterator = ChildObjects.begin();
        while(iterator != ChildObjects.end())
        {
            (*iterator)->KeyPressed(key,x,y);
            iterator++;
        }
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X