怎么写GLUT键盘功能?

时间:2011-12-25 10:14:16

标签: c opengl keyboard-events

我编写了下面的代码,但是在运行时,当我按下键时,程序不起作用 我想编写一个程序,当用户按下right_keyalt_key时绘制三角形。但这根本不起作用。它总是显示黑屏。

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

3 个答案:

答案 0 :(得分:6)

好的,现在有效。我修改了您的代码以启用ALT或SHIFT或CTRL。代码打印出密钥的扫描码。 要打印ALT,CTRL或SHIFT扫描码,只需按ALT或SHIFT或CTRL与其他键组合。 其他,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;
}

答案 1 :(得分: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编程而不必担心处理其他问题,我建议您使用预制的库处理窗口,输入等,例如: SFMLSDL。它们的工作方式类似于过剩,但它们通常更强大,并且仍然允许您直接运行OpenGL调用,同时提供简化的事件处理。

答案 2 :(得分:1)

您无法在键盘回调中生成图形命令。当您感兴趣的键被按下时设置一些全局状态,并使用显示代码中的信息。

调试此类问题的方法是在您认为无效的代码中使用printf语句。这里在键盘处理程序中添加一个printf很快就会告诉你代码正在执行但是没有绘制三角形。这可能会让你考虑什么时候可以使用图形命令,什么时候不可以。