2

qt4でopenglを使用してゲームを実装しようとしています。これまでサッカー場を作成してきましたが、現在、ユーザーが矢印キーを使用して自由に世界を移動できるカメラを実装しようとしています。私の友人は、NeHe のチュートリアルで見つけたコードを使用し、コードにコピーして貼り付けるだけで、カメラが機能しました。私が同じことを試みたとき、エスケープボタンだけが機能し、openglウィジェットを閉じるだけです。f1 キーはフルスクリーンに切り替えるはずですが、フルスクリーン モードに切り替えずにマウス カーソルを非表示にするだけです。矢印キーはまったく機能しません。私はopenglが初めてなので、実装の何が問題なのかわかりませんでした。

ピッチとキーボード イベント ハンドラーを描画するコードを追加しています。

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

コピーペーストが効率的な方法ではないことはわかっていますが、友人のプロジェクトは私のプロジェクトと変わらず、彼にとってはうまくいきます。同じコードが 1 つのプロジェクトで機能し、別のプロジェクトでは機能しない可能性があることを知っている場合は、それを指摘してください。もちろん、コードに関するその他のコメントは大歓迎です。

4

1 に答える 1

1

見て:

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」は現在のマトリックスをリセットします。コードでは、マトリックスを回転および変換しますが、その後、「glLoadIdentity」を呼び出してマトリックスをリセットするため、前のマトリックス変換は何もしません。

基本的にこれはあなたのコードです:

  • OpenGL、マトリックスをリセットします。
  • OpenGL、プレーヤーとカメラを動かします。
  • OpenGL、マトリックスをリセットし、今行ったことをすべて忘れてください。
  • OpenGL、どうにかして...それが何であれ。
  • OpenGL、私のシーンを描いてください!
于 2012-12-19T21:14:43.350 に答える