4

モデルビュー マトリックスと や のような関数を使用して、オブジェクトまたはシーン全体の視点を変換することができましたがglTranslatef()gluLookAt()両方を実行しようとすると問題が発生します。

で使用するパラメータに関係なく、gluLookAt()描画するオブジェクトは同じ角度から表示されるようです。私は、他のスレッドで読んだものに基づいて、他のさまざまな用途で関数を呼び出してみましたが、うまくいきませんでしglPushMatrix()た。glPopMatrixこれが私が今持っているものです。オブジェクトは動くはずですが、1 つの視点からしか表示できません。

たとえば、xy 平面内を移動しているはずで、反時計回りに回転しているので、 に変更z_0する-30と時計回りに移動しているように見えると思いますが、違いはないようです。その前に省略している定数の長いリストがあります。最終的な目標は、太陽系の単純なモデルを作成することです。

    GLfloat time = 0.0;
GLfloat inc = 0.01;

// viewing parameters
GLint winWidth = 600, winHeight = 600;
GLfloat x_0 = 0.0, y_0 = 0.0, z_0 = 30.0;
GLfloat xref = 0.0, yref = 0.0, zref = 0.0;
GLfloat Vx = 0.0, Vy= 1.0, Vz = 0.0;
GLfloat xwMin = -50.0, ywMin = -50.0, xwMax = 50.0, ywMax = 50.0;
GLfloat dnear = .3, dfar = 10.0;

void view(void) {
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(xwMin, xwMax, ywMin, ywMax, dnear, dfar);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(x_0, y_0, z_0, xref, yref, zref, Vx, Vy, Vz);
}

void init(void) {
    view();
    glEnable(GL_DEPTH_TEST);
}

void drawPlanet(GLfloat maj, GLfloat min, GLfloat x0, GLfloat theta,
        GLfloat size) {
    GLfloat x = maj * cosf(theta) + x0;
    GLfloat y = min * sinf(theta);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glTranslatef(x, y, 0);
    glutSolidSphere(size, 25, 25);
    glPopMatrix();
}

void display(void) {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glColor3f(1.0, 1.0, 1.0);

    drawPlanet(MERCURY_MAJOR, MERCURY_MINOR, MERCURY_CENTER,
        time / MERCURY_YEAR, MERCURY_SIZE);

    drawPlanet(MARS_MAJOR, MARS_MINOR, MARS_CENTER,
        time / MARS_YEAR, MARS_SIZE);

    drawPlanet(URANUS_MAJOR, URANUS_MINOR, URANUS_CENTER,
        time / URANUS_YEAR, URANUS_SIZE);

    glFlush();
}

void idle(void) {
    time += inc;
    display();
    glutSwapBuffers();
}

int main (int argc, char **argv) {
    glutInit(&argc, argv);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(0,0);
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH);
    glutCreateWindow("");

    init();

    glutDisplayFunc(display);
    glutIdleFunc(idle);

    glutMainLoop();
}

誰かが私が見逃しているものを見たら、問題を解決するのに役立つ説明や追加の読書への指示を本当に感謝します.

4

1 に答える 1

4

あなたは典型的なOpenGL初心者の間違いを犯し、マトリックス操作をあちこちに散らばらせます。OpenGLマトリックスの状態を初期化することはありません。表示機能に入るときは、必ず新しく設定してください。これにより、物事を簡単に見つけることができます。

また、OpenGLを、変換階層を「魔法のように」確立するglPush/PopMatrixを使用したシーングラフと間違える可能性があります。

glPushMatrix–おそらくご存知のとおり–スタックマトリックスの現在の最上位のコピーを作成し、スタックにプッシュします。アイデアは、さらなる変換を掛けることができる一時的なコピーを作成することです。

次に、コードを少し異なる形式で見てみましょう。

void display(void) {
    glViewport(…);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(xwMin, xwMax, ywMin, ywMax, dnear, dfar);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(x_0, y_0, z_0, xref, yref, zref, Vx, Vy, Vz);

    glColor3f(1.0, 1.0, 1.0);

    {
        GLfloat x = maj * cosf(theta) + x0;
        GLfloat y = min * sinf(theta);
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        glLoadIdentity(); // <<<<<<<<<

        glTranslatef(x, y, 0);
        glutSolidSphere(size, 25, 25);
        glPopMatrix();
    }

ここで何が起こっているのか分かりますか?モデルビューマトリックスをIDにリセットしてから、それを変換します。以前に作成したルックアットマトリックスは完全に破棄され、球の描画には影響しません。

glLoadIdentity()私がマークしたものを削除すると、問題なく動作するはずです。

于 2013-01-17T10:14:06.363 に答える