简体   繁体   English

无法在QT OpenGL中使用键盘命令移动相机

[英]Can't move the camera using keyboard commands in qt opengl

I am trying to implement a game using opengl in qt4. 我正在尝试在qt4中使用opengl实现游戏。 So far I have created the football pitch and I am now trying to implement a camera with which the user can move in the world freely using the arrow keys. 到目前为止,我已经创建了足球场,现在我正在尝试实现一种摄像机,用户可以使用该摄像机使用箭头键在世界上自由移动。 My friend used a piece of code he found on NeHe's tutorials and simply copy pasted it to his code and the camera worked for him. 我的朋友使用了他在NeHe的教程中找到的一段代码,然后将其复制粘贴到他的代码中,相机为他工作了。 When I tried the same only the escape button works and it just closes the opengl widget. 当我尝试同样的操作时,只有退出按钮起作用,并且它只是关闭了opengl小部件。 f1 key is supposed to switch to fullscreen but it just makes the mouse cursor invisible without switching to fullscreen mode. f1键应该切换到全屏模式,但是它只是使鼠标光标不可见而无需切换到全屏模式。 The arrow keys don't work at all. 箭头键根本不起作用。 As I'm new to opengl I could not figure out what is wrong with the implementation. 由于我是opengl的新手,所以我无法弄清楚实现的问题。

I'm adding the code where I draw the pitch and also the keyboard event handlers. 我在绘制音高的地方添加了代码,还添加了键盘事件处理程序。

void metinalifeyyaz::paintGL(){

movePlayer();

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

GLfloat xtrans = -xpos;
GLfloat ytrans = -walkbias - 0.50f;
GLfloat ztrans = -zpos;
GLfloat sceneroty = 360.0f - yrot;

glLoadIdentity();
glRotatef(lookupdown, 1.0f, 0.0f, 0.0f);
glRotatef(sceneroty, 0.0f, 1.0f, 0.0f);
glTranslatef(xtrans, ytrans+50, ztrans-130);

glLoadIdentity();
glTranslatef(1.0f,0.0f,-18.0f);
glRotatef(45,1,0,0);
drawScene();

int delay = time.msecsTo(QTime::currentTime());
if (delay == 0)
    delay = 1;
time = QTime::currentTime();
timer->start(qMax(0,10 - delay));

}


void metinalifeyyaz::movePlayer() {

if (keyUp) {
    xpos -= sin(yrot * PI_OVER_180) * 0.5f;
    zpos -= cos(yrot * PI_OVER_180) * 0.5f;
    if (walkbiasangle >= 360.0f)
        walkbiasangle = 0.0f;
    else
        walkbiasangle += 7.0f;
    walkbias = sin(walkbiasangle * PI_OVER_180) / 10.0f;
} else if (keyDown) {
    xpos += sin(yrot * PI_OVER_180)*0.5f;
    zpos += cos(yrot * PI_OVER_180)*0.5f ;
    if (walkbiasangle <= 7.0f)
        walkbiasangle = 360.0f;
    else
        walkbiasangle -= 7.0f;
    walkbias = sin(walkbiasangle * PI_OVER_180) / 10.0f;
}

if (keyLeft)
    yrot += 0.5f;
else if (keyRight)
    yrot -= 0.5f;

if (keyPageUp)
    lookupdown -= 0.5;
else if (keyPageDown)
    lookupdown += 0.5;
}


void metinalifeyyaz::keyPressEvent(QKeyEvent *event) {

switch (event->key()) {
case Qt::Key_Escape:
    close();
    break;
case Qt::Key_F1:
    setWindowState(windowState() ^ Qt::WindowFullScreen);
    break;
default:
    QGLWidget::keyPressEvent(event);
case Qt::Key_PageUp:
    keyPageUp = true;
    break;
case Qt::Key_PageDown:
    keyPageDown = true;
    break;
case Qt::Key_Left:
    keyLeft = true;
    break;
case Qt::Key_Right:
    keyRight = true;
    break;
case Qt::Key_Up:
    keyUp = true;
    break;
case Qt::Key_Down:
    keyDown = true;
    break;

}
}

void metinalifeyyaz::changeEvent(QEvent *event) {

switch (event->type()) {
case QEvent::WindowStateChange:

    if (windowState() == Qt::WindowFullScreen)
        setCursor(Qt::BlankCursor);
    else
        unsetCursor();
    break;
default:
    break;
}
}
void metinalifeyyaz::keyReleaseEvent(QKeyEvent *event) {

switch (event->key()) {
case Qt::Key_PageUp:
    keyPageUp = false;
    break;
case Qt::Key_PageDown:
    keyPageDown = false;
    break;
case Qt::Key_Left:
    keyLeft = false;
    break;
case Qt::Key_Right:
    keyRight = false;
    break;
case Qt::Key_Up:
    keyUp = false;
    break;
case Qt::Key_Down:
    keyDown = false;
    break;
default:
    QGLWidget::keyReleaseEvent(event);
}
}

I know that copy paste is not an efficient method but my friend's project is not different than mine and it works for him. 我知道复制粘贴不是一种有效的方法,但是我朋友的项目与我的项目没有什么不同,并且对他有用。 If you know anything that might cause the same code to work on one project and not the other please point it out. 如果您知道可能导致同一代码在一个项目上起作用而在另一个项目上不起​​作用的任何信息,请指出。 Of course any other comment about the code are much appreciated. 当然,有关该代码的任何其他注释都将受到赞赏。

Look: 看:

glLoadIdentity();
glRotatef(lookupdown, 1.0f, 0.0f, 0.0f);
glRotatef(sceneroty, 0.0f, 1.0f, 0.0f);
glTranslatef(xtrans, ytrans+50, ztrans-130);

glLoadIdentity(); // get rid of this!
glTranslatef(1.0f,0.0f,-18.0f);
glRotatef(45,1,0,0);
drawScene();

"glLoadIdentity" resets the current matrix. “ glLoadIdentity”重置当前矩阵。 In your code, you rotate and translate the matrix, but afterward, you reset the matrix by calling "glLoadIdentity", so the previous matrix transformations do nothing. 在您的代码中,您旋转并转换了矩阵,但是随后,您通过调用“ glLoadIdentity”来重置矩阵,因此先前的矩阵转换不执行任何操作。

Basically this is your code: 基本上,这是您的代码:

  • OpenGL, reset the matrix. OpenGL,重置矩阵。
  • OpenGL, move the player and camera. OpenGL,移动播放器和相机。
  • OpenGL, reset the matrix, and forget anything I just did. OpenGL,重置矩阵,然后忘记我刚刚做的所有事情。
  • OpenGL, do... whatever that is. OpenGL,执行...不管是什么。
  • OpenGL, draw my scene! OpenGL,绘制我的场景!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM