0

我是 OpenGL 的新手,我正在尝试画一个火柴人,然后使用键盘上的箭头键移动它。我的想法是为火柴人使用全局变量,并在按下某个键时更改它们。之后再次调用绘图函数 (myDisplay())。不幸的是,我总是收到以下错误消息:“错误 10 错误 C2371:'myDisplay':重新定义;不同的基本类型”当我按照某些教程中的建议用 glutPostRedisplay() 替换键盘功能中的 myDisplay() 调用时,我阅读错误消息消失,构建成功。但是火柴人在按键时不会移动。

这是我的代码:

#include <GL/glut.h>

GLint x; GLint y; GLint d;  //parameters for the stickman

void myKeyboard(unsigned char key, int mx, int my) {
    int x1 = mx;
    int y1 = 480 - my;

    switch(key){
    case GLUT_KEY_LEFT :
        x = x-50;
        myDisplay();
        break;
    case 'E' : 
        exit(-1);
        break;
    default: 
        break;
    }
}


void stickman () {
    glBegin(GL_LINES);          //body
        glVertex2i(x, y);
        glVertex2i(x, y-2*d);
        glVertex2i(x-d, y-d);
        glVertex2i(x+d, y-d);
        glVertex2i(x, y-2*d);
        glVertex2i(x-d, y-3*d);
        glVertex2i(x, y-2*d);
        glVertex2i(x+d, y-3*d);
    glEnd();

    glBegin(GL_LINE_LOOP);      //head
        glVertex2i(x,y);
        glVertex2i(x+0.5*d, y);
        glVertex2i(x+0.5*d, y+0.5*d);
        glVertex2i(x-0.5*d, y+0.5*d);
        glVertex2i(x-0.5*d, y);
    glEnd();
}


void myDisplay() {
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0.0, 0.0, 0.0);

    stickman();

    glFlush();
}

void myInit() {
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, 640.0, 0.0, 480.0);
}

void main(int argc, char** argv) {
    x = 320;
    y = 350;
    d = 100;

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(640, 480);
    glutInitWindowPosition(200, 50);
    glutCreateWindow("Stickman");
    glutDisplayFunc(myDisplay);
    glutKeyboardFunc(myKeyboard);
    glutPostRedisplay();
    myInit();
    glutMainLoop();
}
4

2 回答 2

1

正如我所发现的(GLUT 键盘教程),问题不在于重新绘制图片,而在于无法识别左箭头键。我需要为我的特殊键(例如箭头键)编写另一个键盘功能。

现在我的代码看起来像这样并且它可以工作:

void processNormalKeys (unsigned char key, int mx, int my) {
    if (key == 'E')
        exit(-1);   
}

void processSpecialKeys (int key, int mx, int my) {
    switch(key){
    case GLUT_KEY_LEFT :
        x = x-5;
        glutPostRedisplay();
        break;
    case GLUT_KEY_RIGHT :
        x = x+5;
        glutPostRedisplay();
        break;
    case GLUT_KEY_UP :
        y = y+5;
        glutPostRedisplay();
        break;
    case GLUT_KEY_DOWN :
        y = y-5;
        glutPostRedisplay();
        break;
    default: 
        break;
    }
}

我还必须调整主要功能:

glutKeyboardFunc(processNormalKeys);
glutSpecialFunc(processSpecialKeys);

但无论如何感谢您的帮助!

于 2013-09-04T16:30:47.430 回答
0

glutPostRedisplay()用于告诉标记需要重新显示当前窗口,如文档中所述。这意味着您需要在函数结束时调用此myKeyboard函数。

我还建议您使用双倍或三倍缓冲液以避免不希望的结果。对于双缓冲区,您需要更改glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB );glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB );然后在显示功能结束时添加glutSwapBuffers();. 你可以在这里找到更多信息http://www.swiftless.com/tutorials/opengl/smooth_rotation.html

于 2013-09-04T11:00:03.703 回答