0

まず、ピラミッドの座標を表す構造を定義しました。

typedef struct
{
    GLfloat xUp;
    GLfloat yUp;
    GLfloat zUp;
    GLfloat base;
    GLfloat height;
}pyramid;

ここでかなり自明です:私は最高点、底辺、高さの座標を保存します。
ピラミッドを描画する関数を書きました:

void drawPyramid(pyramid pyr)
{
    GLfloat p1[]= {pyr.xUp+pyr.base/2.0, pyr.yUp-pyr.height, pyr.zUp-pyr.base/2.0};
    GLfloat p2[]= {pyr.xUp+pyr.base/2.0, pyr.yUp-pyr.height, pyr.zUp+pyr.base/2.0};
    GLfloat p3[]= {pyr.xUp-pyr.base/2.0, pyr.yUp-pyr.height, pyr.zUp+pyr.base/2.0};
    GLfloat p4[]= {pyr.xUp-pyr.base/2.0, pyr.yUp-pyr.height, pyr.zUp-pyr.base/2.0};
    GLfloat up[]= {pyr.xUp, pyr.yUp, pyr.zUp};

    glBegin(GL_TRIANGLES);

    glColor4f(1.0, 0.0, 0.0, 0.0);
    glVertex3fv(up);
    glVertex3fv(p1);
    glVertex3fv(p2);

    glColor4f(0.0, 1.0, 0.0, 0.0);
    glVertex3fv(up);
    glVertex3fv(p2);
    glVertex3fv(p3);

    glColor4f(0.0, 0.0, 1.0, 0.0);
    glVertex3fv(up);
    glVertex3fv(p3);
    glVertex3fv(p4);

    glColor4f(1.0, 1.0, 0.0, 0.0);
    glVertex3fv(up);
    glVertex3fv(p4);
    glVertex3fv(p1);
    glEnd();



    glColor4f(0.0, 1.0, 1.0, 0.0);
    glBegin(GL_QUADS);
    glVertex3fv(p1);
    glVertex3fv(p2);
    glVertex3fv(p3);
    glVertex3fv(p4);
    glEnd();

}

すべての頂点を反時計回りに描くのに苦労しましたが、おそらく何かを台無しにしました。
これは、レンダリング関数でピラミッドを表示する方法です。

void display()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glTranslatef(0.0, -25.0, 50.0);
    glRotatef(-angle, 0.0, 1.0, 0.0);
    glTranslatef(0.0, 25.0, -50.0);

    pyramid pyr;
    pyr.xUp=0.0;
    pyr.yUp=10.0;
    pyr.zUp=50.0;
    pyr.base=10.0;
    pyr.height=18.0;
    glColor4f(1.0, 0.0, 0.0, 0.0);
    drawPyramid(pyr);

    glutSwapBuffers();
}

また、glut メインループの前に呼び出される init メソッドも使用します。

void init()
{
    glEnable(GL_DEPTH);
    glViewport(-1.0, 1.0, -1.0, 1.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(35.0, 1.0, 1.0, 100.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0.0,1.0,0.0, 0.0,1.0,30.0, 0.0,1.0,0.0);
}

angle は、ピラミッドを回転させるために使用する倍数であり、「r」を押すことで変更できますが、これは関係ありません。実際の問題は、頂点をどのように描画するかにあるようです。
問題は、ピラミッドの面が散らばって、ごちゃごちゃしているように見えることです。この状況を画像で説明すると、

ピラミッド

小さすぎる顔が表示されますが、その理由はわかりません。
ピラミッドを回転させると、めちゃくちゃに見えるので、これを説明するビデオを録画しました。
問題が完全に明確でない場合は、後でアップロードできます。

PS: 多くの人が、私が時代遅れの手法を使用していることに気付きました.しかし、残念ながら、これは私の大学が提供しているものです.

編集

メイン関数について言うのを忘れていました:

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(500, 500);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("Sierpinsky Pyramid");
    glutDisplayFunc(display);
    glutKeyboardFunc(keyboard);
    init();
    glutMainLoop();
    return 0;
}
4

1 に答える 1

3

デプスバッファが初期化されていないようです。

電話をかけるglEnable(GL_DEPTH_TEST)だけでは不十分です。glutを正しく初期化し、デプスバッファをサポートするように指定する必要があります。そうしないと、デプスバッファを取得できません。私が正しく覚えていれば、これはを使用して行われglutInitDisplayMode(GLUT_DEPTH|...)ます。こちらのドキュメントとこちらの紹介をご覧ください。追加情報はグーグルを使用して見つけることができます。

- 編集 -

無効なパラメータをglEnableに渡しています。glEnable(GL_DEPTH_TEST)の代わりに呼び出しますglEnable(GL_DEPTH)

また:

  1. 表示機能の行列コードはglPushMatrix/glPopMatrixで保護されていません。つまり、ピラミッドを回転させるたびに、回転が前の変換に適用されます。つまり、表示関数を呼び出すとピラミッドが回転します。
  2. glViewportが無効なパラメーターで呼び出されました。glViewportは4つの整数引数を取りますが、floatを渡そうとしています。また、「-1.0の幅」とはどういう意味ですか?
  3. エラーコード(glGetError)をチェックしていません。glEnable呼び出しの後にglGetErrorを呼び出そうとすると、GL_INVALID_ENUMが返されることがわかります。

OpenGLにはドキュメントがあります。ドキュメントはopengl.orgで入手できます。それを使って読んでください。また、「OpenGLレッドブック」を読むことをお勧めします。

于 2012-11-18T17:07:10.963 に答える