2012-05-03 2 views
0

Это простая программа opengl/sdl. Как правило, это огромный детекс, в котором программа хранит данные дисплея, например, треугольник будет вставлен/прочитан в/из dequeue, как это (GL_Begin .... Vertice 1 .... Vertice 2 ... Vertice 3 .. . GL_End)C++ Weird поведение указателя функции

Деталь структура

enum Shapes{ 
    LINE, 
    POLYGON, 
    TRIANGLE 
}; 

struct Item{ 
    int id; 
    int type; 
    Shapes shape; 
    double x; 
    double y; 
    double z; 
}; 

...

void GEngine::CC2D(int id,double x,double y){ // Change Coordinates ... Move the Item 

    for(int i=0;i<Items.size();i++){ 
     Item* item = &Items[i];     // Pointer to the item INSIDE the deque because we need to edit it, we can not create a new instance of Item 

     if(item->id == id && item->type == 2){ 
      item->x += x; 
      item->y += y; 
     } 
    } 

    DrawScene(); 
} 

void GEngine::PollEvents(void (*Event)()){ 
    int mbpressed = 0; // Mouse button pressed flag 
    int mouse_xpre = 0; 
    int mouse_ypre = 0; 
    int move_id = 0; // TESTING 
    while(1){ 
     while(SDL_PollEvent(&event)){ 

      switch(event.type){ 
       case SDL_MOUSEMOTION:{ 
        if(mbpressed == 1){ 
         mouse_x = event.motion.x; // X2 
         mouse_y = event.motion.y; // Y2 
        // (*Event)(); 

        // CC2D( ( X2 - X1 ),( Y2 - Y1 ) 
         CC2D(move_id,(mouse_x-mouse_xpre),(mouse_y-mouse_ypre));  // The difference between the current and the previous mouse position is equal to the DX and DY which will be used to move the vertices. 
         mouse_xpre = mouse_x;  // X1 
         mouse_ypre = mouse_y;  // Y1 

         SDL_Delay(20); 

        } 
        break; 

Теперь вопрос. Если я использую CC2D (move_id, (mouse_x-mouse_xpre), (mouse_y-mouse_ypre)); он работает нормально, но если я добавлю функцию CC2D в Событие один, алгоритм завершится неудачно, и вместо перемещения элемента с помощью мыши он отодвинется от экрана.

Иными словами.

case SDL_MOUSEMOTION:{ 
         if(mbpressed == 1){ 
          mouse_x = event.motion.x; // X2 
          mouse_y = event.motion.y; // Y2 
         // (*Event)(); 

         // CC2D( ( X2 - X1 ),( Y2 - Y1 ) 
         CC2D(move_id,(mouse_x-mouse_xpre),(mouse_y-mouse_ypre));  // The difference between the current and the previous mouse position is equal to the DX and DY which will be used to move the vertices. 
         mouse_xpre = mouse_x;  // X1 
         mouse_ypre = mouse_y;  // Y1 

         SDL_Delay(20); 

        } 
        break; 
} 

^Работы просто отлично.

Но

GEngine gEngine; 

void Event(){ 
      gEngine.CC2D(0,(gEngine.mouse_x-gEngine.mouse_xpre),(gEngine.mouse_y-gEngine.mouse_ypre)); 
    } 

int main(int argc, char *argv[]){ 

... code ... 

gEngine.PollEvents(&Event); 

return 0; // NEVER REACHED 
} 

с

case SDL_MOUSEMOTION:{ 
        if(mbpressed == 1){ 
         mouse_x = event.motion.x; // X2 
         mouse_y = event.motion.y; // Y2 
         (*Event)(); 

         mouse_xpre = mouse_x;  // X1 
         mouse_ypre = mouse_y;  // Y1 

         SDL_Delay(20); 

        } 
        break; 
} 

не ...

Для дальнейшего упрощения вещи:

Case SDL_MOUSEMOTION: ...... code ..... CC2D(params) ........ 

работает отлично, но

Event(){ CC2D(params) } // Main.cpp 
Case SDL_MOUSEMOTION: ...... code ..... (*Event)() ........ // GEngine.cpp 

не работает по назначению

+1

...... * Стена текста * ...... и вместо элемента, перемещающегося с помощью мыши, он отходит от экрана. :) –

+0

Что такое «(* Event)();», его просто псевдокод вроде «...» или синтаксическая ошибка? Помните, некоторые cccompilers позволяют делать некоторые werid вещи с outing генерации исключения ;-) – umlcat

+0

Да, извините, пропустил это. @umlcat no, это допустимый синтаксис для вызова функции через указатель функции. –

ответ

3

Вы объявляете локальные переменные здесь внутри PollEvents:

int mouse_xpre = 0; 
int mouse_ypre = 0; 

Обратите внимание, что они называются mouse_xpre и mouse_ypre. Затем в обратном вызове вы делаете

gEngine.CC2D(0,(gEngine.mouse_x-gEngine.mouse_xpre),(gEngine.mouse_y-gEngine.mouse_ypre)); 
//          ^^^^^^^^^^       ^^^^^^^^^^ 

, который обращается к переменным-членам. Вам нужно удалить объявление локальных переменных, чтобы они не скрывали переменные-члены, и вы будете использовать переменные-члены в обоих местах.

+0

Спасибо! Это цена, за которую не следует использовать конструкторы. По какой-то странной причине я решил добавить * int * перед целыми числами, которые уже были определены в классе. –

Смежные вопросы