2011-12-25 3 views
2

Я написал код ниже, но во время выполнения, когда я нажимаю клавиши, программа не работает.
Я хочу написать программу, которая рисует треугольник, когда пользователь нажимает right_key и alt_key. Но это совсем не работает. Он всегда показывает черный экран.Как написать функции клавиатуры GLUT?

#include <GL/glut.h> 
void init (void) 
{ 
    glClearColor(0.0,0.0,0.0,0.0); 
    glMatrixMode(GL_PROJECTION); 
    gluOrtho2D(0.0,200.0,0.0,200.0); 
} 
float red=1,green=1,blue=1; 
void processSpecialKeys(int key, int x, int y) { 
    if(key=='0') 
     exit(0); 
    int mod; 
    if(key== GLUT_KEY_RIGHT) { 
     mod = glutGetModifiers(); 
     if (mod==GLUT_ACTIVE_ALT) { 
      red = 1.0; green = 0.0; blue = 0.0; 
      glColor3f(red,green,blue); 
      glBegin(GL_TRIANGLES); 
      glVertex2f(0,0); 
      glVertex2f(0,100); 
      glVertex2f(50,100); 
      glEnd(); 
     } 
    } 
} 
void display(void) 
{ 
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
    glFlush(); 
} 
int main(int argc, char **argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); 
    glutInitWindowPosition(50,20); 
    glutInitWindowSize(400, 300); 
    glutCreateWindow("A simple example"); 
    init(); 
    glutDisplayFunc(display); 
    glutSpecialFunc(processSpecialKeys); 
    glutMainLoop(); 
} 
+0

OpenGL не занимается обработкой киосков. Вероятно, вы подразумеваете GLUT, который не имеет ничего общего с OpenGL. –

ответ

6

ОК, сейчас он работает. Я изменил ваш код, чтобы включить ALT или SHIFT или CTRL. Код выводит сканноды ключей. Чтобы распечатать scancode ALT, CTRL ИЛИ SHIFT, просто нажмите ALT или SHIFT или CTRL в комбинации с другими клавишами. Otherwse GLUT не зарегистрирует его.

#include <stdio.h> 
#include <GL/glut.h> 

float red=1,green=1,blue=1; 



void init (void) 
{ 
    glClearColor(0.0,0.0,0.0,0.0); 
    glMatrixMode(GL_PROJECTION); 
    gluOrtho2D(0.0,200.0,0.0,200.0); 
} 


void process_SHIFT_ALT_CTRL(unsigned char key, int x, int y) 
{ 
    // Press ALT or SHIFT or CTRL in combination with other keys. 
    printf("key_code =%d \n",key); 

    int mod = glutGetModifiers(); 

    if (mod != 0) //ALT=4 SHIFT=1 CTRL=2 
    {  
      switch(mod) 
      { 
      case 1 : printf("SHIFT key %d\n",mod); break; 
      case 2 : printf("CTRL key %d\n",mod); break; 
      case 4 : printf("ALT key %d\n",mod); break; 
      mod=0; 
      } 
    } 
} 


void process_Normal_Keys(int key, int x, int y) 
{ 
    switch (key) 
    {  
     case 27 :  break; 
     case 100 : printf("GLUT_KEY_LEFT %d\n",key); break; 
     case 102: printf("GLUT_KEY_RIGHT %d\n",key); ; break; 
     case 101 : printf("GLUT_KEY_UP %d\n",key); ; break; 
     case 103 : printf("GLUT_KEY_DOWN %d\n",key); ; break; 
    } 

} 


void display(void) 
{ 
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
    glFlush(); 
} 


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

    printf("Press ALT or SHIFT or CTRL in combination with other keys. \n\n"); 

    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); 
    glutInitWindowPosition(800,20); 
    glutInitWindowSize(400, 300); 
    glutCreateWindow("A simple example"); 
    init(); 

    // famous GLUT callback functions 

    glutDisplayFunc(display); 


    glutSpecialFunc(process_Normal_Keys); 
    glutKeyboardFunc(process_SHIFT_ALT_CTRL); 


    glutMainLoop(); 

return 0; 
} 
+0

Спасибо за коды ... –

+0

'glutSpecialFunc (process_Normal_Keys);', действительно? – wmamrak

3

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

Это означает, что вы не увидите треугольник, если только нажатие клавиши не будет обработано прямо между glClear() и glFlush(), что произойдет довольно редко и только для одного кадра.

Что вам нужно сделать, это довольно просто: После обработки нажатия клавиши сохраните этот статус, например. установите логическую переменную в true/false в зависимости от ввода ключа.

Затем проверьте это в display() и нарисуйте треугольник, если потребуется.

пример

Псевдо кода:

bool status = false; 

inputhandler(key) 
{ 
    if(key == KEY_A) 
     status = true 
    else if(KEY == KEY_S) 
     status = false; 
} 

displayhandler() 
{ 
    clear(); 
    if(status) 
     drawTriangle(); 
    flush(); 
} 

main() 
{ 
    //... init etc. 
    glutDisplayFunc(&displayhandler); 
    glutSpecialFunc(&inputhandler); 
} 

О дальнейших примечаниях, если вы хотели бы получить в программирование OpenGL, не беспокоясь об обработке других вещей вокруг, я бы рекомендовал использовать Premade библиотеку обработки окон , входы и т. д. для вас, например SFML или SDL. Они работают аналогично перенасыщению, но в целом они более мощные и позволят вам напрямую запускать вызовы OpenGL, предлагая упрощенную обработку событий.

+0

Можете ли вы объяснить больше? –

+0

можно вызвать функцию glutSpecialFunc (processSpecialKeys). в функции дисплея? –

+0

Вызов клавиатуры не будет * когда-либо * запускается * пока * обратный вызов дисплея работает. Если бы это было так, нужно было бы синхронизировать доступ к общему состоянию. –

1

Вы не можете генерировать графические команды в обратном вызове клавиатуры. Установите часть глобального состояния, когда интересующий вас ключ нажат, и используйте информацию в коде дисплея.

Путь к отлаживанию подобных проблем заключается в использовании операторов printf в коде, который, по вашему мнению, не работает. Здесь добавление printf в обработчик клавиатуры скоро скажет вам, что код выполняется, но треугольник не рисуется. Возможно, это заставило вас задуматься о том, когда графическая команда возможна, а когда нет.

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