[译]GLUT教程 - 移动镜头2

Lighthouse3d.com >> GLUT Tutorial >> Input >> Move the Camera II

 

本节的最后一个示例是回顾.现在我们会使用键盘的高级特性.

方法是测试当键盘按下时开始运动.因此我们打算用glutIgnoreKeyRepeat关闭重复按键的回调函数.

当一个键被按下,我们设置一个非零的变量值.一旦按钮松开,该变量会置零.

当按键的按下和松开事件没有绑定函数时,我们需要检查渲染函数中以下两个变量来保持更新镜头位置和方向的一致性.

在入门一节,我们有两个变量: deltaAngle和deltaMove.这两个变量各自控制了镜头的旋转和移动.当发生非零时,镜头会执行动作,为零时镜头保持不变.这两个变量的初始值为0,即初始为镜头不变.

在代码的开头我们准备添加两个变量来跟踪按键状态,一个是方向(deltaAngle),另一个是位置(deltaMove).

// the key states. These variables will be zero
// when no key is being presses
float deltaAngle = 0.0f;
float deltaMove = 0;

 

在渲染函数我们会在开头添加一些代码来检查这两个变量和更新相应的位置和方向.

void renderScene(void) {

    if (deltaMove)
        computePos(deltaMove);
    if (deltaAngle)
        computeDir(deltaAngle);
    ...

 

其中computePos和computeDir函数的定义如下:

void computePos(float deltaMove) {

    x += deltaMove * lx * 0.1f;
    z += deltaMove * lz * 0.1f;
}

void computeDir(float deltaAngle) {

    angle += deltaAngle;
    lx = sin(angle);
    lz = -cos(angle);
}

 

响应按键按下和松开的事件函数必须要有自动恢复机制.当键按下我们只是设置指定变量为非零值.当键松开的时候变量自动归零.

void pressKey(int key, int xx, int yy) {

    switch (key) {
        case GLUT_KEY_LEFT : deltaAngle = -0.01f; break;
        case GLUT_KEY_RIGHT : deltaAngle = 0.01f; break;
        case GLUT_KEY_UP : deltaMove = 0.5f; break;
        case GLUT_KEY_DOWN : deltaMove = -0.5f; break;
    }
}

void releaseKey(int key, int x, int y) {

    switch (key) {
        case GLUT_KEY_LEFT :
        case GLUT_KEY_RIGHT : deltaAngle = 0.0f;break;
        case GLUT_KEY_UP :
        case GLUT_KEY_DOWN : deltaMove = 0;break;
    }
}

 

最后,要在main函数中添加以下代码:

glutIngnoreKeyRepeat函数是被传入非零参数来让GLUT停止报告按键重复输入.往后看,glutSpecialkUpFunc函数是用于注册按键松开事件.

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

    // init GLUT and create window
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(320,320);
    glutCreateWindow("Lighthouse3D - GLUT Tutorial");

    // register callbacks
    glutDisplayFunc(renderScene);
    glutReshapeFunc(changeSize);
    glutIdleFunc(renderScene);
    glutSpecialFunc(pressKey);

    // here are the new entries
    glutIgnoreKeyRepeat(1);
    glutSpecialUpFunc(releaseKey);

    // OpenGL init
    glEnable(GL_DEPTH_TEST);

    // enter GLUT event processing cycle
    glutMainLoop();

    return 1;
}

 

posted @ 2013-10-25 14:58  Clotho_Lee  阅读(534)  评论(0编辑  收藏  举报